From fc656e1c61634c604300e4e489aa1b44b20c3ce0 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Tue, 10 Oct 2023 20:25:51 +0500 Subject: [PATCH 01/57] feat:knowledge rag graph --- pilot/embedding_engine/knowledge_type.py | 6 +++- pilot/embedding_engine/source_embedding.py | 4 +-- pilot/embedding_engine/url_embedding.py | 2 +- pilot/scene/base.py | 10 +++++++ pilot/scene/base_chat.py | 34 ++++++++++++++++++++++ pilot/scene/chat_factory.py | 2 ++ pilot/utils/utils.py | 6 ++-- 7 files changed, 58 insertions(+), 6 deletions(-) diff --git a/pilot/embedding_engine/knowledge_type.py b/pilot/embedding_engine/knowledge_type.py index 77fb98666..c4c278be4 100644 --- a/pilot/embedding_engine/knowledge_type.py +++ b/pilot/embedding_engine/knowledge_type.py @@ -41,7 +41,11 @@ class KnowledgeType(Enum): def get_knowledge_embedding( - knowledge_type, knowledge_source, vector_store_config, source_reader, text_splitter + knowledge_type, + knowledge_source, + vector_store_config=None, + source_reader=None, + text_splitter=None, ): match knowledge_type: case KnowledgeType.DOCUMENT.value: diff --git a/pilot/embedding_engine/source_embedding.py b/pilot/embedding_engine/source_embedding.py index 24bae97b2..5b1e57ae2 100644 --- a/pilot/embedding_engine/source_embedding.py +++ b/pilot/embedding_engine/source_embedding.py @@ -31,11 +31,11 @@ class SourceEmbedding(ABC): ): """Initialize with Loader url, model_name, vector_store_config""" self.file_path = file_path - self.vector_store_config = vector_store_config + self.vector_store_config = vector_store_config or {} self.source_reader = source_reader or None self.text_splitter = text_splitter or None self.embedding_args = embedding_args - self.embeddings = vector_store_config["embeddings"] + self.embeddings = self.vector_store_config.get("embeddings", None) @abstractmethod @register diff --git a/pilot/embedding_engine/url_embedding.py b/pilot/embedding_engine/url_embedding.py index e00cf84e2..39e7bf1dc 100644 --- a/pilot/embedding_engine/url_embedding.py +++ b/pilot/embedding_engine/url_embedding.py @@ -27,7 +27,7 @@ class URLEmbedding(SourceEmbedding): file_path, vector_store_config, source_reader=None, text_splitter=None ) self.file_path = file_path - self.vector_store_config = vector_store_config + self.vector_store_config = vector_store_config or None self.source_reader = source_reader or None self.text_splitter = text_splitter or None diff --git a/pilot/scene/base.py b/pilot/scene/base.py index 162759e3c..489e98d0b 100644 --- a/pilot/scene/base.py +++ b/pilot/scene/base.py @@ -75,6 +75,16 @@ class ChatScene(Enum): "Dialogue through natural language and private documents and knowledge bases.", ["Knowledge Space Select"], ) + ExtractTriplet = Scene( + "extract_triplet", + "Extract Triplet", + "Extract Triplet", + ["Extract Select"], + True, + ) + ExtractEntity = Scene( + "extract_entity", "Extract Entity", "Extract Entity", ["Extract Select"], True + ) @staticmethod def of_mode(mode): diff --git a/pilot/scene/base_chat.py b/pilot/scene/base_chat.py index daab56964..5c16ee286 100644 --- a/pilot/scene/base_chat.py +++ b/pilot/scene/base_chat.py @@ -205,6 +205,40 @@ class BaseChat(ABC): self.memory.append(self.current_message) return self.current_ai_response() + async def get_llm_response(self): + payload = self.__call_base() + logger.info(f"Request: \n{payload}") + ai_response_text = "" + try: + from pilot.model.cluster import WorkerManagerFactory + + worker_manager = CFG.SYSTEM_APP.get_component( + ComponentType.WORKER_MANAGER_FACTORY, WorkerManagerFactory + ).create() + + model_output = await worker_manager.generate(payload) + + ### output parse + ai_response_text = ( + self.prompt_template.output_parser.parse_model_nostream_resp( + model_output, self.prompt_template.sep + ) + ) + ### model result deal + self.current_message.add_ai_message(ai_response_text) + prompt_define_response = ( + self.prompt_template.output_parser.parse_prompt_response( + ai_response_text + ) + ) + except Exception as e: + print(traceback.format_exc()) + logger.error("model response parse failed!" + str(e)) + self.current_message.add_view_message( + f"""model response parse failed!{str(e)}\n {ai_response_text} """ + ) + return prompt_define_response + def _blocking_stream_call(self): logger.warn( "_blocking_stream_call is only temporarily used in webserver and will be deleted soon, please use stream_call to replace it for higher performance" diff --git a/pilot/scene/chat_factory.py b/pilot/scene/chat_factory.py index ad2da3b3f..fc47b7468 100644 --- a/pilot/scene/chat_factory.py +++ b/pilot/scene/chat_factory.py @@ -13,6 +13,8 @@ class ChatFactory(metaclass=Singleton): from pilot.scene.chat_dashboard.chat import ChatDashboard from pilot.scene.chat_knowledge.v1.chat import ChatKnowledge from pilot.scene.chat_knowledge.inner_db_summary.chat import InnerChatDBSummary + from pilot.scene.chat_knowledge.extract_triplet.chat import ExtractTriplet + from pilot.scene.chat_knowledge.extract_entity.chat import ExtractEntity from pilot.scene.chat_data.chat_excel.excel_analyze.chat import ChatExcel chat_classes = BaseChat.__subclasses__() diff --git a/pilot/utils/utils.py b/pilot/utils/utils.py index b72745a33..ebb3534e0 100644 --- a/pilot/utils/utils.py +++ b/pilot/utils/utils.py @@ -168,10 +168,12 @@ def get_or_create_event_loop() -> asyncio.BaseEventLoop: assert loop is not None return loop except RuntimeError as e: - if not "no running event loop" in str(e): + if not "no running event loop" in str(e) and not "no current event loop" in str( + e + ): raise e logging.warning("Cant not get running event loop, create new event loop now") - return asyncio.get_event_loop_policy().get_event_loop() + return asyncio.get_event_loop_policy().new_event_loop() def logging_str_to_uvicorn_level(log_level_str): From eb2c220d227464006d203306665e4602be597284 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Thu, 12 Oct 2023 11:00:21 +0500 Subject: [PATCH 02/57] feat:rag graph conponent --- pilot/component.py | 1 + pilot/server/component_configs.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/pilot/component.py b/pilot/component.py index 3179fa696..74af0e150 100644 --- a/pilot/component.py +++ b/pilot/component.py @@ -47,6 +47,7 @@ class ComponentType(str, Enum): WORKER_MANAGER_FACTORY = "dbgpt_worker_manager_factory" MODEL_CONTROLLER = "dbgpt_model_controller" EXECUTOR_DEFAULT = "dbgpt_thread_pool_default" + RAG_GRAPH_DEFAULT = "dbgpt_rag_engine_default" class BaseComponent(LifeCycle, ABC): diff --git a/pilot/server/component_configs.py b/pilot/server/component_configs.py index 71ef797d9..f7bcde332 100644 --- a/pilot/server/component_configs.py +++ b/pilot/server/component_configs.py @@ -28,6 +28,10 @@ def initialize_components( system_app.register_instance(controller) + # Register global default RAGGraphFactory + from pilot.graph_engine.graph_factory import DefaultRAGGraphFactory + system_app.register(DefaultRAGGraphFactory) + _initialize_embedding_model( param, system_app, embedding_model_name, embedding_model_path ) From fa6a9040d5e0670ba491b5574101e5de3e8f046a Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Fri, 13 Oct 2023 14:22:46 +0800 Subject: [PATCH 03/57] feat:knowledge rag graph --- pilot/scene/chat_knowledge/v1/chat.py | 25 ++++++++++++++++ pilot/server/component_configs.py | 1 + pilot/server/knowledge/api.py | 35 +++++++++++++++++++++++ pilot/server/knowledge/request/request.py | 7 +++++ pilot/server/knowledge/service.py | 22 +++++++++++++- 5 files changed, 89 insertions(+), 1 deletion(-) diff --git a/pilot/scene/chat_knowledge/v1/chat.py b/pilot/scene/chat_knowledge/v1/chat.py index 8177a1a5a..ebecddd19 100644 --- a/pilot/scene/chat_knowledge/v1/chat.py +++ b/pilot/scene/chat_knowledge/v1/chat.py @@ -1,6 +1,7 @@ import os from typing import Dict +from pilot.component import ComponentType from pilot.scene.base_chat import BaseChat from pilot.scene.base import ChatScene from pilot.configs.config import Config @@ -47,6 +48,11 @@ class ChatKnowledge(BaseChat): "vector_store_name": self.knowledge_space, "vector_store_type": CFG.VECTOR_STORE_TYPE, } + from pilot.graph_engine.graph_factory import RAGGraphFactory + + self.rag_engine = CFG.SYSTEM_APP.get_component( + ComponentType.RAG_GRAPH_DEFAULT.value, RAGGraphFactory + ).create() embedding_factory = CFG.SYSTEM_APP.get_component( "embedding_factory", EmbeddingFactory ) @@ -82,6 +88,25 @@ class ChatKnowledge(BaseChat): if self.space_context: self.prompt_template.template_define = self.space_context["prompt"]["scene"] self.prompt_template.template = self.space_context["prompt"]["template"] + # docs = self.rag_engine.search(query=self.current_user_input) + # import httpx + # with httpx.Client() as client: + # request = client.build_request( + # "post", + # "http://127.0.0.1/api/knowledge/entities/extract", + # json="application/json", # using json for data to ensure it sends as application/json + # params={"text": self.current_user_input}, + # headers={}, + # ) + # + # response = client.send(request) + # if response.status_code != 200: + # error_msg = f"request /api/knowledge/entities/extract failed, error: {response.text}" + # raise Exception(error_msg) + # docs = response.json() + # import requests + # docs = requests.post("http://127.0.0.1:5000/api/knowledge/entities/extract", headers={}, json={"text": self.current_user_input}) + docs = self.knowledge_embedding_client.similar_search( self.current_user_input, self.top_k ) diff --git a/pilot/server/component_configs.py b/pilot/server/component_configs.py index 7d306ada1..ba5c35ec6 100644 --- a/pilot/server/component_configs.py +++ b/pilot/server/component_configs.py @@ -31,6 +31,7 @@ def initialize_components( # Register global default RAGGraphFactory from pilot.graph_engine.graph_factory import DefaultRAGGraphFactory + system_app.register(DefaultRAGGraphFactory) _initialize_embedding_model( diff --git a/pilot/server/knowledge/api.py b/pilot/server/knowledge/api.py index 57fadb21e..e0f31031e 100644 --- a/pilot/server/knowledge/api.py +++ b/pilot/server/knowledge/api.py @@ -24,6 +24,7 @@ from pilot.server.knowledge.request.request import ( ChunkQueryRequest, DocumentQueryRequest, SpaceArgumentRequest, + EntityExtractRequest, ) from pilot.server.knowledge.request.request import KnowledgeSpaceRequest @@ -198,3 +199,37 @@ def similar_query(space_name: str, query_request: KnowledgeQueryRequest): for d in docs ] return {"response": res} + + +@router.post("/knowledge/entity/extract") +async def entity_extract(request: EntityExtractRequest): + logger.info(f"Received params: {request}") + try: + # from pilot.graph_engine.graph_factory import RAGGraphFactory + # from pilot.component import ComponentType + # rag_engine = CFG.SYSTEM_APP.get_component( + # ComponentType.RAG_GRAPH_DEFAULT.value, RAGGraphFactory + # ).create() + # return Result.succ(await rag_engine.search(request.text)) + from pilot.scene.base import ChatScene + from pilot.common.chat_util import llm_chat_response_nostream + import uuid + + chat_param = { + "chat_session_id": uuid.uuid1(), + "current_user_input": request.text, + "select_param": "entity", + "model_name": request.model_name, + } + + # import nest_asyncio + # nest_asyncio.apply() + # loop = asyncio.get_event_loop() + # loop.stop() + # loop = utils.get_or_create_event_loop() + res = await llm_chat_response_nostream( + ChatScene.ExtractEntity.value(), **{"chat_param": chat_param} + ) + return Result.succ(res) + except Exception as e: + return Result.faild(code="E000X", msg=f"entity extract error {e}") diff --git a/pilot/server/knowledge/request/request.py b/pilot/server/knowledge/request/request.py index b83165c19..c6b94ff0d 100644 --- a/pilot/server/knowledge/request/request.py +++ b/pilot/server/knowledge/request/request.py @@ -104,3 +104,10 @@ class SpaceArgumentRequest(BaseModel): """argument: argument""" argument: str + + +class EntityExtractRequest(BaseModel): + """argument: argument""" + + text: str + model_name: str diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index c11fc3b46..f4150fa73 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -58,7 +58,11 @@ class SyncStatus(Enum): # @singleton class KnowledgeService: def __init__(self): - pass + from pilot.graph_engine.graph_engine import RAGGraphEngine + + # source = "/Users/chenketing/Desktop/project/llama_index/examples/paul_graham_essay/data/test/test_kg_text.txt" + + # pass """create knowledge space""" @@ -229,6 +233,10 @@ class KnowledgeService: pre_separator=sync_request.pre_separator, text_splitter_impl=text_splitter, ) + from pilot.graph_engine.graph_engine import RAGGraphEngine + + # source = "/Users/chenketing/Desktop/project/llama_index/examples/paul_graham_essay/data/test/test_kg_text.txt" + # engine = RAGGraphEngine(knowledge_source=source, model_name="proxyllm", text_splitter=text_splitter) embedding_factory = CFG.SYSTEM_APP.get_component( "embedding_factory", EmbeddingFactory ) @@ -244,6 +252,18 @@ class KnowledgeService: embedding_factory=embedding_factory, ) chunk_docs = client.read() + from pilot.graph_engine.graph_factory import RAGGraphFactory + + rag_engine = CFG.SYSTEM_APP.get_component( + ComponentType.RAG_GRAPH_DEFAULT.value, RAGGraphFactory + ).create() + rag_engine.knowledge_graph(docs=chunk_docs) + # docs = engine.search( + # "Comparing Curry and James in terms of their positions, playing styles, and achievements in the NBA" + # ) + embedding_factory = CFG.SYSTEM_APP.get_component( + "embedding_factory", EmbeddingFactory + ) # update document status doc.status = SyncStatus.RUNNING.name doc.chunk_size = len(chunk_docs) From 2f82f98e315d81129987c28196fd66e62a75f56b Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Fri, 13 Oct 2023 17:13:51 +0800 Subject: [PATCH 04/57] feat:knowledge rag graph --- pilot/common/chat_util.py | 20 + pilot/graph_engine/__init__.py | 0 pilot/graph_engine/graph_engine.py | 137 +++++ pilot/graph_engine/graph_factory.py | 34 ++ pilot/graph_engine/graph_search.py | 193 ++++++ pilot/graph_engine/index_struct.py | 259 ++++++++ pilot/graph_engine/index_type.py | 48 ++ pilot/graph_engine/kv_index.py | 74 +++ pilot/graph_engine/node.py | 569 ++++++++++++++++++ pilot/graph_engine/search.py | 44 ++ .../chat_knowledge/extract_entity/__init__.py | 0 .../chat_knowledge/extract_entity/chat.py | 35 ++ .../extract_entity/out_parser.py | 39 ++ .../chat_knowledge/extract_entity/prompt.py | 52 ++ .../extract_triplet/__init__.py | 0 .../chat_knowledge/extract_triplet/chat.py | 35 ++ .../extract_triplet/out_parser.py | 57 ++ .../chat_knowledge/extract_triplet/prompt.py | 57 ++ pilot/scene/chat_knowledge/v1/chat.py | 20 +- pilot/server/knowledge/api.py | 11 - 20 files changed, 1654 insertions(+), 30 deletions(-) create mode 100644 pilot/common/chat_util.py create mode 100644 pilot/graph_engine/__init__.py create mode 100644 pilot/graph_engine/graph_engine.py create mode 100644 pilot/graph_engine/graph_factory.py create mode 100644 pilot/graph_engine/graph_search.py create mode 100644 pilot/graph_engine/index_struct.py create mode 100644 pilot/graph_engine/index_type.py create mode 100644 pilot/graph_engine/kv_index.py create mode 100644 pilot/graph_engine/node.py create mode 100644 pilot/graph_engine/search.py create mode 100644 pilot/scene/chat_knowledge/extract_entity/__init__.py create mode 100644 pilot/scene/chat_knowledge/extract_entity/chat.py create mode 100644 pilot/scene/chat_knowledge/extract_entity/out_parser.py create mode 100644 pilot/scene/chat_knowledge/extract_entity/prompt.py create mode 100644 pilot/scene/chat_knowledge/extract_triplet/__init__.py create mode 100644 pilot/scene/chat_knowledge/extract_triplet/chat.py create mode 100644 pilot/scene/chat_knowledge/extract_triplet/out_parser.py create mode 100644 pilot/scene/chat_knowledge/extract_triplet/prompt.py diff --git a/pilot/common/chat_util.py b/pilot/common/chat_util.py new file mode 100644 index 000000000..159db99d0 --- /dev/null +++ b/pilot/common/chat_util.py @@ -0,0 +1,20 @@ +import asyncio + +from starlette.responses import StreamingResponse + +from pilot.scene.base_chat import BaseChat +from pilot.scene.chat_factory import ChatFactory + +chat_factory = ChatFactory() + + +async def llm_chat_response_nostream(chat_scene: str, **chat_param): + """ llm_chat_response_nostream """ + chat: BaseChat = chat_factory.get_implementation(chat_scene, **chat_param) + res = await chat.get_llm_response() + return res + + +async def llm_chat_response(chat_scene: str, **chat_param): + chat: BaseChat = chat_factory.get_implementation(chat_scene, **chat_param) + return chat.stream_call() diff --git a/pilot/graph_engine/__init__.py b/pilot/graph_engine/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pilot/graph_engine/graph_engine.py b/pilot/graph_engine/graph_engine.py new file mode 100644 index 000000000..c20142123 --- /dev/null +++ b/pilot/graph_engine/graph_engine.py @@ -0,0 +1,137 @@ +import logging +from typing import Any, Optional, Callable, Tuple, List + +from langchain.schema import Document +from langchain.text_splitter import RecursiveCharacterTextSplitter + +from pilot.embedding_engine import KnowledgeType +from pilot.embedding_engine.knowledge_type import get_knowledge_embedding +from pilot.graph_engine.index_struct import KG +from pilot.graph_engine.node import TextNode +from pilot.utils import utils + +logger = logging.getLogger(__name__) + + +class RAGGraphEngine: + """Knowledge RAG Graph Engine. + Build a KG by extracting triplets, and leveraging the KG during query-time. + Args: + knowledge_type (Optional[str]): Default: KnowledgeType.DOCUMENT.value + extracting triplets. + graph_store (Optional[GraphStore]): The graph store to use.refrence:llama-index + include_embeddings (bool): Whether to include embeddings in the index. + Defaults to False. + max_object_length (int): The maximum length of the object in a triplet. + Defaults to 128. + extract_triplet_fn (Optional[Callable]): The function to use for + extracting triplets. Defaults to None. + """ + + index_struct_cls = KG + + def __init__( + self, + knowledge_type: Optional[str] = KnowledgeType.DOCUMENT.value, + knowledge_source: Optional[str] = None, + text_splitter=None, + graph_store=None, + index_struct: Optional[KG] = None, + model_name: Optional[str] = None, + max_triplets_per_chunk: int = 10, + include_embeddings: bool = False, + max_object_length: int = 128, + extract_triplet_fn: Optional[Callable] = None, + **kwargs: Any, + ) -> None: + """Initialize params.""" + # from llama_index.graph_stores import SimpleGraphStore + # from llama_index.graph_stores.types import GraphStore + + # need to set parameters before building index in base class. + self.knowledge_source = knowledge_source + self.knowledge_type = knowledge_type + self.model_name = model_name + self.text_splitter = text_splitter + self.index_struct = index_struct + self.include_embeddings = include_embeddings + # self.graph_store = graph_store or SimpleGraphStore() + self.graph_store = graph_store + self.max_triplets_per_chunk = max_triplets_per_chunk + self._max_object_length = max_object_length + self._extract_triplet_fn = extract_triplet_fn + + def knowledge_graph(self, docs=None): + """knowledge docs into graph store""" + if not docs: + if self.text_splitter: + self.text_splitter = RecursiveCharacterTextSplitter( + chunk_size=2000, chunk_overlap=100 + ) + knowledge_source = get_knowledge_embedding( + knowledge_type=self.knowledge_type, + knowledge_source=self.knowledge_source, + text_splitter=self.text_splitter, + ) + docs = knowledge_source.read() + if self.index_struct is None: + self.index_struct = self._build_index_from_docs(docs) + + def _extract_triplets(self, text: str) -> List[Tuple[str, str, str]]: + """Extract triplets from text by function or llm""" + if self._extract_triplet_fn is not None: + return self._extract_triplet_fn(text) + else: + return self._llm_extract_triplets(text) + + def _llm_extract_triplets(self, text: str) -> List[Tuple[str, str, str]]: + """Extract triplets from text by llm""" + from pilot.scene.base import ChatScene + from pilot.common.chat_util import llm_chat_response_nostream + import uuid + + chat_param = { + "chat_session_id": uuid.uuid1(), + "current_user_input": text, + "select_param": "triplet", + "model_name": self.model_name, + } + loop = utils.get_or_create_event_loop() + triplets = loop.run_until_complete( + llm_chat_response_nostream( + ChatScene.ExtractTriplet.value(), **{"chat_param": chat_param} + ) + ) + return triplets + # response = self._service_context.llm_predictor.predict( + # self.kg_triple_extract_template, + # text=text, + # ) + # print(response, flush=True) + # return self._parse_triplet_response( + # response, max_length=self._max_object_length + # ) + + def _build_index_from_docs(self, documents: List[Document]) -> KG: + """Build the index from nodes.""" + index_struct = self.index_struct_cls() + for doc in documents: + triplets = self._extract_triplets(doc.page_content) + if len(triplets) == 0: + continue + text_node = TextNode(text=doc.page_content, metadata=doc.metadata) + logger.info(f"extracted knowledge triplets: {triplets}") + for triplet in triplets: + subj, _, obj = triplet + self.graph_store.upsert_triplet(*triplet) + index_struct.add_node([subj, obj], text_node) + + + return index_struct + + def search(self, query): + from pilot.graph_engine.graph_search import RAGGraphSearch + + graph_search = RAGGraphSearch(graph_engine=self) + return graph_search.search(query) + diff --git a/pilot/graph_engine/graph_factory.py b/pilot/graph_engine/graph_factory.py new file mode 100644 index 000000000..3a8b99c17 --- /dev/null +++ b/pilot/graph_engine/graph_factory.py @@ -0,0 +1,34 @@ +from __future__ import annotations +from abc import ABC, abstractmethod +from typing import Any, Type + +from pilot.component import BaseComponent, ComponentType + + +class RAGGraphFactory(BaseComponent, ABC): + name = ComponentType.RAG_GRAPH_DEFAULT.value + + @abstractmethod + def create(self, model_name: str = None, embedding_cls: Type = None): + """Create RAG Graph Engine""" + + +class DefaultRAGGraphFactory(RAGGraphFactory): + def __init__( + self, system_app=None, default_model_name: str = None, **kwargs: Any + ) -> None: + super().__init__(system_app=system_app) + self._default_model_name = default_model_name + self.kwargs = kwargs + from pilot.graph_engine.graph_engine import RAGGraphEngine + + self.rag_engine = RAGGraphEngine(model_name="proxyllm") + + def init_app(self, system_app): + pass + + def create(self, model_name: str = None, rag_cls: Type = None): + if not model_name: + model_name = self._default_model_name + + return self.rag_engine diff --git a/pilot/graph_engine/graph_search.py b/pilot/graph_engine/graph_search.py new file mode 100644 index 000000000..9b06fd234 --- /dev/null +++ b/pilot/graph_engine/graph_search.py @@ -0,0 +1,193 @@ +import logging +import os +from collections import defaultdict +from concurrent.futures import ThreadPoolExecutor +from typing import List, Optional, Dict, Any, Set, Callable + +from pilot.graph_engine.node import BaseNode, TextNode, NodeWithScore +from pilot.graph_engine.search import BaseSearch, SearchMode +from pilot.utils import utils + +logger = logging.getLogger(__name__) +DEFAULT_NODE_SCORE = 1000.0 +GLOBAL_EXPLORE_NODE_LIMIT = 3 +REL_TEXT_LIMIT = 30 + + +class RAGGraphSearch(BaseSearch): + """RAG Graph Search. + + args: + graph_engine RAGGraphEngine. + model_name (str): model name + (see :ref:`Prompt-Templates`). + text_qa_template (Optional[BasePromptTemplate]): A Question Answering Prompt + (see :ref:`Prompt-Templates`). + max_keywords_per_query (int): Maximum number of keywords to extract from query. + num_chunks_per_query (int): Maximum number of text chunks to query. + search_mode (Optional[SearchMode]): Specifies whether to use keyowrds, default SearchMode.KEYWORD + embeddings, or both to find relevant triplets. Should be one of "keyword", + "embedding", or "hybrid". + graph_store_query_depth (int): The depth of the graph store query. + extract_subject_entities_fn (Optional[Callback]): extract_subject_entities callback. + """ + + def __init__( + self, + graph_engine, + model_name: str = None, + max_keywords_per_query: int = 10, + num_chunks_per_query: int = 10, + search_mode: Optional[SearchMode] = SearchMode.KEYWORD, + graph_store_query_depth: int = 2, + extract_subject_entities_fn: Optional[Callable] = None, + **kwargs: Any, + ) -> None: + """Initialize params.""" + from pilot.graph_engine.graph_engine import RAGGraphEngine + + self.graph_engine: RAGGraphEngine = graph_engine + self.model_name = model_name or self.graph_engine.model_name + self._index_struct = self.graph_engine.index_struct + self.max_keywords_per_query = max_keywords_per_query + self.num_chunks_per_query = num_chunks_per_query + self._search_mode = search_mode + + self._graph_store = self.graph_engine.graph_store + self.graph_store_query_depth = graph_store_query_depth + self._verbose = kwargs.get("verbose", False) + refresh_schema = kwargs.get("refresh_schema", False) + self.extract_subject_entities_fn = extract_subject_entities_fn + self.executor = ThreadPoolExecutor(max_workers=os.cpu_count() * 5) + try: + self._graph_schema = self._graph_store.get_schema(refresh=refresh_schema) + except NotImplementedError: + self._graph_schema = "" + except Exception as e: + logger.warn(f"can not to find graph schema: {e}") + self._graph_schema = "" + + def _extract_subject_entities(self, query_str: str) -> Set[str]: + """extract subject entities.""" + if self.extract_subject_entities_fn is not None: + return self.extract_subject_entities_fn(query_str) + else: + return self._extract_entities_by_llm(query_str) + + def _extract_entities_by_llm(self, text: str) -> Set[str]: + """extract subject entities from text by llm""" + from pilot.scene.base import ChatScene + from pilot.common.chat_util import llm_chat_response_nostream + import uuid + + chat_param = { + "chat_session_id": uuid.uuid1(), + "current_user_input": text, + "select_param": "entity", + "model_name": self.model_name, + } + loop = utils.get_or_create_event_loop() + entities = loop.run_until_complete( + llm_chat_response_nostream( + ChatScene.ExtractEntity.value(), **{"chat_param": chat_param} + ) + ) + return entities + + def _search( + self, + query_str: str, + ) -> List[NodeWithScore]: + """Get nodes for response.""" + node_visited = set() + keywords = self._extract_subject_entities(query_str) + print(f"extract entities: {keywords}\n") + rel_texts = [] + cur_rel_map = {} + chunk_indices_count: Dict[str, int] = defaultdict(int) + if self._search_mode != SearchMode.EMBEDDING: + for keyword in keywords: + keyword = keyword.lower() + subjs = set((keyword,)) + node_ids = self._index_struct.search_node_by_keyword(keyword) + for node_id in node_ids[:GLOBAL_EXPLORE_NODE_LIMIT]: + if node_id in node_visited: + continue + + if self._include_text: + chunk_indices_count[node_id] += 1 + + node_visited.add(node_id) + + rel_map = self._graph_store.get_rel_map( + list(subjs), self.graph_store_query_depth + ) + logger.debug(f"rel_map: {rel_map}") + + if not rel_map: + continue + rel_texts.extend( + [ + str(rel_obj) + for rel_objs in rel_map.values() + for rel_obj in rel_objs + ] + ) + cur_rel_map.update(rel_map) + + sorted_nodes_with_scores = [] + if not rel_texts: + logger.info("> No relationships found, returning nodes found by keywords.") + if len(sorted_nodes_with_scores) == 0: + logger.info("> No nodes found by keywords, returning empty response.") + return [ + NodeWithScore(node=TextNode(text="No relationships found."), score=1.0) + ] + + # add relationships as Node + # TODO: make initial text customizable + rel_initial_text = ( + f"The following are knowledge sequence in max depth" + f" {self.graph_store_query_depth} " + f"in the form of directed graph like:\n" + f"`subject -[predicate]->, object, <-[predicate_next_hop]-," + f" object_next_hop ...`" + ) + rel_info = [rel_initial_text] + rel_texts + rel_node_info = { + "kg_rel_texts": rel_texts, + "kg_rel_map": cur_rel_map, + } + if self._graph_schema != "": + rel_node_info["kg_schema"] = {"schema": self._graph_schema} + rel_info_text = "\n".join( + [ + str(item) + for sublist in rel_info + for item in (sublist if isinstance(sublist, list) else [sublist]) + ] + ) + if self._verbose: + print(f"KG context:\n{rel_info_text}\n", color="blue") + rel_text_node = TextNode( + text=rel_info_text, + metadata=rel_node_info, + excluded_embed_metadata_keys=["kg_rel_map", "kg_rel_texts"], + excluded_llm_metadata_keys=["kg_rel_map", "kg_rel_texts"], + ) + # this node is constructed from rel_texts, give high confidence to avoid cutoff + sorted_nodes_with_scores.append( + NodeWithScore(node=rel_text_node, score=DEFAULT_NODE_SCORE) + ) + + return sorted_nodes_with_scores + + def _get_metadata_for_response( + self, nodes: List[BaseNode] + ) -> Optional[Dict[str, Any]]: + """Get metadata for response.""" + for node in nodes: + if node.metadata is None or "kg_rel_map" not in node.metadata: + continue + return node.metadata + raise ValueError("kg_rel_map must be found in at least one Node.") \ No newline at end of file diff --git a/pilot/graph_engine/index_struct.py b/pilot/graph_engine/index_struct.py new file mode 100644 index 000000000..edc47a7ac --- /dev/null +++ b/pilot/graph_engine/index_struct.py @@ -0,0 +1,259 @@ +"""Data structures. + +Nodes are decoupled from the indices. + +""" + +import uuid +from abc import abstractmethod +from dataclasses import dataclass, field +from typing import Dict, List, Optional, Sequence, Set + +from dataclasses_json import DataClassJsonMixin + + +from pilot.graph_engine.index_type import IndexStructType +from pilot.graph_engine.node import TextNode, BaseNode + +# TODO: legacy backport of old Node class +Node = TextNode + + +@dataclass +class IndexStruct(DataClassJsonMixin): + """A base data struct for a LlamaIndex.""" + + index_id: str = field(default_factory=lambda: str(uuid.uuid4())) + summary: Optional[str] = None + + def get_summary(self) -> str: + """Get text summary.""" + if self.summary is None: + raise ValueError("summary field of the index_struct not set.") + return self.summary + + @classmethod + @abstractmethod + def get_type(cls): + """Get index struct type.""" + + +@dataclass +class IndexGraph(IndexStruct): + """A graph representing the tree-structured index.""" + + # mapping from index in tree to Node doc id. + all_nodes: Dict[int, str] = field(default_factory=dict) + root_nodes: Dict[int, str] = field(default_factory=dict) + node_id_to_children_ids: Dict[str, List[str]] = field(default_factory=dict) + + @property + def node_id_to_index(self) -> Dict[str, int]: + """Map from node id to index.""" + return {node_id: index for index, node_id in self.all_nodes.items()} + + @property + def size(self) -> int: + """Get the size of the graph.""" + return len(self.all_nodes) + + def get_index(self, node: BaseNode) -> int: + """Get index of node.""" + return self.node_id_to_index[node.node_id] + + def insert( + self, + node: BaseNode, + index: Optional[int] = None, + children_nodes: Optional[Sequence[BaseNode]] = None, + ) -> None: + """Insert node.""" + index = index or self.size + node_id = node.node_id + + self.all_nodes[index] = node_id + + if children_nodes is None: + children_nodes = [] + children_ids = [n.node_id for n in children_nodes] + self.node_id_to_children_ids[node_id] = children_ids + + def get_children(self, parent_node: Optional[BaseNode]) -> Dict[int, str]: + """Get children nodes.""" + if parent_node is None: + return self.root_nodes + else: + parent_id = parent_node.node_id + children_ids = self.node_id_to_children_ids[parent_id] + return { + self.node_id_to_index[child_id]: child_id for child_id in children_ids + } + + def insert_under_parent( + self, + node: BaseNode, + parent_node: Optional[BaseNode], + new_index: Optional[int] = None, + ) -> None: + """Insert under parent node.""" + new_index = new_index or self.size + if parent_node is None: + self.root_nodes[new_index] = node.node_id + self.node_id_to_children_ids[node.node_id] = [] + else: + if parent_node.node_id not in self.node_id_to_children_ids: + self.node_id_to_children_ids[parent_node.node_id] = [] + self.node_id_to_children_ids[parent_node.node_id].append(node.node_id) + + self.all_nodes[new_index] = node.node_id + + @classmethod + def get_type(cls) -> IndexStructType: + """Get type.""" + return IndexStructType.TREE + + +@dataclass +class KeywordTable(IndexStruct): + """A table of keywords mapping keywords to text chunks.""" + + table: Dict[str, Set[str]] = field(default_factory=dict) + + def add_node(self, keywords: List[str], node: BaseNode) -> None: + """Add text to table.""" + for keyword in keywords: + if keyword not in self.table: + self.table[keyword] = set() + self.table[keyword].add(node.node_id) + + @property + def node_ids(self) -> Set[str]: + """Get all node ids.""" + return set.union(*self.table.values()) + + @property + def keywords(self) -> Set[str]: + """Get all keywords in the table.""" + return set(self.table.keys()) + + @property + def size(self) -> int: + """Get the size of the table.""" + return len(self.table) + + @classmethod + def get_type(cls) -> IndexStructType: + """Get type.""" + return IndexStructType.KEYWORD_TABLE + + +@dataclass +class IndexList(IndexStruct): + """A list of documents.""" + + nodes: List[str] = field(default_factory=list) + + def add_node(self, node: BaseNode) -> None: + """Add text to table, return current position in list.""" + # don't worry about child indices for now, nodes are all in order + self.nodes.append(node.node_id) + + @classmethod + def get_type(cls) -> IndexStructType: + """Get type.""" + return IndexStructType.LIST + + +@dataclass +class IndexDict(IndexStruct): + """A simple dictionary of documents.""" + + # TODO: slightly deprecated, should likely be a list or set now + # mapping from vector store id to node doc_id + nodes_dict: Dict[str, str] = field(default_factory=dict) + + # TODO: deprecated, not used + # mapping from node doc_id to vector store id + doc_id_dict: Dict[str, List[str]] = field(default_factory=dict) + + # TODO: deprecated, not used + # this should be empty for all other indices + embeddings_dict: Dict[str, List[float]] = field(default_factory=dict) + + def add_node( + self, + node: BaseNode, + text_id: Optional[str] = None, + ) -> str: + """Add text to table, return current position in list.""" + # # don't worry about child indices for now, nodes are all in order + # self.nodes_dict[int_id] = node + vector_id = text_id if text_id is not None else node.node_id + self.nodes_dict[vector_id] = node.node_id + + return vector_id + + def delete(self, doc_id: str) -> None: + """Delete a Node.""" + del self.nodes_dict[doc_id] + + @classmethod + def get_type(cls) -> IndexStructType: + """Get type.""" + return IndexStructType.VECTOR_STORE + + +@dataclass +class KG(IndexStruct): + """A table of keywords mapping keywords to text chunks.""" + + # Unidirectional + + # table of keywords to node ids + table: Dict[str, Set[str]] = field(default_factory=dict) + + # TODO: legacy attribute, remove in future releases + rel_map: Dict[str, List[List[str]]] = field(default_factory=dict) + + # TBD, should support vector store, now we just persist the embedding memory + # maybe chainable abstractions for *_stores could be designed + embedding_dict: Dict[str, List[float]] = field(default_factory=dict) + + @property + def node_ids(self) -> Set[str]: + """Get all node ids.""" + return set.union(*self.table.values()) + + def add_to_embedding_dict(self, triplet_str: str, embedding: List[float]) -> None: + """Add embedding to dict.""" + self.embedding_dict[triplet_str] = embedding + + def add_node(self, keywords: List[str], node: BaseNode) -> None: + """Add text to table.""" + node_id = node.node_id + for keyword in keywords: + keyword = keyword.lower() + if keyword not in self.table: + self.table[keyword] = set() + self.table[keyword].add(node_id) + + def search_node_by_keyword(self, keyword: str) -> List[str]: + """Search for nodes by keyword.""" + if keyword not in self.table: + return [] + return list(self.table[keyword]) + + @classmethod + def get_type(cls) -> IndexStructType: + """Get type.""" + return IndexStructType.KG + + +@dataclass +class EmptyIndexStruct(IndexStruct): + """Empty index.""" + + @classmethod + def get_type(cls) -> IndexStructType: + """Get type.""" + return IndexStructType.EMPTY diff --git a/pilot/graph_engine/index_type.py b/pilot/graph_engine/index_type.py new file mode 100644 index 000000000..939066be9 --- /dev/null +++ b/pilot/graph_engine/index_type.py @@ -0,0 +1,48 @@ +"""IndexStructType class.""" + +from enum import Enum + + +class IndexStructType(str, Enum): + """Index struct type. Identifier for a "type" of index. + + Attributes: + TREE ("tree"): Tree index. See :ref:`Ref-Indices-Tree` for tree indices. + LIST ("list"): Summary index. See :ref:`Ref-Indices-List` for summary indices. + KEYWORD_TABLE ("keyword_table"): Keyword table index. See + :ref:`Ref-Indices-Table` + for keyword table indices. + DICT ("dict"): Faiss Vector Store Index. See + :ref:`Ref-Indices-VectorStore` + for more information on the faiss vector store index. + SIMPLE_DICT ("simple_dict"): Simple Vector Store Index. See + :ref:`Ref-Indices-VectorStore` + for more information on the simple vector store index. + KG ("kg"): Knowledge Graph index. + See :ref:`Ref-Indices-Knowledge-Graph` for KG indices. + DOCUMENT_SUMMARY ("document_summary"): Document Summary Index. + See :ref:`Ref-Indices-Document-Summary` for Summary Indices. + + """ + + # TODO: refactor so these are properties on the base class + + NODE = "node" + TREE = "tree" + LIST = "list" + KEYWORD_TABLE = "keyword_table" + + DICT = "dict" + # simple + SIMPLE_DICT = "simple_dict" + # for KG index + KG = "kg" + SIMPLE_KG = "simple_kg" + NEBULAGRAPH = "nebulagraph" + FALKORDB = "falkordb" + + # EMPTY + EMPTY = "empty" + COMPOSITE = "composite" + + DOCUMENT_SUMMARY = "document_summary" diff --git a/pilot/graph_engine/kv_index.py b/pilot/graph_engine/kv_index.py new file mode 100644 index 000000000..7b44b7d04 --- /dev/null +++ b/pilot/graph_engine/kv_index.py @@ -0,0 +1,74 @@ +from typing import List, Optional +from llama_index.data_structs.data_structs import IndexStruct +from llama_index.storage.index_store.utils import ( + index_struct_to_json, + json_to_index_struct, +) +from llama_index.storage.kvstore.types import BaseKVStore + +DEFAULT_NAMESPACE = "index_store" + + +class KVIndexStore: + """Key-Value Index store. + + Args: + kvstore (BaseKVStore): key-value store + namespace (str): namespace for the index store + + """ + + def __init__(self, kvstore: BaseKVStore, namespace: Optional[str] = None) -> None: + """Init a KVIndexStore.""" + self._kvstore = kvstore + self._namespace = namespace or DEFAULT_NAMESPACE + self._collection = f"{self._namespace}/data" + + def add_index_struct(self, index_struct: IndexStruct) -> None: + """Add an index struct. + + Args: + index_struct (IndexStruct): index struct + + """ + key = index_struct.index_id + data = index_struct_to_json(index_struct) + self._kvstore.put(key, data, collection=self._collection) + + def delete_index_struct(self, key: str) -> None: + """Delete an index struct. + + Args: + key (str): index struct key + + """ + self._kvstore.delete(key, collection=self._collection) + + def get_index_struct( + self, struct_id: Optional[str] = None + ) -> Optional[IndexStruct]: + """Get an index struct. + + Args: + struct_id (Optional[str]): index struct id + + """ + if struct_id is None: + structs = self.index_structs() + assert len(structs) == 1 + return structs[0] + else: + json = self._kvstore.get(struct_id, collection=self._collection) + if json is None: + return None + return json_to_index_struct(json) + + def index_structs(self) -> List[IndexStruct]: + """Get all index structs. + + Returns: + List[IndexStruct]: index structs + + """ + jsons = self._kvstore.get_all(collection=self._collection) + return [json_to_index_struct(json) for json in jsons.values()] diff --git a/pilot/graph_engine/node.py b/pilot/graph_engine/node.py new file mode 100644 index 000000000..6f6d45ae4 --- /dev/null +++ b/pilot/graph_engine/node.py @@ -0,0 +1,569 @@ +"""Base schema for data structures.""" +import json +import textwrap +import uuid +from abc import abstractmethod +from enum import Enum, auto +from hashlib import sha256 +from typing import Any, Dict, List, Optional, Union + +from langchain.schema import Document +from pydantic import BaseModel, Field, root_validator +from typing_extensions import Self + + +DEFAULT_TEXT_NODE_TMPL = "{metadata_str}\n\n{content}" +DEFAULT_METADATA_TMPL = "{key}: {value}" +# NOTE: for pretty printing +TRUNCATE_LENGTH = 350 +WRAP_WIDTH = 70 + + +class BaseComponent(BaseModel): + """Base component object to caputure class names.""" + """reference llama-index""" + + @classmethod + @abstractmethod + def class_name(cls) -> str: + """Get class name.""" + + def to_dict(self, **kwargs: Any) -> Dict[str, Any]: + data = self.dict(**kwargs) + data["class_name"] = self.class_name() + return data + + def to_json(self, **kwargs: Any) -> str: + data = self.to_dict(**kwargs) + return json.dumps(data) + + # TODO: return type here not supported by current mypy version + @classmethod + def from_dict(cls, data: Dict[str, Any], **kwargs: Any) -> Self: # type: ignore + if isinstance(kwargs, dict): + data.update(kwargs) + + data.pop("class_name", None) + return cls(**data) + + @classmethod + def from_json(cls, data_str: str, **kwargs: Any) -> Self: # type: ignore + data = json.loads(data_str) + return cls.from_dict(data, **kwargs) + + +class NodeRelationship(str, Enum): + """Node relationships used in `BaseNode` class. + + Attributes: + SOURCE: The node is the source document. + PREVIOUS: The node is the previous node in the document. + NEXT: The node is the next node in the document. + PARENT: The node is the parent node in the document. + CHILD: The node is a child node in the document. + + """ + + SOURCE = auto() + PREVIOUS = auto() + NEXT = auto() + PARENT = auto() + CHILD = auto() + + +class ObjectType(str, Enum): + TEXT = auto() + IMAGE = auto() + INDEX = auto() + DOCUMENT = auto() + + +class MetadataMode(str, Enum): + ALL = auto() + EMBED = auto() + LLM = auto() + NONE = auto() + + +class RelatedNodeInfo(BaseComponent): + node_id: str + node_type: Optional[ObjectType] = None + metadata: Dict[str, Any] = Field(default_factory=dict) + hash: Optional[str] = None + + @classmethod + def class_name(cls) -> str: + """Get class name.""" + return "RelatedNodeInfo" + + +RelatedNodeType = Union[RelatedNodeInfo, List[RelatedNodeInfo]] + + +# Node classes for indexes +class BaseNode(BaseComponent): + """Base node Object. + + Generic abstract interface for retrievable nodes + + """ + + class Config: + allow_population_by_field_name = True + + id_: str = Field( + default_factory=lambda: str(uuid.uuid4()), description="Unique ID of the node." + ) + embedding: Optional[List[float]] = Field( + default=None, description="Embedding of the node." + ) + + """" + metadata fields + - injected as part of the text shown to LLMs as context + - injected as part of the text for generating embeddings + - used by vector DBs for metadata filtering + + """ + metadata: Dict[str, Any] = Field( + default_factory=dict, + description="A flat dictionary of metadata fields", + alias="extra_info", + ) + excluded_embed_metadata_keys: List[str] = Field( + default_factory=list, + description="Metadata keys that are exluded from text for the embed model.", + ) + excluded_llm_metadata_keys: List[str] = Field( + default_factory=list, + description="Metadata keys that are exluded from text for the LLM.", + ) + relationships: Dict[NodeRelationship, RelatedNodeType] = Field( + default_factory=dict, + description="A mapping of relationships to other node information.", + ) + hash: str = Field(default="", description="Hash of the node content.") + + @classmethod + @abstractmethod + def get_type(cls) -> str: + """Get Object type.""" + + @abstractmethod + def get_content(self, metadata_mode: MetadataMode = MetadataMode.ALL) -> str: + """Get object content.""" + + @abstractmethod + def get_metadata_str(self, mode: MetadataMode = MetadataMode.ALL) -> str: + """Metadata string.""" + + @abstractmethod + def set_content(self, value: Any) -> None: + """Set the content of the node.""" + + @property + def node_id(self) -> str: + return self.id_ + + @node_id.setter + def node_id(self, value: str) -> None: + self.id_ = value + + @property + def source_node(self) -> Optional[RelatedNodeInfo]: + """Source object node. + + Extracted from the relationships field. + + """ + if NodeRelationship.SOURCE not in self.relationships: + return None + + relation = self.relationships[NodeRelationship.SOURCE] + if isinstance(relation, list): + raise ValueError("Source object must be a single RelatedNodeInfo object") + return relation + + @property + def prev_node(self) -> Optional[RelatedNodeInfo]: + """Prev node.""" + if NodeRelationship.PREVIOUS not in self.relationships: + return None + + relation = self.relationships[NodeRelationship.PREVIOUS] + if not isinstance(relation, RelatedNodeInfo): + raise ValueError("Previous object must be a single RelatedNodeInfo object") + return relation + + @property + def next_node(self) -> Optional[RelatedNodeInfo]: + """Next node.""" + if NodeRelationship.NEXT not in self.relationships: + return None + + relation = self.relationships[NodeRelationship.NEXT] + if not isinstance(relation, RelatedNodeInfo): + raise ValueError("Next object must be a single RelatedNodeInfo object") + return relation + + @property + def parent_node(self) -> Optional[RelatedNodeInfo]: + """Parent node.""" + if NodeRelationship.PARENT not in self.relationships: + return None + + relation = self.relationships[NodeRelationship.PARENT] + if not isinstance(relation, RelatedNodeInfo): + raise ValueError("Parent object must be a single RelatedNodeInfo object") + return relation + + @property + def child_nodes(self) -> Optional[List[RelatedNodeInfo]]: + """Child nodes.""" + if NodeRelationship.CHILD not in self.relationships: + return None + + relation = self.relationships[NodeRelationship.CHILD] + if not isinstance(relation, list): + raise ValueError("Child objects must be a list of RelatedNodeInfo objects.") + return relation + + @property + def ref_doc_id(self) -> Optional[str]: + """Deprecated: Get ref doc id.""" + source_node = self.source_node + if source_node is None: + return None + return source_node.node_id + + @property + def extra_info(self) -> Dict[str, Any]: + """TODO: DEPRECATED: Extra info.""" + return self.metadata + + def __str__(self) -> str: + source_text_truncated = truncate_text( + self.get_content().strip(), TRUNCATE_LENGTH + ) + source_text_wrapped = textwrap.fill( + f"Text: {source_text_truncated}\n", width=WRAP_WIDTH + ) + return f"Node ID: {self.node_id}\n{source_text_wrapped}" + + def truncate_text(text: str, max_length: int) -> str: + """Truncate text to a maximum length.""" + if len(text) <= max_length: + return text + return text[: max_length - 3] + "..." + + def get_embedding(self) -> List[float]: + """Get embedding. + + Errors if embedding is None. + + """ + if self.embedding is None: + raise ValueError("embedding not set.") + return self.embedding + + def as_related_node_info(self) -> RelatedNodeInfo: + """Get node as RelatedNodeInfo.""" + return RelatedNodeInfo( + node_id=self.node_id, metadata=self.metadata, hash=self.hash + ) + + +class TextNode(BaseNode): + text: str = Field(default="", description="Text content of the node.") + start_char_idx: Optional[int] = Field( + default=None, description="Start char index of the node." + ) + end_char_idx: Optional[int] = Field( + default=None, description="End char index of the node." + ) + text_template: str = Field( + default=DEFAULT_TEXT_NODE_TMPL, + description=( + "Template for how text is formatted, with {content} and " + "{metadata_str} placeholders." + ), + ) + metadata_template: str = Field( + default=DEFAULT_METADATA_TMPL, + description=( + "Template for how metadata is formatted, with {key} and " + "{value} placeholders." + ), + ) + metadata_seperator: str = Field( + default="\n", + description="Seperator between metadata fields when converting to string.", + ) + + @classmethod + def class_name(cls) -> str: + """Get class name.""" + return "TextNode" + + @root_validator + def _check_hash(cls, values: dict) -> dict: + """Generate a hash to represent the node.""" + text = values.get("text", "") + metadata = values.get("metadata", {}) + doc_identity = str(text) + str(metadata) + values["hash"] = str( + sha256(doc_identity.encode("utf-8", "surrogatepass")).hexdigest() + ) + return values + + @classmethod + def get_type(cls) -> str: + """Get Object type.""" + return ObjectType.TEXT + + def get_content(self, metadata_mode: MetadataMode = MetadataMode.NONE) -> str: + """Get object content.""" + metadata_str = self.get_metadata_str(mode=metadata_mode).strip() + if not metadata_str: + return self.text + + return self.text_template.format( + content=self.text, metadata_str=metadata_str + ).strip() + + def get_metadata_str(self, mode: MetadataMode = MetadataMode.ALL) -> str: + """metadata info string.""" + if mode == MetadataMode.NONE: + return "" + + usable_metadata_keys = set(self.metadata.keys()) + if mode == MetadataMode.LLM: + for key in self.excluded_llm_metadata_keys: + if key in usable_metadata_keys: + usable_metadata_keys.remove(key) + elif mode == MetadataMode.EMBED: + for key in self.excluded_embed_metadata_keys: + if key in usable_metadata_keys: + usable_metadata_keys.remove(key) + + return self.metadata_seperator.join( + [ + self.metadata_template.format(key=key, value=str(value)) + for key, value in self.metadata.items() + if key in usable_metadata_keys + ] + ) + + def set_content(self, value: str) -> None: + """Set the content of the node.""" + self.text = value + + def get_node_info(self) -> Dict[str, Any]: + """Get node info.""" + return {"start": self.start_char_idx, "end": self.end_char_idx} + + def get_text(self) -> str: + return self.get_content(metadata_mode=MetadataMode.NONE) + + @property + def node_info(self) -> Dict[str, Any]: + """Deprecated: Get node info.""" + return self.get_node_info() + + +# TODO: legacy backport of old Node class +Node = TextNode + + +class ImageNode(TextNode): + """Node with image.""" + + # TODO: store reference instead of actual image + # base64 encoded image str + image: Optional[str] = None + + @classmethod + def get_type(cls) -> str: + return ObjectType.IMAGE + + @classmethod + def class_name(cls) -> str: + """Get class name.""" + return "ImageNode" + + +class IndexNode(TextNode): + """Node with reference to any object. + + This can include other indices, query engines, retrievers. + + This can also include other nodes (though this is overlapping with `relationships` + on the Node class). + + """ + + index_id: str + + @classmethod + def from_text_node( + cls, + node: TextNode, + index_id: str, + ) -> "IndexNode": + """Create index node from text node.""" + # copy all attributes from text node, add index id + return cls( + **node.dict(), + index_id=index_id, + ) + + @classmethod + def get_type(cls) -> str: + return ObjectType.INDEX + + @classmethod + def class_name(cls) -> str: + """Get class name.""" + return "IndexNode" + + +class NodeWithScore(BaseComponent): + node: BaseNode + score: Optional[float] = None + + def __str__(self) -> str: + return f"{self.node}\nScore: {self.score: 0.3f}\n" + + def get_score(self, raise_error: bool = False) -> float: + """Get score.""" + if self.score is None: + if raise_error: + raise ValueError("Score not set.") + else: + return 0.0 + else: + return self.score + + @classmethod + def class_name(cls) -> str: + """Get class name.""" + return "NodeWithScore" + + ##### pass through methods to BaseNode ##### + @property + def node_id(self) -> str: + return self.node.node_id + + @property + def id_(self) -> str: + return self.node.id_ + + @property + def text(self) -> str: + if isinstance(self.node, TextNode): + return self.node.text + else: + raise ValueError("Node must be a TextNode to get text.") + + @property + def metadata(self) -> Dict[str, Any]: + return self.node.metadata + + @property + def embedding(self) -> Optional[List[float]]: + return self.node.embedding + + def get_text(self) -> str: + if isinstance(self.node, TextNode): + return self.node.get_text() + else: + raise ValueError("Node must be a TextNode to get text.") + + def get_content(self, metadata_mode: MetadataMode = MetadataMode.NONE) -> str: + return self.node.get_content(metadata_mode=metadata_mode) + + def get_embedding(self) -> List[float]: + return self.node.get_embedding() + + +# Document Classes for Readers + + +class Document(TextNode): + """Generic interface for a data document. + + This document connects to data sources. + + """ + + # TODO: A lot of backwards compatibility logic here, clean up + id_: str = Field( + default_factory=lambda: str(uuid.uuid4()), + description="Unique ID of the node.", + alias="doc_id", + ) + + _compat_fields = {"doc_id": "id_", "extra_info": "metadata"} + + @classmethod + def get_type(cls) -> str: + """Get Document type.""" + return ObjectType.DOCUMENT + + @property + def doc_id(self) -> str: + """Get document ID.""" + return self.id_ + + def __str__(self) -> str: + source_text_truncated = truncate_text( + self.get_content().strip(), TRUNCATE_LENGTH + ) + source_text_wrapped = textwrap.fill( + f"Text: {source_text_truncated}\n", width=WRAP_WIDTH + ) + return f"Doc ID: {self.doc_id}\n{source_text_wrapped}" + + def get_doc_id(self) -> str: + """TODO: Deprecated: Get document ID.""" + return self.id_ + + def __setattr__(self, name: str, value: object) -> None: + if name in self._compat_fields: + name = self._compat_fields[name] + super().__setattr__(name, value) + + def to_langchain_format(self) -> Document: + """Convert struct to LangChain document format.""" + metadata = self.metadata or {} + return Document(page_content=self.text, metadata=metadata) + + @classmethod + def from_langchain_format(cls, doc: Document) -> "Document": + """Convert struct from LangChain document format.""" + return cls(text=doc.page_content, metadata=doc.metadata) + + @classmethod + def example(cls) -> "Document": + document = Document( + text="", + metadata={"filename": "README.md", "category": "codebase"}, + ) + return document + + @classmethod + def class_name(cls) -> str: + """Get class name.""" + return "Document" + + +class ImageDocument(Document): + """Data document containing an image.""" + + # base64 encoded image str + image: Optional[str] = None + + @classmethod + def class_name(cls) -> str: + """Get class name.""" + return "ImageDocument" diff --git a/pilot/graph_engine/search.py b/pilot/graph_engine/search.py new file mode 100644 index 000000000..8db837278 --- /dev/null +++ b/pilot/graph_engine/search.py @@ -0,0 +1,44 @@ +from abc import ABC, abstractmethod +from enum import Enum + + +class SearchMode(str, Enum): + """Query mode enum for Knowledge Graphs. + + Can be passed as the enum struct, or as the underlying string. + + Attributes: + KEYWORD ("keyword"): Default query mode, using keywords to find triplets. + EMBEDDING ("embedding"): Embedding mode, using embeddings to find + similar triplets. + HYBRID ("hybrid"): Hyrbid mode, combining both keywords and embeddings + to find relevant triplets. + """ + + KEYWORD = "keyword" + EMBEDDING = "embedding" + HYBRID = "hybrid" + + +class BaseSearch(ABC): + """Base Search.""" + + def search(self, query: str): + """Retrieve nodes given query. + + Args: + query (QueryType): Either a query string or + a QueryBundle object. + + """ + # if isinstance(query, str): + return self._search(query) + + @abstractmethod + def _search(self, query: str): + """search nodes given query. + + Implemented by the user. + + """ + pass diff --git a/pilot/scene/chat_knowledge/extract_entity/__init__.py b/pilot/scene/chat_knowledge/extract_entity/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pilot/scene/chat_knowledge/extract_entity/chat.py b/pilot/scene/chat_knowledge/extract_entity/chat.py new file mode 100644 index 000000000..bb52961b5 --- /dev/null +++ b/pilot/scene/chat_knowledge/extract_entity/chat.py @@ -0,0 +1,35 @@ +from typing import Dict + +from pilot.scene.base_chat import BaseChat +from pilot.scene.base import ChatScene +from pilot.configs.config import Config + +from pilot.scene.chat_knowledge.extract_entity.prompt import prompt + +CFG = Config() + + +class ExtractEntity(BaseChat): + chat_scene: str = ChatScene.ExtractEntity.value() + + """extracting entities by llm""" + + def __init__(self, chat_param: Dict): + """ """ + chat_param["chat_mode"] = ChatScene.ExtractEntity + super().__init__( + chat_param=chat_param, + ) + + self.user_input = chat_param["current_user_input"] + self.extract_mode = chat_param["select_param"] + + def generate_input_values(self): + input_values = { + "text": self.user_input, + } + return input_values + + @property + def chat_type(self) -> str: + return ChatScene.ExtractEntity.value diff --git a/pilot/scene/chat_knowledge/extract_entity/out_parser.py b/pilot/scene/chat_knowledge/extract_entity/out_parser.py new file mode 100644 index 000000000..4093e460f --- /dev/null +++ b/pilot/scene/chat_knowledge/extract_entity/out_parser.py @@ -0,0 +1,39 @@ +import json +import logging +from typing import Set + +from pilot.out_parser.base import BaseOutputParser, T +from pilot.configs.config import Config + +CFG = Config() + + +logger = logging.getLogger(__name__) + + +class ExtractEntityParser(BaseOutputParser): + def __init__(self, sep: str, is_stream_out: bool): + super().__init__(sep=sep, is_stream_out=is_stream_out) + + def parse_prompt_response(self, response, max_length: int = 128) -> Set[str]: + lowercase = True + # clean_str = super().parse_prompt_response(response) + print("clean prompt response:", response) + + results = [] + response = response.strip() # Strip newlines from responses. + + if response.startswith("KEYWORDS:"): + response = response[len("KEYWORDS:") :] + + keywords = response.split(",") + for k in keywords: + rk = k + if lowercase: + rk = rk.lower() + results.append(rk.strip()) + + return set(results) + + def parse_view_response(self, speak, data) -> str: + return data diff --git a/pilot/scene/chat_knowledge/extract_entity/prompt.py b/pilot/scene/chat_knowledge/extract_entity/prompt.py new file mode 100644 index 000000000..77349bd28 --- /dev/null +++ b/pilot/scene/chat_knowledge/extract_entity/prompt.py @@ -0,0 +1,52 @@ +import json + +from pilot.prompts.prompt_new import PromptTemplate +from pilot.configs.config import Config +from pilot.scene.base import ChatScene +from pilot.common.schema import SeparatorStyle +from pilot.scene.chat_knowledge.extract_entity.out_parser import ExtractEntityParser + +from pilot.scene.chat_knowledge.extract_triplet.out_parser import ( + ExtractTripleParser, +) + + +CFG = Config() + +PROMPT_SCENE_DEFINE = """""" + +_DEFAULT_TEMPLATE = """ +"A question is provided below. Given the question, extract up to 10 " + "keywords from the text. Focus on extracting the keywords that we can use " + "to best lookup answers to the question. Avoid stopwords.\n" + "Example:" + "Text: Alice is Bob's mother." + "KEYWORDS:Alice,mother,Bob\n" + "---------------------\n" + "{text}\n" + "---------------------\n" + "Provide keywords in the following comma-separated format: 'KEYWORDS: '\n" +""" +PROMPT_RESPONSE = """""" + + +RESPONSE_FORMAT = """""" + + +PROMPT_SEP = SeparatorStyle.SINGLE.value + +PROMPT_NEED_NEED_STREAM_OUT = False + +prompt = PromptTemplate( + template_scene=ChatScene.ExtractEntity.value(), + input_variables=["text"], + response_format="", + template_define=PROMPT_SCENE_DEFINE, + template=_DEFAULT_TEMPLATE + PROMPT_RESPONSE, + stream_out=PROMPT_NEED_NEED_STREAM_OUT, + output_parser=ExtractEntityParser( + sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_NEED_STREAM_OUT + ), +) + +CFG.prompt_template_registry.register(prompt, is_default=True) diff --git a/pilot/scene/chat_knowledge/extract_triplet/__init__.py b/pilot/scene/chat_knowledge/extract_triplet/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pilot/scene/chat_knowledge/extract_triplet/chat.py b/pilot/scene/chat_knowledge/extract_triplet/chat.py new file mode 100644 index 000000000..11fe871ab --- /dev/null +++ b/pilot/scene/chat_knowledge/extract_triplet/chat.py @@ -0,0 +1,35 @@ +from typing import Dict + +from pilot.scene.base_chat import BaseChat +from pilot.scene.base import ChatScene +from pilot.configs.config import Config + +from pilot.scene.chat_knowledge.extract_triplet.prompt import prompt + +CFG = Config() + + +class ExtractTriplet(BaseChat): + chat_scene: str = ChatScene.ExtractTriplet.value() + + """extracting triplets by llm""" + + def __init__(self, chat_param: Dict): + """ """ + chat_param["chat_mode"] = ChatScene.ExtractTriplet + super().__init__( + chat_param=chat_param, + ) + + self.user_input = chat_param["current_user_input"] + self.extract_mode = chat_param["select_param"] + + def generate_input_values(self): + input_values = { + "text": self.user_input, + } + return input_values + + @property + def chat_type(self) -> str: + return ChatScene.ExtractTriplet.value diff --git a/pilot/scene/chat_knowledge/extract_triplet/out_parser.py b/pilot/scene/chat_knowledge/extract_triplet/out_parser.py new file mode 100644 index 000000000..75606bd0f --- /dev/null +++ b/pilot/scene/chat_knowledge/extract_triplet/out_parser.py @@ -0,0 +1,57 @@ +import json +import logging +import re +from typing import List, Tuple + +from pilot.out_parser.base import BaseOutputParser, T +from pilot.configs.config import Config + +CFG = Config() + + +logger = logging.getLogger(__name__) + + +class ExtractTripleParser(BaseOutputParser): + def __init__(self, sep: str, is_stream_out: bool): + super().__init__(sep=sep, is_stream_out=is_stream_out) + + def parse_prompt_response( + self, response, max_length: int = 128 + ) -> List[Tuple[str, str, str]]: + # clean_str = super().parse_prompt_response(response) + print("clean prompt response:", response) + + if response.startswith("Triplets:"): + response = response[len("Triplets:") :] + pattern = r"\([^()]+\)" + response = re.findall(pattern, response) + # response = response.strip().split("\n") + print("parse prompt response:", response) + results = [] + for text in response: + if not text or text[0] != "(" or text[-1] != ")": + # skip empty lines and non-triplets + continue + tokens = text[1:-1].split(",") + if len(tokens) != 3: + continue + + if any(len(s.encode("utf-8")) > max_length for s in tokens): + # We count byte-length instead of len() for UTF-8 chars, + # will skip if any of the tokens are too long. + # This is normally due to a poorly formatted triplet + # extraction, in more serious KG building cases + # we'll need NLP models to better extract triplets. + continue + + subject, predicate, obj = map(str.strip, tokens) + if not subject or not predicate or not obj: + # skip partial triplets + continue + results.append((subject.lower(), predicate.lower(), obj.lower())) + return results + + def parse_view_response(self, speak, data) -> str: + ### tool out data to table view + return data diff --git a/pilot/scene/chat_knowledge/extract_triplet/prompt.py b/pilot/scene/chat_knowledge/extract_triplet/prompt.py new file mode 100644 index 000000000..dd391bce8 --- /dev/null +++ b/pilot/scene/chat_knowledge/extract_triplet/prompt.py @@ -0,0 +1,57 @@ +import json + +from pilot.prompts.prompt_new import PromptTemplate +from pilot.configs.config import Config +from pilot.scene.base import ChatScene +from pilot.common.schema import SeparatorStyle + +from pilot.scene.chat_knowledge.extract_triplet.out_parser import ( + ExtractTripleParser, +) + + +CFG = Config() + +PROMPT_SCENE_DEFINE = """""" + +_DEFAULT_TEMPLATE = """ +"Some text is provided below. Given the text, extract up to 10" + "knowledge triplets in the form of (subject, predicate, object). Avoid stopwords.\n" + "---------------------\n" + "Example:" + "Text: Alice is Bob's mother." + "Triplets:\n(Alice, is mother of, Bob)\n" + "Text: Philz is a coffee shop founded in Berkeley in 1982.\n" + "Triplets:\n" + "(Philz, is, coffee shop)\n" + "(Philz, founded in, Berkeley)\n" + "(Philz, founded in, 1982)\n" + "---------------------\n" + "Text: {text}\n" + "Triplets:\n" + ensure Respond in the following List(Tuple) format: + '(Stephen Curry, plays for, Golden State Warriors)\n(Stephen Curry, known for, shooting skills)\n(Stephen Curry, attended, Davidson College)\n(Stephen Curry, led, team to success)' +""" +PROMPT_RESPONSE = """""" + + +RESPONSE_FORMAT = """""" + + +PROMPT_SEP = SeparatorStyle.SINGLE.value + +PROMPT_NEED_NEED_STREAM_OUT = False + +prompt = PromptTemplate( + template_scene=ChatScene.ExtractTriplet.value(), + input_variables=["text"], + response_format="", + template_define=PROMPT_SCENE_DEFINE, + template=_DEFAULT_TEMPLATE + PROMPT_RESPONSE, + stream_out=PROMPT_NEED_NEED_STREAM_OUT, + output_parser=ExtractTripleParser( + sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_NEED_STREAM_OUT + ), +) + +CFG.prompt_template_registry.register(prompt, is_default=True) diff --git a/pilot/scene/chat_knowledge/v1/chat.py b/pilot/scene/chat_knowledge/v1/chat.py index ebecddd19..c381546f8 100644 --- a/pilot/scene/chat_knowledge/v1/chat.py +++ b/pilot/scene/chat_knowledge/v1/chat.py @@ -88,25 +88,7 @@ class ChatKnowledge(BaseChat): if self.space_context: self.prompt_template.template_define = self.space_context["prompt"]["scene"] self.prompt_template.template = self.space_context["prompt"]["template"] - # docs = self.rag_engine.search(query=self.current_user_input) - # import httpx - # with httpx.Client() as client: - # request = client.build_request( - # "post", - # "http://127.0.0.1/api/knowledge/entities/extract", - # json="application/json", # using json for data to ensure it sends as application/json - # params={"text": self.current_user_input}, - # headers={}, - # ) - # - # response = client.send(request) - # if response.status_code != 200: - # error_msg = f"request /api/knowledge/entities/extract failed, error: {response.text}" - # raise Exception(error_msg) - # docs = response.json() - # import requests - # docs = requests.post("http://127.0.0.1:5000/api/knowledge/entities/extract", headers={}, json={"text": self.current_user_input}) - + docs = self.rag_engine.search(query=self.current_user_input) docs = self.knowledge_embedding_client.similar_search( self.current_user_input, self.top_k ) diff --git a/pilot/server/knowledge/api.py b/pilot/server/knowledge/api.py index e0f31031e..8e5e52b58 100644 --- a/pilot/server/knowledge/api.py +++ b/pilot/server/knowledge/api.py @@ -205,12 +205,6 @@ def similar_query(space_name: str, query_request: KnowledgeQueryRequest): async def entity_extract(request: EntityExtractRequest): logger.info(f"Received params: {request}") try: - # from pilot.graph_engine.graph_factory import RAGGraphFactory - # from pilot.component import ComponentType - # rag_engine = CFG.SYSTEM_APP.get_component( - # ComponentType.RAG_GRAPH_DEFAULT.value, RAGGraphFactory - # ).create() - # return Result.succ(await rag_engine.search(request.text)) from pilot.scene.base import ChatScene from pilot.common.chat_util import llm_chat_response_nostream import uuid @@ -222,11 +216,6 @@ async def entity_extract(request: EntityExtractRequest): "model_name": request.model_name, } - # import nest_asyncio - # nest_asyncio.apply() - # loop = asyncio.get_event_loop() - # loop.stop() - # loop = utils.get_or_create_event_loop() res = await llm_chat_response_nostream( ChatScene.ExtractEntity.value(), **{"chat_param": chat_param} ) From b63fa2dfe10a50c970fa402b819bfef98dec2138 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Mon, 16 Oct 2023 14:09:04 +0800 Subject: [PATCH 05/57] feat:rag graph --- pilot/common/chat_util.py | 2 +- pilot/graph_engine/graph_engine.py | 17 ++------ pilot/graph_engine/graph_search.py | 43 +++++++++++-------- pilot/graph_engine/node.py | 1 + pilot/graph_engine/search.py | 6 +-- pilot/scene/base_chat.py | 14 ++++-- .../chat_knowledge/extract_entity/chat.py | 2 +- .../chat_knowledge/extract_triplet/chat.py | 2 +- pilot/scene/chat_knowledge/v1/chat.py | 12 +++--- pilot/server/knowledge/service.py | 3 -- 10 files changed, 51 insertions(+), 51 deletions(-) diff --git a/pilot/common/chat_util.py b/pilot/common/chat_util.py index 159db99d0..0de0b9bda 100644 --- a/pilot/common/chat_util.py +++ b/pilot/common/chat_util.py @@ -9,7 +9,7 @@ chat_factory = ChatFactory() async def llm_chat_response_nostream(chat_scene: str, **chat_param): - """ llm_chat_response_nostream """ + """llm_chat_response_nostream""" chat: BaseChat = chat_factory.get_implementation(chat_scene, **chat_param) res = await chat.get_llm_response() return res diff --git a/pilot/graph_engine/graph_engine.py b/pilot/graph_engine/graph_engine.py index c20142123..04c4f54d9 100644 --- a/pilot/graph_engine/graph_engine.py +++ b/pilot/graph_engine/graph_engine.py @@ -45,8 +45,7 @@ class RAGGraphEngine: **kwargs: Any, ) -> None: """Initialize params.""" - # from llama_index.graph_stores import SimpleGraphStore - # from llama_index.graph_stores.types import GraphStore + from llama_index.graph_stores import SimpleGraphStore # need to set parameters before building index in base class. self.knowledge_source = knowledge_source @@ -55,8 +54,8 @@ class RAGGraphEngine: self.text_splitter = text_splitter self.index_struct = index_struct self.include_embeddings = include_embeddings - # self.graph_store = graph_store or SimpleGraphStore() - self.graph_store = graph_store + self.graph_store = graph_store or SimpleGraphStore() + # self.graph_store = graph_store self.max_triplets_per_chunk = max_triplets_per_chunk self._max_object_length = max_object_length self._extract_triplet_fn = extract_triplet_fn @@ -103,14 +102,6 @@ class RAGGraphEngine: ) ) return triplets - # response = self._service_context.llm_predictor.predict( - # self.kg_triple_extract_template, - # text=text, - # ) - # print(response, flush=True) - # return self._parse_triplet_response( - # response, max_length=self._max_object_length - # ) def _build_index_from_docs(self, documents: List[Document]) -> KG: """Build the index from nodes.""" @@ -126,7 +117,6 @@ class RAGGraphEngine: self.graph_store.upsert_triplet(*triplet) index_struct.add_node([subj, obj], text_node) - return index_struct def search(self, query): @@ -134,4 +124,3 @@ class RAGGraphEngine: graph_search = RAGGraphSearch(graph_engine=self) return graph_search.search(query) - diff --git a/pilot/graph_engine/graph_search.py b/pilot/graph_engine/graph_search.py index 9b06fd234..d1f6a4519 100644 --- a/pilot/graph_engine/graph_search.py +++ b/pilot/graph_engine/graph_search.py @@ -4,6 +4,8 @@ from collections import defaultdict from concurrent.futures import ThreadPoolExecutor from typing import List, Optional, Dict, Any, Set, Callable +from langchain.schema import Document + from pilot.graph_engine.node import BaseNode, TextNode, NodeWithScore from pilot.graph_engine.search import BaseSearch, SearchMode from pilot.utils import utils @@ -67,14 +69,14 @@ class RAGGraphSearch(BaseSearch): logger.warn(f"can not to find graph schema: {e}") self._graph_schema = "" - def _extract_subject_entities(self, query_str: str) -> Set[str]: + async def _extract_subject_entities(self, query_str: str) -> Set[str]: """extract subject entities.""" if self.extract_subject_entities_fn is not None: - return self.extract_subject_entities_fn(query_str) + return await self.extract_subject_entities_fn(query_str) else: - return self._extract_entities_by_llm(query_str) + return await self._extract_entities_by_llm(query_str) - def _extract_entities_by_llm(self, text: str) -> Set[str]: + async def _extract_entities_by_llm(self, text: str) -> Set[str]: """extract subject entities from text by llm""" from pilot.scene.base import ChatScene from pilot.common.chat_util import llm_chat_response_nostream @@ -86,21 +88,23 @@ class RAGGraphSearch(BaseSearch): "select_param": "entity", "model_name": self.model_name, } - loop = utils.get_or_create_event_loop() - entities = loop.run_until_complete( - llm_chat_response_nostream( - ChatScene.ExtractEntity.value(), **{"chat_param": chat_param} - ) + # loop = utils.get_or_create_event_loop() + # entities = loop.run_until_complete( + # llm_chat_response_nostream( + # ChatScene.ExtractEntity.value(), **{"chat_param": chat_param} + # ) + # ) + return await llm_chat_response_nostream( + ChatScene.ExtractEntity.value(), **{"chat_param": chat_param} ) - return entities - def _search( + async def _search( self, query_str: str, - ) -> List[NodeWithScore]: + ) -> List[Document]: """Get nodes for response.""" node_visited = set() - keywords = self._extract_subject_entities(query_str) + keywords = await self._extract_subject_entities(query_str) print(f"extract entities: {keywords}\n") rel_texts = [] cur_rel_map = {} @@ -114,8 +118,8 @@ class RAGGraphSearch(BaseSearch): if node_id in node_visited: continue - if self._include_text: - chunk_indices_count[node_id] += 1 + # if self._include_text: + # chunk_indices_count[node_id] += 1 node_visited.add(node_id) @@ -179,8 +183,11 @@ class RAGGraphSearch(BaseSearch): sorted_nodes_with_scores.append( NodeWithScore(node=rel_text_node, score=DEFAULT_NODE_SCORE) ) - - return sorted_nodes_with_scores + docs = [ + Document(page_content=node.text, metadata=node.metadata) + for node in sorted_nodes_with_scores + ] + return docs def _get_metadata_for_response( self, nodes: List[BaseNode] @@ -190,4 +197,4 @@ class RAGGraphSearch(BaseSearch): if node.metadata is None or "kg_rel_map" not in node.metadata: continue return node.metadata - raise ValueError("kg_rel_map must be found in at least one Node.") \ No newline at end of file + raise ValueError("kg_rel_map must be found in at least one Node.") diff --git a/pilot/graph_engine/node.py b/pilot/graph_engine/node.py index 6f6d45ae4..b23681010 100644 --- a/pilot/graph_engine/node.py +++ b/pilot/graph_engine/node.py @@ -21,6 +21,7 @@ WRAP_WIDTH = 70 class BaseComponent(BaseModel): """Base component object to caputure class names.""" + """reference llama-index""" @classmethod diff --git a/pilot/graph_engine/search.py b/pilot/graph_engine/search.py index 8db837278..297620b00 100644 --- a/pilot/graph_engine/search.py +++ b/pilot/graph_engine/search.py @@ -23,7 +23,7 @@ class SearchMode(str, Enum): class BaseSearch(ABC): """Base Search.""" - def search(self, query: str): + async def search(self, query: str): """Retrieve nodes given query. Args: @@ -32,10 +32,10 @@ class BaseSearch(ABC): """ # if isinstance(query, str): - return self._search(query) + return await self._search(query) @abstractmethod - def _search(self, query: str): + async def _search(self, query: str): """search nodes given query. Implemented by the user. diff --git a/pilot/scene/base_chat.py b/pilot/scene/base_chat.py index c1880f48a..bea00bde3 100644 --- a/pilot/scene/base_chat.py +++ b/pilot/scene/base_chat.py @@ -105,8 +105,14 @@ class BaseChat(ABC): speak_to_user = prompt_define_response return speak_to_user - def __call_base(self): - input_values = self.generate_input_values() + async def __call_base(self): + import inspect + + input_values = ( + await self.generate_input_values() + if inspect.isawaitable(self.generate_input_values()) + else self.generate_input_values() + ) ### Chat sequence advance self.current_message.chat_order = len(self.history_message) + 1 self.current_message.add_user_message(self.current_user_input) @@ -146,7 +152,7 @@ class BaseChat(ABC): async def stream_call(self): # TODO Retry when server connection error - payload = self.__call_base() + payload = await self.__call_base() self.skip_echo_len = len(payload.get("prompt").replace("", " ")) + 11 logger.info(f"Request: \n{payload}") @@ -234,7 +240,7 @@ class BaseChat(ABC): return self.current_ai_response() async def get_llm_response(self): - payload = self.__call_base() + payload = await self.__call_base() logger.info(f"Request: \n{payload}") ai_response_text = "" try: diff --git a/pilot/scene/chat_knowledge/extract_entity/chat.py b/pilot/scene/chat_knowledge/extract_entity/chat.py index bb52961b5..373bb4e5d 100644 --- a/pilot/scene/chat_knowledge/extract_entity/chat.py +++ b/pilot/scene/chat_knowledge/extract_entity/chat.py @@ -24,7 +24,7 @@ class ExtractEntity(BaseChat): self.user_input = chat_param["current_user_input"] self.extract_mode = chat_param["select_param"] - def generate_input_values(self): + async def generate_input_values(self): input_values = { "text": self.user_input, } diff --git a/pilot/scene/chat_knowledge/extract_triplet/chat.py b/pilot/scene/chat_knowledge/extract_triplet/chat.py index 11fe871ab..28152b92e 100644 --- a/pilot/scene/chat_knowledge/extract_triplet/chat.py +++ b/pilot/scene/chat_knowledge/extract_triplet/chat.py @@ -24,7 +24,7 @@ class ExtractTriplet(BaseChat): self.user_input = chat_param["current_user_input"] self.extract_mode = chat_param["select_param"] - def generate_input_values(self): + async def generate_input_values(self): input_values = { "text": self.user_input, } diff --git a/pilot/scene/chat_knowledge/v1/chat.py b/pilot/scene/chat_knowledge/v1/chat.py index c381546f8..ea7ca1922 100644 --- a/pilot/scene/chat_knowledge/v1/chat.py +++ b/pilot/scene/chat_knowledge/v1/chat.py @@ -64,7 +64,7 @@ class ChatKnowledge(BaseChat): self.prompt_template.template_is_strict = False async def stream_call(self): - input_values = self.generate_input_values() + input_values = await self.generate_input_values() # Source of knowledge file relations = input_values.get("relations") last_output = None @@ -84,14 +84,14 @@ class ChatKnowledge(BaseChat): ) yield last_output - def generate_input_values(self): + async def generate_input_values(self): if self.space_context: self.prompt_template.template_define = self.space_context["prompt"]["scene"] self.prompt_template.template = self.space_context["prompt"]["template"] - docs = self.rag_engine.search(query=self.current_user_input) - docs = self.knowledge_embedding_client.similar_search( - self.current_user_input, self.top_k - ) + docs = await self.rag_engine.search(query=self.current_user_input) + # docs = self.knowledge_embedding_client.similar_search( + # self.current_user_input, self.top_k + # ) if not docs: raise ValueError( "you have no knowledge space, please add your knowledge space" diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index f4150fa73..95949d319 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -261,9 +261,6 @@ class KnowledgeService: # docs = engine.search( # "Comparing Curry and James in terms of their positions, playing styles, and achievements in the NBA" # ) - embedding_factory = CFG.SYSTEM_APP.get_component( - "embedding_factory", EmbeddingFactory - ) # update document status doc.status = SyncStatus.RUNNING.name doc.chunk_size = len(chunk_docs) From 68c9010e5c6e8ef464e139b0b479c76ca534e002 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Mon, 16 Oct 2023 21:14:20 +0800 Subject: [PATCH 06/57] feat:rag graph --- pilot/graph_engine/graph_engine.py | 49 ++++++++++++++++++++++------ pilot/scene/base_chat.py | 5 ++- pilot/vector_store/weaviate_store.py | 8 ++--- 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/pilot/graph_engine/graph_engine.py b/pilot/graph_engine/graph_engine.py index 04c4f54d9..e34baba79 100644 --- a/pilot/graph_engine/graph_engine.py +++ b/pilot/graph_engine/graph_engine.py @@ -106,21 +106,50 @@ class RAGGraphEngine: def _build_index_from_docs(self, documents: List[Document]) -> KG: """Build the index from nodes.""" index_struct = self.index_struct_cls() - for doc in documents: - triplets = self._extract_triplets(doc.page_content) - if len(triplets) == 0: - continue - text_node = TextNode(text=doc.page_content, metadata=doc.metadata) - logger.info(f"extracted knowledge triplets: {triplets}") - for triplet in triplets: - subj, _, obj = triplet - self.graph_store.upsert_triplet(*triplet) - index_struct.add_node([subj, obj], text_node) + num_threads = 5 + chunk_size = len(documents) if (len(documents) < num_threads) else len(documents) / num_threads + import concurrent + future_tasks = [] + with concurrent.futures.ThreadPoolExecutor() as executor: + for i in range(num_threads): + start = i * chunk_size + end = start + chunk_size if i < num_threads - 1 else None + future_tasks.append(executor.submit(self._extract_triplets_task, documents[start:end][0], index_struct)) + + result = [future.result() for future in future_tasks] return index_struct + # for doc in documents: + # triplets = self._extract_triplets(doc.page_content) + # if len(triplets) == 0: + # continue + # text_node = TextNode(text=doc.page_content, metadata=doc.metadata) + # logger.info(f"extracted knowledge triplets: {triplets}") + # for triplet in triplets: + # subj, _, obj = triplet + # self.graph_store.upsert_triplet(*triplet) + # index_struct.add_node([subj, obj], text_node) + # + # return index_struct def search(self, query): from pilot.graph_engine.graph_search import RAGGraphSearch graph_search = RAGGraphSearch(graph_engine=self) return graph_search.search(query) + + def _extract_triplets_task(self, doc, index_struct): + import threading + thread_id = threading.get_ident() + print(f"current thread-{thread_id} begin extract triplets task") + triplets = self._extract_triplets(doc.page_content) + if len(triplets) == 0: + triplets = [] + text_node = TextNode(text=doc.page_content, metadata=doc.metadata) + logger.info(f"extracted knowledge triplets: {triplets}") + print(f"current thread-{thread_id} end extract triplets tasks, triplets-{triplets}") + for triplet in triplets: + subj, _, obj = triplet + self.graph_store.upsert_triplet(*triplet) + self.graph_store.upsert_triplet(*triplet) + index_struct.add_node([subj, obj], text_node) diff --git a/pilot/scene/base_chat.py b/pilot/scene/base_chat.py index bea00bde3..58a0becc9 100644 --- a/pilot/scene/base_chat.py +++ b/pilot/scene/base_chat.py @@ -107,10 +107,9 @@ class BaseChat(ABC): async def __call_base(self): import inspect - input_values = ( await self.generate_input_values() - if inspect.isawaitable(self.generate_input_values()) + if inspect.isawaitable(self.generate_input_values) else self.generate_input_values() ) ### Chat sequence advance @@ -181,7 +180,7 @@ class BaseChat(ABC): span.end(metadata={"error": str(e)}) async def nostream_call(self): - payload = self.__call_base() + payload = await self.__call_base() logger.info(f"Request: \n{payload}") ai_response_text = "" span = root_tracer.start_span( diff --git a/pilot/vector_store/weaviate_store.py b/pilot/vector_store/weaviate_store.py index 795cf21f9..a8e126eb5 100644 --- a/pilot/vector_store/weaviate_store.py +++ b/pilot/vector_store/weaviate_store.py @@ -1,11 +1,7 @@ import os -import json import logging -import weaviate +#import weaviate from langchain.schema import Document -from langchain.vectorstores import Weaviate -from weaviate.exceptions import WeaviateBaseError - from pilot.configs.config import Config from pilot.configs.model_config import KNOWLEDGE_UPLOAD_ROOT_PATH from pilot.vector_store.base import VectorStoreBase @@ -72,7 +68,7 @@ class WeaviateStore(VectorStoreBase): if self.vector_store_client.schema.get(self.vector_name): return True return False - except WeaviateBaseError as e: + except Exception as e: logger.error("vector_name_exists error", e.message) return False From f93af985eda442e9f960bcb9d9eeec34276427ea Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Tue, 17 Oct 2023 10:35:46 +0800 Subject: [PATCH 07/57] feat:rag graph --- pilot/graph_engine/graph_engine.py | 3 ++- pilot/scene/base_chat.py | 2 +- pilot/scene/chat_knowledge/extract_entity/chat.py | 2 +- pilot/scene/chat_knowledge/extract_triplet/chat.py | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pilot/graph_engine/graph_engine.py b/pilot/graph_engine/graph_engine.py index e34baba79..80cbab066 100644 --- a/pilot/graph_engine/graph_engine.py +++ b/pilot/graph_engine/graph_engine.py @@ -107,7 +107,7 @@ class RAGGraphEngine: """Build the index from nodes.""" index_struct = self.index_struct_cls() num_threads = 5 - chunk_size = len(documents) if (len(documents) < num_threads) else len(documents) / num_threads + chunk_size = len(documents) if (len(documents) < num_threads) else len(documents) // num_threads import concurrent future_tasks = [] @@ -132,6 +132,7 @@ class RAGGraphEngine: # # return index_struct + def search(self, query): from pilot.graph_engine.graph_search import RAGGraphSearch diff --git a/pilot/scene/base_chat.py b/pilot/scene/base_chat.py index 58a0becc9..a1d6d9f08 100644 --- a/pilot/scene/base_chat.py +++ b/pilot/scene/base_chat.py @@ -109,7 +109,7 @@ class BaseChat(ABC): import inspect input_values = ( await self.generate_input_values() - if inspect.isawaitable(self.generate_input_values) + if inspect.isawaitable(self.generate_input_values()) else self.generate_input_values() ) ### Chat sequence advance diff --git a/pilot/scene/chat_knowledge/extract_entity/chat.py b/pilot/scene/chat_knowledge/extract_entity/chat.py index 373bb4e5d..bb52961b5 100644 --- a/pilot/scene/chat_knowledge/extract_entity/chat.py +++ b/pilot/scene/chat_knowledge/extract_entity/chat.py @@ -24,7 +24,7 @@ class ExtractEntity(BaseChat): self.user_input = chat_param["current_user_input"] self.extract_mode = chat_param["select_param"] - async def generate_input_values(self): + def generate_input_values(self): input_values = { "text": self.user_input, } diff --git a/pilot/scene/chat_knowledge/extract_triplet/chat.py b/pilot/scene/chat_knowledge/extract_triplet/chat.py index 28152b92e..11fe871ab 100644 --- a/pilot/scene/chat_knowledge/extract_triplet/chat.py +++ b/pilot/scene/chat_knowledge/extract_triplet/chat.py @@ -24,7 +24,7 @@ class ExtractTriplet(BaseChat): self.user_input = chat_param["current_user_input"] self.extract_mode = chat_param["select_param"] - async def generate_input_values(self): + def generate_input_values(self): input_values = { "text": self.user_input, } From aff0553b7ecb5d2173b45995fdf08ca1409ca75f Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Thu, 19 Oct 2023 09:40:05 +0800 Subject: [PATCH 08/57] style:fmt --- pilot/graph_engine/graph_engine.py | 21 +++++++++++++++++---- pilot/scene/base_chat.py | 1 + pilot/server/knowledge/service.py | 3 --- pilot/vector_store/weaviate_store.py | 3 ++- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/pilot/graph_engine/graph_engine.py b/pilot/graph_engine/graph_engine.py index 80cbab066..a50ebabdc 100644 --- a/pilot/graph_engine/graph_engine.py +++ b/pilot/graph_engine/graph_engine.py @@ -107,15 +107,26 @@ class RAGGraphEngine: """Build the index from nodes.""" index_struct = self.index_struct_cls() num_threads = 5 - chunk_size = len(documents) if (len(documents) < num_threads) else len(documents) // num_threads + chunk_size = ( + len(documents) + if (len(documents) < num_threads) + else len(documents) // num_threads + ) import concurrent + future_tasks = [] with concurrent.futures.ThreadPoolExecutor() as executor: for i in range(num_threads): start = i * chunk_size end = start + chunk_size if i < num_threads - 1 else None - future_tasks.append(executor.submit(self._extract_triplets_task, documents[start:end][0], index_struct)) + future_tasks.append( + executor.submit( + self._extract_triplets_task, + documents[start:end][0], + index_struct, + ) + ) result = [future.result() for future in future_tasks] return index_struct @@ -132,7 +143,6 @@ class RAGGraphEngine: # # return index_struct - def search(self, query): from pilot.graph_engine.graph_search import RAGGraphSearch @@ -141,6 +151,7 @@ class RAGGraphEngine: def _extract_triplets_task(self, doc, index_struct): import threading + thread_id = threading.get_ident() print(f"current thread-{thread_id} begin extract triplets task") triplets = self._extract_triplets(doc.page_content) @@ -148,7 +159,9 @@ class RAGGraphEngine: triplets = [] text_node = TextNode(text=doc.page_content, metadata=doc.metadata) logger.info(f"extracted knowledge triplets: {triplets}") - print(f"current thread-{thread_id} end extract triplets tasks, triplets-{triplets}") + print( + f"current thread-{thread_id} end extract triplets tasks, triplets-{triplets}" + ) for triplet in triplets: subj, _, obj = triplet self.graph_store.upsert_triplet(*triplet) diff --git a/pilot/scene/base_chat.py b/pilot/scene/base_chat.py index a1d6d9f08..10c89d620 100644 --- a/pilot/scene/base_chat.py +++ b/pilot/scene/base_chat.py @@ -107,6 +107,7 @@ class BaseChat(ABC): async def __call_base(self): import inspect + input_values = ( await self.generate_input_values() if inspect.isawaitable(self.generate_input_values()) diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index 95949d319..7bba99c0a 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -258,9 +258,6 @@ class KnowledgeService: ComponentType.RAG_GRAPH_DEFAULT.value, RAGGraphFactory ).create() rag_engine.knowledge_graph(docs=chunk_docs) - # docs = engine.search( - # "Comparing Curry and James in terms of their positions, playing styles, and achievements in the NBA" - # ) # update document status doc.status = SyncStatus.RUNNING.name doc.chunk_size = len(chunk_docs) diff --git a/pilot/vector_store/weaviate_store.py b/pilot/vector_store/weaviate_store.py index a8e126eb5..93816ea66 100644 --- a/pilot/vector_store/weaviate_store.py +++ b/pilot/vector_store/weaviate_store.py @@ -1,6 +1,7 @@ import os import logging -#import weaviate + +# import weaviate from langchain.schema import Document from pilot.configs.config import Config from pilot.configs.model_config import KNOWLEDGE_UPLOAD_ROOT_PATH From 39219a4fdce92e1c464e7ea9f56e7a4b7a2eabd1 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Thu, 19 Oct 2023 12:02:27 +0800 Subject: [PATCH 09/57] feat:rag_graph --- pilot/graph_engine/graph_engine.py | 16 +++++++++++----- pilot/graph_engine/graph_search.py | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/pilot/graph_engine/graph_engine.py b/pilot/graph_engine/graph_engine.py index a50ebabdc..faf53aba1 100644 --- a/pilot/graph_engine/graph_engine.py +++ b/pilot/graph_engine/graph_engine.py @@ -129,6 +129,11 @@ class RAGGraphEngine: ) result = [future.result() for future in future_tasks] + # for triplet in triplets: + # subj, _, obj = triplet + # self.graph_store.upsert_triplet(*triplet) + # self.graph_store.upsert_triplet(*triplet) + # index_struct.add_node([subj, obj], text_node) return index_struct # for doc in documents: # triplets = self._extract_triplets(doc.page_content) @@ -162,8 +167,9 @@ class RAGGraphEngine: print( f"current thread-{thread_id} end extract triplets tasks, triplets-{triplets}" ) - for triplet in triplets: - subj, _, obj = triplet - self.graph_store.upsert_triplet(*triplet) - self.graph_store.upsert_triplet(*triplet) - index_struct.add_node([subj, obj], text_node) + return triplets + # for triplet in triplets: + # subj, _, obj = triplet + # self.graph_store.upsert_triplet(*triplet) + # self.graph_store.upsert_triplet(*triplet) + # index_struct.add_node([subj, obj], text_node) diff --git a/pilot/graph_engine/graph_search.py b/pilot/graph_engine/graph_search.py index d1f6a4519..fb883e48b 100644 --- a/pilot/graph_engine/graph_search.py +++ b/pilot/graph_engine/graph_search.py @@ -145,7 +145,7 @@ class RAGGraphSearch(BaseSearch): if len(sorted_nodes_with_scores) == 0: logger.info("> No nodes found by keywords, returning empty response.") return [ - NodeWithScore(node=TextNode(text="No relationships found."), score=1.0) + Document(page_content="No relationships found.") ] # add relationships as Node From 724456dc3e82e9bc53d9cdf21bbd485f4a48e4eb Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Wed, 25 Oct 2023 21:18:37 +0800 Subject: [PATCH 10/57] feat:extract summary --- pilot/graph_engine/graph_engine.py | 115 ++++++++++++++++++----------- pilot/graph_engine/graph_search.py | 19 +++-- pilot/scene/base.py | 7 ++ pilot/scene/chat_factory.py | 1 + pilot/server/knowledge/service.py | 60 ++++++++++++--- 5 files changed, 141 insertions(+), 61 deletions(-) diff --git a/pilot/graph_engine/graph_engine.py b/pilot/graph_engine/graph_engine.py index faf53aba1..491a8625c 100644 --- a/pilot/graph_engine/graph_engine.py +++ b/pilot/graph_engine/graph_engine.py @@ -15,10 +15,12 @@ logger = logging.getLogger(__name__) class RAGGraphEngine: """Knowledge RAG Graph Engine. - Build a KG by extracting triplets, and leveraging the KG during query-time. + Build a RAG Graph Client can extract triplets and insert into graph store. Args: knowledge_type (Optional[str]): Default: KnowledgeType.DOCUMENT.value extracting triplets. + knowledge_source (Optional[str]): + model_name (Optional[str]): llm model name graph_store (Optional[GraphStore]): The graph store to use.refrence:llama-index include_embeddings (bool): Whether to include embeddings in the index. Defaults to False. @@ -104,37 +106,64 @@ class RAGGraphEngine: return triplets def _build_index_from_docs(self, documents: List[Document]) -> KG: - """Build the index from nodes.""" + """Build the index from nodes. + Args:documents:List[Document] + """ index_struct = self.index_struct_cls() - num_threads = 5 - chunk_size = ( - len(documents) - if (len(documents) < num_threads) - else len(documents) // num_threads - ) - - import concurrent - - future_tasks = [] - with concurrent.futures.ThreadPoolExecutor() as executor: - for i in range(num_threads): - start = i * chunk_size - end = start + chunk_size if i < num_threads - 1 else None - future_tasks.append( - executor.submit( - self._extract_triplets_task, - documents[start:end][0], - index_struct, - ) - ) - - result = [future.result() for future in future_tasks] + triplets = [] + for doc in documents: + trips = self._extract_triplets_task([doc], index_struct) + triplets.extend(trips) + print(triplets) + text_node = TextNode(text=doc.page_content, metadata=doc.metadata) + for triplet in triplets: + subj, _, obj = triplet + self.graph_store.upsert_triplet(*triplet) + index_struct.add_node([subj, obj], text_node) + return index_struct + # num_threads = 5 + # chunk_size = ( + # len(documents) + # if (len(documents) < num_threads) + # else len(documents) // num_threads + # ) + # + # import concurrent + # triples = [] + # future_tasks = [] + # with concurrent.futures.ThreadPoolExecutor() as executor: + # for i in range(num_threads): + # start = i * chunk_size + # end = start + chunk_size if i < num_threads - 1 else None + # # doc = documents[start:end] + # future_tasks.append( + # executor.submit( + # self._extract_triplets_task, + # documents[start:end], + # index_struct, + # ) + # ) + # # for doc in documents[start:end]: + # # future_tasks.append( + # # executor.submit( + # # self._extract_triplets_task, + # # doc, + # # index_struct, + # # ) + # # ) + # + # # result = [future.result() for future in future_tasks] + # completed_futures, _ = concurrent.futures.wait(future_tasks, return_when=concurrent.futures.ALL_COMPLETED) + # for future in completed_futures: + # # 获取已完成的future的结果并添加到results列表中 + # result = future.result() + # triplets.extend(result) + # print(f"total triplets-{triples}") # for triplet in triplets: # subj, _, obj = triplet # self.graph_store.upsert_triplet(*triplet) - # self.graph_store.upsert_triplet(*triplet) - # index_struct.add_node([subj, obj], text_node) - return index_struct + # # index_struct.add_node([subj, obj], text_node) + # return index_struct # for doc in documents: # triplets = self._extract_triplets(doc.page_content) # if len(triplets) == 0: @@ -154,20 +183,22 @@ class RAGGraphEngine: graph_search = RAGGraphSearch(graph_engine=self) return graph_search.search(query) - def _extract_triplets_task(self, doc, index_struct): - import threading - - thread_id = threading.get_ident() - print(f"current thread-{thread_id} begin extract triplets task") - triplets = self._extract_triplets(doc.page_content) - if len(triplets) == 0: - triplets = [] - text_node = TextNode(text=doc.page_content, metadata=doc.metadata) - logger.info(f"extracted knowledge triplets: {triplets}") - print( - f"current thread-{thread_id} end extract triplets tasks, triplets-{triplets}" - ) - return triplets + def _extract_triplets_task(self, docs, index_struct): + triple_results = [] + for doc in docs: + import threading + thread_id = threading.get_ident() + print(f"current thread-{thread_id} begin extract triplets task") + triplets = self._extract_triplets(doc.page_content) + if len(triplets) == 0: + triplets = [] + text_node = TextNode(text=doc.page_content, metadata=doc.metadata) + logger.info(f"extracted knowledge triplets: {triplets}") + print( + f"current thread-{thread_id} end extract triplets tasks, triplets-{triplets}" + ) + triple_results.extend(triplets) + return triple_results # for triplet in triplets: # subj, _, obj = triplet # self.graph_store.upsert_triplet(*triplet) diff --git a/pilot/graph_engine/graph_search.py b/pilot/graph_engine/graph_search.py index fb883e48b..f3025be85 100644 --- a/pilot/graph_engine/graph_search.py +++ b/pilot/graph_engine/graph_search.py @@ -8,7 +8,6 @@ from langchain.schema import Document from pilot.graph_engine.node import BaseNode, TextNode, NodeWithScore from pilot.graph_engine.search import BaseSearch, SearchMode -from pilot.utils import utils logger = logging.getLogger(__name__) DEFAULT_NODE_SCORE = 1000.0 @@ -113,15 +112,15 @@ class RAGGraphSearch(BaseSearch): for keyword in keywords: keyword = keyword.lower() subjs = set((keyword,)) - node_ids = self._index_struct.search_node_by_keyword(keyword) - for node_id in node_ids[:GLOBAL_EXPLORE_NODE_LIMIT]: - if node_id in node_visited: - continue - - # if self._include_text: - # chunk_indices_count[node_id] += 1 - - node_visited.add(node_id) + # node_ids = self._index_struct.search_node_by_keyword(keyword) + # for node_id in node_ids[:GLOBAL_EXPLORE_NODE_LIMIT]: + # if node_id in node_visited: + # continue + # + # # if self._include_text: + # # chunk_indices_count[node_id] += 1 + # + # node_visited.add(node_id) rel_map = self._graph_store.get_rel_map( list(subjs), self.graph_store_query_depth diff --git a/pilot/scene/base.py b/pilot/scene/base.py index 6abc9c937..5c98003d9 100644 --- a/pilot/scene/base.py +++ b/pilot/scene/base.py @@ -89,6 +89,13 @@ class ChatScene(Enum): ["Extract Select"], True, ) + ExtractSummary = Scene( + "extract_summary", + "Extract Summary", + "Extract Summary", + ["Extract Select"], + True, + ) ExtractEntity = Scene( "extract_entity", "Extract Entity", "Extract Entity", ["Extract Select"], True ) diff --git a/pilot/scene/chat_factory.py b/pilot/scene/chat_factory.py index de11332f5..a57855a2b 100644 --- a/pilot/scene/chat_factory.py +++ b/pilot/scene/chat_factory.py @@ -15,6 +15,7 @@ class ChatFactory(metaclass=Singleton): from pilot.scene.chat_knowledge.inner_db_summary.chat import InnerChatDBSummary from pilot.scene.chat_knowledge.extract_triplet.chat import ExtractTriplet from pilot.scene.chat_knowledge.extract_entity.chat import ExtractEntity + from pilot.scene.chat_knowledge.summary.chat import ExtractSummary from pilot.scene.chat_data.chat_excel.excel_analyze.chat import ChatExcel from pilot.scene.chat_agent.chat import ChatAgent diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index ed8c2846e..4c1c41994 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -280,12 +280,6 @@ class KnowledgeService: embedding_factory=embedding_factory, ) chunk_docs = client.read() - from pilot.graph_engine.graph_factory import RAGGraphFactory - - rag_engine = CFG.SYSTEM_APP.get_component( - ComponentType.RAG_GRAPH_DEFAULT.value, RAGGraphFactory - ).create() - rag_engine.knowledge_graph(docs=chunk_docs) # update document status doc.status = SyncStatus.RUNNING.name doc.chunk_size = len(chunk_docs) @@ -294,8 +288,8 @@ class KnowledgeService: executor = CFG.SYSTEM_APP.get_component( ComponentType.EXECUTOR_DEFAULT, ExecutorFactory ).create() - executor.submit(self.async_doc_embedding, client, chunk_docs, doc) - + executor.submit(self.async_knowledge_graph, chunk_docs, doc) + # executor.submit(self.async_doc_embedding, client, chunk_docs, doc) logger.info(f"begin save document chunks, doc:{doc.doc_name}") # save chunk details chunk_entities = [ @@ -397,13 +391,40 @@ class KnowledgeService: res.total = document_chunk_dao.get_document_chunks_count(query) res.page = request.page return res + def async_knowledge_graph(self, chunk_docs, doc): + """async document extract triplets and save into graph db + Args: + - chunk_docs: List[Document] + - doc: KnowledgeDocumentEntity + """ + for doc in chunk_docs: + text = doc.page_content + self._llm_extract_summary(text) + logger.info( + f"async_knowledge_graph, doc:{doc.doc_name}, chunk_size:{len(chunk_docs)}, begin embedding to graph store" + ) + # try: + # from pilot.graph_engine.graph_factory import RAGGraphFactory + # + # rag_engine = CFG.SYSTEM_APP.get_component( + # ComponentType.RAG_GRAPH_DEFAULT.value, RAGGraphFactory + # ).create() + # rag_engine.knowledge_graph(chunk_docs) + # doc.status = SyncStatus.FINISHED.name + # doc.result = "document build graph success" + # except Exception as e: + # doc.status = SyncStatus.FAILED.name + # doc.result = "document build graph failed" + str(e) + # logger.error(f"document build graph failed:{doc.doc_name}, {str(e)}") + return knowledge_document_dao.update_knowledge_document(doc) + def async_doc_embedding(self, client, chunk_docs, doc): """async document embedding into vector db Args: - client: EmbeddingEngine Client - chunk_docs: List[Document] - - doc: doc + - doc: KnowledgeDocumentEntity """ logger.info( f"async_doc_embedding, doc:{doc.doc_name}, chunk_size:{len(chunk_docs)}, begin embedding to vector store-{CFG.VECTOR_STORE_TYPE}" @@ -461,3 +482,24 @@ class KnowledgeService: if space.context is not None: return json.loads(spaces[0].context) return None + + def _llm_extract_summary(self, doc: str): + """Extract triplets from text by llm""" + from pilot.scene.base import ChatScene + from pilot.common.chat_util import llm_chat_response_nostream + import uuid + + chat_param = { + "chat_session_id": uuid.uuid1(), + "current_user_input": doc, + "select_param": "summery", + "model_name": "proxyllm", + } + from pilot.utils import utils + loop = utils.get_or_create_event_loop() + triplets = loop.run_until_complete( + llm_chat_response_nostream( + ChatScene.ExtractSummary.value(), **{"chat_param": chat_param} + ) + ) + return triplets From 95d3f5222b9e3b707f7baf62c0ca1e7f6969aa28 Mon Sep 17 00:00:00 2001 From: FangYin Cheng Date: Mon, 30 Oct 2023 11:48:05 +0800 Subject: [PATCH 11/57] feat(model): Support AquilaChat2-34B --- .env.template | 9 ++ docs/getting_started/faq/llm/llm_faq.md | 28 ++-- .../getting_started/faq/llm/llm_faq.po | 126 +++++++++++------- pilot/configs/config.py | 2 + pilot/model/cluster/controller/controller.py | 6 +- pilot/model/cluster/worker/default_worker.py | 2 +- .../model/cluster/worker/embedding_worker.py | 2 +- pilot/model/cluster/worker/manager.py | 8 +- pilot/model/loader.py | 2 +- pilot/model/model_adapter.py | 52 ++++++-- pilot/model/proxy/llms/chatgpt.py | 14 +- pilot/server/dbgpt_server.py | 6 +- pilot/utils/parameter_utils.py | 21 ++- pilot/utils/utils.py | 41 ++++++ 14 files changed, 234 insertions(+), 85 deletions(-) diff --git a/.env.template b/.env.template index 16f4e3a6e..e03650033 100644 --- a/.env.template +++ b/.env.template @@ -23,6 +23,15 @@ WEB_SERVER_PORT=7860 #*******************************************************************# # LLM_MODEL, see /pilot/configs/model_config.LLM_MODEL_CONFIG LLM_MODEL=vicuna-13b-v1.5 +## LLM model path, by default, DB-GPT will read the model path from LLM_MODEL_CONFIG based on the LLM_MODEL. +## Of course you can specify your model path according to LLM_MODEL_PATH +## In DB-GPT, the priority from high to low to read model path: +## 1. environment variable with key: {LLM_MODEL}_MODEL_PATH (Avoid multi-model conflicts) +## 2. environment variable with key: MODEL_PATH +## 3. environment variable with key: LLM_MODEL_PATH +## 4. the config in /pilot/configs/model_config.LLM_MODEL_CONFIG +# LLM_MODEL_PATH=/app/models/vicuna-13b-v1.5 +# LLM_PROMPT_TEMPLATE=vicuna_v1.1 MODEL_SERVER=http://127.0.0.1:8000 LIMIT_MODEL_CONCURRENCY=5 MAX_POSITION_EMBEDDINGS=4096 diff --git a/docs/getting_started/faq/llm/llm_faq.md b/docs/getting_started/faq/llm/llm_faq.md index 7b4409d1f..53b8cf279 100644 --- a/docs/getting_started/faq/llm/llm_faq.md +++ b/docs/getting_started/faq/llm/llm_faq.md @@ -1,6 +1,6 @@ LLM USE FAQ ================================== -##### Q1:how to use openai chatgpt service +##### Q1: how to use openai chatgpt service change your LLM_MODEL in `.env` ````shell LLM_MODEL=proxyllm @@ -15,7 +15,7 @@ PROXY_SERVER_URL=https://api.openai.com/v1/chat/completions make sure your openapi API_KEY is available -##### Q2 What difference between `python dbgpt_server --light` and `python dbgpt_server` +##### Q2: What difference between `python dbgpt_server --light` and `python dbgpt_server` ```{note} * `python dbgpt_server --light` dbgpt_server does not start the llm service. Users can deploy the llm service separately by using `python llmserver`, and dbgpt_server accesses the llm service through set the LLM_SERVER environment variable in .env. The purpose is to allow for the separate deployment of dbgpt's backend service and llm service. @@ -35,7 +35,7 @@ python pilot/server/dbgpt_server.py --light ``` -##### Q3 How to use MultiGPUs +##### Q3: How to use MultiGPUs DB-GPT will use all available gpu by default. And you can modify the setting `CUDA_VISIBLE_DEVICES=0,1` in `.env` file to use the specific gpu IDs. @@ -52,7 +52,7 @@ CUDA_VISIBLE_DEVICES=3,4,5,6 python3 pilot/server/dbgpt_server.py You can modify the setting `MAX_GPU_MEMORY=xxGib` in `.env` file to configure the maximum memory used by each GPU. -##### Q4 Not Enough Memory +##### Q4: Not Enough Memory DB-GPT supported 8-bit quantization and 4-bit quantization. @@ -60,9 +60,9 @@ You can modify the setting `QUANTIZE_8bit=True` or `QUANTIZE_4bit=True` in `.env Llama-2-70b with 8-bit quantization can run with 80 GB of VRAM, and 4-bit quantization can run with 48 GB of VRAM. -Note: you need to install the latest dependencies according to [requirements.txt](https://github.com/eosphoros-ai/DB-GPT/blob/main/requirements.txt). +Note: you need to install the quantization dependencies with `pip install -e ".[quantization]"` -##### Q5 How to Add LLM Service dynamic local mode +##### Q5: How to Add LLM Service dynamic local mode Now DB-GPT through multi-llm service switch, so how to add llm service dynamic, @@ -75,7 +75,7 @@ eg: dbgpt model start --model_name chatglm2-6b --model_path /root/DB-GPT/models/ chatgpt eg: dbgpt model start --model_name chatgpt_proxyllm --model_path chatgpt_proxyllm --proxy_api_key ${OPENAI_KEY} --proxy_server_url {OPENAI_URL} ``` -##### Q6 How to Add LLM Service dynamic in remote mode +##### Q6: How to Add LLM Service dynamic in remote mode If you deploy llm service in remote machine instance, and you want to add model service to dbgpt server to manage use dbgpt start worker and set --controller_addr. @@ -88,13 +88,13 @@ eg: dbgpt start worker --model_name vicuna-13b-v1.5 \ ``` -##### Q7 dbgpt command not found +##### Q7: dbgpt command not found ```commandline pip install -e "pip install -e ".[default]" ``` -##### Q8 When starting the worker_manager on a cloud server and registering it with the controller, it is noticed that the worker's exposed IP is a private IP instead of a public IP, which leads to the inability to access the service. +##### Q8: When starting the worker_manager on a cloud server and registering it with the controller, it is noticed that the worker's exposed IP is a private IP instead of a public IP, which leads to the inability to access the service. ```commandline @@ -103,4 +103,14 @@ pip install -e "pip install -e ".[default]" automatically determined ``` +##### Q9: How to customize model path and prompt template + +DB-GPT will read the model path from `pilot.configs.model_config.LLM_MODEL_CONFIG` based on the `LLM_MODEL`. +Of course, you can use the environment variable `LLM_MODEL_PATH` to specify the model path and `LLM_PROMPT_TEMPLATE` to specify your model prompt template. + +``` +LLM_MODEL=vicuna-13b-v1.5 +LLM_MODEL_PATH=/app/models/vicuna-13b-v1.5 +# LLM_PROMPT_TEMPLATE=vicuna_v1.1 +``` diff --git a/docs/locales/zh_CN/LC_MESSAGES/getting_started/faq/llm/llm_faq.po b/docs/locales/zh_CN/LC_MESSAGES/getting_started/faq/llm/llm_faq.po index c0791b7cb..590cccfba 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/getting_started/faq/llm/llm_faq.po +++ b/docs/locales/zh_CN/LC_MESSAGES/getting_started/faq/llm/llm_faq.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 👏👏 0.3.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-20 22:29+0800\n" +"POT-Creation-Date: 2023-10-30 11:37+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -19,34 +19,36 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.12.1\n" -#: ../../getting_started/faq/llm/llm_faq.md:1 54763acec7da4deb90669195c54ec3a1 +#: ../../getting_started/faq/llm/llm_faq.md:1 98e23f85313c45169ff2ba7f80193356 msgid "LLM USE FAQ" msgstr "LLM模型使用FAQ" -#: ../../getting_started/faq/llm/llm_faq.md:3 66f73fd2ee7b462e92d3f263792a5e33 -msgid "Q1:how to use openai chatgpt service" +#: ../../getting_started/faq/llm/llm_faq.md:3 0d49acfb4af947cb969b249346b00d33 +#, fuzzy +msgid "Q1: how to use openai chatgpt service" msgstr "我怎么使用OPENAI服务" -#: ../../getting_started/faq/llm/llm_faq.md:4 9d178d8462b74cb188bbacf2ac2ac12b +#: ../../getting_started/faq/llm/llm_faq.md:4 7010fec33e264987a29de86c54da93e8 #, fuzzy msgid "change your LLM_MODEL in `.env`" msgstr "通过在.env文件设置LLM_MODEL" -#: ../../getting_started/faq/llm/llm_faq.md:9 f7ca82f257be4ac09639a7f8af5e83eb +#: ../../getting_started/faq/llm/llm_faq.md:9 0982d6d5d0b3434fb00698aaf675f3f3 msgid "set your OPENAPI KEY" msgstr "set your OPENAPI KEY" -#: ../../getting_started/faq/llm/llm_faq.md:16 d6255b20dce34a2690df7e2af3505d97 +#: ../../getting_started/faq/llm/llm_faq.md:16 63650494c1574de09c007e1d470dd53d msgid "make sure your openapi API_KEY is available" msgstr "确认openapi API_KEY是否可用" -#: ../../getting_started/faq/llm/llm_faq.md:18 6f1c6dbdb31f4210a6d21f0f3a6ae589 +#: ../../getting_started/faq/llm/llm_faq.md:18 5721ec71e344499d96c55b7e531d7c08 +#, fuzzy msgid "" -"Q2 What difference between `python dbgpt_server --light` and `python " +"Q2: What difference between `python dbgpt_server --light` and `python " "dbgpt_server`" -msgstr "Q2 `python dbgpt_server --light` 和 `python dbgpt_server`的区别是什么?" +msgstr "Q2: `python dbgpt_server --light` 和 `python dbgpt_server`的区别是什么?" -#: ../../getting_started/faq/llm/llm_faq.md:20 b839771ae9e34e998b0edf8d69deabdd +#: ../../getting_started/faq/llm/llm_faq.md:20 76a650f195dd40b6a3a3564030cdc040 msgid "" "`python dbgpt_server --light` dbgpt_server does not start the llm " "service. Users can deploy the llm service separately by using `python " @@ -58,75 +60,75 @@ msgstr "" "用户可以通过`python " "llmserver`单独部署模型服务,dbgpt_server通过LLM_SERVER环境变量来访问模型服务。目的是为了可以将dbgpt后台服务和大模型服务分离部署。" -#: ../../getting_started/faq/llm/llm_faq.md:22 aba39cef6fe84799bcd03e8f36c41296 +#: ../../getting_started/faq/llm/llm_faq.md:22 8cd87e3504784d9e891e1fb96c79e143 msgid "" "`python dbgpt_server` dbgpt_server service and the llm service are " "deployed on the same instance. when dbgpt_server starts the service, it " "also starts the llm service at the same time." msgstr "`python dbgpt_server` 是将后台服务和模型服务部署在同一台实例上.dbgpt_server在启动服务的时候同时开启模型服务." -#: ../../getting_started/faq/llm/llm_faq.md:27 c65270d479af49e28e99b35a7932adbd +#: ../../getting_started/faq/llm/llm_faq.md:27 58a6eaf57e6d425685f67058b1a642d4 msgid "" "If you want to access an external LLM service(deployed by DB-GPT), you " "need to" msgstr "如果模型服务部署(通过DB-GPT部署)在别的机器,想通过dbgpt服务访问模型服务" -#: ../../getting_started/faq/llm/llm_faq.md:29 da153e6d18c543f28e0c4e85618e3d3d +#: ../../getting_started/faq/llm/llm_faq.md:29 67ac8823ca2e49ba9c833368e2cfb53c msgid "" "1.set the variables LLM_MODEL=YOUR_MODEL_NAME, " "MODEL_SERVER=YOUR_MODEL_SERVER(eg:http://localhost:5000) in the .env " "file." msgstr "" -#: ../../getting_started/faq/llm/llm_faq.md:31 cd89b8a2075f4407b8036a74151a6377 +#: ../../getting_started/faq/llm/llm_faq.md:31 e5c066bcdf0649a1b33bbfc7fd3b1a66 msgid "2.execute dbgpt_server.py in light mode" msgstr "2.execute dbgpt_server.py light 模式" -#: ../../getting_started/faq/llm/llm_faq.md:33 8f4b9401ac4f4a25a7479bee9ef5e8c1 +#: ../../getting_started/faq/llm/llm_faq.md:33 402ff01d7ee94d97be4a0eb964e39b97 msgid "python pilot/server/dbgpt_server.py --light" msgstr "" -#: ../../getting_started/faq/llm/llm_faq.md:38 69e1064cd7554ce6b49da732f800eacc +#: ../../getting_started/faq/llm/llm_faq.md:38 86190c689d8f4d9a9b58d904e0b5867b #, fuzzy -msgid "Q3 How to use MultiGPUs" -msgstr "Q2 怎么使用 MultiGPUs" +msgid "Q3: How to use MultiGPUs" +msgstr "Q3: 怎么使用 MultiGPUs" -#: ../../getting_started/faq/llm/llm_faq.md:40 6de3f105ce96430db5756f38bbd9ca12 +#: ../../getting_started/faq/llm/llm_faq.md:40 6b08cff88750440b98956203d8b8a084 msgid "" "DB-GPT will use all available gpu by default. And you can modify the " "setting `CUDA_VISIBLE_DEVICES=0,1` in `.env` file to use the specific gpu" " IDs." msgstr "DB-GPT默认加载可利用的gpu,你也可以通过修改 在`.env`文件 `CUDA_VISIBLE_DEVICES=0,1`来指定gpu IDs" -#: ../../getting_started/faq/llm/llm_faq.md:43 87cb9bfb20af4b259d719df797c42a7d +#: ../../getting_started/faq/llm/llm_faq.md:43 93b39089e5be4475b9e90e7813f5a7d9 msgid "" "Optionally, you can also specify the gpu ID to use before the starting " "command, as shown below:" msgstr "你也可以指定gpu ID启动" -#: ../../getting_started/faq/llm/llm_faq.md:53 bcfa35cda6304ee5ab9a775a2d4eda63 +#: ../../getting_started/faq/llm/llm_faq.md:53 62e3074c109d401fa4bf1ddbdc6c7be1 msgid "" "You can modify the setting `MAX_GPU_MEMORY=xxGib` in `.env` file to " "configure the maximum memory used by each GPU." msgstr "同时你可以通过在.env文件设置`MAX_GPU_MEMORY=xxGib`修改每个GPU的最大使用内存" -#: ../../getting_started/faq/llm/llm_faq.md:55 a05c5484927844c8bb4791f0a9ccc82e +#: ../../getting_started/faq/llm/llm_faq.md:55 d235bd83545c476f8e12572658d1c723 #, fuzzy -msgid "Q4 Not Enough Memory" -msgstr "Q3 机器显存不够 " +msgid "Q4: Not Enough Memory" +msgstr "Q4: 机器显存不够 " -#: ../../getting_started/faq/llm/llm_faq.md:57 fe17a023b6eb4a92b1b927e1b94e3784 +#: ../../getting_started/faq/llm/llm_faq.md:57 b3243ed9147f42bba987d7f9b778e66f msgid "DB-GPT supported 8-bit quantization and 4-bit quantization." msgstr "DB-GPT 支持 8-bit quantization 和 4-bit quantization." -#: ../../getting_started/faq/llm/llm_faq.md:59 76c3684c10864b8e87e5c2255b6c0b7f +#: ../../getting_started/faq/llm/llm_faq.md:59 1ddb9f94ab994bfebfee46d1c19888d4 msgid "" "You can modify the setting `QUANTIZE_8bit=True` or `QUANTIZE_4bit=True` " "in `.env` file to use quantization(8-bit quantization is enabled by " "default)." msgstr "你可以通过在.env文件设置`QUANTIZE_8bit=True` or `QUANTIZE_4bit=True`" -#: ../../getting_started/faq/llm/llm_faq.md:61 c5d849a38f1a4f0687bbcffb6699dc39 +#: ../../getting_started/faq/llm/llm_faq.md:61 54b85daa3fb24b17b67a6da31d2be8b0 msgid "" "Llama-2-70b with 8-bit quantization can run with 80 GB of VRAM, and 4-bit" " quantization can run with 48 GB of VRAM." @@ -134,49 +136,77 @@ msgstr "" "Llama-2-70b with 8-bit quantization 可以运行在 80 GB VRAM机器, 4-bit " "quantization可以运行在 48 GB VRAM" -#: ../../getting_started/faq/llm/llm_faq.md:63 867329a5e3b0403083e96f72b8747fb2 +#: ../../getting_started/faq/llm/llm_faq.md:63 097d680aed184fee9eceebee55a47ac1 msgid "" -"Note: you need to install the latest dependencies according to " -"[requirements.txt](https://github.com/eosphoros-ai/DB-" -"GPT/blob/main/requirements.txt)." +"Note: you need to install the quantization dependencies with `pip install" +" -e \".[quantization]\"`" msgstr "" -#: ../../getting_started/faq/llm/llm_faq.md:65 60ceee25e9fb4ddba40c5306bfb0a82f +#: ../../getting_started/faq/llm/llm_faq.md:65 f3a51056043c49eb84471040f2b364aa #, fuzzy -msgid "Q5 How to Add LLM Service dynamic local mode" -msgstr "Q5 怎样动态新增模型服务" +msgid "Q5: How to Add LLM Service dynamic local mode" +msgstr "Q5: 怎样动态新增模型服务" -#: ../../getting_started/faq/llm/llm_faq.md:67 c99eb7f7ae844884a8f0da94238ea7e0 +#: ../../getting_started/faq/llm/llm_faq.md:67 43ee6b0f23814c94a4ddb2429801a5e1 msgid "" "Now DB-GPT through multi-llm service switch, so how to add llm service " "dynamic," msgstr "DB-GPT支持多个模型服务切换, 怎样添加一个模型服务呢" -#: ../../getting_started/faq/llm/llm_faq.md:78 cd89b8a2075f4407b8036a74151a6377 +#: ../../getting_started/faq/llm/llm_faq.md:78 c217bbf0d2b6425fa7a1c691b7704a8d #, fuzzy -msgid "Q6 How to Add LLM Service dynamic in remote mode" -msgstr "Q5 怎样动态新增模型服务" +msgid "Q6: How to Add LLM Service dynamic in remote mode" +msgstr "Q6: 怎样动态新增模型服务" -#: ../../getting_started/faq/llm/llm_faq.md:79 8833ce89465848259b08ef0a4fa68d96 +#: ../../getting_started/faq/llm/llm_faq.md:79 195bdaa937a94c7aa0d8c6e1a5430d6e msgid "" "If you deploy llm service in remote machine instance, and you want to " "add model service to dbgpt server to manage" msgstr "如果你想在远程机器实例部署大模型服务并添加到本地dbgpt_server进行管理" -#: ../../getting_started/faq/llm/llm_faq.md:81 992eb37e3cca48829636c15ba3ec2ee8 +#: ../../getting_started/faq/llm/llm_faq.md:81 c64098b838a94821963a1d16e56497ff msgid "use dbgpt start worker and set --controller_addr." msgstr "使用1`dbgpt start worker`命令并设置注册地址--controller_addr" -#: ../../getting_started/faq/llm/llm_faq.md:91 0d06d7d6dd3d4780894ecd914c89b5a2 +#: ../../getting_started/faq/llm/llm_faq.md:91 cb12d5e9d9d24f14abc3ebea877a4b24 #, fuzzy -msgid "Q7 dbgpt command not found" -msgstr "Q6 dbgpt command not found" +msgid "Q7: dbgpt command not found" +msgstr "Q7: dbgpt command not found" -#: ../../getting_started/faq/llm/llm_faq.md:97 5d9beed0d95a4503a43d0e025664273b +#: ../../getting_started/faq/llm/llm_faq.md:97 f95cdccfa82d4b3eb2a23dd297131faa +#, fuzzy msgid "" -"Q8 When starting the worker_manager on a cloud server and registering it " -"with the controller, it is noticed that the worker's exposed IP is a " +"Q8: When starting the worker_manager on a cloud server and registering it" +" with the controller, it is noticed that the worker's exposed IP is a " "private IP instead of a public IP, which leads to the inability to access" " the service." -msgstr "云服务器启动worker_manager注册到controller时,发现worker暴露的ip是私网ip, 没有以公网ip暴露,导致服务访问不到" +msgstr "" +"Q8: 云服务器启动worker_manager注册到controller时,发现worker暴露的ip是私网ip, " +"没有以公网ip暴露,导致服务访问不到" + +#: ../../getting_started/faq/llm/llm_faq.md:106 +#: 739a2983f3484acf98e877dc12f4ccda +msgid "Q9: How to customize model path and prompt template" +msgstr "Q9: 如何自定义模型路径和 prompt 模板" + +#: ../../getting_started/faq/llm/llm_faq.md:108 +#: 8b82a33a311649c7850c30c00c987c72 +#, fuzzy +msgid "" +"DB-GPT will read the model path from " +"`pilot.configs.model_config.LLM_MODEL_CONFIG` based on the `LLM_MODEL`. " +"Of course, you can use the environment variable `LLM_MODEL_PATH` to " +"specify the model path and `LLM_PROMPT_TEMPLATE` to specify your model " +"prompt template." +msgstr "" +"DB-GPT 会根据 `LLM_MODEL` 从 `pilot.configs.model_config.LLM_MODEL_CONFIG` " +"中读取模型路径。当然,你可以使用环境 `LLM_MODEL_PATH` 来指定模型路径,以及使用 `LLM_PROMPT_TEMPLATE` " +"来指定模型的 prompt 模板。" + +#~ msgid "" +#~ "Note: you need to install the " +#~ "latest dependencies according to " +#~ "[requirements.txt](https://github.com/eosphoros-ai/DB-" +#~ "GPT/blob/main/requirements.txt)." +#~ msgstr "" diff --git a/pilot/configs/config.py b/pilot/configs/config.py index 6213cedf2..b263b46c4 100644 --- a/pilot/configs/config.py +++ b/pilot/configs/config.py @@ -194,6 +194,8 @@ class Config(metaclass=Singleton): ### LLM Model Service Configuration self.LLM_MODEL = os.getenv("LLM_MODEL", "vicuna-13b-v1.5") + self.LLM_MODEL_PATH = os.getenv("LLM_MODEL_PATH") + ### Proxy llm backend, this configuration is only valid when "LLM_MODEL=proxyllm" ### When we use the rest API provided by deployment frameworks like fastchat as a proxyllm, "PROXYLLM_BACKEND" is the model they actually deploy. ### We need to use "PROXYLLM_BACKEND" to load the prompt of the corresponding scene. diff --git a/pilot/model/cluster/controller/controller.py b/pilot/model/cluster/controller/controller.py index 35a91ee3c..173c8c019 100644 --- a/pilot/model/cluster/controller/controller.py +++ b/pilot/model/cluster/controller/controller.py @@ -13,7 +13,7 @@ from pilot.utils.api_utils import ( _api_remote as api_remote, _sync_api_remote as sync_api_remote, ) -from pilot.utils.utils import setup_logging +from pilot.utils.utils import setup_logging, setup_http_service_logging logger = logging.getLogger(__name__) @@ -149,6 +149,7 @@ def initialize_controller( else: import uvicorn + setup_http_service_logging() app = FastAPI() app.include_router(router, prefix="/api", tags=["Model"]) uvicorn.run(app, host=host, port=port, log_level="info") @@ -179,7 +180,8 @@ def run_model_controller(): parser = EnvArgumentParser() env_prefix = "controller_" controller_params: ModelControllerParameters = parser.parse_args_into_dataclass( - ModelControllerParameters, env_prefix=env_prefix + ModelControllerParameters, + env_prefixes=[env_prefix], ) setup_logging( diff --git a/pilot/model/cluster/worker/default_worker.py b/pilot/model/cluster/worker/default_worker.py index 04b47cbdb..5caa2ee7e 100644 --- a/pilot/model/cluster/worker/default_worker.py +++ b/pilot/model/cluster/worker/default_worker.py @@ -76,7 +76,7 @@ class DefaultModelWorker(ModelWorker): model_type = self.llm_adapter.model_type() model_params: ModelParameters = model_args.parse_args_into_dataclass( param_cls, - env_prefix=env_prefix, + env_prefixes=[env_prefix, "LLM_"], command_args=command_args, model_name=self.model_name, model_path=self.model_path, diff --git a/pilot/model/cluster/worker/embedding_worker.py b/pilot/model/cluster/worker/embedding_worker.py index 62b799864..22c644034 100644 --- a/pilot/model/cluster/worker/embedding_worker.py +++ b/pilot/model/cluster/worker/embedding_worker.py @@ -106,7 +106,7 @@ def _parse_embedding_params( env_prefix = EnvArgumentParser.get_env_prefix(model_name) model_params: BaseEmbeddingModelParameters = model_args.parse_args_into_dataclass( param_cls, - env_prefix=env_prefix, + env_prefixes=[env_prefix], command_args=command_args, model_name=model_name, model_path=model_path, diff --git a/pilot/model/cluster/worker/manager.py b/pilot/model/cluster/worker/manager.py index cc5ef97d6..a76fa6685 100644 --- a/pilot/model/cluster/worker/manager.py +++ b/pilot/model/cluster/worker/manager.py @@ -38,7 +38,7 @@ from pilot.utils.parameter_utils import ( _dict_to_command_args, _get_dict_from_obj, ) -from pilot.utils.utils import setup_logging +from pilot.utils.utils import setup_logging, setup_http_service_logging from pilot.utils.tracer import initialize_tracer, root_tracer, SpanType, SpanTypeRunName from pilot.utils.system_utils import get_system_info @@ -735,6 +735,8 @@ def _setup_fastapi( ): if not app: app = FastAPI() + setup_http_service_logging() + if worker_params.standalone: from pilot.model.cluster.controller.controller import initialize_controller from pilot.model.cluster.controller.controller import ( @@ -781,7 +783,7 @@ def _parse_worker_params( env_prefix = EnvArgumentParser.get_env_prefix(model_name) worker_params: ModelWorkerParameters = worker_args.parse_args_into_dataclass( ModelWorkerParameters, - env_prefix=env_prefix, + env_prefixes=[env_prefix], model_name=model_name, model_path=model_path, **kwargs, @@ -790,7 +792,7 @@ def _parse_worker_params( # Read parameters agein with prefix of model name. new_worker_params = worker_args.parse_args_into_dataclass( ModelWorkerParameters, - env_prefix=env_prefix, + env_prefixes=[env_prefix], model_name=worker_params.model_name, model_path=worker_params.model_path, **kwargs, diff --git a/pilot/model/loader.py b/pilot/model/loader.py index 2f5f10c2d..b7cf57815 100644 --- a/pilot/model/loader.py +++ b/pilot/model/loader.py @@ -95,7 +95,7 @@ class ModelLoader: env_prefix = env_prefix.replace("-", "_") model_params = args_parser.parse_args_into_dataclass( param_cls, - env_prefix=env_prefix, + env_prefixes=[env_prefix], device=self.device, model_path=self.model_path, model_name=self.model_name, diff --git a/pilot/model/model_adapter.py b/pilot/model/model_adapter.py index 3809729bc..1580e8863 100644 --- a/pilot/model/model_adapter.py +++ b/pilot/model/model_adapter.py @@ -445,17 +445,47 @@ class VLLMModelAdaperWrapper(LLMModelAdaper): # Covering the configuration of fastcaht, we will regularly feedback the code here to fastchat. # We also recommend that you modify it directly in the fastchat repository. + +# source: https://huggingface.co/BAAI/AquilaChat2-34B/blob/4608b75855334b93329a771aee03869dbf7d88cc/predict.py#L212 register_conv_template( Conversation( - name="internlm-chat", - system_message="A chat between a curious <|User|> and an <|Bot|>. The <|Bot|> gives helpful, detailed, and polite answers to the <|User|>'s questions.\n\n", - roles=("<|User|>", "<|Bot|>"), - sep_style=SeparatorStyle.CHATINTERN, - sep="", - sep2="", - stop_token_ids=[1, 103028], - # TODO feedback stop_str to fastchat - stop_str="", - ), - override=True, + name="aquila-legacy", + system_message="A chat between a curious human and an artificial intelligence assistant. " + "The assistant gives helpful, detailed, and polite answers to the human's questions.\n\n", + roles=("### Human: ", "### Assistant: ", "System"), + messages=(), + offset=0, + sep_style=SeparatorStyle.NO_COLON_TWO, + sep="\n", + sep2="", + stop_str=["", "[UNK]"], + ) +) +# source: https://huggingface.co/BAAI/AquilaChat2-34B/blob/4608b75855334b93329a771aee03869dbf7d88cc/predict.py#L227 +register_conv_template( + Conversation( + name="aquila", + system_message="A chat between a curious human and an artificial intelligence assistant. " + "The assistant gives helpful, detailed, and polite answers to the human's questions.", + roles=("Human", "Assistant", "System"), + messages=(), + offset=0, + sep_style=SeparatorStyle.ADD_COLON_TWO, + sep="###", + sep2="", + stop_str=["", "[UNK]"], + ) +) +# source: https://huggingface.co/BAAI/AquilaChat2-34B/blob/4608b75855334b93329a771aee03869dbf7d88cc/predict.py#L242 +register_conv_template( + Conversation( + name="aquila-v1", + roles=("<|startofpiece|>", "<|endofpiece|>", ""), + messages=(), + offset=0, + sep_style=SeparatorStyle.NO_COLON_TWO, + sep="", + sep2="", + stop_str=["", "<|endoftext|>"], + ) ) diff --git a/pilot/model/proxy/llms/chatgpt.py b/pilot/model/proxy/llms/chatgpt.py index a2aff0b86..ab95e58f6 100644 --- a/pilot/model/proxy/llms/chatgpt.py +++ b/pilot/model/proxy/llms/chatgpt.py @@ -5,8 +5,6 @@ import os from typing import List import logging -import openai - from pilot.model.proxy.llms.proxy_model import ProxyModel from pilot.model.parameter import ProxyModelParameters from pilot.scene.base_message import ModelMessage, ModelMessageRoleType @@ -15,6 +13,14 @@ logger = logging.getLogger(__name__) def _initialize_openai(params: ProxyModelParameters): + try: + import openai + except ImportError as exc: + raise ValueError( + "Could not import python package: openai " + "Please install openai by command `pip install openai` " + ) from exc + api_type = params.proxy_api_type or os.getenv("OPENAI_API_TYPE", "open_ai") api_base = params.proxy_api_base or os.getenv( @@ -106,6 +112,8 @@ def _build_request(model: ProxyModel, params): def chatgpt_generate_stream( model: ProxyModel, tokenizer, params, device, context_len=2048 ): + import openai + history, payloads = _build_request(model, params) res = openai.ChatCompletion.create(messages=history, **payloads) @@ -121,6 +129,8 @@ def chatgpt_generate_stream( async def async_chatgpt_generate_stream( model: ProxyModel, tokenizer, params, device, context_len=2048 ): + import openai + history, payloads = _build_request(model, params) res = await openai.ChatCompletion.acreate(messages=history, **payloads) diff --git a/pilot/server/dbgpt_server.py b/pilot/server/dbgpt_server.py index c6e084a93..e94526b9a 100644 --- a/pilot/server/dbgpt_server.py +++ b/pilot/server/dbgpt_server.py @@ -2,6 +2,7 @@ import os import argparse import sys from typing import List +import logging ROOT_PATH = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.append(ROOT_PATH) @@ -39,6 +40,7 @@ from pilot.utils.utils import ( setup_logging, _get_logging_level, logging_str_to_uvicorn_level, + setup_http_service_logging, ) from pilot.utils.tracer import root_tracer, initialize_tracer, SpanType, SpanTypeRunName from pilot.utils.parameter_utils import _get_dict_from_obj @@ -127,6 +129,7 @@ def initialize_app(param: WebWerverParameters = None, args: List[str] = None): setup_logging( "pilot", logging_level=param.log_level, logger_filename=param.log_file ) + # Before start system_app.before_start() @@ -141,7 +144,7 @@ def initialize_app(param: WebWerverParameters = None, args: List[str] = None): model_name = param.model_name or CFG.LLM_MODEL - model_path = LLM_MODEL_CONFIG.get(model_name) + model_path = CFG.LLM_MODEL_PATH or LLM_MODEL_CONFIG.get(model_name) if not param.light: print("Model Unified Deployment Mode!") if not param.remote_embedding: @@ -180,6 +183,7 @@ def initialize_app(param: WebWerverParameters = None, args: List[str] = None): def run_uvicorn(param: WebWerverParameters): import uvicorn + setup_http_service_logging() uvicorn.run( app, host=param.host, diff --git a/pilot/utils/parameter_utils.py b/pilot/utils/parameter_utils.py index fbf9c5fb5..e76904203 100644 --- a/pilot/utils/parameter_utils.py +++ b/pilot/utils/parameter_utils.py @@ -190,6 +190,17 @@ def _genenv_ignoring_key_case(env_key: str, env_prefix: str = None, default_valu ) +def _genenv_ignoring_key_case_with_prefixes( + env_key: str, env_prefixes: List[str] = None, default_value=None +) -> str: + if env_prefixes: + for env_prefix in env_prefixes: + env_var_value = _genenv_ignoring_key_case(env_key, env_prefix) + if env_var_value: + return env_var_value + return _genenv_ignoring_key_case(env_key, default_value=default_value) + + class EnvArgumentParser: @staticmethod def get_env_prefix(env_key: str) -> str: @@ -201,18 +212,16 @@ class EnvArgumentParser: def parse_args_into_dataclass( self, dataclass_type: Type, - env_prefix: str = None, + env_prefixes: List[str] = None, command_args: List[str] = None, **kwargs, ) -> Any: """Parse parameters from environment variables and command lines and populate them into data class""" parser = argparse.ArgumentParser() for field in fields(dataclass_type): - env_var_value = _genenv_ignoring_key_case(field.name, env_prefix) - if not env_var_value: - # Read without env prefix - env_var_value = _genenv_ignoring_key_case(field.name) - + env_var_value = _genenv_ignoring_key_case_with_prefixes( + field.name, env_prefixes + ) if env_var_value: env_var_value = env_var_value.strip() if field.type is int or field.type == Optional[int]: diff --git a/pilot/utils/utils.py b/pilot/utils/utils.py index b72745a33..e3add3a0a 100644 --- a/pilot/utils/utils.py +++ b/pilot/utils/utils.py @@ -3,6 +3,8 @@ import logging import logging.handlers +from typing import Any, List + import os import sys import asyncio @@ -184,3 +186,42 @@ def logging_str_to_uvicorn_level(log_level_str): "NOTSET": "info", } return level_str_mapping.get(log_level_str.upper(), "info") + + +class EndpointFilter(logging.Filter): + """Disable access log on certain endpoint + + source: https://github.com/encode/starlette/issues/864#issuecomment-1254987630 + """ + + def __init__( + self, + path: str, + *args: Any, + **kwargs: Any, + ): + super().__init__(*args, **kwargs) + self._path = path + + def filter(self, record: logging.LogRecord) -> bool: + return record.getMessage().find(self._path) == -1 + + +def setup_http_service_logging(exclude_paths: List[str] = None): + """Setup http service logging + + Now just disable some logs + + Args: + exclude_paths (List[str]): The paths to disable log + """ + if not exclude_paths: + # Not show heartbeat log + exclude_paths = ["/api/controller/heartbeat"] + uvicorn_logger = logging.getLogger("uvicorn.access") + if uvicorn_logger: + for path in exclude_paths: + uvicorn_logger.addFilter(EndpointFilter(path=path)) + httpx_logger = logging.getLogger("httpx") + if httpx_logger: + httpx_logger.setLevel(logging.WARNING) From b3d3716de74903f6a725f5915bca1629c0881c07 Mon Sep 17 00:00:00 2001 From: Aditya Aryaman Das <128703909+alienishi@users.noreply.github.com> Date: Mon, 30 Oct 2023 13:33:21 +0530 Subject: [PATCH 12/57] docs: corrected all grammatical errors in README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index c819c8a51..4a6878297 100644 --- a/README.md +++ b/README.md @@ -107,11 +107,11 @@ Currently, we have released multiple key features, which are listed below to dem - Multi-Agents&Plugins - Supports custom plug-ins to perform tasks, natively supports the Auto-GPT plug-in model, and the Agents protocol adopts the Agent Protocol standard + It supports custom plug-ins to perform tasks, natively supports the Auto-GPT plug-in model, and the Agents protocol adopts the Agent Protocol standard. - Fine-tuning text2SQL - An automated fine-tuning lightweight framework built around large language models, Text2SQL data sets, LoRA/QLoRA/Pturning and other fine-tuning methods, making TextSQL fine-tuning as convenient as an assembly line. [DB-GPT-Hub](https://github.com/eosphoros-ai/DB-GPT-Hub) + An automated fine-tuning lightweight framework built around large language models, Text2SQL data sets, LoRA/QLoRA/Pturning, and other fine-tuning methods, making TextSQL fine-tuning as convenient as an assembly line. [DB-GPT-Hub](https://github.com/eosphoros-ai/DB-GPT-Hub) - Multi LLMs Support, Supports multiple large language models, currently supporting @@ -141,7 +141,7 @@ Currently, we have released multiple key features, which are listed below to dem - [Llama2-Chinese-13b-Chat](https://huggingface.co/FlagAlpha/Llama2-Chinese-13b-Chat) - [OpenLLaMa OpenInstruct](https://huggingface.co/VMware/open-llama-7b-open-instruct) - etc. + Etc. - Support API Proxy LLMs - [x] [ChatGPT](https://api.openai.com/) @@ -151,7 +151,7 @@ Currently, we have released multiple key features, which are listed below to dem - Privacy and security - The privacy and security of data are ensured through various technologies such as privatized large models and proxy desensitization. + The privacy and security of data are ensured through various technologies, such as privatized large models and proxy desensitization. - Support Datasources @@ -185,7 +185,7 @@ Is the architecture of the entire DB-GPT shown in the following figure: The core capabilities mainly consist of the following parts: 1. Multi-Models: Support multi-LLMs, such as LLaMA/LLaMA2、CodeLLaMA、ChatGLM, QWen、Vicuna and proxy model ChatGPT、Baichuan、tongyi、wenxin etc -2. Knowledge Based QA: You can perform high-quality intelligent Q&A based on local documents such as pdf, word, excel and other data. +2. Knowledge-Based QA: You can perform high-quality intelligent Q&A based on local documents such as PDF, word, excel, and other data. 3. Embedding: Unified data vector storage and indexing, Embed data as vectors and store them in vector databases, providing content similarity search. 4. Multi-Datasources: Used to connect different modules and data sources to achieve data flow and interaction. 5. Multi-Agents: Provides Agent and plugin mechanisms, allowing users to customize and enhance the system's behavior. @@ -199,7 +199,7 @@ The core capabilities mainly consist of the following parts: ### SubModule - [DB-GPT-Hub](https://github.com/eosphoros-ai/DB-GPT-Hub) Text-to-SQL performance by applying Supervised Fine-Tuning (SFT) on large language models. -- [DB-GPT-Plugins](https://github.com/eosphoros-ai/DB-GPT-Plugins) DB-GPT Plugins, Can run autogpt plugin directly +- [DB-GPT-Plugins](https://github.com/eosphoros-ai/DB-GPT-Plugins) DB-GPT Plugins Can run autogpt plugin directly - [DB-GPT-Web](https://github.com/eosphoros-ai/DB-GPT-Web) ChatUI for DB-GPT ## Image @@ -213,7 +213,7 @@ The core capabilities mainly consist of the following parts: ## Contribution -- Please run `black .` before submitting the code. contributing guidelines, [how to contribution](https://github.com/csunny/DB-GPT/blob/main/CONTRIBUTING.md) +- Please run `black .` before submitting the code. Contributing guidelines, [how to contribution](https://github.com/csunny/DB-GPT/blob/main/CONTRIBUTING.md) ## RoadMap @@ -224,7 +224,7 @@ The core capabilities mainly consist of the following parts: ### KBQA RAG optimization - [x] Multi Documents - [x] PDF - - [x] Excel, csv + - [x] Excel, CSV - [x] Word - [x] Text - [x] MarkDown @@ -235,7 +235,7 @@ The core capabilities mainly consist of the following parts: - [ ] Graph Database - [ ] Neo4j Graph - [ ] Nebula Graph -- [x] Multi Vector Database +- [x] Multi-Vector Database - [x] Chroma - [x] Milvus - [x] Weaviate From 7619a16c163abd1a9fb52cfad097815d3d8b7364 Mon Sep 17 00:00:00 2001 From: wangzaistone Date: Mon, 30 Oct 2023 17:06:24 +0800 Subject: [PATCH 13/57] support DB-GPT-Hub sft codellama --- .env.template | 3 ++- pilot/configs/model_config.py | 2 ++ pilot/model/adapter.py | 13 +++++++++++++ pilot/model/conversation.py | 22 ++++++++++++++++++++++ pilot/model/model_adapter.py | 1 + pilot/server/chat_adapter.py | 10 ++++++++++ 6 files changed, 50 insertions(+), 1 deletion(-) diff --git a/.env.template b/.env.template index e03650033..272ee2922 100644 --- a/.env.template +++ b/.env.template @@ -22,7 +22,8 @@ WEB_SERVER_PORT=7860 #** LLM MODELS **# #*******************************************************************# # LLM_MODEL, see /pilot/configs/model_config.LLM_MODEL_CONFIG -LLM_MODEL=vicuna-13b-v1.5 +# LLM_MODEL=vicuna-13b-v1.5 +LLM_MODEL=codellama-13b-sql-sft ## LLM model path, by default, DB-GPT will read the model path from LLM_MODEL_CONFIG based on the LLM_MODEL. ## Of course you can specify your model path according to LLM_MODEL_PATH ## In DB-GPT, the priority from high to low to read model path: diff --git a/pilot/configs/model_config.py b/pilot/configs/model_config.py index e1575ea03..16deee50a 100644 --- a/pilot/configs/model_config.py +++ b/pilot/configs/model_config.py @@ -78,6 +78,8 @@ LLM_MODEL_CONFIG = { "internlm-7b": os.path.join(MODEL_PATH, "internlm-chat-7b"), "internlm-7b-8k": os.path.join(MODEL_PATH, "internlm-chat-7b-8k"), "internlm-20b": os.path.join(MODEL_PATH, "internlm-chat-20b"), + "codellama-13b-sql-sft": os.path.join(MODEL_PATH, "codellama-13b-sql-sft"), + # For test now "opt-125m": os.path.join(MODEL_PATH, "opt-125m"), } diff --git a/pilot/model/adapter.py b/pilot/model/adapter.py index 69b159a13..02fbe8aa9 100644 --- a/pilot/model/adapter.py +++ b/pilot/model/adapter.py @@ -319,6 +319,18 @@ class Llama2Adapter(BaseLLMAdaper): model.config.pad_token_id = tokenizer.pad_token_id return model, tokenizer +class CodeLlamaAdapter(BaseLLMAdaper): + """The model adapter for codellama """ + + def match(self, model_path: str): + return "codelama" in model_path.lower() + + def loader(self, model_path: str, from_pretrained_kwargs: dict): + model, tokenizer = super().loader(model_path, from_pretrained_kwargs) + model.config.eos_token_id = tokenizer.eos_token_id + model.config.pad_token_id = tokenizer.pad_token_id + return model, tokenizer + class BaichuanAdapter(BaseLLMAdaper): """The model adapter for Baichuan models (e.g., baichuan-inc/Baichuan-13B-Chat)""" @@ -420,6 +432,7 @@ register_llm_model_adapters(FalconAdapater) register_llm_model_adapters(GorillaAdapter) register_llm_model_adapters(GPT4AllAdapter) register_llm_model_adapters(Llama2Adapter) +register_llm_model_adapters(CodeLlamaAdapter) register_llm_model_adapters(BaichuanAdapter) register_llm_model_adapters(WizardLMAdapter) register_llm_model_adapters(LlamaCppAdapater) diff --git a/pilot/model/conversation.py b/pilot/model/conversation.py index b3674e946..98dfc720d 100644 --- a/pilot/model/conversation.py +++ b/pilot/model/conversation.py @@ -339,6 +339,28 @@ register_conv_template( ) ) + +# codellama template +# reference: https://github.com/facebookresearch/llama/blob/cfc3fc8c1968d390eb830e65c63865e980873a06/llama/generation.py#L212 +# reference2 : https://github.com/eosphoros-ai/DB-GPT-Hub/blob/main/README.zh.md +register_conv_template( + Conversation( + name="codellama", + system="[INST] <>\nI want you to act as a SQL terminal in front of an example database, you need only to return the sql command to me.Below is an instruction that describes a task, Write a response that appropriately completes the request." + "If you don't know the answer to the request, please don't share false information.\n<>\n\n", + roles=("[INST]", "[/INST]"), + messages=(), + offset=0, + sep_style=SeparatorStyle.LLAMA2, + sep=" ", + sep2=" ", + stop_token_ids=[2], + system_formatter=lambda msg: f"[INST] <>\n{msg}\n<>\n\n", + ) +) + + + # Alpaca default template register_conv_template( Conversation( diff --git a/pilot/model/model_adapter.py b/pilot/model/model_adapter.py index 1580e8863..112fb468a 100644 --- a/pilot/model/model_adapter.py +++ b/pilot/model/model_adapter.py @@ -45,6 +45,7 @@ _OLD_MODELS = [ "llama-cpp", "proxyllm", "gptj-6b", + "codellama-13b-sql-sft" ] diff --git a/pilot/server/chat_adapter.py b/pilot/server/chat_adapter.py index cb486021b..509305247 100644 --- a/pilot/server/chat_adapter.py +++ b/pilot/server/chat_adapter.py @@ -213,6 +213,15 @@ class Llama2ChatAdapter(BaseChatAdpter): def get_conv_template(self, model_path: str) -> Conversation: return get_conv_template("llama-2") + + +class CodeLlamaChatAdapter(BaseChatAdpter): + """The model ChatAdapter for codellama .""" + def match(self, model_path: str): + return "codelama" in model_path.lower() + + def get_conv_template(self, model_path: str) -> Conversation: + return get_conv_template("codellama") class BaichuanChatAdapter(BaseChatAdpter): @@ -268,6 +277,7 @@ register_llm_model_chat_adapter(FalconChatAdapter) register_llm_model_chat_adapter(GorillaChatAdapter) register_llm_model_chat_adapter(GPT4AllChatAdapter) register_llm_model_chat_adapter(Llama2ChatAdapter) +register_llm_model_chat_adapter(CodeLlamaChatAdapter) register_llm_model_chat_adapter(BaichuanChatAdapter) register_llm_model_chat_adapter(WizardLMChatAdapter) register_llm_model_chat_adapter(LlamaCppChatAdapter) From 53b1fc40901cb59ebcdc93caaa852c942ea5f858 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Mon, 30 Oct 2023 19:06:09 +0800 Subject: [PATCH 14/57] feat:document summary --- pilot/scene/base.py | 7 ++ pilot/scene/base_chat.py | 2 - pilot/scene/chat_factory.py | 1 + pilot/server/knowledge/document_db.py | 3 +- pilot/server/knowledge/request/response.py | 3 +- pilot/server/knowledge/service.py | 89 ++++++++++++++++------ 6 files changed, 79 insertions(+), 26 deletions(-) diff --git a/pilot/scene/base.py b/pilot/scene/base.py index 5c98003d9..e3478f7c3 100644 --- a/pilot/scene/base.py +++ b/pilot/scene/base.py @@ -96,6 +96,13 @@ class ChatScene(Enum): ["Extract Select"], True, ) + ExtractRefineSummary = Scene( + "extract_refine_summary", + "Extract Summary", + "Extract Summary", + ["Extract Select"], + True, + ) ExtractEntity = Scene( "extract_entity", "Extract Entity", "Extract Entity", ["Extract Select"], True ) diff --git a/pilot/scene/base_chat.py b/pilot/scene/base_chat.py index 73a2c5ef6..e43cdc812 100644 --- a/pilot/scene/base_chat.py +++ b/pilot/scene/base_chat.py @@ -127,8 +127,6 @@ class BaseChat(ABC): speak_to_user = prompt_define_response return speak_to_user - async def __call_base(self): - input_values = await self.generate_input_values() async def __call_base(self): import inspect diff --git a/pilot/scene/chat_factory.py b/pilot/scene/chat_factory.py index 2e103f15d..10a588c04 100644 --- a/pilot/scene/chat_factory.py +++ b/pilot/scene/chat_factory.py @@ -17,6 +17,7 @@ class ChatFactory(metaclass=Singleton): from pilot.scene.chat_knowledge.extract_triplet.chat import ExtractTriplet from pilot.scene.chat_knowledge.extract_entity.chat import ExtractEntity from pilot.scene.chat_knowledge.summary.chat import ExtractSummary + from pilot.scene.chat_knowledge.refine_summary.chat import ExtractRefineSummary from pilot.scene.chat_data.chat_excel.excel_analyze.chat import ChatExcel from pilot.scene.chat_agent.chat import ChatAgent diff --git a/pilot/server/knowledge/document_db.py b/pilot/server/knowledge/document_db.py index 3e6dfb0c4..bbe1426d7 100644 --- a/pilot/server/knowledge/document_db.py +++ b/pilot/server/knowledge/document_db.py @@ -30,11 +30,12 @@ class KnowledgeDocumentEntity(Base): content = Column(Text) result = Column(Text) vector_ids = Column(Text) + summary = Column(Text) gmt_created = Column(DateTime) gmt_modified = Column(DateTime) def __repr__(self): - return f"KnowledgeDocumentEntity(id={self.id}, doc_name='{self.doc_name}', doc_type='{self.doc_type}', chunk_size='{self.chunk_size}', status='{self.status}', last_sync='{self.last_sync}', content='{self.content}', result='{self.result}', gmt_created='{self.gmt_created}', gmt_modified='{self.gmt_modified}')" + return f"KnowledgeDocumentEntity(id={self.id}, doc_name='{self.doc_name}', doc_type='{self.doc_type}', chunk_size='{self.chunk_size}', status='{self.status}', last_sync='{self.last_sync}', content='{self.content}', result='{self.result}', summary='{self.summary}', gmt_created='{self.gmt_created}', gmt_modified='{self.gmt_modified}')" class KnowledgeDocumentDao(BaseDao): diff --git a/pilot/server/knowledge/request/response.py b/pilot/server/knowledge/request/response.py index fb7aa55e9..2e3e5f0ab 100644 --- a/pilot/server/knowledge/request/response.py +++ b/pilot/server/knowledge/request/response.py @@ -5,8 +5,9 @@ from pydantic import BaseModel class ChunkQueryResponse(BaseModel): """data: data""" - data: List = None + """summary: document summary""" + summary: str = None """total: total size""" total: int = None """page: current page""" diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index 4c1c41994..017fef3ec 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -288,8 +288,8 @@ class KnowledgeService: executor = CFG.SYSTEM_APP.get_component( ComponentType.EXECUTOR_DEFAULT, ExecutorFactory ).create() - executor.submit(self.async_knowledge_graph, chunk_docs, doc) - # executor.submit(self.async_doc_embedding, client, chunk_docs, doc) + executor.submit(self.async_document_summary, chunk_docs, doc) + executor.submit(self.async_doc_embedding, client, chunk_docs, doc) logger.info(f"begin save document chunks, doc:{doc.doc_name}") # save chunk details chunk_entities = [ @@ -384,38 +384,59 @@ class KnowledgeService: doc_name=request.doc_name, doc_type=request.doc_type, ) + document_query = KnowledgeDocumentEntity(id=request.document_id) + documents = knowledge_document_dao.get_documents(document_query) + res = ChunkQueryResponse() res.data = document_chunk_dao.get_document_chunks( query, page=request.page, page_size=request.page_size ) + res.summary = documents[0].summary res.total = document_chunk_dao.get_document_chunks_count(query) res.page = request.page return res + def async_knowledge_graph(self, chunk_docs, doc): """async document extract triplets and save into graph db Args: - chunk_docs: List[Document] - doc: KnowledgeDocumentEntity """ - for doc in chunk_docs: - text = doc.page_content - self._llm_extract_summary(text) logger.info( f"async_knowledge_graph, doc:{doc.doc_name}, chunk_size:{len(chunk_docs)}, begin embedding to graph store" ) - # try: - # from pilot.graph_engine.graph_factory import RAGGraphFactory - # - # rag_engine = CFG.SYSTEM_APP.get_component( - # ComponentType.RAG_GRAPH_DEFAULT.value, RAGGraphFactory - # ).create() - # rag_engine.knowledge_graph(chunk_docs) - # doc.status = SyncStatus.FINISHED.name - # doc.result = "document build graph success" - # except Exception as e: - # doc.status = SyncStatus.FAILED.name - # doc.result = "document build graph failed" + str(e) - # logger.error(f"document build graph failed:{doc.doc_name}, {str(e)}") + try: + from pilot.graph_engine.graph_factory import RAGGraphFactory + + rag_engine = CFG.SYSTEM_APP.get_component( + ComponentType.RAG_GRAPH_DEFAULT.value, RAGGraphFactory + ).create() + rag_engine.knowledge_graph(chunk_docs) + doc.status = SyncStatus.FINISHED.name + doc.result = "document build graph success" + except Exception as e: + doc.status = SyncStatus.FAILED.name + doc.result = "document build graph failed" + str(e) + logger.error(f"document build graph failed:{doc.doc_name}, {str(e)}") + return knowledge_document_dao.update_knowledge_document(doc) + + def async_document_summary(self, chunk_docs, doc): + """async document extract summary + Args: + - chunk_docs: List[Document] + - doc: KnowledgeDocumentEntity + """ + from llama_index import PromptHelper + from llama_index.prompts.default_prompt_selectors import DEFAULT_TREE_SUMMARIZE_PROMPT_SEL + texts = [doc.page_content for doc in chunk_docs] + prompt_helper = PromptHelper() + texts = prompt_helper.repack(prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=texts) + summary = self._llm_extract_summary(chunk_docs[0]) + outputs, summary = self._refine_extract_summary(texts[1:], summary) + logger.info( + f"async_document_summary, doc:{doc.doc_name}, chunk_size:{len(chunk_docs)}, begin embedding to graph store" + ) + doc.summary = summary return knowledge_document_dao.update_knowledge_document(doc) @@ -491,15 +512,39 @@ class KnowledgeService: chat_param = { "chat_session_id": uuid.uuid1(), - "current_user_input": doc, - "select_param": "summery", + "current_user_input": doc.page_content, + "select_param": "summary", "model_name": "proxyllm", } from pilot.utils import utils loop = utils.get_or_create_event_loop() - triplets = loop.run_until_complete( + summary = loop.run_until_complete( llm_chat_response_nostream( ChatScene.ExtractSummary.value(), **{"chat_param": chat_param} ) ) - return triplets + return summary + def _refine_extract_summary(self, docs, summary: str): + """Extract refine summary by llm""" + from pilot.scene.base import ChatScene + from pilot.common.chat_util import llm_chat_response_nostream + import uuid + outputs = [] + for doc in docs: + chat_param = { + "chat_session_id": uuid.uuid1(), + "current_user_input": doc, + "select_param": summary, + "model_name": "proxyllm", + } + from pilot.utils import utils + loop = utils.get_or_create_event_loop() + summary = loop.run_until_complete( + llm_chat_response_nostream( + ChatScene.ExtractRefineSummary.value(), **{"chat_param": chat_param} + ) + ) + outputs.append(summary) + return outputs, summary + + From d4d231afe742753f49af7b475eeb8d8b58b6e538 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Mon, 30 Oct 2023 19:09:00 +0800 Subject: [PATCH 15/57] chore:discord expire --- README.md | 8 ++++---- README.zh.md | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index c819c8a51..b73db828d 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,8 @@ Open Issues - - Discord + + Discord Open in GitHub Codespaces @@ -34,7 +34,7 @@

-[**简体中文**](README.zh.md) |[**Discord**](https://discord.gg/vqBrcV7Nd) |[**Documents**](https://db-gpt.readthedocs.io/en/latest/)|[**Wechat**](https://github.com/eosphoros-ai/DB-GPT/blob/main/README.zh.md#%E8%81%94%E7%B3%BB%E6%88%91%E4%BB%AC)|[**Community**](https://github.com/eosphoros-ai/community) +[**简体中文**](README.zh.md) |[**Discord**](https://discord.gg/nASQyBjvY) |[**Documents**](https://db-gpt.readthedocs.io/en/latest/)|[**Wechat**](https://github.com/eosphoros-ai/DB-GPT/blob/main/README.zh.md#%E8%81%94%E7%B3%BB%E6%88%91%E4%BB%AC)|[**Community**](https://github.com/eosphoros-ai/community) ## What is DB-GPT? @@ -331,7 +331,7 @@ The MIT License (MIT) ## Contact Information We are working on building a community, if you have any ideas about building the community, feel free to contact us. -[![](https://dcbadge.vercel.app/api/server/vqBrcV7Nd?compact=true&style=flat)](https://discord.gg/vqBrcV7Nd) +[![](https://dcbadge.vercel.app/api/server/nASQyBjvY?compact=true&style=flat)](https://discord.gg/nASQyBjvY)

diff --git a/README.zh.md b/README.zh.md index a6119663d..dca465541 100644 --- a/README.zh.md +++ b/README.zh.md @@ -22,15 +22,15 @@ Open Issues - - Discord + + Discord Open in GitHub Codespaces

-[**English**](README.md)|[**Discord**](https://discord.gg/vqBrcV7Nd)|[**文档**](https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-cn/zh_CN/latest/)|[**微信**](https://github.com/csunny/DB-GPT/blob/main/README.zh.md#%E8%81%94%E7%B3%BB%E6%88%91%E4%BB%AC)|[**社区**](https://github.com/eosphoros-ai/community) +[**English**](README.md)|[**Discord**](https://discord.gg/nASQyBjvY)|[**文档**](https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-cn/zh_CN/latest/)|[**微信**](https://github.com/csunny/DB-GPT/blob/main/README.zh.md#%E8%81%94%E7%B3%BB%E6%88%91%E4%BB%AC)|[**社区**](https://github.com/eosphoros-ai/community) ## DB-GPT 是什么? From 6841050d43c015c6355549b3834d7743b4275cdb Mon Sep 17 00:00:00 2001 From: hairyputtar <148847552+hairyputtar@users.noreply.github.com> Date: Mon, 30 Oct 2023 22:11:32 +0530 Subject: [PATCH 16/57] fix typo --- docs/getting_started/install/environment/environment.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting_started/install/environment/environment.md b/docs/getting_started/install/environment/environment.md index 4c8b23751..021bbe861 100644 --- a/docs/getting_started/install/environment/environment.md +++ b/docs/getting_started/install/environment/environment.md @@ -59,11 +59,11 @@ Embedding Chunk size, default 500 Embedding Chunk Overlap, default 100 * KNOWLEDGE_CHUNK_OVERLAP=100 -embeding recall top k,5 +embedding recall top k,5 * KNOWLEDGE_SEARCH_TOP_SIZE=5 -embeding recall max token ,2000 +embedding recall max token ,2000 * KNOWLEDGE_SEARCH_MAX_TOKEN=5 ``` From e74e37f8187206466c9db028c5018f6e5954883e Mon Sep 17 00:00:00 2001 From: Abhishekgupta204 <116148980+Abhishekgupta204@users.noreply.github.com> Date: Mon, 30 Oct 2023 23:16:52 +0530 Subject: [PATCH 17/57] Added CODE_OF_CONDUCT file --- CODE_OF_CONDUCT | 126 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 CODE_OF_CONDUCT diff --git a/CODE_OF_CONDUCT b/CODE_OF_CONDUCT new file mode 100644 index 000000000..b7efcc0b3 --- /dev/null +++ b/CODE_OF_CONDUCT @@ -0,0 +1,126 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[INSERT CONTACT METHOD]. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +*Community Impact*: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +*Consequence*: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +*Community Impact*: A violation through a single incident or series of +actions. + +*Consequence*: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +*Community Impact*: A serious violation of community standards, including +sustained inappropriate behavior. + +*Consequence*: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +*Community Impact*: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +*Consequence*: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. From 29dac02955c02da2bbe50a0472d32db3a707c13f Mon Sep 17 00:00:00 2001 From: chinmay7016 <75988613+chinmay7016@users.noreply.github.com> Date: Tue, 31 Oct 2023 00:27:51 +0530 Subject: [PATCH 18/57] Update and rename knownledge.md to knowledge.md typo solved --- docs/modules/{knownledge.md => knowledge.md} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename docs/modules/{knownledge.md => knowledge.md} (97%) diff --git a/docs/modules/knownledge.md b/docs/modules/knowledge.md similarity index 97% rename from docs/modules/knownledge.md rename to docs/modules/knowledge.md index 03fb45eec..7c8b2758f 100644 --- a/docs/modules/knownledge.md +++ b/docs/modules/knowledge.md @@ -1,4 +1,4 @@ -# Knownledge +# Knowledge As the knowledge base is currently the most significant user demand scenario, we natively support the construction and processing of knowledge bases. At the same time, we also provide multiple knowledge base management strategies in this project, such as: 1. Default built-in knowledge base @@ -32,4 +32,4 @@ Optionally, you can run `dbgpt knowledge load --help` command to see more usage. 3.Add the knowledge repository in the interface by entering the name of your knowledge repository (if not specified, enter "default") so you can use it for Q&A based on your knowledge base. -Note that the default vector model used is text2vec-large-chinese (which is a large model, so if your personal computer configuration is not enough, it is recommended to use text2vec-base-chinese). Therefore, ensure that you download the model and place it in the models directory. \ No newline at end of file +Note that the default vector model used is text2vec-large-chinese (which is a large model, so if your personal computer configuration is not enough, it is recommended to use text2vec-base-chinese). Therefore, ensure that you download the model and place it in the models directory. From dca3ddb93113cd426e26253fdebffaec37f0da4b Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Tue, 31 Oct 2023 13:47:19 +0800 Subject: [PATCH 19/57] feat:add summary --- pilot/common/chat_util.py | 35 ++++++++++++ .../chat_knowledge/refine_summary/__init__.py | 0 .../chat_knowledge/refine_summary/chat.py | 37 ++++++++++++ .../refine_summary/out_parser.py | 57 +++++++++++++++++++ .../chat_knowledge/refine_summary/prompt.py | 40 +++++++++++++ .../scene/chat_knowledge/summary/__init__.py | 0 pilot/scene/chat_knowledge/summary/chat.py | 35 ++++++++++++ .../chat_knowledge/summary/out_parser.py | 28 +++++++++ pilot/scene/chat_knowledge/summary/prompt.py | 47 +++++++++++++++ pilot/server/knowledge/service.py | 41 +++++++++++-- 10 files changed, 315 insertions(+), 5 deletions(-) create mode 100644 pilot/scene/chat_knowledge/refine_summary/__init__.py create mode 100644 pilot/scene/chat_knowledge/refine_summary/chat.py create mode 100644 pilot/scene/chat_knowledge/refine_summary/out_parser.py create mode 100644 pilot/scene/chat_knowledge/refine_summary/prompt.py create mode 100644 pilot/scene/chat_knowledge/summary/__init__.py create mode 100644 pilot/scene/chat_knowledge/summary/chat.py create mode 100644 pilot/scene/chat_knowledge/summary/out_parser.py create mode 100644 pilot/scene/chat_knowledge/summary/prompt.py diff --git a/pilot/common/chat_util.py b/pilot/common/chat_util.py index 0de0b9bda..ae0ce73ed 100644 --- a/pilot/common/chat_util.py +++ b/pilot/common/chat_util.py @@ -1,4 +1,5 @@ import asyncio +from typing import Coroutine, List, Any from starlette.responses import StreamingResponse @@ -18,3 +19,37 @@ async def llm_chat_response_nostream(chat_scene: str, **chat_param): async def llm_chat_response(chat_scene: str, **chat_param): chat: BaseChat = chat_factory.get_implementation(chat_scene, **chat_param) return chat.stream_call() + + +def run_async_tasks( + tasks: List[Coroutine], + show_progress: bool = False, + progress_bar_desc: str = "Running async tasks", +) -> List[Any]: + """Run a list of async tasks.""" + + tasks_to_execute: List[Any] = tasks + if show_progress: + try: + import nest_asyncio + from tqdm.asyncio import tqdm + + nest_asyncio.apply() + loop = asyncio.get_event_loop() + + async def _tqdm_gather() -> List[Any]: + return await tqdm.gather(*tasks_to_execute, desc=progress_bar_desc) + + tqdm_outputs: List[Any] = loop.run_until_complete(_tqdm_gather()) + return tqdm_outputs + # run the operation w/o tqdm on hitting a fatal + # may occur in some environments where tqdm.asyncio + # is not supported + except Exception: + pass + + async def _gather() -> List[Any]: + return await asyncio.gather(*tasks_to_execute) + + outputs: List[Any] = asyncio.run(_gather()) + return outputs diff --git a/pilot/scene/chat_knowledge/refine_summary/__init__.py b/pilot/scene/chat_knowledge/refine_summary/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pilot/scene/chat_knowledge/refine_summary/chat.py b/pilot/scene/chat_knowledge/refine_summary/chat.py new file mode 100644 index 000000000..b3a934dd5 --- /dev/null +++ b/pilot/scene/chat_knowledge/refine_summary/chat.py @@ -0,0 +1,37 @@ +from typing import Dict + +from pilot.scene.base_chat import BaseChat +from pilot.scene.base import ChatScene +from pilot.configs.config import Config + +from pilot.scene.chat_knowledge.refine_summary.prompt import prompt + +CFG = Config() + + +class ExtractRefineSummary(BaseChat): + chat_scene: str = ChatScene.ExtractRefineSummary.value() + + """get summary by llm""" + + def __init__(self, chat_param: Dict): + """ """ + chat_param["chat_mode"] = ChatScene.ExtractRefineSummary + super().__init__( + chat_param=chat_param, + ) + + self.user_input = chat_param["current_user_input"] + self.existing_answer = chat_param["select_param"] + # self.extract_mode = chat_param["select_param"] + + def generate_input_values(self): + input_values = { + "context": self.user_input, + "existing_answer": self.existing_answer, + } + return input_values + + @property + def chat_type(self) -> str: + return ChatScene.ExtractRefineSummary.value diff --git a/pilot/scene/chat_knowledge/refine_summary/out_parser.py b/pilot/scene/chat_knowledge/refine_summary/out_parser.py new file mode 100644 index 000000000..104419e88 --- /dev/null +++ b/pilot/scene/chat_knowledge/refine_summary/out_parser.py @@ -0,0 +1,57 @@ +import json +import logging +import re +from typing import List, Tuple + +from pilot.out_parser.base import BaseOutputParser, T +from pilot.configs.config import Config + +CFG = Config() + + +logger = logging.getLogger(__name__) + + +class ExtractRefineSummaryParser(BaseOutputParser): + def __init__(self, sep: str, is_stream_out: bool): + super().__init__(sep=sep, is_stream_out=is_stream_out) + + def parse_prompt_response( + self, response, max_length: int = 128 + ) -> List[Tuple[str, str, str]]: + # clean_str = super().parse_prompt_response(response) + print("clean prompt response:", response) + + # if response.startswith("Triplets:"): + # response = response[len("Triplets:") :] + # pattern = r"\([^()]+\)" + # response = re.findall(pattern, response) + # # response = response.strip().split("\n") + # print("parse prompt response:", response) + # results = [] + # for text in response: + # if not text or text[0] != "(" or text[-1] != ")": + # # skip empty lines and non-triplets + # continue + # tokens = text[1:-1].split(",") + # if len(tokens) != 3: + # continue + # + # if any(len(s.encode("utf-8")) > max_length for s in tokens): + # # We count byte-length instead of len() for UTF-8 chars, + # # will skip if any of the tokens are too long. + # # This is normally due to a poorly formatted triplet + # # extraction, in more serious KG building cases + # # we'll need NLP models to better extract triplets. + # continue + # + # subject, predicate, obj = map(str.strip, tokens) + # if not subject or not predicate or not obj: + # # skip partial triplets + # continue + # results.append((subject.lower(), predicate.lower(), obj.lower())) + return response + + def parse_view_response(self, speak, data) -> str: + ### tool out data to table view + return data diff --git a/pilot/scene/chat_knowledge/refine_summary/prompt.py b/pilot/scene/chat_knowledge/refine_summary/prompt.py new file mode 100644 index 000000000..0161cee35 --- /dev/null +++ b/pilot/scene/chat_knowledge/refine_summary/prompt.py @@ -0,0 +1,40 @@ +from pilot.prompts.prompt_new import PromptTemplate +from pilot.configs.config import Config +from pilot.scene.base import ChatScene +from pilot.common.schema import SeparatorStyle + +from pilot.scene.chat_knowledge.refine_summary.out_parser import ExtractRefineSummaryParser + +CFG = Config() + + +PROMPT_SCENE_DEFINE = """Your job is to produce a final summary.""" + +_DEFAULT_TEMPLATE = """ +We have provided an existing summary up to a certain point: {existing_answer}\nWe have the opportunity to refine the existing summary (only if needed) with some more context below.\n------------\n{context}\n------------\nGiven the new context, refine the original summary.\nIf the context isn't useful, return the original summary. + +please use original language. +""" +PROMPT_RESPONSE = """""" + + +RESPONSE_FORMAT = """""" + + +PROMPT_SEP = SeparatorStyle.SINGLE.value + +PROMPT_NEED_NEED_STREAM_OUT = False + +prompt = PromptTemplate( + template_scene=ChatScene.ExtractRefineSummary.value(), + input_variables=["existing_answer","context"], + response_format="", + template_define=PROMPT_SCENE_DEFINE, + template=_DEFAULT_TEMPLATE + PROMPT_RESPONSE, + stream_out=PROMPT_NEED_NEED_STREAM_OUT, + output_parser=ExtractRefineSummaryParser( + sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_NEED_STREAM_OUT + ), +) + +CFG.prompt_template_registry.register(prompt, is_default=True) diff --git a/pilot/scene/chat_knowledge/summary/__init__.py b/pilot/scene/chat_knowledge/summary/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pilot/scene/chat_knowledge/summary/chat.py b/pilot/scene/chat_knowledge/summary/chat.py new file mode 100644 index 000000000..f887bde82 --- /dev/null +++ b/pilot/scene/chat_knowledge/summary/chat.py @@ -0,0 +1,35 @@ +from typing import Dict + +from pilot.scene.base_chat import BaseChat +from pilot.scene.base import ChatScene +from pilot.configs.config import Config + +from pilot.scene.chat_knowledge.summary.prompt import prompt + +CFG = Config() + + +class ExtractSummary(BaseChat): + chat_scene: str = ChatScene.ExtractSummary.value() + + """get summary by llm""" + + def __init__(self, chat_param: Dict): + """ """ + chat_param["chat_mode"] = ChatScene.ExtractSummary + super().__init__( + chat_param=chat_param, + ) + + self.user_input = chat_param["current_user_input"] + # self.extract_mode = chat_param["select_param"] + + def generate_input_values(self): + input_values = { + "context": self.user_input, + } + return input_values + + @property + def chat_type(self) -> str: + return ChatScene.ExtractSummary.value diff --git a/pilot/scene/chat_knowledge/summary/out_parser.py b/pilot/scene/chat_knowledge/summary/out_parser.py new file mode 100644 index 000000000..5626d0d4a --- /dev/null +++ b/pilot/scene/chat_knowledge/summary/out_parser.py @@ -0,0 +1,28 @@ +import json +import logging +import re +from typing import List, Tuple + +from pilot.out_parser.base import BaseOutputParser, T +from pilot.configs.config import Config + +CFG = Config() + + +logger = logging.getLogger(__name__) + + +class ExtractSummaryParser(BaseOutputParser): + def __init__(self, sep: str, is_stream_out: bool): + super().__init__(sep=sep, is_stream_out=is_stream_out) + + def parse_prompt_response( + self, response, max_length: int = 128 + ) -> List[Tuple[str, str, str]]: + # clean_str = super().parse_prompt_response(response) + print("clean prompt response:", response) + return response + + def parse_view_response(self, speak, data) -> str: + ### tool out data to table view + return data diff --git a/pilot/scene/chat_knowledge/summary/prompt.py b/pilot/scene/chat_knowledge/summary/prompt.py new file mode 100644 index 000000000..cbf452c99 --- /dev/null +++ b/pilot/scene/chat_knowledge/summary/prompt.py @@ -0,0 +1,47 @@ +from pilot.prompts.prompt_new import PromptTemplate +from pilot.configs.config import Config +from pilot.scene.base import ChatScene +from pilot.common.schema import SeparatorStyle + +from pilot.scene.chat_knowledge.summary.out_parser import ExtractSummaryParser + +CFG = Config() + +# PROMPT_SCENE_DEFINE = """You are an expert Q&A system that is trusted around the world.\nAlways answer the query using the provided context information, and not prior knowledge.\nSome rules to follow:\n1. Never directly reference the given context in your answer.\n2. Avoid statements like 'Based on the context, ...' or 'The context information ...' or anything along those lines.""" + +PROMPT_SCENE_DEFINE = """Your job is to produce a final summary.""" + +# _DEFAULT_TEMPLATE = """ +# Context information from multiple sources is below.\n---------------------\n +# {context} +# Given the information from multiple sources and not prior knowledge, answer the query.\nQuery: Describe what the provided text is about. Also describe some of the questions that this text can answer. \nAnswer: " +# """ + +_DEFAULT_TEMPLATE = """ +Write a concise summary of the following context: +{context} +please use original language. +""" +PROMPT_RESPONSE = """""" + + +RESPONSE_FORMAT = """""" + + +PROMPT_SEP = SeparatorStyle.SINGLE.value + +PROMPT_NEED_NEED_STREAM_OUT = False + +prompt = PromptTemplate( + template_scene=ChatScene.ExtractSummary.value(), + input_variables=["context"], + response_format="", + template_define=PROMPT_SCENE_DEFINE, + template=_DEFAULT_TEMPLATE + PROMPT_RESPONSE, + stream_out=PROMPT_NEED_NEED_STREAM_OUT, + output_parser=ExtractSummaryParser( + sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_NEED_STREAM_OUT + ), +) + +CFG.prompt_template_registry.register(prompt, is_default=True) diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index 017fef3ec..cde2b7bb7 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -288,7 +288,7 @@ class KnowledgeService: executor = CFG.SYSTEM_APP.get_component( ComponentType.EXECUTOR_DEFAULT, ExecutorFactory ).create() - executor.submit(self.async_document_summary, chunk_docs, doc) + # executor.submit(self.async_document_summary, chunk_docs, doc) executor.submit(self.async_doc_embedding, client, chunk_docs, doc) logger.info(f"begin save document chunks, doc:{doc.doc_name}") # save chunk details @@ -431,7 +431,8 @@ class KnowledgeService: texts = [doc.page_content for doc in chunk_docs] prompt_helper = PromptHelper() texts = prompt_helper.repack(prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=texts) - summary = self._llm_extract_summary(chunk_docs[0]) + summary = self._llm_extract_summary(texts[0]) + # summaries = self._mapreduce_extract_summary(texts) outputs, summary = self._refine_extract_summary(texts[1:], summary) logger.info( f"async_document_summary, doc:{doc.doc_name}, chunk_size:{len(chunk_docs)}, begin embedding to graph store" @@ -452,6 +453,7 @@ class KnowledgeService: ) try: vector_ids = client.knowledge_embedding_batch(chunk_docs) + self.async_document_summary(chunk_docs, doc) doc.status = SyncStatus.FINISHED.name doc.result = "document embedding success" if vector_ids is not None: @@ -512,9 +514,9 @@ class KnowledgeService: chat_param = { "chat_session_id": uuid.uuid1(), - "current_user_input": doc.page_content, + "current_user_input": doc, "select_param": "summary", - "model_name": "proxyllm", + "model_name": CFG.LLM_MODEL, } from pilot.utils import utils loop = utils.get_or_create_event_loop() @@ -535,7 +537,7 @@ class KnowledgeService: "chat_session_id": uuid.uuid1(), "current_user_input": doc, "select_param": summary, - "model_name": "proxyllm", + "model_name": CFG.LLM_MODEL, } from pilot.utils import utils loop = utils.get_or_create_event_loop() @@ -547,4 +549,33 @@ class KnowledgeService: outputs.append(summary) return outputs, summary + def _mapreduce_extract_summary(self, docs): + """Extract mapreduce summary by llm""" + from pilot.scene.base import ChatScene + from pilot.common.chat_util import llm_chat_response_nostream + import uuid + outputs = [] + tasks = [] + for doc in docs: + chat_param = { + "chat_session_id": uuid.uuid1(), + "current_user_input": doc, + "select_param": "summary", + "model_name": CFG.LLM_MODEL, + } + tasks.append(llm_chat_response_nostream( + ChatScene.ExtractSummary.value(), **{"chat_param": chat_param} + )) + from pilot.common.chat_util import run_async_tasks + summaries = run_async_tasks(tasks) + # from pilot.utils import utils + # loop = utils.get_or_create_event_loop() + # summary = loop.run_until_complete( + # llm_chat_response_nostream( + # ChatScene.ExtractRefineSummary.value(), **{"chat_param": chat_param} + # ) + # ) + # outputs.append(summary) + return summaries + From 16dd8e3ef550765144e53ed824be695b79ace0df Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Tue, 31 Oct 2023 13:48:15 +0800 Subject: [PATCH 20/57] feat:document summary --- pilot/scene/base_chat.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pilot/scene/base_chat.py b/pilot/scene/base_chat.py index e43cdc812..5c33f4770 100644 --- a/pilot/scene/base_chat.py +++ b/pilot/scene/base_chat.py @@ -284,6 +284,7 @@ class BaseChat(ABC): ) ### model result deal self.current_message.add_ai_message(ai_response_text) + prompt_define_response = None prompt_define_response = ( self.prompt_template.output_parser.parse_prompt_response( ai_response_text From 523838fb796d6611b2e0075311d9e2a9741b15e5 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Tue, 31 Oct 2023 15:09:11 +0800 Subject: [PATCH 21/57] feat:document summary --- pilot/server/knowledge/service.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index cde2b7bb7..81e1dbdcc 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -429,14 +429,15 @@ class KnowledgeService: from llama_index import PromptHelper from llama_index.prompts.default_prompt_selectors import DEFAULT_TREE_SUMMARIZE_PROMPT_SEL texts = [doc.page_content for doc in chunk_docs] - prompt_helper = PromptHelper() + prompt_helper = PromptHelper(context_window=5000) texts = prompt_helper.repack(prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=texts) + logger.info( + f"async_document_summary, doc:{doc.doc_name}, chunk_size:{len(texts)}, begin generate summary" + ) summary = self._llm_extract_summary(texts[0]) # summaries = self._mapreduce_extract_summary(texts) outputs, summary = self._refine_extract_summary(texts[1:], summary) - logger.info( - f"async_document_summary, doc:{doc.doc_name}, chunk_size:{len(chunk_docs)}, begin embedding to graph store" - ) + doc.summary = summary return knowledge_document_dao.update_knowledge_document(doc) @@ -525,14 +526,18 @@ class KnowledgeService: ChatScene.ExtractSummary.value(), **{"chat_param": chat_param} ) ) + logger.info( + f"initialize summary is :{summary}" + ) return summary - def _refine_extract_summary(self, docs, summary: str): + def _refine_extract_summary(self, docs, summary: str, max_iteration:int = 5): """Extract refine summary by llm""" from pilot.scene.base import ChatScene from pilot.common.chat_util import llm_chat_response_nostream import uuid outputs = [] - for doc in docs: + max_iteration = max_iteration if len(docs) > max_iteration else len(docs) + for doc in docs[0:max_iteration]: chat_param = { "chat_session_id": uuid.uuid1(), "current_user_input": doc, @@ -547,6 +552,9 @@ class KnowledgeService: ) ) outputs.append(summary) + logger.info( + f"iterator is {len(outputs)} current summary is :{summary}" + ) return outputs, summary def _mapreduce_extract_summary(self, docs): @@ -567,7 +575,8 @@ class KnowledgeService: ChatScene.ExtractSummary.value(), **{"chat_param": chat_param} )) from pilot.common.chat_util import run_async_tasks - summaries = run_async_tasks(tasks) + summary_iters = run_async_tasks(tasks) + summary = self._llm_extract_summary(" ".join(summary_iters)) # from pilot.utils import utils # loop = utils.get_or_create_event_loop() # summary = loop.run_until_complete( @@ -576,6 +585,6 @@ class KnowledgeService: # ) # ) # outputs.append(summary) - return summaries + return summary From 7dcfa1921d10f02c9a8c57093dfd57f77fe92e58 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Tue, 31 Oct 2023 15:53:40 +0800 Subject: [PATCH 22/57] feat:document summary --- pilot/server/knowledge/service.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index 81e1dbdcc..570a549ed 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -437,7 +437,11 @@ class KnowledgeService: summary = self._llm_extract_summary(texts[0]) # summaries = self._mapreduce_extract_summary(texts) outputs, summary = self._refine_extract_summary(texts[1:], summary) - + summaries = prompt_helper.repack(prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=outputs) + summary = self._llm_extract_summary("|".join(summaries)) + print( + f"final summary:{summary}" + ) doc.summary = summary return knowledge_document_dao.update_knowledge_document(doc) @@ -526,7 +530,7 @@ class KnowledgeService: ChatScene.ExtractSummary.value(), **{"chat_param": chat_param} ) ) - logger.info( + print( f"initialize summary is :{summary}" ) return summary @@ -552,7 +556,7 @@ class KnowledgeService: ) ) outputs.append(summary) - logger.info( + print( f"iterator is {len(outputs)} current summary is :{summary}" ) return outputs, summary From b3dbf31209ebfa6c2dde1d46d53a520b46f054bf Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Tue, 31 Oct 2023 16:10:06 +0800 Subject: [PATCH 23/57] feat:document summary --- pilot/server/knowledge/service.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index 570a549ed..f906ff372 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -437,6 +437,9 @@ class KnowledgeService: summary = self._llm_extract_summary(texts[0]) # summaries = self._mapreduce_extract_summary(texts) outputs, summary = self._refine_extract_summary(texts[1:], summary) + print( + f"refine summary outputs:{outputs}" + ) summaries = prompt_helper.repack(prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=outputs) summary = self._llm_extract_summary("|".join(summaries)) print( @@ -530,16 +533,16 @@ class KnowledgeService: ChatScene.ExtractSummary.value(), **{"chat_param": chat_param} ) ) - print( - f"initialize summary is :{summary}" - ) return summary def _refine_extract_summary(self, docs, summary: str, max_iteration:int = 5): """Extract refine summary by llm""" from pilot.scene.base import ChatScene from pilot.common.chat_util import llm_chat_response_nostream import uuid - outputs = [] + print( + f"initialize summary is :{summary}" + ) + outputs = [summary] max_iteration = max_iteration if len(docs) > max_iteration else len(docs) for doc in docs[0:max_iteration]: chat_param = { From 40eed546ac346061989c429a319f1e72f3ac3df4 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Tue, 31 Oct 2023 16:14:04 +0800 Subject: [PATCH 24/57] chore:discord expire --- pilot/server/knowledge/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index f906ff372..cd18c539f 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -429,7 +429,7 @@ class KnowledgeService: from llama_index import PromptHelper from llama_index.prompts.default_prompt_selectors import DEFAULT_TREE_SUMMARIZE_PROMPT_SEL texts = [doc.page_content for doc in chunk_docs] - prompt_helper = PromptHelper(context_window=5000) + prompt_helper = PromptHelper(context_window=3900) texts = prompt_helper.repack(prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=texts) logger.info( f"async_document_summary, doc:{doc.doc_name}, chunk_size:{len(texts)}, begin generate summary" From 04dcd905022b55bc5354828d6e5c283ccec5d6b1 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Tue, 31 Oct 2023 16:14:26 +0800 Subject: [PATCH 25/57] feat:document summary --- pilot/server/knowledge/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index cd18c539f..4db3d6c51 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -429,7 +429,7 @@ class KnowledgeService: from llama_index import PromptHelper from llama_index.prompts.default_prompt_selectors import DEFAULT_TREE_SUMMARIZE_PROMPT_SEL texts = [doc.page_content for doc in chunk_docs] - prompt_helper = PromptHelper(context_window=3900) + prompt_helper = PromptHelper() texts = prompt_helper.repack(prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=texts) logger.info( f"async_document_summary, doc:{doc.doc_name}, chunk_size:{len(texts)}, begin generate summary" From 48539d7206a754644306cd1541337ad37b2d1c4c Mon Sep 17 00:00:00 2001 From: wangzaistone Date: Tue, 31 Oct 2023 17:10:12 +0800 Subject: [PATCH 26/57] codellama bug fix --- pilot/server/chat_adapter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pilot/server/chat_adapter.py b/pilot/server/chat_adapter.py index 509305247..4b6dd0eed 100644 --- a/pilot/server/chat_adapter.py +++ b/pilot/server/chat_adapter.py @@ -218,7 +218,7 @@ class Llama2ChatAdapter(BaseChatAdpter): class CodeLlamaChatAdapter(BaseChatAdpter): """The model ChatAdapter for codellama .""" def match(self, model_path: str): - return "codelama" in model_path.lower() + return "codellama" in model_path.lower() def get_conv_template(self, model_path: str) -> Conversation: return get_conv_template("codellama") From a670e5c00d31007652ef370a85d7f9996cd5a36b Mon Sep 17 00:00:00 2001 From: wangzaistone Date: Tue, 31 Oct 2023 17:24:54 +0800 Subject: [PATCH 27/57] add other codellama models --- pilot/configs/model_config.py | 7 +++++++ pilot/model/adapter.py | 2 +- pilot/model/model_adapter.py | 5 ++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/pilot/configs/model_config.py b/pilot/configs/model_config.py index 16deee50a..803d0fae9 100644 --- a/pilot/configs/model_config.py +++ b/pilot/configs/model_config.py @@ -78,8 +78,15 @@ LLM_MODEL_CONFIG = { "internlm-7b": os.path.join(MODEL_PATH, "internlm-chat-7b"), "internlm-7b-8k": os.path.join(MODEL_PATH, "internlm-chat-7b-8k"), "internlm-20b": os.path.join(MODEL_PATH, "internlm-chat-20b"), + "codellama-7b": os.path.join(MODEL_PATH, "CodeLlama-7b-Instruct-hf"), + "codellama-7b-sql-sft": os.path.join(MODEL_PATH, "codellama-7b-sql-sft"), + "codellama-13b": os.path.join(MODEL_PATH, "CodeLlama-13b-Instruct-hf"), "codellama-13b-sql-sft": os.path.join(MODEL_PATH, "codellama-13b-sql-sft"), + + + + # For test now "opt-125m": os.path.join(MODEL_PATH, "opt-125m"), } diff --git a/pilot/model/adapter.py b/pilot/model/adapter.py index 02fbe8aa9..cb9885d2a 100644 --- a/pilot/model/adapter.py +++ b/pilot/model/adapter.py @@ -323,7 +323,7 @@ class CodeLlamaAdapter(BaseLLMAdaper): """The model adapter for codellama """ def match(self, model_path: str): - return "codelama" in model_path.lower() + return "codellama" in model_path.lower() def loader(self, model_path: str, from_pretrained_kwargs: dict): model, tokenizer = super().loader(model_path, from_pretrained_kwargs) diff --git a/pilot/model/model_adapter.py b/pilot/model/model_adapter.py index 112fb468a..cadb1cebd 100644 --- a/pilot/model/model_adapter.py +++ b/pilot/model/model_adapter.py @@ -45,7 +45,10 @@ _OLD_MODELS = [ "llama-cpp", "proxyllm", "gptj-6b", - "codellama-13b-sql-sft" + "codellama-13b-sql-sft", + "codellama-7b", + "codellama-7b-sql-sft", + "codellama-13b" ] From 17e21a395bcff6228ad3dacc0c251af0ec38d4b8 Mon Sep 17 00:00:00 2001 From: wangzaistone Date: Tue, 31 Oct 2023 17:26:59 +0800 Subject: [PATCH 28/57] keep as origin default param --- .env.template | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.env.template b/.env.template index 272ee2922..e03650033 100644 --- a/.env.template +++ b/.env.template @@ -22,8 +22,7 @@ WEB_SERVER_PORT=7860 #** LLM MODELS **# #*******************************************************************# # LLM_MODEL, see /pilot/configs/model_config.LLM_MODEL_CONFIG -# LLM_MODEL=vicuna-13b-v1.5 -LLM_MODEL=codellama-13b-sql-sft +LLM_MODEL=vicuna-13b-v1.5 ## LLM model path, by default, DB-GPT will read the model path from LLM_MODEL_CONFIG based on the LLM_MODEL. ## Of course you can specify your model path according to LLM_MODEL_PATH ## In DB-GPT, the priority from high to low to read model path: From 3233e260b20e16fa39424dfe8a606b3df4d92b1a Mon Sep 17 00:00:00 2001 From: wangzaistone Date: Tue, 31 Oct 2023 17:39:14 +0800 Subject: [PATCH 29/57] add conv judge --- pilot/configs/model_config.py | 5 ----- pilot/model/adapter.py | 3 ++- pilot/model/conversation.py | 1 - pilot/model/model_adapter.py | 8 ++++++-- pilot/server/chat_adapter.py | 3 ++- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pilot/configs/model_config.py b/pilot/configs/model_config.py index 803d0fae9..0e1fb3d40 100644 --- a/pilot/configs/model_config.py +++ b/pilot/configs/model_config.py @@ -82,11 +82,6 @@ LLM_MODEL_CONFIG = { "codellama-7b-sql-sft": os.path.join(MODEL_PATH, "codellama-7b-sql-sft"), "codellama-13b": os.path.join(MODEL_PATH, "CodeLlama-13b-Instruct-hf"), "codellama-13b-sql-sft": os.path.join(MODEL_PATH, "codellama-13b-sql-sft"), - - - - - # For test now "opt-125m": os.path.join(MODEL_PATH, "opt-125m"), } diff --git a/pilot/model/adapter.py b/pilot/model/adapter.py index cb9885d2a..5ce5b2173 100644 --- a/pilot/model/adapter.py +++ b/pilot/model/adapter.py @@ -319,8 +319,9 @@ class Llama2Adapter(BaseLLMAdaper): model.config.pad_token_id = tokenizer.pad_token_id return model, tokenizer + class CodeLlamaAdapter(BaseLLMAdaper): - """The model adapter for codellama """ + """The model adapter for codellama""" def match(self, model_path: str): return "codellama" in model_path.lower() diff --git a/pilot/model/conversation.py b/pilot/model/conversation.py index 98dfc720d..5d4309d9f 100644 --- a/pilot/model/conversation.py +++ b/pilot/model/conversation.py @@ -360,7 +360,6 @@ register_conv_template( ) - # Alpaca default template register_conv_template( Conversation( diff --git a/pilot/model/model_adapter.py b/pilot/model/model_adapter.py index cadb1cebd..e09b868e7 100644 --- a/pilot/model/model_adapter.py +++ b/pilot/model/model_adapter.py @@ -48,7 +48,7 @@ _OLD_MODELS = [ "codellama-13b-sql-sft", "codellama-7b", "codellama-7b-sql-sft", - "codellama-13b" + "codellama-13b", ] @@ -152,8 +152,12 @@ class LLMModelAdaper: conv.append_message(conv.roles[1], content) else: raise ValueError(f"Unknown role: {role}") + if system_messages: - conv.set_system_message("".join(system_messages)) + if isinstance(conv, Conversation): + conv.set_system_message("".join(system_messages)) + else: + conv.update_system_message("".join(system_messages)) # Add a blank message for the assistant. conv.append_message(conv.roles[1], None) diff --git a/pilot/server/chat_adapter.py b/pilot/server/chat_adapter.py index 4b6dd0eed..64b72739b 100644 --- a/pilot/server/chat_adapter.py +++ b/pilot/server/chat_adapter.py @@ -213,10 +213,11 @@ class Llama2ChatAdapter(BaseChatAdpter): def get_conv_template(self, model_path: str) -> Conversation: return get_conv_template("llama-2") - + class CodeLlamaChatAdapter(BaseChatAdpter): """The model ChatAdapter for codellama .""" + def match(self, model_path: str): return "codellama" in model_path.lower() From de902448280a16fdd0b7756e904cc256280d3551 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Tue, 31 Oct 2023 18:52:58 +0800 Subject: [PATCH 30/57] feat:document summary --- pilot/model/cluster/worker/remote_worker.py | 2 +- .../chat_knowledge/refine_summary/prompt.py | 16 +++-- pilot/scene/chat_knowledge/summary/prompt.py | 17 +++-- pilot/server/knowledge/service.py | 70 ++++++++++--------- 4 files changed, 58 insertions(+), 47 deletions(-) diff --git a/pilot/model/cluster/worker/remote_worker.py b/pilot/model/cluster/worker/remote_worker.py index f974ba714..149f8b86a 100644 --- a/pilot/model/cluster/worker/remote_worker.py +++ b/pilot/model/cluster/worker/remote_worker.py @@ -13,7 +13,7 @@ class RemoteModelWorker(ModelWorker): def __init__(self) -> None: self.headers = {} # TODO Configured by ModelParameters - self.timeout = 180 + self.timeout = 360 self.host = None self.port = None diff --git a/pilot/scene/chat_knowledge/refine_summary/prompt.py b/pilot/scene/chat_knowledge/refine_summary/prompt.py index 0161cee35..69d4e46df 100644 --- a/pilot/scene/chat_knowledge/refine_summary/prompt.py +++ b/pilot/scene/chat_knowledge/refine_summary/prompt.py @@ -8,19 +8,21 @@ from pilot.scene.chat_knowledge.refine_summary.out_parser import ExtractRefineSu CFG = Config() -PROMPT_SCENE_DEFINE = """Your job is to produce a final summary.""" +PROMPT_SCENE_DEFINE = """""" -_DEFAULT_TEMPLATE = """ -We have provided an existing summary up to a certain point: {existing_answer}\nWe have the opportunity to refine the existing summary (only if needed) with some more context below.\n------------\n{context}\n------------\nGiven the new context, refine the original summary.\nIf the context isn't useful, return the original summary. +_DEFAULT_TEMPLATE_ZH = """根据提供的上下文信息,我们已经提供了一个到某一点的现有总结:{existing_answer}\n 我们有机会在下面提供的更多上下文信息的基础上进一步完善现有的总结(仅在需要的情况下)。请根据新的上下文信息,完善原来的总结。\n------------\n{context}\n------------\n如果上下文信息没有用处,请返回原来的总结。""" +_DEFAULT_TEMPLATE_EN = """ +We have provided an existing summary up to a certain point: {existing_answer}\nWe have the opportunity to refine the existing summary (only if needed) with some more context below.\n------------\n{context}\n------------\nGiven the new context, refine the original summary. \nIf the context isn't useful, return the original summary. please use original language. """ + +_DEFAULT_TEMPLATE = ( + _DEFAULT_TEMPLATE_EN if CFG.LANGUAGE == "en" else _DEFAULT_TEMPLATE_ZH +) + PROMPT_RESPONSE = """""" - -RESPONSE_FORMAT = """""" - - PROMPT_SEP = SeparatorStyle.SINGLE.value PROMPT_NEED_NEED_STREAM_OUT = False diff --git a/pilot/scene/chat_knowledge/summary/prompt.py b/pilot/scene/chat_knowledge/summary/prompt.py index cbf452c99..ec7c05c32 100644 --- a/pilot/scene/chat_knowledge/summary/prompt.py +++ b/pilot/scene/chat_knowledge/summary/prompt.py @@ -9,19 +9,22 @@ CFG = Config() # PROMPT_SCENE_DEFINE = """You are an expert Q&A system that is trusted around the world.\nAlways answer the query using the provided context information, and not prior knowledge.\nSome rules to follow:\n1. Never directly reference the given context in your answer.\n2. Avoid statements like 'Based on the context, ...' or 'The context information ...' or anything along those lines.""" -PROMPT_SCENE_DEFINE = """Your job is to produce a final summary.""" +PROMPT_SCENE_DEFINE = """""" -# _DEFAULT_TEMPLATE = """ -# Context information from multiple sources is below.\n---------------------\n -# {context} -# Given the information from multiple sources and not prior knowledge, answer the query.\nQuery: Describe what the provided text is about. Also describe some of the questions that this text can answer. \nAnswer: " -# """ +_DEFAULT_TEMPLATE_ZH = """请根据提供的上下文信息的进行简洁地总结: +{context} +""" -_DEFAULT_TEMPLATE = """ +_DEFAULT_TEMPLATE_EN = """ Write a concise summary of the following context: {context} please use original language. """ + +_DEFAULT_TEMPLATE = ( + _DEFAULT_TEMPLATE_EN if CFG.LANGUAGE == "en" else _DEFAULT_TEMPLATE_ZH +) + PROMPT_RESPONSE = """""" diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index 4db3d6c51..d7fb476d7 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -429,19 +429,22 @@ class KnowledgeService: from llama_index import PromptHelper from llama_index.prompts.default_prompt_selectors import DEFAULT_TREE_SUMMARIZE_PROMPT_SEL texts = [doc.page_content for doc in chunk_docs] - prompt_helper = PromptHelper() + prompt_helper = PromptHelper(context_window=2500) + texts = prompt_helper.repack(prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=texts) logger.info( f"async_document_summary, doc:{doc.doc_name}, chunk_size:{len(texts)}, begin generate summary" ) - summary = self._llm_extract_summary(texts[0]) - # summaries = self._mapreduce_extract_summary(texts) - outputs, summary = self._refine_extract_summary(texts[1:], summary) - print( - f"refine summary outputs:{outputs}" - ) - summaries = prompt_helper.repack(prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=outputs) - summary = self._llm_extract_summary("|".join(summaries)) + # summary = self._llm_extract_summary(texts[0]) + summary = self._mapreduce_extract_summary(texts) + # summaries = prompt_helper.repack(prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=summaries) + # if (len(summaries)) > 1: + # outputs, summary = self._refine_extract_summary(summaries[1:], summaries[0]) + # else: + # summary = self._llm_extract_summary("\n".join(summaries)) + # print( + # f"refine summary outputs:{summaries}" + # ) print( f"final summary:{summary}" ) @@ -565,33 +568,36 @@ class KnowledgeService: return outputs, summary def _mapreduce_extract_summary(self, docs): - """Extract mapreduce summary by llm""" + """Extract mapreduce summary by llm + map -> multi thread generate summary + reduce -> merge the summaries by map process + Args: + docs:List[str] + """ from pilot.scene.base import ChatScene from pilot.common.chat_util import llm_chat_response_nostream import uuid - outputs = [] tasks = [] - for doc in docs: - chat_param = { - "chat_session_id": uuid.uuid1(), - "current_user_input": doc, - "select_param": "summary", - "model_name": CFG.LLM_MODEL, - } - tasks.append(llm_chat_response_nostream( + if len(docs) == 1: + summary = self._llm_extract_summary(doc=docs[0]) + return summary + else: + for doc in docs: + chat_param = { + "chat_session_id": uuid.uuid1(), + "current_user_input": doc, + "select_param": "summary", + "model_name": CFG.LLM_MODEL, + } + tasks.append(llm_chat_response_nostream( ChatScene.ExtractSummary.value(), **{"chat_param": chat_param} - )) - from pilot.common.chat_util import run_async_tasks - summary_iters = run_async_tasks(tasks) - summary = self._llm_extract_summary(" ".join(summary_iters)) - # from pilot.utils import utils - # loop = utils.get_or_create_event_loop() - # summary = loop.run_until_complete( - # llm_chat_response_nostream( - # ChatScene.ExtractRefineSummary.value(), **{"chat_param": chat_param} - # ) - # ) - # outputs.append(summary) - return summary + )) + from pilot.common.chat_util import run_async_tasks + summary_iters = run_async_tasks(tasks) + from pilot.common.prompt_util import PromptHelper + from llama_index.prompts.default_prompt_selectors import DEFAULT_TREE_SUMMARIZE_PROMPT_SEL + prompt_helper = PromptHelper(context_window=2500) + summary_iters = prompt_helper.repack(prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=summary_iters) + return self._mapreduce_extract_summary(summary_iters) From 67f41559a8ce7c614d1088f1a361e74e405e29fb Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Tue, 31 Oct 2023 19:33:58 +0800 Subject: [PATCH 31/57] feat:mapreduce summary --- pilot/server/knowledge/service.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index d7fb476d7..0b6e260dc 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -578,10 +578,12 @@ class KnowledgeService: from pilot.common.chat_util import llm_chat_response_nostream import uuid tasks = [] + max_iteration = 5 if len(docs) == 1: summary = self._llm_extract_summary(doc=docs[0]) return summary else: + max_iteration = max_iteration if len(docs) > max_iteration else len(docs) for doc in docs: chat_param = { "chat_session_id": uuid.uuid1(), From be1e1cb1603b3e3eb7478f944d0a140b5da19379 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Tue, 31 Oct 2023 19:38:20 +0800 Subject: [PATCH 32/57] feat:document summary set max iteration --- pilot/server/knowledge/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index 0b6e260dc..7e899ba78 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -584,7 +584,7 @@ class KnowledgeService: return summary else: max_iteration = max_iteration if len(docs) > max_iteration else len(docs) - for doc in docs: + for doc in docs[0:max_iteration]: chat_param = { "chat_session_id": uuid.uuid1(), "current_user_input": doc, From d319470f69e5f84cbaa41f8f31c4d2d74a84ea21 Mon Sep 17 00:00:00 2001 From: 0xrahul6 <113128186+0xrahul6@users.noreply.github.com> Date: Tue, 31 Oct 2023 19:49:40 +0530 Subject: [PATCH 33/57] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7d7af852a..eaee7ec9d 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,7 @@ Currently, we have released multiple key features, which are listed below to dem | [StarRocks](https://github.com/StarRocks/starrocks) | No | TODO | ## Introduction -Is the architecture of the entire DB-GPT shown in the following figure: +The architecture of the entire DB-GPT is shown.

@@ -330,7 +330,7 @@ As of October 10, 2023, by fine-tuning an open-source model of 13 billion parame The MIT License (MIT) ## Contact Information -We are working on building a community, if you have any ideas about building the community, feel free to contact us. +We are working on building a community, if you have any ideas for building the community, feel free to contact us. [![](https://dcbadge.vercel.app/api/server/nASQyBjvY?compact=true&style=flat)](https://discord.gg/nASQyBjvY)

From eb3ddccd0a04a1a74c7556068265e5840a1e6fa0 Mon Sep 17 00:00:00 2001 From: nobunagaaa <146952817+nobunagaaa@users.noreply.github.com> Date: Tue, 31 Oct 2023 19:54:48 +0530 Subject: [PATCH 34/57] fixed typos --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7d7af852a..e74db5c76 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,8 @@ DB-GPT is an experimental open-source project that uses localized GPT large mode ## Contents -- [install](#install) -- [demo](#demo) +- [Install](#install) +- [Demo](#demo) - [introduction](#introduction) - [features](#features) - [contribution](#contribution) @@ -213,7 +213,7 @@ The core capabilities mainly consist of the following parts: ## Contribution -- Please run `black .` before submitting the code. Contributing guidelines, [how to contribution](https://github.com/csunny/DB-GPT/blob/main/CONTRIBUTING.md) +- Please run `black .` before submitting the code. Contributing guidelines, [how to contribute](https://github.com/csunny/DB-GPT/blob/main/CONTRIBUTING.md) ## RoadMap From 606d384a55e548621fc9d0f8c235267eaf601279 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Wed, 1 Nov 2023 21:55:24 +0800 Subject: [PATCH 35/57] feat:add knowledge reference --- pilot/graph_engine/graph_engine.py | 1 + pilot/graph_engine/graph_search.py | 4 +- pilot/scene/base_chat.py | 6 +- .../chat_knowledge/refine_summary/chat.py | 4 +- .../chat_knowledge/refine_summary/prompt.py | 12 +-- pilot/scene/chat_knowledge/summary/prompt.py | 7 +- pilot/scene/chat_knowledge/v1/chat.py | 70 ++++++++++++---- pilot/server/knowledge/request/request.py | 2 + pilot/server/knowledge/request/response.py | 1 + pilot/server/knowledge/service.py | 81 +++++++++++-------- 10 files changed, 122 insertions(+), 66 deletions(-) diff --git a/pilot/graph_engine/graph_engine.py b/pilot/graph_engine/graph_engine.py index 491a8625c..bea5f3123 100644 --- a/pilot/graph_engine/graph_engine.py +++ b/pilot/graph_engine/graph_engine.py @@ -187,6 +187,7 @@ class RAGGraphEngine: triple_results = [] for doc in docs: import threading + thread_id = threading.get_ident() print(f"current thread-{thread_id} begin extract triplets task") triplets = self._extract_triplets(doc.page_content) diff --git a/pilot/graph_engine/graph_search.py b/pilot/graph_engine/graph_search.py index f3025be85..9419a4979 100644 --- a/pilot/graph_engine/graph_search.py +++ b/pilot/graph_engine/graph_search.py @@ -143,9 +143,7 @@ class RAGGraphSearch(BaseSearch): logger.info("> No relationships found, returning nodes found by keywords.") if len(sorted_nodes_with_scores) == 0: logger.info("> No nodes found by keywords, returning empty response.") - return [ - Document(page_content="No relationships found.") - ] + return [Document(page_content="No relationships found.")] # add relationships as Node # TODO: make initial text customizable diff --git a/pilot/scene/base_chat.py b/pilot/scene/base_chat.py index 5c33f4770..34f294c31 100644 --- a/pilot/scene/base_chat.py +++ b/pilot/scene/base_chat.py @@ -141,7 +141,6 @@ class BaseChat(ABC): self.current_message.start_date = datetime.datetime.now().strftime( "%Y-%m-%d %H:%M:%S" ) - self.current_message.tokens = 0 if self.prompt_template.template: current_prompt = self.prompt_template.format(**input_values) @@ -152,7 +151,6 @@ class BaseChat(ABC): # Not new server mode, we convert the message format(List[ModelMessage]) to list of dict # fix the error of "Object of type ModelMessage is not JSON serializable" when passing the payload to request.post llm_messages = list(map(lambda m: m.dict(), llm_messages)) - payload = { "model": self.llm_model, "prompt": self.generate_llm_text(), @@ -167,6 +165,9 @@ class BaseChat(ABC): def stream_plugin_call(self, text): return text + def knowledge_reference_call(self, text): + return text + async def check_iterator_end(iterator): try: await asyncio.anext(iterator) @@ -196,6 +197,7 @@ class BaseChat(ABC): view_msg = view_msg.replace("\n", "\\n") yield view_msg self.current_message.add_ai_message(msg) + view_msg = self.knowledge_reference_call(msg) self.current_message.add_view_message(view_msg) except Exception as e: print(traceback.format_exc()) diff --git a/pilot/scene/chat_knowledge/refine_summary/chat.py b/pilot/scene/chat_knowledge/refine_summary/chat.py index b3a934dd5..d0b1e9471 100644 --- a/pilot/scene/chat_knowledge/refine_summary/chat.py +++ b/pilot/scene/chat_knowledge/refine_summary/chat.py @@ -21,13 +21,13 @@ class ExtractRefineSummary(BaseChat): chat_param=chat_param, ) - self.user_input = chat_param["current_user_input"] + # self.user_input = chat_param["current_user_input"] self.existing_answer = chat_param["select_param"] # self.extract_mode = chat_param["select_param"] def generate_input_values(self): input_values = { - "context": self.user_input, + # "context": self.user_input, "existing_answer": self.existing_answer, } return input_values diff --git a/pilot/scene/chat_knowledge/refine_summary/prompt.py b/pilot/scene/chat_knowledge/refine_summary/prompt.py index 69d4e46df..cd5087f35 100644 --- a/pilot/scene/chat_knowledge/refine_summary/prompt.py +++ b/pilot/scene/chat_knowledge/refine_summary/prompt.py @@ -3,18 +3,20 @@ from pilot.configs.config import Config from pilot.scene.base import ChatScene from pilot.common.schema import SeparatorStyle -from pilot.scene.chat_knowledge.refine_summary.out_parser import ExtractRefineSummaryParser +from pilot.scene.chat_knowledge.refine_summary.out_parser import ( + ExtractRefineSummaryParser, +) CFG = Config() PROMPT_SCENE_DEFINE = """""" -_DEFAULT_TEMPLATE_ZH = """根据提供的上下文信息,我们已经提供了一个到某一点的现有总结:{existing_answer}\n 我们有机会在下面提供的更多上下文信息的基础上进一步完善现有的总结(仅在需要的情况下)。请根据新的上下文信息,完善原来的总结。\n------------\n{context}\n------------\n如果上下文信息没有用处,请返回原来的总结。""" +_DEFAULT_TEMPLATE_ZH = """根据提供的上下文信息,我们已经提供了一个到某一点的现有总结:{existing_answer}\n 请再完善一下原来的总结。\n回答的时候最好按照1.2.3.点进行总结""" _DEFAULT_TEMPLATE_EN = """ -We have provided an existing summary up to a certain point: {existing_answer}\nWe have the opportunity to refine the existing summary (only if needed) with some more context below.\n------------\n{context}\n------------\nGiven the new context, refine the original summary. \nIf the context isn't useful, return the original summary. -please use original language. +We have provided an existing summary up to a certain point: {existing_answer}\nWe have the opportunity to refine the existing summary (only if needed) with some more context below.please refine the original summary. +\nWhen answering, it is best to summarize according to points 1.2.3. """ _DEFAULT_TEMPLATE = ( @@ -29,7 +31,7 @@ PROMPT_NEED_NEED_STREAM_OUT = False prompt = PromptTemplate( template_scene=ChatScene.ExtractRefineSummary.value(), - input_variables=["existing_answer","context"], + input_variables=["existing_answer"], response_format="", template_define=PROMPT_SCENE_DEFINE, template=_DEFAULT_TEMPLATE + PROMPT_RESPONSE, diff --git a/pilot/scene/chat_knowledge/summary/prompt.py b/pilot/scene/chat_knowledge/summary/prompt.py index ec7c05c32..10a239586 100644 --- a/pilot/scene/chat_knowledge/summary/prompt.py +++ b/pilot/scene/chat_knowledge/summary/prompt.py @@ -11,14 +11,15 @@ CFG = Config() PROMPT_SCENE_DEFINE = """""" -_DEFAULT_TEMPLATE_ZH = """请根据提供的上下文信息的进行简洁地总结: +_DEFAULT_TEMPLATE_ZH = """请根据提供的上下文信息的进行总结: {context} +回答的时候最好按照1.2.3.点进行总结 """ _DEFAULT_TEMPLATE_EN = """ -Write a concise summary of the following context: +Write a summary of the following context: {context} -please use original language. +When answering, it is best to summarize according to points 1.2.3. """ _DEFAULT_TEMPLATE = ( diff --git a/pilot/scene/chat_knowledge/v1/chat.py b/pilot/scene/chat_knowledge/v1/chat.py index 576a93872..e6c3d9056 100644 --- a/pilot/scene/chat_knowledge/v1/chat.py +++ b/pilot/scene/chat_knowledge/v1/chat.py @@ -1,5 +1,5 @@ import os -from typing import Dict +from typing import Dict, List from pilot.component import ComponentType from pilot.scene.base_chat import BaseChat @@ -20,7 +20,6 @@ CFG = Config() class ChatKnowledge(BaseChat): chat_scene: str = ChatScene.ChatKnowledge.value() - """KBQA Chat Module""" def __init__(self, chat_param: Dict): @@ -46,7 +45,6 @@ class ChatKnowledge(BaseChat): if self.space_context is None else int(self.space_context["embedding"]["topk"]) ) - # self.recall_score = CFG.KNOWLEDGE_SEARCH_TOP_SIZE if self.space_context is None else self.space_context["embedding"]["recall_score"] self.max_token = ( CFG.KNOWLEDGE_SEARCH_MAX_TOKEN if self.space_context is None @@ -56,11 +54,11 @@ class ChatKnowledge(BaseChat): "vector_store_name": self.knowledge_space, "vector_store_type": CFG.VECTOR_STORE_TYPE, } - from pilot.graph_engine.graph_factory import RAGGraphFactory - - self.rag_engine = CFG.SYSTEM_APP.get_component( - ComponentType.RAG_GRAPH_DEFAULT.value, RAGGraphFactory - ).create() + # from pilot.graph_engine.graph_factory import RAGGraphFactory + # + # self.rag_engine = CFG.SYSTEM_APP.get_component( + # ComponentType.RAG_GRAPH_DEFAULT.value, RAGGraphFactory + # ).create() embedding_factory = CFG.SYSTEM_APP.get_component( "embedding_factory", EmbeddingFactory ) @@ -90,25 +88,29 @@ class ChatKnowledge(BaseChat): last_output.text = ( last_output.text + "\n\nrelations:\n\n" + ",".join(relations) ) - yield last_output + reference = f"\n\n{self.parse_source_view(self.sources)}" + last_output = last_output + reference + yield last_output + + def knowledge_reference_call(self, text): + """return reference""" + return text + f"\n\n{self.parse_source_view(self.sources)}" async def generate_input_values(self) -> Dict: if self.space_context: self.prompt_template.template_define = self.space_context["prompt"]["scene"] self.prompt_template.template = self.space_context["prompt"]["template"] - # docs = self.knowledge_embedding_client.similar_search( - # self.current_user_input, self.top_k - # ) docs = await blocking_func_to_async( self._executor, self.knowledge_embedding_client.similar_search, self.current_user_input, self.top_k, ) - docs = await self.rag_engine.search(query=self.current_user_input) - # docs = self.knowledge_embedding_client.similar_search( - # self.current_user_input, self.top_k - # ) + self.sources = self.merge_by_key( + list(map(lambda doc: doc.metadata, docs)), "source" + ) + + self.current_message.knowledge_source = self.sources if not docs: raise ValueError( "you have no knowledge space, please add your knowledge space" @@ -125,6 +127,42 @@ class ChatKnowledge(BaseChat): } return input_values + def parse_source_view(self, sources: List): + html_title = f"##### **References:**" + lines = "" + for item in sources: + source = item["source"] if "source" in item else "" + pages = ",".join(item["pages"]) if "pages" in item else "" + lines += f"{source}" + if len(pages) > 0: + lines += f", **pages**:{pages}\n\n" + else: + lines += "\n\n" + html = f"""{html_title}\n{lines}""" + return html + + def merge_by_key(self, data, key): + result = {} + for item in data: + item_key = os.path.basename(item.get(key)) + if item_key in result: + if "pages" in result[item_key] and "page" in item: + result[item_key]["pages"].append(str(item["page"])) + elif "page" in item: + result[item_key]["pages"] = [ + result[item_key]["pages"], + str(item["page"]), + ] + else: + if "page" in item: + result[item_key] = { + "source": item_key, + "pages": [str(item["page"])], + } + else: + result[item_key] = {"source": item_key} + return list(result.values()) + @property def chat_type(self) -> str: return ChatScene.ChatKnowledge.value() diff --git a/pilot/server/knowledge/request/request.py b/pilot/server/knowledge/request/request.py index c6b94ff0d..032b97ba1 100644 --- a/pilot/server/knowledge/request/request.py +++ b/pilot/server/knowledge/request/request.py @@ -59,6 +59,8 @@ class DocumentSyncRequest(BaseModel): """doc_ids: doc ids""" doc_ids: List + model_name: Optional[str] = None + """Preseparator, this separator is used for pre-splitting before the document is actually split by the text splitter. Preseparator are not included in the vectorized text. """ diff --git a/pilot/server/knowledge/request/response.py b/pilot/server/knowledge/request/response.py index 2e3e5f0ab..5c1c7efd1 100644 --- a/pilot/server/knowledge/request/response.py +++ b/pilot/server/knowledge/request/response.py @@ -5,6 +5,7 @@ from pydantic import BaseModel class ChunkQueryResponse(BaseModel): """data: data""" + data: List = None """summary: document summary""" summary: str = None diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index 7e899ba78..1dece9054 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -199,6 +199,7 @@ class KnowledgeService: # import langchain is very very slow!!! doc_ids = sync_request.doc_ids + self.model_name = sync_request.model_name or CFG.LLM_MODEL for doc_id in doc_ids: query = KnowledgeDocumentEntity( id=doc_id, @@ -427,11 +428,16 @@ class KnowledgeService: - doc: KnowledgeDocumentEntity """ from llama_index import PromptHelper - from llama_index.prompts.default_prompt_selectors import DEFAULT_TREE_SUMMARIZE_PROMPT_SEL - texts = [doc.page_content for doc in chunk_docs] - prompt_helper = PromptHelper(context_window=2500) + from llama_index.prompts.default_prompt_selectors import ( + DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, + ) - texts = prompt_helper.repack(prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=texts) + texts = [doc.page_content for doc in chunk_docs] + prompt_helper = PromptHelper(context_window=2000) + + texts = prompt_helper.repack( + prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=texts + ) logger.info( f"async_document_summary, doc:{doc.doc_name}, chunk_size:{len(texts)}, begin generate summary" ) @@ -445,13 +451,10 @@ class KnowledgeService: # print( # f"refine summary outputs:{summaries}" # ) - print( - f"final summary:{summary}" - ) + print(f"final summary:{summary}") doc.summary = summary return knowledge_document_dao.update_knowledge_document(doc) - def async_doc_embedding(self, client, chunk_docs, doc): """async document embedding into vector db Args: @@ -460,11 +463,11 @@ class KnowledgeService: - doc: KnowledgeDocumentEntity """ logger.info( - f"async_doc_embedding, doc:{doc.doc_name}, chunk_size:{len(chunk_docs)}, begin embedding to vector store-{CFG.VECTOR_STORE_TYPE}" + f"async doc sync, doc:{doc.doc_name}, chunk_size:{len(chunk_docs)}, begin embedding to vector store-{CFG.VECTOR_STORE_TYPE}" ) try: - vector_ids = client.knowledge_embedding_batch(chunk_docs) self.async_document_summary(chunk_docs, doc) + vector_ids = client.knowledge_embedding_batch(chunk_docs) doc.status = SyncStatus.FINISHED.name doc.result = "document embedding success" if vector_ids is not None: @@ -526,25 +529,27 @@ class KnowledgeService: chat_param = { "chat_session_id": uuid.uuid1(), "current_user_input": doc, - "select_param": "summary", - "model_name": CFG.LLM_MODEL, + "select_param": doc, + "model_name": self.model_name, } - from pilot.utils import utils - loop = utils.get_or_create_event_loop() - summary = loop.run_until_complete( - llm_chat_response_nostream( - ChatScene.ExtractSummary.value(), **{"chat_param": chat_param} - ) + from pilot.common.chat_util import run_async_tasks + + summary_iters = run_async_tasks( + [ + llm_chat_response_nostream( + ChatScene.ExtractRefineSummary.value(), **{"chat_param": chat_param} + ) + ] ) - return summary - def _refine_extract_summary(self, docs, summary: str, max_iteration:int = 5): + return summary_iters[0] + + def _refine_extract_summary(self, docs, summary: str, max_iteration: int = 5): """Extract refine summary by llm""" from pilot.scene.base import ChatScene from pilot.common.chat_util import llm_chat_response_nostream import uuid - print( - f"initialize summary is :{summary}" - ) + + print(f"initialize summary is :{summary}") outputs = [summary] max_iteration = max_iteration if len(docs) > max_iteration else len(docs) for doc in docs[0:max_iteration]: @@ -552,9 +557,10 @@ class KnowledgeService: "chat_session_id": uuid.uuid1(), "current_user_input": doc, "select_param": summary, - "model_name": CFG.LLM_MODEL, + "model_name": self.model_name, } from pilot.utils import utils + loop = utils.get_or_create_event_loop() summary = loop.run_until_complete( llm_chat_response_nostream( @@ -562,9 +568,7 @@ class KnowledgeService: ) ) outputs.append(summary) - print( - f"iterator is {len(outputs)} current summary is :{summary}" - ) + print(f"iterator is {len(outputs)} current summary is :{summary}") return outputs, summary def _mapreduce_extract_summary(self, docs): @@ -577,6 +581,7 @@ class KnowledgeService: from pilot.scene.base import ChatScene from pilot.common.chat_util import llm_chat_response_nostream import uuid + tasks = [] max_iteration = 5 if len(docs) == 1: @@ -589,17 +594,23 @@ class KnowledgeService: "chat_session_id": uuid.uuid1(), "current_user_input": doc, "select_param": "summary", - "model_name": CFG.LLM_MODEL, + "model_name": self.model_name, } - tasks.append(llm_chat_response_nostream( - ChatScene.ExtractSummary.value(), **{"chat_param": chat_param} - )) + tasks.append( + llm_chat_response_nostream( + ChatScene.ExtractSummary.value(), **{"chat_param": chat_param} + ) + ) from pilot.common.chat_util import run_async_tasks + summary_iters = run_async_tasks(tasks) from pilot.common.prompt_util import PromptHelper - from llama_index.prompts.default_prompt_selectors import DEFAULT_TREE_SUMMARIZE_PROMPT_SEL + from llama_index.prompts.default_prompt_selectors import ( + DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, + ) + prompt_helper = PromptHelper(context_window=2500) - summary_iters = prompt_helper.repack(prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=summary_iters) + summary_iters = prompt_helper.repack( + prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=summary_iters + ) return self._mapreduce_extract_summary(summary_iters) - - From 41ad69cb3901376e6374edfbd0ff3ce85c6271da Mon Sep 17 00:00:00 2001 From: csunny Date: Thu, 2 Nov 2023 14:25:50 +0800 Subject: [PATCH 36/57] chores: update wechat --- assets/wechat.jpg | Bin 234518 -> 206792 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/assets/wechat.jpg b/assets/wechat.jpg index c7de6223b996de33e357f4ecf70edc60fd2a59af..ec465785c48264626c9fb04b51dde1cd09fd7769 100644 GIT binary patch literal 206792 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Âr)OYT3JjdNthIP`Sb^`5fVvaqETg?bg2A(x&WiR|h zMNRxzjBfrk|7ZzM`Lp;VKeO_yV3Y;S;5RDY;>n?K+=uL??JldXRZri0#ecN!Xm}JK z&llR~U5(X5ksi~5|LZG!f}LoZWW8_ zk;0UF^093p09OYT0ZOIE5hiN$Rx6pmwW;y6#HgI}9Mt*Q6HspEV6(0L(R?GjT|3tX zal#yHfgw3#6VUvIA;nPwQ>>RXombKo+P;VT$E-T4zY+Lk=%u}MU0BI_BC9V8a}o3R zK@}iJaFiWJjZb=})UGsb&slXEkgBYCo-zDlk4o9Dca!IsEXD9ME(CV$L^_7WNS2~X z4J0Ew>SQ-8vYxbX-z}`ONObl{Jowfu03NtqJ%;$>JtVXaAP;javHGsS>Jj$)CwshV zHyXtmhOIgMy~_H%7$-vgSC4Tbc$YW>8tWr{&4Eq;5>e4j`^(2P0OISw~2)#&3qUD zr+}luF`#{k0N=!KX3}>MY|#_fF-&pF_yrwLvN%YZ=AH|>IN9S`RsXypd4V2t(?z#m z*qAf>&>?*eh+Z%Q#J`@o+B;Mo%tL=g5DahR_+hhcb1w&ZGGAU|LB`L#yuqSqAIH>E3U;LFih9&>Lm%jK>!*3H&wsa^(GN~FiC55+vjUE zy33r+dO5GFN?cQ_yA#gE!-ij=6Vg#1WLD2ndZtk$$QHZVd_lrR%}>@t8(;nFqg4x2 zIHMgurM@f(li;~eTs>jT3_Q`+jmjjDobN_Dzr%X>@;LkER*bZi_!~LCviM@w|Kvam zX1hgn2X=Qg?I^I9E^+)(n^U>-w1>762USp?vY+T; z9cu~(6O`yb^0s>OB-JwYXk*TTChd@GOn6o*TcPP?GuEO^6AbXF(nc(?M+V~d&Y=av zamW+Cagqa?^|#p-8q&)?{MhB9ZI&*<5`d7qGU4I$cAR9db^$F?g&Dzh#>rs0PL9py zD>P)&JEz{V?{d!;LyGMw8EGqIeE`J;J1vJ!q9rKpfK%}wh6ln^@0FUmNBiYk9Q~Oi zx?)*th9ojc@y3K;F1SxRbugVVl>SSTXO-J9m6(oE3`H)0z!VgAQ6#-wWmgdM#jC-R z;hQI)1e{|xtby=eATf}e;}x;%bLF0Hg={N)DF~K6#W?p7{0NDQ_kdyqt@x;ZUAl?C z#g)XBp7Gey&c8j#h(Gp7b-s-=b^8;Qr_U@dHv(8ER^vUBY@VrWwi6iem*H zjZj=R-u1K*`~5^J$4um^>|6Lg|Hv{{IS1*1tsCqgyQPAV)06^Lxb5Un7z0X-gZIw| zd&c)T40?;~zIVgwQb>^9L^!mhfvFAOLTAhg6f_yc3$0jAN>YpXfx1S*WuVMqpmPrn)_780yh>eVfETui3U>zOMUBp}? z{N32#N7N`X_!hNfx+Eoi3X`0_qc14zF5B>J!R#N}7eC*58Xy}4=Vd(%UQjrq2zKGq z(G*2*YQ8O)qfK@kO}LtT{(K=ACKm`jySKF54FsV@VArnzSq0ExK6)t%Bo`RayexW| z1wa3gkRD7?$fV|@+t8crNE)nkbLSS^tp4&P9~UUMKqZg5wsIO~KQ*({&+%%8e>WEP zDM$VtU1D1YDZrqa#$_^~1Wqh{*9C)D$_f8Om#Dwv)B>KR6cAGX172GG1FFIsie3aN zbQy6Fe>AlfMkUw|28H01MtwY6HU;RrXaS1$kw^L`i(r`Z65uWWg=LFT@V}znPx(ndB0<#n@j9P^% zL82$S4;*nH4Mu-!z^(P)Td2kT9JAe=dGDvl)cc<=g*T9p?F8{yP4dB{RH}68@!5^b zmr8atI8^)?Ze9qGH0hEeu6`%^cdRv`DTgP~;&c0D>V~RDV@e#)v1Y;0Wmxw2v=({~ zVJT>whcM3$+)_~o6!Yfq@E`Lad>u%G*%Pc)T@e4z%Yj8ySPfz22Djof=W&u%@VZ8z z0KN5GCJ4?qPGIuTe=jm-j*E!^xsEx_P>}Dg%clO#kFYM*cRm0c@zpbrh+*aNl(qWfQ}d&8L?24 z-Tyk~2BNQ~=4DH^po2bdfp|V}mIkY>w8sqwn{w3MlDhBbZyz2EXQy{P9O1g0H&GI6 zfUGM#a&5!ua}w1E;I`$1Pp~8<3>hB^20V)G79z3I(zqGW{cPe-HxMla&zl0N@x4R) ztMU1rWEl$Mn_T2`F(cYpa#lU)$49 z!a#=J3NzRU9o^hsFw2A;-_bBW?bLziqH<7Nr%>9iX_ zs857Z5_HvBEN5)sq#5bw_a8MwBEs)9TgvZHlcj<#)_H_!QM-R--@E=T`)-Wt8(-)E zJaYDAam??ihE1|$?$64Rnunidhz5>JADZkwZGw+SPp;6V!TQ1!W5?I$KY13|C1CT8AcWCBnWXjbMqfCXw_R`XkiHgyNJ<)Hz;HD0v zWC(uLSL95paMO2Nve5(gNfcyq{$7j5gQ_)wIvZKPGh#QQ5F1Ar5Xl<1uF(s^r9}YG zW}i6yWI!O!M;*pCjlaEsF0f4kRa{=K*oyh;2e%{PrVpad&ADy=^65#h%2OF8#6{7` z_!>^0=OBO>yYEw8;0z%p9*cT}vu1T*Vg74LLxiR`YIKtv+)5{!hOk2r+$$MSKEQk9 zJ09+zz7m+e4{5x|7T7OAuqjVb?!dKXrnuC$Eiy&z+k0-@EUT=1SI~o~`86QZrqlEa>JTwy!{o%1o=H*8x1+mVM{FQaNO*wDmNq~ zk!7yPbi}FaV6%933RJdgfL@7`DZ}}gibtvBk!LOVZ%6Ah6ERB;u^`TH z^GDJYts#09ArS1c2Dgn@SYBTCMOUC}sU}nEF0bD0b3n=OXbQ;Q{Vly2GRUKXm6SxJ zB+--O?lK_k*nJ?!5$sEEz*3YSYC}Sc0>I+1!o1#Q@C>SYD7|!q0l9+=Z&Z>=d#?7g zY|>5H0GWG|q4{iDYaLj99LWs5E=iZe4r>z`kfqbIlQFY2>>|QL+(nV8c6goveY=ER zds*V1sCbcY$3tu#RH9gb>_(5G=p0E8rsg z_BK3Q8rG1!bHRYvoeIQKPxhLupKQ!A04Ae{u0<-Q3XaolQ>TJy;RD#^5B?aIKGszn ziMaZL5=n-y`oEw(xFuiFw_NJ{b#RCBi^-h#CO1SjKUp9fk&0;>5L4s-f zO5FQGZS3FBAKI?jE)^hK#*?ummt&eJ3BM7Ywnc<#>CDl?qGdmRJdAp9Q-SM?$OZPd ztjEKj*m7c90v2~s&5K7U_(@u0ewND1+QY6N4SFQZCT|Hnmj#GCzK%e>jK_X&z-{n7 zW?v)D0TW?JE5`a0nCZP}go@Fw9>0ycs6^dE*Mj4VCd*~`AO55&KmAPnTue10w4;}8 zmKQhaD>Eq4Vf^}@-isi0-3yX~1AfGxAB<68FLCQwB(q>21M2cY(Kz{m!z|SAol$8cSWWDLQ+ylFZ?G zo00@hkYm6t?VxG{9&Qln$puJYNdDa@5cUz=2%~GJv?qA2V2*Jg<;h+?-{jSc2-ya8 z*KgYrBu(LiPD|#PXK0c+IQXE8;l~aO5tdH@9eE4VFUV{l%a z^ZqZCeu&bTVoi&MO(~-Vqim197^vPRCcOVk%F)9&^jcaz$2hHiAhCAoXSVmo=d+XP zrgx>ykPXlmLZY#^OmFU{Kl{XV;x!BL2nzmzy z`2nsmPobm!Sq81;Q3rwD1$$N9cl@!d{GhwO5rXyipNHujK$P+!z(fyQw*g!P&g$4a z0v*#U2@~1lOI{-iv`Z@}nyB(}9YGWO_o53N)H&J<^eJxSYGbYiS@JF($3?kkiK$Gz zCF6fPI?zhRzL4kUDF8cTzNOHF@ZY+&Rv>=LJIOF`QtdK*J8_q08B2`7qn_>es?=@H z$SOYgyifFTM#9hqb?jtU(;k4}@a|ybx3KH-1V{8~!Z6srt6;sTR<&)f{mPrj<2U37 z@hLa&WfdVTp6zpvSBj6x4(*=Byu?sd#*@*@+J55{R0udRL0q;13V(^xPu|vrV{ZtZ z>=m6`@>?C_%|Xt8doFKv&v`oQgSdrkMf^Qz8Ke?@6!DX7Q)&yGWZaZx`U-9v<#xwN zs-H`Bn~h@p+%f3`v5&Jl(}e5=neFr;{guZjIVs=C2`%}`@2K_#l(r)&4Cv5vtJB`~ zd1fDr@5wxKK%N1i%Lz=4!u-8S{K)uZ6iK@hD}SxTcYs!Tpz%OO%UQvP9+^`6)1Ek9 zY-xEZH9`CwOx0cML@ztegVWH!yvPz4aczx$o9zT7Rby)Jfs%&zVLi$(Qn(*`<|DF5 z23!C&r9*LE^mY{K(A{mTHe}%k(`CW!-W`&1^_R;|v022@otvK1q?es4cnkW;V>e)CKEbe30&nM~dOlxB&9wB1ry&s#Uy z(CXskD1=GY`9d=5l*ol29f|c1M_nxgL#p;%`7~w{@S^~n*swZQGC#cc5q!xSLy=xg z`yBW&DZ+uIXc&@u}yWI&8OtGm`cSNuPqkHvL__D;?`i zuV)`se|f^`k^O~38UO|BtAjHNw=^>~n^fQ5`k3RsI=ilLjT*jMOBI-&UhEj>p}&`8 z=__kE7!z3x&T1wcAk^09+g$lld-p)W*}vZGnE1|^jz2$Yb;H0(_2FbG;6V(3=*8Gv9Z-&T*( zG7LpFHL1dbae|hSyK2>v5oKj3p7~sUeXZkjZO+Ba>qY1r#(F=j42fTL(y$ZBA}&eE zE6R&3RGXwj{oc36hQ=0cW0H%~Gxk-LsTZ4Wlq4hA$}N;^XQci3#B)rD5~B_59d ze8%z|L?1U2iPa^2YgJ3y5NQi$mw9+?a`V_iV0(tg`K&b0TNPGX<4$ie6_%M)8?xo< z84@xx)=mH8ck#|#1X2C*JW~3kD}1Oa9i+dM*HeKls)`Mxl%N(w!E$ti#BQZdMl*cUI#+kEk@I`XUczgZ{%=VXax*cLA% zjaW;P#jOcUQa<01*E`KjKGpZ{*FN0r(8T+Y*R4GqM5R=-Ssj?;n81$18_G4{b-aN8 zxwwV``^;Ep+|#vrjRJaCoyD`zT~%W{$l8rpe&B_~*${j+pEGoAwDmqelf5>hi*HgU zCD7R>$)!_HsfA=>+qmHO!+s+cNrBr}Zq|9_9D8tM^*R3@)vA@2MNHOsRqX;R`C1oF zqQSlNd%iNkO0`l+u+RHG>1FB?hEk9w}l_4FV8&<>u%NdT5H6+ovfeVvh+1TMlYy2gV>3r zG3oRBzEt5-a{51rNiju*HkOsDp#m&v4T(+$N7AnD!5w#6cn^Hg{#Rnw`AI1*ig1$alsA>{ z5O-vkcugf~dW!3uNYbL0hU>90XRAon=W))4lj_2Dp;cM+qTLF4Z6rLEkAHQb-Q|35 zDqX$}d(T{5Yf!i@rp53XJm*N(!!!3YG^(Zu1)%58$dS-hBa-cc2+7ixVz}loQ#$$i zlFypb8-)*fV|zHFQ*0NVPPKeId+wVd@iX!7OM7ITbQG7GZ$xq4G@7lUBi^H|u>5{# zxB5I(jyr44@yEJf&RWVw;J+%+g@fC18{4#ksmSMB$0^_&$+Roji96yt^S7to*i1HZr{avyv*L+x_AJKC$3^7=sPjg=)oqTxeeOe;>kCMZC((v zIlINr=4!tYFYWwcbv#M>!o-BrTLQ@*lZg}28V5T)CnavT6KnFkFE7dt%&RWQXOHPl zrmgWk{n)-_HRl8W4nkP4c9O6utKd&qazVJ{zp{9ccC|@(cI)61RsA~J56e+~d(`mF zo=uxKvWby*o;Gt02*~#_A?pOygs5kc$>aPcFUfx?I2MC_itIp%QQc|RsC?7oS40RS zE(`BYjP{;AqI^K*$AenS*zmJi@m=*EAY~2WP2RN*`KiOcWS2LmRK|{-SF$*BYu%LZ z3`}><7-hWyUv&ctVL1zMa+8WLRv`BLv?E!6MrD^uV4&*B*PIW~$}c;eIh9s8_FN;% zq|ow#ht(nkAt?%pshh6f^)YExSUwb2R8HrfK-qWgM7x7QdK{;DZXc7p#J8A75ui)N zOrtiG{^EW^w&;S9DJ`Agf#ZpLN#OP%#pOQge&RQBzxDg!##8q4I3N2j9oaJGc959D z;I%jBqmTEdhr2d%w$!cGo-%$hFu$vOhl+ZWhrLF*Wk}XL!j;AC)M!e_G)~lSOohyv zx}vAWZ9VzrdRL^1ef%Nlhy}-ERtN^RbzYpKOt1FRuEy$Zo{TlBA$1m(7^Oa$<-eV- zy<(EBd*7}4QWjI;`y_-1-*5{3VBB_U9Hn~#xy^^JMp{f=ksZ_=y_AjCpL4z!bmkSg zUdZ#*eyLS0T0JFbaa1Y7yow^n9HHo8LN}^wQPrFVe1IK_Mg9xaL0)k*SX>fF23+t%~ zIsN1V-QvK5WYQw-BIw0JoPPKF`W3JmKp52BPKl&9Cxa71+)&)!-}`x6-%hJ^`#h0HtN{Y3c_X#&GIg_EL3&Y+LRpn_|<+}80P>u%^yHqHUX>YM4wiDa3W5y z+CNpSsA90V#>V*;n^m6f10KFit|R{!ckdn5)VH>a20=k7k=}^{3QALoNR5g#5wWAR zC`FopiUMlLLZl-gARwSbMZ^L`x+oAjg3^&H1VZl#B`iqsPIkHX+xxfAz2lrSzWc}d zgJg^d%dENH`IhH>-e<E?h3`D(aJ&oh4s1Bga_i74Aly)sgRAO`)dK27#&E8vw%|^9-j!j zX`HsR!#SpV;;NX-6`7I8@fU!d3RAQj!GEOKJHJlXhbOJVD;2+d?OuE6%zG!9KhpRc ze#3R|_gbeHU^ukWlZ=8DX_24caN0pQJ!|^%9n!E?@sl@VyT4B!)#7${x%MeBBt|^F zeVgZ$8*wC`Sg@M#*2^{Ll_Q(e%|jZ$S1{R?NUDD*OAfZMqC%lQvcK*cc(5r8?w8PU z!f~;#J#GiQG!}Qno)L<1U?_c?+k=KJ{=*?%<7d6WjaN&`Uetv$-phKm$&I~vKb}}c zn4Puizd-X!Hc7S$`^v4CV1DGVb7J>u-j8bZc9tOaNM-s3z%?lv+O{~V|6yNYiJ5(( z&cLZBW3oX8N1`@Rv=n9$iwE}unSGUU;%i!<#rYqmu5NG4>zr6N>QkX@h~6eVWdqd@ zv9MYM#tzijF;wnd>qv$W^Od0l_91)^RYzi*wNOnEu56dz>s;*CV80(#bMa1K86i?1 z1KgJnGX<+awl}SPOt-keYD;~sedM!G*oknCOxO5hsP}8IJNTt9?Q7AbZHyy5IrHx_ zYR^;s!eS*F2>eWH_h>F01uJjg{)1SgC!)4*cck$5O1@BNj6K zI9;D_Y#1F8HBdM4T=l8T5To?Q6qz&7^as3(jQB^RU*Yu+pMd>P&(sM%btz54r@f=m+qCEyCYrfWeR8to8en;M01fr0_( z5eHVclVnVh33q+fXTCS-bz$iB6H~!;ic-{LsQUEuc^?i&S$FZx=gAn5K88yTYaRU&oiW!2HqaGQnMGIpO_>8ITp7}19 zLDmynEPsQZNYwL}Ng5f@UH}jlM|+%g{zE8~($`#AcYb8%uwv+A9y2p3Fa4>3AhZQ^ zy#;Je5Nq(1HnU#kiO&_K9Sc2XH%=t%9ekmlVH{}haDj|^0tO@W{w(Pe1erA%S3e5GF)fyT)G6iJ*&%S%vpq zG>_q6DXS!}G%O11Q=O1`qPuC=7-mSAqU&Sact zk^hdrFuVK%iA_QyiW?`zu!tH!M#xBhrtT;zDeUJ=SYl;D#Tx zuf?Ef&gJ+^1!uI)*ZVUdcdH&|n-{Ja?2fmU*F_epK z{h4G!tme|TD?b9?+Rw&JRBNrCP&^&J`1$XYZLGLhzcCa`2sU3O&XdC0r`Ju$hlR&x z&dFAdQzpXq08)p?8z0_)vD$;ppFIX-@_nlInDbChRUB^rup(%{q64;o(6 zuTSe1Cq3)xcQ3JdY=1h!=IF`f`3U=P?y?AW153ypO=(6IS~CR=IR60Y*FT6|t7vxY zLD-AZqMA6m9+so8Uz&BA_v&Vn zhg~_8%&&eAT1_VHW9PCrcJ& znImx-elLOpKS|b*DArc}zIDU0U8|fD8PC-w&2U}5JNg`lZ?;dsFQ|zTRCJYF3=U`_Ov(@|n5LGLr5JrfnnYH)L}lE^6Wpe< zIiK5v9`6|$7v3{&9Rt-W;#x4Pr&m!7L^MN@ePb3ZrOvcXOYef!J%a63%l+w2uN~?Q znqMD2xuWl2Q@FalxqOu{J8Dyaw7POvySzN2Op%l z2y?a7C|*MpRx;jwW0zcy!(R*5Tw`JI*MrjM2)NIcP@+#FE|DDd7!x z-a+_B-I3i3iC)kAz1()TCC?8bv0y4B6w{~15L7Vg(MQvT8R*Zw%I`jx-F|;Y_9c(E z+-I$uKG|tE6y7=H!gIXMgEZbBfvR@^YAS*DHVd7rR&j z_lC63cC39`P`gx`(7D{>E|)BRF*Ebi?n}>>0X1}PM6Gct98=`_$cqt3A=4L*+>uTI z3_9hW<=FgYVoeR6jO=e5(T-Y+#_tYDtkOM_^}(TJBTu0)W;{OsNg;oN8#^3EnN0dH zmj<)|+Oqx~|gl1r};A9l&vIVZ|UftYvrtu&_Uy)&T3#FW8WXwV%oy zE4pmgd;BdXesdT|souW;cGP819kDS$#_^Z=qqzm-U$}&bz-$nL{!*A}F+8DaeQ2D@ z0=>&VGiaI@({Bj|6zZUASJ1m7V*vzq4bVwC!id=qSdQqCLO>h3Z72;&Fb59HpzN{Ybqsa`LoI;41eWrg7c7Ps$<2Sg+8 z0}9e*U@9IL#RMB8{2U9kELPRP%g7xt>7xnN0(!trXj2q)lXM_B4Z-;RhG+(m|8A%R z&Ey6MhZK=viK5JI5lcepCJE*aaxTL+31-5M5bBKhQ!T?Lz4W3>+h-#B@ zWA>Oc6oZP4idXeIbm93FZuS;#M6-iBpO~ws-*@@j7qI}<;7DSAEJg{rCp+xVFX+@P zb3N{RS2g*9(EW|)d)O7Ew<91+A}4x0J^;n4vT?Ta(_9Wq+M94|E?FL|9IvYD)b&R1o#zo^!Rr}38+`a6hJB3TCk2N zL*Oy3?*2LX_MCH9f@~K)-a=l8sra;M%}g=mv7j3;wo_7SxTC?i=Ydu3`y8cge&NYv zcUAda=&!kZxk-o{K?bZXuEfMA&{YO>hjU=%uSuere5V-C2{X2=T~>5<>;>j)2K1J3 z0X`?My&ml@9oq6_aW7ZAh)cZP;}?t7!W*ez7%`KX54bZJ@KQAa5L-9)MZizDVx&$r zLhDOl8}%q{{6TyJPv!%WW%oMsNJ`2cc0~)s9}z- z5ta%q{ve*ZWHWDr&30UvQNTch48Vldl}389`ckb?g!W*^BhA`{(){1bOFRd;51Unq zJH>n&lozarE*@!*_H@gw{vIi;F<0amq_8!I2tQ=LhsMcu& zOe_+Oz-a|U*Ascp_u6+9(^J(Rx9C>OTWPpt9z5QvCqdyx!SYiJk8VHo@wu0I#nwnU zf^eYxGXJOD+}BjkbhIjh21X2iIoyW>>g5IC*a;67R%w$4r_jYP0ogR!F5nD?lx%@- zh>djhP+1&8Ty-tt2)*8a<%P5LCIBJzy3Cq^;47y$$Gmk(M7o04j{O^Jvfmet)fGx6dr!aGL3fM!~5}dq(M_X zbgT$r9fAY@^|B9&A3e_vuKT9tVZ|+yAXW^|kCTDJs|xHSjeBptD^h=ykl~Ruv}K>w z6aFY3;`m$GidEBt+B}=Ixt##)b>AO^rvciwvY_Mc4{4K{o%Ywt=r)a$4anv}GkIq} z!f_bHEsj^rx2E-IBnE2~)^)tSi2gorsw`^MHIXS@8*&kGr_Kp9!F!>R68y3_3=H2v zBAgY@ixcc!y8seLC1$j~Km82+u;%M}t;O?+Uj6;@r6LzT$EfZtbN*dpHR?Qod@W9B z#Q(boJ_cx|)q=$F+wf~(^PeE5geP@VTwH>Rpmh z0G{ksch=KkUyRrGCp_|I*CR_g)%|Z6R4A?B!D=%EQfRSda2eU&cJ$|wG+O8<2g^X- zy22cR17-1V-TJxoKOFr&dl; z{fXTMZ+o5^dv8nNn~2|iXpzgij}Rfs+G$L85;cMyUVn>aH@3VfwCvi0p@|b& z=d5QIurKMtxVEox^KBHQ8SI{m;bxjys4R5tsgdtx^Eat{?KfsHHz$Em+5oO0co5*m zZd=M!j&wlqwJT;SSdY6hgxY8*IEHSCfn6Jk-0z~MtUFX<@hTznveuz*-A{f}&=0QL z{m>E2vv{x`fo~9wU*>|_SgcU6ZY1kk=wBl)(H;Cs8ZmzfU=c2HYyoek$kN@=AWI|d z*So@y@Yo(De)UGMmj%%;>SzcgXm6h@hBmmjNP73tt8y0wmk8a~v+MOpSUzPzEel?` zQcMvNNn<^lDjaYyzxCN%-rJvd`gkqR$k>zB9MrBYJ4bsAS=Bwb7aozLeD|gL{djNH z(9Y)T5%|<#1ov(|(8%thpjl?6LFjo*Cvi1FcTHllTzvFJMXgj|ytRNNp$IZcYi^BWofs}VF5;`Z{iq@Hehc+l$5 zqlI_AE2iJ|!e75a*6d=HLnF!PWoH?-t$F8C)(dYX3P>V>&$zkr>IzsQkP}k1nEP2x zBz9Nk3mjX3?dbO5S6UXi5;_?VL+w9y*`Hn);6M#sej3_#lwFf;)nzN``_ae{v1OgX zn1h5<8MVnz`2Lag96geS`i!YZ4Jb9Fq3cMY>a~G^yaoMsS6a!t--pW@-$9a8t@Du4VIMx8DfUCv7&9@%F1?N{$Wtl zIKv989JpGCCq}fLa{!`Pp*HlPFhD6oZL(X_E?^n}8RuVnIAG%Y-w1`CoBo6!aj;_C zJn93hJNc_?43_O4FCqHwl{AzpPGFYrwKlYq^EL3y&6k8Xfz$j;eE#b_YO-yV8RI~% z^lxb{`d{-~1kU>$=Iy`jxwyZ2*Yu?SP-Q@9G%s-^9$oaVjQm3njWTr^WeVvQ*VnWv z1O_phKO)9sQ^~|^~_)K>0d78;5NJg&FynE86g!QQrLdCKv}eV5x_yAs$MHk^%{MqK3|C1U!|?hSI$ z;e2Y0Pyx2|&*91c`~5%7`nZ5S;74^0*TnZ<9;?-jVceSi+M4O%rP6BgbML;ldl0vT z_?zkx&_SX9neiW0;M&d+y{w`kguc-zF^sfJ)!O(=cW&%!!&iv=r@|FwFI_t(-9#8T z$Z|!G6l0bh^g%qorU9CUX+ee{I)^`F_2XC1y8b~B4?|R8I!MYm+L*bxy|@lMkN#P_ zK(NCsi#I__yLMNvxw>A=><)I--_G||2@|TsS70=_lo5d!L(gU5S&`s^B5*jkO%vuP zhQ*kdlP#q!(kg5<{X^ftOuI>(bor@m9~WKr#qPMW?s$gtRMrRyKCr&v`z9d!^e-*E zNJ+7ikFI8qZ@pOT-8RMgi~R93m<;RxA{jQhB^lPvxt=*PgoOz;5~!%tXjk3((A=q% zmxG2K0!^g`)NkT>3FTuWQ;Y;Pc90|>PlF`k%3R0aWh)3TiJodtzT)TUbp3!fGA-st z%KGN^aK!AN?a6?|Z7p`MyP;$IgdH)>k*u=>?P zLEPCdm1kwHV#&>NwcCVEe$#s=+8FxTw4WgBdyHmok+mWSAfxzCqd%LI;B!x0w~RLP z9gD|9H>FPAT#LYi;Wf0a8yR{m&|IJ%EBv|d=-iXu>0+EBuq6TX_!BJP>wIQFo95EE z-oLfCw_3TJ%S<}Rw5m^`-91sU4*P+&>w*u9KTz`6*W?DhfOGPs@sch%jSo5=8?%k9 zT~2go8;8Lmi?K5A^Wyvi2lhrgKQh~AyNeHLwBW%0pGI!HvFDft*bAe?K5a|pyVbyh zV#N!7t?j1Vhuucf=7m>uvDIeZg<)9|uz!`BAQ|7Hs z^y+@XR80`t7aGA6DQEEm?2V+NBQcaha_lGYI1E$CEwt&*j}5d0W65Uu6G6_0&T|KYZV!A_^OuHzDIdCdiP<) zjbFtF)^@Wu^ScCu9L(WjS4wzD#S~m(0H~rGv^B?zu%PV84+Ldbo(%$~vt%yNZ$KT# z@hnC?sH&|OLD{$t^pT_Kr(n+d0ZbjabbuHQ9uBj}LYLvZ6iLs8%SP%Q?PBOQGMwRhk;LxuX*390kWiO)1z@K;p~{z54DTg5~E8QYBK! z#dU$!41=_N@u|VehrQ08xussgc^q?&)qtU#TN==_hXJS*w;gNR1C1(nlv~|Ndswgj z_J+taMnR@*tm&->Q4Dv&JE9YMLl+4FI*QEb~b_;Hd@->JDjh?DJ{lgPg; zXActIx3rK?g~ocL?=6Kv!iy=k$(?pO; ztB%*EM})84;WFR?GAM@sl;HTU@Bf2ghZYp9q#cdbdCh9b*iTvf1W8wBk@YInNmivd zQ@$i{_jv<~uDmic%;8~RYiB`Q&F{$4#C^703M}6CGWAGP&kS~#8&_-(kWmH2Vu+}eb zAY_-Z`T>~R2~n(han9f--+?yII(kr>^;iN7)Qo1bWTxn#3~YA-6+pF})<(QB0+$Yw z#@_%NC2jJ!qhY16IQSuc0epBoMgc_ZTfLJ2{oV8dvq!$nLTLK%TTp%ENuWm;p%NeF z4ov_s*J4sZ6!>5GI)rFLO-3O6fqp#Tos}r|e9!nVA4x+y=nj_<=-!?~CW-c0$8>-s z>U@wnf+uln#Fz0`L8MwVn&75^#don?>EOf(k_LRE%%r_53be-s^bxS(#}}|)fz(8QqVN?_z!}!vv+oV{@aLE zkjxJFg41=nPH|Rm$l}$vw%_g>*V>gGy^-vYH&iyQ1jhrtG8R`j6sY}}wcmZk?mMld zw?swg^mwDBxm0@8hojp+s~?+^0`&!YH+tkbRG?M|iF*v|^pxxQyTA9;kc^I)S92~d zUAe+LpRdrI^uO+xSBsSjRCiuX8q*bycV_|sVKZtV0t*p-SO z#WYxOzqA_lk5a~3c-q~gFGd+uE$OrLhM9d&+E6J{pl9slS9e)! zS#4*Rfvd-><@5!P5@wGC?V4g(X9oDxIY@M`qQwRVho}8ZmW?0sw(sD4^lV9B$C$Ss zZO(o>7R0vg2Z)tjkRv*B-R9oUpVlMQo$QiS=Z z)!`__3Ni%4St-NdrWmKxE`@!yaknvukXPJz8{eiPpLgHipszPQAf494OwpIl8xC*< zxu~F~J^EtT_+dNSA9r4l-J8vQvaHl&sQlZ`2CGC(8hV?{Lz(^>-6(t5+SJy4SHb7; z-S;`}0;>1nSMFs%+gT3eQf>}L=XwPH^Nvg~5 zQ!Az-Z*SV18!(rP3vTRQ!Jyrs!Zrr~vZbe0Y;8kNX^P72-BCNWnxyyL8S_xj5Whk> zKC481NXsQwb_2D?2!DytpDE{K9B0^@C;ASS?NYCM!Pf3az=NUIiXNO4){yF7J7Xv{ z`@lGt6zZd5T-sNo7C-J)Gtd6$(Yo0ThNF}rphr``p~8&$#Ixy<=vV=wwII0oAB1yU znCL*#&lG?4Y1+g@>d#n`nxCUNA@@BXSqDL%8|SC!N8p6HdJ?bZfeTl@Mx0Rf@s?OL zyP$J@Csg(gj+lGo&_>l8%dSB_=I{SOwW?2p!mQ6aehw_TF8=g=(||73As^F3VhDd_ zZBEgM-Sdm8&dI}Fr}K9=EMAoxep^znz@6CCpaBE{pnu<|tG(e^(^v2}<02|5%;z=G zaf9nV+Z`Jni{AxZ10t{qe(;0P127K1mT~#etw1Q zX$C?dN1+I`K>2n`c5OjGA^FHR&(Q^0g_EA?WgNG|eTz-3&YKeeA0cds8AqJXal^nu z=o;by^vD;{^&dG{l`awTao2s7nMx<5HY{b!Pvu=Ws?4@W%6VI$C*@2Kx*Qdb7pz1v zuC$BRqj}fntai_wUO){fj|=Qy8woZ&q4bR~^^nCC31PAJRE5*p>XKUd#m|f?%3tqI z@n)tr%-??DD$Ly7&UR&!MSKI>nv_$K5lfC;MMH-B)5v7Mol>`7{m>9>XR{UF0I_a+ z7_qW|`HURfN;VUivnh(YE?E#McW}xx2h3pHHjryS&e# zW){5tShCnGeY_S?wHs;Ff`DwEfy!NLNY*65WLMNq`4T0SzlWjgZ*v1pa{XB9s$p!OV$=@MdnDK!1vv+;KXJI>KdG5@YgdU%TAKOWS&%6lg zpLjlSa!B$2wq6%LhDt?Irb&H2SV04&EZ+TuA{Hl>9mW8;XB8|bgmUq;pzHl?dWuxv97*<geerIJtOYYG%f!2D{5oi`h0OqwegI^cg9E8mzhMZK86J|vvLPks(WG8Cz5rf zOJ6(i9x7c(+c#n;@#s)#p3=Y^4ER04!59*T)rS_u4f*bC>|b+#6Zg|EF#dJToADQl z(uffNR>SBmJBD8%qa{RH+mRGPRK%kPvlO8OZEj_aT1Ccj4jEpE z;}R1GRjc_d6{GqRM;V)2Uen~B;-#!R^Z7=Q{_R)FXN37ryq`uOZYi?Im4Po|&T6pM z7WgfVycpMV!|TI`pYOlL-pc$e9r|FZ8U-t?&;OvK;ktm8DqW6+TvPE_al)d*Qq$0{ zH^`cNDQ_uqW%rvP{Vp=50Ub)>)ST9WqGa|LP<~}~ZQM4$ulPi7lV{np9vb}yhzLuY zO8>Zx+BjIbg}F*Ba){10_mvx{&8(Z*dB@4*hR(sVDupukGzRnvxnx~EtVzkPL-F;) zrPaE*m4%t4R{^TIFU*Ca9tJCA6YAPvSuf^VV+~5W-_FilrQ%&duvmYSS#8ymL7^9_ z=1q+kT5$aUvo*kVWpKgBF?^_QGM;`?(iYlT!;vs#*SzP*ysrM8HIr4@%1}Zr9#*Mf zuA=xVWv(3emG|q_O{z}bcSpc7-o^j@(VH?R56*Ie`1ug#u3QBD|>6(PSndxDZXD6>Hn_E;Q!A;#d8c3i!MTg4Icwh$=w(M@u4U!L=-fQpTof0)!=i$7ze5AtVq@tHwyGgL!sNN zKsSE$FQ5PG-&wDt{!h5r9Orx+{g_>wbUB1vdkM}*N!LL%9UYIyLP%{w+P3Di!2?xG@>QBZNxVUl(R_cO2V2I9ToO1L&@vLWka;G#0yb zNesc(&UOKWd0`m9z1tr$UsNh%k5R)zaSAZ%WV&7F!p+u~`hHO^89EjzmlbseOdl|p z2tNsfb2KKNcIsP)zTBuKzZPD=gUWo*eEX~D~ zh&YOA$1?=fM%3!?At+wPRiMDB>omh&?|-Dz#`fo~R=E=E%dSSv=>Uj+d977|0lr;)U&u-VIE zvtS7`8#}-d6_O!fLGyr#BTLZ(rS(=~(;Cw@26=d`2+@cR3*|0hIY(`IgpL*yc@7hS zDlTORLm2olHRUR7OX;nl4ZOff#^tNqVwJ~?4TKBw$V)oaP{MxP75g2#dMtaGd4!51sHUP!b~Gs zs5!l-NkD!Gv(;0I z-r=uwZ*R>`c8F~zzAG1j8`pZrG0rj!nXyDSLWF}x zCsr~$K;c|I{^IkKs%k33k^vWa+vHhKABQWKNj27AE0T)?wbqL3pQ!0u3jH)|I#(@SkNxFDKg4Q(5V}wi zN~~o%wUounTJ|IyT)ZRX93Q0qAdUHs`8Py~wGZ~8dfHG#Ytg%GNHd#4EuNa|^V3WE zuE=8RH&gFCYv;i%6iG~k_IuWlt23?JEaO(}Rio$2+S|W3fMTEmftzGCcv;HPQb6(|HHsEK(3@#-5;wQD&CcWqO zv~tl1W}tJQj)V`E&NouiG0a!QQ8(DOwp4d9GVki(U_;NjqBg0LS)-l8_r+U}6J`tn z)-8n|O~)C6o-i7)aQQG4!b}%yXDH=DBg6qzpe}V8?zsxyNpse5xa0*^!O^z}#ixEg z9!$x+3yp@VU0C*!1=ohJRel8>DlT82o2b{z+Sjqo9h0^fW(<3RfMi38LJ#_rC@}#F zmaJw0Vt-|aa>ngw^nt)k@kTrAdlV-Y_dYT>ehJ7T>g!MyYDE0L%6z(&OwfA#twk#F z&`Gb{YWv1C#2Pq306D)wH6mvujo@WqPV+>YBFez;0iap&&LULXN8I$HRMPfax4X1p z(1G|%n27&g(2zhdMZ~?%ZU@2_3;}i^BAZ32#=20s8^50Xx-a<~&t*S=48)G6iEC>J z>4(nmBn%EX$I6++e^r!c3B#P!HWs%ynZ(67*IRyo(p7WBKTS2}_P*yC%%S}WZenk9 zivzg7T=O3TG8LfF0wxVFSOpL3z(aH`dp8KVU`YDlF8X=a(i^$7FKWBjoY-QY4toX8 zaT>q1NcaI7M0pyZaGKS!V!a@9vfzH@Wt>;4SgY<0qCHNZ)h{CoAE#?v#kH3_!1hw- z+N+tVH*4M97cV}q%Z4vr8>fR-769`8%Z=Xw@e%hNK&8si4P=aj+5*axYE;LPDr+x7 z^VtlUY795D7bV!A=y=nRqu!^W(0&n5*(Al_SLLVwAl7NX7D@nTkN_V@{y;y)I0J>s zpeggZCZ7U%65W^kHS{gV_udz={QbDd83j61m@Q=+3Sq!!bg_(zp+VH8T0GA@>lbxL zqOZHxr1X22c-&d5n`tcld#L`0w2;m6$V(q<7jL$f5btZrR&N55B z$`h>5`1bkmH|g8ML58Q9iD+k^xM6viJ~AUuiJ>LBznvB7UDwubFXxv((y3JXvo_&a zl`u2NdW0~)09+Z4imn572kH?J&N$!Gc)Hg$wpC|deAsL%HMrrbt+?F_DeI+62%#pS z@|&3-I4*!0d~z*08=UNMGJuo3qjc1kw0&0MasO{aAjy6|chW>JsiXT^Fc-QNlpVWp zP52_yD28cvz@6Hvw6_|wg7S(hgZj4*I6e9Hxr)7vuuvI=7&DX#z^&9^kosz)_Qpwh zt6r+j%>Z(DE`22DnB8^ow*5;$uE#Wkp#eGC1$c^cL65v7>TW3dt)~btY~S?W#>z?X zOr>4;Vr9qjX9HvCvKE|3cYvxd-&+dCh!tCf;(5yt`+SH)>XcM|A-Y=j9>iT2vtwj# z#U;jmRH08}C&=^xu?PglDjleXn2YWM`gGBioVXu2Zus`tmjseszQu<{S(Bj&$seiS zBI;22r#-xjytuxQ^w=UiZcxBO{eo*Dief#fXd^gtq-9s2zga?)vi;5WAIf)L zD@+|aN@?^6~_GMRE)BglcyM-SsBsIL@2 ztB+W)wQFNo)hNnYi@1TtOFjCc4+kwR#h`%#urEU9VJQRY65l)eE-s64@bnTG3af z-fBPaNPnI+@Ubo?^A@|G4*OG2x-wYGaOA(NuOh(7ykOwdPX6624gjv4HFz!5%$5gCTxG&bUk0@M1YOHNvf z#DBY63XVuU`DH}mj&25M#CIGM&dFKOoI9#X=Q=+;&@ZBxc}$ppx7Ve!M-gm62V1s= zX8!)e`5#UoLA;4iJ!f$k!IofkOi7LY&JMHRWmUDY`2RK;j zY@4r-r+C`zrLe=lUIxeg{DoXtK(d05kk&WQ4MAFN@2`C+{TgBEb+AS9uJg6#+lxm( z_DbZXx+^5!yU(M}=T{z;jXL4BjVYWiQ=Iv8PRP1lFTd(i(oTgwb{oDK332&rA2a0> zgE-4xah|)185}?{IlPEV%TSDMNku`$_MAnz7it_0qxoy~2%9$_?J<4*UZN?7tBKjq zXHy&BSzcld0~*`3oYx-&l*n*nzZ`YU2+@28xhKj75Ip}~1eo=FZlrBcgT_ZeFZg{u z^C|Gd53q}O128>yQ(j=PRAK*-6UX$Iksb(^!KY0L;CBEC`g<|ef>pV?#1vHlN=o5- zrb(+8^3ar>X!s-Z2s0k-3~k3X$?W(_X$)I@+r6f8**N_y@tK$VkoxZJQU~8FYzs0h z{#zS7RXM*_(n2GmV~54zD)#QgtHl3uy9ke7sw@32V55?-Ahr6;oMMGy2KE(CWRb;{ zr_8&h1SNMMn8vvCxGp>prDen7;MWk<=plzdUw&jBneDp3SUrg)m24#fAJyAr%ajyd>-v;L_Z`cYRGd0 z<8*k*@CKHIZXII&L7>;mSnEKfnZI}qnpXpK{D+iuaIB3QlgD~C1e{s{CPh;18maz{ zi$^bToP3nQwlOzN>i1;r^rie5@vqlIMScyBZhPW$_k==zkgUmPy8|08UQf&i`v5t3 zF7)5HWT;xw0x)0&exMFpYmMJL)cd%1l}QKmoN9S}Hfl84A&ZKv#T~%c0ME;JqpbJ} z$8=Zz58Z_0;;RIyeDJhn1MVmd-uGe2|8BdPus2z&@RI8j{xT!)k@$v(pqY!D=LWiX zfs|5K6+nTSE35J}MyG%6#IQ;OAHHUsDC=6?nD7rC%DrqPbn}iNZuG_77C$@}dL-5X0Yg-7 zGipi{<2pL>W>MQ<{kL9KwYWC2*SHup@A; zngZD{e=Ken{1xIEm{TwQnS6pxH)mO(Q$2rAP~DVttQ-4AI$;{UC1mjI8ulRAXQ1`a zasF}%faN$&QL-`!uKqa;qq55UuuJZ*Y>l5Z2aV?~{C4djp1~bvHIsO7D%c%Xk0f#| zufK8sY*HeSiS0=^_SSSyn|;Mf_l+QQlmt^6JiGHy(+nW%m#?9j`yS9CmK1S>u&Ffm z2f+rmD0yxk>I0`fwNOa38`O%nx&VgRuv)KU%SWZ1 zdytb$=|U<0;8H8;aE+_sQAOp_kpzBG5braCO_2;6lQZ zUZVpyWvY(2!-KVhdV1T6NpG%maar6^q|m3w!RS*AyOL3rdY?q!=r} zNXfVN_L@%;*tasaCo|tfK2#r^K<(tMnwu-Pl9y$6;pp#qA=g>AZ4Z=`{^8Y2x4e2T zmuuMMzO-TE`{OOX2ofu~+?J-<}l7E+0X#VI6Xpg?g&f@IQ8K3peVs#lnQU*31rPGS*XU;{Te@PSIrZ`zH&A`0u)_gdqu_p>oIB$ebhSVl0;?8^gwW-U=L%#yTTfho=GQ1u-SS z`4|O1gou~aLW%xLs=wQyoV;%vs=&U+<`v?&iuZ&1-cziUQYXZZ} zoPS$Hjv)1bZ3V>ABJ?KLAVeD9k^=bk<|81ih-QVp{COd1ZsKdD;TO%h^g+FS$ou-Y zl%&|@wsX*L1Sxm?OYCwtl|2<~_FVVS_dVnM^KNXbmv4S;jpKTNffzI7?<*zwgp zX@QlWvWCp|7MF*)BaO|4<7BGZw{IRiFcmzoKV#B3N^7?D#QQd>#Cq312p>0Sl^;}H z#3nF#{mIzK$JfUn_0sd8rTEyLL)SN=2)94Fm)yB;?SHEVZtab~I5usGaClQFXxou> zTgsm{|MM1NE8^ZL`nyN_Cn@V6@9cm6!)XUAgREWmshkZcKFE2&=Q8C?_Ws0&f%iR~ zl-ozlY4>Y4B65HEU)yHFceG85@wDVyZocwBXthED7ElKyScT}3kA}ijR5aSz@P2o`EwaJn6{NMA6|UH9g? z4HTYowyay>IMQirZ>wjjeCL2Q$j1O(OluZs!c2uQ z%mD@xQ_0m)uJNwzgTqUQ2A_jM$~8w_P2=NUUE%<3QwSAc0DI@OnL#_0Xo4)Rm!l{_o9sGp(45^&VST2@*{e3T_PWAR?j!DLCr>;`;wx*+ z#i?QMQ1Fph6!l^KCMt5Ze{~REvnX}DaU!?CJhh_&2tY_6#_n24z~5@qz(D02PfwMLT$`OCKI9(eyPFo{&ggoE3B@=0erk3Bh$JQ zF+WTFV(DWEWOS)ecHN;}J;kE~PTc&L zc>+{CnsS900fg+etJILwEP-F|Iv2{VK1r$^JLXqJo8w5>aB2K0RPZFo#FSGmisb~A ztPwW;Aieeu5 zG~NHZVbgU$8gmOy86&_BX~fzxt<*`%0xi{GyyVUim;s*(y*HGQ%`wH{S^-%UGk}#= zOMvU!#tlebqTbcLx$vgnU39ml|L2VZ%2|GUz0+fn!c0AY#mKNoI0K+Hi3Ud|Yd>Ki z-&ZE(UL6>y-`;&?MOM`Mv+eh@PyO;^P1wQ@o;l9Jj=64KkEfhNatDMrK>67~4j8t! zO1apbRa}^=GGf21Zi}&PJFrVfPcG*97$CEZ6<9*{Km^I&Wa4Ghjs4d0i9k4!4kW^7 zs78$}L1qq?E!)jzsHGx1;+~@B9Bh#iOYZSw>-be*P(6#>^BBWjq#-AC_geF<4E10V&{^058?Y@7e-o5=_~lrOHZ8lW zoZBnc4!QHMdQCeyF(~m@Y_A;T12+I>f$}K+PdL_`2 zfW3QvwL+vB9=7|4I*8QW5o@r}F5(D8bbvw%o{DZ9SYHSv6SzEVhJH*B3)t#;ssFNj zdwIs!b$i|0gCipMrIMYJ_b9dsA7e~NOqRS=pA|*K9$&#QJeL3_bHmP>68A4>RmYaI!cX7%=)cvnSLR(QiVcB_R7JtkIffOXz z4lX5M++6K~(`!X+-inBJZoltnaiy!d>6*XL?_0JC*{=wbogg_g+~2+A+FdMtd6qmo z3s`RsuCD&R$v5Q36V6yd#`waxT2urQtW_qJ5VGU(U9H>)ZPsZG?F}b;`CBCJ-;BDy zx8%hGGBJHFTJPJ{@#3$clA{gjIacnYgD7NE}k%0 z5PInBYsEK2^H)~$_QvvQw;pp}LJi9FH*5Yo%#yn$*Rl1*F6b&Q%}-BzchRu ze{ERt^NUOVN5tkfU5!S+TxuL|XaBIQi7hUg!%plpOG=TGR^!Mb7fIireM`&LNzwMv ztIhKj?2wsx-1HF<3B!o1L2)f2H#+=%KTdWjes-8D@aygd3CFT&D2B=wVgWAm2%HD< zz@=HD-@>?rzj;&>MfLYw*7%K0nIadsx$lc0@sZY2yIz6v>uo>&7`aM?b1ZXUi*ZgU z&cKXTc!hOyD~XYz1IQMSJ|3Ftc+SP)MbO+o`8t68dhx$~Mut$q(q&QZ6-6FaBWcrzY63G)daS)D@5gA3C`Tb^L*IqMxBK$karvySYq z;C!=jZ>aQQX?q3N+&g(dI^InB@9%7U9gGC_s->7ns2CA-snBFk~wQvDnh9Z!% zTe`ZhD)0=DWb;69a3=Lq49Jh4hj4xD$n%J&JPKbB=d@DzIDAr1!&2@@STjoi%TWeE z9xAtUdneWq>nk7)14{3t8`%c~liCm^z3~rmT<(J&k6(1TKJ07ApSB;I29QA8(of66CdY8q`~Xh>HX2wXe$8`RzlK%&Xj##Yw61+{MW+f>`{t zj#4m?!g>o{VhTNQn1*<1Q;p>PGwxNZ7HhsN&fr=RF$f;U3CO$E zk$2=lIsNK5h1Et_uOTl{=vQj#=g&MGQW1`JAKfoxC48`7x={SNGCeKj?2XIEgaW5{ zL~lu6Vyi_xWAKxeNk<;NEi>Xgces<$$bQd-<9H&x5Lehy3+i(1O;5*ZW2xJAYsgMoua z*6}pq#U^m?o&`;?(LRnY8!kVQrE4G1iqS>eXHOwg zVQ4ByrO|SMbJoKl0i+$vUyF5pii)}QRTZgKpREs_%2gHa5WN8ioL>|+P?Q|#Bj`l_ z4TEd@7C~5tZ}l~mzp(cS$MxbQzL&3yTjZP;vb@OyTX{J&vYbTY(`rJ?Rgn!_c#j|p zdL-j?vxV{=-+y*x^Lc8wNBhTvoCKUK#vKW2rpCWvl666OQ1-QK(>gB?MnIy=Dch5a zK{CF}pYsmu!-5{96V?U)d`qar=6mc|Ri*hUe(ijD-sPdD6}!$QEHMMfhB+*tbSk^P6wcLUt6O$QgAPq_Xob5aT7QS3YwdX!$-q;LQd<#J$L#Q zhbf!3w&NK080NCiULH0Mv-Xv3(v@khEDFgJj9+k)1w0&IS{3W14Tj7;@qC_}2FI(* z23f9AlB?O&R8r^6?ZrRMXZpt<_WW0G>mMHAfGr=6#dNF$mNDweadg?lFoYRqmXdt{ z_eY;B{~J7NhtQri2}?q-E_yyPmP_Gk`r^uuDmQUf?e~-leoWUn3n>zVNB%Kkp*E}?$ z$b>b7*ukotpeKf)$XZuPU*cw%NsPZ?R>#K=nFVu+1=7YixVTL2cdsl+via0B$je%9 zN;t*=`SzUKKYh=Gw)P1>yargFL_ zUnFu}MVzFG?ZH4#tXEAzL+Ln}F?2`J{OWcXTuy((WF9y3Qd#XWf5vI*?|4_&DLV9z zx*X^M0J>+-3Z+2)R2~Dn??SV&<93&1RBW`XjgwsJzPic^yfB;54{;&`D8q&-1`O}+ z7R?r;W_QW-wX~*buj^b~TrqEqIu0G}^6OkZOioViy*ykGRw!Hsp#B)bIz3_wPv;@v zj_4i-i*7_l(Ic^7g7N(y=ADTqAe@*z`krQ5aEx{=y}9*^470@r$2U16@{;anYK;zT zcZPdXnoWm7bmmYz6U&eIFBRPzuj7*SicAxo{maG2Pt-`Ac6elmoq8Jl?b?tFVB^VU zGvWl905si{wr_c+cRT_-OD&3_;b0wICq0YcXjPOH>{onvtMK-KQfj$X=PDbM)6oy| z5Xwi7|@X*Ps{SyztMmOHIGLh9_7p zS`7y{e>KL_TFn7nHEmX@W&=6~Od!W`GB^Mg9#F{{S+MPe7jpegLsjkPURg3b2dQVTiB1qrH?)`rE%@_kz@s zTp=g>+QYX^5L?j$d6iWaDS_>5E_Qb;8vX?RSa0>il)KS{m}iiyWHQg#RR7NCsj%cp;f2+FMgRJ!~DZC5uhLJ;>hGT8~3e;QKK5 z2WCpCGNhE$@Hmwp$r6~TeuwE!<+BqyW~`0c!PYCNW?YQpVF)|(R)!$*RGnknfy@3G z(#scaV4vzLwedOrU}=`+Q}$$3V=Kl9LAsW-tI8Xdy}i%77)Fyn4`D+!jFDDsmRWzL$1T%Cs=t0QI*(ojkHvwZZW44#?|E&2rtnw*E?dPF@hyUtx zvYJp=bWXR;-59!S;%QX!UL-+C3rA5`T157zDx5p*-xY!8$`1TuPz1w=j%3 zf)~7(5_}mpzRoodva{(|PvWxm@aGV_J|v7^P3vx0b&tQHbxOD?ZKA@zCdS-|8ccaj z|D<~a-KEPC-8PNLGKs3koNj6x@pN!J-{{0&ViCzAeCMLL%Z38<234n9L1)7>dgA8w z_i0D_M{VnxAkz}+A4h`fO);le)$^l=0V~k)pxs+}n*p<>@-9-G|GYSp>hAsJA4v8? zjVtl73^fG`3Y0Q`!{pZ6;1nhxV+yo1@^BKknIbrh!9lxJ4?U*8{s?{Ayr%0gw0AqK zQLuUaimlBJ#qT5zq4`P#pc92zYgAHp9J$Ftd8$8RH!s+hwtT*LTF847kAIb@Yqa} z1pVL8y1gN#?1mS>12gc&Q@n5pIPk4O*tXu?%T?ism8fLEV^GKF3Nq0jqPw$6*KtpQ z0$Oik#_Z2jH{eS0;NH%d{wI!`j;S3FpXa1p`hM}}V7P(NPaeS8_Q-}#pc<3LZnT_p z&K+{`Rz7^-EnYXdV@w14e--}90^@6?YlDL zU@z#3B!jRzs)htd;Aj})D(DjYBcNK4k|-}BOLF?GJnghMx5r1}rz}Xh+019b$K&r_ z$;5Ce&p!b^Tq}FL^l-#)ag^}iur)c*X1K>Zst$^LCHN{e&-3xPRjR) zOXaOX%k$IW#=k1F#>_oSAg~cxAJMaQ<)IxDlKNUwQJ@{w_7b=Cx0ov7rn~2_Jc_ke zsLniKpaurRI_dwZU-cIgeYQy9Lx3i?D#zL(CCd_UVJTqt7P5a>eu5d?epe>W)S

zNseY5#8Y)?C!nXF0@((Qe}&xKyS%G5?ViKzwfOOv(Xae8)mDy1DZVVV7oOV}))_i? z|AzVEQZWZnM{x6B0`ZLIH|dO2W8mL+8UQP-`Sk1xQ^#I294QM|U^m%W(h;C)TkcaN zF5)Y`Ix0cp!~&r(YtnjRh`QJ3rR&W__rCR1r)a?Tg>37i!}G)sqf>$YG-ZVf7OSIt zpM(EZ3CoDMD1oP)^p42hI(83?=T?B8Wxx;=+&Ilgiuc!_HRW&DHwiy#Sy~x8swsY; zNzOibLcJd_Z(rjo<%xKzGL47an$(;WGc5u?96&ws#+^7@UQx^F7I@}jbM()r-0o_x zSQD> z@_^wiW!V(>%Aaeiem1Y#Q;dNqC^M*|K#O9&_cLx)4MWSp4vxd-%Hh#y7^!%6NLyw0 zt(xIC*AsWkO2eo13O^_vJ=tFA>1Iz_kES8-JjC%YrG2Y-eVd^_c~aXhJ@@_#)p@sw z*ikTK(#sIUHumoEorTkcz=kJ(TibdIH|jeJJxn;*cIZOeBp)aZOt_6WWr&r{gvw2$NnXX(1q#f zT0&4*L3*L5z6<8TCNQg;RErQLdR{#!D0*3@GlEUdG@Dm`JN0r@+p{Lkhm)CW^8w38 z@o@bR={XdnSh%`5>n-GgmKdnhDTbm(kgwmHP}Qr1H;FUl==(o@`}d`aE}zG;flYT6 z(@_%Q{WlD~2!znKA?6^EaQK6SW8YA?u=fC_(FNg_Bm&_~NI#3-tvHHR4i((8Gq1P9 zl-Z@t+TIZS+2|i;Hpx9dbHJ16Jsw9%fz+u8nzF7UR8X>V^wDRQM{hg~C7PGzqKGB! z@;{ozQ}8FmU!qz=qiGmBASrf*aR-OS&3px_2v-=~7*O$4#$6NuWc&f#9q&D9HOx$r zF*uK@dxxk;(IAThxf@Z$>Ej;^XSwez7hOHRbcx@t(No4Ca5L4b!+`z0)cj-YT;=~) zY2naA8^PSL&W3P~AHbYs0Y}QO=aIzBvH+ENYmjWUtqh)c$79z#%}%m@=I9O*1Uf=L zIE*F1)%{S3&jmJ>Q}et}AU8@k9o!Ok*T<-q19c)~!{+Ap3*F5`_*lQ4or8Lw%VE$W zlor59`#hEmY*62WqdNAr&wCljgH%St9%eHwOcxM^qVv%$_$@tf=QUcr1p0&u+l4c3 zL_Sh5XtOo`0f+-XMFP?MBt-E+&I?)iSd-8sxijLoX{=iNk$GQKizVg~$ZE~-yN2y; z-g}FmK#3z}&aOYF44p!*nrA8e0xcU8!u2Xu=8p-=W==s-?U~$brH7~dW{$4bbApe! z2ByCdhiS$GXAf!3E|FM=a~7tRY=c2>A}2`K(mHMGb)V);rq{NV^`@qSd<16R8$9&N z9^hUWfG&ODxB7(Kz&O)%qmj>E+d8^)-mks=`AxZq(&>KZPx)Mwk@>(@?G0TAdZ2%< z{NLprkp3HX15VA|z4;eYa?ZV@yixbrK;m?6;%e#jTbJAqUOMbN^empWW6c+pf-46y zWl3O8$GU}%Y&yCV1_Gs%#|2HQdRs1QLPEEvqD%BM6Ti-$-&s7W@8;d4Mpl_a2e+`Z z)^iwIS`r*Hin+NjQ+R@T$GRD}UutJlgOTlx9pyKGO=Jc=y@0pOpHZcviAl$Ha&BRV zm1962;MSBBgB@pCda)XO3wL4GZ3J%lLjr3t#t6cUkhV%gDqti?M~w2LL8 z#YzDx{1wXv`T2*BWa%p%O=vYfRHevtumvLpEMNdI{sjO4^ZQbO_7zEV^(k}q?b(0e z5C5yV%K{u+!W5A3M7@C|ib9m5{)SO6Y}m-uR{RxTI4*Ul1VvAqyrfgK%kYL|aKu|j zB3~NHXu~VP6yq{F7WggEpJ8TRgXu>$nr{izN_M+m9>L)Iuy7%u;;(RTUC$3LRsPZp zA*0Fc>qcAZwNwnI@f<@2-G>pu&3cEN8uD_f`E@&ri)uH>OvL=U5XW|#bh;Y7F|0^;T)75=_Kgun+V^XixbUwa=twQ=6Q z*&w=(dIDrNy0U7(qWIAZl(yr3oK^UKeBI3WmR*-zU&6FDE&s1Xo(r*CSg=7zMwo$cK0md&|>uB{} zn1{+G0`H+*JGt*&_oME~dUZdh+{Rp>W&Y!#qcDxuAP>aHp$-u1vau_0?rjN#d7rx0>(jHr zH7#l<-^P`yg4rS@`}a_=4_R{PMQBCZ!@fHA8C>j>rz3@=H!vL+r@vZBOUy@LWrk>1E?~qwZ_`9CKC4x$G~D@3sMr zf|YT08ecmlt!DW1J2LCSOSb~;52x<}nLu)D_UqJ(^H2M%w~9$CjcGU@8s|Gmxb1Fr zgkD)xzbsm`<*JDM3hIY2$gf!s(6MKA9<<+jNwE6(K`yi7WK~T-pzA?Di;;VsSy8xP z1bAcPBLwAU+-PkxMkGW+`~oH>#Pv{~*Qww2KOQ(w_8vyGXu0LX&^i66Rvb;kn+Q&a zz8#1nxUPLM+9q?&WrQ4u(g~b(mIW*4%Ixz-3LjDi>^>lBZ?kuf&BMX% zb$Q5o6Qo+K0`wZ7dce)--@`W}qqB}zlhTrAkEQ)l6my=eE6Gcc?QWQlpJ8gCdCu}t zAEQTRKvd?kwmrZ7dSBt1(fykC(4JFgf7!xNlvY7hl7z9 zu*GJ3;T4Z}w!CTF@Y#LgU=k8PI%q>rMT>ckKaLL&tR11*9MhTik?3nEQ8;!=gDkEh zJMt$1%pU!qT?V0DgBDyt{(|Lg?lCkQs?%IdE6G}(xvZtvaEAZ*c~{wwtG>y@9|N@* z9KWghNJ4@tLIl6`=%~tD-Cx=o2WgBWMbH?{dNraLf$A7Dz~M z33T_g#xLFDG_xVEpG9(IW47aC)oF;+_QH=bj%Qc{4T<2_SiV9fWW%{M92qfdkn0xU zOn5!Lx1ca~MVYlFdQqRTvBQQ#d+vtNYcbxuExUcu+Hegu_@u)aN&-^&?V21 z@e~NnZdmP9)twgP7{now9uhAyAw)}Ur3Nxa$X8PU7B)1Da$-Mp>V@xU!gqzeVtSJ9 z87N{7zdAL8jh#LfenLIeW7^42ip5~S&ffTeJ@X(Yy*e>0ljj8UQtW=aT7hK3I9N!% zL-PiB>19I*Ny6E^Y!>#t)%wBo@x4crKR1QV<692%J=&7++<3_ltD@jQT~}QEHw^## zU%Js$MY3+BHzDbe$Fykeqr^jw1HqaS=#BgqFEPF~W?xhfZ#-@$5mkOo^2E>_DUy+n z$>p3J?^SPzHH^vp=pqxbg8GOfnXHc+65vDulF7|%!p#-TC&=3Ts89Wp($HPGR7b~& zwpIQMbLx9`7vbH}&7h)`@oq1|i!Pl5lZfg{TBfA2S7J*?7^5vOn_|jL$919w+}*Jm4K~mpA0!PIREt#Q@Kj z9kO29@9|_)I6&4>{|Zw5|Li!FrL{HJCw|fx!%}^C=RH8rRj}XWRTJ`;Wz#)dS5H2)^73J)V|s6Y^Utd zzbblrtsAyVIQn}ZGydImtj_yuM8$~rDc^7{a5<#v9%Hl#>nhO`6>+Y`S~h_bhUJwe zcI_6My&kF=?XJ$lIQ|R<$2!%DP1>dZM=v`OoW$)60*;6wvxB5DJY)$~9+l+j78P@6&Rhd{WZymJ?OKXB_+2NOIiy6! znE_K=XN&Txq-Ll5lJHIom8>9(T&-Txry{g$>?&^N9g1Ye8C8Ix%gT zB5Z!fY~Y9_hs;3jI&^ZKSV&%+U2H!KnE=Uqfk121{$i<`pwEe8Yc4g{ePs@#E!$zC z_m~%P|G8a=$kiUIC~pL&lu}GmXt_{QT~EGpBV+eHEKhZ^U_fS@Yh@buW*vHf2MH7- zwz3Lvi_?L&ICe>f!Py8VFc&E?^z1pZNQ=Bl0?O!HF#9))s2aYoD=9n~Ng-f=wtHb1 z9COsG6P}Oz0-tPNtsCUG79KSAlX(mV30-9(5_4+T!!aZy<;0`jEkyQPQ2K|ZJ@nH8 z`}W6b<7UTSzhUS3P{imL&-z7|>%Yj?dL&9V#*a^raal+Xtp)b$EsRHY9Gqzj!x1Py zdpGCdNt(HQP4$oyI4XH2h8JbxGb6d}7S8`<(;ArtN8_L2v5%b+cZ}0Hu-A|U9YC9* zfkH3*N{H8Ry#f^70_O&)5}p0lx3s-;wV9Vyb(+hQ#FRrn2kNG7yV3YDlwzogJb-V_ zVulJop8GBzos+nMH_y%}5YQbIOAc!YU>B88pjZI~Y8}9#`%S%O??LhLta@TvkhSrl zI!)`{TJqw;sds+9AXUgEwKojoxEYcVra@S(V(2Jqrqy$Wc(s@|Rm1O(|Bbw|&!!Wn zKqTmZGRR$X2>@e!HlC0NLP$zG9}pvSIs8h#B1-F_N;bjz3UHEJRv-WhS-2MCS7ey` zSs%3yD!7RbG77=)+be`KnDAOrbDF2t-bQWONc?lG|JK zKpatsEPn&iA!)SX1-3i`*VgOQ^Cuk}1#33OjYdw1iGzcY=7FjjA!0r(i(H7NDbj5x zh^pFIH&stv$@uvwhd66^QR^U#@$(P%H!}qk9^qk(!C{m{h^XzfACDQ{QEGhDqpSK&Md%F_V*Bfr;0~6npL=6O}{M zTz!2AhqRDBX~X3ARd728DA{VA9Iz^{3rLv` zxRH`_x<6G0uw};dg?7ED!65hMLkloEB@dGUiCX)+f*pD5k<*%p;_#h?QG1nWokp!o zI_&BY6R;_ppn}Efw*n2I^$mdQoMoctS);fKUW>R#gj15ph_E_#LPj>{y=j4(V2+%@QR$2>?XHuzjqhN9O{t~@cz{59 zQE>f#Wf(H_SGw$W=${B?ni>f`POrF}V|X%c{!72?j%wXTsziG5i<-qFJ(%MWlr=iQ zs%T1Ho}hK83(1?{)bnDk!KjYsUJzbNk^;Fh!^O^|h`OY*4 zvd%Xk>m>FP7pb@HCry0NCs+7(KlfC~S?W*vM~Ve9f5jGI?s!j3P*Srg&q;;PXr6>F ztneR({I?{tEWE{Sg33w4tr`uhy8%<`A5*(z66r7U^EEHC8=PNVuGaQNRp4+RtfkFb@hZ^xfB&U*~R;^ z^c+J`8NGm$t@8zoc zWF3}XwVH{Ho!hx{3!Zyh|0I4j_(PzAC?kQ zes5i?K<+73Al>rY`ako>i{L_!>>?I~qL(zlslrXY&bch6D1!Wt4W#j8DG7$ds7(} zAb*x=6Z4--NXeyG(&Kv@dB<{XAq9fN%}IP)Tzm-yT8M4!B|FNQb8bM3Dy4{lsi>RaFU_&xL@e?0f{>+MinJNH<70t*j?g*zX0I$ zRiFn#9?=t&7{?huY~5Bza+Zm#?NRT_y>yq&RTL>IrBW~ZQNA4#=drc>RxbcMX_Nq! z@noiMQqmp`)Lwq*1{}#0@f-oGSHDC~BGl)43XZd=6}<^u!yL!LE<8~ngnBa$DpN(EVC&kxZRGRH=RwX2 zmru33g{rb&4rfWWD?P^>a7Sn56XZ_yMR(#vXm(yRsA$|_r2rkjEtT-G;t?_e{%7OmLJwLa8U*ZB8^$KwZd?PtbpB|n8jbNZ(FdsbWN}wxa z0;#f^Kc$_n8ba6GwlX|9^ zRE}6Jpxg*F{ZhcMQ~rB*?g#3|vWjw0ee8@HG-Q%JXaL-MF4_HK`i!e@rGxTZyh-657JFnZTbp&ps&g zBquArCtW+&;zoBin40VpFA9N4+OH@+ z>(`F*C~oFCYU?n_PV3e23=Py{bSnk(HOB;NLOs^w>>HTRx@+<9bgI#=kFurf27Sn@ z_d5)u4UDI5xyDg?p~L|hsgz~5>joOUWo@cD`XS1w2}E1c7#Ag&{w^R6aX7@1lzE{t z-&HhLD>B6-=%B#cFMXvV%$2KinE}`%aMCs8=tm=&2IizabS=Q;%b9)vSC*VK_$dA| zf9`RjiMdlX-wT%`pb>&j9npM$&+!O}H_EGAhiCi{{7U}}r}#Y}~ezBFr^{Oe;gyO&AhLZ$={+u_16sc?h>FT>lw}tKOL1X+v^O z1TM~|)v)1m9MW!9NBA@=bAL$`>W>a^WgidI`F9g*4vdxPk*u3=oOo!3AdF>;e((Og zp0Moq=z~0r)!gP)me5UM`7lmwGHw=B@FnbYK?p%YeZ*`i!9vFXkVTx}{<@D53blOb zz&X}}^-EQHVGw+jQB{A4(T`xo-4hd=x;z5{S~1N~ICJ*2@YyucJ4$`!H}bs8DPGk( z*aXCVE@kNWF7*8V->?d$wrp?0VujuTu0fyM9iw-JPmLm`HqW&BCaPS70|z4~9O>F< zel+D6bnm5%!L->spN5F2q0>g%6krkASXqf8U0JWVJijble|LN0dq7W3ujrJd%1V}w z=Z-)V3G(CRaZe7^wmZaar%!>G5UCntu@Ry%g`MVK4kkAWGSvc8ua{YpRVxRV zGOc^zq*cUd5#t%iM4ygeXph2lLEaZG*L*5Oh`gE@|M7Tzq%jNIf#EYg!JDWG%O=`+ z$bAO$EQ_y%q|w}STtZBLaOA%E6`df(ZolsKT7ZlNTx3P_fxF%3SSnCPDRnha$zRJ8 z4Li@$&Z8RaR)Jo#&Y<0d3`v`FsApfadC6)9(RTf79L|C@tTss4F=H#U?5n%E z4););Av!$KUct(5HLZeNlS`g{Gv?A{{`!;M1ID<3@VEtDN-PuuUP`-d?fKi68ehz8 zI?EXM9sM#5*$RHtZ#O22-T`GI>(_K^^6 z%X+7%2vP$sQIT#W18n}p>^`d z1`#5H>jgtHtO`#u$M-{Fp-!OfS~zK$D7 zo#QKuzzflj(nRPlaBkSK9UCAm+Jxn7&Re$bk8!DXm#uzbz^P?X;C6y1Xd<4R6<+5} z=`W*4I-0Vf#+NkZ(+ZV z)WUtQU0}zaWm?{{ZnfQ^3ErTnkcKOQXXz+{Yu@8;A;sKX68T$yN~N2bWUbZ`BBpL7 zJ^8~BM^EBQ(_68^wt->|@WWmKN`8OC9*+^Trk6)Mty4bj9BzyJF7gQJbP@g%MY2DV zuPY5%pEuZO{gRje^-+{EC$o-PEBcT%rHpDff$qK$a@vjlX}VMSpi;M<#<$Ioejj9~ z6!pAX8iN!MPnWB=ANf7L$B7Z`Iv%pO5Pf?sCX=F?^`UCtq;~cj?p?T^{e=-jxxckXc~3( zYfGsOUN3TThFP|9Iqv1uE8Zu2U9Gxmq{8qJrQkVlq2(9uZ-n16RcCFu9gvOTUiF(h_Twstmu4yBfC6syM&XLoPDz#mK$q2rL`HTfw7cV=iAvM_jOR+HPqJ#e)Y5_{Y(&l?t8-Z_9YgTnTUZhf>n^kVd1+{ zFiqJJiUXOM0;9jImk+EmC%4DdadGd}e_*(Ff9=)z_5*6XlYHUJ+)$=V7E(QRHVKq5 ztHHAp=;oGjjW8#X@%u&E$2~Ki&+$Y{mHQd}Xx5227KT6|W(psTFjFL;6Wpe+ZkX_g z6wU)Y%`YiqFiR7=n1-wIPI`o6lY?#)1M$t0_L)}%_MwoR8L} z$1ylSse6eFL!ARf-rPebGC;TZ2%;!TjeF{mwk-G%^BH#7YpFKm{khoPS_(b(7VbVg zR@Xz-dsyCelH-SbxK0A*Dyk%)aMeWeEw+m)-R11VQj%btD{_G7r)%0owsI0(WI6P@ zH)JG_=1d2;f*T?UEfw905Y(3D`S_{%NQ}K~=|rv6AMvKHS_$B$0?g(QVf3c?%WDxN zeXZ&%$_wh>HzUXWZm#e&%=IPuFZF~D?d!^ym}>&DG#F+k0RJ~k0$Z6wN{XBzH9@Bj zof_9+Rcg%{{d`rawb~&^Me-bRq74M-Mx{_Ksz|FM9!$WnMv8W>JnGg9_hFhRk6LdH z`hv6FNsoK*MXn~j;h^MQx7$_eS8JSKhRHQZHs?RVG{Hx)6i-NmaF?9ajAXxDu)-$8 zKdD_hsd`d-b@O%8%jGk^t*}s}eqe8#^0>%MZ^NN;gO(7E5QpKJz}F-)9Wyzba%QFS z1ivwd#Lr1y+ucQmB#L?%(~pb*0euhPp~w2zr~b0$C9M#UPti(&SKHfBJOQuNr?@N} z`X(F9c+N|whJQPwEp!_Iw%AN*%+lr$mjKS}padX+QEb>#FLYy?edmUTE~ZP1kTGvl7T2-AR;k(Z2V-IGaXpq1kLE=WEl_XBA(IJrC7C5yBp!mwO?cYGnH4=wB8}s$SJan4LatItbH6 zE2ide&`l1#ZU;u+s|dBxhL7I_6frJOc2?PMap*}e)pk@Hpi1|gdV zl4%AqGa+^#F6ZCdyQ!q}Ylv8RKG!iXyN{_u7RD)M&PEp^y$7)%9o+((p&=uZ_M(>& zv^d8Jk~1Y2VyEgkc$|Z?*Ex9+#JGA%#G%p^`#A3A# zq^;Gssa?3xmm*B|&+ZrY|Gj=ne(L#R(gev#MU_r^G(J=zJ2c@C)bW zJt{&e7^znav{1($@IZ?WZc(YhD{;i@<3PWMP?755R1?;9?#w4m#Kn8eE9;QbvjNac zwj?!4EOuRRS+&-7>t0E+rKw<-05pT6Dug&fgRV2{;vvcdE@VE^DzB@*^SxrZu}zdu zvJA6g?)!F`j|3b)ZZ-zznY1UHB@43bhj>6QL1$qad0qd4UJ}Y#d()K8R&r%AshV-N zV}ENx2=7 z${xD_NDBy{eW_T&=pMh*_WSb688+CQjQh;UN+dcI(`c*=jxdw@rvV-1LFdrTv-{k4~M}VhvjQ$1j zCnXRN;8+JSWYBX4K@LYxKvEH{!#2 zI6!m~pq}nhM3f_%ho5(<412NNoSFHdHn8t-K2zb>iPnV99a!u-Ds#r3{8G(7$(D>C zgHw3uh03}*f!0=Jjqm{8gG;s&^VT~ePm1f(`tL_p-M`+v@Mx7a6tuEgUFa{-YBUrX z8Ko;vQ|?lWJKd;V)#3!MWFXwnkUlV z1X;>Ief9e%`*$?JT$}mOBk(O_ZDVl9EbV)=ZG#`Kqk9m7x=b`pvThmqGSW+Uy|qes z$^k-$WIG0zyW&TZNrP{0s*U!=#<26;te^8- z9xveDbTUdYGampMGrI*dE--^m7im_w^l=$2G{lobIr-AppYJ)r_36dkOz)|xk8Ny7 zA=(<|pHBs&axpmYibd4x(@kIWbfX_#T@1f`TvcHnH&JQhO2;x3cE6zRet(oJf8KnO zX;onx!Qix@N{9GDPGoB<2uoIL9+4CtoGD3bQV7*M7qt*{{M2LF`%I(N^I19y3)x^) z?kGJEi*QGZKogBwy!GSp*7s|8How z;STnKdzv-9Bp_z0OZJItRG-HgwWocbjTsF?CNl_ zRHe#NiT37%@%=owx}b}KTa@^t72t|)Nk7PF*wFwD>~^xlv*K4#`Cr!%%4@+-tmmU? zDk4OXPhNT1k`0~C*l%?Ik)d3mzhuY(;o?}DDJi#2LHIR6S+w=BqK}c8muYvf#qoyO zXfV39#YFq4rpDjxhm?J@Rxb<=g@Cr4;%SSvV(0Ke7BpQec8?21k3e`Pu-n!5<7TZ_ z(g~ebG4{4&CTIC0&-04M=BZ}Ai`_~J!+nJlEeOhSXwiyaG}e!hN82!kt7g5z#9gU4 zCvjRoxwN~kr0qbWDJ&E)U|7rFpopkvFV=PKZsAMpNk;d4d{rXTF*8;;|60lDgb+??P7Y7{6) zXYk{nlh(Zz-5(LFwB364m9XHtY9@+!5t^^;Plv>skACg)aj#(u`;&|ixOi8K$-y(< z3*$rl$%e)+0naqKAEw>6q^jztC)^uP5*0S)C~@?s7!L=oIYjKp71HrS zLa3HGuDZUeet?))Q>B3mb6F~WRuqjbAxK3P6Ur5xCA&N4uD5arCu$h2zB`qe_lCYh zF9H@Bz0c7X=#jwr%&iG+kV`KtM4w3-=fM-& zTTt8%fk-0~v7*~9;Jo9s=j+os_lET1nWX*G9z+!QUxbTb8qM<4kP{Jv>qfuRPM-aB z(M%6Z@hWN95|ssVE2iiH5L|F~fUrpmpyd9n0(dN7qbO@T$(#PoHNmqMEH|Ma;sQ7Q`t@!6?iE2{8Yv;n=LPPHlEhNyL_H*{?Z)=c<5lB1F zlF1D?2AuzQ;)3`0CWA{^v6yQ7hm?L?z5l(me}i0-l=ZwiMh`)<#Eyx~J#IzDj4QW- zt|JTML@D*?tsXBYG1CC9_wvC8xmvs*erk=(7yggy16Ue)L$Z0BApV@8d7@NG1k>f% zkO05or;(R{Di=_juI&i*m5sM~V<`JF#SCf7$OVxz17F$;Uhy+{S$cdqDrPwM%CC?o zcT>1Dn>mSACf?HMzUtju*{`tX7vjmNsObyzFq|jyAcV8*lZL!Md#a56{F9z0oMLbL zv!=7oPf9ABceZcyB3xpr)L1yzQ}LR`z)k6=jVx#8kJ7;-gf}D4Kr$pRmV`>fF78Yf z;n<*UZ1;LJo`eLqdv9y~*?yXiFKNZP?|oghehSs1JY{-#ioLs6HvSz9wltK*E^AH1 z(*#FA7L`lRo{5f_g}hwpRUaVf2&60QZgur#j+j>ha1|Ce@9P%;8N^P3qQ>C(em0l# zl&mQIBmPe}2y-EgKNV)Pp*zasbByQm&k-aCjeRZx7D#Erf!;f+2_+U7O^9xxAH;Cm z+S`h8C@JUOdys#pF)n7*MQZzeuLq3gMlW7S^BzYLE?@ioWB5y$qJP5!))2t$LsS~B z%22O01IIrsic}T8%`3E|D_xszUR66#JYN$p+w(T5T;j|3#=S&^1z=|9N%>Y+8`X~% zfTCoyKC!1X-PBj~O}lF@WawuGTL?qg>Yj9%f5vIm-{yu+ljulb^S zO)=KlhY>Ey&u!aj0$J^pdxLi?vRlU;Qu8t%CkvL2cc11yHSY{^S9xX~at}sFp7NjB z-dUzma8$Hh)08K~WIct(~b{o0#lWC*L zpbmt1QT5P0w&@YNaD()tJ(0xvLWx>&^`;5gr#VSguP*<-v=Sd61xo%AR1TbUwZ=7x zLLdqH)>x)V+&<6F6gGI;h<)S*?{M8s2B_(N$YPrE$Uvf-=Uycgfu8A zgStv!uIoGgSviWcF{s+Z=X+h%b;t3Z`_B)Y>GImtC=2al^|&>H6DO zJL0pKm@F3EX&`P$)&{=F5U+(=5k0uLKq3x7-Nm9NT_`hc$#Znoo9D@G-`}~&hiVR@I+$9={{{t|X8h|v zXrV5kCUB(Z;UpXK$)e!ft{N-p=QVt*6CDmeb>R5i9k?cJs5-av2h-dMUc3)Ek{5j+ z*7ndLVdv65YWgbj6Ckw0&JDPMvwGnX^#f*ZKLq}Ma~wfG3K(8zah;R$;b^`}_2Vh+ z9$yuEOU|i0*VQamxMxstHd$-l|NC^<(a(%b%6g0IpnJkBM_gQ6COQV6Ae+6jyb<(K zhkZX{G*9?z{8Jlly~GbspFc9_?)A*9)MLpi|W|?X?>fP>(eN@wxOZK(Yj*( zInmtcQ%s$Q-EOj3%Fz?vy_ke1`z~cUm%zLS~(z#rHbw zP7FUv7Jf1J#Y5yNdvaZ(z}AIfEHByNKhR1{=;7~|R7*8xQue zR=5(ykp#FOP;>)KCOEYp5LlcSDmBp5fB{jwdclUt9Wl95cMaqNlHEEE)Ewv!>M*e3m!a#(s&r&RZ(R<)W zO$0~!!A-xQQsxoP-Is4!MM{T zFuB%lV2}|4THT@8on$Nelhcg*ptKeS>}t!EU>nLU^6(unqIprTvTF2kP0*xu)+HfT zc9Ur}gZK?UuS6ZHY%7q;1@hSg?VHbW!n?Q#+!1d%RZH>%`|^79o#=&tQX9Cso@COY zoTZD&fyALE6Yz9ZFg!Z~y3XUAAOg93ZBLd2lIoNuas{9bq72ZEhG@0Dq_ZheOwN9? zA8b$^3{zonQkC+9&~otDT-?urSuHf>axfnO+sUEau`}MF%UEyStt*fhX%S||zyfj9ROo)s&sdZ@VEh zv}%>{Q@*s+hsjC&ShvBIEBcqM&lpM(ml0qq347>?xAagk;R7Lqg8|SYFmQ>QTRDqb zV{`yR>OF`QFr*$&Z^2b%4XnEo(iS_c`qSzjH0Iua7Jln4YWBBb^%17TFeBzOZQ|Kb zK_wFH|Dhz0K!b0)1)qeO0)+sW6Mqx`(EE`FeZ13rWKXG%^5++aDih8Wm_HR@h9qDx zOUy`+Bel3==kAitK;)JIxIiL9v`oSM_(mVW?HnfH=nMm3$$1ZCiOzf|T^`sZo80hbvvB29m?P)MAS@ES1Xw&=SYO*BC+SG86*; zXmwD+@t_qo!6%V@Fs5BhOoh{W;SGD6unCB7(LLiNvF)D>bF&%LLvG}=W9!%MrVdh- zS^WQk=%VxKOcub;Q+d(!>o{v*1=7Ha=2oFj?l8~{83G3$l+}$HgAqIIPJmGymH+FU8yl{!>8*a@z*`yh1_*N z@4wlHx-y0$uBuSts72)4Y#e0qfC+_?PdWl_ zP#UP@#gNO9TvW5cv$>5UGik0`t2g5CSCp4*lTKQS_I!;$tm)qsNOvmQ@uMFx1T+Tu zGw}WG5nydoml$`VNK4=;XzFD$8?k(Qdb9ODXUiO6&V%FT>Yca+9%HZLUY(zdJx~2G z_+=M;@^w-Ozx3=$@Dsqo<%YV#+HCy}_7m`w13=~UN8kj45j?2X(zk%6q}Ph94ERsr zKZQvVQKT&L$q&@q_cfONObt)w{Sy4j_WID~h3tCHX}thZ&DG@$Dli~nSHbB-TcXD8 z!L_=I$glj{%$Zt-$=G~nA1=Iv9q9qX^>-MkKdB&73;RZOLWnvOgB1v*B&V5A4vuTX zCSjJPG19$tdWK1!?G6x+OxxXJ`J>=gIA9%BgRkZr0TT~hvIso$4eb&$dL%b%X5gEo z@0-?YHSUjCaUawk+XFD)901>uyu-7J8M(#!r)I|Z*o1$5>pnbYXUBitr${|$JncH` z-3=SdI7%Vh}(+W6}I}EfkP}gEeEnOkeVc&N}1J^C5hg}zH zlPormN3eYs+zjnNDL(*SFRVW}5XI*l)!YOdlvCtVFUj=#Y^2m2eUtU|s)CHoSj21| z>MGdzxwn9Fss;SO{>@#g!~;~WY8&?!nY>~>GRJnZ@>aN=6RH5<-AG$h>3>QAAXSk#U^;KZgz0@K?z2tDsd9r)Hk4Fdhqm@t zZ|kK=icCIt;?`U8N|h?p8sC81tnR_VTY}J|X9j^9hZ)m7zq2}lqw4;3%MFj}ECpH+QxLz33l0Q(jRK zQ1~e)wC6GM9;_Qj4jxzs1sm-I4iH6%0IQjV&_T6$0wZvO;6Sf+0gKHWfn@p4x*Gwk zI)PTNag}1(0)}G!w++JD+5?$fyzR?xr-4>D6QfOq!WZe0FyQ5kCs+?S&Vkl5jITj= z1`(mglFky5J7x5^q@WEL!rmtfmqcFAUo|_+IT+rB^zQ-7BZca@PJRjaZ~&KhF6c4* z`@r_jL0LVlpFZT_oR+*A$RD+#xSM*N*ygI}sS&UjR+|-;ti}x;!oJ^($cBF=7Z4WP z&|EuT#72kPeb4{yI{xMNONGdZ@mUG%b0PXq(Bj=wLPelSkaDoYk3+Q5fV=)jsQr&m z#{VP~*+W;RN)Y6`V3GSZZ38b7k9Y^oof~>O{@oxX_03(vQBP0*PA^29JXkI?Ev2T0 zir{--409SLlPJ5SE-J5lr`Sn?!&*Y|Z!+Rm`i(D**vg6wgS$nFJZ`_=h|E;Sj&13= zVGN~y8323g2o^qo0z)>#EApG&#O?u{Fuw?+qQML;^w9MqCZ^66ME|KQA)S82 zZZ?6>5nYW4*U8Y(Dei_#3&7dJOyew$p?YJ z;N?+p1;l=1uQwg1_rch-xTr!f#!3z_?zKbEuy|*a-Vl(^-6I2Qr~l%FEF-i5=p@!^ zk;-K~ot9txz*)#I&L>WJ6mOoaZX3gT*DU@r%Toi0i_;?<*V>Z4QwtTq~)$FmBr*oLh4(Hx^$Pgmq2=LYON^WBQFzp64-+DZl zN34Tfh+NnZu!ZcX-w$mmO`D0a{<`9Bb~mBff-puL>!iyO(H(%(+oehR$5SP?#gUC! zh3>hmq-)(Vnvh$7T9;P-lL~C-r~6m!9^p&QEZ}|FL`)Fc8*72gW}b#5-ia}S(npv5 z-*KNNohR<^jEsoKw8c@ zcHX6AKuBsJ#DS}#fFU5CifS2{u;~iNYi<+-%{;UBCp~D4(U+JipO&oa8GOZV>m#s( zc?)K)rKic_=oeN$#n28lm`S12jNi04!D&P^4@6BM+7OV5XDNn5!)z(($$FHnOB?+G zO3OPY+RSz?LL1RDtHw2}`w>lVT)#-a^-<6joBjUOlf^jCd2Ab8JLY^MCgvSEYZ}LN zwV+Qdik2}J`QzS;zLvy~Tdby`U_gZmQrr?kJw1v8#HK8Kz*gM%RrAfucj5DJR=Y7` zQJuoxrN~*XH~YiVkd>fBWv5kd(}Td(ekMc*XLdSHOqKWmL#V*(g%&z{-M{O|V_g+{ z`+{A~#jBE9-*%WjsRB!$Wr~M}R2nTS_PMlY*hS2#Zi|0uh?FsPXIGK@EGZtQpe8a5 z4B`tcw92Ksa$UB4|Ni{Q;uH6_Ag1I?J7yMA=p4*UO6LP*A|kHAtkA!rLoKiKeUWoI zRI{(WoG(B$K??nyvn{4*27TN=sx6R?E?o+YC0US6r9StG#FobAi-!ZiHRw+|Ljg)N zVO^Bay4iv~F2$$p+qJH||H3D3&Hk2tX7QXnBvIF02N0rT$=)D=1}Xj3J}f~Jgbw&s zU{k{Kg7t}2>1#fOvf`?MX*Yh&u$4&VGfz{C+1EtkbGlWy5d9XDZt%qh^q)b%Ts};? zNQ*%-A^ZLa<;OIM0>evq<2)9=ws_m=QDO_%T>HC2cN_`^lsb@u;Gc{zVW0@E((ZzZ zPAJ0pTbqtVuFjVk%*8Jtx4ERJ9;?k3EMPCdr{l7fiFXi{oF&s$Ba3P$H&Q%2v@2|8 zEVMWhox9}z!ZnvEnZ@Yh1x?HGG@D<^E?@p@xIv47RsnyE358ca-$%qWNgljGflaa zMvRIRo?T=Q_||=G2Lfq;$S!^Td#LfE|8NH&wc^0XNwy2U8Y9)Ql*<+0HkX^bOpuD; z*JN3c=B03GGY9ukOh65c6XlF!?3f1Vti9@#@oxJvY)u#1Me^aLTR0hZ2oubCAEsVKhGj$9`YRcskKX&`V)eV&_r|B+%$8RenJyQiPv48p zo*SFE^EZ(kYkII9*?1ZihvwXMi$Wb+@92#C)M=D8X~nO7?Q6-;#H}NkP7t7n86$fp zC+YGpyU_^$Yl5 z=5FC0BpZH7OreA0wK6~gAz&C1*^gihM#0KJ$ue88H^| zPZWrQb6rzPuBBF9$?ul@pIsr__YBJP^5R+UcQZu-@bJmFEly}6^P5^tk)H>0NFcfa$s*$nzjRoo~MU) zp9#0~Nr3Ct7=F7V<;=;NRQtHH7KX$`4_pQ{f(%;QOdYgTsuNMgjOe=A&NFRPa=&R< zE2CoK%n@6uhQf-^?jqaqZ~A4M0icSmOf*|xY)7#EcJ{jQe%w;mkGZ1OaW-piqCaOx z$_LZ6IU(IiKTAySf(ox{o%$h-Z4hc)J7g%5ED`1xuP7FJ2f_?NPLdtyM|3Ht^zj^8 z`sC*Qq2lfviM3@cv#c~kH>K%mrWc|R%?r0jN1*wdIAEa@q^vprz{A|KCyuoJY%qH9 zAr_5CARA)nr@YtwEQj3IcQutsE`0R;LAI&VTT1DAW2F0+&b4^uSp`?49d^B17E}=E$#T!cFvZcscgvxdxy2D=J8- zu@A9ru3o{PB1csO67|Z6=_1@g9*7)}j4bM}8-cYOBdY^(-7WcOwa9$ni+t}sw-_2P zG^nXRRBSBK)9h_hBUv~NtCL*-Re&%lsu(+4@a55N)+AC8(uLF+1KGla;aI3V1mT(A zZwO<}${#07D^$)NcRp%WF|gvs*l7J9vH`*d`{uQO>EtfsDBj1av!^4Me3Dx<099T_=5(S3le z8FtlW-hOIlVDl@GqhGrRNM{mFDboIn9ZgVLE|nEE(`X(fSn3m`?qsDR8GP~Dr=_+p z58baK-=SKbXt>~u5MpF#GayDBbo5*{4kmq?w{byN8p2*{ulRmq1ahjtQnOjl_|Z6p zROsw-z|YsM?yMVMA1$^S@qYQmZEca&_ParO`!qM_*lnFTt`^L++dqul*bZ1;rfbCf z7^MN0;2VUGn1UOAd5$V-chb%qbfis{j;{9q%nqe~kP3`}>_S1uNZ&YA>=LoG2oHqg z1JM!dK9{by8CS;3h)29l<9eg@Ft1#DeW)xL{2ELT$ilh)FO5f)Q2ZfN0_^NBI#9+oQS z7J=JQb;Oa+*Bm&#?Td6a{#kh*vNb92`ssPc}qyN2*m#s>_Ew5 zT^j(0+ZGC^7XoiA;crKZ5v8C$GgG(6%py;XZ@Q@6EFAAY5}U}WZszLNDaK70NovCb zmY8eFk81fg7EZGBGTu|>;Z@oSzAr08C#p5Fkm|!M|R@Q&`aLk%I z{Yc|1jK_bK1hj5mXjp$TDs(>SRua2iy(c7V-IMczPa~`BU8!*%B-q0XY{PZ3l3aUv z%j~+dz|`x)!*Y|4Q(EV?+*SL6P;0=_1JV;&0u-;5-<~$=Mm0lyliI#T= z-q7qlz*vIJ9@G{T8hD`y&hj>LRZxFbWg&6lVzMAXJ%j2@ab2YTNulp6GSD`Qmgpx3C%-0(8eJcG zY$qoiEs-I^!YOFTd{?X!D-jIbJd-_H5RU@na^iyx7DbMHe%p#YHcak4$AxRp#Qp`j zaBpYeW~veWaN8{WxPQWQ%}d1_ez!A7y_bL7W;;Fqxb<*0ujk9`a1Y>x<+Wi6NKgX| zQ=+mF(qHaixm_Nd{tW#zO8=99%kgFnSzkf*5^zod$X zchp@;?rt$Nr~j(BpbCNPNo9v&<2NTQy2Rv&h;^mepTRnX1A(JLnWWEdo>$zjj9)PU zqq}l#1uM$iC)@dNcb&a1Xn8NJ7{rY$09NoUZ}3+4w?m=HhO=U|rBFIwP3z{qh@u-+ z08}E0K6|o22^!aa2fU%dvX)lD{aWK=E6QrmD*xnmzrknE>58AdwD*3`a23&)|Br)} z1Kl*bLiCH!xW3gj)92i4=BTZ}X7qaTH1u+-vg$x%urS4r-iCsp9J3sZh&Am{Zd5B* zajRDUSkKuDv{EIe;_K2U3?CRsX4+$!fKz`frb2Xx0NK~H-J+fBPodX?P#YMw8 zcP49}D8Y^|o7bGbU?`Ec&y*zK!(Kccrpa-4C^%@^HE`E^9ola7^u6zNYUIS0;D-|d zQfDq`_~Eh7<1E_MHfjr|T!gBqV-_{#iWNpuvHe?@dM`+A8J14Yz~VKmr_s?!VWM=TrN*v;vOWPg9s$6=k1fBt z+ZC~U#QUd@rd5CE%*^AGla&Rs8n*H79W2OK41b)+C4?{T!H@nC&XtDi0;r>(}TTdF@`$<+ADRvAPA;4W z!eO##7;h857;Ef5FB!EC@UaEE;Tx?<%|z))w_U^ep&hoM!)va+Ng`}YA50Ca^aUL} z4KaNtLH?I`{?1S#bjnPI@ax<7snNT6x4Kt!Wo6mJ4o`=v2_<8du+y)!6o~LRxUH+& zYKK~E-K&YGML{-Cw=dWmIbN|>ZPA$V6R}vn@y|dQ^&g~g8Mg=MN5iM#{J}c3T2&yg$uwaw;%*_EKsj4^$vtcva)j7aKAHcHj zBBGnLlG1N{zV(v(+~SvP?cgsKpU>%=HVbO~Ag=(sZj}((5|0bN_<4YpqQ`)yrU6M2 z>~yLYgqRQmezy9*j$NIqriJBUJ?N(&x}(8S1Im_?QpVT@`5@k;(?(JPQ+u)JI?6SL*3I)bs#Fs zw12+-0U})2y_jI|vd2#RnE_@7OA05zUeZOV_C&wP2G_j44=b{trfy2S@u-u@bBMnx zc_Q`I+<7Ua8Lih$aHmgg#aMY^ROTMBcJMCU_7*GQM(&bTS2P$#hA#1W;#RDl7cnlI;U(jztYhljw}R@e2s=?Gc6P3uIpa$wrqJgXKDwqw^lB_Lm~B`avg1wIMX zOW}!@CEL3;0gFB z8U_*1u>`8|VbtI$FxA~siJ&GR5cF=q5)F&QRXMyoM`g<3?RwszD`M|r9k9r6#LJxErnBLUF`Fwzqi03*e4eQP-* zBk}fCS*eTC+*f8P-TqSUE~B3y2f%tZ(`lFhAeUgJ8r(SNKp0wHXxY5;H2Pd{D_%u% zBe|i}9jXfG60(9%Q0$Q)sbmK=|K4Y^hD6Rd>6j`S;!l}Vl3FX@lqdUu?E6oPA%~I! zmbGDB*&HZ+G(is=m3{F$otvsdyot%X;qcM_-CdS9itiuR9qW>)7uQH-Z)WL)+O(8{ zhOh}?mi__+edG(_fSI6ZXPcx)D@KYTf6x!1+nd-bQuG^#J{-d>CnxqfZzjL?F|#m- zBx;Lp0jcf??^u4SMd+ZVO+h8DED1UmB zjU3gPeR^0!Zsxw0tEu@&e!Osym^_XMMc1mDans7&g2YNI+YHD#=Xkuj^Y+JnEiZS{qt?l zq7!Wja|}JI3)r_$gy?js_)AIeQgz?6^FB({|DuGZMZZT4Jcs>RMzw~(GcaUH{gB{C zKEyE#ax`c91;Tvf8_mp`cGu_kuHE_Y5Zy4&lz0)0$1J}qnw+qjkTJS@n^#&&B0`WV zyEQ-p@mp9C^#b7JK7|9w{|0%VSz#LNkJaY2|n9RTsaETIUGdaiXbSZh%06q$SJw`1UrmQQ{8 zE03xeHMQ*6_~O`0f~-tHQun*#yBG-F9y?v3#XyX}bZH9X&raNHYxA49$7h0IsN?Zq zyX4pd^ZBd;nFSccI8`NDAo3@wW)ZZ1ej42#){rhV%K;UL~|E7$PY7fI}>BRaMBB6kI;y42-oqBwr z8F`KzMLFr8phqx&a}I-Y@o)(wXsZ~`S(iBpS`@j8Oxsc{wphM??YMhPpGoWo?F(Ri z%q1JmKtsYwF^wZai>(&QWxuQy9fNx#Un4h8-d45O@M^~NfI@rNNU-uRU#dW6ECE&d za1nHhKQT^2$tM@V$--kN7F!=k66onl3+XcsX{)BSCNE0fB@0SkUUOGib1(W6e}oY- zyT6L*Mg0WhHV%Zhq?hD4z=qXMzUju~q88?0j8nMR<-a7DEjQR9)@df34yIF+;sbFL z+w`M4K+*U%(GDGgzWfD9W!l9W`?xaUf4DyO*y2l?b^kW?iZgSu3WALLFDnWE7c2P* z&5U)%MBs$zY(_+^UTqMESgQ=oB>v&`G`FK0NdlqUHf4-xXUM))3{{iJO69}N{LU)* zJ?@C&aND(J3$PTgQ;T&M9K6Z6XU`&={pFWS#Q}v3b3ECa$d6}9nZ_LVKeyfLo6+!Y zN{O}6=*#Sz?z=x`4NR)bRDVImUNOv}2-flta+_H>5UpmtF|<%iAiYTUt*P;d>v5Co z?R?B_lM1a2X}3`o>;Vl{O|lYg-;lRzP59K+3~9(rh@EB^O92=-cEoMZu+sJsgdAuK zlq}KJwkc?dYHcRc7E%?(U_V?X$}8&=UE>30Q@n};=BwjBurq=tPy(V78$v}8HfJ$$ z-cTVYFDHv3=k#<#k)k-ly>DArCAbp1zxs`hXd! zN_`5pzK$wF_9IGL5N<|H%TOKo;!aejoA6(llr$EUm5?xGE4w2p94&ZhwiZHn-f;!0 zkDNtLxl6vu2xtDGv*&fV(~}KFX3Xw*0!lrkQrRTJ`K z6pe-b-EI)wA~%?Srx$6bD-VU}k>>&LvCYHmh$Msxc^&&l=gj66=g~BOV;C# zy5x@zse>aNZO(BYQnIs};qjS5^mtHK|II**ilQl99SsqSje+XKz&NL+&SUDF|6sjseR9-`8x?V={ zhW?e*M}j@5yPL^8P_f$ZZC8o>ZzcNPXr!z}zK&TynbF0Zcu zsO}lBr!R1QX?bcRv%o8o%Cx1ey5f(SuVBGqqb1|-T=<$h7Cc#Q0pw6=yhCiFX0I&FW@~kDW)b-njX~%sWRsyGQMd+XnX%&)-zI zxa~(h9^R~Vp5V6bFdJvwUUzR)87a{Oo?`r_Yh%N8PDA5~0yI~!TjLl9>R~l0tvcrR z(D4Yvp2N91@CXHbYbP=M{$$sM2MpdE3Ex2UC&r+`fEWixo2Ljo7Eln0`}4GBs|_s- zR=pS{Ef`scRy)qt*Jt?GVD8um7n~WllV)dNviJ%AAFm;M^KTab&qyGj#et=Pc51TX zC6~QWt(Uy=_3hJhp1xc^Y4<5Ws0{5JoL#A-2AvvdjBmwzSELR)lp1K_Idx`%prsmVDU#YovW$PIP|rq*UE2_N0Yl zUt``Ux5EIw_ufiR9=S})|P?jbdVzN z;FxdB2E~cIe!4M=R|i#h<38@_6N%No7emqg4O#$VY)oj`bRF89-tDO5kcd8ML>7I2 zJK!PK;eI=(cK5)i9OzAQ7C{|fi6a=&Z`%a-rRHPq?gl-Akg;73*GD$?hLtt(+*7{d_h{}iV|>2p zF?<`xU(0lJ=7zxIASi~{N;Fwii)Is7uwFSW94YRYJ^_Z9eqV^X_3Vsbb>|-$rLuTs zh8Gipb$p!w3I9`m?S?Qt7@&NxMs(hHFOtOLm5vskhX_EPfoNKEY=^_Gbz%ze&FkBp z%PMrL&}{6hT)KTXFLvfYMU}%3#jL@M2a{ij<5Z;?7~`^+^M2KjHTJ~I3ch+XS>u_^ zW{hXQX)_jJHtcUmUVAfP`DDh=Cb+mbM2!<*94&(a+RcNgElmh=-2`!*-i59H(}tU%82x~MR@`fVV;skWvXt>U>W2j) zEN`2cnKNZ_h3IryQ9#s31^CafLNZ$i9S)LiVPh8XMq@%Z^PLLrbwH*htgJu0vplr> z@NMV`9dX-PNCr*fV|h`5K0|6G&^T9Qpfd74bk{qKIgsPc57Dr}!zMPhiPZ^teIB{~ zw{f?g-6XKF%&Kjgj!Xub`JIeRyrcW z#H<*8)#Xe;i1ZQ!GIl^IRzs6w?ehELsA6r&4*a-|?Y_^9VC1y5)m8SwVg*LY0_K|n z>>>}tP#0RuRDl}ppLs7khk(laEh3aaw_D=_ADuD(@>LKjh^oWP$gG_(DAqPhp{q0S z-o%amqJjs`%EX(>-J>;!;Abv3-q9M;e#m*=BTRM&nPg^iS)2hNDZVop{S(^=`|Agd z`fs2Z#%&(@(RqL+3qk=9?MvwVNtE;tS`G3Cx?N14?@@}D?a3f1#*15i{6aAtNufI80hr-1`_M+%Vk^pqDhtNi^TS4!; z)MM7pVEIswL4Z3JgLN2)9mNXJW&G3n>8owTURtV4-kYO}e=Zm@Vcdt_Wfci07QRn= zk|ykqtNa(_^55`2i#Y_9&w_pfeGLFXM_~Iv59r#SE~$(5dJVMrvEhH!IJc|_$uXuHJO9G)S$`#wEU>Psq{-h(Qk3-e#Av|7L!9wjEt*5-D$M8NADx~qQ-tm%R4Pm?nr4u3(m2=!e0%kQnQb z-=_>?ckWef=Tk3PkU%9Vx26sCXKVE@NUX&w4p8g~Vb>z2MNMyv`uL1$=;JTF&!A0r zS0?nZmwixwb*b4V?TN#8n?z{CCy<8zEm%yhpw*$~Hk;0Z-~KUSDTpl($&!ud_dRMc-7i2N7+Wcm%Jf^Fu+nMp%WNZ>4F_peaM@>}p^+SpxQfjd96MF~yW2@@ zC1D2&n~-h}u*=ZTuxOsqNg6NQ4h>C-O@!JW0KWHtLk{acK%U5wo3FtR6Rod^7^ zTO@!u&Vy(|AP0&88ypSW($f-0jU(YecN6PUgx?(ZA{j-I^vEVE&!6s^7OiId7?`Y* zF@5QSei$nS37O=*!(Jn`9XixB_a4Qf6s#U97v*7;NVT{0ktN=?s=Yk?}3QqN zrS4?IZtuHRzp_2Cm}I5wG;w$AXraHEpwzCwVkw}poz6f?&^~HOO;XLtu6Wt|D(1DJ za+vj93H+hNFiC$aDSOs3rXY~(qRv;*Sm`aWt$6vDs6X5Q45tK6 zGu*yUe_FYy=*FiWyunBMNbSp`Of^TUs3H1C8*6OQPhT-m-7P!_z4U9w&w+=Od-NA1 z?+Bs;|@(!2b?X~^5dz9l6yUYWzKPDesw6drKcW=Ic0vU>x{puswB7=E!XH%C|m5F zG8&v_5_1(`#&jXnTmes!p}IeN&=;&bD|%G!{8y}#i~W~?=azfbvR4YNMHRF$OK)e! z!W0K0o0z{hFupgG8nxp1V4kG$K~T^}p!Xp|%1#bvKS+2E{o@bzEsQLOrKTlBfiIHB z(o=g8Lq145P_)%SJ&e;Q)uNzeOiRX`m45Wj>A1AsDV$B(VAh9Kp^D;|Z$Za&*5kF| zDS`AbaML2OTb$$`AdTn^qp|EaK zu8K($?|nD?q||gZ)6i+*>=Dj+&YLG6uZ{PJLzL%3v?%}POb<||jC=lI8U9V)3-LpK z9mG6Lgi(|;mTMV)OoJKIlII`R&*h|H73x;r!1lHL_26q&P0zzxKlZ?Z=QN|eLoK-y za5QQi;KMr3up33?g3%2T?QjamRWP*BgQ%$@!q(&{5}37@gr>zdwfGVm2IG=`Xxk+D zoLt(i+(VZSb5z}7NSn)cSF@OW1+kd%qw;OjuOK3EByRA~K_$w21REWMQ)M%>Qo6|a zQige{V#2W{o~nMd)KBHojr#kijJMK$ZAD5|pP~_(2jo6Kn`Tz2@K%VIM(; z3vM)gN15zKr{6~rV`vgIKr@Y2t69q}TGdh|jyAFs;WhQ-%dhfAZkBhsWhP&LQQB|( znejK^xG8`B~;z$I7PTfpWTPlVHt2+yLUQ36Vs7l@+`rumc0zr|Ba7sJh* z%aR`U8v|t{x*?TG%*>YweB9NoK#`l3}m9=fgWA zk7TQ1tL zGQcCdIf0w4E~1z?!q|f?@j+NF5OWxPdMY_`(rJRPvNC(&(uuQ%=HG&hA44^ny>VcW zcLF;b6^V81MFT|-;>ocnMFgkSM6bZ-)ZApJb2FCr^Xx9E_CuCq_Ab(oggf~8P~531 zX%nn(u9|7n`!@<+OlCGX}c4) zY|b&)QraLotfIgJrJ-huP)_iD8LLe?s}Ws^rUs%vq^kewY|YxFD~5WxmVe@7QjqfN zbH@8U??Z1Dbq6&GGyUmw**l6^@uMGJcJOndoVnNI#n@USG(VTbe>->B*2Xhs#Fi_m z>o~(c_P<5Fm`pFl3rdNa8B!xqq9_>F)p$a`1I)CTa1taFS zUYxd>rn`c%DPlbJ`>Barmre@rSrAf*4~90{@KG;IQBo7(Hi3k-Y;voQHtfS?3ECbER~0o;l_5XOnhlgF03sNB6kSYir~PQVe0 zf}QZ{XfDV7sSkfRNP9v~Cz7XhSd^b?Uz)SPDl@QZ2NodGK#kA4t2667aR@Ot%xmn0-{pdH0ts9cb4>82`x^W~>meW>MMwdRqOHjZJW?++z6B&TD?#avWm- z?^-X~_{uhee$J6`$Bm?OuuzV1Fc6YFFIIvJAXX=kRY4qaebu?@16=X;kVFAOTNy9S zeT>LVk^MP^Lk=RKkIF+gq=Y((c;k$+3a3*-vmq-klxP3fpB>ysY$|MWmefk71HdmX zw&7%sfBB!b3H=CpyJ1(?oxKcZ#~HUKiovh70I9Lv`-qOk^?3(B2MU5}#_z7da^G|1 z%I`cs$!fDm?XQ6IHC$Wd4x%byU535j4ApS#$YlY0(q#qC071;EG3gAs437d?YXyI3 z(<$<|_p4S_4Xd8SxWY{rFS#$lzGo%bpY>qy@33Vs@~Nz>sf0Bn!VufI*l$y2%39Jj z<)88!qQb1K>>rK=g&oF+Xs!MSkN1z+ivQ1_9}PMr?L|Ws_v4>Fc8AxYQXwco*zvz0 zuGk6dt_SeZhMRQNk;+g%cZwXi48o2koIkEy)r2r+=NFWsTG7=G>lbI-xR!sPs3C_J z-S2s%aP35GUBIIhr~WZLRXfd&;7z=&Q9TFhb~!e5y;Qt5RVwD{>7|zLGhfHWM;RHa-21L|@6ZK%cWs}{%l*Xr?xXIPANz3&F2BZR|qjMctfb$EE2aS-IkeMU36z1Radg!Om`yPs4x!&o0Ud&F8Pu z)+E~ihRtTI3lu4L756eAJ%W@iS4l6PUt_zvh)x9cI7|P=FsX%{MfxHJQ#a4}duK(8 z&IN{#$8$genrXl;okz|6<2voWq_9&T5*@nSexh2?+*J3$o|2U#KFr^eN(W^vfAu_- zlFV`7ihSac?1AX$Lm?0Zqk8pv*m%MW)#9^eeZBMT!tT5y@kV=70*tXmGVJ-eOk5oh zWa$5ct%!lxwZ2YF=m4|rD0|p(>Se;&XwE7&YpWL7xZf5N^LMYuz#DSQFaE~9!jheF z6UOuy^LoJLJoFbN4s{(%Ff&rG$BkEXEITmv5B^#n`W$D(8+R`0O*}*ECqd~PQI|bI zz$h|6mUdeYAg(L|!!;HfY=kcw;Bus&d2RWt?bG$)HG#8Y3OJuoSX|&DmDie7NFD>= zo@(6D1|GaDnsaIYMlAoEvZUNJr>8363kqA8Bc{C8 zm>50L&ObZ8#9DxF%%>kEI`~1?eZ2e>p(6Z3nhEKWGKVSbZ>v*UI`uq;LbTNXmo3}5 zNZ~*Z<9Iau0Ihx-9`!0yg~=8Yc=JGP7q0<#uwnak&*+m?p}tVMua-06xGjjXp-YSOqni}{ z;M-*N8Dj>2`I*kbeIarOCcm-1=5hK7@9ihIReyOF_9$`+x{PSG-3jAt zl5pW(9j((WM@-(Ex{y3$Wyq&|c`^CRB|!L(8`}nR7fgB;;2cFn6G1B0jjBM|>B8Pt z?gdeI)cw5sSv&y2h0xzcgada#cfd~PW2?|znyjSsA6oqWy6s~RLr?^&_F z*;s#{_1oMuO}q)R1lb>3JpK2j(gDv;EhT~$#=&WQCJA1~q@uo>Rz-EyY=<7VxV4#wba+MDR;wN;Tk#g9LxkNq=|9R=nSn5JFH+~7A!iWns{#u7T zJ@qoFAYb^gn?U7lnS$F)>Duu2V;*vHDqN7}rDg+x(KY~7)1`&)ZXS2Z&|hoJ|G890 zttKjcv&XHC@gFZFP@JJnjPXS8j$2Ijy_Xk_3S5c3SGZ1U2>Z>F*(ENIohr(6Rm3AE> zgD>Wg)pg1UT@h=KhrLUbPe%U!&3i<|Bc~a1bn1U7YU~vqR24SYeh~HB$HXoWaUtGQ z)_3cVo~%ui&m!$i#oAKFhAMBd_E^EzWGScoy(}umD%~O{%o=x}7bz+nE;so;C&I1I z(&#d4Ur%`73ZO7PZ*j5qKQyEg74GYM<|be1R6YZ1Fn%aIy1J!8XFI)tu24?neZf)O z%n3EA+|7Y9f%8!TPNEkmb!kDVdHLYM!D%T9Qr}G`A-ER-O21rOJi2;dZI`0%A9hd>^dUu= z)y4Lbg6_t(b%sm}9!je5dl-msPz7K&xJ{Tgh&#e4=zR}2`WY-EeELKDCdDz>fU_fP zN}J`TyVd~gP!q79n~a9!&}kUI{}GL6`76~m+58PvDlAKNuQifuUFQhr)xr^AOs@k= zmfT*o3dfPnNAdHeClz|dGUufdYkz&!h1|*3W4)G3P<8@2=4|JNlxweBafqiU&j%N*5oj41?^vmE-A1=Tc~qs*aq>^fQ?15l+Ziz?!>|gJ|hlv$R~g zn8F29T9u;$Cwx8!v%&p;p&DR5?kKg5hG_z+QH!Qx!i(yC#QKT6pDxHVHPyGSS<&9z zwUJ6Sv^?DA2iamqW?K+lC_eSr^=CwzAimBQsFu z`tr3H2AHT*%*fGk^1uuoP1uKtIPK?UVZ+yp(-zd*eXQ?PUhRIU&!9aGZ4<;}!@ts_ zG?uY5U0a3=pej{FfnX`d&aySN;$^@@SS1e_OUd_hJ`5-+@P+Mv7qF{dWy$}aFK zs2arD3@{rVQ7v$2!{yClfp1A|K3p{ynODlvq`myQ?pY9{5qIgWrOT8DRO#^!FU-&I z@Ypaauv9}!z+TxV>$AHme&beTe)D=7&~m4IKT2lpz!FSRKZRSGB!NtOfqz=SM&(Z{ zL9vOSAD`D{ik2Q`*IZp4c)8X~NbmfX&*Yeq#N@-eHe^9~A87R8<~PslammO^1{%tr zjegXWatc&(km=J|Jnci1D?$xTS2zNmJ`DdRo@$;H&+j3u7nCTwsjVX@5{_uTa+CNq zS+B#=Ks+4KBj{i@i;O^WYnM;+NC0%)#~A`+WV?|X!B&HG)?jHMi#O%^>gxN+i=D+D z3)l4|bvF7!wZ&8@rt}HKQMg?R7p^@WKB0Bu%|(~I=H{=9WnNU-4Htqi*eu=zQWkNy zqYwKWGebaT4zWZ$xpibv-$tfaATlB03XbE4X99kG#kDCo=m^9Z|QrjJ$Iz z5Tc4v$bpt)XQr`065u$^f=-7L-qXd{C?MY$H2#6woCf_E@@Nc%BKz-u3;&lN!o)fL z{|`dxf>Rue91m13a4W#J8?6!qy>tUO%kP(TYsnK4;r$5VJoJX^HXzvusPvUx? z+_&oU)hiARNaBS2;iYba!C#zmMCr2FsUbO^DV7cORkjgsUB&ByqSlEzyd{W%C@Qxs z>GMc@nf%)9tonfR#Ej7Yq3p}Up?v$d$CePXlVvK(PFb=WDj`YQgff-v*~t=fiz0gz ziYygTma&U4_DPX_CkBOVGh*DCrT6mvzQ1SrJL&fLs zme*|%!z~Ub02ELk#Dst9*Bc-c{vagi@*pTE+QV3^5$V#Y^5Oa`{I8VPidVW8f60Xz zCJDlhL%_~Zjlf#A5h0uwUf;^h1Z;oomCQ4>yG1m5 zLEjh1GMd~?pvfc$NzszEH+K;7&5g2{E;K`$d77@|icA24h5^BBz%-b{EqTMIjtV(V>p6tBSetsY>;$za1 zT`>_&-k@dZ>%x_R$R_zad<=H1dZ6mWMCdk_ z3%ccktI|u!!uow(ckt*9eLZ_TPW4Hy%B!Uw=8YF zGzksFLZmC}I0oo0HVj>vPz>dS92<%MnxEfM-cZ$rIgJ(hYNLKT;1ONH?-O?RE$$Q` zuqP~2ykV9rkGZ)@g@HJj!;}QXV}Kk)wnJkBGx>P76^}-_z_VZ4F1fr){bu%jV-Y*J zM_6+%FK92gDWP=y&H0dH{U3mCj1$#u1-yF5)}1}Egd2iiS{ubHVl4*z7J)Bd;AJWA zjtGX!?4$p8>bTo5{1=-xrn&5ini(V*o;d@y>%=uUXlCMZ&hW)R&(;208(+!IINy(w zE}@ghKlRwvBD(>9Llfuje;Y?E^i1GVQMy|SxD3#FApPaE$`(XXp|TFqrCovp2dns# z<#kL(XVtQ1PK+UktUSD@W9WesVB$`3NIl{oFU1&$982=v>1FMo25X(8tmJ4Iq8Nh@ z0jxxwvx!kl`rKyG7vMc8QDU(lI`-H^!&<$$;R0Bf;OQDOI1O*+!X1Dh*sP%5VD9j z!dwS0l{(}OiD8CdavG?=v@qn`!-x23Pf>=az;WNkC5_ejN@#u7W=K zbU7HIFy6(%G)yAEXK}ZXi8yx52~>MethO=raB8qo(QxnhS5mj$z$Ai0IeF!MVM6YF z*70w+9BnX`0Z}_V0(@8$D}pRM?OmDAz_}*c2|^7nDVQPb@D1WYBBd8yy>0d zpu4eGSOj+d>p}Z~O8k*+i0b6z7)08ke*%2GZa^q6tBKdupfI^+S18pK+8WO4VZM^G z9L@x~zpZcGo7ly%qAMuelZV-hhMG^{+->D2V%1<5f4@=_QuM33%HyB-lNvbA6<5{8 zg?SIM)7uw;E#XJ91^ASn^g*u>Un2f-2t-IFVq$Zq+C$ZcCQHq6o$f7aCJwi)8;C5> zMK!B=3o3s$nFz;IjxS3f;ZWlH;l1jaSD8Z9X@hRMZj5Dy2ihh*q?0WSfdJQy0_;3+ z`k13QLcLC4fYW>(HHWSQ-R$~=bURc97NPb}Q4PxCbqxt@JW3w!gT|cwT}6vugeh^1 zPmIq$W7sh@f)um&15Be7Rr&4R+zq>J!ta4fBv<|XwJ{4P@vgp;IWoVFcvw$}W|T@j zXc91M#u2T0#!K++2OLIXj}EBEi%VNn*&K=U(k*lPaV06}QbJ@H>OH&suR`)ST7^G$ zY@K|MINgS2T5>yDGxy3XDLCF zfY!nR+zZ@9BAsoTVg|>OV@OtQ+>u!lp2CZbN_9^!nkwFj6s&eh?A}+X8~aOk@w16! zmNsA$63-(6T-S~qN8#)8Tc%^L4v(aVk2h=;Z{?bKyidBR=6QhV`!XDLfT%p7LuZdB z4G?Hs{FwOFqHcJONh!BK^{rH97k1d zh|^;7y*{>jeOvS8OYS_#fQhU|0)Zynzh))QztD2laUg2vY6nGmJTgaJSsKVtMm_yu zPiw%nqGP>*nj?_OdzK<$ZflyvAO3~*V*ezo<&(f}$P`&2)R7H4dp@w^gPX>K`g2Jv z_3?_;tArypFIMNrp*lMiE8Ur0nCbH*4nP(Yc3Kk0iH%z=$r_5?SzJ1CU%5C#eJNbv zA^@n%1>&Oj+3|zErVYnc6H$rYJJtS9x8~w0)$5gtDd9)L&-{MA<=Dg|ofWm?0Gc>? z5-@=P+i)z5@GFW2{Oc@iO-vmhAGmP;G_DT!G1^1m&9m|%7g4X{mB|(abUK>2jhs-W zM`&Bn*$ICT2S8UD;*_HiLq(Rr)<*@qi>}?Ujy}7_lkqrRuiZzr=AL&_whjGky$i^( zU9_@Iq=0Mi`KL3cRTLeUsauVeAF8i;@abx^IT#}n+Pu;A*=4M&nZ=l1Tm?Q_Un+3U z?AjKV@i*xwr)QO9{V`iwuC5!EB`sW=X&{DrkCaUn_(gu-NIIYIOOUPXMj8iAuT&>r z!|Sx~N6A&je-ZOnWB5MJjhlIntlEwZams}Q+Uz)=wxr)!Y4-3p>nxs+?BCC!^PKP^ zbAoAa4riBvLQX1j#3&c#SQR;$`R$^d)7yJ-j<_^sAUb>vHSTFb%6eK5VyJx&NBHy> z=}{j3RmUaoLFDkpcXZuy=9ersgajM*r~ddYUr&LSI5x}c+~%!n4C)vopcF{GRI~_H zU=rWB380sRyv~iu5v&lg1{(r!^{|x*8 z6sKp{v{*@-&2(y>u8eB!b~>5ysg6Ec8F5c_!{T5(UjKcY6?p;OYPGTeHWbzg3$&=p zKfu^Hh4#6Z!QB5_T&4yiO52~GftoL$b9qDjxpm@<;NG2sXISsN1Hw3f|A;N zK0bN#Qtl~wl#`#~b0A-<=gc${e7}YFyi&%gfntSo&G*04K?b z8}Kb+jJzJwf>_z@pqqAY$^S^#BF1IU`iF)vB%pm74*eQgwIW7bg?|y5I#BF>@}E}J zIqwZh@pk3C;XSi_xbS8;lfXpQ*jMhebk8WN0G`~{qur4VtqBRiBbyLKF2omA8Px=F zP;Wgo2dio}2@YAKC$>yi9q$L-llaKdadsgy*9oX4*sSgHX{xIl+DesMMLQqf{VZjc zp_0JR@x5ziW(%-X2dB#*DqlW1qaWq0%mMcRrip0txbmYl`@uU|YbK7W&lC4|JUNT^ zmB=eaEM%q7wEGNL1Yq#mvK#~p2S@4MjmP`-MX1u%HC2Q8HMSG6%O6q+=RCY5O(x=Y zo}ynM|Knu`r~B1n)QsFkVqFy>O11$ppC9SbC4ti22|H$9@5C2UxUyNu`fNy~hdp`JNRDo^s zt5QF%=o*&(_bOibW`bA# z`)K}StV`*LzQ2eY!8Fj8%)ErEShn$4J~*GS5Sh`Tt^Bwo7Z>xR-{jUt9R8>*ugm2% zwB-}y{IkDHdgyGm6xXR6&441duVi)D>9Wcfe@96JylBSVwpH=-44R9akiFUk)(CnR z#I~jUV46`^oQS#WsKMgytI$eCfJ!FJ(JtR1d>qa9kyV>%Z?1D+-!D?inwcf=S_06mX;>EDu^xjHS4(`9E%dr#Xr=xf z*zBlI@1Ih%8^6mdQce8n9j=`)w1gsBTEH@C?TKUCvnkmv77tI5hlNh0mVNv7ZK|c_ z@Re*YlRnW$OfFJepb1LG5!X-?_Vj3nZ94N`Rnz0$qn)ns1j9&2>;rQ`&*O`y(}%0> zd48`-%r0NM@cM+8iKFm*f_{S=&>j6>WlBwUIeInY9o3DNR<#~4ajc)wHH#}|VYSoa zWZuAdn}eb-owLb)*Zs2hz5MTsz_=O&_)6S}=X!{qf1XS5odF$No2rMt!ndWrpOO?S zV|u6OR=&H<%@RP%eFG=HY9&dz>}*GQl<;yC+TPb(b(EK9-j^&(c=j?ZP;ZfG=l<*T z_yz$y2?1&QBls`!JxHg!;G7d-dDJR*9+=1}M>Ps6Mn1}MPJ4RIh;t}6;F1ZsT+LHn zM?ym-88NdjAcuR&wNaLa!#Pb00^fs*w|O(l%ohB?Lz$BYGV3pKr+zO^HMq%{RQ3|} z883N|DQ+IKAMAfyWsh$RT&}Dg@~q5QmdU%C&XA86Nj-+S^DSRKsl)gztp=u094D#j zw0OVlaf{aRqqI})$E@?>E4$cjEkZ@L>$AUIBTKMeN*K%GUho3R9>ARLUM7DPwBBI& zaRN=n;0%GSF;r^2%1Rs{N0q|uBqu;IdT4A;ED|~?e?Kb5Wj(K$1x zK8x{@PBc2j;;%3zHFvEaRLG^*(R1i~;3w!qGr5p(qbAj-8dfJoa@;r1xzaZ;SxlzVWM*_d~}KQ~(-=-+?+eb~!;Mb@}x4 zwPgxBwi`Ve1(H3F6Ai=>|B>HWrY7W-{l%A__X+kMDvN;BQUahz{0Qxr!KVFuEu zyvzTSRT-$uP_qZ1M+L#|fF8AsrHP{-rO>kIqsWSpCS*buJHQqmeGig|;(8%NIZ^l{ zm+#bvU%~-1g~11?eW17c>r7hkr?evDQ6o%&Wc0D3O_>s>nE zcUO8y-R=3x%IdTF^3TmY{Qe3Shzl$~<=Y@ao<0J6Z-YLFsDdJuEVm$e>RCyQTHlH1 zaSp|K?>J;DUpS1KeB!JG9CsHZFU&Fc6>*tB9VXK?Na6|6ildIv9t$QfTIQtoNFH?j zKmZHoj8Y79G*M}Kw&ZTHM;@1}YFN#i$_*e7NLBaeBuQOm5!w6cX0W}$yauWg-4v_y z;_g~~(3^H$uD(z4LBeuBy$lx$4u|Pw;a>E>idNLLL{?~YA0U?ez%F{W;Dq%B0~ai{ zjU%X6^4)~q=XISJVUq*_x7Ro3cMaI_N#AWR6KwXpD4_Zb+7lfZr_L!M(HO1V&Yk?{I`~IHCpjj{F8R^Lb*|GG`D#0#-9t z&C21ZeQ)~oIZOrf^IR3~WLt7omqX)@&im%*$#y8e+rh#*|1B9$=eO8_lRL5wm9BVmo^LUj~I-AFDZvGkuJ^Q0yuv@Ankh-CFymbM&5CC zrH3w4d}*)gtW**BBQbKl86`jnZ*2_@aV1VU+@kj!R~k%~);&5jHy|bNz?Zg0|zO@Z!7v+f~#gWvBg{#JEW)(zlo%M8hr4a?cmuS%hugqlI>2Io1B#6Jx&8fhGR?YbSK zKRoWM;O2Yq4lUjBRSb0wdG61jr4!_EzVVVOvB_T| zg{Vx`8KJX*(!vO1K^3uuNNNnMRNj30xnFZQ$~HK1Hvuqd1rv7s;53k|#jaw>zA%#L zL=b9`N3(=TM{)p&)0L;9+rQRP`@u8!pd;R`Yj%2wxx5hDS@2>@aj*2uX7m2kKUC8& z%Hde7E zj)PU3{crhVMYoNsUJQzdU%4WhV#`_cs)Or{5$3JjdzsV1SA-Gw7{kQT@n8=W`x{7z zgJ8W)?+vDxSXtbkp8AD~})2uStvzrw>-z0=^|9H0c8*qR_JDodcQp+?W+ z#y&5^@$Ae}F4dRpG;J7gE19j}NAGP!vmbv`sqD-9oDw;#>UB0Nr>uh$fkF162Rzci z*Vw@f0?%9u;WX>4MefYmz&POTLufx z7YQ}<>l(W`_y!P{@yDjGuS=L$%^y87YN36^Dme`dWl5^|L z=Jzkw^lhR=T{O~0JR~E9OXi#c^cdqdfQ8>}sM!@a9}$S6w?+YIOC3`6r!~|2ruXXe zhd9Hx3Siqg_IAN2;a`m-k_zt5%l(&=8kdm87?7A-8=#pi{_>_c2sKOK z=GUP$^dPi(N8lH<3czXU2$BW8RRj4Im&-khCtsrhZP?BtAYU4ZMaHVjCm+nP44SJ= z{ie$_|L**LjZ2fe9^BL9Dq0+vIwVHp_78Mq3xu4_VjtPsTXXJEUCijz6Yn2&AGAE$ z5*iknej8(#@pLwO5QYqAkUPtT&{D^2qXd#@frh0cp?Rzcv~~n!!nToBTq}+d)*$4E zS7tMZph{!Sd({dAee)v`=nJK5ve=R|y^lq>Ln5d;Zo6m8Lh9LW^f` zhYKnDcd2-e%47L+{#j|oRIed>V#8EM&;?gB-Fq8#e-J%~ds?~RRdn_=aUJ~hD4M`; z6wzV#hxf8TV9|@3A=CjZM%SRtX>^!IHfbA0S*0#hZqw2+tRaH19x;8Q1-&=E$?VJC>&k#+lJ(F6>tuw!qU?SOyc6}_+d zB}y-jJ-7b$Dc)0Fd5TxAK#D0MZe}h^eskp7FjZ$}if7B*XM*q%N&h=d9 z5sYCP&R8BWQhEk6f!M?Z?nBcjz+G?PYr$v{0}@uymxzuPZpAid+7H-TU%j$Vhd1|^ zf%p}H1$}wAf%vhhF5JcLIO%-m8#`^!YoOlMkh?$ga<+B?8dsgs8zhZS1a2EATR%T6 zQy-V=sEP0$1c^bK&i)ZR<}0&3J5<1y*(}kfo48S$;aK8&bGA@D&$~cAydcldafu2+ zAVO`(n&Pkb!a}a~Nsz$rd(ccAx*~wax;0Iq2>n3-j6VkCSLAP9C=w#`B6paq0HUx9 zbIlX6xE1dFKL{S((o)U~7sugrZk}3n_RifM~4vw!L zM+KJ7>~4y13G@eQ(9h7g>9}Itrt8S2^qeOwjid5?ufI{)u+SEf^L0cetu*n%gNsA4 zytgkjJrT-b9&sb8lG$kym8j@C{VGD@f&92FGa*&mr5d493$bMBLvhXw?)fkM0Pke< z6EujYFVe3Zxf%GhT|$)Tn5fh+TYPrfbin;{)Q8%n+wo>k-gBH_l?s#ZLj8N~mc#At zS%*oX%27e3pWHXMPT>aIcVOGYi!KNjmqR??LU-X)SE`2<%=mv5-?6^r^;4zx2Tre1 z1!`7+oRs72^an8qr}XF#0^ZlW@ZR%sNsRmW_xbV9UR^<&bGpDv^%lCfW)&m~nGD!! zs~6hL3f_(ft7`;`noD}#+gIN2mo@q(&X%k3e$Kl7>ioTGeldxtJ-Ac)2SfJ2_9SV7 zE{=t2^yXxUl6(JN#kmVO$Bi@|T}@D_Ki*z3M?m|kc0@p)C;_WX^DqRKTB;Ih>Qh$B zN#Hgdr+4Q*r8Sf!Qrvd$5!#I21ujz0gY5G47!RsDfw^v|YHW7nX5FC3o%@$>o(>n! zVNqd<)bmd2eHj+o^M5JW|HI~I{cqkozXIs&WwYYGt=Z**SpA4l#fNFZ@tKvy9Q;m^ z7OKI#Iw$tH{XQ!7^l7I$4T74@8btzoW@}aoi=8D{O5M#Y%Rg4*ocB{#IX^(EH|a+i zDiXG+85*tV$DiA6TgD3{Bj^zzkAPRe4Qf`bH!fKO6QleGYMDwqZf=Ust|zuj-|&dH zSuSn!9sbm?*P7>AFb@!8g=BF=v+M`c0?Ifyhyz}t>I68vf(<>D)HyN=?4~Z9&^^qKZvXU(v)n2x68fWsHC|hM3>m5(T~r&Zgc&*>D{8!7II%Ib(DQr znbcuvbniA*(4N5BW+8+N*FPADK9hZ=U+wYHiaNJDE_Y%~?@YchVyRA=48S&f!dJnH z!s68-h`0x$9}Yu-yEgL}b9ltV6G+h9p53ul%aHM-JXU-W9V6=)lxloMkAp=750LK^ z*cLq8+pr;tySds6>dZ4c8J44UnD1nAhMeB*9rM0ZWocsSg}N6?WCG?L;&DZ%aOF%X#In zcy=KI4dx5P;>N>JZ}EHZn}Mc-YJ|yynvY`Gs1_FEM*4@o!I+<|hP^8#w?1V3l#bX= zV`r3OMU>6G^vmJS1_(^!;SvAr2_d{TrZ7}-sQRhGF&iUE-Y2JToso;kVTnH4$hh>d_iczh<%qXQ_CRun%_uw&wwHWLEYd zH-~F2YIE-IJJf5@G>wD@fudafm09m%5JBBsQiF?5jGQ^?5Tp6{@)i3}>|896X7U%Q ze%%4BWK%XrM=b>lspMc_H!#xdIW{+2oKNLrwSx`s=hCv{35||`|!?j~*Qs5a5foF&ktQRFfHDwYEyDY=xR9Z!r4Uk_oqPJ*n?fQoXLyTtS$Na@DE@b}r@F6p{Q!38KI=Vnj z@seeqe}d=>sC2PV)-(8>Lf%6o9Dso)sdSVq*zKF?FaYOG9i8ge<bG8sp#h!Af_oMx6>mR7>^lR_V#=Lg3q_3M4PV zLd#Qdw5}wKeG-*?p*FK*}NZ}SG_MJKl#LsBCEG&EYxWzt6#q0>q6k;B;|AP zSRwW7(58H*hGF@DQ@KmY8)q|%;}_q@%z|s}qGzfE6_lmX%?g!W8F}UA?UZRHNS3*FC7?-{Hi5f-Yh!Nu@apX zRtDrtWzoqX9GIXU(sf}MA`(4V@0r(`i;YpYyzd~^R8;Iynrl0@m&NBZkY2+A3feBg zK%Vr5&T$1eW$`tGrA0vR8RtfqZ@~cLVF3{(nGGOM6mDph707V7{kASa;=t}__M z!;T-~vl{j(Z_RzzU9aoJhn%~+#S}vZ8y!6>8u?UaKxJ%4Js!8oew@B(+tS5!BI7Q# zNJd*BPU}g6@5TZn?#d#Qv{7#*nscdl=>SWdw*NDBfkO`j)h^^Pv^*GPA1?6la4(uk z{<(HJT=;=gz|HqL{!&?pqABS%?LGA+JA(Oc1x3bO?r%-QvqK-whMm|w1i9kX_^dbX zM^axg2b|c5)AcFvyR}yQ#Ff*+s^8D{(*2@u&9^-E?lFrNlym-(QKa_`LFL)hBq|)J;oM;a=7QUWBP_RGmQ<0ls0eJ?Wt}kOCh97 z3*SlN60!JjxT4@+*Ik�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 L{mBgd$It%<>7F}Y literal 234518 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℘tnb_=0$0y5i?4r#yxA_K$w3 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 esdC`h Date: Thu, 2 Nov 2023 20:38:58 +0800 Subject: [PATCH 37/57] feat(model): Support OpenAI-Compatible RESTful APIs --- .../cluster-docker-compose.yml | 10 + pilot/base_modules/agent/db/__init__.py | 0 pilot/component.py | 44 +- pilot/model/base.py | 4 +- pilot/model/cli.py | 23 +- pilot/model/cluster/__init__.py | 2 + pilot/model/cluster/apiserver/__init__.py | 0 pilot/model/cluster/apiserver/api.py | 443 ++++++++++++++++++ .../model/cluster/apiserver/tests/__init__.py | 0 .../model/cluster/apiserver/tests/test_api.py | 248 ++++++++++ pilot/model/cluster/controller/controller.py | 10 +- pilot/model/cluster/registry.py | 42 +- pilot/model/cluster/tests/__init__.py | 0 .../tests/base_tests.py => tests/conftest.py} | 73 ++- pilot/model/cluster/worker/default_worker.py | 9 +- pilot/model/cluster/worker/manager.py | 4 +- .../cluster/worker/tests/test_manager.py | 34 +- pilot/model/model_adapter.py | 9 +- pilot/model/parameter.py | 82 +++- pilot/scene/base_message.py | 49 +- pilot/utils/openai_utils.py | 99 ++++ requirements/dev-requirements.txt | 1 + 22 files changed, 1124 insertions(+), 62 deletions(-) create mode 100644 pilot/base_modules/agent/db/__init__.py create mode 100644 pilot/model/cluster/apiserver/__init__.py create mode 100644 pilot/model/cluster/apiserver/api.py create mode 100644 pilot/model/cluster/apiserver/tests/__init__.py create mode 100644 pilot/model/cluster/apiserver/tests/test_api.py create mode 100644 pilot/model/cluster/tests/__init__.py rename pilot/model/cluster/{worker/tests/base_tests.py => tests/conftest.py} (71%) create mode 100644 pilot/utils/openai_utils.py diff --git a/docker/compose_examples/cluster-docker-compose.yml b/docker/compose_examples/cluster-docker-compose.yml index b41033458..0ad6be9ae 100644 --- a/docker/compose_examples/cluster-docker-compose.yml +++ b/docker/compose_examples/cluster-docker-compose.yml @@ -7,6 +7,16 @@ services: restart: unless-stopped networks: - dbgptnet + api-server: + image: eosphorosai/dbgpt:latest + command: dbgpt start apiserver --controller_addr http://controller:8000 + restart: unless-stopped + depends_on: + - controller + networks: + - dbgptnet + ports: + - 8100:8100/tcp llm-worker: image: eosphorosai/dbgpt:latest command: dbgpt start worker --model_name vicuna-13b-v1.5 --model_path /app/models/vicuna-13b-v1.5 --port 8001 --controller_addr http://controller:8000 diff --git a/pilot/base_modules/agent/db/__init__.py b/pilot/base_modules/agent/db/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pilot/component.py b/pilot/component.py index 8f8c8c5a4..8182f3435 100644 --- a/pilot/component.py +++ b/pilot/component.py @@ -46,6 +46,8 @@ class ComponentType(str, Enum): WORKER_MANAGER = "dbgpt_worker_manager" WORKER_MANAGER_FACTORY = "dbgpt_worker_manager_factory" MODEL_CONTROLLER = "dbgpt_model_controller" + MODEL_REGISTRY = "dbgpt_model_registry" + MODEL_API_SERVER = "dbgpt_model_api_server" AGENT_HUB = "dbgpt_agent_hub" EXECUTOR_DEFAULT = "dbgpt_thread_pool_default" TRACER = "dbgpt_tracer" @@ -68,7 +70,6 @@ class BaseComponent(LifeCycle, ABC): This method needs to be implemented by every component to define how it integrates with the main system app. """ - pass T = TypeVar("T", bound=BaseComponent) @@ -90,13 +91,28 @@ class SystemApp(LifeCycle): """Returns the internal ASGI app.""" return self._asgi_app - def register(self, component: Type[BaseComponent], *args, **kwargs): - """Register a new component by its type.""" + def register(self, component: Type[BaseComponent], *args, **kwargs) -> T: + """Register a new component by its type. + + Args: + component (Type[BaseComponent]): The component class to register + + Returns: + T: The instance of registered component + """ instance = component(self, *args, **kwargs) self.register_instance(instance) + return instance - def register_instance(self, instance: T): - """Register an already initialized component.""" + def register_instance(self, instance: T) -> T: + """Register an already initialized component. + + Args: + instance (T): The component instance to register + + Returns: + T: The instance of registered component + """ name = instance.name if isinstance(name, ComponentType): name = name.value @@ -107,18 +123,34 @@ class SystemApp(LifeCycle): logger.info(f"Register component with name {name} and instance: {instance}") self.components[name] = instance instance.init_app(self) + return instance def get_component( self, name: Union[str, ComponentType], component_type: Type[T], default_component=_EMPTY_DEFAULT_COMPONENT, + or_register_component: Type[BaseComponent] = None, + *args, + **kwargs, ) -> T: - """Retrieve a registered component by its name and type.""" + """Retrieve a registered component by its name and type. + + Args: + name (Union[str, ComponentType]): Component name + component_type (Type[T]): The type of current retrieve component + default_component : The default component instance if not retrieve by name + or_register_component (Type[BaseComponent]): The new component to register if not retrieve by name + + Returns: + T: The instance retrieved by component name + """ if isinstance(name, ComponentType): name = name.value component = self.components.get(name) if not component: + if or_register_component: + return self.register(or_register_component, *args, **kwargs) if default_component != _EMPTY_DEFAULT_COMPONENT: return default_component raise ValueError(f"No component found with name {name}") diff --git a/pilot/model/base.py b/pilot/model/base.py index e89b243c9..48480b94b 100644 --- a/pilot/model/base.py +++ b/pilot/model/base.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- from enum import Enum -from typing import TypedDict, Optional, Dict, List +from typing import TypedDict, Optional, Dict, List, Any from dataclasses import dataclass, asdict from datetime import datetime from pilot.utils.parameter_utils import ParameterDescription @@ -52,6 +52,8 @@ class ModelOutput: text: str error_code: int model_context: Dict = None + finish_reason: str = None + usage: Dict[str, Any] = None def to_dict(self) -> Dict: return asdict(self) diff --git a/pilot/model/cli.py b/pilot/model/cli.py index 1030adfc2..79b47db82 100644 --- a/pilot/model/cli.py +++ b/pilot/model/cli.py @@ -8,6 +8,7 @@ from pilot.configs.model_config import LOGDIR from pilot.model.base import WorkerApplyType from pilot.model.parameter import ( ModelControllerParameters, + ModelAPIServerParameters, ModelWorkerParameters, ModelParameters, BaseParameters, @@ -441,15 +442,27 @@ def stop_model_worker(port: int): @click.command(name="apiserver") +@EnvArgumentParser.create_click_option(ModelAPIServerParameters) def start_apiserver(**kwargs): - """Start apiserver(TODO)""" - raise NotImplementedError + """Start apiserver""" + + if kwargs["daemon"]: + log_file = os.path.join(LOGDIR, "model_apiserver_uvicorn.log") + _run_current_with_daemon("ModelAPIServer", log_file) + else: + from pilot.model.cluster import run_apiserver + + run_apiserver() @click.command(name="apiserver") -def stop_apiserver(**kwargs): - """Start apiserver(TODO)""" - raise NotImplementedError +@add_stop_server_options +def stop_apiserver(port: int): + """Stop apiserver""" + name = "ModelAPIServer" + if port: + name = f"{name}-{port}" + _stop_service("apiserver", name, port=port) def _stop_all_model_server(**kwargs): diff --git a/pilot/model/cluster/__init__.py b/pilot/model/cluster/__init__.py index 9937ffa0b..a777a8d4b 100644 --- a/pilot/model/cluster/__init__.py +++ b/pilot/model/cluster/__init__.py @@ -21,6 +21,7 @@ from pilot.model.cluster.controller.controller import ( run_model_controller, BaseModelController, ) +from pilot.model.cluster.apiserver.api import run_apiserver from pilot.model.cluster.worker.remote_manager import RemoteWorkerManager @@ -40,4 +41,5 @@ __all__ = [ "ModelRegistryClient", "RemoteWorkerManager", "run_model_controller", + "run_apiserver", ] diff --git a/pilot/model/cluster/apiserver/__init__.py b/pilot/model/cluster/apiserver/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pilot/model/cluster/apiserver/api.py b/pilot/model/cluster/apiserver/api.py new file mode 100644 index 000000000..148a51eed --- /dev/null +++ b/pilot/model/cluster/apiserver/api.py @@ -0,0 +1,443 @@ +"""A server that provides OpenAI-compatible RESTful APIs. It supports: +- Chat Completions. (Reference: https://platform.openai.com/docs/api-reference/chat) + +Adapted from https://github.com/lm-sys/FastChat/blob/main/fastchat/serve/openai_api_server.py +""" +from typing import Optional, List, Dict, Any, Generator + +import logging +import asyncio +import shortuuid +import json +from fastapi import APIRouter, FastAPI +from fastapi import Depends, HTTPException +from fastapi.exceptions import RequestValidationError +from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import StreamingResponse +from fastapi.security.http import HTTPAuthorizationCredentials, HTTPBearer + +from pydantic import BaseSettings + +from fastchat.protocol.openai_api_protocol import ( + ChatCompletionResponse, + ChatCompletionResponseStreamChoice, + ChatCompletionStreamResponse, + ChatMessage, + ChatCompletionResponseChoice, + DeltaMessage, + EmbeddingsRequest, + EmbeddingsResponse, + ErrorResponse, + ModelCard, + ModelList, + ModelPermission, + UsageInfo, +) +from fastchat.protocol.api_protocol import ( + APIChatCompletionRequest, + APITokenCheckRequest, + APITokenCheckResponse, + APITokenCheckResponseItem, +) +from fastchat.serve.openai_api_server import create_error_response, check_requests +from fastchat.constants import ErrorCode + +from pilot.component import BaseComponent, ComponentType, SystemApp +from pilot.utils.parameter_utils import EnvArgumentParser +from pilot.scene.base_message import ModelMessage, ModelMessageRoleType +from pilot.model.base import ModelInstance, ModelOutput +from pilot.model.parameter import ModelAPIServerParameters, WorkerType +from pilot.model.cluster import ModelRegistry, ModelRegistryClient +from pilot.model.cluster.manager_base import WorkerManager, WorkerManagerFactory +from pilot.utils.utils import setup_logging + +logger = logging.getLogger(__name__) + + +class APIServerException(Exception): + def __init__(self, code: int, message: str): + self.code = code + self.message = message + + +class APISettings(BaseSettings): + api_keys: Optional[List[str]] = None + + +api_settings = APISettings() +get_bearer_token = HTTPBearer(auto_error=False) + + +async def check_api_key( + auth: Optional[HTTPAuthorizationCredentials] = Depends(get_bearer_token), +) -> str: + if api_settings.api_keys: + if auth is None or (token := auth.credentials) not in api_settings.api_keys: + raise HTTPException( + status_code=401, + detail={ + "error": { + "message": "", + "type": "invalid_request_error", + "param": None, + "code": "invalid_api_key", + } + }, + ) + return token + else: + # api_keys not set; allow all + return None + + +class APIServer(BaseComponent): + name = ComponentType.MODEL_API_SERVER + + def init_app(self, system_app: SystemApp): + self.system_app = system_app + + def get_worker_manager(self) -> WorkerManager: + """Get the worker manager component instance + + Raises: + APIServerException: If can't get worker manager component instance + """ + worker_manager = self.system_app.get_component( + ComponentType.WORKER_MANAGER_FACTORY, WorkerManagerFactory + ).create() + if not worker_manager: + raise APIServerException( + ErrorCode.INTERNAL_ERROR, + f"Could not get component {ComponentType.WORKER_MANAGER_FACTORY} from system_app", + ) + return worker_manager + + def get_model_registry(self) -> ModelRegistry: + """Get the model registry component instance + + Raises: + APIServerException: If can't get model registry component instance + """ + + controller = self.system_app.get_component( + ComponentType.MODEL_REGISTRY, ModelRegistry + ) + if not controller: + raise APIServerException( + ErrorCode.INTERNAL_ERROR, + f"Could not get component {ComponentType.MODEL_REGISTRY} from system_app", + ) + return controller + + async def get_model_instances_or_raise( + self, model_name: str + ) -> List[ModelInstance]: + """Get healthy model instances with request model name + + Args: + model_name (str): Model name + + Raises: + APIServerException: If can't get healthy model instances with request model name + """ + registry = self.get_model_registry() + registry_model_name = f"{model_name}@llm" + model_instances = await registry.get_all_instances( + registry_model_name, healthy_only=True + ) + if not model_instances: + all_instances = await registry.get_all_model_instances(healthy_only=True) + models = [ + ins.model_name.split("@llm")[0] + for ins in all_instances + if ins.model_name.endswith("@llm") + ] + if models: + models = "&&".join(models) + message = f"Only {models} allowed now, your model {model_name}" + else: + message = f"No models allowed now, your model {model_name}" + raise APIServerException(ErrorCode.INVALID_MODEL, message) + return model_instances + + async def get_available_models(self) -> ModelList: + """Return available models + + Just include LLM and embedding models. + + Returns: + List[ModelList]: The list of models. + """ + registry = self.get_model_registry() + model_instances = await registry.get_all_model_instances(healthy_only=True) + model_name_set = set() + for inst in model_instances: + name, worker_type = WorkerType.parse_worker_key(inst.model_name) + if worker_type == WorkerType.LLM or worker_type == WorkerType.TEXT2VEC: + model_name_set.add(name) + models = list(model_name_set) + models.sort() + # TODO: return real model permission details + model_cards = [] + for m in models: + model_cards.append( + ModelCard( + id=m, root=m, owned_by="DB-GPT", permission=[ModelPermission()] + ) + ) + return ModelList(data=model_cards) + + async def chat_completion_stream_generator( + self, model_name: str, params: Dict[str, Any], n: int + ) -> Generator[str, Any, None]: + """Chat stream completion generator + + Args: + model_name (str): Model name + params (Dict[str, Any]): The parameters pass to model worker + n (int): How many completions to generate for each prompt. + """ + worker_manager = self.get_worker_manager() + id = f"chatcmpl-{shortuuid.random()}" + finish_stream_events = [] + for i in range(n): + # First chunk with role + choice_data = ChatCompletionResponseStreamChoice( + index=i, + delta=DeltaMessage(role="assistant"), + finish_reason=None, + ) + chunk = ChatCompletionStreamResponse( + id=id, choices=[choice_data], model=model_name + ) + yield f"data: {chunk.json(exclude_unset=True, ensure_ascii=False)}\n\n" + + previous_text = "" + async for model_output in worker_manager.generate_stream(params): + model_output: ModelOutput = model_output + if model_output.error_code != 0: + yield f"data: {json.dumps(model_output.to_dict(), ensure_ascii=False)}\n\n" + yield "data: [DONE]\n\n" + return + decoded_unicode = model_output.text.replace("\ufffd", "") + delta_text = decoded_unicode[len(previous_text) :] + previous_text = ( + decoded_unicode + if len(decoded_unicode) > len(previous_text) + else previous_text + ) + + if len(delta_text) == 0: + delta_text = None + choice_data = ChatCompletionResponseStreamChoice( + index=i, + delta=DeltaMessage(content=delta_text), + finish_reason=model_output.finish_reason, + ) + chunk = ChatCompletionStreamResponse( + id=id, choices=[choice_data], model=model_name + ) + if delta_text is None: + if model_output.finish_reason is not None: + finish_stream_events.append(chunk) + continue + yield f"data: {chunk.json(exclude_unset=True, ensure_ascii=False)}\n\n" + # There is not "content" field in the last delta message, so exclude_none to exclude field "content". + for finish_chunk in finish_stream_events: + yield f"data: {finish_chunk.json(exclude_none=True, ensure_ascii=False)}\n\n" + yield "data: [DONE]\n\n" + + async def chat_completion_generate( + self, model_name: str, params: Dict[str, Any], n: int + ) -> ChatCompletionResponse: + """Generate completion + Args: + model_name (str): Model name + params (Dict[str, Any]): The parameters pass to model worker + n (int): How many completions to generate for each prompt. + """ + worker_manager: WorkerManager = self.get_worker_manager() + choices = [] + chat_completions = [] + for i in range(n): + model_output = asyncio.create_task(worker_manager.generate(params)) + chat_completions.append(model_output) + try: + all_tasks = await asyncio.gather(*chat_completions) + except Exception as e: + return create_error_response(ErrorCode.INTERNAL_ERROR, str(e)) + usage = UsageInfo() + for i, model_output in enumerate(all_tasks): + model_output: ModelOutput = model_output + if model_output.error_code != 0: + return create_error_response(model_output.error_code, model_output.text) + choices.append( + ChatCompletionResponseChoice( + index=i, + message=ChatMessage(role="assistant", content=model_output.text), + finish_reason=model_output.finish_reason or "stop", + ) + ) + if model_output.usage: + task_usage = UsageInfo.parse_obj(model_output.usage) + for usage_key, usage_value in task_usage.dict().items(): + setattr(usage, usage_key, getattr(usage, usage_key) + usage_value) + + return ChatCompletionResponse(model=model_name, choices=choices, usage=usage) + + +def get_api_server() -> APIServer: + api_server = global_system_app.get_component( + ComponentType.MODEL_API_SERVER, APIServer, default_component=None + ) + if not api_server: + global_system_app.register(APIServer) + return global_system_app.get_component(ComponentType.MODEL_API_SERVER, APIServer) + + +router = APIRouter() + + +@router.get("/v1/models", dependencies=[Depends(check_api_key)]) +async def get_available_models(api_server: APIServer = Depends(get_api_server)): + return await api_server.get_available_models() + + +@router.post("/v1/chat/completions", dependencies=[Depends(check_api_key)]) +async def create_chat_completion( + request: APIChatCompletionRequest, api_server: APIServer = Depends(get_api_server) +): + await api_server.get_model_instances_or_raise(request.model) + error_check_ret = check_requests(request) + if error_check_ret is not None: + return error_check_ret + params = { + "model": request.model, + "messages": ModelMessage.to_dict_list( + ModelMessage.from_openai_messages(request.messages) + ), + "echo": False, + } + if request.temperature: + params["temperature"] = request.temperature + if request.top_p: + params["top_p"] = request.top_p + if request.max_tokens: + params["max_new_tokens"] = request.max_tokens + if request.stop: + params["stop"] = request.stop + if request.user: + params["user"] = request.user + + # TODO check token length + if request.stream: + generator = api_server.chat_completion_stream_generator( + request.model, params, request.n + ) + return StreamingResponse(generator, media_type="text/event-stream") + return await api_server.chat_completion_generate(request.model, params, request.n) + + +def _initialize_all(controller_addr: str, system_app: SystemApp): + from pilot.model.cluster import RemoteWorkerManager, ModelRegistryClient + from pilot.model.cluster.worker.manager import _DefaultWorkerManagerFactory + + if not system_app.get_component( + ComponentType.MODEL_REGISTRY, ModelRegistry, default_component=None + ): + # Register model registry if not exist + registry = ModelRegistryClient(controller_addr) + registry.name = ComponentType.MODEL_REGISTRY.value + system_app.register_instance(registry) + + registry = system_app.get_component( + ComponentType.MODEL_REGISTRY, ModelRegistry, default_component=None + ) + worker_manager = RemoteWorkerManager(registry) + + # Register worker manager component if not exist + system_app.get_component( + ComponentType.WORKER_MANAGER_FACTORY, + WorkerManagerFactory, + or_register_component=_DefaultWorkerManagerFactory, + worker_manager=worker_manager, + ) + # Register api server component if not exist + system_app.get_component( + ComponentType.MODEL_API_SERVER, APIServer, or_register_component=APIServer + ) + + +def initialize_apiserver( + controller_addr: str, + app=None, + system_app: SystemApp = None, + host: str = None, + port: int = None, + api_keys: List[str] = None, +): + global global_system_app + global api_settings + embedded_mod = True + if not app: + embedded_mod = False + app = FastAPI() + app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"], + allow_headers=["*"], + ) + + if not system_app: + system_app = SystemApp(app) + global_system_app = system_app + + if api_keys: + api_settings.api_keys = api_keys + + app.include_router(router, prefix="/api", tags=["APIServer"]) + + @app.exception_handler(APIServerException) + async def validation_apiserver_exception_handler(request, exc: APIServerException): + return create_error_response(exc.code, exc.message) + + @app.exception_handler(RequestValidationError) + async def validation_exception_handler(request, exc): + return create_error_response(ErrorCode.VALIDATION_TYPE_ERROR, str(exc)) + + _initialize_all(controller_addr, system_app) + + if not embedded_mod: + import uvicorn + + uvicorn.run(app, host=host, port=port, log_level="info") + + +def run_apiserver(): + parser = EnvArgumentParser() + env_prefix = "apiserver_" + apiserver_params: ModelAPIServerParameters = parser.parse_args_into_dataclass( + ModelAPIServerParameters, + env_prefixes=[env_prefix], + ) + setup_logging( + "pilot", + logging_level=apiserver_params.log_level, + logger_filename=apiserver_params.log_file, + ) + api_keys = None + if apiserver_params.api_keys: + api_keys = apiserver_params.api_keys.strip().split(",") + + initialize_apiserver( + apiserver_params.controller_addr, + host=apiserver_params.host, + port=apiserver_params.port, + api_keys=api_keys, + ) + + +if __name__ == "__main__": + run_apiserver() diff --git a/pilot/model/cluster/apiserver/tests/__init__.py b/pilot/model/cluster/apiserver/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pilot/model/cluster/apiserver/tests/test_api.py b/pilot/model/cluster/apiserver/tests/test_api.py new file mode 100644 index 000000000..281a8aff6 --- /dev/null +++ b/pilot/model/cluster/apiserver/tests/test_api.py @@ -0,0 +1,248 @@ +import pytest +import pytest_asyncio +from aioresponses import aioresponses +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from httpx import AsyncClient, HTTPError + +from pilot.component import SystemApp +from pilot.utils.openai_utils import chat_completion_stream, chat_completion + +from pilot.model.cluster.apiserver.api import ( + api_settings, + initialize_apiserver, + ModelList, + UsageInfo, + ChatCompletionResponse, + ChatCompletionResponseStreamChoice, + ChatCompletionStreamResponse, + ChatMessage, + ChatCompletionResponseChoice, + DeltaMessage, +) +from pilot.model.cluster.tests.conftest import _new_cluster + +from pilot.model.cluster.worker.manager import _DefaultWorkerManagerFactory + +app = FastAPI() +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"], + allow_headers=["*"], +) + + +@pytest_asyncio.fixture +async def system_app(): + return SystemApp(app) + + +@pytest_asyncio.fixture +async def client(request, system_app: SystemApp): + param = getattr(request, "param", {}) + api_keys = param.get("api_keys", []) + client_api_key = param.get("client_api_key") + if "num_workers" not in param: + param["num_workers"] = 2 + if "api_keys" in param: + del param["api_keys"] + headers = {} + if client_api_key: + headers["Authorization"] = "Bearer " + client_api_key + print(f"param: {param}") + if api_settings: + # Clear global api keys + api_settings.api_keys = [] + async with AsyncClient(app=app, base_url="http://test", headers=headers) as client: + async with _new_cluster(**param) as cluster: + worker_manager, model_registry = cluster + system_app.register(_DefaultWorkerManagerFactory, worker_manager) + system_app.register_instance(model_registry) + # print(f"Instances {model_registry.registry}") + initialize_apiserver(None, app, system_app, api_keys=api_keys) + yield client + + +@pytest.mark.asyncio +async def test_get_all_models(client: AsyncClient): + res = await client.get("/api/v1/models") + res.status_code == 200 + model_lists = ModelList.parse_obj(res.json()) + print(f"model list json: {res.json()}") + assert model_lists.object == "list" + assert len(model_lists.data) == 2 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "client, expected_messages", + [ + ({"stream_messags": ["Hello", " world."]}, "Hello world."), + ({"stream_messags": ["你好,我是", "张三。"]}, "你好,我是张三。"), + ], + indirect=["client"], +) +async def test_chat_completions(client: AsyncClient, expected_messages): + chat_data = { + "model": "test-model-name-0", + "messages": [{"role": "user", "content": "Hello"}], + "stream": True, + } + full_text = "" + async for text in chat_completion_stream( + "/api/v1/chat/completions", chat_data, client + ): + full_text += text + assert full_text == expected_messages + + assert ( + await chat_completion("/api/v1/chat/completions", chat_data, client) + == expected_messages + ) + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "client, expected_messages, client_api_key", + [ + ( + {"stream_messags": ["Hello", " world."], "api_keys": ["abc"]}, + "Hello world.", + "abc", + ), + ({"stream_messags": ["你好,我是", "张三。"], "api_keys": ["abc"]}, "你好,我是张三。", "abc"), + ], + indirect=["client"], +) +async def test_chat_completions_with_openai_lib_async_no_stream( + client: AsyncClient, expected_messages: str, client_api_key: str +): + import openai + + openai.api_key = client_api_key + openai.api_base = "http://test/api/v1" + + model_name = "test-model-name-0" + + with aioresponses() as mocked: + mock_message = {"text": expected_messages} + one_res = ChatCompletionResponseChoice( + index=0, + message=ChatMessage(role="assistant", content=expected_messages), + finish_reason="stop", + ) + data = ChatCompletionResponse( + model=model_name, choices=[one_res], usage=UsageInfo() + ) + mock_message = f"{data.json(exclude_unset=True, ensure_ascii=False)}\n\n" + # Mock http request + mocked.post( + "http://test/api/v1/chat/completions", status=200, body=mock_message + ) + completion = await openai.ChatCompletion.acreate( + model=model_name, + messages=[{"role": "user", "content": "Hello! What is your name?"}], + ) + assert completion.choices[0].message.content == expected_messages + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "client, expected_messages, client_api_key", + [ + ( + {"stream_messags": ["Hello", " world."], "api_keys": ["abc"]}, + "Hello world.", + "abc", + ), + ({"stream_messags": ["你好,我是", "张三。"], "api_keys": ["abc"]}, "你好,我是张三。", "abc"), + ], + indirect=["client"], +) +async def test_chat_completions_with_openai_lib_async_stream( + client: AsyncClient, expected_messages: str, client_api_key: str +): + import openai + + openai.api_key = client_api_key + openai.api_base = "http://test/api/v1" + + model_name = "test-model-name-0" + + with aioresponses() as mocked: + mock_message = {"text": expected_messages} + choice_data = ChatCompletionResponseStreamChoice( + index=0, + delta=DeltaMessage(content=expected_messages), + finish_reason="stop", + ) + chunk = ChatCompletionStreamResponse( + id=0, choices=[choice_data], model=model_name + ) + mock_message = f"data: {chunk.json(exclude_unset=True, ensure_ascii=False)}\n\n" + mocked.post( + "http://test/api/v1/chat/completions", + status=200, + body=mock_message, + content_type="text/event-stream", + ) + + stream_stream_resp = "" + async for stream_resp in await openai.ChatCompletion.acreate( + model=model_name, + messages=[{"role": "user", "content": "Hello! What is your name?"}], + stream=True, + ): + stream_stream_resp = stream_resp.choices[0]["delta"].get("content", "") + assert stream_stream_resp == expected_messages + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + "client, expected_messages, api_key_is_error", + [ + ( + { + "stream_messags": ["Hello", " world."], + "api_keys": ["abc", "xx"], + "client_api_key": "abc", + }, + "Hello world.", + False, + ), + ({"stream_messags": ["你好,我是", "张三。"]}, "你好,我是张三。", False), + ( + {"stream_messags": ["你好,我是", "张三。"], "api_keys": ["abc", "xx"]}, + "你好,我是张三。", + True, + ), + ( + { + "stream_messags": ["你好,我是", "张三。"], + "api_keys": ["abc", "xx"], + "client_api_key": "error_api_key", + }, + "你好,我是张三。", + True, + ), + ], + indirect=["client"], +) +async def test_chat_completions_with_api_keys( + client: AsyncClient, expected_messages: str, api_key_is_error: bool +): + chat_data = { + "model": "test-model-name-0", + "messages": [{"role": "user", "content": "Hello"}], + "stream": True, + } + if api_key_is_error: + with pytest.raises(HTTPError): + await chat_completion("/api/v1/chat/completions", chat_data, client) + else: + assert ( + await chat_completion("/api/v1/chat/completions", chat_data, client) + == expected_messages + ) diff --git a/pilot/model/cluster/controller/controller.py b/pilot/model/cluster/controller/controller.py index 173c8c019..0006d91a0 100644 --- a/pilot/model/cluster/controller/controller.py +++ b/pilot/model/cluster/controller/controller.py @@ -66,7 +66,9 @@ class LocalModelController(BaseModelController): f"Get all instances with {model_name}, healthy_only: {healthy_only}" ) if not model_name: - return await self.registry.get_all_model_instances() + return await self.registry.get_all_model_instances( + healthy_only=healthy_only + ) else: return await self.registry.get_all_instances(model_name, healthy_only) @@ -98,8 +100,10 @@ class _RemoteModelController(BaseModelController): class ModelRegistryClient(_RemoteModelController, ModelRegistry): - async def get_all_model_instances(self) -> List[ModelInstance]: - return await self.get_all_instances() + async def get_all_model_instances( + self, healthy_only: bool = False + ) -> List[ModelInstance]: + return await self.get_all_instances(healthy_only=healthy_only) @sync_api_remote(path="/api/controller/models") def sync_get_all_instances( diff --git a/pilot/model/cluster/registry.py b/pilot/model/cluster/registry.py index 398882eb9..eb5f1e415 100644 --- a/pilot/model/cluster/registry.py +++ b/pilot/model/cluster/registry.py @@ -1,22 +1,37 @@ import random import threading import time +import logging from abc import ABC, abstractmethod from collections import defaultdict from datetime import datetime, timedelta -from typing import Dict, List, Tuple +from typing import Dict, List, Optional, Tuple import itertools +from pilot.component import BaseComponent, ComponentType, SystemApp from pilot.model.base import ModelInstance -class ModelRegistry(ABC): +logger = logging.getLogger(__name__) + + +class ModelRegistry(BaseComponent, ABC): """ Abstract base class for a model registry. It provides an interface for registering, deregistering, fetching instances, and sending heartbeats for instances. """ + name = ComponentType.MODEL_REGISTRY + + def __init__(self, system_app: SystemApp | None = None): + self.system_app = system_app + super().__init__(system_app) + + def init_app(self, system_app: SystemApp): + """Initialize the component with the main application.""" + self.system_app = system_app + @abstractmethod async def register_instance(self, instance: ModelInstance) -> bool: """ @@ -65,9 +80,11 @@ class ModelRegistry(ABC): """Fetch all instances of a given model. Optionally, fetch only the healthy instances.""" @abstractmethod - async def get_all_model_instances(self) -> List[ModelInstance]: + async def get_all_model_instances( + self, healthy_only: bool = False + ) -> List[ModelInstance]: """ - Fetch all instances of all models + Fetch all instances of all models, Optionally, fetch only the healthy instances. Returns: - List[ModelInstance]: A list of instances for the all models. @@ -105,8 +122,12 @@ class ModelRegistry(ABC): class EmbeddedModelRegistry(ModelRegistry): def __init__( - self, heartbeat_interval_secs: int = 60, heartbeat_timeout_secs: int = 120 + self, + system_app: SystemApp | None = None, + heartbeat_interval_secs: int = 60, + heartbeat_timeout_secs: int = 120, ): + super().__init__(system_app) self.registry: Dict[str, List[ModelInstance]] = defaultdict(list) self.heartbeat_interval_secs = heartbeat_interval_secs self.heartbeat_timeout_secs = heartbeat_timeout_secs @@ -180,9 +201,14 @@ class EmbeddedModelRegistry(ModelRegistry): instances = [ins for ins in instances if ins.healthy == True] return instances - async def get_all_model_instances(self) -> List[ModelInstance]: - print(self.registry) - return list(itertools.chain(*self.registry.values())) + async def get_all_model_instances( + self, healthy_only: bool = False + ) -> List[ModelInstance]: + logger.debug("Current registry metadata:\n{self.registry}") + instances = list(itertools.chain(*self.registry.values())) + if healthy_only: + instances = [ins for ins in instances if ins.healthy == True] + return instances async def send_heartbeat(self, instance: ModelInstance) -> bool: _, exist_ins = self._get_instances( diff --git a/pilot/model/cluster/tests/__init__.py b/pilot/model/cluster/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pilot/model/cluster/worker/tests/base_tests.py b/pilot/model/cluster/tests/conftest.py similarity index 71% rename from pilot/model/cluster/worker/tests/base_tests.py rename to pilot/model/cluster/tests/conftest.py index 21821d9f9..f614387ac 100644 --- a/pilot/model/cluster/worker/tests/base_tests.py +++ b/pilot/model/cluster/tests/conftest.py @@ -6,6 +6,7 @@ from pilot.model.parameter import ModelParameters, ModelWorkerParameters, Worker from pilot.model.base import ModelOutput from pilot.model.cluster.worker_base import ModelWorker from pilot.model.cluster.worker.manager import ( + WorkerManager, LocalWorkerManager, RegisterFunc, DeregisterFunc, @@ -13,6 +14,23 @@ from pilot.model.cluster.worker.manager import ( ApplyFunction, ) +from pilot.model.base import ModelInstance +from pilot.model.cluster.registry import ModelRegistry, EmbeddedModelRegistry + + +@pytest.fixture +def model_registry(request): + return EmbeddedModelRegistry() + + +@pytest.fixture +def model_instance(): + return ModelInstance( + model_name="test_model", + host="192.168.1.1", + port=5000, + ) + class MockModelWorker(ModelWorker): def __init__( @@ -51,8 +69,10 @@ class MockModelWorker(ModelWorker): raise Exception("Stop worker error for mock") def generate_stream(self, params: Dict) -> Iterator[ModelOutput]: + full_text = "" for msg in self.stream_messags: - yield ModelOutput(text=msg, error_code=0) + full_text += msg + yield ModelOutput(text=full_text, error_code=0) def generate(self, params: Dict) -> ModelOutput: output = None @@ -67,6 +87,8 @@ class MockModelWorker(ModelWorker): _TEST_MODEL_NAME = "vicuna-13b-v1.5" _TEST_MODEL_PATH = "/app/models/vicuna-13b-v1.5" +ClusterType = Tuple[WorkerManager, ModelRegistry] + def _new_worker_params( model_name: str = _TEST_MODEL_NAME, @@ -85,7 +107,9 @@ def _create_workers( worker_type: str = WorkerType.LLM.value, stream_messags: List[str] = None, embeddings: List[List[float]] = None, -) -> List[Tuple[ModelWorker, ModelWorkerParameters]]: + host: str = "127.0.0.1", + start_port=8001, +) -> List[Tuple[ModelWorker, ModelWorkerParameters, ModelInstance]]: workers = [] for i in range(num_workers): model_name = f"test-model-name-{i}" @@ -98,10 +122,16 @@ def _create_workers( stream_messags=stream_messags, embeddings=embeddings, ) + model_instance = ModelInstance( + model_name=WorkerType.to_worker_key(model_name, worker_type), + host=host, + port=start_port + i, + healthy=True, + ) worker_params = _new_worker_params( model_name, model_path, worker_type=worker_type ) - workers.append((worker, worker_params)) + workers.append((worker, worker_params, model_instance)) return workers @@ -127,12 +157,12 @@ async def _start_worker_manager(**kwargs): model_registry=model_registry, ) - for worker, worker_params in _create_workers( + for worker, worker_params, model_instance in _create_workers( num_workers, error_worker, stop_error, stream_messags, embeddings ): worker_manager.add_worker(worker, worker_params) if workers: - for worker, worker_params in workers: + for worker, worker_params, model_instance in workers: worker_manager.add_worker(worker, worker_params) if start: @@ -143,6 +173,15 @@ async def _start_worker_manager(**kwargs): await worker_manager.stop() +async def _create_model_registry( + workers: List[Tuple[ModelWorker, ModelWorkerParameters, ModelInstance]] +) -> ModelRegistry: + registry = EmbeddedModelRegistry() + for _, _, inst in workers: + assert await registry.register_instance(inst) == True + return registry + + @pytest_asyncio.fixture async def manager_2_workers(request): param = getattr(request, "param", {}) @@ -166,3 +205,27 @@ async def manager_2_embedding_workers(request): ) async with _start_worker_manager(workers=workers, **param) as worker_manager: yield (worker_manager, workers) + + +@asynccontextmanager +async def _new_cluster(**kwargs) -> ClusterType: + num_workers = kwargs.get("num_workers", 0) + workers = _create_workers( + num_workers, stream_messags=kwargs.get("stream_messags", []) + ) + if "num_workers" in kwargs: + del kwargs["num_workers"] + registry = await _create_model_registry( + workers, + ) + async with _start_worker_manager(workers=workers, **kwargs) as worker_manager: + yield (worker_manager, registry) + + +@pytest_asyncio.fixture +async def cluster_2_workers(request): + param = getattr(request, "param", {}) + workers = _create_workers(2) + registry = await _create_model_registry(workers) + async with _start_worker_manager(workers=workers, **param) as worker_manager: + yield (worker_manager, registry) diff --git a/pilot/model/cluster/worker/default_worker.py b/pilot/model/cluster/worker/default_worker.py index 5caa2ee7e..44a476f20 100644 --- a/pilot/model/cluster/worker/default_worker.py +++ b/pilot/model/cluster/worker/default_worker.py @@ -256,15 +256,22 @@ class DefaultModelWorker(ModelWorker): return params, model_context, generate_stream_func, model_span def _handle_output(self, output, previous_response, model_context): + finish_reason = None + usage = None if isinstance(output, dict): finish_reason = output.get("finish_reason") + usage = output.get("usage") output = output["text"] if finish_reason is not None: logger.info(f"finish_reason: {finish_reason}") incremental_output = output[len(previous_response) :] print(incremental_output, end="", flush=True) model_output = ModelOutput( - text=output, error_code=0, model_context=model_context + text=output, + error_code=0, + model_context=model_context, + finish_reason=finish_reason, + usage=usage, ) return model_output, incremental_output, output diff --git a/pilot/model/cluster/worker/manager.py b/pilot/model/cluster/worker/manager.py index a76fa6685..2dcfb086e 100644 --- a/pilot/model/cluster/worker/manager.py +++ b/pilot/model/cluster/worker/manager.py @@ -99,9 +99,7 @@ class LocalWorkerManager(WorkerManager): ) def _worker_key(self, worker_type: str, model_name: str) -> str: - if isinstance(worker_type, WorkerType): - worker_type = worker_type.value - return f"{model_name}@{worker_type}" + return WorkerType.to_worker_key(model_name, worker_type) async def run_blocking_func(self, func, *args): if asyncio.iscoroutinefunction(func): diff --git a/pilot/model/cluster/worker/tests/test_manager.py b/pilot/model/cluster/worker/tests/test_manager.py index 919e64f99..681fb49a3 100644 --- a/pilot/model/cluster/worker/tests/test_manager.py +++ b/pilot/model/cluster/worker/tests/test_manager.py @@ -3,7 +3,7 @@ import pytest from typing import List, Iterator, Dict, Tuple from dataclasses import asdict from pilot.model.parameter import ModelParameters, ModelWorkerParameters, WorkerType -from pilot.model.base import ModelOutput, WorkerApplyType +from pilot.model.base import ModelOutput, WorkerApplyType, ModelInstance from pilot.model.cluster.base import WorkerApplyRequest, WorkerStartupRequest from pilot.model.cluster.worker_base import ModelWorker from pilot.model.cluster.manager_base import WorkerRunData @@ -14,7 +14,7 @@ from pilot.model.cluster.worker.manager import ( SendHeartbeatFunc, ApplyFunction, ) -from pilot.model.cluster.worker.tests.base_tests import ( +from pilot.model.cluster.tests.conftest import ( MockModelWorker, manager_2_workers, manager_with_2_workers, @@ -216,7 +216,7 @@ async def test__remove_worker(): workers = _create_workers(3) async with _start_worker_manager(workers=workers, stop=False) as manager: assert len(manager.workers) == 3 - for _, worker_params in workers: + for _, worker_params, _ in workers: manager._remove_worker(worker_params) not_exist_parmas = _new_worker_params( model_name="this is a not exist worker params" @@ -229,7 +229,7 @@ async def test__remove_worker(): async def test_model_startup(mock_build_worker): async with _start_worker_manager() as manager: workers = _create_workers(1) - worker, worker_params = workers[0] + worker, worker_params, model_instance = workers[0] mock_build_worker.return_value = worker req = WorkerStartupRequest( @@ -245,7 +245,7 @@ async def test_model_startup(mock_build_worker): async with _start_worker_manager() as manager: workers = _create_workers(1, error_worker=True) - worker, worker_params = workers[0] + worker, worker_params, model_instance = workers[0] mock_build_worker.return_value = worker req = WorkerStartupRequest( host="127.0.0.1", @@ -263,7 +263,7 @@ async def test_model_startup(mock_build_worker): async def test_model_shutdown(mock_build_worker): async with _start_worker_manager(start=False, stop=False) as manager: workers = _create_workers(1) - worker, worker_params = workers[0] + worker, worker_params, model_instance = workers[0] mock_build_worker.return_value = worker req = WorkerStartupRequest( @@ -298,7 +298,7 @@ async def test_get_model_instances(is_async): workers = _create_workers(3) async with _start_worker_manager(workers=workers, stop=False) as manager: assert len(manager.workers) == 3 - for _, worker_params in workers: + for _, worker_params, _ in workers: model_name = worker_params.model_name worker_type = worker_params.worker_type if is_async: @@ -326,7 +326,7 @@ async def test__simple_select( ] ): manager, workers = manager_with_2_workers - for _, worker_params in workers: + for _, worker_params, _ in workers: model_name = worker_params.model_name worker_type = worker_params.worker_type instances = await manager.get_model_instances(worker_type, model_name) @@ -351,7 +351,7 @@ async def test_select_one_instance( ], ): manager, workers = manager_with_2_workers - for _, worker_params in workers: + for _, worker_params, _ in workers: model_name = worker_params.model_name worker_type = worker_params.worker_type if is_async: @@ -376,7 +376,7 @@ async def test__get_model( ], ): manager, workers = manager_with_2_workers - for _, worker_params in workers: + for _, worker_params, _ in workers: model_name = worker_params.model_name worker_type = worker_params.worker_type params = {"model": model_name} @@ -403,13 +403,13 @@ async def test_generate_stream( expected_messages: str, ): manager, workers = manager_with_2_workers - for _, worker_params in workers: + for _, worker_params, _ in workers: model_name = worker_params.model_name worker_type = worker_params.worker_type params = {"model": model_name} text = "" async for out in manager.generate_stream(params): - text += out.text + text = out.text assert text == expected_messages @@ -417,8 +417,8 @@ async def test_generate_stream( @pytest.mark.parametrize( "manager_with_2_workers, expected_messages", [ - ({"stream_messags": ["Hello", " world."]}, " world."), - ({"stream_messags": ["你好,我是", "张三。"]}, "张三。"), + ({"stream_messags": ["Hello", " world."]}, "Hello world."), + ({"stream_messags": ["你好,我是", "张三。"]}, "你好,我是张三。"), ], indirect=["manager_with_2_workers"], ) @@ -429,7 +429,7 @@ async def test_generate( expected_messages: str, ): manager, workers = manager_with_2_workers - for _, worker_params in workers: + for _, worker_params, _ in workers: model_name = worker_params.model_name worker_type = worker_params.worker_type params = {"model": model_name} @@ -454,7 +454,7 @@ async def test_embeddings( is_async: bool, ): manager, workers = manager_2_embedding_workers - for _, worker_params in workers: + for _, worker_params, _ in workers: model_name = worker_params.model_name worker_type = worker_params.worker_type params = {"model": model_name, "input": ["hello", "world"]} @@ -472,7 +472,7 @@ async def test_parameter_descriptions( ] ): manager, workers = manager_with_2_workers - for _, worker_params in workers: + for _, worker_params, _ in workers: model_name = worker_params.model_name worker_type = worker_params.worker_type params = await manager.parameter_descriptions(worker_type, model_name) diff --git a/pilot/model/model_adapter.py b/pilot/model/model_adapter.py index e09b868e7..e2deeaa02 100644 --- a/pilot/model/model_adapter.py +++ b/pilot/model/model_adapter.py @@ -467,7 +467,8 @@ register_conv_template( sep="\n", sep2="", stop_str=["", "[UNK]"], - ) + ), + override=True, ) # source: https://huggingface.co/BAAI/AquilaChat2-34B/blob/4608b75855334b93329a771aee03869dbf7d88cc/predict.py#L227 register_conv_template( @@ -482,7 +483,8 @@ register_conv_template( sep="###", sep2="", stop_str=["", "[UNK]"], - ) + ), + override=True, ) # source: https://huggingface.co/BAAI/AquilaChat2-34B/blob/4608b75855334b93329a771aee03869dbf7d88cc/predict.py#L242 register_conv_template( @@ -495,5 +497,6 @@ register_conv_template( sep="", sep2="", stop_str=["", "<|endoftext|>"], - ) + ), + override=True, ) diff --git a/pilot/model/parameter.py b/pilot/model/parameter.py index ea81ec091..e21de1c42 100644 --- a/pilot/model/parameter.py +++ b/pilot/model/parameter.py @@ -1,9 +1,10 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- + import os from dataclasses import dataclass, field from enum import Enum -from typing import Dict, Optional +from typing import Dict, Optional, Union, Tuple from pilot.model.conversation import conv_templates from pilot.utils.parameter_utils import BaseParameters @@ -19,6 +20,35 @@ class WorkerType(str, Enum): def values(): return [item.value for item in WorkerType] + @staticmethod + def to_worker_key(worker_name, worker_type: Union[str, "WorkerType"]) -> str: + """Generate worker key from worker name and worker type + + Args: + worker_name (str): Worker name(eg., chatglm2-6b) + worker_type (Union[str, "WorkerType"]): Worker type(eg., 'llm', or [`WorkerType.LLM`]) + + Returns: + str: Generated worker key + """ + if "@" in worker_name: + raise ValueError(f"Invaild symbol '@' in your worker name {worker_name}") + if isinstance(worker_type, WorkerType): + worker_type = worker_type.value + return f"{worker_name}@{worker_type}" + + @staticmethod + def parse_worker_key(worker_key: str) -> Tuple[str, str]: + """Parse worker name and worker type from worker key + + Args: + worker_key (str): Worker key generated by [`WorkerType.to_worker_key`] + + Returns: + Tuple[str, str]: Worker name and worker type + """ + return tuple(worker_key.split("@")) + @dataclass class ModelControllerParameters(BaseParameters): @@ -60,6 +90,56 @@ class ModelControllerParameters(BaseParameters): ) +@dataclass +class ModelAPIServerParameters(BaseParameters): + host: Optional[str] = field( + default="0.0.0.0", metadata={"help": "Model API server deploy host"} + ) + port: Optional[int] = field( + default=8100, metadata={"help": "Model API server deploy port"} + ) + daemon: Optional[bool] = field( + default=False, metadata={"help": "Run Model API server in background"} + ) + controller_addr: Optional[str] = field( + default="http://127.0.0.1:8000", + metadata={"help": "The Model controller address to connect"}, + ) + + api_keys: Optional[str] = field( + default=None, + metadata={"help": "Optional list of comma separated API keys"}, + ) + + log_level: Optional[str] = field( + default=None, + metadata={ + "help": "Logging level", + "valid_values": [ + "FATAL", + "ERROR", + "WARNING", + "WARNING", + "INFO", + "DEBUG", + "NOTSET", + ], + }, + ) + log_file: Optional[str] = field( + default="dbgpt_model_apiserver.log", + metadata={ + "help": "The filename to store log", + }, + ) + tracer_file: Optional[str] = field( + default="dbgpt_model_apiserver_tracer.jsonl", + metadata={ + "help": "The filename to store tracer span records", + }, + ) + + @dataclass class BaseModelParameters(BaseParameters): model_name: str = field(metadata={"help": "Model name", "tags": "fixed"}) diff --git a/pilot/scene/base_message.py b/pilot/scene/base_message.py index eeb42a285..12a72e909 100644 --- a/pilot/scene/base_message.py +++ b/pilot/scene/base_message.py @@ -1,7 +1,7 @@ from __future__ import annotations from abc import ABC, abstractmethod -from typing import Any, Dict, List, Tuple, Optional +from typing import Any, Dict, List, Tuple, Optional, Union from pydantic import BaseModel, Field, root_validator @@ -70,14 +70,6 @@ class SystemMessage(BaseMessage): return "system" -class ModelMessage(BaseModel): - """Type of message that interaction between dbgpt-server and llm-server""" - - """Similar to openai's message format""" - role: str - content: str - - class ModelMessageRoleType: """ "Type of ModelMessage role""" @@ -87,6 +79,45 @@ class ModelMessageRoleType: VIEW = "view" +class ModelMessage(BaseModel): + """Type of message that interaction between dbgpt-server and llm-server""" + + """Similar to openai's message format""" + role: str + content: str + + @staticmethod + def from_openai_messages( + messages: Union[str, List[Dict[str, str]]] + ) -> List["ModelMessage"]: + """Openai message format to current ModelMessage format""" + if isinstance(messages, str): + return [ModelMessage(role=ModelMessageRoleType.HUMAN, content=messages)] + result = [] + for message in messages: + msg_role = message["role"] + content = message["content"] + if msg_role == "system": + result.append( + ModelMessage(role=ModelMessageRoleType.SYSTEM, content=content) + ) + elif msg_role == "user": + result.append( + ModelMessage(role=ModelMessageRoleType.HUMAN, content=content) + ) + elif msg_role == "assistant": + result.append( + ModelMessage(role=ModelMessageRoleType.AI, content=content) + ) + else: + raise ValueError(f"Unknown role: {msg_role}") + return result + + @staticmethod + def to_dict_list(messages: List["ModelMessage"]) -> List[Dict[str, str]]: + return list(map(lambda m: m.dict(), messages)) + + class Generation(BaseModel): """Output of a single generation.""" diff --git a/pilot/utils/openai_utils.py b/pilot/utils/openai_utils.py new file mode 100644 index 000000000..6577d3abf --- /dev/null +++ b/pilot/utils/openai_utils.py @@ -0,0 +1,99 @@ +from typing import Dict, Any, Awaitable, Callable, Optional, Iterator +import httpx +import asyncio +import logging +import json + +logger = logging.getLogger(__name__) +MessageCaller = Callable[[str], Awaitable[None]] + + +async def _do_chat_completion( + url: str, + chat_data: Dict[str, Any], + client: httpx.AsyncClient, + headers: Dict[str, Any] = {}, + timeout: int = 60, + caller: Optional[MessageCaller] = None, +) -> Iterator[str]: + async with client.stream( + "POST", + url, + headers=headers, + json=chat_data, + timeout=timeout, + ) as res: + if res.status_code != 200: + error_message = await res.aread() + if error_message: + error_message = error_message.decode("utf-8") + logger.error( + f"Request failed with status {res.status_code}. Error: {error_message}" + ) + raise httpx.RequestError( + f"Request failed with status {res.status_code}", + request=res.request, + ) + async for line in res.aiter_lines(): + if line: + if not line.startswith("data: "): + if caller: + await caller(line) + yield line + else: + decoded_line = line.split("data: ", 1)[1] + if decoded_line.lower().strip() != "[DONE]".lower(): + obj = json.loads(decoded_line) + if obj["choices"][0]["delta"].get("content") is not None: + text = obj["choices"][0]["delta"].get("content") + if caller: + await caller(text) + yield text + await asyncio.sleep(0.02) + + +async def chat_completion_stream( + url: str, + chat_data: Dict[str, Any], + client: Optional[httpx.AsyncClient] = None, + headers: Dict[str, Any] = {}, + timeout: int = 60, + caller: Optional[MessageCaller] = None, +) -> Iterator[str]: + if client: + async for text in _do_chat_completion( + url, + chat_data, + client=client, + headers=headers, + timeout=timeout, + caller=caller, + ): + yield text + else: + async with httpx.AsyncClient() as client: + async for text in _do_chat_completion( + url, + chat_data, + client=client, + headers=headers, + timeout=timeout, + caller=caller, + ): + yield text + + +async def chat_completion( + url: str, + chat_data: Dict[str, Any], + client: Optional[httpx.AsyncClient] = None, + headers: Dict[str, Any] = {}, + timeout: int = 60, + caller: Optional[MessageCaller] = None, +) -> str: + full_text = "" + async for text in chat_completion_stream( + url, chat_data, client, headers=headers, timeout=timeout, caller=caller + ): + full_text += text + return full_text diff --git a/requirements/dev-requirements.txt b/requirements/dev-requirements.txt index 072b527f1..d1a98ed49 100644 --- a/requirements/dev-requirements.txt +++ b/requirements/dev-requirements.txt @@ -8,6 +8,7 @@ pytest-integration pytest-mock pytest-recording pytesseract==0.3.10 +aioresponses # python code format black # for git hooks From 9e08886de9ae6e745f830ccb46bcdc41bbb96bb4 Mon Sep 17 00:00:00 2001 From: FangYin Cheng Date: Thu, 2 Nov 2023 21:16:12 +0800 Subject: [PATCH 38/57] docs: Add document for OpenAI-Compatible RESTful APIs --- .../install/cluster/cluster.rst | 1 + .../getting_started/install/cluster/openai.md | 51 ++++ .../install/llm/proxyllm/proxyllm.md | 9 +- .../getting_started/install/cluster/openai.po | 71 +++++ .../install/environment/environment.po | 136 ++++----- .../zh_CN/LC_MESSAGES/modules/knowledge.po | 264 +++++++++++------- 6 files changed, 354 insertions(+), 178 deletions(-) create mode 100644 docs/getting_started/install/cluster/openai.md create mode 100644 docs/locales/zh_CN/LC_MESSAGES/getting_started/install/cluster/openai.po diff --git a/docs/getting_started/install/cluster/cluster.rst b/docs/getting_started/install/cluster/cluster.rst index 93660d0a4..17895e7bc 100644 --- a/docs/getting_started/install/cluster/cluster.rst +++ b/docs/getting_started/install/cluster/cluster.rst @@ -77,3 +77,4 @@ By analyzing this information, we can identify performance bottlenecks in model ./vms/standalone.md ./vms/index.md + ./openai.md diff --git a/docs/getting_started/install/cluster/openai.md b/docs/getting_started/install/cluster/openai.md new file mode 100644 index 000000000..8f23ba0fa --- /dev/null +++ b/docs/getting_started/install/cluster/openai.md @@ -0,0 +1,51 @@ +OpenAI-Compatible RESTful APIs +================================== +(openai-apis-index)= + +### Install Prepare + +You must [deploy DB-GPT cluster](https://db-gpt.readthedocs.io/en/latest/getting_started/install/cluster/vms/index.html) first. + +### Launch Model API Server + +```bash +dbgpt start apiserver --controller_addr http://127.0.0.1:8000 --api_keys EMPTY +``` +By default, the Model API Server starts on port 8100. + +### Validate with cURL + +#### List models + +```bash +curl http://127.0.0.1:8100/api/v1/models \ +-H "Authorization: Bearer EMPTY" \ +-H "Content-Type: application/json" +``` + +#### Chat completions + +```bash +curl http://127.0.0.1:8100/api/v1/chat/completions \ +-H "Authorization: Bearer EMPTY" \ +-H "Content-Type: application/json" \ +-d '{"model": "vicuna-13b-v1.5", "messages": [{"role": "user", "content": "hello"}]}' +``` + +### Validate with OpenAI Official SDK + +#### Chat completions + +```python +import openai +openai.api_key = "EMPTY" +openai.api_base = "http://127.0.0.1:8100/api/v1" +model = "vicuna-13b-v1.5" + +completion = openai.ChatCompletion.create( + model=model, + messages=[{"role": "user", "content": "hello"}] +) +# print the completion +print(completion.choices[0].message.content) +``` \ No newline at end of file diff --git a/docs/getting_started/install/llm/proxyllm/proxyllm.md b/docs/getting_started/install/llm/proxyllm/proxyllm.md index a04252d2f..fae549dd3 100644 --- a/docs/getting_started/install/llm/proxyllm/proxyllm.md +++ b/docs/getting_started/install/llm/proxyllm/proxyllm.md @@ -24,9 +24,12 @@ PROXY_SERVER_URL=https://api.openai.com/v1/chat/completions #Azure LLM_MODEL=chatgpt_proxyllm -OPENAI_API_TYPE=azure -PROXY_API_KEY={your-openai-sk} -PROXY_SERVER_URL=https://xx.openai.azure.com/v1/chat/completions +PROXY_API_KEY={your-azure-sk} +PROXY_API_BASE=https://{your domain}.openai.azure.com/ +PROXY_API_TYPE=azure +PROXY_SERVER_URL=xxxx +PROXY_API_VERSION=2023-05-15 +PROXYLLM_BACKEND=gpt-35-turbo #Aliyun tongyi LLM_MODEL=tongyi_proxyllm diff --git a/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/cluster/openai.po b/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/cluster/openai.po new file mode 100644 index 000000000..0ef41aa6d --- /dev/null +++ b/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/cluster/openai.po @@ -0,0 +1,71 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, csunny +# This file is distributed under the same license as the DB-GPT package. +# FIRST AUTHOR , 2023. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: DB-GPT 👏👏 0.4.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-11-02 21:09+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh_CN\n" +"Language-Team: zh_CN \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.12.1\n" + +#: ../../getting_started/install/cluster/openai.md:1 +#: 01f4e2bf853341198633b367efec1522 +msgid "OpenAI-Compatible RESTful APIs" +msgstr "OpenAI RESTful 兼容接口" + +#: ../../getting_started/install/cluster/openai.md:5 +#: d8717e42335e4027bf4e76b3d28768ee +msgid "Install Prepare" +msgstr "安装准备" + +#: ../../getting_started/install/cluster/openai.md:7 +#: 9a48d8ee116942468de4c6faf9a64758 +msgid "" +"You must [deploy DB-GPT cluster](https://db-" +"gpt.readthedocs.io/en/latest/getting_started/install/cluster/vms/index.html)" +" first." +msgstr "你必须先部署 [DB-GPT 集群]" +"(https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-cn/zh-cn/latest/getting_started/install/cluster/vms/index.html)。" + +#: ../../getting_started/install/cluster/openai.md:9 +#: 7673a7121f004f7ca6b1a94a7e238fa3 +msgid "Launch Model API Server" +msgstr "启动模型 API Server" + +#: ../../getting_started/install/cluster/openai.md:14 +#: 84a925c2cbcd4e4895a1d2d2fe8f720f +msgid "By default, the Model API Server starts on port 8100." +msgstr "默认情况下,模型 API Server 使用 8100 端口启动。" + +#: ../../getting_started/install/cluster/openai.md:16 +#: e53ed41977cd4721becd51eba05c6609 +msgid "Validate with cURL" +msgstr "通过 cURL 验证" + +#: ../../getting_started/install/cluster/openai.md:18 +#: 7c883b410b5c4e53a256bf17c1ded80d +msgid "List models" +msgstr "列出模型" + +#: ../../getting_started/install/cluster/openai.md:26 +#: ../../getting_started/install/cluster/openai.md:37 +#: 7cf0ed13f0754f149ec085cd6cf7a45a 990d5d5ed5d64ab49550e68495b9e7a0 +msgid "Chat completions" +msgstr "" + +#: ../../getting_started/install/cluster/openai.md:35 +#: 81583edd22df44e091d18a0832278131 +msgid "Validate with OpenAI Official SDK" +msgstr "通过 OpenAI 官方 SDK 验证" + diff --git a/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/environment/environment.po b/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/environment/environment.po index 09b3c8fa2..addf53bc6 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/environment/environment.po +++ b/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/environment/environment.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 👏👏 0.3.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-17 13:07+0800\n" +"POT-Creation-Date: 2023-11-02 21:04+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -20,290 +20,292 @@ msgstr "" "Generated-By: Babel 2.12.1\n" #: ../../getting_started/install/environment/environment.md:1 -#: be341d16f7b24bf4ad123ab78a6d855a +#: a17719d2f4374285a7beb4d1db470146 #, fuzzy msgid "Environment Parameter" msgstr "环境变量说明" #: ../../getting_started/install/environment/environment.md:4 -#: 46eddb27c90f41548ea9a724bbcebd37 +#: 9a62e6fff7914eeaa2d195ddef4fcb61 msgid "LLM MODEL Config" msgstr "模型配置" #: ../../getting_started/install/environment/environment.md:5 -#: 7deaa85df4a04fb098f5994547a8724f +#: 90e3991538324ecfac8cac7ef2103ac2 msgid "LLM Model Name, see /pilot/configs/model_config.LLM_MODEL_CONFIG" msgstr "LLM Model Name, see /pilot/configs/model_config.LLM_MODEL_CONFIG" #: ../../getting_started/install/environment/environment.md:6 -#: 3902801c546547b3a4009df681ef7d52 +#: 1f45af01100c4586acbc05469e3006bc msgid "LLM_MODEL=vicuna-13b" msgstr "LLM_MODEL=vicuna-13b" #: ../../getting_started/install/environment/environment.md:8 -#: 84b0fdbfa1544ec28751e9b69b00cc02 +#: bed14b704f154c2db525f7fafd3aa5a4 msgid "MODEL_SERVER_ADDRESS" msgstr "MODEL_SERVER_ADDRESS" #: ../../getting_started/install/environment/environment.md:9 -#: 0b430bfab77d405989470d00ca3f6fe0 +#: ea42946cfe4f4ad996bf82c1996e7344 msgid "MODEL_SERVER=http://127.0.0.1:8000 LIMIT_MODEL_CONCURRENCY" msgstr "MODEL_SERVER=http://127.0.0.1:8000 LIMIT_MODEL_CONCURRENCY" #: ../../getting_started/install/environment/environment.md:12 -#: b477a25586c546729a93fb6785b7b2ec +#: 021c261231f342fdba34098b1baa06fd msgid "LIMIT_MODEL_CONCURRENCY=5" msgstr "LIMIT_MODEL_CONCURRENCY=5" #: ../../getting_started/install/environment/environment.md:14 -#: 1d6ea800af384fff9c265610f71cc94e +#: afaf0ba7fd09463d8ff74b514ed7264c msgid "MAX_POSITION_EMBEDDINGS" msgstr "MAX_POSITION_EMBEDDINGS" #: ../../getting_started/install/environment/environment.md:16 -#: 388e758ce4ea4692a4c34294cebce7f2 +#: e4517a942bca4361a64a00408f993f5b msgid "MAX_POSITION_EMBEDDINGS=4096" msgstr "MAX_POSITION_EMBEDDINGS=4096" #: ../../getting_started/install/environment/environment.md:18 -#: 16a307dce1294ceba892ff93ae4e81c0 +#: 78d2ef04ed4548b9b7b0fb8ae35c9d5c msgid "QUANTIZE_QLORA" msgstr "QUANTIZE_QLORA" #: ../../getting_started/install/environment/environment.md:20 -#: 93ceb2b2fcd5454b82eefb0ae8c7ae77 +#: bfa65db03c6d46bba293331f03ab15ac msgid "QUANTIZE_QLORA=True" msgstr "QUANTIZE_QLORA=True" #: ../../getting_started/install/environment/environment.md:22 -#: 15ffa35d023a4530b02a85ee6168dd4b +#: 1947d45a7f184821910b4834ad5f1897 msgid "QUANTIZE_8bit" msgstr "QUANTIZE_8bit" #: ../../getting_started/install/environment/environment.md:24 -#: 81df248ac5cb4ab0b13a711505f6a177 +#: 4a2ee2919d0e4bdaa13c9d92eefd2aac msgid "QUANTIZE_8bit=True" msgstr "QUANTIZE_8bit=True" #: ../../getting_started/install/environment/environment.md:27 -#: 15cc7b7d41ad44f0891c1189709f00f1 +#: 348dc1e411b54ab09414f40a20e934e4 msgid "LLM PROXY Settings" msgstr "LLM PROXY Settings" #: ../../getting_started/install/environment/environment.md:28 -#: e6c1115a39404f11b193a1593bc51a22 +#: a692e78425a040f5828ab54ff9a33f77 msgid "OPENAI Key" msgstr "OPENAI Key" #: ../../getting_started/install/environment/environment.md:30 -#: 8157e0a831fe4506a426822b7565e4f6 +#: 940d00e25a424acf92951a314a64e5ea msgid "PROXY_API_KEY={your-openai-sk}" msgstr "PROXY_API_KEY={your-openai-sk}" #: ../../getting_started/install/environment/environment.md:31 -#: 89b34d00bdb64e738bd9bc8c086b1f02 +#: 4bd27547ae6041679e91f2a363cd1deb msgid "PROXY_SERVER_URL=https://api.openai.com/v1/chat/completions" msgstr "PROXY_SERVER_URL=https://api.openai.com/v1/chat/completions" #: ../../getting_started/install/environment/environment.md:33 -#: 7a97df730aeb484daf19c8172e61a290 +#: cfa3071afb0b47baad6bd729d4a02cb9 msgid "from https://bard.google.com/ f12-> application-> __Secure-1PSID" msgstr "from https://bard.google.com/ f12-> application-> __Secure-1PSID" #: ../../getting_started/install/environment/environment.md:35 -#: d430ddf726a049c0a9e0a9bfd5a6fe0e +#: a17efa03b10f47f68afac9e865982a75 msgid "BARD_PROXY_API_KEY={your-bard-token}" msgstr "BARD_PROXY_API_KEY={your-bard-token}" #: ../../getting_started/install/environment/environment.md:38 -#: 23d6b0da3e7042abb55f6181c4a382d2 +#: 6bcfe90574da4d82a459e8e11bf73cba msgid "DATABASE SETTINGS" msgstr "DATABASE SETTINGS" #: ../../getting_started/install/environment/environment.md:39 -#: dbae0a2d847f41f5be9396a160ef88d0 +#: 2b1e62d9bf5d4af5a22f68c8248eaafb msgid "SQLite database (Current default database)" msgstr "SQLite database (Current default database)" #: ../../getting_started/install/environment/environment.md:40 -#: bdb55b7280c341a981e9d338cce53345 +#: 8a909ac3b3c943da8dbc4e8dd596c80c msgid "LOCAL_DB_PATH=data/default_sqlite.db" msgstr "LOCAL_DB_PATH=data/default_sqlite.db" #: ../../getting_started/install/environment/environment.md:41 -#: 739d67927a9d46b28500deba1917916b +#: 90ae6507932f4815b6e180051738bb93 msgid "LOCAL_DB_TYPE=sqlite # Database Type default:sqlite" msgstr "LOCAL_DB_TYPE=sqlite # Database Type default:sqlite" #: ../../getting_started/install/environment/environment.md:43 -#: eb4717bce6a6483b86d9780d924c5ff1 +#: d2ce34e0dcf44ccf9e8007d548ba7b0a msgid "MYSQL database" msgstr "MYSQL database" #: ../../getting_started/install/environment/environment.md:44 -#: 0f4cdf0ff5dd4ff0b397dfa88541a2e1 +#: c07159d63c334f6cbb95fcc30bfb7ea5 msgid "LOCAL_DB_TYPE=mysql" msgstr "LOCAL_DB_TYPE=mysql" #: ../../getting_started/install/environment/environment.md:45 -#: c971ead492c34487bd766300730a9cba +#: e16700b2ea8d411e91d010c1cde7aecc msgid "LOCAL_DB_USER=root" msgstr "LOCAL_DB_USER=root" #: ../../getting_started/install/environment/environment.md:46 -#: 02828b29ad044eeab890a2f8af0e5907 +#: bfc2dce1bf374121b6861e677b4e1ffa msgid "LOCAL_DB_PASSWORD=aa12345678" msgstr "LOCAL_DB_PASSWORD=aa12345678" #: ../../getting_started/install/environment/environment.md:47 -#: 53dc7f15b3934987b1f4c2e2d0b11299 +#: bc384739f5b04e21a34d0d2b78e7906c msgid "LOCAL_DB_HOST=127.0.0.1" msgstr "LOCAL_DB_HOST=127.0.0.1" #: ../../getting_started/install/environment/environment.md:48 -#: 1ac95fc482934247a118bab8dcebeb57 +#: e5253d452e0d42b7ac308fe6fbfb5017 msgid "LOCAL_DB_PORT=3306" msgstr "LOCAL_DB_PORT=3306" #: ../../getting_started/install/environment/environment.md:51 -#: 34e46aa926844be19c7196759b03af63 +#: 9ca8f6fe06ed4cbab390f94be252e165 msgid "EMBEDDING SETTINGS" msgstr "EMBEDDING SETTINGS" #: ../../getting_started/install/environment/environment.md:52 -#: 2b5aa08cc995495e85a1f7dc4f97b5d7 +#: 76c7c260293c4b49bae057143fd48377 msgid "EMBEDDING MODEL Name, see /pilot/configs/model_config.LLM_MODEL_CONFIG" msgstr "EMBEDDING模型, 参考see /pilot/configs/model_config.LLM_MODEL_CONFIG" #: ../../getting_started/install/environment/environment.md:53 -#: 0de0ca551ed040248406f848feca541d +#: f1d63a0128ce493cae37d34f1976bcca msgid "EMBEDDING_MODEL=text2vec" msgstr "EMBEDDING_MODEL=text2vec" #: ../../getting_started/install/environment/environment.md:55 -#: 43019fb570904c9981eb68f33e64569c +#: b8fbb99109d04781b2dd5bc5d6efa5bd msgid "Embedding Chunk size, default 500" msgstr "Embedding 切片大小, 默认500" #: ../../getting_started/install/environment/environment.md:57 -#: 7e3f93854873461286e96887e04167aa +#: bf8256576ea34f6a9c5f261ab9aab676 msgid "KNOWLEDGE_CHUNK_SIZE=500" msgstr "KNOWLEDGE_CHUNK_SIZE=500" #: ../../getting_started/install/environment/environment.md:59 -#: 9504f4a59ae74352a524b7741113e2d6 +#: 9b156c6b599b4c02a58ce023b4ff25f2 msgid "Embedding Chunk Overlap, default 100" msgstr "Embedding chunk Overlap, 文本块之间的最大重叠量。保留一些重叠可以保持文本块之间的连续性(例如使用滑动窗口),默认100" #: ../../getting_started/install/environment/environment.md:60 -#: 24e6119c2051479bbd9dba71a9c23dbe +#: dcafd903c36041ac85ac99a14dbee512 msgid "KNOWLEDGE_CHUNK_OVERLAP=100" msgstr "KNOWLEDGE_CHUNK_OVERLAP=100" #: ../../getting_started/install/environment/environment.md:62 -#: 0d180d7f2230442abee901c19526e442 -msgid "embeding recall top k,5" +#: 6c3244b7e5e24b0188c7af4bb52e9134 +#, fuzzy +msgid "embedding recall top k,5" msgstr "embedding 召回topk, 默认5" #: ../../getting_started/install/environment/environment.md:64 -#: a5bb9ab2ba50411cbbe87f7836bfbb6d +#: f4a2f30551cf4fe1a7ff3c7c74ec77be msgid "KNOWLEDGE_SEARCH_TOP_SIZE=5" msgstr "KNOWLEDGE_SEARCH_TOP_SIZE=5" #: ../../getting_started/install/environment/environment.md:66 -#: 183b8dd78cba4ae19bd2e08d69d21e0b -msgid "embeding recall max token ,2000" +#: 593f2512362f467e92fdaa60dd5903a0 +#, fuzzy +msgid "embedding recall max token ,2000" msgstr "embedding向量召回最大token, 默认2000" #: ../../getting_started/install/environment/environment.md:68 -#: ce0c711febcb44c18ae0fc858c3718d1 +#: 83d6d28914be4d6282d457272e508ddc msgid "KNOWLEDGE_SEARCH_MAX_TOKEN=5" msgstr "KNOWLEDGE_SEARCH_MAX_TOKEN=5" #: ../../getting_started/install/environment/environment.md:71 #: ../../getting_started/install/environment/environment.md:87 -#: 4cab1f399cc245b4a1a1976d2c4fc926 ec9cec667a1c4473bf9a796a26e1ce20 +#: 6bc1b9d995e74294a1c78e783c550db7 d33c77ded834438e9f4a2df06e7e041a msgid "Vector Store SETTINGS" msgstr "Vector Store SETTINGS" #: ../../getting_started/install/environment/environment.md:72 #: ../../getting_started/install/environment/environment.md:88 -#: 4dd04aadd46948a5b1dcf01fdb0ef074 bab7d512f33e40cf9e10f0da67e699c8 +#: 9cafa06e2d584f70afd848184e0fa52a f01057251b8b4ffea806192dfe1048ed msgid "Chroma" msgstr "Chroma" #: ../../getting_started/install/environment/environment.md:73 #: ../../getting_started/install/environment/environment.md:89 -#: 13eec36741b14e028e2d3859a320826e ab3ffbcf9358401993af636ba9ab2e2d +#: e6c16fab37484769b819aeecbc13e6db faad299722e5400e95ec6ac3c1e018b8 msgid "VECTOR_STORE_TYPE=Chroma" msgstr "VECTOR_STORE_TYPE=Chroma" #: ../../getting_started/install/environment/environment.md:74 #: ../../getting_started/install/environment/environment.md:90 -#: d15b91e2a2884f23a1dd2d54783b0638 d1f856d571b547098bb0c2a18f9f1979 +#: 4eca3a51716d406f8ffd49c06550e871 581ee9dd38064b119660c44bdd00cbaa msgid "MILVUS" msgstr "MILVUS" #: ../../getting_started/install/environment/environment.md:75 #: ../../getting_started/install/environment/environment.md:91 -#: 1e165f6c934343c7808459cc7a65bc70 985dd60c2b7d4baaa6601a810a6522d7 +#: 814c93048bed46589358a854d6c99683 b72b1269a2224f5f961214e41c019f21 msgid "VECTOR_STORE_TYPE=Milvus" msgstr "VECTOR_STORE_TYPE=Milvus" #: ../../getting_started/install/environment/environment.md:76 #: ../../getting_started/install/environment/environment.md:92 -#: a1a53f051cee40ed886346a94babd75a d263e8eaee684935a58f0a4fe61c6f0e +#: 73ae665f1db9402883662734588fd02c c4da20319c994e83ba5a7706db967178 msgid "MILVUS_URL=127.0.0.1" msgstr "MILVUS_URL=127.0.0.1" #: ../../getting_started/install/environment/environment.md:77 #: ../../getting_started/install/environment/environment.md:93 -#: 2741a312db1a4c6a8a1c1d62415c5fba d03bbf921ddd4f4bb715fe5610c3d0aa +#: e30c5288516d42aa858a485db50490c1 f843b2e58bcb4e4594e3c28499c341d0 msgid "MILVUS_PORT=19530" msgstr "MILVUS_PORT=19530" #: ../../getting_started/install/environment/environment.md:78 #: ../../getting_started/install/environment/environment.md:94 -#: d0786490d38c4e4f971cc14f62fe1fc8 e9e0854873dc4c209861ee4eb77d25cd +#: 158669efcc7d4bcaac1c8dd01b499029 24e88ffd32f242f281c56c0ec3ad2639 msgid "MILVUS_USERNAME" msgstr "MILVUS_USERNAME" #: ../../getting_started/install/environment/environment.md:79 #: ../../getting_started/install/environment/environment.md:95 -#: 9a82d07153cc432ebe754b5bc02fde0d a6485c1cfa7d4069a6894c43674c8c2b +#: 111a985297184c8aa5a0dd8e14a58445 6602093a6bb24d6792548e2392105c82 msgid "MILVUS_PASSWORD" msgstr "MILVUS_PASSWORD" #: ../../getting_started/install/environment/environment.md:80 #: ../../getting_started/install/environment/environment.md:96 -#: 2f233f32b8ba408a9fbadb21fabb99ec 809b3219dd824485bc2cfc898530d708 +#: 47bdfcd78fbe4ccdb5f49b717a6d01a6 b96c0545b2044926a8a8190caf94ad25 msgid "MILVUS_SECURE=" msgstr "MILVUS_SECURE=" #: ../../getting_started/install/environment/environment.md:82 #: ../../getting_started/install/environment/environment.md:98 -#: f00603661f2b42e1bd2bca74ad1e3c31 f378e16fdec44c559e34c6929de812e8 +#: 755c32b5d6c54607907a138b5474c0ec ff4f2a7ddaa14f089dda7a14e1062c36 msgid "WEAVIATE" msgstr "WEAVIATE" #: ../../getting_started/install/environment/environment.md:83 -#: da2049ebc6874cf0a6b562e0e2fd9ec7 +#: 23b2ce83385d40a589a004709f9864be msgid "VECTOR_STORE_TYPE=Weaviate" msgstr "VECTOR_STORE_TYPE=Weaviate" #: ../../getting_started/install/environment/environment.md:84 #: ../../getting_started/install/environment/environment.md:99 -#: 25f1246629934289aad7ef01c7304097 c9fe0e413d9a4fc8abf86b3ed99e0581 +#: 9acef304d89a448a9e734346705ba872 cf5151b6c1594ccd8beb1c3f77769acb msgid "WEAVIATE_URL=https://kt-region-m8hcy0wc.weaviate.network" msgstr "WEAVIATE_URL=https://kt-region-m8hcy0wc.weaviate.network" #: ../../getting_started/install/environment/environment.md:102 -#: ba7c9e707f6a4cd6b99e52b58da3ab2d +#: c3003516b2364051bf34f8c3086e348a msgid "Multi-GPU Setting" msgstr "Multi-GPU Setting" #: ../../getting_started/install/environment/environment.md:103 -#: 5ca75fdf2c264b2c844d77f659b4f0b3 +#: ade8fc381c5e438aa29d159c10041713 msgid "" "See https://developer.nvidia.com/blog/cuda-pro-tip-control-gpu-" "visibility-cuda_visible_devices/ If CUDA_VISIBLE_DEVICES is not " @@ -313,49 +315,49 @@ msgstr "" "cuda_visible_devices/ 如果 CUDA_VISIBLE_DEVICES没有设置, 会使用所有可用的gpu" #: ../../getting_started/install/environment/environment.md:106 -#: de92eb310aff43fbbbf3c5a116c3b2c6 +#: e137bd19be5e410ba6709027dbf2923a msgid "CUDA_VISIBLE_DEVICES=0" msgstr "CUDA_VISIBLE_DEVICES=0" #: ../../getting_started/install/environment/environment.md:108 -#: d2641df6123a442b8e4444ad5f01a9aa +#: 7669947acbdc4b1d92bcc029a8353a5d msgid "" "Optionally, you can also specify the gpu ID to use before the starting " "command" msgstr "你也可以通过启动命令设置gpu ID" #: ../../getting_started/install/environment/environment.md:110 -#: 76c66179d11a4e5fa369421378609aae +#: 751743d1753b4051beea46371278d793 msgid "CUDA_VISIBLE_DEVICES=3,4,5,6" msgstr "CUDA_VISIBLE_DEVICES=3,4,5,6" #: ../../getting_started/install/environment/environment.md:112 -#: 29bd0f01fdf540ad98385ea8473f7647 +#: 3acc3de0af0d4df2bb575e161e377f85 msgid "You can configure the maximum memory used by each GPU." msgstr "可以设置GPU的最大内存" #: ../../getting_started/install/environment/environment.md:114 -#: 31e5e23838734ba7a2810e2387e6d6a0 +#: 67f1d9b172b84294a44ecace5436e6e0 msgid "MAX_GPU_MEMORY=16Gib" msgstr "MAX_GPU_MEMORY=16Gib" #: ../../getting_started/install/environment/environment.md:117 -#: 99aa63ab1ae049d9b94536d6a96f3443 +#: 3c69dfe48bcf46b89b76cac1e7849a66 msgid "Other Setting" msgstr "Other Setting" #: ../../getting_started/install/environment/environment.md:118 -#: 3168732183874bffb59a3575d3473d62 +#: d5015b70f4fe4d20a63de9d87f86957a msgid "Language Settings(influence prompt language)" msgstr "Language Settings(涉及prompt语言以及知识切片方式)" #: ../../getting_started/install/environment/environment.md:119 -#: 73eb0a96f29b4739bd456faa9cb5033d +#: 5543c28bb8e34c9fb3bb6b063c2b1750 msgid "LANGUAGE=en" msgstr "LANGUAGE=en" #: ../../getting_started/install/environment/environment.md:120 -#: c6646b78c6cf4d25a13108232f5b2046 +#: cb4ed5b892ee41068c1ca76cb29aa400 msgid "LANGUAGE=zh" msgstr "LANGUAGE=zh" diff --git a/docs/locales/zh_CN/LC_MESSAGES/modules/knowledge.po b/docs/locales/zh_CN/LC_MESSAGES/modules/knowledge.po index 0b3eac094..bb2dae7af 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/modules/knowledge.po +++ b/docs/locales/zh_CN/LC_MESSAGES/modules/knowledge.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 0.3.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-13 15:39+0800\n" +"POT-Creation-Date: 2023-11-02 21:04+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -19,103 +19,84 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.12.1\n" -#: ../../modules/knowledge.rst:2 ../../modules/knowledge.rst:136 -#: 3cc8fa6e9fbd4d889603d99424e9529a +#: ../../modules/knowledge.md:1 b94b3b15cb2441ed9d78abd222a717b7 msgid "Knowledge" msgstr "知识" -#: ../../modules/knowledge.rst:4 0465a393d9d541958c39c1d07c885d1f +#: ../../modules/knowledge.md:3 c6d6e308a6ce42948d29e928136ef561 #, fuzzy msgid "" "As the knowledge base is currently the most significant user demand " "scenario, we natively support the construction and processing of " "knowledge bases. At the same time, we also provide multiple knowledge " -"base management strategies in this project, such as pdf knowledge,md " -"knowledge, txt knowledge, word knowledge, ppt knowledge:" +"base management strategies in this project, such as:" msgstr "" "由于知识库是当前用户需求最显著的场景,我们原生支持知识库的构建和处理。同时,我们还在本项目中提供了多种知识库管理策略,如:pdf,md , " "txt, word, ppt" -#: ../../modules/knowledge.rst:6 e670cbe14d8e4da88ba935e4120c31e0 -msgid "" -"We currently support many document formats: raw text, txt, pdf, md, html," -" doc, ppt, and url. In the future, we will continue to support more types" -" of knowledge, including audio, video, various databases, and big data " -"sources. Of course, we look forward to your active participation in " -"contributing code." +#: ../../modules/knowledge.md:4 268abc408d40410ba90cf5f121dc5270 +msgid "Default built-in knowledge base" msgstr "" -#: ../../modules/knowledge.rst:9 e0bf601a1a0c458297306db6ff79f931 -msgid "**Create your own knowledge repository**" +#: ../../modules/knowledge.md:5 558c3364c38b458a8ebf81030efc2a48 +msgid "Custom addition of knowledge bases" +msgstr "" + +#: ../../modules/knowledge.md:6 9cb3ce62da1440579c095848c7aef88c +msgid "" +"Various usage scenarios such as constructing knowledge bases through " +"plugin capabilities and web crawling. Users only need to organize the " +"knowledge documents, and they can use our existing capabilities to build " +"the knowledge base required for the large model." +msgstr "" + +#: ../../modules/knowledge.md:9 b8ca6bc4dd9845baa56e36eea7fac2a2 +#, fuzzy +msgid "Create your own knowledge repository" msgstr "创建你自己的知识库" -#: ../../modules/knowledge.rst:11 bb26708135d44615be3c1824668010f6 -msgid "1.prepare" -msgstr "准备" +#: ../../modules/knowledge.md:11 17d7178a67924f43aa5b6293707ef041 +msgid "" +"1.Place personal knowledge files or folders in the pilot/datasets " +"directory." +msgstr "" -#: ../../modules/knowledge.rst:13 c150a0378f3e4625908fa0d8a25860e9 +#: ../../modules/knowledge.md:13 31c31f14bf444981939689f9a9fb038a #, fuzzy msgid "" -"We currently support many document formats: TEXT(raw text), " -"DOCUMENT(.txt, .pdf, .md, .doc, .ppt, .html), and URL." +"We currently support many document formats: txt, pdf, md, html, doc, ppt," +" and url." msgstr "当前支持txt, pdf, md, html, doc, ppt, url文档格式" -#: ../../modules/knowledge.rst:15 7f9f02a93d5d4325b3d2d976f4bb28a0 +#: ../../modules/knowledge.md:15 9ad2f2e05f8842a9b9d8469a3704df23 msgid "before execution:" msgstr "开始前" -#: ../../modules/knowledge.rst:24 59699a8385e04982a992cf0d71f6dcd5 -#, fuzzy +#: ../../modules/knowledge.md:22 6fd2775914b641c4b8e486417b558ea6 msgid "" -"2.prepare embedding model, you can download from https://huggingface.co/." -" Notice you have installed git-lfs." +"2.Update your .env, set your vector store type, VECTOR_STORE_TYPE=Chroma " +"(now only support Chroma and Milvus, if you set Milvus, please set " +"MILVUS_URL and MILVUS_PORT)" msgstr "" -"提前准备Embedding Model, 你可以在https://huggingface.co/进行下载,注意:你需要先安装git-lfs.eg:" -" git clone https://huggingface.co/THUDM/chatglm2-6b" -#: ../../modules/knowledge.rst:27 2be1a17d0b54476b9dea080d244fd747 -msgid "" -"eg: git clone https://huggingface.co/sentence-transformers/all-" -"MiniLM-L6-v2" -msgstr "eg: git clone https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2" - -#: ../../modules/knowledge.rst:33 d328f6e243624c9488ebd27c9324621b -msgid "" -"3.prepare vector_store instance and vector store config, now we support " -"Chroma, Milvus and Weaviate." -msgstr "提前准备向量数据库环境,目前支持Chroma, Milvus and Weaviate向量数据库" - -#: ../../modules/knowledge.rst:63 44f97154eff647d399fd30b6f9e3b867 -msgid "" -"3.init Url Type EmbeddingEngine api and embedding your document into " -"vector store in your code." -msgstr "初始化 Url类型 EmbeddingEngine api, 将url文档embedding向量化到向量数据库 " - -#: ../../modules/knowledge.rst:75 e2581b414f0148bca88253c7af9cd591 -msgid "If you want to add your source_reader or text_splitter, do this:" -msgstr "如果你想手动添加你自定义的source_reader和text_splitter, 请参考:" - -#: ../../modules/knowledge.rst:95 74c110414f924bbfa3d512e45ba2f30f -#, fuzzy -msgid "" -"4.init Document Type EmbeddingEngine api and embedding your document into" -" vector store in your code. Document type can be .txt, .pdf, .md, .doc, " -".ppt." +#: ../../modules/knowledge.md:25 131c5f58898a4682940910980edb2043 +msgid "2.Run the knowledge repository initialization command" msgstr "" -"初始化 文档型类型 EmbeddingEngine api, 将文档embedding向量化到向量数据库(文档可以是.txt, .pdf, " -".md, .html, .doc, .ppt)" -#: ../../modules/knowledge.rst:108 0afd40098d5f4dfd9e44fe1d8004da25 +#: ../../modules/knowledge.md:31 2cf550f17881497bb881b19efcc18c23 msgid "" -"5.init TEXT Type EmbeddingEngine api and embedding your document into " -"vector store in your code." -msgstr "初始化TEXT类型 EmbeddingEngine api, 将文档embedding向量化到向量数据库" +"Optionally, you can run `dbgpt knowledge load --help` command to see more" +" usage." +msgstr "" -#: ../../modules/knowledge.rst:120 a66961bf3efd41fa8ea938129446f5a5 -msgid "4.similar search based on your knowledge base. ::" -msgstr "在知识库进行相似性搜索" +#: ../../modules/knowledge.md:33 c8a2ea571b944bdfbcad48fa8b54fcc9 +msgid "" +"3.Add the knowledge repository in the interface by entering the name of " +"your knowledge repository (if not specified, enter \"default\") so you " +"can use it for Q&A based on your knowledge base." +msgstr "" -#: ../../modules/knowledge.rst:126 b7066f408378450db26770f83fbd2716 +#: ../../modules/knowledge.md:35 b701170ad75e49dea7d7734c15681e0f msgid "" "Note that the default vector model used is text2vec-large-chinese (which " "is a large model, so if your personal computer configuration is not " @@ -125,48 +106,6 @@ msgstr "" "注意,这里默认向量模型是text2vec-large-chinese(模型比较大,如果个人电脑配置不够建议采用text2vec-base-" "chinese),因此确保需要将模型download下来放到models目录中。" -#: ../../modules/knowledge.rst:128 58481d55cab74936b6e84b24c39b1674 -#, fuzzy -msgid "" -"`pdf_embedding <./knowledge/pdf/pdf_embedding.html>`_: supported pdf " -"embedding." -msgstr "pdf_embedding <./knowledge/pdf_embedding.html>`_: supported pdf embedding." - -#: ../../modules/knowledge.rst:129 fbb013c4f1bc46af910c91292f6690cf -#, fuzzy -msgid "" -"`markdown_embedding <./knowledge/markdown/markdown_embedding.html>`_: " -"supported markdown embedding." -msgstr "pdf_embedding <./knowledge/pdf_embedding.html>`_: supported pdf embedding." - -#: ../../modules/knowledge.rst:130 59d45732f4914d16b4e01aee0992edf7 -#, fuzzy -msgid "" -"`word_embedding <./knowledge/word/word_embedding.html>`_: supported word " -"embedding." -msgstr "pdf_embedding <./knowledge/pdf_embedding.html>`_: supported pdf embedding." - -#: ../../modules/knowledge.rst:131 df0e6f311861423e885b38e020a7c0f0 -#, fuzzy -msgid "" -"`url_embedding <./knowledge/url/url_embedding.html>`_: supported url " -"embedding." -msgstr "pdf_embedding <./knowledge/pdf_embedding.html>`_: supported pdf embedding." - -#: ../../modules/knowledge.rst:132 7c550c1f5bc34fe9986731fb465e12cd -#, fuzzy -msgid "" -"`ppt_embedding <./knowledge/ppt/ppt_embedding.html>`_: supported ppt " -"embedding." -msgstr "pdf_embedding <./knowledge/pdf_embedding.html>`_: supported pdf embedding." - -#: ../../modules/knowledge.rst:133 8648684cb191476faeeb548389f79050 -#, fuzzy -msgid "" -"`string_embedding <./knowledge/string/string_embedding.html>`_: supported" -" raw text embedding." -msgstr "pdf_embedding <./knowledge/pdf_embedding.html>`_: supported pdf embedding." - #~ msgid "before execution: python -m spacy download zh_core_web_sm" #~ msgstr "在执行之前请先执行python -m spacy download zh_core_web_sm" @@ -201,3 +140,112 @@ msgstr "pdf_embedding <./knowledge/pdf_embedding.html>`_: supported pdf embeddin #~ "and MILVUS_PORT)" #~ msgstr "2.更新你的.env,设置你的向量存储类型,VECTOR_STORE_TYPE=Chroma(现在只支持Chroma和Milvus,如果你设置了Milvus,请设置MILVUS_URL和MILVUS_PORT)" +#~ msgid "" +#~ "We currently support many document " +#~ "formats: raw text, txt, pdf, md, " +#~ "html, doc, ppt, and url. In the" +#~ " future, we will continue to support" +#~ " more types of knowledge, including " +#~ "audio, video, various databases, and big" +#~ " data sources. Of course, we look " +#~ "forward to your active participation in" +#~ " contributing code." +#~ msgstr "" + +#~ msgid "1.prepare" +#~ msgstr "准备" + +#~ msgid "" +#~ "2.prepare embedding model, you can " +#~ "download from https://huggingface.co/. Notice " +#~ "you have installed git-lfs." +#~ msgstr "" +#~ "提前准备Embedding Model, 你可以在https://huggingface.co/进行下载,注意" +#~ ":你需要先安装git-lfs.eg: git clone " +#~ "https://huggingface.co/THUDM/chatglm2-6b" + +#~ msgid "" +#~ "eg: git clone https://huggingface.co/sentence-" +#~ "transformers/all-MiniLM-L6-v2" +#~ msgstr "" +#~ "eg: git clone https://huggingface.co/sentence-" +#~ "transformers/all-MiniLM-L6-v2" + +#~ msgid "" +#~ "3.prepare vector_store instance and vector " +#~ "store config, now we support Chroma, " +#~ "Milvus and Weaviate." +#~ msgstr "提前准备向量数据库环境,目前支持Chroma, Milvus and Weaviate向量数据库" + +#~ msgid "" +#~ "3.init Url Type EmbeddingEngine api and" +#~ " embedding your document into vector " +#~ "store in your code." +#~ msgstr "初始化 Url类型 EmbeddingEngine api, 将url文档embedding向量化到向量数据库 " + +#~ msgid "If you want to add your source_reader or text_splitter, do this:" +#~ msgstr "如果你想手动添加你自定义的source_reader和text_splitter, 请参考:" + +#~ msgid "" +#~ "4.init Document Type EmbeddingEngine api " +#~ "and embedding your document into vector" +#~ " store in your code. Document type" +#~ " can be .txt, .pdf, .md, .doc, " +#~ ".ppt." +#~ msgstr "" +#~ "初始化 文档型类型 EmbeddingEngine api, " +#~ "将文档embedding向量化到向量数据库(文档可以是.txt, .pdf, .md, .html," +#~ " .doc, .ppt)" + +#~ msgid "" +#~ "5.init TEXT Type EmbeddingEngine api and" +#~ " embedding your document into vector " +#~ "store in your code." +#~ msgstr "初始化TEXT类型 EmbeddingEngine api, 将文档embedding向量化到向量数据库" + +#~ msgid "4.similar search based on your knowledge base. ::" +#~ msgstr "在知识库进行相似性搜索" + +#~ msgid "" +#~ "`pdf_embedding <./knowledge/pdf/pdf_embedding.html>`_: " +#~ "supported pdf embedding." +#~ msgstr "" +#~ "pdf_embedding <./knowledge/pdf_embedding.html>`_: " +#~ "supported pdf embedding." + +#~ msgid "" +#~ "`markdown_embedding " +#~ "<./knowledge/markdown/markdown_embedding.html>`_: supported " +#~ "markdown embedding." +#~ msgstr "" +#~ "pdf_embedding <./knowledge/pdf_embedding.html>`_: " +#~ "supported pdf embedding." + +#~ msgid "" +#~ "`word_embedding <./knowledge/word/word_embedding.html>`_: " +#~ "supported word embedding." +#~ msgstr "" +#~ "pdf_embedding <./knowledge/pdf_embedding.html>`_: " +#~ "supported pdf embedding." + +#~ msgid "" +#~ "`url_embedding <./knowledge/url/url_embedding.html>`_: " +#~ "supported url embedding." +#~ msgstr "" +#~ "pdf_embedding <./knowledge/pdf_embedding.html>`_: " +#~ "supported pdf embedding." + +#~ msgid "" +#~ "`ppt_embedding <./knowledge/ppt/ppt_embedding.html>`_: " +#~ "supported ppt embedding." +#~ msgstr "" +#~ "pdf_embedding <./knowledge/pdf_embedding.html>`_: " +#~ "supported pdf embedding." + +#~ msgid "" +#~ "`string_embedding <./knowledge/string/string_embedding.html>`_:" +#~ " supported raw text embedding." +#~ msgstr "" +#~ "pdf_embedding <./knowledge/pdf_embedding.html>`_: " +#~ "supported pdf embedding." + From 9cc638630119f5c65ad5a401f537317089b3346c Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Fri, 3 Nov 2023 10:24:49 +0800 Subject: [PATCH 39/57] doc:update deploy doc --- docs/conf.py | 18 +- docs/getting_started/install.rst | 2 +- docs/getting_started/install/deploy.rst | 438 ++++++++++++++++++ .../install/environment/environment.po | 136 +++--- .../zh_CN/LC_MESSAGES/modules/knowledge.po | 264 ++++++----- docs/requirements.txt | 2 +- 6 files changed, 682 insertions(+), 178 deletions(-) create mode 100644 docs/getting_started/install/deploy.rst diff --git a/docs/conf.py b/docs/conf.py index 539153e4c..8601627ca 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -30,10 +30,24 @@ extensions = [ "myst_nb", "sphinx_copybutton", "sphinx_panels", + "sphinx_tabs.tabs", "IPython.sphinxext.ipython_console_highlighting", + 'sphinx.ext.autosectionlabel' ] source_suffix = [".ipynb", ".html", ".md", ".rst"] + +myst_enable_extensions = [ + "dollarmath", + "amsmath", + "deflist", + "html_admonition", + "html_image", + "colon_fence", + "smartquotes", + "replacements", +] + # autodoc_pydantic_model_show_json = False # autodoc_pydantic_field_list_validators = False # autodoc_pydantic_config_members = False @@ -56,5 +70,7 @@ gettext_uuid = True # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_theme = "furo" +html_theme = "sphinx_book_theme" + + html_static_path = ["_static"] diff --git a/docs/getting_started/install.rst b/docs/getting_started/install.rst index d6e6a15f8..645467e9e 100644 --- a/docs/getting_started/install.rst +++ b/docs/getting_started/install.rst @@ -18,7 +18,7 @@ DB-GPT product is a Web application that you can chat database, chat knowledge, :name: deploy :hidden: - ./install/deploy/deploy.md + ./install/deploy.rst ./install/docker/docker.md ./install/docker_compose/docker_compose.md ./install/cluster/cluster.rst diff --git a/docs/getting_started/install/deploy.rst b/docs/getting_started/install/deploy.rst new file mode 100644 index 000000000..2c6b26b84 --- /dev/null +++ b/docs/getting_started/install/deploy.rst @@ -0,0 +1,438 @@ +.. _installation: + +Installation From Source +============== + +To get started, install DB-GPT with the following steps. + +DB-GPT can be deployed on servers with low hardware requirements or on servers with high hardware requirements. +You can install DB-GPT by Using third-part LLM REST API Service OpenAI, Azure. + +And you can also install DB-GPT by deploy LLM Service by download LLM model. + + +1.Preparation +----------------- +**Download DB-GPT** + +.. code-block:: shell + + git clone https://github.com/eosphoros-ai/DB-GPT.git + +**Install Miniconda** + +We use Sqlite as default database, so there is no need for database installation. If you choose to connect to other databases, you can follow our tutorial for installation and configuration. +For the entire installation process of DB-GPT, we use the miniconda3 virtual environment. Create a virtual environment and install the Python dependencies. +:ref: `https://docs.conda.io/en/latest/miniconda.html` + +.. code-block:: shell + + python>=3.10 + conda create -n dbgpt_env python=3.10 + conda activate dbgpt_env + # it will take some minutes + pip install -e ".[default]" + +.. code-block:: shell + + cp .env.template .env + +2.Deploy LLM Service +----------------- +DB-GPT can be deployed on servers with low hardware requirements or on servers with high hardware requirements. + +If you are low hardware requirements you can install DB-GPT by Using third-part LLM REST API Service OpenAI, Azure, tongyi. + +.. tabs:: + + .. tab:: OpenAI + + Download embedding model + + .. code-block:: shell + + cd DB-GPT + mkdir models and cd models + + #### embedding model + git clone https://huggingface.co/GanymedeNil/text2vec-large-chinese + or + git clone https://huggingface.co/moka-ai/m3e-large + + Configure LLM_MODEL and PROXY_API_URL and API_KEY in `.env` file + + .. code-block:: shell + + LLM_MODEL=chatgpt_proxyllm + PROXY_API_KEY={your-openai-sk} + PROXY_SERVER_URL=https://api.openai.com/v1/chat/completions + + .. tip:: + + Make sure your .env configuration is not overwritten + + + .. tab:: Vicuna + ([Vicuna-v1.5](https://huggingface.co/lmsys/vicuna-13b-v1.5) based on llama-2 has been released, we recommend you set `LLM_MODEL=vicuna-13b-v1.5` to try this model) + + .. list-table:: vicuna-v1.5 hardware requirements + :widths: 50 50 50 + :header-rows: 1 + + * - Model + - Quantize + - VRAM Size + * - vicuna-7b-v1.5 + - 4-bit + - 8 GB + * - vicuna-7b-v1.5 + - 8-bit + - 12 GB + * - vicuna-13b-v1.5 + - 4-bit + - 12 GB + * - vicuna-13b-v1.5 + - 8-bit + - 20 GB + + + .. note:: + + Notice make sure you have install git-lfs + + centos:yum install git-lfs + + ubuntu:apt-get install git-lfs + + macos:brew install git-lfs + + + .. code-block:: shell + + cd DB-GPT + mkdir models and cd models + + #### embedding model + git clone https://huggingface.co/GanymedeNil/text2vec-large-chinese + or + git clone https://huggingface.co/moka-ai/m3e-large + + #### llm model, if you use openai or Azure or tongyi llm api service, you don't need to download llm model + git clone https://huggingface.co/lmsys/vicuna-13b-v1.5 + + The model files are large and will take a long time to download. + + **Configure LLM_MODEL in `.env` file** + + + .. code-block:: shell + + LLM_MODEL=vicuna-13b-v1.5 + + .. tab:: Baichuan + + .. list-table:: Baichuan hardware requirements + :widths: 50 50 50 + :header-rows: 1 + + * - Model + - Quantize + - VRAM Size + * - baichuan-7b + - 4-bit + - 8 GB + * - baichuan-7b + - 8-bit + - 12 GB + * - baichuan-13b + - 4-bit + - 12 GB + * - baichuan-13b + - 8-bit + - 20 GB + + .. note:: + + Notice make sure you have install git-lfs + + centos:yum install git-lfs + + ubuntu:apt-get install git-lfs + + macos:brew install git-lfs + + + .. code-block:: shell + + cd DB-GPT + mkdir models and cd models + + #### embedding model + git clone https://huggingface.co/GanymedeNil/text2vec-large-chinese + or + git clone https://huggingface.co/moka-ai/m3e-large + + #### llm model + git clone https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat + or + git clone https://huggingface.co/baichuan-inc/Baichuan2-13B-Chat + + The model files are large and will take a long time to download. + + **Configure LLM_MODEL in `.env` file** + + please rename Baichuan path to "baichuan2-13b" or "baichuan2-7b" + + .. code-block:: shell + + LLM_MODEL=baichuan2-13b + + .. tab:: ChatGLM + + .. note:: + + Notice make sure you have install git-lfs + + centos:yum install git-lfs + + ubuntu:apt-get install git-lfs + + macos:brew install git-lfs + + + .. code-block:: shell + + cd DB-GPT + mkdir models and cd models + + #### embedding model + git clone https://huggingface.co/GanymedeNil/text2vec-large-chinese + or + git clone https://huggingface.co/moka-ai/m3e-large + + #### llm model + git clone https://huggingface.co/THUDM/chatglm2-6b + + The model files are large and will take a long time to download. + + **Configure LLM_MODEL in `.env` file** + + please rename chatglm model path to "chatglm2-6b" + + .. code-block:: shell + + LLM_MODEL=chatglm2-6b + + .. tab:: Other LLM API + + Download embedding model + + .. code-block:: shell + + cd DB-GPT + mkdir models and cd models + + #### embedding model + git clone https://huggingface.co/GanymedeNil/text2vec-large-chinese + or + git clone https://huggingface.co/moka-ai/m3e-large + + .. note:: + + * OpenAI + * Azure + * Aliyun tongyi + * Baidu wenxin + * Zhipu + * Baichuan + * Bard + + Configure LLM_MODEL and PROXY_API_URL and API_KEY in `.env` file + + .. code-block:: shell + + #OpenAI + LLM_MODEL=chatgpt_proxyllm + PROXY_API_KEY={your-openai-sk} + PROXY_SERVER_URL=https://api.openai.com/v1/chat/completions + + #Azure + LLM_MODEL=chatgpt_proxyllm + PROXY_API_KEY={your-azure-sk} + PROXY_API_BASE=https://{your domain}.openai.azure.com/ + PROXY_API_TYPE=azure + PROXY_SERVER_URL=xxxx + PROXY_API_VERSION=2023-05-15 + PROXYLLM_BACKEND=gpt-35-turbo + + #Aliyun tongyi + LLM_MODEL=tongyi_proxyllm + TONGYI_PROXY_API_KEY={your-tongyi-sk} + PROXY_SERVER_URL={your_service_url} + + ## Baidu wenxin + LLM_MODEL=wenxin_proxyllm + PROXY_SERVER_URL={your_service_url} + WEN_XIN_MODEL_VERSION={version} + WEN_XIN_API_KEY={your-wenxin-sk} + WEN_XIN_SECRET_KEY={your-wenxin-sct} + + ## Zhipu + LLM_MODEL=zhipu_proxyllm + PROXY_SERVER_URL={your_service_url} + ZHIPU_MODEL_VERSION={version} + ZHIPU_PROXY_API_KEY={your-zhipu-sk} + + ## Baichuan + LLM_MODEL=bc_proxyllm + PROXY_SERVER_URL={your_service_url} + BAICHUN_MODEL_NAME={version} + BAICHUAN_PROXY_API_KEY={your-baichuan-sk} + BAICHUAN_PROXY_API_SECRET={your-baichuan-sct} + + ## bard + LLM_MODEL=bard_proxyllm + PROXY_SERVER_URL={your_service_url} + # from https://bard.google.com/ f12-> application-> __Secure-1PSID + BARD_PROXY_API_KEY={your-bard-token} + + .. tip:: + + Make sure your .env configuration is not overwritten + + .. tab:: llama.cpp + + DB-GPT already supports [llama.cpp](https://github.com/ggerganov/llama.cpp) via [llama-cpp-python](https://github.com/abetlen/llama-cpp-python). + + **Preparing Model Files** + + To use llama.cpp, you need to prepare a gguf format model file, and there are two common ways to obtain it, you can choose either: + + **1. Download a pre-converted model file.** + + Suppose you want to use [Vicuna 13B v1.5](https://huggingface.co/lmsys/vicuna-13b-v1.5), you can download the file already converted from [TheBloke/vicuna-13B-v1.5-GGUF](https://huggingface.co/TheBloke/vicuna-13B-v1.5-GGUF), only one file is needed. Download it to the `models` directory and rename it to `ggml-model-q4_0.gguf`. + + .. code-block:: + + wget https://huggingface.co/TheBloke/vicuna-13B-v1.5-GGUF/resolve/main/vicuna-13b-v1.5.Q4_K_M.gguf -O models/ggml-model-q4_0.gguf + + **2. Convert It Yourself** + + You can convert the model file yourself according to the instructions in [llama.cpp#prepare-data--run](https://github.com/ggerganov/llama.cpp#prepare-data--run), and put the converted file in the models directory and rename it to `ggml-model-q4_0.gguf`. + + **Installing Dependencies** + + llama.cpp is an optional dependency in DB-GPT, and you can manually install it using the following command: + + .. code-block:: + + pip install -e ".[llama_cpp]" + + + **3.Modifying the Configuration File** + + Next, you can directly modify your `.env` file to enable llama.cpp. + + .. code-block:: + + LLM_MODEL=llama-cpp + llama_cpp_prompt_template=vicuna_v1.1 + + Then you can run it according to [Run](https://db-gpt.readthedocs.io/en/latest/getting_started/install/deploy/deploy.html#run). + + + **More Configurations** + + In DB-GPT, the model configuration can be done through `{model name}_{config key}`. + + .. list-table:: More Configurations + :widths: 50 50 50 + :header-rows: 1 + + * - Environment Variable Key + - Default + - Description + * - llama_cpp_prompt_template + - None + - Prompt template name, now support: zero_shot, vicuna_v1.1,alpaca,llama-2,baichuan-chat,internlm-chat, If None, the prompt template is automatically determined from model path。 + * - llama_cpp_model_path + - None + - Model path + * - llama_cpp_n_gpu_layers + - 1000000000 + - Number of layers to offload to the GPU, Set this to 1000000000 to offload all layers to the GPU. If your GPU VRAM is not enough, you can set a low number, eg: 10 + * - llama_cpp_n_threads + - None + - Number of threads to use. If None, the number of threads is automatically determined + * - llama_cpp_n_batch + - 512 + - Maximum number of prompt tokens to batch together when calling llama_eval + * - llama_cpp_n_gqa + - None + - Grouped-query attention. Must be 8 for llama-2 70b. + * - llama_cpp_rms_norm_eps + - 5e-06 + - 5e-6 is a good value for llama-2 models. + * - llama_cpp_cache_capacity + - None + - Maximum cache capacity. Examples: 2000MiB, 2GiB + * - llama_cpp_prefer_cpu + - False + - If a GPU is available, it will be preferred by default, unless prefer_cpu=False is configured. + + + .. tab:: vllm + + vLLM is a fast and easy-to-use library for LLM inference and serving. + + **Running vLLM** + + **1.Installing Dependencies** + + vLLM is an optional dependency in DB-GPT, and you can manually install it using the following command: + + .. code-block:: + + pip install -e ".[vllm]" + + **2.Modifying the Configuration File** + + Next, you can directly modify your .env file to enable vllm. + + .. code-block:: + + LLM_MODEL=vicuna-13b-v1.5 + MODEL_TYPE=vllm + + + + + + + + +3.Prepare sql example(Optional) +----------------- +**(Optional) load examples into SQLite** + + .. code-block:: shell + + bash ./scripts/examples/load_examples.sh + + + On windows platform: + + .. code-block:: shell + + .\scripts\examples\load_examples.bat + +4.Run db-gpt server +----------------- + + .. code-block:: shell + + + python pilot/server/dbgpt_server.py + +**Open http://localhost:5000 with your browser to see the product.** + diff --git a/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/environment/environment.po b/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/environment/environment.po index 09b3c8fa2..1f448ee4e 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/environment/environment.po +++ b/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/environment/environment.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 👏👏 0.3.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-17 13:07+0800\n" +"POT-Creation-Date: 2023-11-02 10:10+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -20,290 +20,292 @@ msgstr "" "Generated-By: Babel 2.12.1\n" #: ../../getting_started/install/environment/environment.md:1 -#: be341d16f7b24bf4ad123ab78a6d855a +#: 28d2f84fc8884e78afad8118cd59c654 #, fuzzy msgid "Environment Parameter" msgstr "环境变量说明" #: ../../getting_started/install/environment/environment.md:4 -#: 46eddb27c90f41548ea9a724bbcebd37 +#: c83fbb5e1aa643cdb09fffe7f3d1a3c5 msgid "LLM MODEL Config" msgstr "模型配置" #: ../../getting_started/install/environment/environment.md:5 -#: 7deaa85df4a04fb098f5994547a8724f +#: eb675965ae57407e8d8bf90fed8e9e2a msgid "LLM Model Name, see /pilot/configs/model_config.LLM_MODEL_CONFIG" msgstr "LLM Model Name, see /pilot/configs/model_config.LLM_MODEL_CONFIG" #: ../../getting_started/install/environment/environment.md:6 -#: 3902801c546547b3a4009df681ef7d52 +#: 5d28d35126d849ea9b0d963fd1ba8699 msgid "LLM_MODEL=vicuna-13b" msgstr "LLM_MODEL=vicuna-13b" #: ../../getting_started/install/environment/environment.md:8 -#: 84b0fdbfa1544ec28751e9b69b00cc02 +#: 01955b2d0fbe4d94939ebf2cbb380bdd msgid "MODEL_SERVER_ADDRESS" msgstr "MODEL_SERVER_ADDRESS" #: ../../getting_started/install/environment/environment.md:9 -#: 0b430bfab77d405989470d00ca3f6fe0 +#: 4eaaa9ab59854c0386b28b3111c82784 msgid "MODEL_SERVER=http://127.0.0.1:8000 LIMIT_MODEL_CONCURRENCY" msgstr "MODEL_SERVER=http://127.0.0.1:8000 LIMIT_MODEL_CONCURRENCY" #: ../../getting_started/install/environment/environment.md:12 -#: b477a25586c546729a93fb6785b7b2ec +#: 5c2dd05e16834443b7451c2541b59757 msgid "LIMIT_MODEL_CONCURRENCY=5" msgstr "LIMIT_MODEL_CONCURRENCY=5" #: ../../getting_started/install/environment/environment.md:14 -#: 1d6ea800af384fff9c265610f71cc94e +#: 7707836c2fb04e7da13d2d59b5f9566f msgid "MAX_POSITION_EMBEDDINGS" msgstr "MAX_POSITION_EMBEDDINGS" #: ../../getting_started/install/environment/environment.md:16 -#: 388e758ce4ea4692a4c34294cebce7f2 +#: ee24a7d3d8384e61b715ef3bd362b965 msgid "MAX_POSITION_EMBEDDINGS=4096" msgstr "MAX_POSITION_EMBEDDINGS=4096" #: ../../getting_started/install/environment/environment.md:18 -#: 16a307dce1294ceba892ff93ae4e81c0 +#: 90b51aa4e46b4d1298c672e0052c2f68 msgid "QUANTIZE_QLORA" msgstr "QUANTIZE_QLORA" #: ../../getting_started/install/environment/environment.md:20 -#: 93ceb2b2fcd5454b82eefb0ae8c7ae77 +#: 7de7a8eb431e4973ae00f68ca0686281 msgid "QUANTIZE_QLORA=True" msgstr "QUANTIZE_QLORA=True" #: ../../getting_started/install/environment/environment.md:22 -#: 15ffa35d023a4530b02a85ee6168dd4b +#: e331ca016a474f4aa4e9182165a2693a msgid "QUANTIZE_8bit" msgstr "QUANTIZE_8bit" #: ../../getting_started/install/environment/environment.md:24 -#: 81df248ac5cb4ab0b13a711505f6a177 +#: 519ccce5a0884778be2719c437a17bd4 msgid "QUANTIZE_8bit=True" msgstr "QUANTIZE_8bit=True" #: ../../getting_started/install/environment/environment.md:27 -#: 15cc7b7d41ad44f0891c1189709f00f1 +#: 1c0586d070f046de8d0f9f94a6b508b4 msgid "LLM PROXY Settings" msgstr "LLM PROXY Settings" #: ../../getting_started/install/environment/environment.md:28 -#: e6c1115a39404f11b193a1593bc51a22 +#: c208c3f4b13f4b39962de814e5be6ab9 msgid "OPENAI Key" msgstr "OPENAI Key" #: ../../getting_started/install/environment/environment.md:30 -#: 8157e0a831fe4506a426822b7565e4f6 +#: 9228bbee2faa4467b1d24f1125faaac8 msgid "PROXY_API_KEY={your-openai-sk}" msgstr "PROXY_API_KEY={your-openai-sk}" #: ../../getting_started/install/environment/environment.md:31 -#: 89b34d00bdb64e738bd9bc8c086b1f02 +#: 759ae581883348019c1ba79e8954728a msgid "PROXY_SERVER_URL=https://api.openai.com/v1/chat/completions" msgstr "PROXY_SERVER_URL=https://api.openai.com/v1/chat/completions" #: ../../getting_started/install/environment/environment.md:33 -#: 7a97df730aeb484daf19c8172e61a290 +#: 83f3952917d34aab80bd34119f7d1e20 msgid "from https://bard.google.com/ f12-> application-> __Secure-1PSID" msgstr "from https://bard.google.com/ f12-> application-> __Secure-1PSID" #: ../../getting_started/install/environment/environment.md:35 -#: d430ddf726a049c0a9e0a9bfd5a6fe0e +#: 1d70707ca82749bb90b2bed1aee44d62 msgid "BARD_PROXY_API_KEY={your-bard-token}" msgstr "BARD_PROXY_API_KEY={your-bard-token}" #: ../../getting_started/install/environment/environment.md:38 -#: 23d6b0da3e7042abb55f6181c4a382d2 +#: 38a2091fa223493ea23cb9bbb33cf58e msgid "DATABASE SETTINGS" msgstr "DATABASE SETTINGS" #: ../../getting_started/install/environment/environment.md:39 -#: dbae0a2d847f41f5be9396a160ef88d0 +#: 5134180d7a5945b48b072a1eb92b27ba msgid "SQLite database (Current default database)" msgstr "SQLite database (Current default database)" #: ../../getting_started/install/environment/environment.md:40 -#: bdb55b7280c341a981e9d338cce53345 +#: 6875e2300e094668a45fa4f2551e0d30 msgid "LOCAL_DB_PATH=data/default_sqlite.db" msgstr "LOCAL_DB_PATH=data/default_sqlite.db" #: ../../getting_started/install/environment/environment.md:41 -#: 739d67927a9d46b28500deba1917916b +#: 034e8f06f24f44af9d8184563f99b4b3 msgid "LOCAL_DB_TYPE=sqlite # Database Type default:sqlite" msgstr "LOCAL_DB_TYPE=sqlite # Database Type default:sqlite" #: ../../getting_started/install/environment/environment.md:43 -#: eb4717bce6a6483b86d9780d924c5ff1 +#: f688149a97f740269f80b79775236ce9 msgid "MYSQL database" msgstr "MYSQL database" #: ../../getting_started/install/environment/environment.md:44 -#: 0f4cdf0ff5dd4ff0b397dfa88541a2e1 +#: 6db0b305137d45a3aa036e4f2262f460 msgid "LOCAL_DB_TYPE=mysql" msgstr "LOCAL_DB_TYPE=mysql" #: ../../getting_started/install/environment/environment.md:45 -#: c971ead492c34487bd766300730a9cba +#: b6d662ce8d5f44f0b54a7f6e7c66f5a5 msgid "LOCAL_DB_USER=root" msgstr "LOCAL_DB_USER=root" #: ../../getting_started/install/environment/environment.md:46 -#: 02828b29ad044eeab890a2f8af0e5907 +#: cd7493d61ac9415283640dc6c018d2f4 msgid "LOCAL_DB_PASSWORD=aa12345678" msgstr "LOCAL_DB_PASSWORD=aa12345678" #: ../../getting_started/install/environment/environment.md:47 -#: 53dc7f15b3934987b1f4c2e2d0b11299 +#: 4ea2a622b23f4342a4c2ab7f8d9c4e8d msgid "LOCAL_DB_HOST=127.0.0.1" msgstr "LOCAL_DB_HOST=127.0.0.1" #: ../../getting_started/install/environment/environment.md:48 -#: 1ac95fc482934247a118bab8dcebeb57 +#: 936db95a0ab246098028f4dbb596cd17 msgid "LOCAL_DB_PORT=3306" msgstr "LOCAL_DB_PORT=3306" #: ../../getting_started/install/environment/environment.md:51 -#: 34e46aa926844be19c7196759b03af63 +#: d9255f25989840ea9c9e7b34f3947c87 msgid "EMBEDDING SETTINGS" msgstr "EMBEDDING SETTINGS" #: ../../getting_started/install/environment/environment.md:52 -#: 2b5aa08cc995495e85a1f7dc4f97b5d7 +#: b09291d32aca43928a981e873476a985 msgid "EMBEDDING MODEL Name, see /pilot/configs/model_config.LLM_MODEL_CONFIG" msgstr "EMBEDDING模型, 参考see /pilot/configs/model_config.LLM_MODEL_CONFIG" #: ../../getting_started/install/environment/environment.md:53 -#: 0de0ca551ed040248406f848feca541d +#: 63de573b03a54413b997f18a1ccee279 msgid "EMBEDDING_MODEL=text2vec" msgstr "EMBEDDING_MODEL=text2vec" #: ../../getting_started/install/environment/environment.md:55 -#: 43019fb570904c9981eb68f33e64569c +#: 0ef8defbab544bd0b9475a036f278489 msgid "Embedding Chunk size, default 500" msgstr "Embedding 切片大小, 默认500" #: ../../getting_started/install/environment/environment.md:57 -#: 7e3f93854873461286e96887e04167aa +#: 33dbc7941d054baa8c6ecfc0bf1ce271 msgid "KNOWLEDGE_CHUNK_SIZE=500" msgstr "KNOWLEDGE_CHUNK_SIZE=500" #: ../../getting_started/install/environment/environment.md:59 -#: 9504f4a59ae74352a524b7741113e2d6 +#: e6ee9f2620ab45ecbc8e9c0642f5ca42 msgid "Embedding Chunk Overlap, default 100" msgstr "Embedding chunk Overlap, 文本块之间的最大重叠量。保留一些重叠可以保持文本块之间的连续性(例如使用滑动窗口),默认100" #: ../../getting_started/install/environment/environment.md:60 -#: 24e6119c2051479bbd9dba71a9c23dbe +#: fcddf64340a04df4ab95176fc2fc67a6 msgid "KNOWLEDGE_CHUNK_OVERLAP=100" msgstr "KNOWLEDGE_CHUNK_OVERLAP=100" #: ../../getting_started/install/environment/environment.md:62 -#: 0d180d7f2230442abee901c19526e442 -msgid "embeding recall top k,5" +#: 61272200194b4461a921581feb1273da +#, fuzzy +msgid "embedding recall top k,5" msgstr "embedding 召回topk, 默认5" #: ../../getting_started/install/environment/environment.md:64 -#: a5bb9ab2ba50411cbbe87f7836bfbb6d +#: b433091f055542b1b89ff2d525ac99e4 msgid "KNOWLEDGE_SEARCH_TOP_SIZE=5" msgstr "KNOWLEDGE_SEARCH_TOP_SIZE=5" #: ../../getting_started/install/environment/environment.md:66 -#: 183b8dd78cba4ae19bd2e08d69d21e0b -msgid "embeding recall max token ,2000" +#: 1db0de41aebd4caa8cc2eaecb4cacd6a +#, fuzzy +msgid "embedding recall max token ,2000" msgstr "embedding向量召回最大token, 默认2000" #: ../../getting_started/install/environment/environment.md:68 -#: ce0c711febcb44c18ae0fc858c3718d1 +#: 81b9d862e58941a4b09680a7520cdabe msgid "KNOWLEDGE_SEARCH_MAX_TOKEN=5" msgstr "KNOWLEDGE_SEARCH_MAX_TOKEN=5" #: ../../getting_started/install/environment/environment.md:71 #: ../../getting_started/install/environment/environment.md:87 -#: 4cab1f399cc245b4a1a1976d2c4fc926 ec9cec667a1c4473bf9a796a26e1ce20 +#: cac73575d54544778bdee09b18532fd9 f78a509949a64f03aa330f31901e2e7a msgid "Vector Store SETTINGS" msgstr "Vector Store SETTINGS" #: ../../getting_started/install/environment/environment.md:72 #: ../../getting_started/install/environment/environment.md:88 -#: 4dd04aadd46948a5b1dcf01fdb0ef074 bab7d512f33e40cf9e10f0da67e699c8 +#: 5ebba1cb047b4b09849000244237dfbb 7e9285e91bcb4b2d9413909c0d0a06a7 msgid "Chroma" msgstr "Chroma" #: ../../getting_started/install/environment/environment.md:73 #: ../../getting_started/install/environment/environment.md:89 -#: 13eec36741b14e028e2d3859a320826e ab3ffbcf9358401993af636ba9ab2e2d +#: 05625cfcc23c4745ae1fa0d94ce5450c 3a8615f1507f4fc49d1adda5100a4edf msgid "VECTOR_STORE_TYPE=Chroma" msgstr "VECTOR_STORE_TYPE=Chroma" #: ../../getting_started/install/environment/environment.md:74 #: ../../getting_started/install/environment/environment.md:90 -#: d15b91e2a2884f23a1dd2d54783b0638 d1f856d571b547098bb0c2a18f9f1979 +#: 5b559376aea44f159262e6d4b75c7ec1 e954782861404b10b4e893e01cf74452 msgid "MILVUS" msgstr "MILVUS" #: ../../getting_started/install/environment/environment.md:75 #: ../../getting_started/install/environment/environment.md:91 -#: 1e165f6c934343c7808459cc7a65bc70 985dd60c2b7d4baaa6601a810a6522d7 +#: 55ee8199c97a4929aeefd32370f2b92d 8f40c02543ea4a2ca9632dd9e8a08c2e msgid "VECTOR_STORE_TYPE=Milvus" msgstr "VECTOR_STORE_TYPE=Milvus" #: ../../getting_started/install/environment/environment.md:76 #: ../../getting_started/install/environment/environment.md:92 -#: a1a53f051cee40ed886346a94babd75a d263e8eaee684935a58f0a4fe61c6f0e +#: 528a01d25720491c8e086bf43a62ad92 ba1386d551d7494a85681a2803081a6f msgid "MILVUS_URL=127.0.0.1" msgstr "MILVUS_URL=127.0.0.1" #: ../../getting_started/install/environment/environment.md:77 #: ../../getting_started/install/environment/environment.md:93 -#: 2741a312db1a4c6a8a1c1d62415c5fba d03bbf921ddd4f4bb715fe5610c3d0aa +#: b031950dafcd4d4783c120dc933c4178 c2e9c8cdd41741e3aba01e59a6ef245d msgid "MILVUS_PORT=19530" msgstr "MILVUS_PORT=19530" #: ../../getting_started/install/environment/environment.md:78 #: ../../getting_started/install/environment/environment.md:94 -#: d0786490d38c4e4f971cc14f62fe1fc8 e9e0854873dc4c209861ee4eb77d25cd +#: 27b0a64af6434cb2840373e2b38c9bd5 d0e4d79af7954b129ffff7303a1ec3ce msgid "MILVUS_USERNAME" msgstr "MILVUS_USERNAME" #: ../../getting_started/install/environment/environment.md:79 #: ../../getting_started/install/environment/environment.md:95 -#: 9a82d07153cc432ebe754b5bc02fde0d a6485c1cfa7d4069a6894c43674c8c2b +#: 27aa1a5b61e64dd6bfe29124e274809e 5c58892498ce4f46a59f54b2887822d4 msgid "MILVUS_PASSWORD" msgstr "MILVUS_PASSWORD" #: ../../getting_started/install/environment/environment.md:80 #: ../../getting_started/install/environment/environment.md:96 -#: 2f233f32b8ba408a9fbadb21fabb99ec 809b3219dd824485bc2cfc898530d708 +#: 009e57d4acc5434da2146f0545911c85 bac8888dcbff47fbb0ea8ae685445aac msgid "MILVUS_SECURE=" msgstr "MILVUS_SECURE=" #: ../../getting_started/install/environment/environment.md:82 #: ../../getting_started/install/environment/environment.md:98 -#: f00603661f2b42e1bd2bca74ad1e3c31 f378e16fdec44c559e34c6929de812e8 +#: a6eeb16ab5274045bee88ecc3d93e09e eb341774403d47658b9b7e94c4c16d5c msgid "WEAVIATE" msgstr "WEAVIATE" #: ../../getting_started/install/environment/environment.md:83 -#: da2049ebc6874cf0a6b562e0e2fd9ec7 +#: fbd97522d8da4824b41b99298fd41069 msgid "VECTOR_STORE_TYPE=Weaviate" msgstr "VECTOR_STORE_TYPE=Weaviate" #: ../../getting_started/install/environment/environment.md:84 #: ../../getting_started/install/environment/environment.md:99 -#: 25f1246629934289aad7ef01c7304097 c9fe0e413d9a4fc8abf86b3ed99e0581 +#: 341785b4abfe42b5af1c2e04497261f4 a81cc2aabc8240f3ac1f674d9350bff4 msgid "WEAVIATE_URL=https://kt-region-m8hcy0wc.weaviate.network" msgstr "WEAVIATE_URL=https://kt-region-m8hcy0wc.weaviate.network" #: ../../getting_started/install/environment/environment.md:102 -#: ba7c9e707f6a4cd6b99e52b58da3ab2d +#: 5bb9e5daa36241d499089c1b1910f729 msgid "Multi-GPU Setting" msgstr "Multi-GPU Setting" #: ../../getting_started/install/environment/environment.md:103 -#: 5ca75fdf2c264b2c844d77f659b4f0b3 +#: 30df45b7f1f7423c9f18c6360f0b7600 msgid "" "See https://developer.nvidia.com/blog/cuda-pro-tip-control-gpu-" "visibility-cuda_visible_devices/ If CUDA_VISIBLE_DEVICES is not " @@ -313,49 +315,49 @@ msgstr "" "cuda_visible_devices/ 如果 CUDA_VISIBLE_DEVICES没有设置, 会使用所有可用的gpu" #: ../../getting_started/install/environment/environment.md:106 -#: de92eb310aff43fbbbf3c5a116c3b2c6 +#: 8631ea968dfb4d90a7ae6bdb2acdfdce msgid "CUDA_VISIBLE_DEVICES=0" msgstr "CUDA_VISIBLE_DEVICES=0" #: ../../getting_started/install/environment/environment.md:108 -#: d2641df6123a442b8e4444ad5f01a9aa +#: 0010422280dd4fe79326ebceb2a66f0e msgid "" "Optionally, you can also specify the gpu ID to use before the starting " "command" msgstr "你也可以通过启动命令设置gpu ID" #: ../../getting_started/install/environment/environment.md:110 -#: 76c66179d11a4e5fa369421378609aae +#: 00106f7341304fbd9425721ea8e6a261 msgid "CUDA_VISIBLE_DEVICES=3,4,5,6" msgstr "CUDA_VISIBLE_DEVICES=3,4,5,6" #: ../../getting_started/install/environment/environment.md:112 -#: 29bd0f01fdf540ad98385ea8473f7647 +#: 720aa8b3478744d78e4b10dfeccb50b4 msgid "You can configure the maximum memory used by each GPU." msgstr "可以设置GPU的最大内存" #: ../../getting_started/install/environment/environment.md:114 -#: 31e5e23838734ba7a2810e2387e6d6a0 +#: f9639ac96a244296832c75bbcbdae2af msgid "MAX_GPU_MEMORY=16Gib" msgstr "MAX_GPU_MEMORY=16Gib" #: ../../getting_started/install/environment/environment.md:117 -#: 99aa63ab1ae049d9b94536d6a96f3443 +#: fc4d955fdb3e4256af5c8f29b042dcd6 msgid "Other Setting" msgstr "Other Setting" #: ../../getting_started/install/environment/environment.md:118 -#: 3168732183874bffb59a3575d3473d62 +#: 66b14a834e884339be2d48392e884933 msgid "Language Settings(influence prompt language)" msgstr "Language Settings(涉及prompt语言以及知识切片方式)" #: ../../getting_started/install/environment/environment.md:119 -#: 73eb0a96f29b4739bd456faa9cb5033d +#: 5c9f05174eb84edd9e1316cc0721a840 msgid "LANGUAGE=en" msgstr "LANGUAGE=en" #: ../../getting_started/install/environment/environment.md:120 -#: c6646b78c6cf4d25a13108232f5b2046 +#: 7f6d62117d024c51bba9255fa4fcf151 msgid "LANGUAGE=zh" msgstr "LANGUAGE=zh" diff --git a/docs/locales/zh_CN/LC_MESSAGES/modules/knowledge.po b/docs/locales/zh_CN/LC_MESSAGES/modules/knowledge.po index 0b3eac094..032e81609 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/modules/knowledge.po +++ b/docs/locales/zh_CN/LC_MESSAGES/modules/knowledge.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 0.3.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-13 15:39+0800\n" +"POT-Creation-Date: 2023-11-02 10:10+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -19,103 +19,84 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.12.1\n" -#: ../../modules/knowledge.rst:2 ../../modules/knowledge.rst:136 -#: 3cc8fa6e9fbd4d889603d99424e9529a +#: ../../modules/knowledge.md:1 436b94d3a8374ed18feb5c14893a84e6 msgid "Knowledge" msgstr "知识" -#: ../../modules/knowledge.rst:4 0465a393d9d541958c39c1d07c885d1f +#: ../../modules/knowledge.md:3 918a3747cbed42d18b8c9c4547e67b14 #, fuzzy msgid "" "As the knowledge base is currently the most significant user demand " "scenario, we natively support the construction and processing of " "knowledge bases. At the same time, we also provide multiple knowledge " -"base management strategies in this project, such as pdf knowledge,md " -"knowledge, txt knowledge, word knowledge, ppt knowledge:" +"base management strategies in this project, such as:" msgstr "" "由于知识库是当前用户需求最显著的场景,我们原生支持知识库的构建和处理。同时,我们还在本项目中提供了多种知识库管理策略,如:pdf,md , " "txt, word, ppt" -#: ../../modules/knowledge.rst:6 e670cbe14d8e4da88ba935e4120c31e0 -msgid "" -"We currently support many document formats: raw text, txt, pdf, md, html," -" doc, ppt, and url. In the future, we will continue to support more types" -" of knowledge, including audio, video, various databases, and big data " -"sources. Of course, we look forward to your active participation in " -"contributing code." +#: ../../modules/knowledge.md:4 d4d4b5d57918485aafa457bb9fdcf626 +msgid "Default built-in knowledge base" msgstr "" -#: ../../modules/knowledge.rst:9 e0bf601a1a0c458297306db6ff79f931 -msgid "**Create your own knowledge repository**" +#: ../../modules/knowledge.md:5 d4d4b5d57918485aafa457bb9fdcf626 +msgid "Custom addition of knowledge bases" +msgstr "" + +#: ../../modules/knowledge.md:6 984361ce835c4c3492e29e1fb897348a +msgid "" +"Various usage scenarios such as constructing knowledge bases through " +"plugin capabilities and web crawling. Users only need to organize the " +"knowledge documents, and they can use our existing capabilities to build " +"the knowledge base required for the large model." +msgstr "" + +#: ../../modules/knowledge.md:9 746e4fbd3212460198be51b90caee2c8 +#, fuzzy +msgid "Create your own knowledge repository" msgstr "创建你自己的知识库" -#: ../../modules/knowledge.rst:11 bb26708135d44615be3c1824668010f6 -msgid "1.prepare" -msgstr "准备" +#: ../../modules/knowledge.md:11 1c46b33b0532417c824efbaa3e687c3f +msgid "" +"1.Place personal knowledge files or folders in the pilot/datasets " +"directory." +msgstr "" -#: ../../modules/knowledge.rst:13 c150a0378f3e4625908fa0d8a25860e9 +#: ../../modules/knowledge.md:13 3b16f387b5354947a89d6df77bd65bdb #, fuzzy msgid "" -"We currently support many document formats: TEXT(raw text), " -"DOCUMENT(.txt, .pdf, .md, .doc, .ppt, .html), and URL." +"We currently support many document formats: txt, pdf, md, html, doc, ppt," +" and url." msgstr "当前支持txt, pdf, md, html, doc, ppt, url文档格式" -#: ../../modules/knowledge.rst:15 7f9f02a93d5d4325b3d2d976f4bb28a0 +#: ../../modules/knowledge.md:15 09ec337d7da4418db854e58afb6c0980 msgid "before execution:" msgstr "开始前" -#: ../../modules/knowledge.rst:24 59699a8385e04982a992cf0d71f6dcd5 -#, fuzzy +#: ../../modules/knowledge.md:22 c09b3decb018485f8e56830ddc156194 msgid "" -"2.prepare embedding model, you can download from https://huggingface.co/." -" Notice you have installed git-lfs." +"2.Update your .env, set your vector store type, VECTOR_STORE_TYPE=Chroma " +"(now only support Chroma and Milvus, if you set Milvus, please set " +"MILVUS_URL and MILVUS_PORT)" msgstr "" -"提前准备Embedding Model, 你可以在https://huggingface.co/进行下载,注意:你需要先安装git-lfs.eg:" -" git clone https://huggingface.co/THUDM/chatglm2-6b" -#: ../../modules/knowledge.rst:27 2be1a17d0b54476b9dea080d244fd747 -msgid "" -"eg: git clone https://huggingface.co/sentence-transformers/all-" -"MiniLM-L6-v2" -msgstr "eg: git clone https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2" - -#: ../../modules/knowledge.rst:33 d328f6e243624c9488ebd27c9324621b -msgid "" -"3.prepare vector_store instance and vector store config, now we support " -"Chroma, Milvus and Weaviate." -msgstr "提前准备向量数据库环境,目前支持Chroma, Milvus and Weaviate向量数据库" - -#: ../../modules/knowledge.rst:63 44f97154eff647d399fd30b6f9e3b867 -msgid "" -"3.init Url Type EmbeddingEngine api and embedding your document into " -"vector store in your code." -msgstr "初始化 Url类型 EmbeddingEngine api, 将url文档embedding向量化到向量数据库 " - -#: ../../modules/knowledge.rst:75 e2581b414f0148bca88253c7af9cd591 -msgid "If you want to add your source_reader or text_splitter, do this:" -msgstr "如果你想手动添加你自定义的source_reader和text_splitter, 请参考:" - -#: ../../modules/knowledge.rst:95 74c110414f924bbfa3d512e45ba2f30f -#, fuzzy -msgid "" -"4.init Document Type EmbeddingEngine api and embedding your document into" -" vector store in your code. Document type can be .txt, .pdf, .md, .doc, " -".ppt." +#: ../../modules/knowledge.md:25 74460ec7709441d5945ce9f745a26d20 +msgid "2.Run the knowledge repository initialization command" msgstr "" -"初始化 文档型类型 EmbeddingEngine api, 将文档embedding向量化到向量数据库(文档可以是.txt, .pdf, " -".md, .html, .doc, .ppt)" -#: ../../modules/knowledge.rst:108 0afd40098d5f4dfd9e44fe1d8004da25 +#: ../../modules/knowledge.md:31 4498ec4e46ff4e24b45dd855e829bd32 msgid "" -"5.init TEXT Type EmbeddingEngine api and embedding your document into " -"vector store in your code." -msgstr "初始化TEXT类型 EmbeddingEngine api, 将文档embedding向量化到向量数据库" +"Optionally, you can run `dbgpt knowledge load --help` command to see more" +" usage." +msgstr "" -#: ../../modules/knowledge.rst:120 a66961bf3efd41fa8ea938129446f5a5 -msgid "4.similar search based on your knowledge base. ::" -msgstr "在知识库进行相似性搜索" +#: ../../modules/knowledge.md:33 5048ac3289e540f2a2b5fd0e5ed043f5 +msgid "" +"3.Add the knowledge repository in the interface by entering the name of " +"your knowledge repository (if not specified, enter \"default\") so you " +"can use it for Q&A based on your knowledge base." +msgstr "" -#: ../../modules/knowledge.rst:126 b7066f408378450db26770f83fbd2716 +#: ../../modules/knowledge.md:35 deeccff20f7f453dad0881b63dae2a18 msgid "" "Note that the default vector model used is text2vec-large-chinese (which " "is a large model, so if your personal computer configuration is not " @@ -125,48 +106,6 @@ msgstr "" "注意,这里默认向量模型是text2vec-large-chinese(模型比较大,如果个人电脑配置不够建议采用text2vec-base-" "chinese),因此确保需要将模型download下来放到models目录中。" -#: ../../modules/knowledge.rst:128 58481d55cab74936b6e84b24c39b1674 -#, fuzzy -msgid "" -"`pdf_embedding <./knowledge/pdf/pdf_embedding.html>`_: supported pdf " -"embedding." -msgstr "pdf_embedding <./knowledge/pdf_embedding.html>`_: supported pdf embedding." - -#: ../../modules/knowledge.rst:129 fbb013c4f1bc46af910c91292f6690cf -#, fuzzy -msgid "" -"`markdown_embedding <./knowledge/markdown/markdown_embedding.html>`_: " -"supported markdown embedding." -msgstr "pdf_embedding <./knowledge/pdf_embedding.html>`_: supported pdf embedding." - -#: ../../modules/knowledge.rst:130 59d45732f4914d16b4e01aee0992edf7 -#, fuzzy -msgid "" -"`word_embedding <./knowledge/word/word_embedding.html>`_: supported word " -"embedding." -msgstr "pdf_embedding <./knowledge/pdf_embedding.html>`_: supported pdf embedding." - -#: ../../modules/knowledge.rst:131 df0e6f311861423e885b38e020a7c0f0 -#, fuzzy -msgid "" -"`url_embedding <./knowledge/url/url_embedding.html>`_: supported url " -"embedding." -msgstr "pdf_embedding <./knowledge/pdf_embedding.html>`_: supported pdf embedding." - -#: ../../modules/knowledge.rst:132 7c550c1f5bc34fe9986731fb465e12cd -#, fuzzy -msgid "" -"`ppt_embedding <./knowledge/ppt/ppt_embedding.html>`_: supported ppt " -"embedding." -msgstr "pdf_embedding <./knowledge/pdf_embedding.html>`_: supported pdf embedding." - -#: ../../modules/knowledge.rst:133 8648684cb191476faeeb548389f79050 -#, fuzzy -msgid "" -"`string_embedding <./knowledge/string/string_embedding.html>`_: supported" -" raw text embedding." -msgstr "pdf_embedding <./knowledge/pdf_embedding.html>`_: supported pdf embedding." - #~ msgid "before execution: python -m spacy download zh_core_web_sm" #~ msgstr "在执行之前请先执行python -m spacy download zh_core_web_sm" @@ -201,3 +140,112 @@ msgstr "pdf_embedding <./knowledge/pdf_embedding.html>`_: supported pdf embeddin #~ "and MILVUS_PORT)" #~ msgstr "2.更新你的.env,设置你的向量存储类型,VECTOR_STORE_TYPE=Chroma(现在只支持Chroma和Milvus,如果你设置了Milvus,请设置MILVUS_URL和MILVUS_PORT)" +#~ msgid "" +#~ "We currently support many document " +#~ "formats: raw text, txt, pdf, md, " +#~ "html, doc, ppt, and url. In the" +#~ " future, we will continue to support" +#~ " more types of knowledge, including " +#~ "audio, video, various databases, and big" +#~ " data sources. Of course, we look " +#~ "forward to your active participation in" +#~ " contributing code." +#~ msgstr "" + +#~ msgid "1.prepare" +#~ msgstr "准备" + +#~ msgid "" +#~ "2.prepare embedding model, you can " +#~ "download from https://huggingface.co/. Notice " +#~ "you have installed git-lfs." +#~ msgstr "" +#~ "提前准备Embedding Model, 你可以在https://huggingface.co/进行下载,注意" +#~ ":你需要先安装git-lfs.eg: git clone " +#~ "https://huggingface.co/THUDM/chatglm2-6b" + +#~ msgid "" +#~ "eg: git clone https://huggingface.co/sentence-" +#~ "transformers/all-MiniLM-L6-v2" +#~ msgstr "" +#~ "eg: git clone https://huggingface.co/sentence-" +#~ "transformers/all-MiniLM-L6-v2" + +#~ msgid "" +#~ "3.prepare vector_store instance and vector " +#~ "store config, now we support Chroma, " +#~ "Milvus and Weaviate." +#~ msgstr "提前准备向量数据库环境,目前支持Chroma, Milvus and Weaviate向量数据库" + +#~ msgid "" +#~ "3.init Url Type EmbeddingEngine api and" +#~ " embedding your document into vector " +#~ "store in your code." +#~ msgstr "初始化 Url类型 EmbeddingEngine api, 将url文档embedding向量化到向量数据库 " + +#~ msgid "If you want to add your source_reader or text_splitter, do this:" +#~ msgstr "如果你想手动添加你自定义的source_reader和text_splitter, 请参考:" + +#~ msgid "" +#~ "4.init Document Type EmbeddingEngine api " +#~ "and embedding your document into vector" +#~ " store in your code. Document type" +#~ " can be .txt, .pdf, .md, .doc, " +#~ ".ppt." +#~ msgstr "" +#~ "初始化 文档型类型 EmbeddingEngine api, " +#~ "将文档embedding向量化到向量数据库(文档可以是.txt, .pdf, .md, .html," +#~ " .doc, .ppt)" + +#~ msgid "" +#~ "5.init TEXT Type EmbeddingEngine api and" +#~ " embedding your document into vector " +#~ "store in your code." +#~ msgstr "初始化TEXT类型 EmbeddingEngine api, 将文档embedding向量化到向量数据库" + +#~ msgid "4.similar search based on your knowledge base. ::" +#~ msgstr "在知识库进行相似性搜索" + +#~ msgid "" +#~ "`pdf_embedding <./knowledge/pdf/pdf_embedding.html>`_: " +#~ "supported pdf embedding." +#~ msgstr "" +#~ "pdf_embedding <./knowledge/pdf_embedding.html>`_: " +#~ "supported pdf embedding." + +#~ msgid "" +#~ "`markdown_embedding " +#~ "<./knowledge/markdown/markdown_embedding.html>`_: supported " +#~ "markdown embedding." +#~ msgstr "" +#~ "pdf_embedding <./knowledge/pdf_embedding.html>`_: " +#~ "supported pdf embedding." + +#~ msgid "" +#~ "`word_embedding <./knowledge/word/word_embedding.html>`_: " +#~ "supported word embedding." +#~ msgstr "" +#~ "pdf_embedding <./knowledge/pdf_embedding.html>`_: " +#~ "supported pdf embedding." + +#~ msgid "" +#~ "`url_embedding <./knowledge/url/url_embedding.html>`_: " +#~ "supported url embedding." +#~ msgstr "" +#~ "pdf_embedding <./knowledge/pdf_embedding.html>`_: " +#~ "supported pdf embedding." + +#~ msgid "" +#~ "`ppt_embedding <./knowledge/ppt/ppt_embedding.html>`_: " +#~ "supported ppt embedding." +#~ msgstr "" +#~ "pdf_embedding <./knowledge/pdf_embedding.html>`_: " +#~ "supported pdf embedding." + +#~ msgid "" +#~ "`string_embedding <./knowledge/string/string_embedding.html>`_:" +#~ " supported raw text embedding." +#~ msgstr "" +#~ "pdf_embedding <./knowledge/pdf_embedding.html>`_: " +#~ "supported pdf embedding." + diff --git a/docs/requirements.txt b/docs/requirements.txt index 8cee184af..d0a125868 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -9,9 +9,9 @@ sphinx_book_theme sphinx_rtd_theme==1.0.0 sphinx-typlog-theme==0.8.0 sphinx-panels +sphinx-tabs==3.4.0 toml myst_nb sphinx_copybutton pydata-sphinx-theme==0.13.1 -pydantic-settings furo \ No newline at end of file From 0874fa25269a9b29bd2a3b62edf4e28ee24d5d28 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Fri, 3 Nov 2023 14:51:25 +0800 Subject: [PATCH 40/57] doc:update deploy doc --- docs/_static/css/custom.css | 928 ++++++++++++++++++ docs/_static/css/examples.css | 223 +++++ docs/_static/css/termynal.css | 108 ++ docs/_static/css/use_cases.css | 23 + docs/conf.py | 10 +- docs/getting_started/install/deploy.rst | 77 +- .../getting_started/install/deploy.po | 629 ++++++++++++ .../zh_CN/LC_MESSAGES/modules/prompts.po | 72 +- pilot/scene/chat_knowledge/v1/chat.py | 5 - pilot/scene/chat_knowledge/v1/prompt.py | 4 +- pilot/server/component_configs.py | 4 +- pilot/server/knowledge/service.py | 42 +- 12 files changed, 2000 insertions(+), 125 deletions(-) create mode 100644 docs/_static/css/custom.css create mode 100644 docs/_static/css/examples.css create mode 100644 docs/_static/css/termynal.css create mode 100644 docs/_static/css/use_cases.css create mode 100644 docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css new file mode 100644 index 000000000..f3bcfe7b5 --- /dev/null +++ b/docs/_static/css/custom.css @@ -0,0 +1,928 @@ +/* override default colors used in the Sphinx theme */ +:root { + --tabs-color-label-active: #0475DE; + --tabs-color-label-hover: #0475DE; + --buttons-color-blue: #0475DE; + --tabs-color-label-inactive: #9E9E9E; + --tabs-color-overline: #e0e0e0; + --tabs-color-underline: #e0e0e0; + --border-color-gray: #e0e0e0; + --background-color-light-gray:#fafafa; + --background-color-disabled: #9E9E9E; + --pst-color-link: 4, 117, 222; + --pst-color-primary: 4, 117, 222; + --pst-color-text-secondary: #616161; + --blue: #0475DE; + --sidebar-top: 5em; +} + +/* Remove flicker for announcement top bar replacement */ +.header-item.announcement { + background-color: white; + color: white; + padding: 0; +} + +/* Make the book theme secondary nav stick below the new main top nav */ +.header-article { + top: 58px; + z-index: 900 !important; +} + +.toctree-l1.has-children { + font-weight: bold; +} + +.toctree-l2 { + font-weight: normal; +} + +div.navbar-brand-box { + padding-top: 4em; +} + +td p { + margin-left: 0.75rem; +} + +table.longtable.table.autosummary { + table-layout: fixed; +} + +.table.autosummary td { + width: 100%; +} + +tr.row-odd { + background-color: #f9fafb; +} + +/* For Algolia search box + * overflow-y: to flow-over horizontally into main content + * height: to prevent topbar overlap +*/ +#site-navigation { + overflow-y: auto; + height: calc(100vh - var(--sidebar-top)); + position: sticky; + top: var(--sidebar-top) !important; +} + +/* Center the algolia search bar*/ +#search-input { + text-align: center; +} +.algolia-autocomplete { + width: 100%; + margin: auto; +} + +/* Hide confusing "<-" back arrow in navigation for larger displays */ +@media (min-width: 768px) { + #navbar-toggler { + display: none; + } +} + +/* Make navigation scrollable on mobile, by making algolia not overflow */ +@media (max-width: 768px) { + #site-navigation { + overflow-y: scroll; + } + + .algolia-autocomplete .ds-dropdown-menu{ + min-width: 250px; + } +} + +/* sphinx-panels overrides the content width to 1140 for large displays.*/ +@media (min-width: 1200px) { + .container, .container-lg, .container-md, .container-sm, .container-xl { + max-width: 1400px !important; + } +} + +.bottom-right-promo-banner { + position: fixed; + bottom: 100px; + right: 20px; + width: 270px; +} + +@media (max-width: 1500px) { + .bottom-right-promo-banner { + display: none; + } +} + +@media screen and (max-width: 767px) { + .remove-mobile { + display: none; + } + } + + @media screen and (max-width: 767px) { + .row-2-column { + flex-direction: column; + margin-top: 20px; + } + } + +/* Make Algolia search box scrollable */ +.algolia-autocomplete .ds-dropdown-menu { + height: 60vh !important; + overflow-y: scroll !important; +} + +.bd-sidebar__content { + overflow-y: unset !important; +} + +.bd-sidebar__top { + display: flex; + flex-direction: column; +} + +.bd-sidebar li { + position: relative; + word-wrap: break-word; +} + +nav.bd-links { + flex: 1; +} + +nav.bd-links::-webkit-scrollbar-thumb { + background-color: #ccc; +} + +nav.bd-links::-webkit-scrollbar { + width: 5px; +} + +dt:target, span.highlighted { + background-color: white; +} + +div.sphx-glr-bigcontainer { + display: inline-block; + width: 100%; +} + +td.tune-colab, +th.tune-colab { + border: 1px solid #dddddd; + text-align: left; + padding: 8px; +} + +/* Adjustment to Sphinx Book Theme */ +.table td { + /* Remove row spacing on the left */ + padding-left: 0; +} + +.table thead th { + /* Remove row spacing on the left */ + padding-left: 0; +} + +img.inline-figure { + /* Override the display: block for img */ + display: inherit !important; +} + +#version-warning-banner { + /* Make version warning clickable */ + z-index: 1; + margin-left: 0; + /* 20% is for ToC rightbar */ + /* 2 * 1.5625em is for horizontal margins */ + width: calc(100% - 20% - 2 * 1.5625em); +} + +/* allow scrollable images */ +.figure { + max-width: 100%; + overflow-x: auto; +} +img.horizontal-scroll { + max-width: none; +} + +.clear-both { + clear: both; + min-height: 100px; + margin-top: 15px; +} + +.buttons-float-left { + width: 150px; + float: left; +} + +.buttons-float-right { + width: 150px; + float: right; +} + +.card-body { + padding: 0.5rem !important; +} + +/* custom css for pre elements */ +pre { + /* Wrap code blocks instead of horizontal scrolling. */ + white-space: pre-wrap; + box-shadow: none; + border-color: var(--border-color-gray); + background-color: var(--background-color-light-gray); + border-radius:0.25em; +} + +/* notebook formatting */ +.cell .cell_output { + max-height: 250px; + overflow-y: auto; + font-weight: bold; +} + +/* Yellow doesn't render well on light background */ +.cell .cell_output pre .-Color-Yellow { + color: #785840; +} + +/* Newlines (\a) and spaces (\20) before each parameter */ +.sig-param::before { + content: "\a\20\20\20\20"; + white-space: pre; +} + +/* custom css for outlined buttons */ +.btn-outline-info:hover span, .btn-outline-primary:hover span { + color: #fff; +} + +.btn-outline-info, .btn-outline-primary{ + border-color: var(--buttons-color-blue); +} + +.btn-outline-info:hover, .btn-outline-primary:hover{ + border-color: var(--buttons-color-blue); + background-color: var(--buttons-color-blue); +} + +.btn-outline-info.active:not(:disabled):not(.disabled), .btn-outline-info:not(:disabled):not(.disabled):active, .show>.btn-outline-info.dropdown-toggle { + border-color: var(--buttons-color-blue); + background-color: var(--buttons-color-blue); + color: #fff; +} + +.btn-info, .btn-info:hover, .btn-info:focus { + border-color: var(--buttons-color-blue); + background-color: var(--buttons-color-blue); +} + +.btn-info:hover{ + opacity: 90%; +} + +.btn-info:disabled{ + border-color: var(--background-color-disabled); + background-color: var(--background-color-disabled); + opacity: 100%; +} + +.btn-info.active:not(:disabled):not(.disabled), .btn-info:not(:disabled):not(.disabled):active, .show>.btn-info.dropdown-toggle { + border-color: var(--buttons-color-blue); + background-color: var(--buttons-color-blue); +} + + +.topnav { + background-color: white; + border-bottom: 1px solid rgba(0, 0, 0, .1); + display: flex; + align-items: center; +} + +/* Content wrapper for the unified nav link / menus */ +.top-nav-content { + max-width: 1400px; + width: 100%; + margin-left: auto; + margin-right: auto; + padding: 0 1.5rem; + display: flex; + align-items: center; + justify-content: space-between; +} + +@media (max-width: 900px) { + /* If the window is too small, hide the custom sticky navigation bar at the top of the page. + Also make the pydata-sphinx-theme nav bar, which usually sits below the top nav bar, stick + to the top of the page. + */ + .top-nav-content { + display: none; + } + div.header-article.row.sticky-top.noprint { + position: sticky; + top: 0; + } +} + +/* Styling the links and menus in the top nav */ +.top-nav-content a { + text-decoration: none; + color: black; + font-size: 17px; +} + +.top-nav-content a:hover { + color: #007bff; +} + +/* The left part are the links and menus */ +.top-nav-content > .left { + display: flex; + white-space: nowrap; +} + +.top-nav-content .left > * { + margin-right: 8px; +} + +.top-nav-content .left > a, +.top-nav-content .left > .menu > a { + text-align: center; + padding: 14px 16px; + border-bottom: 2px solid white; +} + +.top-nav-content .menu:hover > a, +.top-nav-content .left > a:hover { + border-bottom: 2px solid #007bff; +} + +/* Special styling for the Ray logo */ +.top-nav-content .left > a.ray-logo { + width: 90px; + padding: 10px 0; +} +.top-nav-content .left > a.ray-logo:hover { + border-bottom: 2px solid white; +} + +/* Styling the dropdown menus */ +.top-nav-content .menu { + display: flex; +} +.top-nav-content .menu > a > .down-caret { + margin-left: 8px; +} +.top-nav-content .menu > ul { + display: none; +} + +.top-nav-content > button.try-anyscale > span { + margin: 0 12px; +} + +.top-nav-content .menu:hover > ul { + display: flex; + flex-direction: column; + align-items: flex-start; + box-shadow: 0 5px 15px 0 rgb(0 0 0 / 10%); + padding: 15px; + width: 330px; + position: absolute; + z-index: 2000; + background-color: white; + top: 58px; +} + +.top-nav-content .menu:hover > ul > li { + list-style: none; + padding: 5px 0; +} + +.top-nav-content .menu:hover > ul > li span { + display: block; +} + +.top-nav-content .menu:hover > ul > li span.secondary { + color: #787878; +} + +/* Styling the "Try Anyscale" button */ +.top-nav-content > button.try-anyscale { + float: right; + border-radius: 6px; + background-color: #e7f2fa; + padding-left: 12px; + padding-right: 12px; + margin-left: 12px; + height: 40px; + border: none; + white-space: nowrap; +} + +@media (max-width: 1000px) { + .top-nav-content > button.try-anyscale { + display: none; + } +} + +/* custom css for tabs*/ +.tabbed-set>label,.tabbed-set>label:hover { + border-bottom: 1px solid var(--border-color-gray); + color:var(--tabs-color-label-inactive); + font-weight: 500; +} + +.tabbed-set>input:checked+label{ + border-bottom: 0.125em solid; + color:var(--tabs-color-label-active); +} + + +.tabbed-label{ + margin-bottom:0; +} + +/* custom css for jupyter cells */ +div.cell div.cell_input{ + border: 1px var(--border-color-gray) solid; + background-color: var(--background-color-light-gray); + border-radius:0.25em; + border-left-color: var(--green); + border-left-width: medium; +} + +/* custom css for table */ +table { + border-color: var(--border-color-gray); +} + +/* custom css for topic component */ +div.topic{ + border: 1px solid var(--border-color-gray); + border-radius:0.25em; +} + +.topic { + background-color: var(--background-color-light-gray); +} + +/* custom css for card component */ +.card{ + border-color: var(--border-color-gray); +} + +.card-footer{ + background-color: var(--background-color-light-gray); + border-top-color: var(--border-color-gray); +} + +/* custom css for section navigation component */ +.bd-toc nav>.nav { + border-left-color: var(--border-color-gray); +} + +/* custom css for up and down arrows in collapsible cards */ +details.dropdown .summary-up, details.dropdown .summary-down { + top: 1em; +} + +/* remove focus border in collapsible admonition buttons */ +.toggle.admonition button.toggle-button:focus { + outline: none; +} + +/* custom css for shadow class */ +.shadow { + box-shadow: 0 0.2rem 0.5rem rgb(0 0 0 / 5%), 0 0 0.0625rem rgb(0 0 0 / 10%) !important; +} + +/* custom css for text area */ +textarea { + border-color: var(--border-color-gray); +} + +/* custom css for footer */ +footer { + margin-top: 1rem; + padding:1em 0; + border-top-color: var(--border-color-gray); +} + +.footer p{ + color: var(--pst-color-text-secondary); +} + +/* Make the hover color of tag/gallery buttons differ from "active" */ +.tag.btn-outline-primary:hover { + background-color: rgba(20, 99, 208, 0.62) !important; +} + +span.rst-current-version > span.fa.fa-book { + /* Move the book icon away from the top right + * corner of the version flyout menu */ + margin: 10px 0px 0px 5px; +} + + +/*Extends the docstring signature box.*/ +.rst-content dl:not(.docutils) dt { + display: block; + padding: 10px; + word-wrap: break-word; + padding-right: 100px; +} + +/*Lists in an admonition note do not have awkward whitespace below.*/ +.rst-content .admonition-note .section ul { + margin-bottom: 0; +} + +/*Properties become blue (classmethod, staticmethod, property)*/ +.rst-content dl dt em.property { + color: #2980b9; + text-transform: uppercase; +} + +.rst-content .section ol p, +.rst-content .section ul p { + margin-bottom: 0; +} + + +/* Adjustment to Version block */ +.rst-versions { + z-index: 1200 !important; +} + +.image-header { + display: flex; + flex-direction: row; + align-items: center; + padding-left: 16px; + padding-right:16px; + gap: 16px; +} + +.info-box { + box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.05); + border-radius: 8px; + padding: 20px; +} + +.info-box:hover{ + box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.1); +} + +.no-underline{ + text-decoration: none; +} +.no-underline:hover{ + text-decoration: none; +} + +.icon-hover:hover{ + height: 30px ; + width: 30px; +} + +.info-box-2 { + background-color: #F9FAFB; + border-radius: 8px; + padding-right: 16px; + padding-left: 16px; + padding-bottom: 24px; + padding-top: 4px; +} + + +.bold-link { + color: #000000 !important; + font-weight: 600; +} + +.community-box { + border: 1px solid #D2DCE6; + border-radius: 8px; + display: flex; + margin-bottom: 16px; +} + +.community-box:hover { + box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.05); + text-decoration: none; +} + +.community-box p { + margin-top: 1rem !important; +} + +.tab-pane pre { + margin: 0; + padding: 0; + max-height: 252px; + overflow-y: auto; +} + +.grid-container { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px,1fr)); + grid-gap: 16px; +} + +.grid-item { +padding: 20px; +} + + +.nav-pills { + background-color: #F9FAFB; + color: #000000; + padding: 8px; + border-bottom:none; + border-radius: 8px; +} + +.nav-pills .nav-link.active { + background-color: #FFFFFF !important; + box-shadow: 0px 3px 14px 2px rgba(3,28,74,0.12); + border-radius: 8px; + padding: 20px; + color: #000000; + font-weight: 500; +} + +.searchDiv { + width: 100%; + position: relative; + display: block; +} + +.searchTerm { + width: 80%; + border: 2px solid var(--blue); + padding: 5px; + height: 45px; + border-radius: 5px; + outline: none; +} + +.searchButton { + width: 40px; + height: 45px; + border: 1px solid var(--blue); + background: var(--blue); + color: #fff; + border-radius: 5px; + cursor: pointer; + font-size: 20px; +} + +/*Resize the wrap to see the search bar change!*/ +.searchWrap { + width: 100%; + position: relative; + margin: 15px; + top: 50%; + left: 50%; + transform: translate(-50%, -10%); + text-align: center; +} + +.sd-card { + border: none !important; +} + +.tag { + margin-bottom: 5px; + font-size: small; +} + +/* Override float positioning of next-prev buttons so that + they take up space normally, and we can put other stuff at + the bottom of the page. */ +.prev-next-area { + display: flex; + flex-direction: row; +} +.prev-next-area a.left-prev { + margin-right: auto; + width: fit-content; + float: none; +} +.prev-next-area a.right-next { + margin-left: auto; + width: fit-content; + float: none; +} + +/* CSAT widgets */ +#csat-inputs { + display: flex; + flex-direction: row; + align-items: center; +} + +.csat-hidden { + display: none !important; +} + +#csat-feedback-label { + color: #000; + font-weight: 500; +} + +.csat-button { + margin-left: 16px; + padding: 8px 16px 8px 16px; + border-radius: 4px; + border: 1px solid #D2DCE6; + background: #FFF; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + cursor: pointer; + width: 85px; +} + +#csat-textarea-group { + display: flex; + flex-direction: column; +} + +#csat-submit { + margin-left: auto; + font-weight: 700; + border: none; + margin-top: 12px; + cursor: pointer; +} + +#csat-feedback-received { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; +} + +.csat-button-active { + border: 1px solid #000; +} + +.csat-icon { + margin-right: 4px; +} + +footer.col.footer { + display: flex; + flex-direction: row; +} + +footer.col.footer > p { + margin-left: auto; +} + +#csat { + min-width: 60%; +} + +#csat-textarea { + resize: none; +} + + +/* Ray Assistant */ + +.container-xl.blurred { + filter: blur(5px); +} + +.chat-widget { + position: fixed; + bottom: 10px; + right: 10px; + z-index: 1000; +} + +.chat-popup { + display: none; + position: fixed; + top: 20%; + left: 50%; + transform: translate(-50%, -20%); + width: 50%; + height: 70%; + background-color: white; + border: 1px solid #ccc; + border-radius: 10px; + box-shadow: 0 5px 10px rgba(0,0,0,0.1); + z-index: 1001; + max-height: 1000px; + overflow: hidden; + padding-bottom: 40px; +} + +.chatFooter { + position: absolute; + bottom: 0; + right: 0; + width: 100%; + background-color: #f8f9fa; +} + +#openChatBtn { + background-color: #000; + color: #fff; + width: 70px; + height: 70px; + border-radius: 10px; + border: none; + display: flex; + align-items: center; + justify-content: center; +} + +#closeChatBtn { + border: none; + background-color: transparent; + color: #000; + font-size: 1.2em; +} + +#closeChatBtn:hover { + color: #888; +} + +.chatHeader { + display: flex; + justify-content: space-between; + align-items: center; +} + +.chatContentContainer { + padding: 15px; + max-height: calc(100% - 80px); + overflow-y: auto; +} + +.chatContentContainer input { + margin-top: 10px; + margin-bottom: 10px; +} + +#result{ + padding: 15px; + border-radius: 10px; + margin-top: 10px; + margin-bottom: 10px; + background-color: #f8f9fa; + max-height: calc(100% - 20px); + overflow-y: auto; +} + +.chatContentContainer textarea { + flex-grow: 1; + min-width: 50px; + max-height: 40px; + resize: none; +} + +.searchBtn { + white-space: nowrap; +} + +.input-group { + display: flex; + align-items: stretch; +} + +/* Kapa Ask AI button */ +#kapa-widget-container figure { + padding: 0 !important; + } + + .mantine-Modal-root figure { + padding: 0 !important; + } + +@font-face { + font-family: "Linux Biolinum Keyboard"; + src: url(../fonts/LinBiolinum_Kah.ttf); +} + +.keys { + font-family: "Linux Biolinum Keyboard", sans-serif; +} + +.bd-article-container h1, .bd-article-container h2, .bd-article-container h3, .bd-article-container h4, .bd-article-container h5, .bd-article-container p.caption { + color: black; +} diff --git a/docs/_static/css/examples.css b/docs/_static/css/examples.css new file mode 100644 index 000000000..bb641d751 --- /dev/null +++ b/docs/_static/css/examples.css @@ -0,0 +1,223 @@ +:root { + --ray-example-gallery-gap-x: 18px; + --ray-example-gallery-gap-y: 22px; + --sidebar-top: 5em; +} + +#site-navigation { + width: 330px !important; + border-right: none; + margin-left: 32px; + overflow-y: auto; + max-height: calc(100vh - var(--sidebar-top)); + position: sticky; + top: var(--sidebar-top) !important; + z-index: 1000; +} + +#site-navigation h5 { + font-size: 16px; + font-weight: 600; + color: #000; +} + +#site-navigation h6 { + font-size: 14px; + font-weight: 600; + color: #000; + text-transform: uppercase; +} + +/* Hide the default sidebar content */ +#site-navigation > div.bd-sidebar__content { + display: none; +} +#site-navigation > div.rtd-footer-container { + display: none; +} + +.searchDiv { + margin-bottom: 2em; +} + +#searchInput { + width: 100%; + color: #5F6469; + border: 1px solid #D2DCE6; + height: 50px; + border-radius: 4px; + background-color: #F9FAFB; + background-image: url("data:image/svg+xml,%3Csvg width='25' height='25' viewBox='0 0 25 25' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg id='Systems / search-line' clip-path='url(%23clip0_1_150)'%3E%3Crect width='24' height='24' transform='translate(0.398529 0.0546875)' fill='%23F9FAFB'/%3E%3Cg id='Group'%3E%3Cpath id='Vector' d='M18.4295 16.6717L22.7125 20.9537L21.2975 22.3687L17.0155 18.0857C15.4223 19.3629 13.4405 20.0576 11.3985 20.0547C6.43053 20.0547 2.39853 16.0227 2.39853 11.0547C2.39853 6.08669 6.43053 2.05469 11.3985 2.05469C16.3665 2.05469 20.3985 6.08669 20.3985 11.0547C20.4014 13.0967 19.7068 15.0784 18.4295 16.6717ZM16.4235 15.9297C17.6926 14.6246 18.4014 12.8751 18.3985 11.0547C18.3985 7.18669 15.2655 4.05469 11.3985 4.05469C7.53053 4.05469 4.39853 7.18669 4.39853 11.0547C4.39853 14.9217 7.53053 18.0547 11.3985 18.0547C13.219 18.0576 14.9684 17.3488 16.2735 16.0797L16.4235 15.9297V15.9297Z' fill='%238C9196'/%3E%3C/g%3E%3C/g%3E%3Cdefs%3E%3CclipPath id='clip0_1_150'%3E%3Crect width='24' height='24' fill='white' transform='translate(0.398529 0.0546875)'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E%0A"); + background-repeat: no-repeat; + background-position-x: 0.5em; + background-position-y: center; + background-size: 1.5em; + padding-left: 3em; +} + +#searchInput::placeholder { + color: #5F6469; + opacity: 1; +} + +.tag { + margin-bottom: 5px; + font-size: small; + color: #000000; + border: 1px solid #D2DCE6; + border-radius: 14px; + display: flex; + flex-direction: row; + align-items: center; + width: fit-content; + gap: 1em; +} + +.tag.btn-outline-primary { + color: #000000; + padding: 3px 12px 3px 12px; + line-height: 20px; +} + +.tag-btn-wrapper { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 1em; +} + +div.sd-container-fluid.docutils > div { + gap: var(--ray-example-gallery-gap-y) var(--ray-example-gallery-gap-x); + display: grid; + grid-template-columns: 1fr; +} + +/* Reflow to a 2-column format for normal screens */ +@media screen and (min-width: 768px) { + div.sd-container-fluid.docutils > div { + grid-template-columns: 1fr 1fr; + } +} + +div.gallery-item { + width: auto; +} + +div.gallery-item > div.sd-card { + border-radius: 8px; + box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.05) !important; +} + +/* Example gallery "Tutorial" title */ +div.sd-card-title > span.sd-bg-success.sd-bg-text-success { + color: #2F80ED !important; + font-weight: 500; + background: linear-gradient(180deg, rgba(25, 177, 226, 0.2) 0%, rgba(0, 109, 255, 0.2) 100%); + background-color: initial !important; +} + +/* Example gallery "Code example" title */ +div.sd-card-title > span.sd-bg-secondary.sd-bg-text-secondary { + color: #219653 !important; + font-weight: 500; + background: linear-gradient(180deg, rgba(29, 151, 108, 0.2) 0%, rgba(0, 226, 147, 0.2) 100%); + background-color: initial !important; +} + +/* Example gallery "Blog" title */ +div.sd-card-title > span.sd-bg-primary.sd-bg-text-primary { + color: #F2994A !important; + font-weight: 500; + background: linear-gradient(180deg, rgba(255, 230, 5, 0.2) 0%, rgba(255, 185, 80, 0.2) 100%); + background-color: initial !important; +} + +/* Example gallery "Video" title */ +div.sd-card-title > span.sd-bg-warning.sd-bg-text-warning { + color: #EB5757 !important; + font-weight: 500; + background: linear-gradient(180deg, rgba(150, 7, 7, 0.2) 0%, rgba(255, 115, 115, 0.2) 100%); + background-color: initial !important; +} + +/* Example gallery "Course" title */ +div.sd-card-title > span.sd-bg-info.sd-bg-text-info { + color: #7A64FF !important; + font-weight: 500; + background: linear-gradient(180deg, rgba(53, 25, 226, 0.2) 0%, rgba(183, 149, 255, 0.2) 100%); + background-color: initial !important; +} + +div.sd-card-body > p.sd-card-text > a { + text-align: initial; +} + +div.sd-card-body > p.sd-card-text > a > span { + color: rgb(81, 81, 81); +} + +#main-content { + max-width: 100%; +} + +#noMatches { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +#noMatchesInnerContent { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +#noMatches.hidden,.gallery-item.hidden { + display: none !important; +} + +.btn-primary { + color: #004293; + background: rgba(61, 138, 233, 0.20); + padding: 3px 12px 3px 12px; + border: 1px solid #D2DCE6; +} + +button.try-anyscale { + background-color: initial !important; + width: fit-content; + padding: 0 !important; + margin-left: auto !important; + float: initial !important; +} + +button.try-anyscale > svg { + display: none; +} + +button.try-anyscale > i { + display: none; +} + +button.try-anyscale > span { + margin: 0; + text-decoration-line: underline; + font-weight: 500; + color: #000; +} + +.top-nav-content { + justify-content: initial; +} + +/* Hide nav bar that has github, fullscreen, and print icons */ +div.header-article.row.sticky-top.noprint { + display: none !important; +} + +/* Hide the footer with 'prev article' and 'next article' buttons */ +.footer-article.hidden { + display: none !important; +} diff --git a/docs/_static/css/termynal.css b/docs/_static/css/termynal.css new file mode 100644 index 000000000..391a48078 --- /dev/null +++ b/docs/_static/css/termynal.css @@ -0,0 +1,108 @@ +/** + * termynal.js + * + * @author Ines Montani + * @version 0.0.1 + * @license MIT + */ + + :root { + --color-bg: #252a33; + --color-text: #eee; + --color-text-subtle: #a2a2a2; +} + +[data-termynal] { + width: auto; + max-width: 100%; + background: var(--color-bg); + color: var(--color-text); + font-size: 18px; + font-family: 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace; + border-radius: 4px; + padding: 75px 45px 35px; + position: relative; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +[data-termynal]:before { + content: ''; + position: absolute; + top: 15px; + left: 15px; + display: inline-block; + width: 15px; + height: 15px; + border-radius: 50%; + /* A little hack to display the window buttons in one pseudo element. */ + background: #d9515d; + -webkit-box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930; + box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930; +} + +[data-termynal]:after { + content: 'bash'; + position: absolute; + color: var(--color-text-subtle); + top: 5px; + left: 0; + width: 100%; + text-align: center; +} + +[data-ty] { + display: block; + line-height: 2; +} + +[data-ty]:before { + /* Set up defaults and ensure empty lines are displayed. */ + content: ''; + display: inline-block; + vertical-align: middle; +} + +[data-ty="input"]:before, +[data-ty-prompt]:before { + margin-right: 0.75em; + color: var(--color-text-subtle); +} + +[data-ty="input"]:before { + content: '$'; +} + +[data-ty][data-ty-prompt]:before { + content: attr(data-ty-prompt); +} + +[data-ty-cursor]:after { + content: attr(data-ty-cursor); + font-family: monospace; + margin-left: 0.5em; + -webkit-animation: blink 1s infinite; + animation: blink 1s infinite; +} + +a[data-terminal-control] { + text-align: right; + display: block; + color: #aebbff; +} + + +/* Cursor animation */ + +@-webkit-keyframes blink { + 50% { + opacity: 0; + } +} + +@keyframes blink { + 50% { + opacity: 0; + } +} + diff --git a/docs/_static/css/use_cases.css b/docs/_static/css/use_cases.css new file mode 100644 index 000000000..5678d2245 --- /dev/null +++ b/docs/_static/css/use_cases.css @@ -0,0 +1,23 @@ +.query-param-ref-wrapper { + display: flex; + justify-content: center; + align-items: center; + border: 1px solid #8C9196; + border-radius: 8px; +} + +.example-gallery-link { + padding: 1em 2em 1em 2em; + text-decoration: none !important; + color: black !important; + display: flex; + align-items: center; +} + +/* Shooting star icon next to gallery links */ +a.example-gallery-link::before { + content: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg id='Group'%3E%3Cpath id='Vector' d='M15.199 9.945C14.7653 9.53412 14.4863 8.98641 14.409 8.394L14.006 5.311L11.276 6.797C10.7511 7.08302 10.1436 7.17943 9.55597 7.07L6.49997 6.5L7.06997 9.556C7.1794 10.1437 7.08299 10.7511 6.79697 11.276L5.31097 14.006L8.39397 14.409C8.98603 14.4865 9.53335 14.7655 9.94397 15.199L12.082 17.456L13.418 14.649C13.6744 14.1096 14.1087 13.6749 14.648 13.418L17.456 12.082L15.199 9.945ZM15.224 15.508L13.011 20.158C12.9691 20.2459 12.9065 20.3223 12.8285 20.3806C12.7505 20.4389 12.6594 20.4774 12.5633 20.4926C12.4671 20.5079 12.3686 20.4995 12.2764 20.4682C12.1842 20.4369 12.101 20.3836 12.034 20.313L8.49197 16.574C8.39735 16.4742 8.27131 16.41 8.13497 16.392L3.02797 15.724C2.93149 15.7113 2.83954 15.6753 2.76006 15.6191C2.68058 15.563 2.61596 15.4883 2.57177 15.4016C2.52758 15.3149 2.50514 15.2187 2.5064 15.1214C2.50765 15.0241 2.53256 14.9285 2.57897 14.843L5.04097 10.319C5.10642 10.198 5.12831 10.0582 5.10297 9.923L4.15997 4.86C4.14207 4.76417 4.14778 4.66541 4.17662 4.57229C4.20546 4.47916 4.25656 4.39446 4.3255 4.32553C4.39444 4.25659 4.47913 4.20549 4.57226 4.17665C4.66539 4.14781 4.76414 4.14209 4.85997 4.16L9.92297 5.103C10.0582 5.12834 10.198 5.10645 10.319 5.041L14.843 2.579C14.9286 2.53257 15.0242 2.50769 15.1216 2.50648C15.219 2.50528 15.3152 2.52781 15.4019 2.57211C15.4887 2.61641 15.5633 2.68116 15.6194 2.76076C15.6755 2.84036 15.7114 2.93242 15.724 3.029L16.392 8.135C16.4099 8.27134 16.4742 8.39737 16.574 8.492L20.313 12.034C20.3836 12.101 20.4369 12.1842 20.4682 12.2765C20.4995 12.3687 20.5079 12.4671 20.4926 12.5633C20.4774 12.6595 20.4389 12.7505 20.3806 12.8285C20.3223 12.9065 20.2459 12.9691 20.158 13.011L15.508 15.224C15.3835 15.2832 15.2832 15.3835 15.224 15.508ZM16.021 17.435L17.435 16.021L21.678 20.263L20.263 21.678L16.021 17.435Z' fill='black'/%3E%3C/g%3E%3C/svg%3E%0A"); + display: flex; + align-items: center; + margin-right: 0.5em; +} diff --git a/docs/conf.py b/docs/conf.py index 437aeab9b..f29e9f73e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,7 +14,7 @@ project = "DB-GPT" copyright = "2023, csunny" author = "csunny" -version = "👏👏 0.4.0" +version = "👏👏 0.4.1" html_title = project + " " + version # -- General configuration --------------------------------------------------- @@ -67,6 +67,14 @@ locales_dirs = ["./locales/"] gettext_compact = False gettext_uuid = True + +def setup(app): + app.add_css_file("css/custom.css") + app.add_css_file("css/examples.css") + app.add_css_file("css/termynal.css") + # app.add_css_file("css/use_cases.css") + + # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output diff --git a/docs/getting_started/install/deploy.rst b/docs/getting_started/install/deploy.rst index 2c6b26b84..acb643d4a 100644 --- a/docs/getting_started/install/deploy.rst +++ b/docs/getting_started/install/deploy.rst @@ -5,11 +5,6 @@ Installation From Source To get started, install DB-GPT with the following steps. -DB-GPT can be deployed on servers with low hardware requirements or on servers with high hardware requirements. -You can install DB-GPT by Using third-part LLM REST API Service OpenAI, Azure. - -And you can also install DB-GPT by deploy LLM Service by download LLM model. - 1.Preparation ----------------- @@ -23,7 +18,7 @@ And you can also install DB-GPT by deploy LLM Service by download LLM model. We use Sqlite as default database, so there is no need for database installation. If you choose to connect to other databases, you can follow our tutorial for installation and configuration. For the entire installation process of DB-GPT, we use the miniconda3 virtual environment. Create a virtual environment and install the Python dependencies. -:ref: `https://docs.conda.io/en/latest/miniconda.html` +`How to install Miniconda `_ .. code-block:: shell @@ -43,6 +38,21 @@ DB-GPT can be deployed on servers with low hardware requirements or on servers w If you are low hardware requirements you can install DB-GPT by Using third-part LLM REST API Service OpenAI, Azure, tongyi. +.. tip:: + + As our project has the ability to achieve OpenAI performance of over 85%, + + +.. note:: + + Notice make sure you have install git-lfs + + centos:yum install git-lfs + + ubuntu:apt-get install git-lfs + + macos:brew install git-lfs + .. tabs:: .. tab:: OpenAI @@ -73,7 +83,7 @@ If you are low hardware requirements you can install DB-GPT by Using third-part .. tab:: Vicuna - ([Vicuna-v1.5](https://huggingface.co/lmsys/vicuna-13b-v1.5) based on llama-2 has been released, we recommend you set `LLM_MODEL=vicuna-13b-v1.5` to try this model) + `Vicuna-v1.5 `_ based on llama-2 has been released, we recommend you set `LLM_MODEL=vicuna-13b-v1.5` to try this model) .. list-table:: vicuna-v1.5 hardware requirements :widths: 50 50 50 @@ -96,17 +106,6 @@ If you are low hardware requirements you can install DB-GPT by Using third-part - 20 GB - .. note:: - - Notice make sure you have install git-lfs - - centos:yum install git-lfs - - ubuntu:apt-get install git-lfs - - macos:brew install git-lfs - - .. code-block:: shell cd DB-GPT @@ -151,16 +150,6 @@ If you are low hardware requirements you can install DB-GPT by Using third-part - 8-bit - 20 GB - .. note:: - - Notice make sure you have install git-lfs - - centos:yum install git-lfs - - ubuntu:apt-get install git-lfs - - macos:brew install git-lfs - .. code-block:: shell @@ -189,16 +178,6 @@ If you are low hardware requirements you can install DB-GPT by Using third-part .. tab:: ChatGLM - .. note:: - - Notice make sure you have install git-lfs - - centos:yum install git-lfs - - ubuntu:apt-get install git-lfs - - macos:brew install git-lfs - .. code-block:: shell @@ -302,7 +281,7 @@ If you are low hardware requirements you can install DB-GPT by Using third-part .. tab:: llama.cpp - DB-GPT already supports [llama.cpp](https://github.com/ggerganov/llama.cpp) via [llama-cpp-python](https://github.com/abetlen/llama-cpp-python). + DB-GPT already supports `llama.cpp `_ via `llama-cpp-python `_ . **Preparing Model Files** @@ -338,7 +317,7 @@ If you are low hardware requirements you can install DB-GPT by Using third-part LLM_MODEL=llama-cpp llama_cpp_prompt_template=vicuna_v1.1 - Then you can run it according to [Run](https://db-gpt.readthedocs.io/en/latest/getting_started/install/deploy/deploy.html#run). + Then you can run it according to `Run `_ **More Configurations** @@ -404,8 +383,9 @@ If you are low hardware requirements you can install DB-GPT by Using third-part LLM_MODEL=vicuna-13b-v1.5 MODEL_TYPE=vllm + You can view the models supported by vLLM `here `_ - + Then you can run it according to `Run `_ @@ -415,24 +395,23 @@ If you are low hardware requirements you can install DB-GPT by Using third-part ----------------- **(Optional) load examples into SQLite** - .. code-block:: shell +.. code-block:: shell - bash ./scripts/examples/load_examples.sh + bash ./scripts/examples/load_examples.sh - On windows platform: +On windows platform: - .. code-block:: shell +.. code-block:: shell - .\scripts\examples\load_examples.bat + .\scripts\examples\load_examples.bat 4.Run db-gpt server ----------------- - .. code-block:: shell +.. code-block:: shell - - python pilot/server/dbgpt_server.py + python pilot/server/dbgpt_server.py **Open http://localhost:5000 with your browser to see the product.** diff --git a/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po b/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po new file mode 100644 index 000000000..4b329573a --- /dev/null +++ b/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po @@ -0,0 +1,629 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2023, csunny +# This file is distributed under the same license as the DB-GPT package. +# FIRST AUTHOR , 2023. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: DB-GPT 👏👏 0.4.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-11-03 13:00+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language: zh_CN\n" +"Language-Team: zh_CN \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.12.1\n" + +#: ../../getting_started/install/deploy.rst:4 7a1ee708aa40431981178ebd1d34b9aa +msgid "Installation From Source" +msgstr "源码安装" + +#: ../../getting_started/install/deploy.rst:6 dd4c542c563b4d4ca5b710dc7326ff8b +msgid "To get started, install DB-GPT with the following steps." +msgstr "按照以下步骤进行安装" + +#: ../../getting_started/install/deploy.rst:8 f352a8d93da744aaab775e8290c74704 +msgid "" +"DB-GPT can be deployed on servers with low hardware requirements or on " +"servers with high hardware requirements. You can install DB-GPT by Using " +"third-part LLM REST API Service OpenAI, Azure." +msgstr "" + +#: ../../getting_started/install/deploy.rst:11 b89bfaa679d5448791d315b9ffebe7c5 +msgid "" +"And you can also install DB-GPT by deploy LLM Service by download LLM " +"model." +msgstr "" + +#: ../../getting_started/install/deploy.rst:15 942b2999b3b5432e956c44e2a51b5269 +msgid "1.Preparation" +msgstr "1.准备" + +#: ../../getting_started/install/deploy.rst:16 d27c8698bd4a45d7a7ebdbba470318d6 +msgid "**Download DB-GPT**" +msgstr "**下载DB-GPT项目**" + +#: ../../getting_started/install/deploy.rst:22 ce3e61a03ca945b4a3c3b264a063442c +msgid "**Install Miniconda**" +msgstr "**安装Miniconda**" + +#: ../../getting_started/install/deploy.rst:24 1fd868a2e84c4752b242b401ac64d0e4 +msgid "" +"We use Sqlite as default database, so there is no need for database " +"installation. If you choose to connect to other databases, you can " +"follow our tutorial for installation and configuration. For the entire " +"installation process of DB-GPT, we use the miniconda3 virtual " +"environment. Create a virtual environment and install the Python " +"dependencies. `How to install Miniconda " +"`_" +msgstr "" +"目前使用Sqlite作为默认数据库,因此DB-" +"GPT快速部署不需要部署相关数据库服务。如果你想使用其他数据库,需要先部署相关数据库服务。我们目前使用Miniconda进行python环境和包依赖管理[安装" +" Miniconda](https://docs.conda.io/en/latest/miniconda.html)" + +#: ../../getting_started/install/deploy.rst:41 59dc27ad4237444d8eb7229fe29c975d +msgid "2.Deploy LLM Service" +msgstr "2.部署LLM服务" + +#: ../../getting_started/install/deploy.rst:42 12ed83127fb744bcb60c5c7c16359a0e +msgid "" +"DB-GPT can be deployed on servers with low hardware requirements or on " +"servers with high hardware requirements." +msgstr "DB-GPT可以部署在对硬件要求不高的服务器,也可以部署在对硬件要求高的服务器" + +#: ../../getting_started/install/deploy.rst:44 1674c59c24804200ab53bd31847be19a +msgid "" +"If you are low hardware requirements you can install DB-GPT by Using " +"third-part LLM REST API Service OpenAI, Azure, tongyi." +msgstr "Low hardware requirements模式适用于对接第三方模型服务的api,比如OpenAI, 通义千问, 文心.cpp。" + +#: ../../getting_started/install/deploy.rst:48 e9c37648778540fe982c26d4104931ae +msgid "As our project has the ability to achieve OpenAI performance of over 85%," +msgstr "使用OpenAI服务可以让DB-GPT准确率达到85%" + +#: ../../getting_started/install/deploy.rst:53 201b7af45c0046faada4b81e110e7745 +msgid "Notice make sure you have install git-lfs" +msgstr "确认是否已经安装git-lfs" + +#: ../../getting_started/install/deploy.rst:55 f7c9535c0eb546f7b1389a181b08c5c0 +msgid "centos:yum install git-lfs" +msgstr "" + +#: ../../getting_started/install/deploy.rst:57 8fb3efededcb42c592fa27b03c4e9a65 +msgid "ubuntu:apt-get install git-lfs" +msgstr "" + +#: ../../getting_started/install/deploy.rst:59 b3df472ae3ae470d94112f7327787e13 +msgid "macos:brew install git-lfs" +msgstr "" + +#: ../../getting_started/install/deploy.rst:63 +#: ../../getting_started/install/deploy.rst:226 +#: 070a6d653f6740cf852ddaf036ac2538 635662e449d34d5b9f6316898d14e0a6 +msgid "OpenAI" +msgstr "OpenAI" + +#: ../../getting_started/install/deploy.rst:65 +#: ../../getting_started/install/deploy.rst:212 +#: 1ff3d5d9f9814e638f118925bedb7800 59cda8abcdc7471eb0a488610121a533 +msgid "Download embedding model" +msgstr "下载embedding model" + +#: ../../getting_started/install/deploy.rst:77 +#: ../../getting_started/install/deploy.rst:234 +#: 0c68e075ab7840bd9d75ced89deaea86 b9e25c8690da4d9c94c012a04ddc8f0d +msgid "Configure LLM_MODEL and PROXY_API_URL and API_KEY in `.env` file" +msgstr "在`.env`文件设置LLM_MODEL and PROXY_API_URL and API_KEY" + +#: ../../getting_started/install/deploy.rst:87 +#: ../../getting_started/install/deploy.rst:285 +#: 5eb0e6ffb66a48dfa05cfea8414b21c5 61b75bb879d64726976c131f0f7cea83 +msgid "Make sure your .env configuration is not overwritten" +msgstr "认.env文件不会被覆盖\"" + +#: ../../getting_started/install/deploy.rst:90 d14c2a247eee401bae9b1711cdcc0712 +msgid "Vicuna" +msgstr "Vicuna" + +#: ../../getting_started/install/deploy.rst:91 d59e03c9d3c3405ea04d814bffc59ef8 +msgid "" +"`Vicuna-v1.5 `_ based on " +"llama-2 has been released, we recommend you set `LLM_MODEL=vicuna-" +"13b-v1.5` to try this model)" +msgstr "" + +#: ../../getting_started/install/deploy.rst:93 c6d22fb4c35c40378159e7845c87bb51 +msgid "vicuna-v1.5 hardware requirements" +msgstr "" + +#: ../../getting_started/install/deploy.rst:97 +#: ../../getting_started/install/deploy.rst:142 +#: 215382b66c944bef8ba8d081792cb3c5 eadfd6f7230f49a4a9d5552b51d766c0 +msgid "Model" +msgstr "" + +#: ../../getting_started/install/deploy.rst:98 +#: ../../getting_started/install/deploy.rst:143 +#: 5eca1dbe065b4e648ee00ca118e84214 abec181550804601ad54500469b332f9 +msgid "Quantize" +msgstr "" + +#: ../../getting_started/install/deploy.rst:99 +#: ../../getting_started/install/deploy.rst:144 +#: 24a907ffe6e4449abb632d80ada8733c 472a99174d68460a84a72d65d9fdcd07 +msgid "VRAM Size" +msgstr "" + +#: ../../getting_started/install/deploy.rst:100 +#: ../../getting_started/install/deploy.rst:103 +#: 87bba38be8f24c0688431a5985622d33 e8c8ef23e4964d059d9615f41719d05f +msgid "vicuna-7b-v1.5" +msgstr "" + +#: ../../getting_started/install/deploy.rst:101 +#: ../../getting_started/install/deploy.rst:107 +#: ../../getting_started/install/deploy.rst:146 +#: ../../getting_started/install/deploy.rst:152 +#: 7695fa31995b4e038ac4359df76a0a2f a8c361af629c4a179c811ac39ef16c3c +#: defc11c71d45471da982eb7c96039450 f9362395c5ff4213b5fb2f4d1e430496 +msgid "4-bit" +msgstr "" + +#: ../../getting_started/install/deploy.rst:102 +#: ../../getting_started/install/deploy.rst:147 +#: 7f2ebb804fb042c1b24cf6274c2cb7fc 9604200fbd974a6e9e3d66a38f9e5895 +msgid "8 GB" +msgstr "" + +#: ../../getting_started/install/deploy.rst:104 +#: ../../getting_started/install/deploy.rst:110 +#: ../../getting_started/install/deploy.rst:149 +#: ../../getting_started/install/deploy.rst:155 +#: 4936725d2b0a47f39286453db766027c 879daa7be9e243b7a8a51f0859459096 +#: c5322eaace39472282941c4bcae87232 e79778e8505e490a912aa80c28e37b0c +msgid "8-bit" +msgstr "" + +#: ../../getting_started/install/deploy.rst:105 +#: ../../getting_started/install/deploy.rst:108 +#: ../../getting_started/install/deploy.rst:150 +#: ../../getting_started/install/deploy.rst:153 +#: 09cd46eb89234d1cbbaf9fccd2d7f206 531282962fd148108a5d4582022b9d11 +#: c2249464c63b4808a13be66c6a04653d c54d26deb5e14bbc9ebeefe751ee32a1 +msgid "12 GB" +msgstr "" + +#: ../../getting_started/install/deploy.rst:106 +#: ../../getting_started/install/deploy.rst:109 +#: 40d56aeeeeae4ad5a08d432da14c91f6 a4aae2c08b35462699a074c20436b583 +msgid "vicuna-13b-v1.5" +msgstr "" + +#: ../../getting_started/install/deploy.rst:111 +#: ../../getting_started/install/deploy.rst:156 +#: 4e58bb5b42d043b8b8105ff1424b3dda 670a8f2e7d9a4f56b338a890a0e6179c +msgid "20 GB" +msgstr "" + +#: ../../getting_started/install/deploy.rst:127 +#: ../../getting_started/install/deploy.rst:174 +#: ../../getting_started/install/deploy.rst:200 +#: 7aec36decef845a4979e4d72b5556166 edb0520c46de41e79a56453901f5dbda +#: f726ecdc3a3b40eeb527464e705d262c +msgid "The model files are large and will take a long time to download." +msgstr "" + +#: ../../getting_started/install/deploy.rst:129 +#: ../../getting_started/install/deploy.rst:176 +#: ../../getting_started/install/deploy.rst:202 +#: 1ced4f4cd3ca4b4a8a545ba4625e5888 1f3fc32e037846ecba6e9d99acaa341e +#: 2e2a3b69997043858a21ce88c349fd87 +msgid "**Configure LLM_MODEL in `.env` file**" +msgstr "" + +#: ../../getting_started/install/deploy.rst:136 +#: ../../getting_started/install/deploy.rst:231 +#: 0ae3d2ff947545fb8ae3a3221ada4fca 908164bbe3f745cf994b65c7cc0d4f42 +msgid "Baichuan" +msgstr "" + +#: ../../getting_started/install/deploy.rst:138 +#: 4249581eb6eb4c90ac467c3b23f9cf47 +msgid "Baichuan hardware requirements" +msgstr "" + +#: ../../getting_started/install/deploy.rst:145 +#: ../../getting_started/install/deploy.rst:148 +#: c01aea1eaf0c4d0ca14c10e51003fa2e f1081e1ecc6b42b6a7d227cf4a3b9aa9 +msgid "baichuan-7b" +msgstr "" + +#: ../../getting_started/install/deploy.rst:151 +#: ../../getting_started/install/deploy.rst:154 +#: 1cf37d7196814348a177341d80d9748a edf669023f5647c89c52475f385dd91f +msgid "baichuan-13b" +msgstr "" + +#: ../../getting_started/install/deploy.rst:178 +#: 25e45bdc7e6b475080f8b39cd555746d +msgid "please rename Baichuan path to \"baichuan2-13b\" or \"baichuan2-7b\"" +msgstr "将Baichuan模型目录修改为\"baichuan2-13b\" 或 \"baichuan2-7b\"" + +#: ../../getting_started/install/deploy.rst:184 +#: 80c36809333c4e2490166571222963cc +msgid "ChatGLM" +msgstr "" + +#: ../../getting_started/install/deploy.rst:204 +#: f1e3c93f447b40039a57d278d49ff32d +msgid "please rename chatglm model path to \"chatglm2-6b\"" +msgstr "将chatglm模型目录修改为\"chatglm2-6b\"" + +#: ../../getting_started/install/deploy.rst:210 +#: 62570cd6084a4b3c8ceff5fdd5234aa0 +msgid "Other LLM API" +msgstr "" + +#: ../../getting_started/install/deploy.rst:227 +#: fb0c2d274f3740a2af7ece03fdb81d22 +msgid "Azure" +msgstr "" + +#: ../../getting_started/install/deploy.rst:228 +#: 13e28550c95e4838b9e35a064448f9ca +msgid "Aliyun tongyi" +msgstr "" + +#: ../../getting_started/install/deploy.rst:229 +#: 32d7289e7e514db5b3f49ebad9eb0e46 +msgid "Baidu wenxin" +msgstr "" + +#: ../../getting_started/install/deploy.rst:230 +#: b8033cd9b67d4b18823fc2053e23114b +msgid "Zhipu" +msgstr "" + +#: ../../getting_started/install/deploy.rst:232 +#: 9cc479d40a3f435a81e8e2aa8c015bbe +msgid "Bard" +msgstr "" + +#: ../../getting_started/install/deploy.rst:287 +#: abd4caa347e3405f86319825c14b3b4a +msgid "llama.cpp" +msgstr "" + +#: ../../getting_started/install/deploy.rst:289 +#: b3b53e55206345e8b332af19851f5a5f +msgid "" +"DB-GPT already supports `llama.cpp " +"`_ via `llama-cpp-python " +"`_ ." +msgstr "" +"DB-GPT 已经支持了 `llama.cpp `_ via " +"`llama-cpp-python `_ ." + +#: ../../getting_started/install/deploy.rst:291 +#: 54fc351de03445e7b4b7a5408215c0cf +msgid "**Preparing Model Files**" +msgstr "**准备Model文件**" + +#: ../../getting_started/install/deploy.rst:293 +#: 41e7c90a891d47c1ae04883454cf999f +msgid "" +"To use llama.cpp, you need to prepare a gguf format model file, and there" +" are two common ways to obtain it, you can choose either:" +msgstr "使用 llama.cpp,你需要准备 gguf 格式的文件,你可以通过以下两种方法获取" + +#: ../../getting_started/install/deploy.rst:295 +#: 8aefa2f2e0ab47469717aff4af20668e +msgid "**1. Download a pre-converted model file.**" +msgstr "**1.下载已转换的模型文件.**" + +#: ../../getting_started/install/deploy.rst:297 +#: 9849e3b8c0824cfa9add58a97fb583c4 +msgid "" +"Suppose you want to use [Vicuna 13B v1.5](https://huggingface.co/lmsys" +"/vicuna-13b-v1.5), you can download the file already converted from " +"[TheBloke/vicuna-13B-v1.5-GGUF](https://huggingface.co/TheBloke/vicuna-" +"13B-v1.5-GGUF), only one file is needed. Download it to the `models` " +"directory and rename it to `ggml-model-q4_0.gguf`." +msgstr "" +"假设您想使用[Vicuna 13B v1.5](https://huggingface.co/lmsys/vicuna-" +"13b-v1.5)您可以从[TheBloke/vicuna-" +"13B-v1.5-GGUF](https://huggingface.co/TheBloke/vicuna-" +"13B-v1.5-GGUF)下载已转换的文件,只需要一个文件。将其下载到models目录并将其重命名为 `ggml-" +"model-q4_0.gguf`。" + +#: ../../getting_started/install/deploy.rst:303 +#: b79538a3af8a4946b24d8ebdb343e8aa +msgid "**2. Convert It Yourself**" +msgstr "**2. 自行转换**" + +#: ../../getting_started/install/deploy.rst:305 +#: 12f31f96202f4789af86c254feaac717 +msgid "" +"You can convert the model file yourself according to the instructions in " +"[llama.cpp#prepare-data--run](https://github.com/ggerganov/llama.cpp" +"#prepare-data--run), and put the converted file in the models directory " +"and rename it to `ggml-model-q4_0.gguf`." +msgstr "" +"您可以根据[llama.cpp#prepare-data--run](https://github.com/ggerganov/llama.cpp" +"#prepare-data--run)中的说明自行转换模型文件,并把转换后的文件放在models目录中,并重命名为`ggml-" +"model-q4_0.gguf`。" + +#: ../../getting_started/install/deploy.rst:307 +#: c45612d904e64b3a8c0d50c564447853 +msgid "**Installing Dependencies**" +msgstr "**安装依赖**" + +#: ../../getting_started/install/deploy.rst:309 +#: c3c04c3e560a46bba53719472a25ce11 +msgid "" +"llama.cpp is an optional dependency in DB-GPT, and you can manually " +"install it using the following command:" +msgstr "llama.cpp在DB-GPT中是可选安装项, 你可以通过以下命令进行安装" + +#: ../../getting_started/install/deploy.rst:316 +#: 25f8ceb4fca941cdbd7c4dcc49818d79 +msgid "**3.Modifying the Configuration File**" +msgstr "**3.修改配置文件**" + +#: ../../getting_started/install/deploy.rst:318 +#: 5a63a04a43a1487eac56f2560dbc2275 +msgid "Next, you can directly modify your `.env` file to enable llama.cpp." +msgstr "修改`.env`文件使用llama.cpp" + +#: ../../getting_started/install/deploy.rst:325 +#: ../../getting_started/install/deploy.rst:393 +#: e8b1498ad8c44201ba2e050db454c61c ffcb505780884dddaf3559990405a081 +msgid "" +"Then you can run it according to `Run `_" +msgstr "" +"然后你可以根据[运行](https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-" +"cn/zh_CN/latest/getting_started/install/deploy/deploy.html#run)来运行" + +#: ../../getting_started/install/deploy.rst:328 +#: 0d8d0f68e43b465a9537fbc741a9d37f +msgid "**More Configurations**" +msgstr "**更多配置文件**" + +#: ../../getting_started/install/deploy.rst:330 +#: 6fdef4b280e5456faf11521700b7fe04 +msgid "" +"In DB-GPT, the model configuration can be done through `{model " +"name}_{config key}`." +msgstr "在DB-GPT中,模型配置可以通过`{模型名称}_{配置名}` 来配置。" + +#: ../../getting_started/install/deploy.rst:332 +#: 256b25378f3d4bfd902f155b3a4346ad +msgid "More Configurations" +msgstr "**更多配置文件**" + +#: ../../getting_started/install/deploy.rst:336 +#: ebe4390d2de44fd288379a439d99bccd +msgid "Environment Variable Key" +msgstr "环境变量Key" + +#: ../../getting_started/install/deploy.rst:337 +#: ee1c68623cc24446b4036870e0c7f21c +msgid "Default" +msgstr "默认值" + +#: ../../getting_started/install/deploy.rst:338 +#: ed6c358d27fb4022a70de1e733ad99cd +msgid "Description" +msgstr "描述" + +#: ../../getting_started/install/deploy.rst:339 +#: 4ad9e1b85c294cf084b8ebf858cc4075 +msgid "llama_cpp_prompt_template" +msgstr "" + +#: ../../getting_started/install/deploy.rst:340 +#: ../../getting_started/install/deploy.rst:343 +#: ../../getting_started/install/deploy.rst:349 +#: ../../getting_started/install/deploy.rst:355 +#: ../../getting_started/install/deploy.rst:361 +#: 0cfccd9b8f7043ec8ccfe5159dfcf2c3 155d01bf0ad94016a32a2ec18a0fd881 +#: 3a194e635268499a939990b3503da72e 8909fd33e33b4f5a9208b8338b82b20f +#: e32e3219d2384884b398054cecceec8a +msgid "None" +msgstr "" + +#: ../../getting_started/install/deploy.rst:341 +#: c395eb1a7b044536a7ed300320e230f5 +msgid "" +"Prompt template name, now support: zero_shot, vicuna_v1.1,alpaca,llama-2" +",baichuan-chat,internlm-chat, If None, the prompt template is " +"automatically determined from model path。" +msgstr "" +"Prompt template 现在可以支持`zero_shot, vicuna_v1.1,alpaca,llama-2,baichuan-" +"chat,internlm-chat`, 如果是None, 可以根据模型路径来自动获取模型 Prompt template" + +#: ../../getting_started/install/deploy.rst:342 +#: 8fb84e002d1f4fc79bd4465b161e018a +msgid "llama_cpp_model_path" +msgstr "" + +#: ../../getting_started/install/deploy.rst:344 +#: 81df474169634fbf9da20fe239d903a0 +msgid "Model path" +msgstr "模型路径" + +#: ../../getting_started/install/deploy.rst:345 +#: a94ac450e72940f78b8ba6f6c9854248 +msgid "llama_cpp_n_gpu_layers" +msgstr "" + +#: ../../getting_started/install/deploy.rst:346 +#: 06a24fb226f24ed4a93cde7034a3b67f +msgid "1000000000" +msgstr "" + +#: ../../getting_started/install/deploy.rst:347 +#: d29a8733688a4c62a3ea88e4793b82ef +msgid "" +"Number of layers to offload to the GPU, Set this to 1000000000 to offload" +" all layers to the GPU. If your GPU VRAM is not enough, you can set a low" +" number, eg: 10" +msgstr "要将多少网络层转移到GPU上,将其设置为1000000000以将所有层转移到GPU上。如果您的 GPU 内存不足,可以设置较低的数字,例如:10。" + +#: ../../getting_started/install/deploy.rst:348 +#: 8531ecd5690e46f2a9d64823405054b1 +msgid "llama_cpp_n_threads" +msgstr "" + +#: ../../getting_started/install/deploy.rst:350 +#: d22c11631f5b4bc3b9dabad2175f26d5 +msgid "" +"Number of threads to use. If None, the number of threads is automatically" +" determined" +msgstr "要使用的线程数量。如果为None,则线程数量将自动确定。" + +#: ../../getting_started/install/deploy.rst:351 +#: 06994945569849a9a07ca0fbb56509e4 +msgid "llama_cpp_n_batch" +msgstr "" + +#: ../../getting_started/install/deploy.rst:352 +#: a509c6b3800941aa8aaed1c2c3a89937 +msgid "512" +msgstr "" + +#: ../../getting_started/install/deploy.rst:353 +#: 02f71c7f7ddc49f6b61b163237f4c4fe +msgid "Maximum number of prompt tokens to batch together when calling llama_eval" +msgstr "在调用llama_eval时,批处理在一起的prompt tokens的最大数量" + +#: ../../getting_started/install/deploy.rst:354 +#: 4d0df2430c22464fac021d816b4fa0c3 +msgid "llama_cpp_n_gqa" +msgstr "" + +#: ../../getting_started/install/deploy.rst:356 +#: 24304fe7c331423ebcc9eb407d6f6f46 +msgid "Grouped-query attention. Must be 8 for llama-2 70b." +msgstr "对于 llama-2 70B 模型,Grouped-query attention 必须为8。" + +#: ../../getting_started/install/deploy.rst:357 +#: 8c6b332cdcc845dc9c218e3de7050e3e +msgid "llama_cpp_rms_norm_eps" +msgstr "" + +#: ../../getting_started/install/deploy.rst:358 +#: 2c2ac24d7d264be3aa6960e776fa5e56 +msgid "5e-06" +msgstr "" + +#: ../../getting_started/install/deploy.rst:359 +#: 2d7170d63e364aa3bb3040d96ba31316 +msgid "5e-6 is a good value for llama-2 models." +msgstr "对于llama-2模型来说,5e-6是一个不错的值。" + +#: ../../getting_started/install/deploy.rst:360 +#: 402b942db0b149a8985685dbfe6f31c7 +msgid "llama_cpp_cache_capacity" +msgstr "" + +#: ../../getting_started/install/deploy.rst:362 +#: c990275acf6741398ac147a8ddce1ce3 +msgid "Maximum cache capacity. Examples: 2000MiB, 2GiB" +msgstr "模型缓存最大值. 例如: 2000MiB, 2GiB" + +#: ../../getting_started/install/deploy.rst:363 +#: 5f579fac7df54a338dc3c8a348bc90ea +msgid "llama_cpp_prefer_cpu" +msgstr "" + +#: ../../getting_started/install/deploy.rst:364 +#: 8413a349be174d50991653a5554933c5 +msgid "False" +msgstr "" + +#: ../../getting_started/install/deploy.rst:365 +#: 78af815bd0724301870ef934d27b208d +msgid "" +"If a GPU is available, it will be preferred by default, unless " +"prefer_cpu=False is configured." +msgstr "如果有可用的GPU,默认情况下会优先使用GPU,除非配置了 prefer_cpu=False。" + +#: ../../getting_started/install/deploy.rst:368 +#: f193ef95a45f42d2a5e156a79ed09685 +msgid "vllm" +msgstr "" + +#: ../../getting_started/install/deploy.rst:370 +#: e28e1d550515498e8e41a2e1187f9956 +msgid "vLLM is a fast and easy-to-use library for LLM inference and serving." +msgstr "\"vLLM 是一个快速且易于使用的 LLM 推理和服务的库。" + +#: ../../getting_started/install/deploy.rst:372 +#: adbcb8083c274d5eae4209b5b4fb8048 +msgid "**Running vLLM**" +msgstr "**运行vLLM**" + +#: ../../getting_started/install/deploy.rst:374 +#: 188e0fb1d0d34fccb15a796707ca95dd +msgid "**1.Installing Dependencies**" +msgstr "**1.安装依赖**" + +#: ../../getting_started/install/deploy.rst:376 +#: dbfcdd5d0e2a4cb29692022e63766116 +msgid "" +"vLLM is an optional dependency in DB-GPT, and you can manually install it" +" using the following command:" +msgstr "vLLM 在 DB-GPT 是一个可选依赖, 你可以使用下面的命令手动安装它:" + +#: ../../getting_started/install/deploy.rst:382 +#: 4401138d25b34b028c4bf43ddfb89aa3 +msgid "**2.Modifying the Configuration File**" +msgstr "**2.修改配置文件**" + +#: ../../getting_started/install/deploy.rst:384 +#: ee0ad8661dce4b909b07df4773150ee6 +msgid "Next, you can directly modify your .env file to enable vllm." +msgstr "你可以直接修改你的 `.env` 文件" + +#: ../../getting_started/install/deploy.rst:391 +#: 1be59f77d774429b9959bf834871a414 +msgid "" +"You can view the models supported by vLLM `here " +"`_" +msgstr "你可以在 " +"[这里](https://vllm.readthedocs.io/en/latest/models/supported_models.html" +"#supported-models) 查看 vLLM 支持的模型。" + +#: ../../getting_started/install/deploy.rst:400 +#: def3d7d7cd03407d9dfeff2e1eee951e +msgid "3.Prepare sql example(Optional)" +msgstr "3.准备 sql example(可选)" + +#: ../../getting_started/install/deploy.rst:401 +#: b6038f79dac74fda8f6db08325bf0686 +msgid "**(Optional) load examples into SQLite**" +msgstr "**(可选) load examples into SQLite**" + +#: ../../getting_started/install/deploy.rst:408 +#: 37c84b22186b48baba5aca60f8a70f49 +msgid "On windows platform:" +msgstr "" + +#: ../../getting_started/install/deploy.rst:415 +#: 09c9508bac8a4330931d45d02c33762f +msgid "4.Run db-gpt server" +msgstr "4.运行db-gpt server" + +#: ../../getting_started/install/deploy.rst:421 +#: 04d68abe85a646388956cbd1b47f3232 +msgid "**Open http://localhost:5000 with your browser to see the product.**" +msgstr "打开浏览器访问http://localhost:5000" + diff --git a/docs/locales/zh_CN/LC_MESSAGES/modules/prompts.po b/docs/locales/zh_CN/LC_MESSAGES/modules/prompts.po index f2b5a19e2..810e20f04 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/modules/prompts.po +++ b/docs/locales/zh_CN/LC_MESSAGES/modules/prompts.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 👏👏 0.4.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-26 19:57+0800\n" +"POT-Creation-Date: 2023-11-03 11:47+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -17,13 +17,13 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.13.1\n" +"Generated-By: Babel 2.12.1\n" -#: ../../modules/prompts.md:1 00907f941b7743b99278d7fd0b67e5d3 +#: ../../modules/prompts.md:1 3c5bdc61dc4a4301acdc9775c854a896 msgid "Prompts" msgstr "Prompts" -#: ../../modules/prompts.md:3 f1c7042cba32483b90ab22db28e369a9 +#: ../../modules/prompts.md:3 118fc2b85e8b4e02a6868b3bc2a7892c msgid "" "**Prompt** is a very important part of the interaction between the large " "model and the user, and to a certain extent, it determines the quality " @@ -33,96 +33,116 @@ msgid "" "users to use large language models." msgstr "**Prompt**是大模型与用户交互中非常重要的一环,在一定程度上决定了大模型生成答案的质量和准确性。在这个项目中,我们会根据用户输入和使用场景自动地优化相应提示,让用户更轻松、更高效地使用大语言模型。" -#: ../../modules/prompts.md:5 695c05f96a2c4077a0a25f5f6dc22d31 +#: ../../modules/prompts.md:5 41614effa0a445b7b5a119311b902305 msgid "Prompt Management" msgstr "Prompt 管理" -#: ../../modules/prompts.md:7 325254a0ceba48b8aa19a4cf66d18c12 +#: ../../modules/prompts.md:7 a8ed0a7b3d1243ffa1ed80c24d1ab518 msgid "" "Here, you can choose to create a Prompt in **Public Prompts** space or " "**Private Prompts** space." msgstr "该页面允许用户选择**公共Prompts**或者**私有Prompts**空间来创建相应的 Prompt。" -#: ../../modules/prompts.md:11 4528a48a14d246d8874c1b31819d3f4f +#: ../../modules/prompts.md:9 ../../modules/prompts.md:17 +#: ../../modules/prompts.md:31 ../../modules/prompts.md:45 +#: 68db272acc6b4572aa275940da4b788b 92d46d647bbb4035add92f750511a840 +#: af1789fae8cb47b8a81e68520086f35e d7c2f6f43b5c406d82b7dc5bd92d183c +#: e2f91ca11e784fe5943d0738671f68bf +msgid "image" +msgstr "" + +#: ../../modules/prompts.md:11 102220bf95f04f81acc9a0093458f297 msgid "" "The difference between **Public Prompts** and **Private Prompts** is that" " Prompts in **Public Prompts** space can be viewed and used by all users," " while prompts in **Private Prompts** space can only be viewed and used " "by the owner." -msgstr "**公共 Prompts**和**私有 Prompts**空间的区别在于,**公共 Prompts**空间下的 Prompt 可供所有的用户查看和使用,而**私有 Prompts**空间下的 Prompt 只能被所有者查看和使用。" +msgstr "" +"**公共 Prompts**和**私有 Prompts**空间的区别在于,**公共 Prompts**空间下的 Prompt " +"可供所有的用户查看和使用,而**私有 Prompts**空间下的 Prompt 只能被所有者查看和使用。" -#: ../../modules/prompts.md:13 45fdbc12758c4cb3aa71f5616c75a6e6 +#: ../../modules/prompts.md:13 2e0d2f6b335a4aacbdc83b7b7042a701 msgid "Create Prompt" msgstr "创建 Prompt" -#: ../../modules/prompts.md:15 850b9c136d5949939c3966b6bff8204e +#: ../../modules/prompts.md:15 c9f8c3d1698941e08b90a35fffb2fce1 msgid "Click the \"Add Prompts\" button to pop up the following subpage:" msgstr "点击 \"新增Prompts\"按钮可以弹出如下的子页面:" -#: ../../modules/prompts.md:19 9db6614fcc454bddbf2e3257232e7c93 +#: ../../modules/prompts.md:19 23ed81a83ab2458f826f2b5d9c55a89a msgid "" "**Scene**: It is assumed here that when we have a lot of Prompts, we " "often classify the Prompts according to scene, such as Prompts in the " "chat knowledge scene, Prompts in the chat data scene, Prompts in the chat" " normal scene, etc." -msgstr "**场景**:这里假设,当我们有很多 Prompts 时,往往会根据场景对 Prompts 进行分类,比如在 DB-GPT 项目中,chat knowledge 场景的 Prompts、chat data 场景的 Prompts、chat normal 场景的 Prompts 等等。" +msgstr "" +"**场景**:这里假设,当我们有很多 Prompts 时,往往会根据场景对 Prompts 进行分类,比如在 DB-GPT 项目中,chat " +"knowledge 场景的 Prompts、chat data 场景的 Prompts、chat normal 场景的 Prompts 等等。" -#: ../../modules/prompts.md:21 45a0a38ceafe4575a5957b2de8c0661f +#: ../../modules/prompts.md:21 11299da493e741869fe67237f1cb1794 msgid "" "**Sub Scene**: Continuing with the above, assuming that we have a lot of " "Prompts, scene classification alone is not enough. For example, in the " "chat data scenario, there can be many types of sub-scene: anomaly " "recognition sub scene, attribution analysis sub scene, etc. sub scene is " "used to distinguish subcategories under each scene." -msgstr "**次级场景**:接着上面的内容,如果我们的 Prompt 很多时,仅使用场景一级分类是不够的。例如,在 chat data 场景中,还可以细分为很多的次级场景:异常识别次级场景、归因分析次级场景等等。次级场景是用于区分每个场景下的子类别。" +msgstr "" +"**次级场景**:接着上面的内容,如果我们的 Prompt 很多时,仅使用场景一级分类是不够的。例如,在 chat data " +"场景中,还可以细分为很多的次级场景:异常识别次级场景、归因分析次级场景等等。次级场景是用于区分每个场景下的子类别。" -#: ../../modules/prompts.md:23 78544fc530114bb0bc0a753811e9ce58 +#: ../../modules/prompts.md:23 c15d62af27094d14acb6428c0e3e1a1d msgid "" "**Name**: Considering that a Prompt generally contains a lot of content, " "for ease of use and easy search, we need to name the Prompt. Note: The " "name of the Prompt is not allowed to be repeated. Name is the unique key " "that identifies a Prompt." -msgstr "**名称**:考虑到每个 Prompt 的内容会非常多,为了方便用户使用和搜索,我们需要给每个 Prompt 命名。注意:Prompt 的名称不允许重复,名称是一个 Prompt 的唯一键。" +msgstr "" +"**名称**:考虑到每个 Prompt 的内容会非常多,为了方便用户使用和搜索,我们需要给每个 Prompt 命名。注意:Prompt " +"的名称不允许重复,名称是一个 Prompt 的唯一键。" -#: ../../modules/prompts.md:25 f44598d2f2a4429d8c1624feca65c867 +#: ../../modules/prompts.md:25 621fe9c729c94e9bbde637b5a1856284 msgid "**Content**: Here is the actual Prompt content that will be input to LLM." msgstr "**内容**:这里是实际要输入 LLM 的提示内容。" -#: ../../modules/prompts.md:27 2384fc6006e74e9f94966f6112e6bb06 +#: ../../modules/prompts.md:27 ac2f153f704c4841a044daaf6548262b msgid "Edit Prompt" msgstr "编辑 Prompt" -#: ../../modules/prompts.md:29 efe8e16acc584f258645b1b20d891f71 +#: ../../modules/prompts.md:29 3d6238ea482842e0968f691f3fd0c947 msgid "" "Existing Prompts can be edited. Note that except **name**, other items " "can be modified." msgstr "已有的 Prompts 可以被编辑,除了名称不可修改,其余的内容均可修改。" -#: ../../modules/prompts.md:33 b1a82b4d88584275955087114cdcf574 +#: ../../modules/prompts.md:33 7cbe985fd9534471bce5f93a93da82fd msgid "Delete Prompt" msgstr "删除 Prompt" -#: ../../modules/prompts.md:35 e4e55367b8574324937f8b3006e7d3cd +#: ../../modules/prompts.md:35 849ab9ef2a2c4a29bb827eb373f37b7d msgid "" "Ordinary users can only delete Prompts created by themselves in the " "private Prompts space. Administrator users can delete Prompts in public " "Prompts spaces and private Prompts spaces." -msgstr "普通用户只能删除他们自己在私有 Prompts 空间中创建的 Prompts,管理员可以删除 公共 Prompts 空间下的 Prompts,也可以删除私有 Prompts 空间下的 Prompts(即使 Prompts 的创建者不是管理员)。" +msgstr "" +"普通用户只能删除他们自己在私有 Prompts 空间中创建的 Prompts,管理员可以删除 公共 Prompts 空间下的 " +"Prompts,也可以删除私有 Prompts 空间下的 Prompts(即使 Prompts 的创建者不是管理员)。" -#: ../../modules/prompts.md:38 ad8210816c524908bd131ffa9adae07c +#: ../../modules/prompts.md:38 191921e5664d4326b01f0c45dc88a1e5 msgid "Use Prompt" msgstr "使用 Prompt" -#: ../../modules/prompts.md:40 e7dd1e88f47647ecbfaf02a0d068b3f9 +#: ../../modules/prompts.md:40 87ad58641f834f30bce178e748d75284 msgid "" "Users can find and use Prompts next to the input boxes in each scene. " "Click to view all contents of Prompts library." msgstr "用户可以在每个场景中的输入框旁边找到并使用 Prompts。 点击悬浮图标可以查看当前用户能使用的全部 Prompts。" -#: ../../modules/prompts.md:42 38b6c173235c4f8499da14496a5a78b3 +#: ../../modules/prompts.md:42 60458c7980174c73bc0d56e9e27cd2b3 msgid "" "✓ Hover the mouse over each Prompt to preview the Prompt content. ✓ " "Click Prompt to automatically fill in the Prompt content in the input " "box." -msgstr "✓ 将鼠标悬停在每个 Prompt 上,可预览 Prompt 的内容。 ✓ 单击对应的 Prompt,可自动将 Prompt 的内容填充到输入框中。" +msgstr "" +"✓ 将鼠标悬停在每个 Prompt 上,可预览 Prompt 的内容。 ✓ 单击对应的 Prompt,可自动将 Prompt " +"的内容填充到输入框中。" diff --git a/pilot/scene/chat_knowledge/v1/chat.py b/pilot/scene/chat_knowledge/v1/chat.py index 4d40a8eef..4f3646718 100644 --- a/pilot/scene/chat_knowledge/v1/chat.py +++ b/pilot/scene/chat_knowledge/v1/chat.py @@ -55,11 +55,6 @@ class ChatKnowledge(BaseChat): "vector_store_name": self.knowledge_space, "vector_store_type": CFG.VECTOR_STORE_TYPE, } - # from pilot.graph_engine.graph_factory import RAGGraphFactory - # - # self.rag_engine = CFG.SYSTEM_APP.get_component( - # ComponentType.RAG_GRAPH_DEFAULT.value, RAGGraphFactory - # ).create() embedding_factory = CFG.SYSTEM_APP.get_component( "embedding_factory", EmbeddingFactory ) diff --git a/pilot/scene/chat_knowledge/v1/prompt.py b/pilot/scene/chat_knowledge/v1/prompt.py index 6788d6d35..394906562 100644 --- a/pilot/scene/chat_knowledge/v1/prompt.py +++ b/pilot/scene/chat_knowledge/v1/prompt.py @@ -13,13 +13,13 @@ The assistant gives helpful, detailed, professional and polite answers to the us _DEFAULT_TEMPLATE_ZH = """ 基于以下已知的信息, 专业、简要的回答用户的问题, - 如果无法从提供的内容中获取答案, 请说: "知识库中提供的内容不足以回答此问题" 禁止胡乱编造。 + 如果无法从提供的内容中获取答案, 请说: "知识库中提供的内容不足以回答此问题" 禁止胡乱编造, 回答的时候最好按照1.2.3.点进行总结。 已知内容: {context} 问题: {question} """ -_DEFAULT_TEMPLATE_EN = """ Based on the known information below, provide users with professional and concise answers to their questions. If the answer cannot be obtained from the provided content, please say: "The information provided in the knowledge base is not sufficient to answer this question." It is forbidden to make up information randomly. +_DEFAULT_TEMPLATE_EN = """ Based on the known information below, provide users with professional and concise answers to their questions. If the answer cannot be obtained from the provided content, please say: "The information provided in the knowledge base is not sufficient to answer this question." It is forbidden to make up information randomly. When answering, it is best to summarize according to points 1.2.3. known information: {context} question: diff --git a/pilot/server/component_configs.py b/pilot/server/component_configs.py index 339fa4713..d127120cc 100644 --- a/pilot/server/component_configs.py +++ b/pilot/server/component_configs.py @@ -29,9 +29,9 @@ def initialize_components( system_app.register_instance(controller) # Register global default RAGGraphFactory - from pilot.graph_engine.graph_factory import DefaultRAGGraphFactory + # from pilot.graph_engine.graph_factory import DefaultRAGGraphFactory - system_app.register(DefaultRAGGraphFactory) + # system_app.register(DefaultRAGGraphFactory) from pilot.base_modules.agent.controller import module_agent diff --git a/pilot/server/knowledge/service.py b/pilot/server/knowledge/service.py index 1dece9054..80bc2226f 100644 --- a/pilot/server/knowledge/service.py +++ b/pilot/server/knowledge/service.py @@ -441,16 +441,7 @@ class KnowledgeService: logger.info( f"async_document_summary, doc:{doc.doc_name}, chunk_size:{len(texts)}, begin generate summary" ) - # summary = self._llm_extract_summary(texts[0]) summary = self._mapreduce_extract_summary(texts) - # summaries = prompt_helper.repack(prompt=DEFAULT_TREE_SUMMARIZE_PROMPT_SEL, text_chunks=summaries) - # if (len(summaries)) > 1: - # outputs, summary = self._refine_extract_summary(summaries[1:], summaries[0]) - # else: - # summary = self._llm_extract_summary("\n".join(summaries)) - # print( - # f"refine summary outputs:{summaries}" - # ) print(f"final summary:{summary}") doc.summary = summary return knowledge_document_dao.update_knowledge_document(doc) @@ -466,7 +457,6 @@ class KnowledgeService: f"async doc sync, doc:{doc.doc_name}, chunk_size:{len(chunk_docs)}, begin embedding to vector store-{CFG.VECTOR_STORE_TYPE}" ) try: - self.async_document_summary(chunk_docs, doc) vector_ids = client.knowledge_embedding_batch(chunk_docs) doc.status = SyncStatus.FINISHED.name doc.result = "document embedding success" @@ -543,37 +533,9 @@ class KnowledgeService: ) return summary_iters[0] - def _refine_extract_summary(self, docs, summary: str, max_iteration: int = 5): - """Extract refine summary by llm""" - from pilot.scene.base import ChatScene - from pilot.common.chat_util import llm_chat_response_nostream - import uuid - - print(f"initialize summary is :{summary}") - outputs = [summary] - max_iteration = max_iteration if len(docs) > max_iteration else len(docs) - for doc in docs[0:max_iteration]: - chat_param = { - "chat_session_id": uuid.uuid1(), - "current_user_input": doc, - "select_param": summary, - "model_name": self.model_name, - } - from pilot.utils import utils - - loop = utils.get_or_create_event_loop() - summary = loop.run_until_complete( - llm_chat_response_nostream( - ChatScene.ExtractRefineSummary.value(), **{"chat_param": chat_param} - ) - ) - outputs.append(summary) - print(f"iterator is {len(outputs)} current summary is :{summary}") - return outputs, summary - def _mapreduce_extract_summary(self, docs): - """Extract mapreduce summary by llm - map -> multi thread generate summary + """Extract summary by mapreduce mode + map -> multi async thread generate summary reduce -> merge the summaries by map process Args: docs:List[str] From 3111760c826adef3d64dfd858328a64eb682b7c8 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Fri, 3 Nov 2023 15:45:45 +0800 Subject: [PATCH 41/57] doc:update document --- .../application/chatdb/chatdb.md | 6 + .../application/chatexcel/chatexcel.md | 5 + .../application/dashboard/dashboard.md | 5 + .../application/chatdb/chatdb.po | 129 ++--- .../application/chatexcel/chatexcel.po | 62 ++- .../application/dashboard/dashboard.po | 92 ++-- .../getting_started/install/deploy.po | 503 +++++++++--------- .../zh_CN/LC_MESSAGES/modules/plugins.po | 37 +- docs/modules/plugins.md | 5 + setup.py | 2 +- 10 files changed, 451 insertions(+), 395 deletions(-) diff --git a/docs/getting_started/application/chatdb/chatdb.md b/docs/getting_started/application/chatdb/chatdb.md index 982953746..12a6aa8b6 100644 --- a/docs/getting_started/application/chatdb/chatdb.md +++ b/docs/getting_started/application/chatdb/chatdb.md @@ -4,6 +4,12 @@ ChatData generates SQL from natural language and executes it. ChatDB involves co Database, including metadata about databases, tables, and fields.![db plugins demonstration](https://github.com/eosphoros-ai/DB-GPT/assets/13723926/d8bfeee9-e982-465e-a2b8-1164b673847e) +```{admonition} The LLM (Language Model) suitable for the ChatData scene is +* chatgpt3.5. +* chatgpt4. +* Vicuna-v1.5. +``` + ### 1.Choose Datasource If you are using DB-GPT for the first time, you need to add a data source and set the relevant connection information diff --git a/docs/getting_started/application/chatexcel/chatexcel.md b/docs/getting_started/application/chatexcel/chatexcel.md index bdd67991c..3df00c720 100644 --- a/docs/getting_started/application/chatexcel/chatexcel.md +++ b/docs/getting_started/application/chatexcel/chatexcel.md @@ -3,6 +3,11 @@ ChatExcel ![db plugins demonstration](https://github.com/eosphoros-ai/DB-GPT/assets/13723926/4113ac15-83c2-4350-86c0-5fc795677abd) ChatExcel uses natural language to analyze and query Excel data.![db plugins demonstration](../../../../assets/chat_excel/chat_excel_1.png) +```{admonition} The LLM (Language Model) suitable for the ChatExcel scene is +* chatgpt3.5. +* chatgpt4. +``` + ### 1.Select And Upload Excel or CSV File Select your excel or csv file to upload and start the conversation. ```{tip} diff --git a/docs/getting_started/application/dashboard/dashboard.md b/docs/getting_started/application/dashboard/dashboard.md index 5cab32581..a233d0f24 100644 --- a/docs/getting_started/application/dashboard/dashboard.md +++ b/docs/getting_started/application/dashboard/dashboard.md @@ -4,6 +4,11 @@ The purpose of the DB-GPT Dashboard is to empower data analysts with efficiency. technology, allowing business analysts to perform self-service analysis directly using natural language and gain insights into their respective areas of business. +```{admonition} The LLM (Language Model) suitable for the Dashboard scene is +* chatgpt3.5. +* chatgpt4. +``` + ```{note} Dashboard now support Datasource Type * Mysql * Sqlite diff --git a/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatdb/chatdb.po b/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatdb/chatdb.po index 974f74f9d..5e8e7cd1c 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatdb/chatdb.po +++ b/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatdb/chatdb.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 👏👏 0.3.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-09-26 17:51+0800\n" +"POT-Creation-Date: 2023-11-03 15:25+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -20,12 +20,12 @@ msgstr "" "Generated-By: Babel 2.12.1\n" #: ../../getting_started/application/chatdb/chatdb.md:1 -#: 0cf45852c1fd430090da81836bc961c7 +#: c1489293ce464cee9577b0aa9a3f3037 msgid "ChatData & ChatDB" msgstr "ChatData & ChatDB" #: ../../getting_started/application/chatdb/chatdb.md:3 -#: 6dc94a787ff844caa21074d71aaf351a +#: 2c421938f270427dbd0ffff892b1a5a1 #, fuzzy msgid "" "ChatData generates SQL from natural language and executes it. ChatDB " @@ -38,47 +38,56 @@ msgstr "" "plugins demonstration](../../../../assets/chat_data/chat_data.jpg)" #: ../../getting_started/application/chatdb/chatdb.md:3 -#: ../../getting_started/application/chatdb/chatdb.md:20 -#: ../../getting_started/application/chatdb/chatdb.md:24 -#: ../../getting_started/application/chatdb/chatdb.md:28 -#: ../../getting_started/application/chatdb/chatdb.md:43 -#: ../../getting_started/application/chatdb/chatdb.md:48 -#: ../../getting_started/application/chatdb/chatdb.md:54 -#: 826032e82a0a40b2bd122a90a35d0161 91652ef9e3224290b0c89112bcca4474 -#: d396ffa33eef4bef8471040369414420 d7f176a7794048d3ac3573970db86d9d -#: f80e5611eca64f86baeeed6c860061f9 +#: ../../getting_started/application/chatdb/chatdb.md:27 +#: ../../getting_started/application/chatdb/chatdb.md:31 +#: ../../getting_started/application/chatdb/chatdb.md:35 +#: ../../getting_started/application/chatdb/chatdb.md:50 +#: ../../getting_started/application/chatdb/chatdb.md:55 +#: ../../getting_started/application/chatdb/chatdb.md:61 +#: 1467691a6012498795a94a14f7eba307 32315140835948c58e1721c7e2fa88a9 +#: 3b8e3c3396ff47348105a6dec9e755ba 6b116d2bac2d43faa4cbcbd0c4151344 +#: a314854e9be945dd88ad241bfa340870 d94d5f0e608f4399a0e10d593f0ab1da +#: e0ca6ec1841040bc828ce2ef29c387b6 msgid "db plugins demonstration" msgstr "db plugins demonstration" -#: ../../getting_started/application/chatdb/chatdb.md:7 -#: aa0f978d3ad34b71aacf143a4c807ba1 +#: ../../getting_started/application/chatdb/chatdb.md:8 +#: 67cb0954cfa54e629b75cf9a241f6b9d +msgid "" +"The LLM (Language Model) suitable for the ChatData scene is * " +"chatgpt3.5. * chatgpt4. * Vicuna-v1.5." +msgstr "ChatData场景适用的LLM * " +"chatgpt3.5. * chatgpt4. * Vicuna-v1.5." + +#: ../../getting_started/application/chatdb/chatdb.md:14 +#: 8bd004993a834b0797ebcb5b6a6b1a23 msgid "1.Choose Datasource" msgstr "1.Choose Datasource" -#: ../../getting_started/application/chatdb/chatdb.md:9 -#: 8a2338e2fbae44f1b61b2fcf062499d3 +#: ../../getting_started/application/chatdb/chatdb.md:16 +#: 34abfdced7804b51a212c0e567ffda6b msgid "" "If you are using DB-GPT for the first time, you need to add a data source" " and set the relevant connection information for the data source." msgstr "如果你是第一次使用DB-GPT, 首先需要添加数据源,设置数据源的相关连接信息" -#: ../../getting_started/application/chatdb/chatdb.md:13 -#: f1d165ab8b564445880e581a2e554434 +#: ../../getting_started/application/chatdb/chatdb.md:20 +#: 3a8d16a8a32c4ac5affbd8093677b4f8 msgid "there are some example data in DB-GPT-NEW/DB-GPT/docker/examples" msgstr "在DB-GPT-NEW/DB-GPT/docker/examples有数据示例" -#: ../../getting_started/application/chatdb/chatdb.md:15 -#: dd390cb518094c96bf5430bfa821830f +#: ../../getting_started/application/chatdb/chatdb.md:22 +#: 2c3333a2705648148f79623c220d90cd msgid "you can execute sql script to generate data." msgstr "你可以通过执行sql脚本生成测试数据" -#: ../../getting_started/application/chatdb/chatdb.md:18 -#: aebd974d23124daa80af6d74431d1ce3 +#: ../../getting_started/application/chatdb/chatdb.md:25 +#: 4994182137574d14a3eefb421ceccd8e msgid "1.1 Datasource management" msgstr "1.1 Datasource management" -#: ../../getting_started/application/chatdb/chatdb.md:20 -#: af4d12aaed5c4fc484a3e7a755a666c2 +#: ../../getting_started/application/chatdb/chatdb.md:27 +#: 94680e1487d84092abc51a7da9bf1075 msgid "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/7678f07e-9eee-40a9-b980-5b3978a0ed52)" @@ -86,13 +95,13 @@ msgstr "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/7678f07e-9eee-40a9-b980-5b3978a0ed52)" -#: ../../getting_started/application/chatdb/chatdb.md:22 -#: 34b7b9ce0f0142af8179a8e1763a32f8 +#: ../../getting_started/application/chatdb/chatdb.md:29 +#: 236dbd6d6cb4467593bf30597ecb215c msgid "1.2 Connection management" msgstr "1.2 Connection管理" -#: ../../getting_started/application/chatdb/chatdb.md:24 -#: 00a1af9f4e0a45b9a398f641c8198114 +#: ../../getting_started/application/chatdb/chatdb.md:31 +#: 6611193e600c4452ac8a9769c6230590 msgid "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/25b8f5a9-d322-459e-a8b2-bfe8cb42bdd6)" @@ -100,13 +109,13 @@ msgstr "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/25b8f5a9-d322-459e-a8b2-bfe8cb42bdd6)" -#: ../../getting_started/application/chatdb/chatdb.md:26 -#: 3b8efc25b482480b8d0f4afe5304ece0 +#: ../../getting_started/application/chatdb/chatdb.md:33 +#: 7cceb9703af54970bee4a50fb07d4509 msgid "1.3 Add Datasource" msgstr "1.3 添加Datasource" -#: ../../getting_started/application/chatdb/chatdb.md:28 -#: d36a476e1eb34a46b2d35e6c1c4c39dd +#: ../../getting_started/application/chatdb/chatdb.md:35 +#: 83c9e18cb87b4f0d9b0ce5e68b7fea77 msgid "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/19ce31a7-4061-4da8-a9cb-efca396cc085)" @@ -114,54 +123,54 @@ msgstr "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/19ce31a7-4061-4da8-a9cb-efca396cc085)" -#: ../../getting_started/application/chatdb/chatdb.md:31 -#: 9205388f91404099bf1add6d55f33801 +#: ../../getting_started/application/chatdb/chatdb.md:38 +#: 143fb04274cd486687c5766179f6103e msgid "now DB-GPT support Datasource Type" msgstr "DB-GPT支持数据源类型" -#: ../../getting_started/application/chatdb/chatdb.md:33 -#: 197722ccd9e54f8196e3037f0ebd4165 +#: ../../getting_started/application/chatdb/chatdb.md:40 +#: 8bcf83e66b2d4d858407fc2b21b8fe85 msgid "Mysql" msgstr "Mysql" -#: ../../getting_started/application/chatdb/chatdb.md:34 -#: e859c194648440b19941a42635f37ac5 +#: ../../getting_started/application/chatdb/chatdb.md:41 +#: cd74abd5d6f4410ca001a3de2685e768 msgid "Sqlite" msgstr "Sqlite" -#: ../../getting_started/application/chatdb/chatdb.md:35 -#: 91c695f437064f01bf1d7c85a0ecf5b4 +#: ../../getting_started/application/chatdb/chatdb.md:42 +#: fc5e01baba43449f8c3eb9b4b36a0ed8 msgid "DuckDB" msgstr "DuckDB" -#: ../../getting_started/application/chatdb/chatdb.md:36 -#: 0a8ff591969c4944890415a84aa64173 +#: ../../getting_started/application/chatdb/chatdb.md:43 +#: 10b6fe2153cd4ceba949687a54c3a68c msgid "Clickhouse" msgstr "Clickhouse" -#: ../../getting_started/application/chatdb/chatdb.md:37 -#: d52ec849653141dc95862e82ce5777e0 +#: ../../getting_started/application/chatdb/chatdb.md:44 +#: 9ce0a41784f041d39138a81099c386e9 #, fuzzy msgid "Mssql" msgstr "Mysql" -#: ../../getting_started/application/chatdb/chatdb.md:38 -#: 430a72d857114422aeecd5595df41881 +#: ../../getting_started/application/chatdb/chatdb.md:45 +#: 4af6eb835e954e0d937e98b308fb512b msgid "Spark" msgstr "Spark" -#: ../../getting_started/application/chatdb/chatdb.md:41 -#: b615a70971e7443291ba33e8bc12b437 +#: ../../getting_started/application/chatdb/chatdb.md:48 +#: 8aaa3a73090b4805b2dddf1cc355d83c msgid "2.ChatData" msgstr "2.ChatData" -#: ../../getting_started/application/chatdb/chatdb.md:42 -#: e3542c64926143958e71c7cb21d25c78 +#: ../../getting_started/application/chatdb/chatdb.md:49 +#: a34c79c99bd34233ae92d3090ff0b877 msgid "Preview Mode" msgstr "Preview Mode" -#: ../../getting_started/application/chatdb/chatdb.md:43 -#: e32f26b7c22141e181b5345a644dffd5 +#: ../../getting_started/application/chatdb/chatdb.md:50 +#: 39e31a2a01494d4191d415a2240e026d #, fuzzy msgid "" "After successfully setting up the data source, you can start conversing " @@ -173,13 +182,13 @@ msgstr "" "设置数据源成功后就可以和数据库进行对话了。你可以让它帮你生成SQL,也可以和问它数据库元数据的相关信息。 ![db plugins " "demonstration](../../../../assets/chat_data/chatdata_eg.png)" -#: ../../getting_started/application/chatdb/chatdb.md:47 -#: 4d5c0465a01b4f5a964d0e803f9cbc89 +#: ../../getting_started/application/chatdb/chatdb.md:54 +#: 999c78e8b604493a8190b0e1258d0da4 msgid "Editor Mode" msgstr "Editor Mode" -#: ../../getting_started/application/chatdb/chatdb.md:48 -#: 79b088787e8f43258bcc4292c89ad1b0 +#: ../../getting_started/application/chatdb/chatdb.md:55 +#: e4a61d1e62c743f8b13dbed92ec265ba msgid "" "In Editor Mode, you can edit your sql and execute it. ![db plugins " "demonstration](https://github.com/eosphoros-ai/DB-" @@ -189,13 +198,13 @@ msgstr "" "/eosphoros-ai/DB-" "GPT/assets/13723926/1a896dc1-7c0e-4354-8629-30357ffd8d7f)" -#: ../../getting_started/application/chatdb/chatdb.md:52 -#: 9efaf27749614cd4bea07146edddf558 +#: ../../getting_started/application/chatdb/chatdb.md:59 +#: b3a0d94083524d249f97dd426e1e1f26 msgid "3.ChatDB" msgstr "3.ChatDB" -#: ../../getting_started/application/chatdb/chatdb.md:54 -#: b2dc15f067064c60974e532c3e2f5893 +#: ../../getting_started/application/chatdb/chatdb.md:61 +#: 8f4bd453447f48019a597eb3e4a59875 msgid "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/e04bc1b1-2c58-4b33-af62-97e89098ace7)" diff --git a/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatexcel/chatexcel.po b/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatexcel/chatexcel.po index 47f93237c..35e8fc9ef 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatexcel/chatexcel.po +++ b/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatexcel/chatexcel.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 👏👏 0.3.6\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-29 21:14+0800\n" +"POT-Creation-Date: 2023-11-03 15:25+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -20,13 +20,13 @@ msgstr "" "Generated-By: Babel 2.12.1\n" #: ../../getting_started/application/chatexcel/chatexcel.md:1 -#: ../../getting_started/application/chatexcel/chatexcel.md:9 -#: 6efcbf4652954b27beb55f600cfe75c7 eefb0c3bc131439fb2dd4045761f1ae9 +#: ../../getting_started/application/chatexcel/chatexcel.md:15 +#: 5e9c1de21de240839a510b9e05afcba1 96556d6d1d734f67ab15e548c9fdce2f msgid "ChatExcel" msgstr "" #: ../../getting_started/application/chatexcel/chatexcel.md:3 -#: 5fc4ddd2690f46658df1e09c601d81ad +#: 19590f67feea4f2580602538b79cd138 #, fuzzy msgid "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" @@ -36,61 +36,69 @@ msgid "" msgstr "使用自然语言进行Excel数据的分析处理" #: ../../getting_started/application/chatexcel/chatexcel.md:3 -#: ../../getting_started/application/chatexcel/chatexcel.md:13 -#: ../../getting_started/application/chatexcel/chatexcel.md:17 -#: ../../getting_started/application/chatexcel/chatexcel.md:21 -#: 4c91baf5f0b244abb021f461851674cc 4eead9a4f81e4855a5c362774696999c -#: 5f309a06170946108ae70806dff157ea 790016c9c68f4a29a84b7ef8e14d6dc2 -#: 93db1eb6af69452982f6028eff626a57 e758c8b320894e2b93f8db78459b7a1f -#: ea3c99f7eafc4ae0a19706a47e4c7bf6 f18d2b88de244173ab2673f2a5e828c0 +#: ../../getting_started/application/chatexcel/chatexcel.md:19 +#: ../../getting_started/application/chatexcel/chatexcel.md:23 +#: ../../getting_started/application/chatexcel/chatexcel.md:27 +#: 05b68001df5449869515898742ba2b3a 13c354703dfd4a8487d2c4e5bf4abd73 +#: 286462d6d79b4189bcd9d17937a96233 5aac360c20ea4ad189539e28e5e1c70f +#: 7009abd113244cc5badb8e90837dc9af 7eb17d02534d4f77b7602f3756da0d5e +#: be04d49fc14641b8b0d17c1e9d02973b f5c1cfd0f77d4199a45988114174c67f msgid "db plugins demonstration" msgstr "" -#: ../../getting_started/application/chatexcel/chatexcel.md:6 -#: 45f137031025409ba2ada9c8f7c5f1e4 +#: ../../getting_started/application/chatexcel/chatexcel.md:7 +#: 338f0b19314f4026b84a670d35056e6c +msgid "" +"The LLM (Language Model) suitable for the ChatExcel scene is * " +"chatgpt3.5. * chatgpt4." +msgstr "ChatExcel场景适用的LLM 是 scene is * " +"chatgpt3.5. * chatgpt4." + +#: ../../getting_started/application/chatexcel/chatexcel.md:12 +#: 2a710e2650bb44ef9d4a1ee4b8225a35 msgid "1.Select And Upload Excel or CSV File" msgstr "" -#: ../../getting_started/application/chatexcel/chatexcel.md:7 -#: cd282be2b4ef49ea8b0eaa3d53042f22 +#: ../../getting_started/application/chatexcel/chatexcel.md:13 +#: df48b1003f3640cfa621e416f0405e8d msgid "Select your excel or csv file to upload and start the conversation." msgstr "选择你的Excel或者CSV文件上传开始对话" -#: ../../getting_started/application/chatexcel/chatexcel.md:11 -#: a5ebc8643eff4b44a951b28d85488143 +#: ../../getting_started/application/chatexcel/chatexcel.md:17 +#: 7ef5d5ebb634406ea4b566bbf5e30fd7 msgid "" "The ChatExcel function supports Excel and CSV format files, select the " "corresponding file to use." msgstr "ChatExcel功能支持Excel和CSV格式的文件,选择对应格式的文件开始使用" -#: ../../getting_started/application/chatexcel/chatexcel.md:13 -#: d52927be09654c8daf29e2ef0c60a671 +#: ../../getting_started/application/chatexcel/chatexcel.md:19 +#: 40c79b71820f44439b1f541db2be9dd9 msgid "" "![db plugins " "demonstration](../../../../assets/chat_excel/chat_excel_2.png) ![db " "plugins demonstration](../../../../assets/chat_excel/chat_excel_3.png)" msgstr "" -#: ../../getting_started/application/chatexcel/chatexcel.md:16 -#: d86202165fdc4da6be06024b45f9af55 +#: ../../getting_started/application/chatexcel/chatexcel.md:22 +#: 0dd469b6f56a442485392346065e345d msgid "2.Wait for Data Processing" msgstr "等待数据处理" -#: ../../getting_started/application/chatexcel/chatexcel.md:17 -#: 3de7205fbdc741e2b79996d67264c058 +#: ../../getting_started/application/chatexcel/chatexcel.md:23 +#: 0e9213342664465187981d6fea41e7ba msgid "" "After the data is uploaded, it will first learn and process the data " "structure and field meaning. ![db plugins " "demonstration](../../../../assets/chat_excel/chat_excel_4.png)" msgstr "等待数据上传完成,会自动进行数据结构的学习和处理" -#: ../../getting_started/application/chatexcel/chatexcel.md:20 -#: fb0620dec5a24b469ceccf86e918fe54 +#: ../../getting_started/application/chatexcel/chatexcel.md:26 +#: dd2047d1199542f7abda4767b953cfac msgid "3.Use Data Analysis Calculation" msgstr "开始使用数据分析计算" -#: ../../getting_started/application/chatexcel/chatexcel.md:21 -#: 221733f01fe04e38b19f191d4001c7a7 +#: ../../getting_started/application/chatexcel/chatexcel.md:27 +#: 4e168def205743c898586e99e34d3e18 msgid "" "Now you can use natural language to analyze and query data in the dialog " "box. ![db plugins " diff --git a/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/dashboard/dashboard.po b/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/dashboard/dashboard.po index 32686d68c..3c5397242 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/dashboard/dashboard.po +++ b/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/dashboard/dashboard.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 👏👏 0.3.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-29 20:50+0800\n" +"POT-Creation-Date: 2023-11-03 15:25+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -20,12 +20,12 @@ msgstr "" "Generated-By: Babel 2.12.1\n" #: ../../getting_started/application/dashboard/dashboard.md:1 -#: 2a1224e675d144269e5cc3695d4d60b4 +#: 3e4ef12c51894e5d93adcbf090a4783b msgid "Dashboard" msgstr "Dashboard" #: ../../getting_started/application/dashboard/dashboard.md:3 -#: 2b6d2f94f73d43e68806bf4c6d0d9269 +#: df9eb8d62bbe460d94e448c23fffa529 msgid "" "The purpose of the DB-GPT Dashboard is to empower data analysts with " "efficiency. DB-GPT provides intelligent reporting technology, allowing " @@ -34,37 +34,45 @@ msgid "" msgstr "DB-GPT Dashboard目的是赋能数据分析人员。DB-GPT通过提供智能报表技术,使得业务分析人员可以直接使用简单的自然语言进行自助分析。" #: ../../getting_started/application/dashboard/dashboard.md:8 -#: 9612fa76c4264bab8e629ac50959faa9 +#: 3ce90998ab9547fc95105f0000e232da +msgid "" +"The LLM (Language Model) suitable for the Dashboard scene is * " +"chatgpt3.5. * chatgpt4." +msgstr "Dashboard场景适用的LLM是 * " +"chatgpt3.5. * chatgpt4." + +#: ../../getting_started/application/dashboard/dashboard.md:14 +#: da3aaa82126942058e72c472e2495641 msgid "Dashboard now support Datasource Type" msgstr "Dashboard目前支持的数据源类型" -#: ../../getting_started/application/dashboard/dashboard.md:9 -#: bb0b15742ebe41628fb0d1fc38caabe2 +#: ../../getting_started/application/dashboard/dashboard.md:15 +#: d21cfc9594a24b69a5040f60cba00abb msgid "Mysql" msgstr "Mysql" -#: ../../getting_started/application/dashboard/dashboard.md:10 -#: 35491581125b4bdd8422f35b11c7bc2c +#: ../../getting_started/application/dashboard/dashboard.md:16 +#: fc0e345321e84de5b9a96107fef5467e msgid "Sqlite" msgstr "Sqlite" -#: ../../getting_started/application/dashboard/dashboard.md:11 -#: 8c4389354e0344aa9a781bdfc94c2cac +#: ../../getting_started/application/dashboard/dashboard.md:17 +#: f5cc4387997441b88a9f10ba9b35b621 msgid "DuckDB" msgstr "DuckDB" -#: ../../getting_started/application/dashboard/dashboard.md:13 -#: 18e8c60f5c2f4aa698cec1e8e8b354c8 +#: ../../getting_started/application/dashboard/dashboard.md:19 +#: d8a86c3d05f84df0aa63c88f5dbfbd78 msgid "Steps to Dashboard In DB-GPT" msgstr "Dashboard使用步骤" -#: ../../getting_started/application/dashboard/dashboard.md:15 -#: 94f98e0f5c2e451ba29b9b77c4139ed9 +#: ../../getting_started/application/dashboard/dashboard.md:21 +#: dbf7b3f73677411a8e660f8d90c11e05 msgid "1 add datasource" msgstr "1.添加数据源" -#: ../../getting_started/application/dashboard/dashboard.md:17 -#: 34e1211e65b940c3beb6234bcfa423a1 +#: ../../getting_started/application/dashboard/dashboard.md:23 +#: 70a599bc716a4af2b5a07a40de6fed9d #, fuzzy msgid "" "If you are using Dashboard for the first time, you need to mock some data" @@ -74,18 +82,18 @@ msgid "" "8c36-213b1c6fb5dd)" msgstr "如果你是第一次使用Dashboard,需要构造测试数据,DB-GPT在pilot/mock_datas/提供了测试数据,只需要将数据源进行添加即可" -#: ../../getting_started/application/dashboard/dashboard.md:17 -#: f29905929b32442ba05833b6c52a11be +#: ../../getting_started/application/dashboard/dashboard.md:23 +#: e38d15f091264563840cf15f0a2fe97c msgid "add_datasource" msgstr "添加数据源" -#: ../../getting_started/application/dashboard/dashboard.md:21 -#: 367a487dd1d54681a6e83d8fdda5b793 +#: ../../getting_started/application/dashboard/dashboard.md:27 +#: c6e87a5b20bb439ab1b3dc88e764d20b msgid "2.Choose Dashboard Mode" msgstr "2.进入Dashboard" -#: ../../getting_started/application/dashboard/dashboard.md:23 -#: 1ee1e980934e4a618591b7c43921c304 +#: ../../getting_started/application/dashboard/dashboard.md:29 +#: 54c25766650546998d3aaa3655f5275b msgid "" "![create_space](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/5e888880-0e97-4b60-8e5c-b7e7224197f0)" @@ -93,18 +101,18 @@ msgstr "" "![create_space](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/5e888880-0e97-4b60-8e5c-b7e7224197f0)" -#: ../../getting_started/application/dashboard/dashboard.md:23 -#: 12c756afdad740a9afc9cb46cc834af8 +#: ../../getting_started/application/dashboard/dashboard.md:29 +#: ea1781528db04000ab4a72308c7be97e msgid "create_space" msgstr "create_space" -#: ../../getting_started/application/dashboard/dashboard.md:25 -#: 5a575b17408c42fbacd32d8ff792d5a8 +#: ../../getting_started/application/dashboard/dashboard.md:31 +#: 5de9b0f0853443368d90e42114e99d6e msgid "3.Select Datasource" msgstr "3.选择数据源" -#: ../../getting_started/application/dashboard/dashboard.md:27 -#: ae051f852a5a4044a147c853cc3fba60 +#: ../../getting_started/application/dashboard/dashboard.md:33 +#: 3d4c429c4660414a8d5c44dea0ea0192 msgid "" "![document](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/da2ac8b5-eca4-48ef-938f-f9dc1ca711b3)" @@ -112,19 +120,19 @@ msgstr "" "![document](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/da2ac8b5-eca4-48ef-938f-f9dc1ca711b3)" -#: ../../getting_started/application/dashboard/dashboard.md:27 -#: ../../getting_started/application/dashboard/dashboard.md:31 -#: 94907bb0dc694bc3a4d2ee57a84b8242 ecc0666385904fce8bb1000735482f65 +#: ../../getting_started/application/dashboard/dashboard.md:33 +#: ../../getting_started/application/dashboard/dashboard.md:37 +#: 338912391ae441328549accdb6d5522b 68ce490680fe4ed4a3c844c4c5b3fbd2 msgid "document" msgstr "document" -#: ../../getting_started/application/dashboard/dashboard.md:29 -#: c8697e93661c48b19674e63094ba7486 +#: ../../getting_started/application/dashboard/dashboard.md:35 +#: 2c0fd7e79393417aa218908c5cc89461 msgid "4.Input your analysis goals" msgstr "4.输入分析目标" -#: ../../getting_started/application/dashboard/dashboard.md:31 -#: 473fc0d00ab54ee6bc5c21e017591cc4 +#: ../../getting_started/application/dashboard/dashboard.md:37 +#: fb0bb655581a4109a5510240e54db006 #, fuzzy msgid "" "![document](https://github.com/eosphoros-ai/DB-" @@ -136,19 +144,19 @@ msgstr "" "![document](https://github.com/eosphoros-ai/DB-GPT/assets/13723926" "/3d14a2da-165e-4b2f-a921-325c20fe5ae9)" -#: ../../getting_started/application/dashboard/dashboard.md:31 -#: ../../getting_started/application/dashboard/dashboard.md:35 -#: 00597e1268544d97a3de368b04d5dcf8 350d04e4b7204823b7a03c0a7606c951 +#: ../../getting_started/application/dashboard/dashboard.md:37 +#: ../../getting_started/application/dashboard/dashboard.md:41 +#: 17a72b7849a6458aa97182b72baad188 44680217a9794eddb97bcb98593a1071 msgid "db plugins demonstration" msgstr "" -#: ../../getting_started/application/dashboard/dashboard.md:34 -#: b48cc911c1614def9e4738d35e8b754c +#: ../../getting_started/application/dashboard/dashboard.md:40 +#: 4a9a8eac8e77465a9519b532afdfd1b7 msgid "5.Adjust and modify your report" msgstr "5.调整" -#: ../../getting_started/application/dashboard/dashboard.md:35 -#: b0442bbc0f6c4c33914814ac92fc4b13 +#: ../../getting_started/application/dashboard/dashboard.md:41 +#: b56da5e50ced4085bb376caa26e50e78 msgid "" "![db plugins " "demonstration](../../../../assets/chat_dashboard/chat_dashboard_2.png)" diff --git a/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po b/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po index 4b329573a..38a88cc6f 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po +++ b/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 👏👏 0.4.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-03 13:00+0800\n" +"POT-Creation-Date: 2023-11-03 15:25+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -19,40 +19,27 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.12.1\n" -#: ../../getting_started/install/deploy.rst:4 7a1ee708aa40431981178ebd1d34b9aa +#: ../../getting_started/install/deploy.rst:4 bb7e1a7b70624a3d91804c5ce2d5216b msgid "Installation From Source" msgstr "源码安装" -#: ../../getting_started/install/deploy.rst:6 dd4c542c563b4d4ca5b710dc7326ff8b +#: ../../getting_started/install/deploy.rst:6 7524477e8b8a456b8e2b942621a6b225 msgid "To get started, install DB-GPT with the following steps." msgstr "按照以下步骤进行安装" -#: ../../getting_started/install/deploy.rst:8 f352a8d93da744aaab775e8290c74704 -msgid "" -"DB-GPT can be deployed on servers with low hardware requirements or on " -"servers with high hardware requirements. You can install DB-GPT by Using " -"third-part LLM REST API Service OpenAI, Azure." -msgstr "" - -#: ../../getting_started/install/deploy.rst:11 b89bfaa679d5448791d315b9ffebe7c5 -msgid "" -"And you can also install DB-GPT by deploy LLM Service by download LLM " -"model." -msgstr "" - -#: ../../getting_started/install/deploy.rst:15 942b2999b3b5432e956c44e2a51b5269 +#: ../../getting_started/install/deploy.rst:10 871cdb0a7e004668b518168461d76945 msgid "1.Preparation" msgstr "1.准备" -#: ../../getting_started/install/deploy.rst:16 d27c8698bd4a45d7a7ebdbba470318d6 +#: ../../getting_started/install/deploy.rst:11 d845f48ec05a4bb7a5b0f95a0644029d msgid "**Download DB-GPT**" msgstr "**下载DB-GPT项目**" -#: ../../getting_started/install/deploy.rst:22 ce3e61a03ca945b4a3c3b264a063442c +#: ../../getting_started/install/deploy.rst:17 85df7bb2b73141058ba0ca5a73e46701 msgid "**Install Miniconda**" msgstr "**安装Miniconda**" -#: ../../getting_started/install/deploy.rst:24 1fd868a2e84c4752b242b401ac64d0e4 +#: ../../getting_started/install/deploy.rst:19 b7b3e120ded344d09fb2d7a3a7903497 msgid "" "We use Sqlite as default database, so there is no need for database " "installation. If you choose to connect to other databases, you can " @@ -66,241 +53,241 @@ msgstr "" "GPT快速部署不需要部署相关数据库服务。如果你想使用其他数据库,需要先部署相关数据库服务。我们目前使用Miniconda进行python环境和包依赖管理[安装" " Miniconda](https://docs.conda.io/en/latest/miniconda.html)" -#: ../../getting_started/install/deploy.rst:41 59dc27ad4237444d8eb7229fe29c975d +#: ../../getting_started/install/deploy.rst:36 a5e34db6a6b8450c8a1f35377a1dc93b msgid "2.Deploy LLM Service" msgstr "2.部署LLM服务" -#: ../../getting_started/install/deploy.rst:42 12ed83127fb744bcb60c5c7c16359a0e +#: ../../getting_started/install/deploy.rst:37 5c49829b086e4d5fbcb5a971a34fa3b5 msgid "" "DB-GPT can be deployed on servers with low hardware requirements or on " "servers with high hardware requirements." msgstr "DB-GPT可以部署在对硬件要求不高的服务器,也可以部署在对硬件要求高的服务器" -#: ../../getting_started/install/deploy.rst:44 1674c59c24804200ab53bd31847be19a +#: ../../getting_started/install/deploy.rst:39 7c2f7e2b49054d17850942bef9570c45 msgid "" "If you are low hardware requirements you can install DB-GPT by Using " "third-part LLM REST API Service OpenAI, Azure, tongyi." msgstr "Low hardware requirements模式适用于对接第三方模型服务的api,比如OpenAI, 通义千问, 文心.cpp。" -#: ../../getting_started/install/deploy.rst:48 e9c37648778540fe982c26d4104931ae +#: ../../getting_started/install/deploy.rst:43 8c392e63073a47698e38456c5994ff25 msgid "As our project has the ability to achieve OpenAI performance of over 85%," msgstr "使用OpenAI服务可以让DB-GPT准确率达到85%" -#: ../../getting_started/install/deploy.rst:53 201b7af45c0046faada4b81e110e7745 +#: ../../getting_started/install/deploy.rst:48 148f8d85c02345219ac535003fe05fca msgid "Notice make sure you have install git-lfs" msgstr "确认是否已经安装git-lfs" -#: ../../getting_started/install/deploy.rst:55 f7c9535c0eb546f7b1389a181b08c5c0 +#: ../../getting_started/install/deploy.rst:50 7f719273d1ff4d888376030531a560c4 msgid "centos:yum install git-lfs" msgstr "" -#: ../../getting_started/install/deploy.rst:57 8fb3efededcb42c592fa27b03c4e9a65 +#: ../../getting_started/install/deploy.rst:52 f5c2035bca214e3fbef2b70be0e76247 msgid "ubuntu:apt-get install git-lfs" msgstr "" -#: ../../getting_started/install/deploy.rst:59 b3df472ae3ae470d94112f7327787e13 +#: ../../getting_started/install/deploy.rst:54 cb1b52b9323e4e9fbccfd3c42067a568 msgid "macos:brew install git-lfs" msgstr "" -#: ../../getting_started/install/deploy.rst:63 -#: ../../getting_started/install/deploy.rst:226 -#: 070a6d653f6740cf852ddaf036ac2538 635662e449d34d5b9f6316898d14e0a6 +#: ../../getting_started/install/deploy.rst:58 +#: ../../getting_started/install/deploy.rst:221 +#: 9c601ee0c06646d58cbd2c2fff342cb5 d3fe6c712b4145d0856487c65057c2a0 msgid "OpenAI" msgstr "OpenAI" -#: ../../getting_started/install/deploy.rst:65 -#: ../../getting_started/install/deploy.rst:212 -#: 1ff3d5d9f9814e638f118925bedb7800 59cda8abcdc7471eb0a488610121a533 +#: ../../getting_started/install/deploy.rst:60 +#: ../../getting_started/install/deploy.rst:207 +#: 5e0e84bd11084d158e18b702022aaa96 6a9c9830e5184eac8b6b7425780f4a3e msgid "Download embedding model" msgstr "下载embedding model" -#: ../../getting_started/install/deploy.rst:77 -#: ../../getting_started/install/deploy.rst:234 -#: 0c68e075ab7840bd9d75ced89deaea86 b9e25c8690da4d9c94c012a04ddc8f0d +#: ../../getting_started/install/deploy.rst:72 +#: ../../getting_started/install/deploy.rst:229 +#: 953d6931627641b985588abf8b6ad9fd d52e287164ca44f79709f4645a1bb774 msgid "Configure LLM_MODEL and PROXY_API_URL and API_KEY in `.env` file" msgstr "在`.env`文件设置LLM_MODEL and PROXY_API_URL and API_KEY" -#: ../../getting_started/install/deploy.rst:87 -#: ../../getting_started/install/deploy.rst:285 -#: 5eb0e6ffb66a48dfa05cfea8414b21c5 61b75bb879d64726976c131f0f7cea83 +#: ../../getting_started/install/deploy.rst:82 +#: ../../getting_started/install/deploy.rst:280 +#: 6dc89616c0bf46a898a49606d1349039 e30b7458fc0d46e8bcf0ec61a2be2e19 msgid "Make sure your .env configuration is not overwritten" msgstr "认.env文件不会被覆盖\"" -#: ../../getting_started/install/deploy.rst:90 d14c2a247eee401bae9b1711cdcc0712 +#: ../../getting_started/install/deploy.rst:85 7adce7ac878d4b1ab9249d840d302520 msgid "Vicuna" msgstr "Vicuna" -#: ../../getting_started/install/deploy.rst:91 d59e03c9d3c3405ea04d814bffc59ef8 +#: ../../getting_started/install/deploy.rst:86 44a32c4cd0b140838b49f739d68ff42d msgid "" "`Vicuna-v1.5 `_ based on " "llama-2 has been released, we recommend you set `LLM_MODEL=vicuna-" "13b-v1.5` to try this model)" msgstr "" -#: ../../getting_started/install/deploy.rst:93 c6d22fb4c35c40378159e7845c87bb51 +#: ../../getting_started/install/deploy.rst:88 f4991de79c434961b0ee777cf42dc491 msgid "vicuna-v1.5 hardware requirements" msgstr "" +#: ../../getting_started/install/deploy.rst:92 +#: ../../getting_started/install/deploy.rst:137 +#: 596405ba21d046c993c18d0bcaf95048 ca993a5f1b194707bbe3d5d6e9d670d8 +msgid "Model" +msgstr "" + +#: ../../getting_started/install/deploy.rst:93 +#: ../../getting_started/install/deploy.rst:138 +#: 8437bb47daa94ca8a43b0eadc1286842 d040d964198d4c95afa6dd0d86586cc2 +msgid "Quantize" +msgstr "" + +#: ../../getting_started/install/deploy.rst:94 +#: ../../getting_started/install/deploy.rst:139 +#: 453bc4416d89421699d90d940498b9ac 5de996bb955f4c6ca8d5651985ced255 +msgid "VRAM Size" +msgstr "" + +#: ../../getting_started/install/deploy.rst:95 +#: ../../getting_started/install/deploy.rst:98 077d52b8588e4ddd956acb7ff86bc458 +#: fcf0ca75422343d19b12502fb7746f08 +msgid "vicuna-7b-v1.5" +msgstr "" + +#: ../../getting_started/install/deploy.rst:96 +#: ../../getting_started/install/deploy.rst:102 +#: ../../getting_started/install/deploy.rst:141 +#: ../../getting_started/install/deploy.rst:147 +#: 799b310b76454f79a261300253a9bb75 bd98df81ec8941b69c7d1de107154b1b +#: ca71731754f545d589e506cb53e6f042 d4023553e4384cc4955ef5bf4dc4d05b +msgid "4-bit" +msgstr "" + #: ../../getting_started/install/deploy.rst:97 #: ../../getting_started/install/deploy.rst:142 -#: 215382b66c944bef8ba8d081792cb3c5 eadfd6f7230f49a4a9d5552b51d766c0 -msgid "Model" -msgstr "" - -#: ../../getting_started/install/deploy.rst:98 -#: ../../getting_started/install/deploy.rst:143 -#: 5eca1dbe065b4e648ee00ca118e84214 abec181550804601ad54500469b332f9 -msgid "Quantize" +#: adfc22d9c6394046bb632831a4a3b066 e4e7762c714a49828da630a5f9d641dc +msgid "8 GB" msgstr "" #: ../../getting_started/install/deploy.rst:99 +#: ../../getting_started/install/deploy.rst:105 #: ../../getting_started/install/deploy.rst:144 -#: 24a907ffe6e4449abb632d80ada8733c 472a99174d68460a84a72d65d9fdcd07 -msgid "VRAM Size" +#: ../../getting_started/install/deploy.rst:150 +#: 0d6bd1c4a6464df38723de978c09e8bc 106e20f7727f43d280b7560dc0f19bbc +#: 5a95691d1d134638bffa478daf2577a0 f8add03506244306b1ac6e10c5a2bc1f +msgid "8-bit" msgstr "" #: ../../getting_started/install/deploy.rst:100 #: ../../getting_started/install/deploy.rst:103 -#: 87bba38be8f24c0688431a5985622d33 e8c8ef23e4964d059d9615f41719d05f -msgid "vicuna-7b-v1.5" -msgstr "" - -#: ../../getting_started/install/deploy.rst:101 -#: ../../getting_started/install/deploy.rst:107 -#: ../../getting_started/install/deploy.rst:146 -#: ../../getting_started/install/deploy.rst:152 -#: 7695fa31995b4e038ac4359df76a0a2f a8c361af629c4a179c811ac39ef16c3c -#: defc11c71d45471da982eb7c96039450 f9362395c5ff4213b5fb2f4d1e430496 -msgid "4-bit" -msgstr "" - -#: ../../getting_started/install/deploy.rst:102 -#: ../../getting_started/install/deploy.rst:147 -#: 7f2ebb804fb042c1b24cf6274c2cb7fc 9604200fbd974a6e9e3d66a38f9e5895 -msgid "8 GB" -msgstr "" - -#: ../../getting_started/install/deploy.rst:104 -#: ../../getting_started/install/deploy.rst:110 -#: ../../getting_started/install/deploy.rst:149 -#: ../../getting_started/install/deploy.rst:155 -#: 4936725d2b0a47f39286453db766027c 879daa7be9e243b7a8a51f0859459096 -#: c5322eaace39472282941c4bcae87232 e79778e8505e490a912aa80c28e37b0c -msgid "8-bit" -msgstr "" - -#: ../../getting_started/install/deploy.rst:105 -#: ../../getting_started/install/deploy.rst:108 -#: ../../getting_started/install/deploy.rst:150 -#: ../../getting_started/install/deploy.rst:153 -#: 09cd46eb89234d1cbbaf9fccd2d7f206 531282962fd148108a5d4582022b9d11 -#: c2249464c63b4808a13be66c6a04653d c54d26deb5e14bbc9ebeefe751ee32a1 +#: ../../getting_started/install/deploy.rst:145 +#: ../../getting_started/install/deploy.rst:148 +#: 03222e6a682e406bb56c21025412fbe5 2eb88af3efb74fb79899d7818a79d177 +#: 9705b9d7d2084f0b8867f6aeec66251b bca6e5151e244a318f4c2078c3f82118 msgid "12 GB" msgstr "" -#: ../../getting_started/install/deploy.rst:106 -#: ../../getting_started/install/deploy.rst:109 -#: 40d56aeeeeae4ad5a08d432da14c91f6 a4aae2c08b35462699a074c20436b583 +#: ../../getting_started/install/deploy.rst:101 +#: ../../getting_started/install/deploy.rst:104 +#: 1596cbb77c954d1db00e2fa283d66a9a c6e8dc1600d14ee5a47f45f75ec709f4 msgid "vicuna-13b-v1.5" msgstr "" -#: ../../getting_started/install/deploy.rst:111 -#: ../../getting_started/install/deploy.rst:156 -#: 4e58bb5b42d043b8b8105ff1424b3dda 670a8f2e7d9a4f56b338a890a0e6179c +#: ../../getting_started/install/deploy.rst:106 +#: ../../getting_started/install/deploy.rst:151 +#: 00ee98593b7f4b29b5d97fa5a323bfa1 0169214dcf8d46c791b3482c81283fa0 msgid "20 GB" msgstr "" -#: ../../getting_started/install/deploy.rst:127 -#: ../../getting_started/install/deploy.rst:174 -#: ../../getting_started/install/deploy.rst:200 -#: 7aec36decef845a4979e4d72b5556166 edb0520c46de41e79a56453901f5dbda -#: f726ecdc3a3b40eeb527464e705d262c +#: ../../getting_started/install/deploy.rst:122 +#: ../../getting_started/install/deploy.rst:169 +#: ../../getting_started/install/deploy.rst:195 +#: 852f800e380c44d3b1b5bdaa881406b7 89ddd6c4a4874f4f8b7f051d797e364a +#: a2b4436f8fcb44ada3b5bf5c1099e646 msgid "The model files are large and will take a long time to download." msgstr "" -#: ../../getting_started/install/deploy.rst:129 -#: ../../getting_started/install/deploy.rst:176 -#: ../../getting_started/install/deploy.rst:202 -#: 1ced4f4cd3ca4b4a8a545ba4625e5888 1f3fc32e037846ecba6e9d99acaa341e -#: 2e2a3b69997043858a21ce88c349fd87 +#: ../../getting_started/install/deploy.rst:124 +#: ../../getting_started/install/deploy.rst:171 +#: ../../getting_started/install/deploy.rst:197 +#: 18ccf7acdf3045588a19866c0161f44b 3d3d93649ec943c8b2b725807e969cbf +#: 6205975466f54d8fbf8e30b58df6b9c2 msgid "**Configure LLM_MODEL in `.env` file**" msgstr "" -#: ../../getting_started/install/deploy.rst:136 -#: ../../getting_started/install/deploy.rst:231 -#: 0ae3d2ff947545fb8ae3a3221ada4fca 908164bbe3f745cf994b65c7cc0d4f42 +#: ../../getting_started/install/deploy.rst:131 +#: ../../getting_started/install/deploy.rst:226 +#: 022addaea4ea432584b8a27ea83a9dc4 7a95d25c58d2491e855dff42f6d3a686 msgid "Baichuan" msgstr "" -#: ../../getting_started/install/deploy.rst:138 -#: 4249581eb6eb4c90ac467c3b23f9cf47 +#: ../../getting_started/install/deploy.rst:133 +#: b5374f6d0ca44ee9bd984c0198515861 msgid "Baichuan hardware requirements" msgstr "" -#: ../../getting_started/install/deploy.rst:145 -#: ../../getting_started/install/deploy.rst:148 -#: c01aea1eaf0c4d0ca14c10e51003fa2e f1081e1ecc6b42b6a7d227cf4a3b9aa9 +#: ../../getting_started/install/deploy.rst:140 +#: ../../getting_started/install/deploy.rst:143 +#: 6a5e6034c185455d81e8ba5349dbc191 9d0109817c524747909417924bb0bd31 msgid "baichuan-7b" msgstr "" -#: ../../getting_started/install/deploy.rst:151 -#: ../../getting_started/install/deploy.rst:154 -#: 1cf37d7196814348a177341d80d9748a edf669023f5647c89c52475f385dd91f +#: ../../getting_started/install/deploy.rst:146 +#: ../../getting_started/install/deploy.rst:149 +#: b3300ed57f0c4ed98816652ea4a5c3c8 d57e98b46fb14f649d6ac8df27edcfd8 msgid "baichuan-13b" msgstr "" -#: ../../getting_started/install/deploy.rst:178 -#: 25e45bdc7e6b475080f8b39cd555746d +#: ../../getting_started/install/deploy.rst:173 +#: ac684ccbea7d4f5380c43ad02a1b7231 msgid "please rename Baichuan path to \"baichuan2-13b\" or \"baichuan2-7b\"" msgstr "将Baichuan模型目录修改为\"baichuan2-13b\" 或 \"baichuan2-7b\"" -#: ../../getting_started/install/deploy.rst:184 -#: 80c36809333c4e2490166571222963cc +#: ../../getting_started/install/deploy.rst:179 +#: d2e283112ed1440b93510c331922b37c msgid "ChatGLM" msgstr "" -#: ../../getting_started/install/deploy.rst:204 -#: f1e3c93f447b40039a57d278d49ff32d +#: ../../getting_started/install/deploy.rst:199 +#: ae30d065461e446e86b02d3903108a02 msgid "please rename chatglm model path to \"chatglm2-6b\"" msgstr "将chatglm模型目录修改为\"chatglm2-6b\"" -#: ../../getting_started/install/deploy.rst:210 -#: 62570cd6084a4b3c8ceff5fdd5234aa0 +#: ../../getting_started/install/deploy.rst:205 +#: 81a8983e89c4400abc20080c86865c02 msgid "Other LLM API" msgstr "" -#: ../../getting_started/install/deploy.rst:227 -#: fb0c2d274f3740a2af7ece03fdb81d22 +#: ../../getting_started/install/deploy.rst:222 +#: 4f7cb7a3f324410d8a34ba96d7c9536a msgid "Azure" msgstr "" -#: ../../getting_started/install/deploy.rst:228 -#: 13e28550c95e4838b9e35a064448f9ca +#: ../../getting_started/install/deploy.rst:223 +#: ee6cbe48a8094637b6b8a049446042c6 msgid "Aliyun tongyi" msgstr "" -#: ../../getting_started/install/deploy.rst:229 -#: 32d7289e7e514db5b3f49ebad9eb0e46 +#: ../../getting_started/install/deploy.rst:224 +#: a3d9c061b0f440258be88cc3143b1887 msgid "Baidu wenxin" msgstr "" -#: ../../getting_started/install/deploy.rst:230 -#: b8033cd9b67d4b18823fc2053e23114b +#: ../../getting_started/install/deploy.rst:225 +#: 176001fb6eaf448f9eca1abd256b3ef4 msgid "Zhipu" msgstr "" -#: ../../getting_started/install/deploy.rst:232 -#: 9cc479d40a3f435a81e8e2aa8c015bbe +#: ../../getting_started/install/deploy.rst:227 +#: 17fecc140be2474ea1566d44641a27c0 msgid "Bard" msgstr "" -#: ../../getting_started/install/deploy.rst:287 -#: abd4caa347e3405f86319825c14b3b4a +#: ../../getting_started/install/deploy.rst:282 +#: bc34832cec754984a40c4d01526f0f83 msgid "llama.cpp" msgstr "" -#: ../../getting_started/install/deploy.rst:289 -#: b3b53e55206345e8b332af19851f5a5f +#: ../../getting_started/install/deploy.rst:284 +#: aa4b14e726dc447f92dec48f38a3d770 msgid "" "DB-GPT already supports `llama.cpp " "`_ via `llama-cpp-python " @@ -309,25 +296,25 @@ msgstr "" "DB-GPT 已经支持了 `llama.cpp `_ via " "`llama-cpp-python `_ ." -#: ../../getting_started/install/deploy.rst:291 -#: 54fc351de03445e7b4b7a5408215c0cf +#: ../../getting_started/install/deploy.rst:286 +#: e97a868ad05b48ee8d25017457c1b7ee msgid "**Preparing Model Files**" msgstr "**准备Model文件**" -#: ../../getting_started/install/deploy.rst:293 -#: 41e7c90a891d47c1ae04883454cf999f +#: ../../getting_started/install/deploy.rst:288 +#: 8efc7824082545a4a98ebbd6b12fa00f msgid "" "To use llama.cpp, you need to prepare a gguf format model file, and there" " are two common ways to obtain it, you can choose either:" msgstr "使用 llama.cpp,你需要准备 gguf 格式的文件,你可以通过以下两种方法获取" -#: ../../getting_started/install/deploy.rst:295 -#: 8aefa2f2e0ab47469717aff4af20668e +#: ../../getting_started/install/deploy.rst:290 +#: 5b9f3a35779c4f89a4b9051904c5f7d8 msgid "**1. Download a pre-converted model file.**" msgstr "**1.下载已转换的模型文件.**" -#: ../../getting_started/install/deploy.rst:297 -#: 9849e3b8c0824cfa9add58a97fb583c4 +#: ../../getting_started/install/deploy.rst:292 +#: e15f33a2e5fc4caaa9ad2e10cabf9d32 msgid "" "Suppose you want to use [Vicuna 13B v1.5](https://huggingface.co/lmsys" "/vicuna-13b-v1.5), you can download the file already converted from " @@ -341,13 +328,13 @@ msgstr "" "13B-v1.5-GGUF)下载已转换的文件,只需要一个文件。将其下载到models目录并将其重命名为 `ggml-" "model-q4_0.gguf`。" -#: ../../getting_started/install/deploy.rst:303 -#: b79538a3af8a4946b24d8ebdb343e8aa +#: ../../getting_started/install/deploy.rst:298 +#: 81ab603cd9b94cabb48add9541590b8b msgid "**2. Convert It Yourself**" msgstr "**2. 自行转换**" -#: ../../getting_started/install/deploy.rst:305 -#: 12f31f96202f4789af86c254feaac717 +#: ../../getting_started/install/deploy.rst:300 +#: f9b46aa70a0842d6acc7e837c8b27778 msgid "" "You can convert the model file yourself according to the instructions in " "[llama.cpp#prepare-data--run](https://github.com/ggerganov/llama.cpp" @@ -358,31 +345,31 @@ msgstr "" "#prepare-data--run)中的说明自行转换模型文件,并把转换后的文件放在models目录中,并重命名为`ggml-" "model-q4_0.gguf`。" -#: ../../getting_started/install/deploy.rst:307 -#: c45612d904e64b3a8c0d50c564447853 +#: ../../getting_started/install/deploy.rst:302 +#: 5278c05568dd4ad688bcc181e45caa18 msgid "**Installing Dependencies**" msgstr "**安装依赖**" -#: ../../getting_started/install/deploy.rst:309 -#: c3c04c3e560a46bba53719472a25ce11 +#: ../../getting_started/install/deploy.rst:304 +#: bd67bf651a9a4096a37e73851b5fad98 msgid "" "llama.cpp is an optional dependency in DB-GPT, and you can manually " "install it using the following command:" msgstr "llama.cpp在DB-GPT中是可选安装项, 你可以通过以下命令进行安装" -#: ../../getting_started/install/deploy.rst:316 -#: 25f8ceb4fca941cdbd7c4dcc49818d79 +#: ../../getting_started/install/deploy.rst:311 +#: 71ed6ae4d0aa4d3ca27ebfffc42a5095 msgid "**3.Modifying the Configuration File**" msgstr "**3.修改配置文件**" -#: ../../getting_started/install/deploy.rst:318 -#: 5a63a04a43a1487eac56f2560dbc2275 +#: ../../getting_started/install/deploy.rst:313 +#: a0a2fdb799524ef4938df2c306536e2a msgid "Next, you can directly modify your `.env` file to enable llama.cpp." msgstr "修改`.env`文件使用llama.cpp" -#: ../../getting_started/install/deploy.rst:325 -#: ../../getting_started/install/deploy.rst:393 -#: e8b1498ad8c44201ba2e050db454c61c ffcb505780884dddaf3559990405a081 +#: ../../getting_started/install/deploy.rst:320 +#: ../../getting_started/install/deploy.rst:388 +#: 03694cbb7dfa432cb32116925357f008 07594f3e3e2e4d0f86b243629df5699e msgid "" "Then you can run it according to `Run `_" @@ -390,56 +377,56 @@ msgstr "" "然后你可以根据[运行](https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-" "cn/zh_CN/latest/getting_started/install/deploy/deploy.html#run)来运行" -#: ../../getting_started/install/deploy.rst:328 -#: 0d8d0f68e43b465a9537fbc741a9d37f +#: ../../getting_started/install/deploy.rst:323 +#: c9bbc15ea2fc4562bdf87a4e099600a0 msgid "**More Configurations**" msgstr "**更多配置文件**" -#: ../../getting_started/install/deploy.rst:330 -#: 6fdef4b280e5456faf11521700b7fe04 +#: ../../getting_started/install/deploy.rst:325 +#: 9beff887d8554d1dac169de93625c1b2 msgid "" "In DB-GPT, the model configuration can be done through `{model " "name}_{config key}`." msgstr "在DB-GPT中,模型配置可以通过`{模型名称}_{配置名}` 来配置。" -#: ../../getting_started/install/deploy.rst:332 -#: 256b25378f3d4bfd902f155b3a4346ad +#: ../../getting_started/install/deploy.rst:327 +#: 6cad64bcc9f141de85479203b21f7f9e msgid "More Configurations" msgstr "**更多配置文件**" -#: ../../getting_started/install/deploy.rst:336 -#: ebe4390d2de44fd288379a439d99bccd +#: ../../getting_started/install/deploy.rst:331 +#: de97b0d5b59c4bfabbd47b7e1766cc70 msgid "Environment Variable Key" msgstr "环境变量Key" -#: ../../getting_started/install/deploy.rst:337 -#: ee1c68623cc24446b4036870e0c7f21c +#: ../../getting_started/install/deploy.rst:332 +#: 76afa3655f644576b54b4422bad3fcad msgid "Default" msgstr "默认值" -#: ../../getting_started/install/deploy.rst:338 -#: ed6c358d27fb4022a70de1e733ad99cd +#: ../../getting_started/install/deploy.rst:333 +#: 0dcabfeeb4874e08ba53d4b4aa6a1d73 msgid "Description" msgstr "描述" -#: ../../getting_started/install/deploy.rst:339 -#: 4ad9e1b85c294cf084b8ebf858cc4075 +#: ../../getting_started/install/deploy.rst:334 +#: c1670aec27cf4c068d825456817d7667 msgid "llama_cpp_prompt_template" msgstr "" -#: ../../getting_started/install/deploy.rst:340 -#: ../../getting_started/install/deploy.rst:343 -#: ../../getting_started/install/deploy.rst:349 -#: ../../getting_started/install/deploy.rst:355 -#: ../../getting_started/install/deploy.rst:361 -#: 0cfccd9b8f7043ec8ccfe5159dfcf2c3 155d01bf0ad94016a32a2ec18a0fd881 -#: 3a194e635268499a939990b3503da72e 8909fd33e33b4f5a9208b8338b82b20f -#: e32e3219d2384884b398054cecceec8a +#: ../../getting_started/install/deploy.rst:335 +#: ../../getting_started/install/deploy.rst:338 +#: ../../getting_started/install/deploy.rst:344 +#: ../../getting_started/install/deploy.rst:350 +#: ../../getting_started/install/deploy.rst:356 +#: 1e13d43ba3574c33afa7e44d1643171b 355e51a688a0463f881ffce1a6cb0934 +#: 3775eb80762c4c6189efcaf62ee25556 49c8f875066f49c6aac195805f88e4a9 +#: 4d4358e00a31419b96d937cbbb4d9943 msgid "None" msgstr "" -#: ../../getting_started/install/deploy.rst:341 -#: c395eb1a7b044536a7ed300320e230f5 +#: ../../getting_started/install/deploy.rst:336 +#: bb31e19533e5434b832d5975bf579dc3 msgid "" "Prompt template name, now support: zero_shot, vicuna_v1.1,alpaca,llama-2" ",baichuan-chat,internlm-chat, If None, the prompt template is " @@ -448,182 +435,198 @@ msgstr "" "Prompt template 现在可以支持`zero_shot, vicuna_v1.1,alpaca,llama-2,baichuan-" "chat,internlm-chat`, 如果是None, 可以根据模型路径来自动获取模型 Prompt template" -#: ../../getting_started/install/deploy.rst:342 -#: 8fb84e002d1f4fc79bd4465b161e018a +#: ../../getting_started/install/deploy.rst:337 +#: 38ed23e19e2a47cf8fbacb035cfe1292 msgid "llama_cpp_model_path" msgstr "" -#: ../../getting_started/install/deploy.rst:344 -#: 81df474169634fbf9da20fe239d903a0 +#: ../../getting_started/install/deploy.rst:339 +#: eb069fdfdfeb4b17b723ee6733ba50c2 msgid "Model path" msgstr "模型路径" -#: ../../getting_started/install/deploy.rst:345 -#: a94ac450e72940f78b8ba6f6c9854248 +#: ../../getting_started/install/deploy.rst:340 +#: 348d3ff3e4f44ceb99aadead11f5cca5 msgid "llama_cpp_n_gpu_layers" msgstr "" -#: ../../getting_started/install/deploy.rst:346 -#: 06a24fb226f24ed4a93cde7034a3b67f +#: ../../getting_started/install/deploy.rst:341 +#: 007deecf593b4553b6ca8df3e9240a28 msgid "1000000000" msgstr "" -#: ../../getting_started/install/deploy.rst:347 -#: d29a8733688a4c62a3ea88e4793b82ef +#: ../../getting_started/install/deploy.rst:342 +#: 4da435c417f0482581895bf4d052a6a1 msgid "" "Number of layers to offload to the GPU, Set this to 1000000000 to offload" " all layers to the GPU. If your GPU VRAM is not enough, you can set a low" " number, eg: 10" msgstr "要将多少网络层转移到GPU上,将其设置为1000000000以将所有层转移到GPU上。如果您的 GPU 内存不足,可以设置较低的数字,例如:10。" -#: ../../getting_started/install/deploy.rst:348 -#: 8531ecd5690e46f2a9d64823405054b1 +#: ../../getting_started/install/deploy.rst:343 +#: 4f186505ea81467590cf817d116e6879 msgid "llama_cpp_n_threads" msgstr "" -#: ../../getting_started/install/deploy.rst:350 -#: d22c11631f5b4bc3b9dabad2175f26d5 +#: ../../getting_started/install/deploy.rst:345 +#: b94dc2fb2cd14a4a8f38ba95b05fbb5b msgid "" "Number of threads to use. If None, the number of threads is automatically" " determined" msgstr "要使用的线程数量。如果为None,则线程数量将自动确定。" -#: ../../getting_started/install/deploy.rst:351 -#: 06994945569849a9a07ca0fbb56509e4 +#: ../../getting_started/install/deploy.rst:346 +#: 867f2357430440eba4e749a8a39bff18 msgid "llama_cpp_n_batch" msgstr "" -#: ../../getting_started/install/deploy.rst:352 -#: a509c6b3800941aa8aaed1c2c3a89937 +#: ../../getting_started/install/deploy.rst:347 +#: 78516f7b23264147bae11e13426097eb msgid "512" msgstr "" -#: ../../getting_started/install/deploy.rst:353 -#: 02f71c7f7ddc49f6b61b163237f4c4fe +#: ../../getting_started/install/deploy.rst:348 +#: c2ec97ffef3e4a70afef6634e78801a2 msgid "Maximum number of prompt tokens to batch together when calling llama_eval" msgstr "在调用llama_eval时,批处理在一起的prompt tokens的最大数量" -#: ../../getting_started/install/deploy.rst:354 -#: 4d0df2430c22464fac021d816b4fa0c3 +#: ../../getting_started/install/deploy.rst:349 +#: 29ad3c5ab7134da49d6fca3b42d734d6 msgid "llama_cpp_n_gqa" msgstr "" -#: ../../getting_started/install/deploy.rst:356 -#: 24304fe7c331423ebcc9eb407d6f6f46 +#: ../../getting_started/install/deploy.rst:351 +#: e5bc322b0c824465b1adbd162838a3b7 msgid "Grouped-query attention. Must be 8 for llama-2 70b." msgstr "对于 llama-2 70B 模型,Grouped-query attention 必须为8。" -#: ../../getting_started/install/deploy.rst:357 -#: 8c6b332cdcc845dc9c218e3de7050e3e +#: ../../getting_started/install/deploy.rst:352 +#: 43e7d412238a4f0ba8227938d9fa4172 msgid "llama_cpp_rms_norm_eps" msgstr "" -#: ../../getting_started/install/deploy.rst:358 -#: 2c2ac24d7d264be3aa6960e776fa5e56 +#: ../../getting_started/install/deploy.rst:353 +#: 6328db04645b4b089593291e2ca13f79 msgid "5e-06" msgstr "" -#: ../../getting_started/install/deploy.rst:359 -#: 2d7170d63e364aa3bb3040d96ba31316 +#: ../../getting_started/install/deploy.rst:354 +#: 6c8bf631cece42fa86954f5cf2d75503 msgid "5e-6 is a good value for llama-2 models." msgstr "对于llama-2模型来说,5e-6是一个不错的值。" -#: ../../getting_started/install/deploy.rst:360 -#: 402b942db0b149a8985685dbfe6f31c7 +#: ../../getting_started/install/deploy.rst:355 +#: 22ebee39fe8b4cc18378447cac67e631 msgid "llama_cpp_cache_capacity" msgstr "" -#: ../../getting_started/install/deploy.rst:362 -#: c990275acf6741398ac147a8ddce1ce3 +#: ../../getting_started/install/deploy.rst:357 +#: 4dc98bede90f4237829f65513e4adf61 msgid "Maximum cache capacity. Examples: 2000MiB, 2GiB" msgstr "模型缓存最大值. 例如: 2000MiB, 2GiB" -#: ../../getting_started/install/deploy.rst:363 -#: 5f579fac7df54a338dc3c8a348bc90ea +#: ../../getting_started/install/deploy.rst:358 +#: bead617b5af943dab0bc1209823d3c22 msgid "llama_cpp_prefer_cpu" msgstr "" -#: ../../getting_started/install/deploy.rst:364 -#: 8413a349be174d50991653a5554933c5 +#: ../../getting_started/install/deploy.rst:359 +#: 8efb44f1cfc54b1a8b3ca8ea138113ee msgid "False" msgstr "" -#: ../../getting_started/install/deploy.rst:365 -#: 78af815bd0724301870ef934d27b208d +#: ../../getting_started/install/deploy.rst:360 +#: b854e6a44c8348ceb72ac382b73ceec5 msgid "" "If a GPU is available, it will be preferred by default, unless " "prefer_cpu=False is configured." msgstr "如果有可用的GPU,默认情况下会优先使用GPU,除非配置了 prefer_cpu=False。" -#: ../../getting_started/install/deploy.rst:368 -#: f193ef95a45f42d2a5e156a79ed09685 +#: ../../getting_started/install/deploy.rst:363 +#: 41b0440eb0074e5fa8c87dd404efe0ce msgid "vllm" msgstr "" -#: ../../getting_started/install/deploy.rst:370 -#: e28e1d550515498e8e41a2e1187f9956 +#: ../../getting_started/install/deploy.rst:365 +#: 6fc445675bf74b2ea2fe0c7f2a64db69 msgid "vLLM is a fast and easy-to-use library for LLM inference and serving." msgstr "\"vLLM 是一个快速且易于使用的 LLM 推理和服务的库。" -#: ../../getting_started/install/deploy.rst:372 -#: adbcb8083c274d5eae4209b5b4fb8048 +#: ../../getting_started/install/deploy.rst:367 +#: aab5f913d29445c4b345180b8793ebc7 msgid "**Running vLLM**" msgstr "**运行vLLM**" -#: ../../getting_started/install/deploy.rst:374 -#: 188e0fb1d0d34fccb15a796707ca95dd +#: ../../getting_started/install/deploy.rst:369 +#: a9560d697821404cb0abdabf9f479645 msgid "**1.Installing Dependencies**" msgstr "**1.安装依赖**" -#: ../../getting_started/install/deploy.rst:376 -#: dbfcdd5d0e2a4cb29692022e63766116 +#: ../../getting_started/install/deploy.rst:371 +#: b008224d4f314e5c988335262c95a42e msgid "" "vLLM is an optional dependency in DB-GPT, and you can manually install it" " using the following command:" msgstr "vLLM 在 DB-GPT 是一个可选依赖, 你可以使用下面的命令手动安装它:" -#: ../../getting_started/install/deploy.rst:382 -#: 4401138d25b34b028c4bf43ddfb89aa3 +#: ../../getting_started/install/deploy.rst:377 +#: 7dc0c8e996124177935a4e0d9ef19837 msgid "**2.Modifying the Configuration File**" msgstr "**2.修改配置文件**" -#: ../../getting_started/install/deploy.rst:384 -#: ee0ad8661dce4b909b07df4773150ee6 +#: ../../getting_started/install/deploy.rst:379 +#: 49667576b44c46bf87d5bf4d207dd63a msgid "Next, you can directly modify your .env file to enable vllm." msgstr "你可以直接修改你的 `.env` 文件" -#: ../../getting_started/install/deploy.rst:391 -#: 1be59f77d774429b9959bf834871a414 +#: ../../getting_started/install/deploy.rst:386 +#: f16a78f0ee6545babab0d66f12654c0a msgid "" "You can view the models supported by vLLM `here " "`_" -msgstr "你可以在 " +msgstr "" +"你可以在 " "[这里](https://vllm.readthedocs.io/en/latest/models/supported_models.html" "#supported-models) 查看 vLLM 支持的模型。" -#: ../../getting_started/install/deploy.rst:400 -#: def3d7d7cd03407d9dfeff2e1eee951e +#: ../../getting_started/install/deploy.rst:395 +#: f7ae366723e9494d8177eeb963ba0ed9 msgid "3.Prepare sql example(Optional)" msgstr "3.准备 sql example(可选)" -#: ../../getting_started/install/deploy.rst:401 -#: b6038f79dac74fda8f6db08325bf0686 +#: ../../getting_started/install/deploy.rst:396 +#: d302aac8ddb346598fc9d73e0f6c2cbc msgid "**(Optional) load examples into SQLite**" msgstr "**(可选) load examples into SQLite**" -#: ../../getting_started/install/deploy.rst:408 -#: 37c84b22186b48baba5aca60f8a70f49 +#: ../../getting_started/install/deploy.rst:403 +#: ae2a315e40854f27a074f2c0f2506014 msgid "On windows platform:" msgstr "" -#: ../../getting_started/install/deploy.rst:415 -#: 09c9508bac8a4330931d45d02c33762f +#: ../../getting_started/install/deploy.rst:410 +#: 36b4b7a813844af3a4ec8062b39059a3 msgid "4.Run db-gpt server" msgstr "4.运行db-gpt server" -#: ../../getting_started/install/deploy.rst:421 -#: 04d68abe85a646388956cbd1b47f3232 +#: ../../getting_started/install/deploy.rst:416 +#: e56f15e563484027b7efb2147c9b71a7 msgid "**Open http://localhost:5000 with your browser to see the product.**" msgstr "打开浏览器访问http://localhost:5000" +#~ msgid "" +#~ "DB-GPT can be deployed on servers" +#~ " with low hardware requirements or on" +#~ " servers with high hardware requirements." +#~ " You can install DB-GPT by " +#~ "Using third-part LLM REST API " +#~ "Service OpenAI, Azure." +#~ msgstr "" + +#~ msgid "" +#~ "And you can also install DB-GPT" +#~ " by deploy LLM Service by download" +#~ " LLM model." +#~ msgstr "" + diff --git a/docs/locales/zh_CN/LC_MESSAGES/modules/plugins.po b/docs/locales/zh_CN/LC_MESSAGES/modules/plugins.po index d42bc3d55..98bc4241d 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/modules/plugins.po +++ b/docs/locales/zh_CN/LC_MESSAGES/modules/plugins.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 0.3.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-14 21:47+0800\n" +"POT-Creation-Date: 2023-11-03 15:25+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -19,11 +19,11 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.12.1\n" -#: ../../modules/plugins.md:1 8e0200134cca45b6aead6d05b60ca95a +#: ../../modules/plugins.md:1 e8c539b65ccd459793e8ed3812903578 msgid "Plugins" msgstr "插件" -#: ../../modules/plugins.md:3 d0d532cfe9b44fa0916d7d5b912a744a +#: ../../modules/plugins.md:3 0d6f6bdcf843416fb35d9f51df52bead msgid "" "The ability of Agent and Plugin is the core of whether large models can " "be automated. In this project, we natively support the plugin mode, and " @@ -35,49 +35,56 @@ msgstr "" "Agent与插件能力是大模型能否自动化的核心,在本的项目中,原生支持插件模式,大模型可以自动化完成目标。 同时为了充分发挥社区的优势" ",本项目中所用的插件原生支持Auto-GPT插件生态,即Auto-GPT的插件可以直接在我们的项目中运行。" -#: ../../modules/plugins.md:5 2f78a6b397a24f34b0d5771ca93efb0b +#: ../../modules/plugins.md:6 625763bc41fe417c8e4ea03ab2f8fdfc +msgid "" +"The LLM (Language Model) suitable for the Plugin scene is * " +"chatgpt3.5. * chatgpt4." +msgstr "Plugin场景适用的LLM是 * " +"chatgpt3.5. * chatgpt4." + +#: ../../modules/plugins.md:11 8c539e139f6648b2bef5dc683b8e093c #, fuzzy msgid "Local Plugins" msgstr "插件" -#: ../../modules/plugins.md:7 54a817a638c3440989191b3bffaca6de +#: ../../modules/plugins.md:13 2cc7ba992d524913b3377cad3bf747d3 msgid "1.1 How to write local plugins." msgstr "" -#: ../../modules/plugins.md:9 fbdc0a9d327f432aa6a380117dfb2f11 +#: ../../modules/plugins.md:15 eddffc1d2c434e45890a9befa1bb5160 msgid "" "Local plugins use the Auto-GPT plugin template. A simple example is as " "follows: first write a plugin file called \"sql_executor.py\"." msgstr "" -#: ../../modules/plugins.md:39 dc398ab427bd4d15b3b7c8cb1ff032b3 +#: ../../modules/plugins.md:45 06efbea552bb4dc7828d842b779e41d4 msgid "" "Then set the \"can_handle_post_prompt\" method of the plugin template to " "True. In the \"post_prompt\" method, write the prompt information and the" " mapped plugin function." msgstr "" -#: ../../modules/plugins.md:81 c9d4019392bf452e906057cbe9271005 +#: ../../modules/plugins.md:87 afd3cfb379bb463e97e515ae65790830 msgid "1.2 How to use local plugins" msgstr "" -#: ../../modules/plugins.md:83 9beaed4a71124ecf9544a1dba0d1e722 +#: ../../modules/plugins.md:89 f43a70e4cb5c4846a5bb8df3853021ba msgid "" "Pack your plugin project into `your-plugin.zip` and place it in the " "`/plugins/` directory of the DB-GPT project. After starting the " "webserver, you can select and use it in the `Plugin Model` section." msgstr "" -#: ../../modules/plugins.md:86 9a1439c883a947d7acac3fd1196b3c1e +#: ../../modules/plugins.md:92 8269458bd7f5480dbc56100865eb1eb0 #, fuzzy msgid "Public Plugins" msgstr "插件" -#: ../../modules/plugins.md:88 2ed4c509bf5848adb3fa163752a1cfa1 +#: ../../modules/plugins.md:94 ec5bb7b6b2cf464d8b8400f3dfd9a50e msgid "1.1 How to use public plugins" msgstr "" -#: ../../modules/plugins.md:90 dd5ba8d582204b2f89ce802a1232b11d +#: ../../modules/plugins.md:96 3025a85c905c49b6b2ac3f5c39c84c93 msgid "" "By default, after launching the webserver, plugins from the public plugin" " library `DB-GPT-Plugins` will be automatically loaded. For more details," @@ -85,17 +92,17 @@ msgid "" "Plugins)" msgstr "" -#: ../../modules/plugins.md:92 244f0591bc5045eab175754521b414c4 +#: ../../modules/plugins.md:98 e73d7779df254ba49fe7123ce06353aa msgid "1.2 Contribute to the DB-GPT-Plugins repository" msgstr "" -#: ../../modules/plugins.md:94 e00bac1a299b46caa19b9cf16709d6ba +#: ../../modules/plugins.md:100 3297fb00dfc940e8a614c3858640cfe5 msgid "" "Please refer to the plugin development process in the public plugin " "library, and put the configuration parameters in `.plugin_env`" msgstr "" -#: ../../modules/plugins.md:96 315fbf576ea24158adc7b564f53940e0 +#: ../../modules/plugins.md:102 13280b270b304e139ed67e5b0dafa5b4 msgid "" "We warmly welcome everyone to contribute plugins to the public plugin " "library!" diff --git a/docs/modules/plugins.md b/docs/modules/plugins.md index 6f2617146..b78578066 100644 --- a/docs/modules/plugins.md +++ b/docs/modules/plugins.md @@ -2,6 +2,11 @@ The ability of Agent and Plugin is the core of whether large models can be automated. In this project, we natively support the plugin mode, and large models can automatically achieve their goals. At the same time, in order to give full play to the advantages of the community, the plugins used in this project natively support the Auto-GPT plugin ecology, that is, Auto-GPT plugins can directly run in our project. +```{admonition} The LLM (Language Model) suitable for the Plugin scene is +* chatgpt3.5. +* chatgpt4. +``` + ## Local Plugins ### 1.1 How to write local plugins. diff --git a/setup.py b/setup.py index 8a62faf4a..a6bea38f1 100644 --- a/setup.py +++ b/setup.py @@ -469,7 +469,7 @@ init_install_requires() setuptools.setup( name="db-gpt", packages=find_packages(exclude=("tests", "*.tests", "*.tests.*", "examples")), - version="0.4.0", + version="0.4.1", author="csunny", author_email="cfqcsunny@gmail.com", description="DB-GPT is an experimental open-source project that uses localized GPT large models to interact with your data and environment." From 3ea85a6d59dc5bb594ea3421f172bc67b1cd3f3d Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Fri, 3 Nov 2023 17:50:01 +0800 Subject: [PATCH 42/57] feat:web add reference --- pilot/scene/chat_knowledge/v1/chat.py | 12 +++++++----- pilot/server/static/404.html | 2 +- pilot/server/static/404/index.html | 2 +- .../_buildManifest.js | 2 +- .../_ssgManifest.js | 0 ...4.f9e3c1ab25dda485.js => 304.406e3b6b89d8e49a.js} | 2 +- .../_next/static/chunks/604.0b6534ada5e802bc.js | 1 - .../_next/static/chunks/604.3bbbeaa2c767e7dc.js | 1 + ...-7394a5c2fd417054.js => _app-41ccdddf1de778e7.js} | 2 +- .../static/chunks/pages/database-2066e1a37e227df6.js | 1 + .../static/chunks/pages/database-ed7e37a49de751e1.js | 1 - .../chunks/pages/knowledge-40fc3593b22ec10a.js | 1 + .../chunks/pages/knowledge-c73b240310994685.js | 1 - ...cb320c82fd7041.js => webpack-77553ab117b6c794.js} | 2 +- .../static/_next/static/css/6e82c5f591153e56.css | 3 --- .../static/_next/static/css/d07b94ffd4f33c05.css | 3 +++ pilot/server/static/agent/index.html | 2 +- pilot/server/static/chat/[scene]/[id]/index.html | 2 +- pilot/server/static/chat/index.html | 2 +- pilot/server/static/database/index.html | 2 +- pilot/server/static/index.html | 2 +- pilot/server/static/knowledge/chunk/index.html | 2 +- pilot/server/static/knowledge/index.html | 2 +- pilot/server/static/models/index.html | 2 +- pilot/server/static/prompt/index.html | 2 +- 25 files changed, 28 insertions(+), 26 deletions(-) rename pilot/server/static/_next/static/{2DHoqE6YLNDUgtBJJVe8p => Kx09a-jiuL7Kdi7fpiNnT}/_buildManifest.js (81%) rename pilot/server/static/_next/static/{2DHoqE6YLNDUgtBJJVe8p => Kx09a-jiuL7Kdi7fpiNnT}/_ssgManifest.js (100%) rename pilot/server/static/_next/static/chunks/{304.f9e3c1ab25dda485.js => 304.406e3b6b89d8e49a.js} (74%) delete mode 100644 pilot/server/static/_next/static/chunks/604.0b6534ada5e802bc.js create mode 100644 pilot/server/static/_next/static/chunks/604.3bbbeaa2c767e7dc.js rename pilot/server/static/_next/static/chunks/pages/{_app-7394a5c2fd417054.js => _app-41ccdddf1de778e7.js} (92%) create mode 100644 pilot/server/static/_next/static/chunks/pages/database-2066e1a37e227df6.js delete mode 100644 pilot/server/static/_next/static/chunks/pages/database-ed7e37a49de751e1.js create mode 100644 pilot/server/static/_next/static/chunks/pages/knowledge-40fc3593b22ec10a.js delete mode 100644 pilot/server/static/_next/static/chunks/pages/knowledge-c73b240310994685.js rename pilot/server/static/_next/static/chunks/{webpack-fbcb320c82fd7041.js => webpack-77553ab117b6c794.js} (60%) delete mode 100644 pilot/server/static/_next/static/css/6e82c5f591153e56.css create mode 100644 pilot/server/static/_next/static/css/d07b94ffd4f33c05.css diff --git a/pilot/scene/chat_knowledge/v1/chat.py b/pilot/scene/chat_knowledge/v1/chat.py index 4f3646718..d57b32b25 100644 --- a/pilot/scene/chat_knowledge/v1/chat.py +++ b/pilot/scene/chat_knowledge/v1/chat.py @@ -130,19 +130,21 @@ class ChatKnowledge(BaseChat): build knowledge reference view message to web { "title":"References", - "reference":{ + "references":[{ "name":"aa.pdf", "pages":["1","2","3"] - }, + }] } """ - references = {"title": "References", "reference": {}} + references = {"title": "References", "references": []} for item in sources: + reference = {} source = item["source"] if "source" in item else "" - references["reference"]["name"] = source + reference["name"] = source pages = item["pages"] if "pages" in item else [] if len(pages) > 0: - references["reference"]["pages"] = pages + reference["pages"] = pages + references["references"].append(reference) html = ( f"""{json.dumps(references, ensure_ascii=False)}""" ) diff --git a/pilot/server/static/404.html b/pilot/server/static/404.html index 63a2f9803..cb2ecf3aa 100644 --- a/pilot/server/static/404.html +++ b/pilot/server/static/404.html @@ -1 +1 @@ -404: This page could not be found

404

This page could not be found.

\ No newline at end of file +404: This page could not be found

404

This page could not be found.

\ No newline at end of file diff --git a/pilot/server/static/404/index.html b/pilot/server/static/404/index.html index 63a2f9803..cb2ecf3aa 100644 --- a/pilot/server/static/404/index.html +++ b/pilot/server/static/404/index.html @@ -1 +1 @@ -404: This page could not be found

404

This page could not be found.

\ No newline at end of file +404: This page could not be found

404

This page could not be found.

\ No newline at end of file diff --git a/pilot/server/static/_next/static/2DHoqE6YLNDUgtBJJVe8p/_buildManifest.js b/pilot/server/static/_next/static/Kx09a-jiuL7Kdi7fpiNnT/_buildManifest.js similarity index 81% rename from pilot/server/static/_next/static/2DHoqE6YLNDUgtBJJVe8p/_buildManifest.js rename to pilot/server/static/_next/static/Kx09a-jiuL7Kdi7fpiNnT/_buildManifest.js index 95dcfcb73..004ab89c7 100644 --- a/pilot/server/static/_next/static/2DHoqE6YLNDUgtBJJVe8p/_buildManifest.js +++ b/pilot/server/static/_next/static/Kx09a-jiuL7Kdi7fpiNnT/_buildManifest.js @@ -1 +1 @@ -self.__BUILD_MANIFEST=function(s,c,a,e,t,n,b,d,k,h,i,u){return{__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":[b,s,c,a,n,d,"static/chunks/539-dcd22f1f6b99ebee.js","static/chunks/pages/index-195d2b50dab810dd.js"],"/_error":["static/chunks/pages/_error-dee72aff9b2e2c12.js"],"/agent":[s,c,e,k,t,"static/chunks/pages/agent-25358689f05784e9.js"],"/chat":["static/chunks/pages/chat-4b4742a8b97ead61.js"],"/chat/[scene]/[id]":["static/chunks/pages/chat/[scene]/[id]-c4ba90e8044f953b.js"],"/database":[s,c,a,e,t,n,h,"static/chunks/643-d8f53f40dd3c5b40.js","static/chunks/pages/database-ed7e37a49de751e1.js"],"/knowledge":[i,s,c,e,k,t,n,"static/chunks/63-d9f1013be8e4599a.js","static/chunks/pages/knowledge-c73b240310994685.js"],"/knowledge/chunk":[e,t,"static/chunks/pages/knowledge/chunk-e27c2e349b868b28.js"],"/models":[i,s,c,a,u,h,"static/chunks/pages/models-fab5e316babfc6de.js"],"/prompt":[b,s,c,a,u,d,"static/chunks/45-9ff739c09925ea35.js","static/chunks/61-d2f6cba798a49339.js","static/chunks/367-2a6e805cba0c79d3.js","static/chunks/pages/prompt-f7fa6931310ae8ba.js"],sortedPages:["/","/_app","/_error","/agent","/chat","/chat/[scene]/[id]","/database","/knowledge","/knowledge/chunk","/models","/prompt"]}}("static/chunks/44-941ba89e47567ba3.js","static/chunks/479-68b22ee2b7a47fb3.js","static/chunks/9-bb2c54d5c06ba4bf.js","static/chunks/442-197e6cbc1e54109a.js","static/chunks/813-cce9482e33f2430c.js","static/chunks/411-d9eba2657c72f766.js","static/chunks/29107295-90b90cb30c825230.js","static/chunks/719-5a18c3c696beda6f.js","static/chunks/365-2cad3676ccbb1b1a.js","static/chunks/928-74244889bd7f2699.js","static/chunks/75fc9c18-a784766a129ec5fb.js","static/chunks/815-fa0a8da2d0a72116.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB(); \ No newline at end of file +self.__BUILD_MANIFEST=function(s,c,a,e,t,n,b,d,k,h,i,f){return{__rewrites:{beforeFiles:[],afterFiles:[],fallback:[]},"/":[b,s,c,a,n,d,"static/chunks/539-dcd22f1f6b99ebee.js","static/chunks/pages/index-195d2b50dab810dd.js"],"/_error":["static/chunks/pages/_error-dee72aff9b2e2c12.js"],"/agent":[s,c,e,k,t,"static/chunks/pages/agent-25358689f05784e9.js"],"/chat":["static/chunks/pages/chat-4b4742a8b97ead61.js"],"/chat/[scene]/[id]":["static/chunks/pages/chat/[scene]/[id]-c4ba90e8044f953b.js"],"/database":[s,c,a,e,t,n,h,"static/chunks/643-d8f53f40dd3c5b40.js","static/chunks/pages/database-2066e1a37e227df6.js"],"/knowledge":[i,s,c,e,k,t,n,"static/chunks/63-d9f1013be8e4599a.js","static/chunks/pages/knowledge-40fc3593b22ec10a.js"],"/knowledge/chunk":[e,t,"static/chunks/pages/knowledge/chunk-e27c2e349b868b28.js"],"/models":[i,s,c,a,f,h,"static/chunks/pages/models-fab5e316babfc6de.js"],"/prompt":[b,s,c,a,f,d,"static/chunks/45-9ff739c09925ea35.js","static/chunks/61-d2f6cba798a49339.js","static/chunks/367-2a6e805cba0c79d3.js","static/chunks/pages/prompt-f7fa6931310ae8ba.js"],sortedPages:["/","/_app","/_error","/agent","/chat","/chat/[scene]/[id]","/database","/knowledge","/knowledge/chunk","/models","/prompt"]}}("static/chunks/44-941ba89e47567ba3.js","static/chunks/479-68b22ee2b7a47fb3.js","static/chunks/9-bb2c54d5c06ba4bf.js","static/chunks/442-197e6cbc1e54109a.js","static/chunks/813-cce9482e33f2430c.js","static/chunks/411-d9eba2657c72f766.js","static/chunks/29107295-90b90cb30c825230.js","static/chunks/719-5a18c3c696beda6f.js","static/chunks/365-2cad3676ccbb1b1a.js","static/chunks/928-74244889bd7f2699.js","static/chunks/75fc9c18-a784766a129ec5fb.js","static/chunks/815-fa0a8da2d0a72116.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB(); \ No newline at end of file diff --git a/pilot/server/static/_next/static/2DHoqE6YLNDUgtBJJVe8p/_ssgManifest.js b/pilot/server/static/_next/static/Kx09a-jiuL7Kdi7fpiNnT/_ssgManifest.js similarity index 100% rename from pilot/server/static/_next/static/2DHoqE6YLNDUgtBJJVe8p/_ssgManifest.js rename to pilot/server/static/_next/static/Kx09a-jiuL7Kdi7fpiNnT/_ssgManifest.js diff --git a/pilot/server/static/_next/static/chunks/304.f9e3c1ab25dda485.js b/pilot/server/static/_next/static/chunks/304.406e3b6b89d8e49a.js similarity index 74% rename from pilot/server/static/_next/static/chunks/304.f9e3c1ab25dda485.js rename to pilot/server/static/_next/static/chunks/304.406e3b6b89d8e49a.js index 0cd7e35d9..a065ea081 100644 --- a/pilot/server/static/_next/static/chunks/304.f9e3c1ab25dda485.js +++ b/pilot/server/static/_next/static/chunks/304.406e3b6b89d8e49a.js @@ -1 +1 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[304],{39156:function(e,t,l){"use strict";l.d(t,{Z:function(){return m}});var a=l(85893),n=l(41118),s=l(30208),r=l(40911),c=l(58234);function i(e){let{chart:t}=e;return(0,a.jsx)("div",{className:"flex-1 min-w-0",children:(0,a.jsx)(n.Z,{className:"h-full",sx:{background:"transparent"},children:(0,a.jsxs)(s.Z,{className:"h-full",children:[(0,a.jsx)(r.ZP,{gutterBottom:!0,component:"div",children:t.chart_name}),(0,a.jsx)(r.ZP,{gutterBottom:!0,level:"body3",children:t.chart_desc}),(0,a.jsx)("div",{className:"h-[300px]",children:(0,a.jsx)(c.k,{style:{height:"100%"},options:{autoFit:!0,type:"interval",data:t.values,encode:{x:"name",y:"value",color:"type"},axis:{x:{labelAutoRotate:!1}}}})})]})})})}function o(e){let{chart:t}=e;return(0,a.jsx)("div",{className:"flex-1 min-w-0",children:(0,a.jsx)(n.Z,{className:"h-full",sx:{background:"transparent"},children:(0,a.jsxs)(s.Z,{className:"h-full",children:[(0,a.jsx)(r.ZP,{gutterBottom:!0,component:"div",children:t.chart_name}),(0,a.jsx)(r.ZP,{gutterBottom:!0,level:"body3",children:t.chart_desc}),(0,a.jsx)("div",{className:"h-[300px]",children:(0,a.jsx)(c.k,{style:{height:"100%"},options:{autoFit:!0,type:"view",data:t.values,children:[{type:"line",encode:{x:"name",y:"value",color:"type",shape:"smooth"}},{type:"area",encode:{x:"name",y:"value",color:"type",shape:"smooth"},legend:!1,style:{fillOpacity:.15}}],axis:{x:{labelAutoRotate:!1}}}})})]})})})}var d=l(61685),u=l(96486);function h(e){var t,l;let{chart:c}=e,i=(0,u.groupBy)(c.values,"type");return(0,a.jsx)("div",{className:"flex-1 min-w-0",children:(0,a.jsx)(n.Z,{className:"h-full overflow-auto",sx:{background:"transparent"},children:(0,a.jsxs)(s.Z,{className:"h-full",children:[(0,a.jsx)(r.ZP,{gutterBottom:!0,component:"div",children:c.chart_name}),(0,a.jsx)(r.ZP,{gutterBottom:!0,level:"body3",children:c.chart_desc}),(0,a.jsx)("div",{className:"flex-1",children:(0,a.jsxs)(d.Z,{"aria-label":"basic table",stripe:"odd",hoverRow:!0,borderAxis:"bothBetween",children:[(0,a.jsx)("thead",{children:(0,a.jsx)("tr",{children:Object.keys(i).map(e=>(0,a.jsx)("th",{children:e},e))})}),(0,a.jsx)("tbody",{children:null===(t=Object.values(i))||void 0===t?void 0:null===(l=t[0])||void 0===l?void 0:l.map((e,t)=>{var l;return(0,a.jsx)("tr",{children:null===(l=Object.keys(i))||void 0===l?void 0:l.map(e=>{var l;return(0,a.jsx)("td",{children:(null==i?void 0:null===(l=i[e])||void 0===l?void 0:l[t].value)||""},e)})},t)})})]})})]})})})}var x=l(67294),m=function(e){let{chartsData:t}=e,l=(0,x.useMemo)(()=>{if(t){let e=[],l=null==t?void 0:t.filter(e=>"IndicatorValue"===e.chart_type);l.length>0&&e.push({charts:l,type:"IndicatorValue"});let a=null==t?void 0:t.filter(e=>"IndicatorValue"!==e.chart_type),n=a.length,s=0;return[[0],[1],[2],[1,2],[1,3],[2,1,2],[2,1,3],[3,1,3],[3,2,3]][n].forEach(t=>{if(t>0){let l=a.slice(s,s+t);s+=t,e.push({charts:l})}}),e}},[t]);return(0,a.jsx)("div",{className:"flex flex-col gap-3",children:null==l?void 0:l.map((e,t)=>(0,a.jsx)("div",{className:"".concat((null==e?void 0:e.type)!=="IndicatorValue"?"flex gap-3":""),children:e.charts.map(e=>"IndicatorValue"===e.chart_type?(0,a.jsx)("div",{className:"flex flex-row gap-3",children:e.values.map(e=>(0,a.jsx)("div",{className:"flex-1",children:(0,a.jsx)(n.Z,{sx:{background:"transparent"},children:(0,a.jsxs)(s.Z,{className:"justify-around",children:[(0,a.jsx)(r.ZP,{gutterBottom:!0,component:"div",children:e.name}),(0,a.jsx)(r.ZP,{children:e.value})]})})},e.name))},e.chart_uid):"LineChart"===e.chart_type?(0,a.jsx)(o,{chart:e},e.chart_uid):"BarChart"===e.chart_type?(0,a.jsx)(i,{chart:e},e.chart_uid):"Table"===e.chart_type?(0,a.jsx)(h,{chart:e},e.chart_uid):void 0)},"chart_row_".concat(t)))})}},70803:function(e,t,l){"use strict";l.d(t,{Z:function(){return B}});var a=l(85893),n=l(67294),s=l(2453),r=l(83062),c=l(31365),i=l(71577),o=l(49591),d=l(88484),u=l(29158),h=l(50489),x=l(41468),m=function(e){var t;let{convUid:l,chatMode:m,onComplete:p,...v}=e,[f,j]=(0,n.useState)(!1),[g,y]=s.ZP.useMessage(),[b,Z]=(0,n.useState)([]),[w,N]=(0,n.useState)(),{model:_}=(0,n.useContext)(x.p),P=async e=>{var t;if(!e){s.ZP.error("Please select the *.(csv|xlsx|xls) file");return}if(!/\.(csv|xlsx|xls)$/.test(null!==(t=e.file.name)&&void 0!==t?t:"")){s.ZP.error("File type must be csv, xlsx or xls");return}Z([e.file])},C=async()=>{j(!0);try{let e=new FormData;e.append("doc_file",b[0]),g.open({content:"Uploading ".concat(b[0].name),type:"loading",duration:0});let[t]=await (0,h.Vx)((0,h.qn)({convUid:l,chatMode:m,data:e,model:_,config:{timeout:36e5,onUploadProgress:e=>{let t=Math.ceil(e.loaded/(e.total||0)*100);N(t)}}}));if(t)return;s.ZP.success("success"),null==p||p()}catch(e){s.ZP.error((null==e?void 0:e.message)||"Upload Error")}finally{j(!1),g.destroy()}};return(0,a.jsx)(a.Fragment,{children:(0,a.jsxs)("div",{className:"flex items-start gap-2",children:[y,(0,a.jsx)(r.Z,{placement:"bottom",title:"File cannot be changed after upload",children:(0,a.jsx)(c.default,{disabled:f,className:"mr-1",beforeUpload:()=>!1,fileList:b,name:"file",accept:".csv,.xlsx,.xls",multiple:!1,onChange:P,showUploadList:{showDownloadIcon:!1,showPreviewIcon:!1,showRemoveIcon:!1},itemRender:()=>(0,a.jsx)(a.Fragment,{}),...v,children:(0,a.jsx)(i.ZP,{className:"flex justify-center items-center",type:"primary",disabled:f,icon:(0,a.jsx)(o.Z,{}),children:"Select File"})})}),(0,a.jsx)(i.ZP,{type:"primary",loading:f,className:"flex justify-center items-center",disabled:!b.length,icon:(0,a.jsx)(d.Z,{}),onClick:C,children:f?100===w?"Analysis":"Uploading":"Upload"}),!!b.length&&(0,a.jsxs)("div",{className:"mt-2 text-gray-500 text-sm flex items-center",children:[(0,a.jsx)(u.Z,{className:"mr-2"}),(0,a.jsx)("span",{children:null===(t=b[0])||void 0===t?void 0:t.name})]})]})})},p=function(e){let{onComplete:t}=e,{currentDialogue:l,scene:s,chatId:r}=(0,n.useContext)(x.p);return"chat_excel"!==s?null:(0,a.jsx)("div",{className:"max-w-md h-full relative",children:l?(0,a.jsxs)("div",{className:"flex h-8 overflow-hidden rounded",children:[(0,a.jsx)("div",{className:"flex items-center justify-center px-2 bg-gray-600 text-lg",children:(0,a.jsx)(u.Z,{className:"text-white"})}),(0,a.jsx)("div",{className:"flex items-center justify-center px-3 bg-gray-100 text-xs rounded-tr rounded-br dark:text-gray-800 truncate",children:l.select_param})]}):(0,a.jsx)(m,{convUid:r,chatMode:s,onComplete:t})})};l(23293);var v=l(78045),f=l(16165),j=l(96991),g=function(){return(0,a.jsx)("svg",{width:"1em",height:"1em",fill:"currentColor",viewBox:"0 0 1024 1024",version:"1.1",children:(0,a.jsx)("path",{d:"M602.24 246.72a17.28 17.28 0 0 0-11.84-16.32l-42.88-14.4A90.56 90.56 0 0 1 490.24 160l-14.4-42.88a17.28 17.28 0 0 0-32 0L428.8 160a90.56 90.56 0 0 1-57.28 57.28l-42.88 14.4a17.28 17.28 0 0 0 0 32l42.88 14.4a90.56 90.56 0 0 1 57.28 57.28l14.4 42.88a17.28 17.28 0 0 0 32 0l14.4-42.88a90.56 90.56 0 0 1 57.28-57.28l42.88-14.4a17.28 17.28 0 0 0 12.48-16.96z m301.12 221.76l-48.32-16a101.44 101.44 0 0 1-64-64l-16-48.32a19.2 19.2 0 0 0-36.8 0l-16 48.32a101.44 101.44 0 0 1-64 64l-48.32 16a19.2 19.2 0 0 0 0 36.8l48.32 16a101.44 101.44 0 0 1 64 64l16 48.32a19.2 19.2 0 0 0 36.8 0l16-48.32a101.44 101.44 0 0 1 64-64l48.32-16a19.2 19.2 0 0 0 0-36.8z m-376.64 195.52l-64-20.8a131.84 131.84 0 0 1-83.52-83.52l-20.8-64a25.28 25.28 0 0 0-47.68 0l-20.8 64a131.84 131.84 0 0 1-82.24 83.52l-64 20.8a25.28 25.28 0 0 0 0 47.68l64 20.8a131.84 131.84 0 0 1 83.52 83.84l20.8 64a25.28 25.28 0 0 0 47.68 0l20.8-64a131.84 131.84 0 0 1 83.52-83.52l64-20.8a25.28 25.28 0 0 0 0-47.68z","p-id":"3992"})})};function y(){let{isContract:e,setIsContract:t,scene:l}=(0,n.useContext)(x.p),s=l&&["chat_with_db_execute","chat_dashboard"].includes(l);return s?(0,a.jsxs)(v.ZP.Group,{value:e,defaultValue:!0,buttonStyle:"solid",onChange:()=>{t(!e)},children:[(0,a.jsxs)(v.ZP.Button,{value:!1,children:[(0,a.jsx)(f.Z,{component:g,className:"mr-1"}),"Preview"]}),(0,a.jsxs)(v.ZP.Button,{value:!0,children:[(0,a.jsx)(j.Z,{className:"mr-1"}),"Editor"]})]}):null}var b=l(81799),Z=function(){return(0,a.jsx)("svg",{width:"1em",height:"1em",fill:"currentColor",viewBox:"0 0 1024 1024",version:"1.1",xmlns:"http://www.w3.org/2000/svg","p-id":"4870",children:(0,a.jsx)("path",{d:"M511.875 128.125c-211.875 0-383.75 76.25-383.75 170.625 0 94.375 171.875 170.625 383.75 170.625 211.875 0 383.75-76.25 383.75-170.625C896.25 204.375 724.375 128.125 511.875 128.125M128.125 383.75l0 128.125c0 94.375 171.875 170.625 383.75 170.625 211.875 0 383.75-76.25 383.75-170.625l0-128.125c0 94.375-171.875 170.625-383.75 170.625C300 555 128.125 478.125 128.125 383.75M128.125 597.5l0 128.125c0 94.375 171.875 170.625 383.75 170.625 211.875 0 383.75-76.25 383.75-170.625l0-128.125c0 94.375-171.875 170.625-383.75 170.625C300 768.125 128.125 691.875 128.125 597.5z","p-id":"4871"})})},w=l(2093),N=l(51009),_=function(){let{scene:e,dbParam:t,setDbParam:l}=(0,n.useContext)(x.p),[s,r]=(0,n.useState)({});(0,w.Z)(async()=>{let[,t]=await (0,h.Vx)((0,h.vD)(e));r(null!=t?t:{})},[e]);let c=(0,n.useMemo)(()=>Object.entries(s).map(e=>{let[t,l]=e;return{label:t,value:l}}),[s]);return((0,n.useEffect)(()=>{c.length&&!t&&l(c[0].value)},[c,l,t]),c.length)?(0,a.jsx)(N.default,{value:t,className:"w-36",onChange:e=>{l(e)},children:c.map(e=>(0,a.jsxs)(N.default.Option,{children:[(0,a.jsx)(f.Z,{component:Z,className:"mr-1"}),e.label]},e.value))}):null},P=l(577),C=l(67421),k=function(){let{t:e}=(0,C.$G)(),{agentList:t,setAgentList:l}=(0,n.useContext)(x.p),{data:s=[]}=(0,P.Z)(async()=>{let[,e]=await (0,h.Vx)((0,h.N6)());return e&&e.length&&(null==l||l([e[0].name])),null!=e?e:[]});return s.length?(0,a.jsx)(N.default,{className:"w-60",value:t,mode:"multiple",maxTagCount:1,maxTagTextLength:12,placeholder:e("Select_Plugins"),options:s.map(e=>({label:e.name,value:e.name})),allowClear:!0,onChange:e=>{null==l||l(e)}}):null},B=function(e){let{refreshHistory:t,modelChange:l}=e,{scene:s,refreshDialogList:r}=(0,n.useContext)(x.p);return(0,a.jsxs)("div",{className:"w-full py-2 px-4 md:px-4 flex flex-wrap items-center justify-center border-b border-gray-100 gap-1 md:gap-4",children:[(0,a.jsx)(b.Z,{onChange:l}),(0,a.jsx)(_,{}),"chat_excel"===s&&(0,a.jsx)(p,{onComplete:()=>{null==r||r(),null==t||t()}}),"chat_agent"===s&&(0,a.jsx)(k,{}),(0,a.jsx)(y,{})]})}},81799:function(e,t,l){"use strict";l.d(t,{A:function(){return u}});var a=l(85893),n=l(41468),s=l(51009),r=l(19284),c=l(25675),i=l.n(c),o=l(67294),d=l(67421);function u(e,t){var l;let{width:n,height:s}=t||{};return e?(0,a.jsx)(i(),{className:"rounded-full border border-gray-200 object-contain bg-white inline-block",width:n||24,height:s||24,src:(null===(l=r.H[e])||void 0===l?void 0:l.icon)||"/models/huggingface.svg",alt:"llm"}):null}t.Z=function(e){let{onChange:t}=e,{t:l}=(0,d.$G)(),{modelList:c,model:i}=(0,o.useContext)(n.p);return!c||c.length<=0?null:(0,a.jsx)(s.default,{value:i,placeholder:l("choose_model"),className:"w-52",onChange:e=>{null==t||t(e)},children:c.map(e=>{var t;return(0,a.jsx)(s.default.Option,{children:(0,a.jsxs)("div",{className:"flex items-center",children:[u(e),(0,a.jsx)("span",{className:"ml-2",children:(null===(t=r.H[e])||void 0===t?void 0:t.label)||e})]})},e)})})}},99513:function(e,t,l){"use strict";l.d(t,{Z:function(){return d}});var a=l(85893),n=l(77119),s=l(63764),r=l(94184),c=l.n(r),i=l(67294),o=l(36782);function d(e){let{className:t,value:l,language:n="mysql",onChange:r,thoughts:d}=e,u=(0,i.useMemo)(()=>"mysql"!==n?l:d&&d.length>0?(0,o.WU)("-- ".concat(d," \n").concat(l)):(0,o.WU)(l),[l,d]);return(0,a.jsx)(s.ZP,{className:c()(t),value:u,language:n,onChange:r,theme:"vs-dark",options:{minimap:{enabled:!1},wordWrap:"on"}})}s._m.config({monaco:n})},30119:function(e,t,l){"use strict";l.d(t,{Tk:function(){return i},PR:function(){return o}});var a=l(2453),n=l(6154),s=l(83454);let r=n.Z.create({baseURL:s.env.API_BASE_URL});r.defaults.timeout=1e4,r.interceptors.response.use(e=>e.data,e=>Promise.reject(e)),l(96486);let c={"content-type":"application/json"},i=(e,t)=>{if(t){let l=Object.keys(t).filter(e=>void 0!==t[e]&&""!==t[e]).map(e=>"".concat(e,"=").concat(t[e])).join("&");l&&(e+="?".concat(l))}return r.get("/api"+e,{headers:c}).then(e=>e).catch(e=>{a.ZP.error(e),Promise.reject(e)})},o=(e,t)=>r.post(e,t,{headers:c}).then(e=>e).catch(e=>{a.ZP.error(e),Promise.reject(e)})},23293:function(){}}]); \ No newline at end of file +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[304],{39156:function(e,t,l){"use strict";l.d(t,{Z:function(){return m}});var a=l(85893),n=l(41118),s=l(30208),r=l(40911),c=l(58234);function i(e){let{chart:t}=e;return(0,a.jsx)("div",{className:"flex-1 min-w-0",children:(0,a.jsx)(n.Z,{className:"h-full",sx:{background:"transparent"},children:(0,a.jsxs)(s.Z,{className:"h-full",children:[(0,a.jsx)(r.ZP,{gutterBottom:!0,component:"div",children:t.chart_name}),(0,a.jsx)(r.ZP,{gutterBottom:!0,level:"body3",children:t.chart_desc}),(0,a.jsx)("div",{className:"h-[300px]",children:(0,a.jsx)(c.k,{style:{height:"100%"},options:{autoFit:!0,type:"interval",data:t.values,encode:{x:"name",y:"value",color:"type"},axis:{x:{labelAutoRotate:!1}}}})})]})})})}function o(e){let{chart:t}=e;return(0,a.jsx)("div",{className:"flex-1 min-w-0",children:(0,a.jsx)(n.Z,{className:"h-full",sx:{background:"transparent"},children:(0,a.jsxs)(s.Z,{className:"h-full",children:[(0,a.jsx)(r.ZP,{gutterBottom:!0,component:"div",children:t.chart_name}),(0,a.jsx)(r.ZP,{gutterBottom:!0,level:"body3",children:t.chart_desc}),(0,a.jsx)("div",{className:"h-[300px]",children:(0,a.jsx)(c.k,{style:{height:"100%"},options:{autoFit:!0,type:"view",data:t.values,children:[{type:"line",encode:{x:"name",y:"value",color:"type",shape:"smooth"}},{type:"area",encode:{x:"name",y:"value",color:"type",shape:"smooth"},legend:!1,style:{fillOpacity:.15}}],axis:{x:{labelAutoRotate:!1}}}})})]})})})}var d=l(61685),u=l(96486);function h(e){var t,l;let{chart:c}=e,i=(0,u.groupBy)(c.values,"type");return(0,a.jsx)("div",{className:"flex-1 min-w-0",children:(0,a.jsx)(n.Z,{className:"h-full overflow-auto",sx:{background:"transparent"},children:(0,a.jsxs)(s.Z,{className:"h-full",children:[(0,a.jsx)(r.ZP,{gutterBottom:!0,component:"div",children:c.chart_name}),(0,a.jsx)(r.ZP,{gutterBottom:!0,level:"body3",children:c.chart_desc}),(0,a.jsx)("div",{className:"flex-1",children:(0,a.jsxs)(d.Z,{"aria-label":"basic table",stripe:"odd",hoverRow:!0,borderAxis:"bothBetween",children:[(0,a.jsx)("thead",{children:(0,a.jsx)("tr",{children:Object.keys(i).map(e=>(0,a.jsx)("th",{children:e},e))})}),(0,a.jsx)("tbody",{children:null===(t=Object.values(i))||void 0===t?void 0:null===(l=t[0])||void 0===l?void 0:l.map((e,t)=>{var l;return(0,a.jsx)("tr",{children:null===(l=Object.keys(i))||void 0===l?void 0:l.map(e=>{var l;return(0,a.jsx)("td",{children:(null==i?void 0:null===(l=i[e])||void 0===l?void 0:l[t].value)||""},e)})},t)})})]})})]})})})}var x=l(67294),m=function(e){let{chartsData:t}=e,l=(0,x.useMemo)(()=>{if(t){let e=[],l=null==t?void 0:t.filter(e=>"IndicatorValue"===e.chart_type);l.length>0&&e.push({charts:l,type:"IndicatorValue"});let a=null==t?void 0:t.filter(e=>"IndicatorValue"!==e.chart_type),n=a.length,s=0;return[[0],[1],[2],[1,2],[1,3],[2,1,2],[2,1,3],[3,1,3],[3,2,3]][n].forEach(t=>{if(t>0){let l=a.slice(s,s+t);s+=t,e.push({charts:l})}}),e}},[t]);return(0,a.jsx)("div",{className:"flex flex-col gap-3",children:null==l?void 0:l.map((e,t)=>(0,a.jsx)("div",{className:"".concat((null==e?void 0:e.type)!=="IndicatorValue"?"flex gap-3":""),children:e.charts.map(e=>"IndicatorValue"===e.chart_type?(0,a.jsx)("div",{className:"flex flex-row gap-3",children:e.values.map(e=>(0,a.jsx)("div",{className:"flex-1",children:(0,a.jsx)(n.Z,{sx:{background:"transparent"},children:(0,a.jsxs)(s.Z,{className:"justify-around",children:[(0,a.jsx)(r.ZP,{gutterBottom:!0,component:"div",children:e.name}),(0,a.jsx)(r.ZP,{children:e.value})]})})},e.name))},e.chart_uid):"LineChart"===e.chart_type?(0,a.jsx)(o,{chart:e},e.chart_uid):"BarChart"===e.chart_type?(0,a.jsx)(i,{chart:e},e.chart_uid):"Table"===e.chart_type?(0,a.jsx)(h,{chart:e},e.chart_uid):void 0)},"chart_row_".concat(t)))})}},70803:function(e,t,l){"use strict";l.d(t,{Z:function(){return U}});var a=l(85893),n=l(67294),s=l(2453),r=l(83062),c=l(31365),i=l(71577),o=l(49591),d=l(88484),u=l(29158),h=l(50489),x=l(41468),m=function(e){var t;let{convUid:l,chatMode:m,onComplete:p,...v}=e,[f,j]=(0,n.useState)(!1),[g,y]=s.ZP.useMessage(),[b,Z]=(0,n.useState)([]),[w,N]=(0,n.useState)(),{model:_}=(0,n.useContext)(x.p),P=async e=>{var t;if(!e){s.ZP.error("Please select the *.(csv|xlsx|xls) file");return}if(!/\.(csv|xlsx|xls)$/.test(null!==(t=e.file.name)&&void 0!==t?t:"")){s.ZP.error("File type must be csv, xlsx or xls");return}Z([e.file])},C=async()=>{j(!0);try{let e=new FormData;e.append("doc_file",b[0]),g.open({content:"Uploading ".concat(b[0].name),type:"loading",duration:0});let[t]=await (0,h.Vx)((0,h.qn)({convUid:l,chatMode:m,data:e,model:_,config:{timeout:36e5,onUploadProgress:e=>{let t=Math.ceil(e.loaded/(e.total||0)*100);N(t)}}}));if(t)return;s.ZP.success("success"),null==p||p()}catch(e){s.ZP.error((null==e?void 0:e.message)||"Upload Error")}finally{j(!1),g.destroy()}};return(0,a.jsx)(a.Fragment,{children:(0,a.jsxs)("div",{className:"flex items-start gap-2",children:[y,(0,a.jsx)(r.Z,{placement:"bottom",title:"File cannot be changed after upload",children:(0,a.jsx)(c.default,{disabled:f,className:"mr-1",beforeUpload:()=>!1,fileList:b,name:"file",accept:".csv,.xlsx,.xls",multiple:!1,onChange:P,showUploadList:{showDownloadIcon:!1,showPreviewIcon:!1,showRemoveIcon:!1},itemRender:()=>(0,a.jsx)(a.Fragment,{}),...v,children:(0,a.jsx)(i.ZP,{className:"flex justify-center items-center",type:"primary",disabled:f,icon:(0,a.jsx)(o.Z,{}),children:"Select File"})})}),(0,a.jsx)(i.ZP,{type:"primary",loading:f,className:"flex justify-center items-center",disabled:!b.length,icon:(0,a.jsx)(d.Z,{}),onClick:C,children:f?100===w?"Analysis":"Uploading":"Upload"}),!!b.length&&(0,a.jsxs)("div",{className:"mt-2 text-gray-500 text-sm flex items-center",children:[(0,a.jsx)(u.Z,{className:"mr-2"}),(0,a.jsx)("span",{children:null===(t=b[0])||void 0===t?void 0:t.name})]})]})})},p=function(e){let{onComplete:t}=e,{currentDialogue:l,scene:s,chatId:r}=(0,n.useContext)(x.p);return"chat_excel"!==s?null:(0,a.jsx)("div",{className:"max-w-md h-full relative",children:l?(0,a.jsxs)("div",{className:"flex h-8 overflow-hidden rounded",children:[(0,a.jsx)("div",{className:"flex items-center justify-center px-2 bg-gray-600 text-lg",children:(0,a.jsx)(u.Z,{className:"text-white"})}),(0,a.jsx)("div",{className:"flex items-center justify-center px-3 bg-gray-100 text-xs rounded-tr rounded-br dark:text-gray-800 truncate",children:l.select_param})]}):(0,a.jsx)(m,{convUid:r,chatMode:s,onComplete:t})})};l(23293);var v=l(78045),f=l(16165),j=l(96991),g=function(){return(0,a.jsx)("svg",{width:"1em",height:"1em",fill:"currentColor",viewBox:"0 0 1024 1024",version:"1.1",children:(0,a.jsx)("path",{d:"M602.24 246.72a17.28 17.28 0 0 0-11.84-16.32l-42.88-14.4A90.56 90.56 0 0 1 490.24 160l-14.4-42.88a17.28 17.28 0 0 0-32 0L428.8 160a90.56 90.56 0 0 1-57.28 57.28l-42.88 14.4a17.28 17.28 0 0 0 0 32l42.88 14.4a90.56 90.56 0 0 1 57.28 57.28l14.4 42.88a17.28 17.28 0 0 0 32 0l14.4-42.88a90.56 90.56 0 0 1 57.28-57.28l42.88-14.4a17.28 17.28 0 0 0 12.48-16.96z m301.12 221.76l-48.32-16a101.44 101.44 0 0 1-64-64l-16-48.32a19.2 19.2 0 0 0-36.8 0l-16 48.32a101.44 101.44 0 0 1-64 64l-48.32 16a19.2 19.2 0 0 0 0 36.8l48.32 16a101.44 101.44 0 0 1 64 64l16 48.32a19.2 19.2 0 0 0 36.8 0l16-48.32a101.44 101.44 0 0 1 64-64l48.32-16a19.2 19.2 0 0 0 0-36.8z m-376.64 195.52l-64-20.8a131.84 131.84 0 0 1-83.52-83.52l-20.8-64a25.28 25.28 0 0 0-47.68 0l-20.8 64a131.84 131.84 0 0 1-82.24 83.52l-64 20.8a25.28 25.28 0 0 0 0 47.68l64 20.8a131.84 131.84 0 0 1 83.52 83.84l20.8 64a25.28 25.28 0 0 0 47.68 0l20.8-64a131.84 131.84 0 0 1 83.52-83.52l64-20.8a25.28 25.28 0 0 0 0-47.68z","p-id":"3992"})})};function y(){let{isContract:e,setIsContract:t,scene:l}=(0,n.useContext)(x.p),s=l&&["chat_with_db_execute","chat_dashboard"].includes(l);return s?(0,a.jsxs)(v.ZP.Group,{value:e,defaultValue:!0,buttonStyle:"solid",onChange:()=>{t(!e)},children:[(0,a.jsxs)(v.ZP.Button,{value:!1,children:[(0,a.jsx)(f.Z,{component:g,className:"mr-1"}),"Preview"]}),(0,a.jsxs)(v.ZP.Button,{value:!0,children:[(0,a.jsx)(j.Z,{className:"mr-1"}),"Editor"]})]}):null}var b=l(81799),Z=function(){return(0,a.jsx)("svg",{width:"1em",height:"1em",fill:"currentColor",viewBox:"0 0 1024 1024",version:"1.1",xmlns:"http://www.w3.org/2000/svg","p-id":"4870",children:(0,a.jsx)("path",{d:"M511.875 128.125c-211.875 0-383.75 76.25-383.75 170.625 0 94.375 171.875 170.625 383.75 170.625 211.875 0 383.75-76.25 383.75-170.625C896.25 204.375 724.375 128.125 511.875 128.125M128.125 383.75l0 128.125c0 94.375 171.875 170.625 383.75 170.625 211.875 0 383.75-76.25 383.75-170.625l0-128.125c0 94.375-171.875 170.625-383.75 170.625C300 555 128.125 478.125 128.125 383.75M128.125 597.5l0 128.125c0 94.375 171.875 170.625 383.75 170.625 211.875 0 383.75-76.25 383.75-170.625l0-128.125c0 94.375-171.875 170.625-383.75 170.625C300 768.125 128.125 691.875 128.125 597.5z","p-id":"4871"})})},w=l(2093),N=l(51009),_=function(){let{scene:e,dbParam:t,setDbParam:l}=(0,n.useContext)(x.p),[s,r]=(0,n.useState)({});(0,w.Z)(async()=>{let[,t]=await (0,h.Vx)((0,h.vD)(e));r(null!=t?t:{})},[e]);let c=(0,n.useMemo)(()=>Object.entries(s).map(e=>{let[t,l]=e;return{label:t,value:l}}),[s]);return((0,n.useEffect)(()=>{c.length&&!t&&l(c[0].value)},[c,l,t]),c.length)?(0,a.jsx)(N.default,{value:t,className:"w-36",onChange:e=>{l(e)},children:c.map(e=>(0,a.jsxs)(N.default.Option,{children:[(0,a.jsx)(f.Z,{component:Z,className:"mr-1"}),e.label]},e.value))}):null},P=l(577),C=l(11163),k=l(67421),B=function(){let{push:e}=(0,C.useRouter)(),{t}=(0,k.$G)(),{agentList:l,setAgentList:s}=(0,n.useContext)(x.p),{data:r=[]}=(0,P.Z)(async()=>{let[,e]=await (0,h.Vx)((0,h.N6)());return e&&e.length&&(null==s||s([e[0].name])),null!=e?e:[]});return r.length?(0,a.jsx)(N.default,{className:"w-60",value:l,mode:"multiple",maxTagCount:1,maxTagTextLength:12,placeholder:t("Select_Plugins"),options:r.map(e=>({label:e.name,value:e.name})),allowClear:!0,onChange:e=>{null==s||s(e)}}):(0,a.jsx)(i.ZP,{type:"primary",onClick:()=>{e("/agent")},children:t("To_Plugin_Market")})},U=function(e){let{refreshHistory:t,modelChange:l}=e,{scene:s,refreshDialogList:r}=(0,n.useContext)(x.p);return(0,a.jsxs)("div",{className:"w-full py-2 px-4 md:px-4 flex flex-wrap items-center justify-center border-b border-gray-100 gap-1 md:gap-4",children:[(0,a.jsx)(b.Z,{onChange:l}),(0,a.jsx)(_,{}),"chat_excel"===s&&(0,a.jsx)(p,{onComplete:()=>{null==r||r(),null==t||t()}}),"chat_agent"===s&&(0,a.jsx)(B,{}),(0,a.jsx)(y,{})]})}},81799:function(e,t,l){"use strict";l.d(t,{A:function(){return u}});var a=l(85893),n=l(41468),s=l(51009),r=l(19284),c=l(25675),i=l.n(c),o=l(67294),d=l(67421);function u(e,t){var l;let{width:n,height:s}=t||{};return e?(0,a.jsx)(i(),{className:"rounded-full border border-gray-200 object-contain bg-white inline-block",width:n||24,height:s||24,src:(null===(l=r.H[e])||void 0===l?void 0:l.icon)||"/models/huggingface.svg",alt:"llm"}):null}t.Z=function(e){let{onChange:t}=e,{t:l}=(0,d.$G)(),{modelList:c,model:i}=(0,o.useContext)(n.p);return!c||c.length<=0?null:(0,a.jsx)(s.default,{value:i,placeholder:l("choose_model"),className:"w-52",onChange:e=>{null==t||t(e)},children:c.map(e=>{var t;return(0,a.jsx)(s.default.Option,{children:(0,a.jsxs)("div",{className:"flex items-center",children:[u(e),(0,a.jsx)("span",{className:"ml-2",children:(null===(t=r.H[e])||void 0===t?void 0:t.label)||e})]})},e)})})}},99513:function(e,t,l){"use strict";l.d(t,{Z:function(){return d}});var a=l(85893),n=l(77119),s=l(63764),r=l(94184),c=l.n(r),i=l(67294),o=l(36782);function d(e){let{className:t,value:l,language:n="mysql",onChange:r,thoughts:d}=e,u=(0,i.useMemo)(()=>"mysql"!==n?l:d&&d.length>0?(0,o.WU)("-- ".concat(d," \n").concat(l)):(0,o.WU)(l),[l,d]);return(0,a.jsx)(s.ZP,{className:c()(t),value:u,language:n,onChange:r,theme:"vs-dark",options:{minimap:{enabled:!1},wordWrap:"on"}})}s._m.config({monaco:n})},30119:function(e,t,l){"use strict";l.d(t,{Tk:function(){return i},PR:function(){return o}});var a=l(2453),n=l(6154),s=l(83454);let r=n.Z.create({baseURL:s.env.API_BASE_URL});r.defaults.timeout=1e4,r.interceptors.response.use(e=>e.data,e=>Promise.reject(e)),l(96486);let c={"content-type":"application/json"},i=(e,t)=>{if(t){let l=Object.keys(t).filter(e=>void 0!==t[e]&&""!==t[e]).map(e=>"".concat(e,"=").concat(t[e])).join("&");l&&(e+="?".concat(l))}return r.get("/api"+e,{headers:c}).then(e=>e).catch(e=>{a.ZP.error(e),Promise.reject(e)})},o=(e,t)=>r.post(e,t,{headers:c}).then(e=>e).catch(e=>{a.ZP.error(e),Promise.reject(e)})},23293:function(){}}]); \ No newline at end of file diff --git a/pilot/server/static/_next/static/chunks/604.0b6534ada5e802bc.js b/pilot/server/static/_next/static/chunks/604.0b6534ada5e802bc.js deleted file mode 100644 index 42a2d2f68..000000000 --- a/pilot/server/static/_next/static/chunks/604.0b6534ada5e802bc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[604],{24093:function(e,l,t){t.r(l),t.d(l,{default:function(){return ev}});var r=t(85893),a=t(67294),s=t(2093),n=t(1375),o=t(2453),i=t(58989),c=t(83454),d=e=>{let{queryAgentURL:l="/api/v1/chat/completions"}=e,t=(0,a.useMemo)(()=>new AbortController,[]),r=(0,a.useCallback)(async e=>{let{context:r,data:a,chatId:s,onMessage:d,onClose:u,onDone:x,onError:m}=e;if(!r){o.ZP.warning(i.Z.t("NoContextTip"));return}let h={...a,conv_uid:s,user_input:r};if(!h.conv_uid){o.ZP.error("conv_uid 不存在,请刷新后重试");return}try{var p;await (0,n.L)("".concat(null!==(p=c.env.API_BASE_URL)&&void 0!==p?p:"").concat(l),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(h),signal:t.signal,openWhenHidden:!0,async onopen(e){if(e.ok&&e.headers.get("content-type")===n.a)return},onclose(){t.abort(),null==u||u()},onerror(e){throw Error(e)},onmessage:e=>{var l;let t=null===(l=e.data)||void 0===l?void 0:l.replaceAll("\\n","\n");"[DONE]"===t?null==x||x():(null==t?void 0:t.startsWith("[ERROR]"))?null==m||m(null==t?void 0:t.replace("[ERROR]","")):null==d||d(t)}})}catch(e){t.abort(),null==m||m("Sorry, We meet some error, please try agin later.",e)}},[l]);return(0,a.useEffect)(()=>()=>{t.abort()},[]),r},u=t(39332),x=t(99513),m=t(24019),h=t(50888),p=t(97937),g=t(63606),v=t(50228),f=t(87547),b=t(89035),j=t(33035),y=t(12767),w=t(94184),Z=t.n(w),_=t(66309),N=t(81799),k=t(41468),C=t(57132),S=t(29158),P=t(98165),R=t(79166),E=t(93179),O=t(71577),D=t(38426),M=t(20640),I=t.n(M);let L={code(e){var l;let{inline:t,node:a,className:s,children:n,style:i,...c}=e,d=/language-(\w+)/.exec(s||"");return!t&&d?(0,r.jsxs)("div",{className:"relative",children:[(0,r.jsx)(O.ZP,{className:"absolute right-3 top-2 text-gray-300 hover:!text-gray-200 bg-gray-700",type:"text",icon:(0,r.jsx)(C.Z,{}),onClick:()=>{let e=I()(n);o.ZP[e?"success":"error"](e?"Copy success":"Copy failed")}}),(0,r.jsx)(E.Z,{language:null!==(l=null==d?void 0:d[1])&&void 0!==l?l:"javascript",style:R.Z,children:n})]}):(0,r.jsx)("code",{...c,style:i,className:"px-[6px] py-[2px] rounded bg-gray-700 text-gray-100 dark:bg-gray-100 dark:text-gray-800 text-sm",children:n})},ul(e){let{children:l}=e;return(0,r.jsx)("ul",{className:"py-1",children:l})},ol(e){let{children:l}=e;return(0,r.jsx)("ol",{className:"py-1",children:l})},li(e){let{children:l,ordered:t}=e;return(0,r.jsx)("li",{className:"text-sm leading-7 ml-5 pl-2 text-gray-600 dark:text-gray-300 ".concat(t?"list-decimal":"list-disc"),children:l})},table(e){let{children:l}=e;return(0,r.jsx)("table",{className:"my-2 rounded-tl-md rounded-tr-md max-w-full bg-white dark:bg-gray-900 text-sm rounded-lg overflow-hidden",children:l})},thead(e){let{children:l}=e;return(0,r.jsx)("thead",{className:"bg-[#fafafa] dark:bg-black font-semibold",children:l})},th(e){let{children:l}=e;return(0,r.jsx)("th",{className:"!text-left p-4",children:l})},td(e){let{children:l}=e;return(0,r.jsx)("td",{className:"p-4 border-t border-[#f0f0f0] dark:border-gray-700",children:l})},h1(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-2xl font-bold my-4 border-b border-slate-300 pb-4",children:l})},h2(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-xl font-bold my-3",children:l})},h3(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-lg font-semibold my-2",children:l})},h4(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-base font-semibold my-1",children:l})},a(e){let{children:l,href:t}=e;return(0,r.jsxs)("div",{className:"inline-block text-blue-600 dark:text-blue-400",children:[(0,r.jsx)(S.Z,{className:"mr-1"}),(0,r.jsx)("a",{href:t,target:"_blank",children:l})]})},img(e){let{src:l,alt:t}=e;return(0,r.jsx)("div",{children:(0,r.jsx)(D.Z,{className:"min-h-[1rem] max-w-full max-h-full border rounded",src:l,alt:t,placeholder:(0,r.jsx)(_.Z,{icon:(0,r.jsx)(P.Z,{spin:!0}),color:"processing",children:"Image Loading..."}),fallback:"/images/fallback.png"})})},blockquote(e){let{children:l}=e;return(0,r.jsx)("blockquote",{className:"py-4 px-6 border-l-4 border-blue-600 rounded bg-white my-2 text-gray-500 dark:bg-slate-800 dark:text-gray-200 dark:border-white shadow-sm",children:l})}},A={todo:{bgClass:"bg-gray-500",icon:(0,r.jsx)(m.Z,{className:"ml-2"})},runing:{bgClass:"bg-blue-500",icon:(0,r.jsx)(h.Z,{className:"ml-2"})},failed:{bgClass:"bg-red-500",icon:(0,r.jsx)(p.Z,{className:"ml-2"})},completed:{bgClass:"bg-green-500",icon:(0,r.jsx)(g.Z,{className:"ml-2"})}};function T(e){return e.replaceAll("\\n","\n").replace(/]+)>/gi,"").replace(/]+)>/gi,"")}var F=(0,a.memo)(function(e){let{children:l,content:t,isChartChat:s,onLinkClick:n}=e,{scene:o}=(0,a.useContext)(k.p),{context:i,model_name:c,role:d}=t,u="view"===d,{relations:x,value:m,cachePlguinContext:h}=(0,a.useMemo)(()=>{if("string"!=typeof i)return{relations:[],value:"",cachePlguinContext:[]};let[e,l]=i.split(" relations:"),t=l?l.split(","):[],r=[],a=0,s=e.replace(/]*>[^<]*<\/dbgpt-view>/gi,e=>{try{var l;console.log(e);let t=e.replaceAll("\n","\\n").replace(/<[^>]*>|<\/[^>]*>/gm,""),s=JSON.parse(t),n="".concat(a,"");return r.push({...s,result:T(null!==(l=s.result)&&void 0!==l?l:"")}),a++,n}catch(l){return console.log(l.message,l),e}});return{relations:t,cachePlguinContext:r,value:s}},[i]),p=(0,a.useMemo)(()=>({"custom-view"(e){var l;let{children:t}=e,a=+t.toString();if(!h[a])return t;let{name:s,status:n,err_msg:o,result:i}=h[a],{bgClass:c,icon:d}=null!==(l=A[n])&&void 0!==l?l:{};return(0,r.jsxs)("div",{className:"bg-white dark:bg-[#212121] rounded-lg overflow-hidden my-2 flex flex-col lg:max-w-[80%]",children:[(0,r.jsxs)("div",{className:Z()("flex px-4 md:px-6 py-2 items-center text-white text-sm",c),children:[s,d]}),i?(0,r.jsx)("div",{className:"px-4 md:px-6 py-4 text-sm",children:(0,r.jsx)(j.D,{components:L,rehypePlugins:[y.Z],children:null!=i?i:""})}):(0,r.jsx)("div",{className:"px-4 md:px-6 py-4 text-sm",children:o})]})}}),[i,h]);return(0,r.jsxs)("div",{className:Z()("relative flex flex-wrap w-full px-2 sm:px-4 py-2 sm:py-6 rounded-xl break-words",{"bg-slate-100 dark:bg-[#353539]":u,"lg:w-full xl:w-full pl-0":["chat_with_db_execute","chat_dashboard"].includes(o)}),children:[(0,r.jsx)("div",{className:"mr-2 flex flex-shrink-0 items-center justify-center h-7 w-7 rounded-full text-lg sm:mr-4",children:u?(0,N.A)(c)||(0,r.jsx)(v.Z,{}):(0,r.jsx)(f.Z,{})}),(0,r.jsxs)("div",{className:"flex-1 overflow-hidden items-center text-md leading-8",children:[!u&&"string"==typeof i&&i,u&&s&&"object"==typeof i&&(0,r.jsxs)("div",{children:["[".concat(i.template_name,"]: "),(0,r.jsxs)("span",{className:"text-[#1677ff] cursor-pointer",onClick:n,children:[(0,r.jsx)(b.Z,{className:"mr-1"}),i.template_introduce||"More Details"]})]}),u&&"string"==typeof i&&(0,r.jsx)(j.D,{components:{...L,...p},rehypePlugins:[y.Z],children:T(m)}),!!(null==x?void 0:x.length)&&(0,r.jsx)("div",{className:"flex flex-wrap mt-2",children:null==x?void 0:x.map((e,l)=>(0,r.jsx)(_.Z,{color:"#108ee9",children:e},e+l))})]}),l]})}),H=t(59301),V=t(41132),$=t(74312),q=t(3414),z=t(72868),J=t(59562),W=t(14553),G=t(25359),B=t(7203),K=t(48665),Q=t(26047),U=t(99056),X=t(57814),Y=t(63955),ee=t(33028),el=t(40911),et=t(66478),er=t(83062),ea=t(50489),es=t(67421),en=e=>{var l;let{conv_index:t,question:s,knowledge_space:n}=e,{t:i}=(0,es.$G)(),{chatId:c}=(0,a.useContext)(k.p),[d,u]=(0,a.useState)(""),[x,m]=(0,a.useState)(4),[h,p]=(0,a.useState)(""),g=(0,a.useRef)(null),[v,f]=o.ZP.useMessage(),[b,j]=(0,a.useState)({});(0,a.useEffect)(()=>{(0,ea.Vx)((0,ea.Lu)()).then(e=>{var l;console.log(e),j(null!==(l=e[1])&&void 0!==l?l:{})}).catch(e=>{console.log(e)})},[]);let y=(0,a.useCallback)((e,l)=>{l?(0,ea.Vx)((0,ea.Eb)(c,t)).then(e=>{var l,t,r,a;let s=null!==(l=e[1])&&void 0!==l?l:{};u(null!==(t=s.ques_type)&&void 0!==t?t:""),m(parseInt(null!==(r=s.score)&&void 0!==r?r:"4")),p(null!==(a=s.messages)&&void 0!==a?a:"")}).catch(e=>{console.log(e)}):(u(""),m(4),p(""))},[c,t]),w=(0,$.Z)(q.Z)(e=>{let{theme:l}=e;return{backgroundColor:"dark"===l.palette.mode?"#FBFCFD":"#0E0E10",...l.typography["body-sm"],padding:l.spacing(1),display:"flex",alignItems:"center",justifyContent:"center",borderRadius:4,width:"100%",height:"100%"}});return(0,r.jsxs)(z.L,{onOpenChange:y,children:[f,(0,r.jsx)(er.Z,{title:i("Rating"),children:(0,r.jsx)(J.Z,{slots:{root:W.ZP},slotProps:{root:{variant:"plain",color:"primary"}},sx:{borderRadius:40},children:(0,r.jsx)(H.Z,{})})}),(0,r.jsxs)(G.Z,{children:[(0,r.jsx)(B.Z,{disabled:!0,sx:{minHeight:0}}),(0,r.jsx)(K.Z,{sx:{width:"100%",maxWidth:350,display:"grid",gap:3,padding:1},children:(0,r.jsx)("form",{onSubmit:e=>{e.preventDefault();let l={conv_uid:c,conv_index:t,question:s,knowledge_space:n,score:x,ques_type:d,messages:h};console.log(l),(0,ea.Vx)((0,ea.VC)({data:l})).then(e=>{v.open({type:"success",content:"save success"})}).catch(e=>{v.open({type:"error",content:"save error"})})},children:(0,r.jsxs)(Q.Z,{container:!0,spacing:.5,columns:13,sx:{flexGrow:1},children:[(0,r.jsx)(Q.Z,{xs:3,children:(0,r.jsx)(w,{children:i("Q_A_Category")})}),(0,r.jsx)(Q.Z,{xs:10,children:(0,r.jsx)(U.Z,{action:g,value:d,placeholder:"Choose one…",onChange:(e,l)=>u(null!=l?l:""),...d&&{endDecorator:(0,r.jsx)(W.ZP,{size:"sm",variant:"plain",color:"neutral",onMouseDown:e=>{e.stopPropagation()},onClick:()=>{var e;u(""),null===(e=g.current)||void 0===e||e.focusVisible()},children:(0,r.jsx)(V.Z,{})}),indicator:null},sx:{width:"100%"},children:null===(l=Object.keys(b))||void 0===l?void 0:l.map(e=>(0,r.jsx)(X.Z,{value:e,children:b[e]},e))})}),(0,r.jsx)(Q.Z,{xs:3,children:(0,r.jsx)(w,{children:(0,r.jsx)(er.Z,{title:(0,r.jsx)(K.Z,{children:(0,r.jsx)("div",{children:i("feed_back_desc")})}),variant:"solid",placement:"left",children:i("Q_A_Rating")})})}),(0,r.jsx)(Q.Z,{xs:10,sx:{pl:0,ml:0},children:(0,r.jsx)(Y.Z,{"aria-label":"Custom",step:1,min:0,max:5,valueLabelFormat:function(e){return({0:i("Lowest"),1:i("Missed"),2:i("Lost"),3:i("Incorrect"),4:i("Verbose"),5:i("Best")})[e]},valueLabelDisplay:"on",marks:[{value:0,label:"0"},{value:1,label:"1"},{value:2,label:"2"},{value:3,label:"3"},{value:4,label:"4"},{value:5,label:"5"}],sx:{width:"90%",pt:3,m:2,ml:1},onChange:e=>{var l;return m(null===(l=e.target)||void 0===l?void 0:l.value)},value:x})}),(0,r.jsx)(Q.Z,{xs:13,children:(0,r.jsx)(ee.Z,{placeholder:i("Please_input_the_text"),value:h,onChange:e=>p(e.target.value),minRows:2,maxRows:4,endDecorator:(0,r.jsx)(el.ZP,{level:"body-xs",sx:{ml:"auto"},children:i("input_count")+h.length+i("input_unit")}),sx:{width:"100%",fontSize:14}})}),(0,r.jsx)(Q.Z,{xs:13,children:(0,r.jsx)(et.Z,{type:"submit",variant:"outlined",sx:{width:"100%",height:"100%"},children:i("submit")})})]})})})]})]})},eo=t(32983),ei=t(12069),ec=t(96486),ed=t.n(ec),eu=t(38954),ex=t(98399),em=e=>{var l;let{messages:t,onSubmit:n}=e,{dbParam:i,currentDialogue:c,scene:d,model:m,refreshDialogList:h,chatId:p,agentList:g}=(0,a.useContext)(k.p),{t:v}=(0,es.$G)(),f=(0,u.useSearchParams)(),b=null!==(l=f&&f.get("spaceNameOriginal"))&&void 0!==l?l:"",[j,y]=(0,a.useState)(!1),[w,_]=(0,a.useState)(!1),[S,P]=(0,a.useState)(t),[R,E]=(0,a.useState)(""),O=(0,a.useRef)(null),D=(0,a.useMemo)(()=>"chat_dashboard"===d,[d]),M=(0,a.useMemo)(()=>{switch(d){case"chat_agent":return g.join(",");case"chat_excel":return null==c?void 0:c.select_param;default:return b||i}},[d,g,c,i,b]),L=async e=>{if(!j&&e.trim())try{y(!0),await n(e,{select_param:null!=M?M:""})}finally{y(!1)}},A=e=>{try{return JSON.parse(e)}catch(l){return e}},[T,H]=o.ZP.useMessage(),V=async e=>{let l=null==e?void 0:e.replace(/\trelations:.*/g,""),t=I()(l);t?l?T.open({type:"success",content:v("Copy_success")}):T.open({type:"warning",content:v("Copy_nothing")}):T.open({type:"error",content:v("Copry_error")})};return(0,s.Z)(async()=>{let e=(0,ex.a_)();e&&e.id===p&&(await L(e.message),h(),localStorage.removeItem(ex.rU))},[p]),(0,a.useEffect)(()=>{let e=t;D&&(e=ed().cloneDeep(t).map(e=>((null==e?void 0:e.role)==="view"&&"string"==typeof(null==e?void 0:e.context)&&(e.context=A(null==e?void 0:e.context)),e))),P(e.filter(e=>["view","human"].includes(e.role)))},[D,t]),(0,a.useEffect)(()=>{setTimeout(()=>{var e;null===(e=O.current)||void 0===e||e.scrollTo(0,O.current.scrollHeight)},50)},[t]),(0,r.jsxs)(r.Fragment,{children:[H,(0,r.jsx)("div",{ref:O,className:"flex flex-1 overflow-y-auto pb-8 w-full flex-col",children:(0,r.jsx)("div",{className:"flex items-center flex-1 flex-col text-sm leading-6 text-slate-900 dark:text-slate-300 sm:text-base sm:leading-7",children:S.length?S.map((e,l)=>{var t;return(0,r.jsx)(F,{content:e,isChartChat:D,onLinkClick:()=>{_(!0),E(JSON.stringify(null==e?void 0:e.context,null,2))},children:"view"===e.role&&(0,r.jsxs)("div",{className:"flex w-full flex-row-reverse pt-2 md:pt-4 border-t border-gray-200 mt-2 md:mt-4",children:[(0,r.jsx)(en,{conv_index:Math.ceil((l+1)/2),question:null===(t=null==S?void 0:S.filter(l=>(null==l?void 0:l.role)==="human"&&(null==l?void 0:l.order)===e.order)[0])||void 0===t?void 0:t.context,knowledge_space:b||i||""}),(0,r.jsx)(er.Z,{title:v("Copy"),children:(0,r.jsx)(et.Z,{onClick:()=>V(null==e?void 0:e.context),slots:{root:W.ZP},slotProps:{root:{variant:"plain",color:"primary"}},sx:{borderRadius:40},children:(0,r.jsx)(C.Z,{})})})]})},l)}):(0,r.jsx)(eo.Z,{image:"/empty.png",imageStyle:{width:320,height:320,margin:"0 auto",maxWidth:"100%",maxHeight:"100%"},className:"flex items-center justify-center flex-col h-full w-full",description:"Start a conversation"})})}),(0,r.jsx)("div",{className:Z()("relative after:absolute after:-top-8 after:h-8 after:w-full after:bg-gradient-to-t after:from-white after:to-transparent dark:after:from-[#212121]",{"cursor-not-allowed":"chat_excel"===d&&!(null==c?void 0:c.select_param)}),children:(0,r.jsxs)("div",{className:"flex flex-wrap w-full py-2 sm:pt-6 sm:pb-10",children:[m&&(0,r.jsx)("div",{className:"mr-2 flex items-center h-10",children:(0,N.A)(m)}),(0,r.jsx)(eu.Z,{loading:j,onSubmit:L})]})}),(0,r.jsx)(ei.default,{title:"JSON Editor",open:w,width:"60%",cancelButtonProps:{hidden:!0},onOk:()=>{_(!1)},onCancel:()=>{_(!1)},children:(0,r.jsx)(x.Z,{className:"w-full h-[500px]",language:"json",value:R})})]})},eh=t(70803),ep=t(39156),eg=t(45247),ev=()=>{var e;let l=(0,u.useSearchParams)(),{scene:t,chatId:n,model:o,setModel:i}=(0,a.useContext)(k.p),c=d({}),x=null!==(e=l&&l.get("initMessage"))&&void 0!==e?e:"",[m,h]=(0,a.useState)(!1),[p,g]=(0,a.useState)(),[v,f]=(0,a.useState)([]),b=async()=>{h(!0);let[,e]=await (0,ea.Vx)((0,ea.$i)(n));f(null!=e?e:[]),h(!1)},j=e=>{var l;let t=null===(l=e[e.length-1])||void 0===l?void 0:l.context;if(t)try{let e=JSON.parse(t);g((null==e?void 0:e.template_name)==="report"?null==e?void 0:e.charts:void 0)}catch(e){g(void 0)}};(0,s.Z)(async()=>{let e=(0,ex.a_)();e&&e.id===n||await b()},[x,n]),(0,a.useEffect)(()=>{var e,l;if(!v.length)return;let t=null===(e=null===(l=v.filter(e=>"view"===e.role))||void 0===l?void 0:l.slice(-1))||void 0===e?void 0:e[0];(null==t?void 0:t.model_name)&&i(t.model_name),j(v)},[v.length]);let y=(0,a.useCallback)((e,l)=>new Promise(r=>{let a=[...v,{role:"human",context:e,model_name:o,order:0,time_stamp:0},{role:"view",context:"",model_name:o,order:0,time_stamp:0}],s=a.length-1;f([...a]),c({context:e,data:{...l,chat_mode:t||"chat_normal",model_name:o},chatId:n,onMessage:e=>{a[s].context=e,f([...a])},onDone:()=>{j(a),r()},onClose:()=>{j(a),r()},onError:e=>{a[s].context=e,f([...a]),r()}})}),[v,c,o]);return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(eg.Z,{visible:m}),(0,r.jsx)(eh.Z,{refreshHistory:b,modelChange:e=>{i(e)}}),(0,r.jsxs)("div",{className:"px-4 flex flex-1 flex-wrap overflow-hidden relative",children:[!!(null==p?void 0:p.length)&&(0,r.jsx)("div",{className:"w-full xl:w-3/4 h-3/5 xl:pr-4 xl:h-full overflow-y-auto",children:(0,r.jsx)(ep.Z,{chartsData:p})}),!(null==p?void 0:p.length)&&"chat_dashboard"===t&&(0,r.jsx)(eo.Z,{image:"/empty.png",imageStyle:{width:320,height:320,margin:"0 auto",maxWidth:"100%",maxHeight:"100%"},className:"w-full xl:w-3/4 h-3/5 xl:h-full pt-0 md:pt-10"}),(0,r.jsx)("div",{className:Z()("flex flex-1 flex-col overflow-hidden",{"px-0 xl:pl-4 h-2/5 xl:h-full border-t xl:border-t-0 xl:border-l":"chat_dashboard"===t,"h-full lg:px-8":"chat_dashboard"!==t}),children:(0,r.jsx)(em,{messages:v,onSubmit:y})})]})]})}},38954:function(e,l,t){t.d(l,{Z:function(){return j}});var r=t(85893),a=t(27496),s=t(59566),n=t(71577),o=t(67294),i=t(2487),c=t(83062),d=t(2453),u=t(74627),x=t(39479),m=t(51009),h=t(58299),p=t(577),g=t(30119),v=t(67421);let f=e=>{let{data:l,loading:t,submit:a,close:s}=e,{t:n}=(0,v.$G)(),o=e=>()=>{a(e),s()};return(0,r.jsx)("div",{style:{maxHeight:400,overflow:"auto"},children:(0,r.jsx)(i.Z,{dataSource:null==l?void 0:l.data,loading:t,rowKey:e=>e.prompt_name,renderItem:e=>(0,r.jsx)(i.Z.Item,{onClick:o(e.content),children:(0,r.jsx)(c.Z,{title:e.content,children:(0,r.jsx)(i.Z.Item.Meta,{style:{cursor:"copy"},title:e.prompt_name,description:n("Prompt_Info_Scene")+":".concat(e.chat_scene,",")+n("Prompt_Info_Sub_Scene")+":".concat(e.sub_chat_scene)})})},e.prompt_name)})})};var b=e=>{let{submit:l}=e,{t}=(0,v.$G)(),[a,s]=(0,o.useState)(!1),[n,i]=(0,o.useState)("common"),{data:b,loading:j}=(0,p.Z)(()=>(0,g.PR)("/prompt/list",{prompt_type:n}),{refreshDeps:[n],onError:e=>{d.ZP.error(null==e?void 0:e.message)}});return(0,r.jsx)(u.Z,{title:(0,r.jsx)(x.Z.Item,{label:"Prompt "+t("Type"),children:(0,r.jsx)(m.default,{style:{width:130},value:n,onChange:e=>{i(e)},options:[{label:t("Public")+" Prompts",value:"common"},{label:t("Private")+" Prompts",value:"private"}]})}),content:(0,r.jsx)(f,{data:b,loading:j,submit:l,close:()=>{s(!1)}}),placement:"topRight",trigger:"click",open:a,onOpenChange:e=>{s(e)},children:(0,r.jsx)(c.Z,{title:t("Click_Select")+" Prompt",children:(0,r.jsx)(h.Z,{className:"bottom-32"})})})},j=function(e){let{children:l,loading:t,onSubmit:i,...c}=e,[d,u]=(0,o.useState)("");return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.default.TextArea,{className:"flex-1",size:"large",value:d,autoSize:{minRows:1,maxRows:4},...c,onPressEnter:e=>{if(d.trim()&&13===e.keyCode){if(e.shiftKey){u(e=>e+"\n");return}i(d),setTimeout(()=>{u("")},0)}},onChange:e=>{if("number"==typeof c.maxLength){u(e.target.value.substring(0,c.maxLength));return}u(e.target.value)}}),(0,r.jsx)(n.ZP,{className:"ml-2 flex items-center justify-center",size:"large",type:"text",loading:t,icon:(0,r.jsx)(a.Z,{}),onClick:()=>{i(d)}}),(0,r.jsx)(b,{submit:e=>{u(d+e)}}),l]})}},45247:function(e,l,t){var r=t(85893),a=t(50888);l.Z=function(e){let{visible:l}=e;return l?(0,r.jsx)("div",{className:"absolute w-full h-full top-0 left-0 flex justify-center items-center z-10 bg-white dark:bg-black bg-opacity-50 dark:bg-opacity-50 backdrop-blur-sm text-3xl animate-fade animate-duration-200",children:(0,r.jsx)(a.Z,{})}):null}}}]); \ No newline at end of file diff --git a/pilot/server/static/_next/static/chunks/604.3bbbeaa2c767e7dc.js b/pilot/server/static/_next/static/chunks/604.3bbbeaa2c767e7dc.js new file mode 100644 index 000000000..ec5108c66 --- /dev/null +++ b/pilot/server/static/_next/static/chunks/604.3bbbeaa2c767e7dc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[604],{24093:function(e,l,t){t.r(l),t.d(l,{default:function(){return ev}});var r=t(85893),a=t(67294),s=t(2093),n=t(1375),o=t(2453),i=t(58989),c=t(83454),d=e=>{let{queryAgentURL:l="/api/v1/chat/completions"}=e,t=(0,a.useMemo)(()=>new AbortController,[]),r=(0,a.useCallback)(async e=>{let{context:r,data:a,chatId:s,onMessage:d,onClose:u,onDone:x,onError:m}=e;if(!r){o.ZP.warning(i.Z.t("NoContextTip"));return}let h={...a,conv_uid:s,user_input:r};if(!h.conv_uid){o.ZP.error("conv_uid 不存在,请刷新后重试");return}try{var p;await (0,n.L)("".concat(null!==(p=c.env.API_BASE_URL)&&void 0!==p?p:"").concat(l),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(h),signal:t.signal,openWhenHidden:!0,async onopen(e){if(e.ok&&e.headers.get("content-type")===n.a)return},onclose(){t.abort(),null==u||u()},onerror(e){throw Error(e)},onmessage:e=>{var l;let t=null===(l=e.data)||void 0===l?void 0:l.replaceAll("\\n","\n");"[DONE]"===t?null==x||x():(null==t?void 0:t.startsWith("[ERROR]"))?null==m||m(null==t?void 0:t.replace("[ERROR]","")):null==d||d(t)}})}catch(e){t.abort(),null==m||m("Sorry, We meet some error, please try agin later.",e)}},[l]);return(0,a.useEffect)(()=>()=>{t.abort()},[]),r},u=t(39332),x=t(99513),m=t(24019),h=t(50888),p=t(97937),g=t(63606),v=t(50228),f=t(87547),b=t(89035),j=t(33035),y=t(12767),w=t(94184),Z=t.n(w),_=t(66309),N=t(81799),k=t(41468),C=t(57132),S=t(29158),P=t(98165),R=t(79166),E=t(93179),O=t(71577),D=t(38426),M=t(20640),I=t.n(M);let L={code(e){var l;let{inline:t,node:a,className:s,children:n,style:i,...c}=e,d=/language-(\w+)/.exec(s||"");return!t&&d?(0,r.jsxs)("div",{className:"relative",children:[(0,r.jsx)(O.ZP,{className:"absolute right-3 top-2 text-gray-300 hover:!text-gray-200 bg-gray-700",type:"text",icon:(0,r.jsx)(C.Z,{}),onClick:()=>{let e=I()(n);o.ZP[e?"success":"error"](e?"Copy success":"Copy failed")}}),(0,r.jsx)(E.Z,{language:null!==(l=null==d?void 0:d[1])&&void 0!==l?l:"javascript",style:R.Z,children:n})]}):(0,r.jsx)("code",{...c,style:i,className:"px-[6px] py-[2px] rounded bg-gray-700 text-gray-100 dark:bg-gray-100 dark:text-gray-800 text-sm",children:n})},ul(e){let{children:l}=e;return(0,r.jsx)("ul",{className:"py-1",children:l})},ol(e){let{children:l}=e;return(0,r.jsx)("ol",{className:"py-1",children:l})},li(e){let{children:l,ordered:t}=e;return(0,r.jsx)("li",{className:"text-sm leading-7 ml-5 pl-2 text-gray-600 dark:text-gray-300 ".concat(t?"list-decimal":"list-disc"),children:l})},table(e){let{children:l}=e;return(0,r.jsx)("table",{className:"my-2 rounded-tl-md rounded-tr-md max-w-full bg-white dark:bg-gray-900 text-sm rounded-lg overflow-hidden",children:l})},thead(e){let{children:l}=e;return(0,r.jsx)("thead",{className:"bg-[#fafafa] dark:bg-black font-semibold",children:l})},th(e){let{children:l}=e;return(0,r.jsx)("th",{className:"!text-left p-4",children:l})},td(e){let{children:l}=e;return(0,r.jsx)("td",{className:"p-4 border-t border-[#f0f0f0] dark:border-gray-700",children:l})},h1(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-2xl font-bold my-4 border-b border-slate-300 pb-4",children:l})},h2(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-xl font-bold my-3",children:l})},h3(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-lg font-semibold my-2",children:l})},h4(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-base font-semibold my-1",children:l})},a(e){let{children:l,href:t}=e;return(0,r.jsxs)("div",{className:"inline-block text-blue-600 dark:text-blue-400",children:[(0,r.jsx)(S.Z,{className:"mr-1"}),(0,r.jsx)("a",{href:t,target:"_blank",children:l})]})},img(e){let{src:l,alt:t}=e;return(0,r.jsx)("div",{children:(0,r.jsx)(D.Z,{className:"min-h-[1rem] max-w-full max-h-full border rounded",src:l,alt:t,placeholder:(0,r.jsx)(_.Z,{icon:(0,r.jsx)(P.Z,{spin:!0}),color:"processing",children:"Image Loading..."}),fallback:"/images/fallback.png"})})},blockquote(e){let{children:l}=e;return(0,r.jsx)("blockquote",{className:"py-4 px-6 border-l-4 border-blue-600 rounded bg-white my-2 text-gray-500 dark:bg-slate-800 dark:text-gray-200 dark:border-white shadow-sm",children:l})},references(e){let l,{children:t}=e;try{l=JSON.parse(t)}catch(e){return console.log(e),(0,r.jsx)("p",{className:"text-sm",children:"Render Reference Error!"})}let a=null==l?void 0:l.references;return!a||(null==a?void 0:a.length)<1?null:(0,r.jsxs)("div",{className:"border-t-[1px] border-gray-300 mt-3 py-2",children:[(0,r.jsxs)("p",{className:"text-sm text-gray-500 dark:text-gray-400 mb-2",children:[(0,r.jsx)(S.Z,{className:"mr-2"}),(0,r.jsx)("span",{className:"font-semibold",children:l.title})]}),a.map((e,l)=>{var t;return(0,r.jsxs)("p",{className:"text-sm text-blue-400 dark:text-blue-400 font-normal block ml-4",children:[(0,r.jsx)("span",{className:"mr-4",children:e.name}),null==e?void 0:null===(t=e.pages)||void 0===t?void 0:t.map((l,t)=>(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("span",{children:l},"file_page_".concat(t)),t<(null==e?void 0:e.pages.length)-1&&(0,r.jsx)("span",{children:","},"file_page__".concat(t))]}))]},"file_".concat(l))})]})}},A={todo:{bgClass:"bg-gray-500",icon:(0,r.jsx)(m.Z,{className:"ml-2"})},runing:{bgClass:"bg-blue-500",icon:(0,r.jsx)(h.Z,{className:"ml-2"})},failed:{bgClass:"bg-red-500",icon:(0,r.jsx)(p.Z,{className:"ml-2"})},completed:{bgClass:"bg-green-500",icon:(0,r.jsx)(g.Z,{className:"ml-2"})}};function F(e){return e.replaceAll("\\n","\n").replace(/]+)>/gi,"
").replace(/]+)>/gi,"")}var T=(0,a.memo)(function(e){let{children:l,content:t,isChartChat:s,onLinkClick:n}=e,{scene:o}=(0,a.useContext)(k.p),{context:i,model_name:c,role:d}=t,u="view"===d,{relations:x,value:m,cachePlguinContext:h}=(0,a.useMemo)(()=>{if("string"!=typeof i)return{relations:[],value:"",cachePlguinContext:[]};let[e,l]=i.split(" relations:"),t=l?l.split(","):[],r=[],a=0,s=e.replace(/]*>[^<]*<\/dbgpt-view>/gi,e=>{try{var l;console.log(e);let t=e.replaceAll("\n","\\n").replace(/<[^>]*>|<\/[^>]*>/gm,""),s=JSON.parse(t),n="".concat(a,"");return r.push({...s,result:F(null!==(l=s.result)&&void 0!==l?l:"")}),a++,n}catch(l){return console.log(l.message,l),e}});return{relations:t,cachePlguinContext:r,value:s}},[i]),p=(0,a.useMemo)(()=>({"custom-view"(e){var l;let{children:t}=e,a=+t.toString();if(!h[a])return t;let{name:s,status:n,err_msg:o,result:i}=h[a],{bgClass:c,icon:d}=null!==(l=A[n])&&void 0!==l?l:{};return(0,r.jsxs)("div",{className:"bg-white dark:bg-[#212121] rounded-lg overflow-hidden my-2 flex flex-col lg:max-w-[80%]",children:[(0,r.jsxs)("div",{className:Z()("flex px-4 md:px-6 py-2 items-center text-white text-sm",c),children:[s,d]}),i?(0,r.jsx)("div",{className:"px-4 md:px-6 py-4 text-sm",children:(0,r.jsx)(j.D,{components:L,rehypePlugins:[y.Z],children:null!=i?i:""})}):(0,r.jsx)("div",{className:"px-4 md:px-6 py-4 text-sm",children:o})]})}}),[i,h]);return(0,r.jsxs)("div",{className:Z()("relative flex flex-wrap w-full px-2 sm:px-4 py-2 sm:py-4 rounded-xl break-words",{"bg-slate-100 dark:bg-[#353539]":u,"lg:w-full xl:w-full pl-0":["chat_with_db_execute","chat_dashboard"].includes(o)}),children:[(0,r.jsx)("div",{className:"mr-2 flex flex-shrink-0 items-center justify-center h-7 w-7 rounded-full text-lg sm:mr-4",children:u?(0,N.A)(c)||(0,r.jsx)(v.Z,{}):(0,r.jsx)(f.Z,{})}),(0,r.jsxs)("div",{className:"flex-1 overflow-hidden items-center text-md leading-8",children:[!u&&"string"==typeof i&&i,u&&s&&"object"==typeof i&&(0,r.jsxs)("div",{children:["[".concat(i.template_name,"]: "),(0,r.jsxs)("span",{className:"text-[#1677ff] cursor-pointer",onClick:n,children:[(0,r.jsx)(b.Z,{className:"mr-1"}),i.template_introduce||"More Details"]})]}),u&&"string"==typeof i&&(0,r.jsx)(j.D,{components:{...L,...p},rehypePlugins:[y.Z],children:F(m)}),!!(null==x?void 0:x.length)&&(0,r.jsx)("div",{className:"flex flex-wrap mt-2",children:null==x?void 0:x.map((e,l)=>(0,r.jsx)(_.Z,{color:"#108ee9",children:e},e+l))})]}),l]})}),H=t(59301),J=t(41132),V=t(74312),$=t(3414),q=t(72868),z=t(59562),W=t(14553),G=t(25359),B=t(7203),K=t(48665),Q=t(26047),U=t(99056),X=t(57814),Y=t(63955),ee=t(33028),el=t(40911),et=t(66478),er=t(83062),ea=t(50489),es=t(67421),en=e=>{var l;let{conv_index:t,question:s,knowledge_space:n}=e,{t:i}=(0,es.$G)(),{chatId:c}=(0,a.useContext)(k.p),[d,u]=(0,a.useState)(""),[x,m]=(0,a.useState)(4),[h,p]=(0,a.useState)(""),g=(0,a.useRef)(null),[v,f]=o.ZP.useMessage(),[b,j]=(0,a.useState)({});(0,a.useEffect)(()=>{(0,ea.Vx)((0,ea.Lu)()).then(e=>{var l;console.log(e),j(null!==(l=e[1])&&void 0!==l?l:{})}).catch(e=>{console.log(e)})},[]);let y=(0,a.useCallback)((e,l)=>{l?(0,ea.Vx)((0,ea.Eb)(c,t)).then(e=>{var l,t,r,a;let s=null!==(l=e[1])&&void 0!==l?l:{};u(null!==(t=s.ques_type)&&void 0!==t?t:""),m(parseInt(null!==(r=s.score)&&void 0!==r?r:"4")),p(null!==(a=s.messages)&&void 0!==a?a:"")}).catch(e=>{console.log(e)}):(u(""),m(4),p(""))},[c,t]),w=(0,V.Z)($.Z)(e=>{let{theme:l}=e;return{backgroundColor:"dark"===l.palette.mode?"#FBFCFD":"#0E0E10",...l.typography["body-sm"],padding:l.spacing(1),display:"flex",alignItems:"center",justifyContent:"center",borderRadius:4,width:"100%",height:"100%"}});return(0,r.jsxs)(q.L,{onOpenChange:y,children:[f,(0,r.jsx)(er.Z,{title:i("Rating"),children:(0,r.jsx)(z.Z,{slots:{root:W.ZP},slotProps:{root:{variant:"plain",color:"primary"}},sx:{borderRadius:40},children:(0,r.jsx)(H.Z,{})})}),(0,r.jsxs)(G.Z,{children:[(0,r.jsx)(B.Z,{disabled:!0,sx:{minHeight:0}}),(0,r.jsx)(K.Z,{sx:{width:"100%",maxWidth:350,display:"grid",gap:3,padding:1},children:(0,r.jsx)("form",{onSubmit:e=>{e.preventDefault();let l={conv_uid:c,conv_index:t,question:s,knowledge_space:n,score:x,ques_type:d,messages:h};console.log(l),(0,ea.Vx)((0,ea.VC)({data:l})).then(e=>{v.open({type:"success",content:"save success"})}).catch(e=>{v.open({type:"error",content:"save error"})})},children:(0,r.jsxs)(Q.Z,{container:!0,spacing:.5,columns:13,sx:{flexGrow:1},children:[(0,r.jsx)(Q.Z,{xs:3,children:(0,r.jsx)(w,{children:i("Q_A_Category")})}),(0,r.jsx)(Q.Z,{xs:10,children:(0,r.jsx)(U.Z,{action:g,value:d,placeholder:"Choose one…",onChange:(e,l)=>u(null!=l?l:""),...d&&{endDecorator:(0,r.jsx)(W.ZP,{size:"sm",variant:"plain",color:"neutral",onMouseDown:e=>{e.stopPropagation()},onClick:()=>{var e;u(""),null===(e=g.current)||void 0===e||e.focusVisible()},children:(0,r.jsx)(J.Z,{})}),indicator:null},sx:{width:"100%"},children:null===(l=Object.keys(b))||void 0===l?void 0:l.map(e=>(0,r.jsx)(X.Z,{value:e,children:b[e]},e))})}),(0,r.jsx)(Q.Z,{xs:3,children:(0,r.jsx)(w,{children:(0,r.jsx)(er.Z,{title:(0,r.jsx)(K.Z,{children:(0,r.jsx)("div",{children:i("feed_back_desc")})}),variant:"solid",placement:"left",children:i("Q_A_Rating")})})}),(0,r.jsx)(Q.Z,{xs:10,sx:{pl:0,ml:0},children:(0,r.jsx)(Y.Z,{"aria-label":"Custom",step:1,min:0,max:5,valueLabelFormat:function(e){return({0:i("Lowest"),1:i("Missed"),2:i("Lost"),3:i("Incorrect"),4:i("Verbose"),5:i("Best")})[e]},valueLabelDisplay:"on",marks:[{value:0,label:"0"},{value:1,label:"1"},{value:2,label:"2"},{value:3,label:"3"},{value:4,label:"4"},{value:5,label:"5"}],sx:{width:"90%",pt:3,m:2,ml:1},onChange:e=>{var l;return m(null===(l=e.target)||void 0===l?void 0:l.value)},value:x})}),(0,r.jsx)(Q.Z,{xs:13,children:(0,r.jsx)(ee.Z,{placeholder:i("Please_input_the_text"),value:h,onChange:e=>p(e.target.value),minRows:2,maxRows:4,endDecorator:(0,r.jsx)(el.ZP,{level:"body-xs",sx:{ml:"auto"},children:i("input_count")+h.length+i("input_unit")}),sx:{width:"100%",fontSize:14}})}),(0,r.jsx)(Q.Z,{xs:13,children:(0,r.jsx)(et.Z,{type:"submit",variant:"outlined",sx:{width:"100%",height:"100%"},children:i("submit")})})]})})})]})]})},eo=t(32983),ei=t(12069),ec=t(96486),ed=t.n(ec),eu=t(38954),ex=t(98399),em=e=>{var l;let{messages:t,onSubmit:n}=e,{dbParam:i,currentDialogue:c,scene:d,model:m,refreshDialogList:h,chatId:p,agentList:g}=(0,a.useContext)(k.p),{t:v}=(0,es.$G)(),f=(0,u.useSearchParams)(),b=null!==(l=f&&f.get("spaceNameOriginal"))&&void 0!==l?l:"",[j,y]=(0,a.useState)(!1),[w,_]=(0,a.useState)(!1),[S,P]=(0,a.useState)(t),[R,E]=(0,a.useState)(""),O=(0,a.useRef)(null),D=(0,a.useMemo)(()=>"chat_dashboard"===d,[d]),M=(0,a.useMemo)(()=>{switch(d){case"chat_agent":return g.join(",");case"chat_excel":return null==c?void 0:c.select_param;default:return b||i}},[d,g,c,i,b]),L=async e=>{if(!j&&e.trim())try{y(!0),await n(e,{select_param:null!=M?M:""})}finally{y(!1)}},A=e=>{try{return JSON.parse(e)}catch(l){return e}},[F,H]=o.ZP.useMessage(),J=async e=>{let l=null==e?void 0:e.replace(/\trelations:.*/g,""),t=I()(l);t?l?F.open({type:"success",content:v("Copy_success")}):F.open({type:"warning",content:v("Copy_nothing")}):F.open({type:"error",content:v("Copry_error")})};return(0,s.Z)(async()=>{let e=(0,ex.a_)();e&&e.id===p&&(await L(e.message),h(),localStorage.removeItem(ex.rU))},[p]),(0,a.useEffect)(()=>{let e=t;D&&(e=ed().cloneDeep(t).map(e=>((null==e?void 0:e.role)==="view"&&"string"==typeof(null==e?void 0:e.context)&&(e.context=A(null==e?void 0:e.context)),e))),P(e.filter(e=>["view","human"].includes(e.role)))},[D,t]),(0,a.useEffect)(()=>{setTimeout(()=>{var e;null===(e=O.current)||void 0===e||e.scrollTo(0,O.current.scrollHeight)},50)},[t]),(0,r.jsxs)(r.Fragment,{children:[H,(0,r.jsx)("div",{ref:O,className:"flex flex-1 overflow-y-auto pb-8 w-full flex-col",children:(0,r.jsx)("div",{className:"flex items-center flex-1 flex-col text-sm leading-6 text-slate-900 dark:text-slate-300 sm:text-base sm:leading-7",children:S.length?S.map((e,l)=>{var t;return(0,r.jsx)(T,{content:e,isChartChat:D,onLinkClick:()=>{_(!0),E(JSON.stringify(null==e?void 0:e.context,null,2))},children:"view"===e.role&&(0,r.jsxs)("div",{className:"flex w-full flex-row-reverse pt-2 border-t border-gray-200",children:[(0,r.jsx)(en,{conv_index:Math.ceil((l+1)/2),question:null===(t=null==S?void 0:S.filter(l=>(null==l?void 0:l.role)==="human"&&(null==l?void 0:l.order)===e.order)[0])||void 0===t?void 0:t.context,knowledge_space:b||i||""}),(0,r.jsx)(er.Z,{title:v("Copy"),children:(0,r.jsx)(et.Z,{onClick:()=>J(null==e?void 0:e.context),slots:{root:W.ZP},slotProps:{root:{variant:"plain",color:"primary"}},sx:{borderRadius:40},children:(0,r.jsx)(C.Z,{})})})]})},l)}):(0,r.jsx)(eo.Z,{image:"/empty.png",imageStyle:{width:320,height:320,margin:"0 auto",maxWidth:"100%",maxHeight:"100%"},className:"flex items-center justify-center flex-col h-full w-full",description:"Start a conversation"})})}),(0,r.jsx)("div",{className:Z()("relative after:absolute after:-top-8 after:h-8 after:w-full after:bg-gradient-to-t after:from-white after:to-transparent dark:after:from-[#212121]",{"cursor-not-allowed":"chat_excel"===d&&!(null==c?void 0:c.select_param)}),children:(0,r.jsxs)("div",{className:"flex flex-wrap w-full py-2 sm:pt-6 sm:pb-10",children:[m&&(0,r.jsx)("div",{className:"mr-2 flex items-center h-10",children:(0,N.A)(m)}),(0,r.jsx)(eu.Z,{loading:j,onSubmit:L})]})}),(0,r.jsx)(ei.default,{title:"JSON Editor",open:w,width:"60%",cancelButtonProps:{hidden:!0},onOk:()=>{_(!1)},onCancel:()=>{_(!1)},children:(0,r.jsx)(x.Z,{className:"w-full h-[500px]",language:"json",value:R})})]})},eh=t(70803),ep=t(39156),eg=t(45247),ev=()=>{var e;let l=(0,u.useSearchParams)(),{scene:t,chatId:n,model:o,setModel:i}=(0,a.useContext)(k.p),c=d({}),x=null!==(e=l&&l.get("initMessage"))&&void 0!==e?e:"",[m,h]=(0,a.useState)(!1),[p,g]=(0,a.useState)(),[v,f]=(0,a.useState)([]),b=async()=>{h(!0);let[,e]=await (0,ea.Vx)((0,ea.$i)(n));f(null!=e?e:[]),h(!1)},j=e=>{var l;let t=null===(l=e[e.length-1])||void 0===l?void 0:l.context;if(t)try{let e=JSON.parse(t);g((null==e?void 0:e.template_name)==="report"?null==e?void 0:e.charts:void 0)}catch(e){g(void 0)}};(0,s.Z)(async()=>{let e=(0,ex.a_)();e&&e.id===n||await b()},[x,n]),(0,a.useEffect)(()=>{var e,l;if(!v.length)return;let t=null===(e=null===(l=v.filter(e=>"view"===e.role))||void 0===l?void 0:l.slice(-1))||void 0===e?void 0:e[0];(null==t?void 0:t.model_name)&&i(t.model_name),j(v)},[v.length]);let y=(0,a.useCallback)((e,l)=>new Promise(r=>{let a=[...v,{role:"human",context:e,model_name:o,order:0,time_stamp:0},{role:"view",context:"",model_name:o,order:0,time_stamp:0}],s=a.length-1;f([...a]),c({context:e,data:{...l,chat_mode:t||"chat_normal",model_name:o},chatId:n,onMessage:e=>{a[s].context=e,f([...a])},onDone:()=>{j(a),r()},onClose:()=>{j(a),r()},onError:e=>{a[s].context=e,f([...a]),r()}})}),[v,c,o]);return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(eg.Z,{visible:m}),(0,r.jsx)(eh.Z,{refreshHistory:b,modelChange:e=>{i(e)}}),(0,r.jsxs)("div",{className:"px-4 flex flex-1 flex-wrap overflow-hidden relative",children:[!!(null==p?void 0:p.length)&&(0,r.jsx)("div",{className:"w-full xl:w-3/4 h-3/5 xl:pr-4 xl:h-full overflow-y-auto",children:(0,r.jsx)(ep.Z,{chartsData:p})}),!(null==p?void 0:p.length)&&"chat_dashboard"===t&&(0,r.jsx)(eo.Z,{image:"/empty.png",imageStyle:{width:320,height:320,margin:"0 auto",maxWidth:"100%",maxHeight:"100%"},className:"w-full xl:w-3/4 h-3/5 xl:h-full pt-0 md:pt-10"}),(0,r.jsx)("div",{className:Z()("flex flex-1 flex-col overflow-hidden",{"px-0 xl:pl-4 h-2/5 xl:h-full border-t xl:border-t-0 xl:border-l":"chat_dashboard"===t,"h-full lg:px-8":"chat_dashboard"!==t}),children:(0,r.jsx)(em,{messages:v,onSubmit:y})})]})]})}},38954:function(e,l,t){t.d(l,{Z:function(){return j}});var r=t(85893),a=t(27496),s=t(59566),n=t(71577),o=t(67294),i=t(2487),c=t(83062),d=t(2453),u=t(74627),x=t(39479),m=t(51009),h=t(58299),p=t(577),g=t(30119),v=t(67421);let f=e=>{let{data:l,loading:t,submit:a,close:s}=e,{t:n}=(0,v.$G)(),o=e=>()=>{a(e),s()};return(0,r.jsx)("div",{style:{maxHeight:400,overflow:"auto"},children:(0,r.jsx)(i.Z,{dataSource:null==l?void 0:l.data,loading:t,rowKey:e=>e.prompt_name,renderItem:e=>(0,r.jsx)(i.Z.Item,{onClick:o(e.content),children:(0,r.jsx)(c.Z,{title:e.content,children:(0,r.jsx)(i.Z.Item.Meta,{style:{cursor:"copy"},title:e.prompt_name,description:n("Prompt_Info_Scene")+":".concat(e.chat_scene,",")+n("Prompt_Info_Sub_Scene")+":".concat(e.sub_chat_scene)})})},e.prompt_name)})})};var b=e=>{let{submit:l}=e,{t}=(0,v.$G)(),[a,s]=(0,o.useState)(!1),[n,i]=(0,o.useState)("common"),{data:b,loading:j}=(0,p.Z)(()=>(0,g.PR)("/prompt/list",{prompt_type:n}),{refreshDeps:[n],onError:e=>{d.ZP.error(null==e?void 0:e.message)}});return(0,r.jsx)(u.Z,{title:(0,r.jsx)(x.Z.Item,{label:"Prompt "+t("Type"),children:(0,r.jsx)(m.default,{style:{width:130},value:n,onChange:e=>{i(e)},options:[{label:t("Public")+" Prompts",value:"common"},{label:t("Private")+" Prompts",value:"private"}]})}),content:(0,r.jsx)(f,{data:b,loading:j,submit:l,close:()=>{s(!1)}}),placement:"topRight",trigger:"click",open:a,onOpenChange:e=>{s(e)},children:(0,r.jsx)(c.Z,{title:t("Click_Select")+" Prompt",children:(0,r.jsx)(h.Z,{className:"bottom-32"})})})},j=function(e){let{children:l,loading:t,onSubmit:i,...c}=e,[d,u]=(0,o.useState)("");return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.default.TextArea,{className:"flex-1",size:"large",value:d,autoSize:{minRows:1,maxRows:4},...c,onPressEnter:e=>{if(d.trim()&&13===e.keyCode){if(e.shiftKey){u(e=>e+"\n");return}i(d),setTimeout(()=>{u("")},0)}},onChange:e=>{if("number"==typeof c.maxLength){u(e.target.value.substring(0,c.maxLength));return}u(e.target.value)}}),(0,r.jsx)(n.ZP,{className:"ml-2 flex items-center justify-center",size:"large",type:"text",loading:t,icon:(0,r.jsx)(a.Z,{}),onClick:()=>{i(d)}}),(0,r.jsx)(b,{submit:e=>{u(d+e)}}),l]})}},45247:function(e,l,t){var r=t(85893),a=t(50888);l.Z=function(e){let{visible:l}=e;return l?(0,r.jsx)("div",{className:"absolute w-full h-full top-0 left-0 flex justify-center items-center z-10 bg-white dark:bg-black bg-opacity-50 dark:bg-opacity-50 backdrop-blur-sm text-3xl animate-fade animate-duration-200",children:(0,r.jsx)(a.Z,{})}):null}}}]); \ No newline at end of file diff --git a/pilot/server/static/_next/static/chunks/pages/_app-7394a5c2fd417054.js b/pilot/server/static/_next/static/chunks/pages/_app-41ccdddf1de778e7.js similarity index 92% rename from pilot/server/static/_next/static/chunks/pages/_app-7394a5c2fd417054.js rename to pilot/server/static/_next/static/chunks/pages/_app-41ccdddf1de778e7.js index d35332230..84ed3fda6 100644 --- a/pilot/server/static/_next/static/chunks/pages/_app-7394a5c2fd417054.js +++ b/pilot/server/static/_next/static/chunks/pages/_app-41ccdddf1de778e7.js @@ -134,7 +134,7 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,i=n?Symbol.for("react.fragment"):60107,a=n?Symbol.for("react.strict_mode"):60108,l=n?Symbol.for("react.profiler"):60114,s=n?Symbol.for("react.provider"):60109,c=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,f=n?Symbol.for("react.concurrent_mode"):60111,d=n?Symbol.for("react.forward_ref"):60112,p=n?Symbol.for("react.suspense"):60113,h=n?Symbol.for("react.suspense_list"):60120,m=n?Symbol.for("react.memo"):60115,g=n?Symbol.for("react.lazy"):60116,v=n?Symbol.for("react.block"):60121,y=n?Symbol.for("react.fundamental"):60117,b=n?Symbol.for("react.responder"):60118,x=n?Symbol.for("react.scope"):60119;function w(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case u:case f:case i:case l:case a:case p:return e;default:switch(e=e&&e.$$typeof){case c:case d:case g:case m:case s:return e;default:return t}}case o:return t}}}function C(e){return w(e)===f}t.AsyncMode=u,t.ConcurrentMode=f,t.ContextConsumer=c,t.ContextProvider=s,t.Element=r,t.ForwardRef=d,t.Fragment=i,t.Lazy=g,t.Memo=m,t.Portal=o,t.Profiler=l,t.StrictMode=a,t.Suspense=p,t.isAsyncMode=function(e){return C(e)||w(e)===u},t.isConcurrentMode=C,t.isContextConsumer=function(e){return w(e)===c},t.isContextProvider=function(e){return w(e)===s},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return w(e)===d},t.isFragment=function(e){return w(e)===i},t.isLazy=function(e){return w(e)===g},t.isMemo=function(e){return w(e)===m},t.isPortal=function(e){return w(e)===o},t.isProfiler=function(e){return w(e)===l},t.isStrictMode=function(e){return w(e)===a},t.isSuspense=function(e){return w(e)===p},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===i||e===f||e===l||e===a||e===p||e===h||"object"==typeof e&&null!==e&&(e.$$typeof===g||e.$$typeof===m||e.$$typeof===s||e.$$typeof===c||e.$$typeof===d||e.$$typeof===y||e.$$typeof===b||e.$$typeof===x||e.$$typeof===v)},t.typeOf=w},21296:function(e,t,n){"use strict";e.exports=n(96103)},62705:function(e,t,n){var r=n(55639).Symbol;e.exports=r},44239:function(e,t,n){var r=n(62705),o=n(89607),i=n(2333),a=r?r.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":a&&a in Object(e)?o(e):i(e)}},27561:function(e,t,n){var r=n(67990),o=/^\s+/;e.exports=function(e){return e?e.slice(0,r(e)+1).replace(o,""):e}},31957:function(e,t,n){var r="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g;e.exports=r},89607:function(e,t,n){var r=n(62705),o=Object.prototype,i=o.hasOwnProperty,a=o.toString,l=r?r.toStringTag:void 0;e.exports=function(e){var t=i.call(e,l),n=e[l];try{e[l]=void 0;var r=!0}catch(e){}var o=a.call(e);return r&&(t?e[l]=n:delete e[l]),o}},2333:function(e){var t=Object.prototype.toString;e.exports=function(e){return t.call(e)}},55639:function(e,t,n){var r=n(31957),o="object"==typeof self&&self&&self.Object===Object&&self,i=r||o||Function("return this")();e.exports=i},67990:function(e){var t=/\s/;e.exports=function(e){for(var n=e.length;n--&&t.test(e.charAt(n)););return n}},23279:function(e,t,n){var r=n(13218),o=n(7771),i=n(14841),a=Math.max,l=Math.min;e.exports=function(e,t,n){var s,c,u,f,d,p,h=0,m=!1,g=!1,v=!0;if("function"!=typeof e)throw TypeError("Expected a function");function y(t){var n=s,r=c;return s=c=void 0,h=t,f=e.apply(r,n)}function b(e){var n=e-p,r=e-h;return void 0===p||n>=t||n<0||g&&r>=u}function x(){var e,n,r,i=o();if(b(i))return w(i);d=setTimeout(x,(e=i-p,n=i-h,r=t-e,g?l(r,u-n):r))}function w(e){return(d=void 0,v&&s)?y(e):(s=c=void 0,f)}function C(){var e,n=o(),r=b(n);if(s=arguments,c=this,p=n,r){if(void 0===d)return h=e=p,d=setTimeout(x,t),m?y(e):f;if(g)return clearTimeout(d),d=setTimeout(x,t),y(p)}return void 0===d&&(d=setTimeout(x,t)),f}return t=i(t)||0,r(n)&&(m=!!n.leading,u=(g="maxWait"in n)?a(i(n.maxWait)||0,t):u,v="trailing"in n?!!n.trailing:v),C.cancel=function(){void 0!==d&&clearTimeout(d),h=0,s=p=c=d=void 0},C.flush=function(){return void 0===d?f:w(o())},C}},13218:function(e){e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},37005:function(e){e.exports=function(e){return null!=e&&"object"==typeof e}},33448:function(e,t,n){var r=n(44239),o=n(37005);e.exports=function(e){return"symbol"==typeof e||o(e)&&"[object Symbol]"==r(e)}},7771:function(e,t,n){var r=n(55639);e.exports=function(){return r.Date.now()}},23493:function(e,t,n){var r=n(23279),o=n(13218);e.exports=function(e,t,n){var i=!0,a=!0;if("function"!=typeof e)throw TypeError("Expected a function");return o(n)&&(i="leading"in n?!!n.leading:i,a="trailing"in n?!!n.trailing:a),r(e,t,{leading:i,maxWait:t,trailing:a})}},14841:function(e,t,n){var r=n(27561),o=n(13218),i=n(33448),a=0/0,l=/^[-+]0x[0-9a-f]+$/i,s=/^0b[01]+$/i,c=/^0o[0-7]+$/i,u=parseInt;e.exports=function(e){if("number"==typeof e)return e;if(i(e))return a;if(o(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=o(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=r(e);var n=s.test(e);return n||c.test(e)?u(e.slice(2),n?2:8):l.test(e)?a:+e}},83454:function(e,t,n){"use strict";var r,o;e.exports=(null==(r=n.g.process)?void 0:r.env)&&"object"==typeof(null==(o=n.g.process)?void 0:o.env)?n.g.process:n(77663)},6840:function(e,t,n){(window.__NEXT_P=window.__NEXT_P||[]).push(["/_app",function(){return n(37262)}])},41468:function(e,t,n){"use strict";n.d(t,{R:function(){return c},p:function(){return s}});var r=n(85893),o=n(67294),i=n(50489),a=n(577),l=n(39332);let s=(0,o.createContext)({scene:"",chatId:"",modelList:[],model:"",dbParam:void 0,dialogueList:[],agentList:[],setAgentList:()=>{},setModel:()=>{},setIsContract:()=>{},setIsMenuExpand:()=>{},setDbParam:()=>void 0,queryDialogueList:()=>{},refreshDialogList:()=>{}}),c=e=>{var t,n,c;let{children:u}=e,f=(0,l.useSearchParams)(),d=null!==(t=null==f?void 0:f.get("id"))&&void 0!==t?t:"",p=null!==(n=null==f?void 0:f.get("scene"))&&void 0!==n?n:"",h=null!==(c=null==f?void 0:f.get("db_param"))&&void 0!==c?c:"",[m,g]=(0,o.useState)(!1),[v,y]=(0,o.useState)(""),[b,x]=(0,o.useState)("chat_dashboard"!==p),[w,C]=(0,o.useState)(h),[E,S]=(0,o.useState)([]),{run:$,data:O=[],refresh:k}=(0,a.Z)(async()=>{let[,e]=await (0,i.Vx)((0,i.iP)());return null!=e?e:[]},{manual:!0}),{data:Z=[]}=(0,a.Z)(async()=>{let[,e]=await (0,i.Vx)((0,i.Vw)());return null!=e?e:[]});(0,o.useEffect)(()=>{y(Z[0])},[Z,null==Z?void 0:Z.length]);let P=(0,o.useMemo)(()=>O.find(e=>e.conv_uid===d),[d,O]);return(0,r.jsx)(s.Provider,{value:{isContract:m,isMenuExpand:b,scene:p,chatId:d,modelList:Z,model:v,dbParam:w||h,dialogueList:O,agentList:E,setAgentList:S,setModel:y,setIsContract:g,setIsMenuExpand:x,setDbParam:C,queryDialogueList:$,refreshDialogList:k,currentDialogue:P},children:u})}},58989:function(e,t,n){"use strict";n.d(t,{Z:function(){return D}});let r={type:"logger",log(e){this.output("log",e)},warn(e){this.output("warn",e)},error(e){this.output("error",e)},output(e,t){console&&console[e]&&console[e].apply(console,t)}};class o{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.init(e,t)}init(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.prefix=t.prefix||"i18next:",this.logger=e||r,this.options=t,this.debug=t.debug}log(){for(var e=arguments.length,t=Array(e),n=0;n{this.observers[e]=this.observers[e]||[],this.observers[e].push(t)}),this}off(e,t){if(this.observers[e]){if(!t){delete this.observers[e];return}this.observers[e]=this.observers[e].filter(e=>e!==t)}}emit(e){for(var t=arguments.length,n=Array(t>1?t-1:0),r=1;r{e(...n)})}if(this.observers["*"]){let t=[].concat(this.observers["*"]);t.forEach(t=>{t.apply(t,[e,...n])})}}}function l(){let e,t;let n=new Promise((n,r)=>{e=n,t=r});return n.resolve=e,n.reject=t,n}function s(e){return null==e?"":""+e}function c(e,t,n){function r(e){return e&&e.indexOf("###")>-1?e.replace(/###/g,"."):e}function o(){return!e||"string"==typeof e}let i="string"!=typeof t?[].concat(t):t.split(".");for(;i.length>1;){if(o())return{};let t=r(i.shift());!e[t]&&n&&(e[t]=new n),e=Object.prototype.hasOwnProperty.call(e,t)?e[t]:{}}return o()?{}:{obj:e,k:r(i.shift())}}function u(e,t,n){let{obj:r,k:o}=c(e,t,Object);r[o]=n}function f(e,t){let{obj:n,k:r}=c(e,t);if(n)return n[r]}function d(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}var p={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};function h(e){return"string"==typeof e?e.replace(/[&<>"'\/]/g,e=>p[e]):e}let m=[" ",",","?","!",";"];function g(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:".";if(!e)return;if(e[t])return e[t];let r=t.split(n),o=e;for(let e=0;ee+i;)i++,l=o[a=r.slice(e,e+i).join(n)];if(void 0===l)return;if(null===l)return null;if(t.endsWith(a)){if("string"==typeof l)return l;if(a&&"string"==typeof l[a])return l[a]}let s=r.slice(e+i).join(n);if(s)return g(l,s,n);return}o=o[r[e]]}return o}function v(e){return e&&e.indexOf("_")>0?e.replace("_","-"):e}class y extends a{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{ns:["translation"],defaultNS:"translation"};super(),this.data=e||{},this.options=t,void 0===this.options.keySeparator&&(this.options.keySeparator="."),void 0===this.options.ignoreJSONStructure&&(this.options.ignoreJSONStructure=!0)}addNamespaces(e){0>this.options.ns.indexOf(e)&&this.options.ns.push(e)}removeNamespaces(e){let t=this.options.ns.indexOf(e);t>-1&&this.options.ns.splice(t,1)}getResource(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},o=void 0!==r.keySeparator?r.keySeparator:this.options.keySeparator,i=void 0!==r.ignoreJSONStructure?r.ignoreJSONStructure:this.options.ignoreJSONStructure,a=[e,t];n&&"string"!=typeof n&&(a=a.concat(n)),n&&"string"==typeof n&&(a=a.concat(o?n.split(o):n)),e.indexOf(".")>-1&&(a=e.split("."));let l=f(this.data,a);return l||!i||"string"!=typeof n?l:g(this.data&&this.data[e]&&this.data[e][t],n,o)}addResource(e,t,n,r){let o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{silent:!1},i=void 0!==o.keySeparator?o.keySeparator:this.options.keySeparator,a=[e,t];n&&(a=a.concat(i?n.split(i):n)),e.indexOf(".")>-1&&(a=e.split("."),r=t,t=a[1]),this.addNamespaces(t),u(this.data,a,r),o.silent||this.emit("added",e,t,n,r)}addResources(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{silent:!1};for(let r in n)("string"==typeof n[r]||"[object Array]"===Object.prototype.toString.apply(n[r]))&&this.addResource(e,t,r,n[r],{silent:!0});r.silent||this.emit("added",e,t,n)}addResourceBundle(e,t,n,r,o){let i=arguments.length>5&&void 0!==arguments[5]?arguments[5]:{silent:!1},a=[e,t];e.indexOf(".")>-1&&(a=e.split("."),r=n,n=t,t=a[1]),this.addNamespaces(t);let l=f(this.data,a)||{};r?function e(t,n,r){for(let o in n)"__proto__"!==o&&"constructor"!==o&&(o in t?"string"==typeof t[o]||t[o]instanceof String||"string"==typeof n[o]||n[o]instanceof String?r&&(t[o]=n[o]):e(t[o],n[o],r):t[o]=n[o]);return t}(l,n,o):l={...l,...n},u(this.data,a,l),i.silent||this.emit("added",e,t,n)}removeResourceBundle(e,t){this.hasResourceBundle(e,t)&&delete this.data[e][t],this.removeNamespaces(t),this.emit("removed",e,t)}hasResourceBundle(e,t){return void 0!==this.getResource(e,t)}getResourceBundle(e,t){return(t||(t=this.options.defaultNS),"v1"===this.options.compatibilityAPI)?{...this.getResource(e,t)}:this.getResource(e,t)}getDataByLanguage(e){return this.data[e]}hasLanguageSomeTranslations(e){let t=this.getDataByLanguage(e),n=t&&Object.keys(t)||[];return!!n.find(e=>t[e]&&Object.keys(t[e]).length>0)}toJSON(){return this.data}}var b={processors:{},addPostProcessor(e){this.processors[e.name]=e},handle(e,t,n,r,o){return e.forEach(e=>{this.processors[e]&&(t=this.processors[e].process(t,n,r,o))}),t}};let x={};class w extends a{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),function(e,t,n){e.forEach(e=>{t[e]&&(n[e]=t[e])})}(["resourceStore","languageUtils","pluralResolver","interpolator","backendConnector","i18nFormat","utils"],e,this),this.options=t,void 0===this.options.keySeparator&&(this.options.keySeparator="."),this.logger=i.create("translator")}changeLanguage(e){e&&(this.language=e)}exists(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{interpolation:{}};if(null==e)return!1;let n=this.resolve(e,t);return n&&void 0!==n.res}extractFromKey(e,t){let n=void 0!==t.nsSeparator?t.nsSeparator:this.options.nsSeparator;void 0===n&&(n=":");let r=void 0!==t.keySeparator?t.keySeparator:this.options.keySeparator,o=t.ns||this.options.defaultNS||[],i=n&&e.indexOf(n)>-1,a=!this.options.userDefinedKeySeparator&&!t.keySeparator&&!this.options.userDefinedNsSeparator&&!t.nsSeparator&&!function(e,t,n){t=t||"",n=n||"";let r=m.filter(e=>0>t.indexOf(e)&&0>n.indexOf(e));if(0===r.length)return!0;let o=RegExp(`(${r.map(e=>"?"===e?"\\?":e).join("|")})`),i=!o.test(e);if(!i){let t=e.indexOf(n);t>0&&!o.test(e.substring(0,t))&&(i=!0)}return i}(e,n,r);if(i&&!a){let t=e.match(this.interpolator.nestingRegexp);if(t&&t.length>0)return{key:e,namespaces:o};let i=e.split(n);(n!==r||n===r&&this.options.ns.indexOf(i[0])>-1)&&(o=i.shift()),e=i.join(r)}return"string"==typeof o&&(o=[o]),{key:e,namespaces:o}}translate(e,t,n){if("object"!=typeof t&&this.options.overloadTranslationOptionHandler&&(t=this.options.overloadTranslationOptionHandler(arguments)),"object"==typeof t&&(t={...t}),t||(t={}),null==e)return"";Array.isArray(e)||(e=[String(e)]);let r=void 0!==t.returnDetails?t.returnDetails:this.options.returnDetails,o=void 0!==t.keySeparator?t.keySeparator:this.options.keySeparator,{key:i,namespaces:a}=this.extractFromKey(e[e.length-1],t),l=a[a.length-1],s=t.lng||this.language,c=t.appendNamespaceToCIMode||this.options.appendNamespaceToCIMode;if(s&&"cimode"===s.toLowerCase()){if(c){let e=t.nsSeparator||this.options.nsSeparator;return r?{res:`${l}${e}${i}`,usedKey:i,exactUsedKey:i,usedLng:s,usedNS:l}:`${l}${e}${i}`}return r?{res:i,usedKey:i,exactUsedKey:i,usedLng:s,usedNS:l}:i}let u=this.resolve(e,t),f=u&&u.res,d=u&&u.usedKey||i,p=u&&u.exactUsedKey||i,h=Object.prototype.toString.apply(f),m=void 0!==t.joinArrays?t.joinArrays:this.options.joinArrays,g=!this.i18nFormat||this.i18nFormat.handleAsObject,v="string"!=typeof f&&"boolean"!=typeof f&&"number"!=typeof f;if(g&&f&&v&&0>["[object Number]","[object Function]","[object RegExp]"].indexOf(h)&&!("string"==typeof m&&"[object Array]"===h)){if(!t.returnObjects&&!this.options.returnObjects){this.options.returnedObjectHandler||this.logger.warn("accessing an object - but returnObjects options is not enabled!");let e=this.options.returnedObjectHandler?this.options.returnedObjectHandler(d,f,{...t,ns:a}):`key '${i} (${this.language})' returned an object instead of string.`;return r?(u.res=e,u):e}if(o){let e="[object Array]"===h,n=e?[]:{},r=e?p:d;for(let e in f)if(Object.prototype.hasOwnProperty.call(f,e)){let i=`${r}${o}${e}`;n[e]=this.translate(i,{...t,joinArrays:!1,ns:a}),n[e]===i&&(n[e]=f[e])}f=n}}else if(g&&"string"==typeof m&&"[object Array]"===h)(f=f.join(m))&&(f=this.extendTranslation(f,e,t,n));else{let r=!1,a=!1,c=void 0!==t.count&&"string"!=typeof t.count,d=w.hasDefaultValue(t),p=c?this.pluralResolver.getSuffix(s,t.count,t):"",h=t.ordinal&&c?this.pluralResolver.getSuffix(s,t.count,{ordinal:!1}):"",m=t[`defaultValue${p}`]||t[`defaultValue${h}`]||t.defaultValue;!this.isValidLookup(f)&&d&&(r=!0,f=m),this.isValidLookup(f)||(a=!0,f=i);let g=t.missingKeyNoValueFallbackToKey||this.options.missingKeyNoValueFallbackToKey,v=g&&a?void 0:f,y=d&&m!==f&&this.options.updateMissing;if(a||r||y){if(this.logger.log(y?"updateKey":"missingKey",s,l,i,y?m:f),o){let e=this.resolve(i,{...t,keySeparator:!1});e&&e.res&&this.logger.warn("Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.")}let e=[],n=this.languageUtils.getFallbackCodes(this.options.fallbackLng,t.lng||this.language);if("fallback"===this.options.saveMissingTo&&n&&n[0])for(let t=0;t{let o=d&&r!==f?r:v;this.options.missingKeyHandler?this.options.missingKeyHandler(e,l,n,o,y,t):this.backendConnector&&this.backendConnector.saveMissing&&this.backendConnector.saveMissing(e,l,n,o,y,t),this.emit("missingKey",e,l,n,f)};this.options.saveMissing&&(this.options.saveMissingPlurals&&c?e.forEach(e=>{this.pluralResolver.getSuffixes(e,t).forEach(n=>{r([e],i+n,t[`defaultValue${n}`]||m)})}):r(e,i,m))}f=this.extendTranslation(f,e,t,u,n),a&&f===i&&this.options.appendNamespaceToMissingKey&&(f=`${l}:${i}`),(a||r)&&this.options.parseMissingKeyHandler&&(f="v1"!==this.options.compatibilityAPI?this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey?`${l}:${i}`:i,r?f:void 0):this.options.parseMissingKeyHandler(f))}return r?(u.res=f,u):f}extendTranslation(e,t,n,r,o){var i=this;if(this.i18nFormat&&this.i18nFormat.parse)e=this.i18nFormat.parse(e,{...this.options.interpolation.defaultVariables,...n},n.lng||this.language||r.usedLng,r.usedNS,r.usedKey,{resolved:r});else if(!n.skipInterpolation){let a;n.interpolation&&this.interpolator.init({...n,interpolation:{...this.options.interpolation,...n.interpolation}});let l="string"==typeof e&&(n&&n.interpolation&&void 0!==n.interpolation.skipOnVariables?n.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables);if(l){let t=e.match(this.interpolator.nestingRegexp);a=t&&t.length}let s=n.replace&&"string"!=typeof n.replace?n.replace:n;if(this.options.interpolation.defaultVariables&&(s={...this.options.interpolation.defaultVariables,...s}),e=this.interpolator.interpolate(e,s,n.lng||this.language,n),l){let t=e.match(this.interpolator.nestingRegexp),r=t&&t.length;a1&&void 0!==arguments[1]?arguments[1]:{};return"string"==typeof e&&(e=[e]),e.forEach(e=>{if(this.isValidLookup(t))return;let l=this.extractFromKey(e,a),s=l.key;n=s;let c=l.namespaces;this.options.fallbackNS&&(c=c.concat(this.options.fallbackNS));let u=void 0!==a.count&&"string"!=typeof a.count,f=u&&!a.ordinal&&0===a.count&&this.pluralResolver.shouldUseIntlApi(),d=void 0!==a.context&&("string"==typeof a.context||"number"==typeof a.context)&&""!==a.context,p=a.lngs?a.lngs:this.languageUtils.toResolveHierarchy(a.lng||this.language,a.fallbackLng);c.forEach(e=>{this.isValidLookup(t)||(i=e,!x[`${p[0]}-${e}`]&&this.utils&&this.utils.hasLoadedNamespace&&!this.utils.hasLoadedNamespace(i)&&(x[`${p[0]}-${e}`]=!0,this.logger.warn(`key "${n}" for languages "${p.join(", ")}" won't get resolved as namespace "${i}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!")),p.forEach(n=>{let i;if(this.isValidLookup(t))return;o=n;let l=[s];if(this.i18nFormat&&this.i18nFormat.addLookupKeys)this.i18nFormat.addLookupKeys(l,s,n,e,a);else{let e;u&&(e=this.pluralResolver.getSuffix(n,a.count,a));let t=`${this.options.pluralSeparator}zero`,r=`${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;if(u&&(l.push(s+e),a.ordinal&&0===e.indexOf(r)&&l.push(s+e.replace(r,this.options.pluralSeparator)),f&&l.push(s+t)),d){let n=`${s}${this.options.contextSeparator}${a.context}`;l.push(n),u&&(l.push(n+e),a.ordinal&&0===e.indexOf(r)&&l.push(n+e.replace(r,this.options.pluralSeparator)),f&&l.push(n+t))}}for(;i=l.pop();)this.isValidLookup(t)||(r=i,t=this.getResource(n,e,i,a))}))})}),{res:t,usedKey:n,exactUsedKey:r,usedLng:o,usedNS:i}}isValidLookup(e){return void 0!==e&&!(!this.options.returnNull&&null===e)&&!(!this.options.returnEmptyString&&""===e)}getResource(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return this.i18nFormat&&this.i18nFormat.getResource?this.i18nFormat.getResource(e,t,n,r):this.resourceStore.getResource(e,t,n,r)}static hasDefaultValue(e){let t="defaultValue";for(let n in e)if(Object.prototype.hasOwnProperty.call(e,n)&&t===n.substring(0,t.length)&&void 0!==e[n])return!0;return!1}}function C(e){return e.charAt(0).toUpperCase()+e.slice(1)}class E{constructor(e){this.options=e,this.supportedLngs=this.options.supportedLngs||!1,this.logger=i.create("languageUtils")}getScriptPartFromCode(e){if(!(e=v(e))||0>e.indexOf("-"))return null;let t=e.split("-");return 2===t.length?null:(t.pop(),"x"===t[t.length-1].toLowerCase())?null:this.formatLanguageCode(t.join("-"))}getLanguagePartFromCode(e){if(!(e=v(e))||0>e.indexOf("-"))return e;let t=e.split("-");return this.formatLanguageCode(t[0])}formatLanguageCode(e){if("string"==typeof e&&e.indexOf("-")>-1){let t=["hans","hant","latn","cyrl","cans","mong","arab"],n=e.split("-");return this.options.lowerCaseLng?n=n.map(e=>e.toLowerCase()):2===n.length?(n[0]=n[0].toLowerCase(),n[1]=n[1].toUpperCase(),t.indexOf(n[1].toLowerCase())>-1&&(n[1]=C(n[1].toLowerCase()))):3===n.length&&(n[0]=n[0].toLowerCase(),2===n[1].length&&(n[1]=n[1].toUpperCase()),"sgn"!==n[0]&&2===n[2].length&&(n[2]=n[2].toUpperCase()),t.indexOf(n[1].toLowerCase())>-1&&(n[1]=C(n[1].toLowerCase())),t.indexOf(n[2].toLowerCase())>-1&&(n[2]=C(n[2].toLowerCase()))),n.join("-")}return this.options.cleanCode||this.options.lowerCaseLng?e.toLowerCase():e}isSupportedCode(e){return("languageOnly"===this.options.load||this.options.nonExplicitSupportedLngs)&&(e=this.getLanguagePartFromCode(e)),!this.supportedLngs||!this.supportedLngs.length||this.supportedLngs.indexOf(e)>-1}getBestMatchFromCodes(e){let t;return e?(e.forEach(e=>{if(t)return;let n=this.formatLanguageCode(e);(!this.options.supportedLngs||this.isSupportedCode(n))&&(t=n)}),!t&&this.options.supportedLngs&&e.forEach(e=>{if(t)return;let n=this.getLanguagePartFromCode(e);if(this.isSupportedCode(n))return t=n;t=this.options.supportedLngs.find(e=>{if(e===n||!(0>e.indexOf("-")&&0>n.indexOf("-"))&&0===e.indexOf(n))return e})}),t||(t=this.getFallbackCodes(this.options.fallbackLng)[0]),t):null}getFallbackCodes(e,t){if(!e)return[];if("function"==typeof e&&(e=e(t)),"string"==typeof e&&(e=[e]),"[object Array]"===Object.prototype.toString.apply(e))return e;if(!t)return e.default||[];let n=e[t];return n||(n=e[this.getScriptPartFromCode(t)]),n||(n=e[this.formatLanguageCode(t)]),n||(n=e[this.getLanguagePartFromCode(t)]),n||(n=e.default),n||[]}toResolveHierarchy(e,t){let n=this.getFallbackCodes(t||this.options.fallbackLng||[],e),r=[],o=e=>{e&&(this.isSupportedCode(e)?r.push(e):this.logger.warn(`rejecting language code not found in supportedLngs: ${e}`))};return"string"==typeof e&&(e.indexOf("-")>-1||e.indexOf("_")>-1)?("languageOnly"!==this.options.load&&o(this.formatLanguageCode(e)),"languageOnly"!==this.options.load&&"currentOnly"!==this.options.load&&o(this.getScriptPartFromCode(e)),"currentOnly"!==this.options.load&&o(this.getLanguagePartFromCode(e))):"string"==typeof e&&o(this.formatLanguageCode(e)),n.forEach(e=>{0>r.indexOf(e)&&o(this.formatLanguageCode(e))}),r}}let S=[{lngs:["ach","ak","am","arn","br","fil","gun","ln","mfe","mg","mi","oc","pt","pt-BR","tg","tl","ti","tr","uz","wa"],nr:[1,2],fc:1},{lngs:["af","an","ast","az","bg","bn","ca","da","de","dev","el","en","eo","es","et","eu","fi","fo","fur","fy","gl","gu","ha","hi","hu","hy","ia","it","kk","kn","ku","lb","mai","ml","mn","mr","nah","nap","nb","ne","nl","nn","no","nso","pa","pap","pms","ps","pt-PT","rm","sco","se","si","so","son","sq","sv","sw","ta","te","tk","ur","yo"],nr:[1,2],fc:2},{lngs:["ay","bo","cgg","fa","ht","id","ja","jbo","ka","km","ko","ky","lo","ms","sah","su","th","tt","ug","vi","wo","zh"],nr:[1],fc:3},{lngs:["be","bs","cnr","dz","hr","ru","sr","uk"],nr:[1,2,5],fc:4},{lngs:["ar"],nr:[0,1,2,3,11,100],fc:5},{lngs:["cs","sk"],nr:[1,2,5],fc:6},{lngs:["csb","pl"],nr:[1,2,5],fc:7},{lngs:["cy"],nr:[1,2,3,8],fc:8},{lngs:["fr"],nr:[1,2],fc:9},{lngs:["ga"],nr:[1,2,3,7,11],fc:10},{lngs:["gd"],nr:[1,2,3,20],fc:11},{lngs:["is"],nr:[1,2],fc:12},{lngs:["jv"],nr:[0,1],fc:13},{lngs:["kw"],nr:[1,2,3,4],fc:14},{lngs:["lt"],nr:[1,2,10],fc:15},{lngs:["lv"],nr:[1,2,0],fc:16},{lngs:["mk"],nr:[1,2],fc:17},{lngs:["mnk"],nr:[0,1,2],fc:18},{lngs:["mt"],nr:[1,2,11,20],fc:19},{lngs:["or"],nr:[2,1],fc:2},{lngs:["ro"],nr:[1,2,20],fc:20},{lngs:["sl"],nr:[5,1,2,3],fc:21},{lngs:["he","iw"],nr:[1,2,20,21],fc:22}],$={1:function(e){return Number(e>1)},2:function(e){return Number(1!=e)},3:function(e){return 0},4:function(e){return Number(e%10==1&&e%100!=11?0:e%10>=2&&e%10<=4&&(e%100<10||e%100>=20)?1:2)},5:function(e){return Number(0==e?0:1==e?1:2==e?2:e%100>=3&&e%100<=10?3:e%100>=11?4:5)},6:function(e){return Number(1==e?0:e>=2&&e<=4?1:2)},7:function(e){return Number(1==e?0:e%10>=2&&e%10<=4&&(e%100<10||e%100>=20)?1:2)},8:function(e){return Number(1==e?0:2==e?1:8!=e&&11!=e?2:3)},9:function(e){return Number(e>=2)},10:function(e){return Number(1==e?0:2==e?1:e<7?2:e<11?3:4)},11:function(e){return Number(1==e||11==e?0:2==e||12==e?1:e>2&&e<20?2:3)},12:function(e){return Number(e%10!=1||e%100==11)},13:function(e){return Number(0!==e)},14:function(e){return Number(1==e?0:2==e?1:3==e?2:3)},15:function(e){return Number(e%10==1&&e%100!=11?0:e%10>=2&&(e%100<10||e%100>=20)?1:2)},16:function(e){return Number(e%10==1&&e%100!=11?0:0!==e?1:2)},17:function(e){return Number(1==e||e%10==1&&e%100!=11?0:1)},18:function(e){return Number(0==e?0:1==e?1:2)},19:function(e){return Number(1==e?0:0==e||e%100>1&&e%100<11?1:e%100>10&&e%100<20?2:3)},20:function(e){return Number(1==e?0:0==e||e%100>0&&e%100<20?1:2)},21:function(e){return Number(e%100==1?1:e%100==2?2:e%100==3||e%100==4?3:0)},22:function(e){return Number(1==e?0:2==e?1:(e<0||e>10)&&e%10==0?2:3)}},O=["v1","v2","v3"],k=["v4"],Z={zero:0,one:1,two:2,few:3,many:4,other:5};class P{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.languageUtils=e,this.options=t,this.logger=i.create("pluralResolver"),(!this.options.compatibilityJSON||k.includes(this.options.compatibilityJSON))&&("undefined"==typeof Intl||!Intl.PluralRules)&&(this.options.compatibilityJSON="v3",this.logger.error("Your environment seems not to be Intl API compatible, use an Intl.PluralRules polyfill. Will fallback to the compatibilityJSON v3 format handling.")),this.rules=function(){let e={};return S.forEach(t=>{t.lngs.forEach(n=>{e[n]={numbers:t.nr,plurals:$[t.fc]}})}),e}()}addRule(e,t){this.rules[e]=t}getRule(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(this.shouldUseIntlApi())try{return new Intl.PluralRules(v(e),{type:t.ordinal?"ordinal":"cardinal"})}catch{return}return this.rules[e]||this.rules[this.languageUtils.getLanguagePartFromCode(e)]}needsPlural(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=this.getRule(e,t);return this.shouldUseIntlApi()?n&&n.resolvedOptions().pluralCategories.length>1:n&&n.numbers.length>1}getPluralFormsOfKey(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return this.getSuffixes(e,n).map(e=>`${t}${e}`)}getSuffixes(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=this.getRule(e,t);return n?this.shouldUseIntlApi()?n.resolvedOptions().pluralCategories.sort((e,t)=>Z[e]-Z[t]).map(e=>`${this.options.prepend}${t.ordinal?`ordinal${this.options.prepend}`:""}${e}`):n.numbers.map(n=>this.getSuffix(e,n,t)):[]}getSuffix(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=this.getRule(e,n);return r?this.shouldUseIntlApi()?`${this.options.prepend}${n.ordinal?`ordinal${this.options.prepend}`:""}${r.select(t)}`:this.getSuffixRetroCompatible(r,t):(this.logger.warn(`no plural rule found for: ${e}`),"")}getSuffixRetroCompatible(e,t){let n=e.noAbs?e.plurals(t):e.plurals(Math.abs(t)),r=e.numbers[n];this.options.simplifyPluralSuffix&&2===e.numbers.length&&1===e.numbers[0]&&(2===r?r="plural":1===r&&(r=""));let o=()=>this.options.prepend&&r.toString()?this.options.prepend+r.toString():r.toString();return"v1"===this.options.compatibilityJSON?1===r?"":"number"==typeof r?`_plural_${r.toString()}`:o():"v2"===this.options.compatibilityJSON||this.options.simplifyPluralSuffix&&2===e.numbers.length&&1===e.numbers[0]?o():this.options.prepend&&n.toString()?this.options.prepend+n.toString():n.toString()}shouldUseIntlApi(){return!O.includes(this.options.compatibilityJSON)}}function j(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:".",o=!(arguments.length>4)||void 0===arguments[4]||arguments[4],i=function(e,t,n){let r=f(e,n);return void 0!==r?r:f(t,n)}(e,t,n);return!i&&o&&"string"==typeof n&&void 0===(i=g(e,n,r))&&(i=g(t,n,r)),i}class _{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.logger=i.create("interpolator"),this.options=e,this.format=e.interpolation&&e.interpolation.format||(e=>e),this.init(e)}init(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e.interpolation||(e.interpolation={escapeValue:!0});let t=e.interpolation;this.escape=void 0!==t.escape?t.escape:h,this.escapeValue=void 0===t.escapeValue||t.escapeValue,this.useRawValueToEscape=void 0!==t.useRawValueToEscape&&t.useRawValueToEscape,this.prefix=t.prefix?d(t.prefix):t.prefixEscaped||"{{",this.suffix=t.suffix?d(t.suffix):t.suffixEscaped||"}}",this.formatSeparator=t.formatSeparator?t.formatSeparator:t.formatSeparator||",",this.unescapePrefix=t.unescapeSuffix?"":t.unescapePrefix||"-",this.unescapeSuffix=this.unescapePrefix?"":t.unescapeSuffix||"",this.nestingPrefix=t.nestingPrefix?d(t.nestingPrefix):t.nestingPrefixEscaped||d("$t("),this.nestingSuffix=t.nestingSuffix?d(t.nestingSuffix):t.nestingSuffixEscaped||d(")"),this.nestingOptionsSeparator=t.nestingOptionsSeparator?t.nestingOptionsSeparator:t.nestingOptionsSeparator||",",this.maxReplaces=t.maxReplaces?t.maxReplaces:1e3,this.alwaysFormat=void 0!==t.alwaysFormat&&t.alwaysFormat,this.resetRegExp()}reset(){this.options&&this.init(this.options)}resetRegExp(){let e=`${this.prefix}(.+?)${this.suffix}`;this.regexp=RegExp(e,"g");let t=`${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`;this.regexpUnescape=RegExp(t,"g");let n=`${this.nestingPrefix}(.+?)${this.nestingSuffix}`;this.nestingRegexp=RegExp(n,"g")}interpolate(e,t,n,r){let o,i,a;let l=this.options&&this.options.interpolation&&this.options.interpolation.defaultVariables||{};function c(e){return e.replace(/\$/g,"$$$$")}let u=e=>{if(0>e.indexOf(this.formatSeparator)){let o=j(t,l,e,this.options.keySeparator,this.options.ignoreJSONStructure);return this.alwaysFormat?this.format(o,void 0,n,{...r,...t,interpolationkey:e}):o}let o=e.split(this.formatSeparator),i=o.shift().trim(),a=o.join(this.formatSeparator).trim();return this.format(j(t,l,i,this.options.keySeparator,this.options.ignoreJSONStructure),a,n,{...r,...t,interpolationkey:i})};this.resetRegExp();let f=r&&r.missingInterpolationHandler||this.options.missingInterpolationHandler,d=r&&r.interpolation&&void 0!==r.interpolation.skipOnVariables?r.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables,p=[{regex:this.regexpUnescape,safeValue:e=>c(e)},{regex:this.regexp,safeValue:e=>this.escapeValue?c(this.escape(e)):c(e)}];return p.forEach(t=>{for(a=0;o=t.regex.exec(e);){let n=o[1].trim();if(void 0===(i=u(n))){if("function"==typeof f){let t=f(e,o,r);i="string"==typeof t?t:""}else if(r&&Object.prototype.hasOwnProperty.call(r,n))i="";else if(d){i=o[0];continue}else this.logger.warn(`missed to pass in variable ${n} for interpolating ${e}`),i=""}else"string"==typeof i||this.useRawValueToEscape||(i=s(i));let l=t.safeValue(i);if(e=e.replace(o[0],l),d?(t.regex.lastIndex+=i.length,t.regex.lastIndex-=o[0].length):t.regex.lastIndex=0,++a>=this.maxReplaces)break}}),e}nest(e,t){let n,r,o,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};function a(e,t){let n=this.nestingOptionsSeparator;if(0>e.indexOf(n))return e;let r=e.split(RegExp(`${n}[ ]*{`)),i=`{${r[1]}`;e=r[0],i=this.interpolate(i,o);let a=i.match(/'/g),l=i.match(/"/g);(a&&a.length%2==0&&!l||l.length%2!=0)&&(i=i.replace(/'/g,'"'));try{o=JSON.parse(i),t&&(o={...t,...o})}catch(t){return this.logger.warn(`failed parsing options string in nesting for key ${e}`,t),`${e}${n}${i}`}return delete o.defaultValue,e}for(;n=this.nestingRegexp.exec(e);){let l=[];(o=(o={...i}).replace&&"string"!=typeof o.replace?o.replace:o).applyPostProcessor=!1,delete o.defaultValue;let c=!1;if(-1!==n[0].indexOf(this.formatSeparator)&&!/{.*}/.test(n[1])){let e=n[1].split(this.formatSeparator).map(e=>e.trim());n[1]=e.shift(),l=e,c=!0}if((r=t(a.call(this,n[1].trim(),o),o))&&n[0]===e&&"string"!=typeof r)return r;"string"!=typeof r&&(r=s(r)),r||(this.logger.warn(`missed to resolve ${n[1]} for nesting ${e}`),r=""),c&&(r=l.reduce((e,t)=>this.format(e,t,i.lng,{...i,interpolationkey:n[1].trim()}),r.trim())),e=e.replace(n[0],r),this.regexp.lastIndex=0}return e}}function R(e){let t={};return function(n,r,o){let i=r+JSON.stringify(o),a=t[i];return a||(a=e(v(r),o),t[i]=a),a(n)}}class A{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.logger=i.create("formatter"),this.options=e,this.formats={number:R((e,t)=>{let n=new Intl.NumberFormat(e,{...t});return e=>n.format(e)}),currency:R((e,t)=>{let n=new Intl.NumberFormat(e,{...t,style:"currency"});return e=>n.format(e)}),datetime:R((e,t)=>{let n=new Intl.DateTimeFormat(e,{...t});return e=>n.format(e)}),relativetime:R((e,t)=>{let n=new Intl.RelativeTimeFormat(e,{...t});return e=>n.format(e,t.range||"day")}),list:R((e,t)=>{let n=new Intl.ListFormat(e,{...t});return e=>n.format(e)})},this.init(e)}init(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{interpolation:{}},n=t.interpolation;this.formatSeparator=n.formatSeparator?n.formatSeparator:n.formatSeparator||","}add(e,t){this.formats[e.toLowerCase().trim()]=t}addCached(e,t){this.formats[e.toLowerCase().trim()]=R(t)}format(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},o=t.split(this.formatSeparator),i=o.reduce((e,t)=>{let{formatName:o,formatOptions:i}=function(e){let t=e.toLowerCase().trim(),n={};if(e.indexOf("(")>-1){let r=e.split("(");t=r[0].toLowerCase().trim();let o=r[1].substring(0,r[1].length-1);if("currency"===t&&0>o.indexOf(":"))n.currency||(n.currency=o.trim());else if("relativetime"===t&&0>o.indexOf(":"))n.range||(n.range=o.trim());else{let e=o.split(";");e.forEach(e=>{if(!e)return;let[t,...r]=e.split(":"),o=r.join(":").trim().replace(/^'+|'+$/g,"");n[t.trim()]||(n[t.trim()]=o),"false"===o&&(n[t.trim()]=!1),"true"===o&&(n[t.trim()]=!0),isNaN(o)||(n[t.trim()]=parseInt(o,10))})}}return{formatName:t,formatOptions:n}}(t);if(this.formats[o]){let t=e;try{let a=r&&r.formatParams&&r.formatParams[r.interpolationkey]||{},l=a.locale||a.lng||r.locale||r.lng||n;t=this.formats[o](e,l,{...i,...r,...a})}catch(e){this.logger.warn(e)}return t}return this.logger.warn(`there was no format function for ${o}`),e},e);return i}}class N extends a{constructor(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};super(),this.backend=e,this.store=t,this.services=n,this.languageUtils=n.languageUtils,this.options=r,this.logger=i.create("backendConnector"),this.waitingReads=[],this.maxParallelReads=r.maxParallelReads||10,this.readingCalls=0,this.maxRetries=r.maxRetries>=0?r.maxRetries:5,this.retryTimeout=r.retryTimeout>=1?r.retryTimeout:350,this.state={},this.queue=[],this.backend&&this.backend.init&&this.backend.init(n,r.backend,r)}queueLoad(e,t,n,r){let o={},i={},a={},l={};return e.forEach(e=>{let r=!0;t.forEach(t=>{let a=`${e}|${t}`;!n.reload&&this.store.hasResourceBundle(e,t)?this.state[a]=2:this.state[a]<0||(1===this.state[a]?void 0===i[a]&&(i[a]=!0):(this.state[a]=1,r=!1,void 0===i[a]&&(i[a]=!0),void 0===o[a]&&(o[a]=!0),void 0===l[t]&&(l[t]=!0)))}),r||(a[e]=!0)}),(Object.keys(o).length||Object.keys(i).length)&&this.queue.push({pending:i,pendingCount:Object.keys(i).length,loaded:{},errors:[],callback:r}),{toLoad:Object.keys(o),pending:Object.keys(i),toLoadLanguages:Object.keys(a),toLoadNamespaces:Object.keys(l)}}loaded(e,t,n){let r=e.split("|"),o=r[0],i=r[1];t&&this.emit("failedLoading",o,i,t),n&&this.store.addResourceBundle(o,i,n),this.state[e]=t?-1:2;let a={};this.queue.forEach(n=>{(function(e,t,n,r){let{obj:o,k:i}=c(e,t,Object);o[i]=o[i]||[],r&&(o[i]=o[i].concat(n)),r||o[i].push(n)})(n.loaded,[o],i),void 0!==n.pending[e]&&(delete n.pending[e],n.pendingCount--),t&&n.errors.push(t),0!==n.pendingCount||n.done||(Object.keys(n.loaded).forEach(e=>{a[e]||(a[e]={});let t=n.loaded[e];t.length&&t.forEach(t=>{void 0===a[e][t]&&(a[e][t]=!0)})}),n.done=!0,n.errors.length?n.callback(n.errors):n.callback())}),this.emit("loaded",a),this.queue=this.queue.filter(e=>!e.done)}read(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:this.retryTimeout,i=arguments.length>5?arguments[5]:void 0;if(!e.length)return i(null,{});if(this.readingCalls>=this.maxParallelReads){this.waitingReads.push({lng:e,ns:t,fcName:n,tried:r,wait:o,callback:i});return}this.readingCalls++;let a=(a,l)=>{if(this.readingCalls--,this.waitingReads.length>0){let e=this.waitingReads.shift();this.read(e.lng,e.ns,e.fcName,e.tried,e.wait,e.callback)}if(a&&l&&r{this.read.call(this,e,t,n,r+1,2*o,i)},o);return}i(a,l)},l=this.backend[n].bind(this.backend);if(2===l.length){try{let n=l(e,t);n&&"function"==typeof n.then?n.then(e=>a(null,e)).catch(a):a(null,n)}catch(e){a(e)}return}return l(e,t,a)}prepareLoading(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=arguments.length>3?arguments[3]:void 0;if(!this.backend)return this.logger.warn("No backend was added via i18next.use. Will not load resources."),r&&r();"string"==typeof e&&(e=this.languageUtils.toResolveHierarchy(e)),"string"==typeof t&&(t=[t]);let o=this.queueLoad(e,t,n,r);if(!o.toLoad.length)return o.pending.length||r(),null;o.toLoad.forEach(e=>{this.loadOne(e)})}load(e,t,n){this.prepareLoading(e,t,{},n)}reload(e,t,n){this.prepareLoading(e,t,{reload:!0},n)}loadOne(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=e.split("|"),r=n[0],o=n[1];this.read(r,o,"read",void 0,void 0,(n,i)=>{n&&this.logger.warn(`${t}loading namespace ${o} for language ${r} failed`,n),!n&&i&&this.logger.log(`${t}loaded namespace ${o} for language ${r}`,i),this.loaded(e,n,i)})}saveMissing(e,t,n,r,o){let i=arguments.length>5&&void 0!==arguments[5]?arguments[5]:{},a=arguments.length>6&&void 0!==arguments[6]?arguments[6]:()=>{};if(this.services.utils&&this.services.utils.hasLoadedNamespace&&!this.services.utils.hasLoadedNamespace(t)){this.logger.warn(`did not save key "${n}" as the namespace "${t}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!");return}if(null!=n&&""!==n){if(this.backend&&this.backend.create){let l={...i,isUpdate:o},s=this.backend.create.bind(this.backend);if(s.length<6)try{let o;(o=5===s.length?s(e,t,n,r,l):s(e,t,n,r))&&"function"==typeof o.then?o.then(e=>a(null,e)).catch(a):a(null,o)}catch(e){a(e)}else s(e,t,n,r,a,l)}e&&e[0]&&this.store.addResource(e[0],t,n,r)}}}function T(){return{debug:!1,initImmediate:!0,ns:["translation"],defaultNS:["translation"],fallbackLng:["dev"],fallbackNS:!1,supportedLngs:!1,nonExplicitSupportedLngs:!1,load:"all",preload:!1,simplifyPluralSuffix:!0,keySeparator:".",nsSeparator:":",pluralSeparator:"_",contextSeparator:"_",partialBundledLanguages:!1,saveMissing:!1,updateMissing:!1,saveMissingTo:"fallback",saveMissingPlurals:!0,missingKeyHandler:!1,missingInterpolationHandler:!1,postProcess:!1,postProcessPassResolved:!1,returnNull:!1,returnEmptyString:!0,returnObjects:!1,joinArrays:!1,returnedObjectHandler:!1,parseMissingKeyHandler:!1,appendNamespaceToMissingKey:!1,appendNamespaceToCIMode:!1,overloadTranslationOptionHandler:function(e){let t={};if("object"==typeof e[1]&&(t=e[1]),"string"==typeof e[1]&&(t.defaultValue=e[1]),"string"==typeof e[2]&&(t.tDescription=e[2]),"object"==typeof e[2]||"object"==typeof e[3]){let n=e[3]||e[2];Object.keys(n).forEach(e=>{t[e]=n[e]})}return t},interpolation:{escapeValue:!0,format:(e,t,n,r)=>e,prefix:"{{",suffix:"}}",formatSeparator:",",unescapePrefix:"-",nestingPrefix:"$t(",nestingSuffix:")",nestingOptionsSeparator:",",maxReplaces:1e3,skipOnVariables:!0}}}function M(e){return"string"==typeof e.ns&&(e.ns=[e.ns]),"string"==typeof e.fallbackLng&&(e.fallbackLng=[e.fallbackLng]),"string"==typeof e.fallbackNS&&(e.fallbackNS=[e.fallbackNS]),e.supportedLngs&&0>e.supportedLngs.indexOf("cimode")&&(e.supportedLngs=e.supportedLngs.concat(["cimode"])),e}function I(){}class F extends a{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0;if(super(),this.options=M(e),this.services={},this.logger=i,this.modules={external:[]},!function(e){let t=Object.getOwnPropertyNames(Object.getPrototypeOf(e));t.forEach(t=>{"function"==typeof e[t]&&(e[t]=e[t].bind(e))})}(this),t&&!this.isInitialized&&!e.isClone){if(!this.options.initImmediate)return this.init(e,t),this;setTimeout(()=>{this.init(e,t)},0)}}init(){var e=this;let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=arguments.length>1?arguments[1]:void 0;"function"==typeof t&&(n=t,t={}),!t.defaultNS&&!1!==t.defaultNS&&t.ns&&("string"==typeof t.ns?t.defaultNS=t.ns:0>t.ns.indexOf("translation")&&(t.defaultNS=t.ns[0]));let r=T();function o(e){return e?"function"==typeof e?new e:e:null}if(this.options={...r,...this.options,...M(t)},"v1"!==this.options.compatibilityAPI&&(this.options.interpolation={...r.interpolation,...this.options.interpolation}),void 0!==t.keySeparator&&(this.options.userDefinedKeySeparator=t.keySeparator),void 0!==t.nsSeparator&&(this.options.userDefinedNsSeparator=t.nsSeparator),!this.options.isClone){let t;this.modules.logger?i.init(o(this.modules.logger),this.options):i.init(null,this.options),this.modules.formatter?t=this.modules.formatter:"undefined"!=typeof Intl&&(t=A);let n=new E(this.options);this.store=new y(this.options.resources,this.options);let a=this.services;a.logger=i,a.resourceStore=this.store,a.languageUtils=n,a.pluralResolver=new P(n,{prepend:this.options.pluralSeparator,compatibilityJSON:this.options.compatibilityJSON,simplifyPluralSuffix:this.options.simplifyPluralSuffix}),t&&(!this.options.interpolation.format||this.options.interpolation.format===r.interpolation.format)&&(a.formatter=o(t),a.formatter.init(a,this.options),this.options.interpolation.format=a.formatter.format.bind(a.formatter)),a.interpolator=new _(this.options),a.utils={hasLoadedNamespace:this.hasLoadedNamespace.bind(this)},a.backendConnector=new N(o(this.modules.backend),a.resourceStore,a,this.options),a.backendConnector.on("*",function(t){for(var n=arguments.length,r=Array(n>1?n-1:0),o=1;o1?n-1:0),o=1;o{e.init&&e.init(this)})}if(this.format=this.options.interpolation.format,n||(n=I),this.options.fallbackLng&&!this.services.languageDetector&&!this.options.lng){let e=this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);e.length>0&&"dev"!==e[0]&&(this.options.lng=e[0])}this.services.languageDetector||this.options.lng||this.logger.warn("init: no languageDetector is used and no lng is defined"),["getResource","hasResourceBundle","getResourceBundle","getDataByLanguage"].forEach(t=>{this[t]=function(){return e.store[t](...arguments)}}),["addResource","addResources","addResourceBundle","removeResourceBundle"].forEach(t=>{this[t]=function(){return e.store[t](...arguments),e}});let a=l(),s=()=>{let e=(e,t)=>{this.isInitialized&&!this.initializedStoreOnce&&this.logger.warn("init: i18next is already initialized. You should call init just once!"),this.isInitialized=!0,this.options.isClone||this.logger.log("initialized",this.options),this.emit("initialized",this.options),a.resolve(t),n(e,t)};if(this.languages&&"v1"!==this.options.compatibilityAPI&&!this.isInitialized)return e(null,this.t.bind(this));this.changeLanguage(this.options.lng,e)};return this.options.resources||!this.options.initImmediate?s():setTimeout(s,0),a}loadResources(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:I,n=t,r="string"==typeof e?e:this.language;if("function"==typeof e&&(n=e),!this.options.resources||this.options.partialBundledLanguages){if(r&&"cimode"===r.toLowerCase()&&(!this.options.preload||0===this.options.preload.length))return n();let e=[],t=t=>{if(!t||"cimode"===t)return;let n=this.services.languageUtils.toResolveHierarchy(t);n.forEach(t=>{"cimode"!==t&&0>e.indexOf(t)&&e.push(t)})};if(r)t(r);else{let e=this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);e.forEach(e=>t(e))}this.options.preload&&this.options.preload.forEach(e=>t(e)),this.services.backendConnector.load(e,this.options.ns,e=>{e||this.resolvedLanguage||!this.language||this.setResolvedLanguage(this.language),n(e)})}else n(null)}reloadResources(e,t,n){let r=l();return e||(e=this.languages),t||(t=this.options.ns),n||(n=I),this.services.backendConnector.reload(e,t,e=>{r.resolve(),n(e)}),r}use(e){if(!e)throw Error("You are passing an undefined module! Please check the object you are passing to i18next.use()");if(!e.type)throw Error("You are passing a wrong module! Please check the object you are passing to i18next.use()");return"backend"===e.type&&(this.modules.backend=e),("logger"===e.type||e.log&&e.warn&&e.error)&&(this.modules.logger=e),"languageDetector"===e.type&&(this.modules.languageDetector=e),"i18nFormat"===e.type&&(this.modules.i18nFormat=e),"postProcessor"===e.type&&b.addPostProcessor(e),"formatter"===e.type&&(this.modules.formatter=e),"3rdParty"===e.type&&this.modules.external.push(e),this}setResolvedLanguage(e){if(e&&this.languages&&!(["cimode","dev"].indexOf(e)>-1))for(let e=0;e-1)&&this.store.hasLanguageSomeTranslations(t)){this.resolvedLanguage=t;break}}}changeLanguage(e,t){var n=this;this.isLanguageChangingTo=e;let r=l();this.emit("languageChanging",e);let o=e=>{this.language=e,this.languages=this.services.languageUtils.toResolveHierarchy(e),this.resolvedLanguage=void 0,this.setResolvedLanguage(e)},i=(e,i)=>{i?(o(i),this.translator.changeLanguage(i),this.isLanguageChangingTo=void 0,this.emit("languageChanged",i),this.logger.log("languageChanged",i)):this.isLanguageChangingTo=void 0,r.resolve(function(){return n.t(...arguments)}),t&&t(e,function(){return n.t(...arguments)})},a=t=>{e||t||!this.services.languageDetector||(t=[]);let n="string"==typeof t?t:this.services.languageUtils.getBestMatchFromCodes(t);n&&(this.language||o(n),this.translator.language||this.translator.changeLanguage(n),this.services.languageDetector&&this.services.languageDetector.cacheUserLanguage&&this.services.languageDetector.cacheUserLanguage(n)),this.loadResources(n,e=>{i(e,n)})};return e||!this.services.languageDetector||this.services.languageDetector.async?!e&&this.services.languageDetector&&this.services.languageDetector.async?0===this.services.languageDetector.detect.length?this.services.languageDetector.detect().then(a):this.services.languageDetector.detect(a):a(e):a(this.services.languageDetector.detect()),r}getFixedT(e,t,n){var r=this;let o=function(e,t){let i,a;if("object"!=typeof t){for(var l=arguments.length,s=Array(l>2?l-2:0),c=2;c`${i.keyPrefix}${u}${e}`):i.keyPrefix?`${i.keyPrefix}${u}${e}`:e,r.t(a,i)};return"string"==typeof e?o.lng=e:o.lngs=e,o.ns=t,o.keyPrefix=n,o}t(){return this.translator&&this.translator.translate(...arguments)}exists(){return this.translator&&this.translator.exists(...arguments)}setDefaultNamespace(e){this.options.defaultNS=e}hasLoadedNamespace(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!this.isInitialized)return this.logger.warn("hasLoadedNamespace: i18next was not initialized",this.languages),!1;if(!this.languages||!this.languages.length)return this.logger.warn("hasLoadedNamespace: i18n.languages were undefined or empty",this.languages),!1;let n=t.lng||this.resolvedLanguage||this.languages[0],r=!!this.options&&this.options.fallbackLng,o=this.languages[this.languages.length-1];if("cimode"===n.toLowerCase())return!0;let i=(e,t)=>{let n=this.services.backendConnector.state[`${e}|${t}`];return -1===n||2===n};if(t.precheck){let e=t.precheck(this,i);if(void 0!==e)return e}return!!(this.hasResourceBundle(n,e)||!this.services.backendConnector.backend||this.options.resources&&!this.options.partialBundledLanguages||i(n,e)&&(!r||i(o,e)))}loadNamespaces(e,t){let n=l();return this.options.ns?("string"==typeof e&&(e=[e]),e.forEach(e=>{0>this.options.ns.indexOf(e)&&this.options.ns.push(e)}),this.loadResources(e=>{n.resolve(),t&&t(e)}),n):(t&&t(),Promise.resolve())}loadLanguages(e,t){let n=l();"string"==typeof e&&(e=[e]);let r=this.options.preload||[],o=e.filter(e=>0>r.indexOf(e));return o.length?(this.options.preload=r.concat(o),this.loadResources(e=>{n.resolve(),t&&t(e)}),n):(t&&t(),Promise.resolve())}dir(e){if(e||(e=this.resolvedLanguage||(this.languages&&this.languages.length>0?this.languages[0]:this.language)),!e)return"rtl";let t=this.services&&this.services.languageUtils||new E(T());return["ar","shu","sqr","ssh","xaa","yhd","yud","aao","abh","abv","acm","acq","acw","acx","acy","adf","ads","aeb","aec","afb","ajp","apc","apd","arb","arq","ars","ary","arz","auz","avl","ayh","ayl","ayn","ayp","bbz","pga","he","iw","ps","pbt","pbu","pst","prp","prd","ug","ur","ydd","yds","yih","ji","yi","hbo","men","xmn","fa","jpr","peo","pes","prs","dv","sam","ckb"].indexOf(t.getLanguagePartFromCode(e))>-1||e.toLowerCase().indexOf("-arab")>1?"rtl":"ltr"}static createInstance(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0;return new F(e,t)}cloneInstance(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:I,n=e.forkResourceStore;n&&delete e.forkResourceStore;let r={...this.options,...e,isClone:!0},o=new F(r);return(void 0!==e.debug||void 0!==e.prefix)&&(o.logger=o.logger.clone(e)),["store","services","language"].forEach(e=>{o[e]=this[e]}),o.services={...this.services},o.services.utils={hasLoadedNamespace:o.hasLoadedNamespace.bind(o)},n&&(o.store=new y(this.store.data,r),o.services.resourceStore=o.store),o.translator=new w(o.services,r),o.translator.on("*",function(e){for(var t=arguments.length,n=Array(t>1?t-1:0),r=1;r{let{componentCls:t,width:n,notificationMarginEdge:r}=e,o=new y.E4("antNotificationTopFadeIn",{"0%":{marginTop:"-100%",opacity:0},"100%":{marginTop:0,opacity:1}}),i=new y.E4("antNotificationBottomFadeIn",{"0%":{marginBottom:"-100%",opacity:0},"100%":{marginBottom:0,opacity:1}}),a=new y.E4("antNotificationLeftFadeIn",{"0%":{right:{_skip_check_:!0,value:n},opacity:0},"100%":{right:{_skip_check_:!0,value:0},opacity:1}});return{[`&${t}-top, &${t}-bottom`]:{marginInline:0},[`&${t}-top`]:{[`${t}-fade-enter${t}-fade-enter-active, ${t}-fade-appear${t}-fade-appear-active`]:{animationName:o}},[`&${t}-bottom`]:{[`${t}-fade-enter${t}-fade-enter-active, ${t}-fade-appear${t}-fade-appear-active`]:{animationName:i}},[`&${t}-topLeft, &${t}-bottomLeft`]:{marginInlineEnd:0,marginInlineStart:r,[`${t}-fade-enter${t}-fade-enter-active, ${t}-fade-appear${t}-fade-appear-active`]:{animationName:a}}}};let E=e=>{let{iconCls:t,componentCls:n,boxShadow:r,fontSizeLG:o,notificationMarginBottom:i,borderRadiusLG:a,colorSuccess:l,colorInfo:s,colorWarning:c,colorError:u,colorTextHeading:f,notificationBg:d,notificationPadding:p,notificationMarginEdge:h,motionDurationMid:m,motionEaseInOut:g,fontSize:v,lineHeight:x,width:w,notificationIconSize:E,colorText:S}=e,$=`${n}-notice`,O=new y.E4("antNotificationFadeIn",{"0%":{left:{_skip_check_:!0,value:w},opacity:0},"100%":{left:{_skip_check_:!0,value:0},opacity:1}}),k=new y.E4("antNotificationFadeOut",{"0%":{maxHeight:e.animationMaxHeight,marginBottom:i,opacity:1},"100%":{maxHeight:0,marginBottom:0,paddingTop:0,paddingBottom:0,opacity:0}}),Z={position:"relative",width:w,maxWidth:`calc(100vw - ${2*h}px)`,marginBottom:i,marginInlineStart:"auto",padding:p,overflow:"hidden",lineHeight:x,wordWrap:"break-word",background:d,borderRadius:a,boxShadow:r,[`${n}-close-icon`]:{fontSize:v,cursor:"pointer"},[`${$}-message`]:{marginBottom:e.marginXS,color:f,fontSize:o,lineHeight:e.lineHeightLG},[`${$}-description`]:{fontSize:v,color:S},[`&${$}-closable ${$}-message`]:{paddingInlineEnd:e.paddingLG},[`${$}-with-icon ${$}-message`]:{marginBottom:e.marginXS,marginInlineStart:e.marginSM+E,fontSize:o},[`${$}-with-icon ${$}-description`]:{marginInlineStart:e.marginSM+E,fontSize:v},[`${$}-icon`]:{position:"absolute",fontSize:E,lineHeight:0,[`&-success${t}`]:{color:l},[`&-info${t}`]:{color:s},[`&-warning${t}`]:{color:c},[`&-error${t}`]:{color:u}},[`${$}-close`]:{position:"absolute",top:e.notificationPaddingVertical,insetInlineEnd:e.notificationPaddingHorizontal,color:e.colorIcon,outline:"none",width:e.notificationCloseButtonSize,height:e.notificationCloseButtonSize,borderRadius:e.borderRadiusSM,transition:`background-color ${e.motionDurationMid}, color ${e.motionDurationMid}`,display:"flex",alignItems:"center",justifyContent:"center","&:hover":{color:e.colorIconHover,backgroundColor:e.wireframe?"transparent":e.colorFillContent}},[`${$}-btn`]:{float:"right",marginTop:e.marginSM}};return[{[n]:Object.assign(Object.assign(Object.assign(Object.assign({},(0,b.Wf)(e)),{position:"fixed",zIndex:e.zIndexPopup,marginInlineEnd:h,[`${n}-hook-holder`]:{position:"relative"},[`&${n}-top, &${n}-bottom`]:{[$]:{marginInline:"auto auto"}},[`&${n}-topLeft, &${n}-bottomLeft`]:{[$]:{marginInlineEnd:"auto",marginInlineStart:0}},[`${n}-fade-enter, ${n}-fade-appear`]:{animationDuration:e.motionDurationMid,animationTimingFunction:g,animationFillMode:"both",opacity:0,animationPlayState:"paused"},[`${n}-fade-leave`]:{animationTimingFunction:g,animationFillMode:"both",animationDuration:m,animationPlayState:"paused"},[`${n}-fade-enter${n}-fade-enter-active, ${n}-fade-appear${n}-fade-appear-active`]:{animationName:O,animationPlayState:"running"},[`${n}-fade-leave${n}-fade-leave-active`]:{animationName:k,animationPlayState:"running"}}),C(e)),{"&-rtl":{direction:"rtl",[`${$}-btn`]:{float:"left"}}})},{[n]:{[$]:Object.assign({},Z)}},{[`${$}-pure-panel`]:Object.assign(Object.assign({},Z),{margin:0})}]};var S=(0,x.Z)("Notification",e=>{let t=e.paddingMD,n=e.paddingLG,r=(0,w.TS)(e,{notificationBg:e.colorBgElevated,notificationPaddingVertical:t,notificationPaddingHorizontal:n,notificationIconSize:e.fontSizeLG*e.lineHeightLG,notificationCloseButtonSize:.55*e.controlHeightLG,notificationMarginBottom:e.margin,notificationPadding:`${e.paddingMD}px ${e.paddingContentHorizontalLG}px`,notificationMarginEdge:e.marginLG,animationMaxHeight:150});return[E(r)]},e=>({zIndexPopup:e.zIndexPopupBase+50,width:384})),$=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&0>t.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,r=Object.getOwnPropertySymbols(e);ot.indexOf(r[o])&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]]);return n};function O(e,t){return null===t||!1===t?null:t||i.createElement("span",{className:`${e}-close-x`},i.createElement(u.Z,{className:`${e}-close-icon`}))}d.Z,s.Z,c.Z,f.Z,p.Z;let k={success:s.Z,info:d.Z,error:c.Z,warning:f.Z},Z=e=>{let{prefixCls:t,icon:n,type:r,message:o,description:a,btn:l,role:s="alert"}=e,c=null;return n?c=i.createElement("span",{className:`${t}-icon`},n):r&&(c=i.createElement(k[r]||null,{className:m()(`${t}-icon`,`${t}-icon-${r}`)})),i.createElement("div",{className:m()({[`${t}-with-icon`]:c}),role:s},c,i.createElement("div",{className:`${t}-message`},o),i.createElement("div",{className:`${t}-description`},a),l&&i.createElement("div",{className:`${t}-btn`},l))};var P=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&0>t.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,r=Object.getOwnPropertySymbols(e);ot.indexOf(r[o])&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]]);return n};let j=e=>{let{children:t,prefixCls:n}=e,[,r]=S(n);return i.createElement(g.JB,{classNames:{list:r,notice:r}},t)},_=(e,t)=>{let{prefixCls:n,key:r}=t;return i.createElement(j,{prefixCls:n,key:r},e)},R=i.forwardRef((e,t)=>{let{top:n,bottom:r,prefixCls:o,getContainer:a,maxCount:l,rtl:s,onAllRemoved:c}=e,{getPrefixCls:u,getPopupContainer:f,notification:d}=i.useContext(v.E_),p=o||u("notification"),[h,y]=(0,g.lm)({prefixCls:p,style:e=>(function(e,t,n){let r;switch(e){case"top":r={left:"50%",transform:"translateX(-50%)",right:"auto",top:t,bottom:"auto"};break;case"topLeft":r={left:0,top:t,bottom:"auto"};break;case"topRight":r={right:0,top:t,bottom:"auto"};break;case"bottom":r={left:"50%",transform:"translateX(-50%)",right:"auto",top:"auto",bottom:n};break;case"bottomLeft":r={left:0,top:"auto",bottom:n};break;default:r={right:0,top:"auto",bottom:n}}return r})(e,null!=n?n:24,null!=r?r:24),className:()=>m()({[`${p}-rtl`]:s}),motion:()=>({motionName:`${p}-fade`}),closable:!0,closeIcon:O(p),duration:4.5,getContainer:()=>(null==a?void 0:a())||(null==f?void 0:f())||document.body,maxCount:l,onAllRemoved:c,renderNotifications:_});return i.useImperativeHandle(t,()=>Object.assign(Object.assign({},h),{prefixCls:p,notification:d})),y});function A(e){let t=i.useRef(null),n=i.useMemo(()=>{let n=n=>{var r;if(!t.current)return;let{open:o,prefixCls:a,notification:l}=t.current,s=`${a}-notice`,{message:c,description:u,icon:f,type:d,btn:p,className:h,style:g,role:v="alert",closeIcon:y}=n,b=P(n,["message","description","icon","type","btn","className","style","role","closeIcon"]),x=O(s,y);return o(Object.assign(Object.assign({placement:null!==(r=null==e?void 0:e.placement)&&void 0!==r?r:"topRight"},b),{content:i.createElement(Z,{prefixCls:s,icon:f,type:d,message:c,description:u,btn:p,role:v}),className:m()(d&&`${s}-${d}`,h,null==l?void 0:l.className),style:Object.assign(Object.assign({},null==l?void 0:l.style),g),closeIcon:x,closable:!!x}))},r={open:n,destroy:e=>{var n,r;void 0!==e?null===(n=t.current)||void 0===n||n.close(e):null===(r=t.current)||void 0===r||r.destroy()}};return["success","info","warning","error"].forEach(e=>{r[e]=t=>n(Object.assign(Object.assign({},t),{type:e}))}),r},[]);return[n,i.createElement(R,Object.assign({key:"notification-holder"},e,{ref:t}))]}let N=null,T=e=>e(),M=[],I={};function F(){let{prefixCls:e,getContainer:t,rtl:n,maxCount:r,top:o,bottom:i}=I,a=null!=e?e:(0,l.w6)().getPrefixCls("notification"),s=(null==t?void 0:t())||document.body;return{prefixCls:a,getContainer:()=>s,rtl:n,maxCount:r,top:o,bottom:i}}let L=i.forwardRef((e,t)=>{let[n,r]=i.useState(F),[o,a]=A(n),s=(0,l.w6)(),c=s.getRootPrefixCls(),u=s.getIconPrefixCls(),f=s.getTheme(),d=()=>{r(F)};return i.useEffect(d,[]),i.useImperativeHandle(t,()=>{let e=Object.assign({},o);return Object.keys(e).forEach(t=>{e[t]=function(){return d(),o[t].apply(o,arguments)}}),{instance:e,sync:d}}),i.createElement(l.ZP,{prefixCls:c,iconPrefixCls:u,theme:f},a)});function B(){if(!N){let e=document.createDocumentFragment(),t={fragment:e};N=t,T(()=>{(0,a.s)(i.createElement(L,{ref:e=>{let{instance:n,sync:r}=e||{};Promise.resolve().then(()=>{!t.instance&&n&&(t.instance=n,t.sync=r,B())})}}),e)});return}N.instance&&(M.forEach(e=>{switch(e.type){case"open":T(()=>{N.instance.open(Object.assign(Object.assign({},I),e.config))});break;case"destroy":T(()=>{null==N||N.instance.destroy(e.key)})}}),M=[])}function D(e){M.push({type:"open",config:e}),B()}let z={open:D,destroy:function(e){M.push({type:"destroy",key:e}),B()},config:function(e){I=Object.assign(Object.assign({},I),e),T(()=>{var e;null===(e=null==N?void 0:N.sync)||void 0===e||e.call(N)})},useNotification:function(e){return A(e)},_InternalPanelDoNotUseOrYouWillBeFired:e=>{let{prefixCls:t,className:n,icon:r,type:o,message:a,description:l,btn:s,closable:c=!0,closeIcon:u}=e,f=$(e,["prefixCls","className","icon","type","message","description","btn","closable","closeIcon"]),{getPrefixCls:d}=i.useContext(v.E_),p=t||d("notification"),h=`${p}-notice`,[,y]=S(p);return i.createElement(g.qX,Object.assign({},f,{prefixCls:p,className:m()(n,y,`${h}-pure-panel`),eventKey:"pure",duration:null,closable:c,closeIcon:O(p,u),content:i.createElement(Z,{prefixCls:h,icon:r,type:o,message:a,description:l,btn:s})}))}};["success","info","warning","error"].forEach(e=>{z[e]=t=>D(Object.assign(Object.assign({},t),{type:e}))});let H=(e,t)=>e.then(e=>{let{data:n}=e;if(!n)throw Error("Network Error!");if(!n.success){if("*"===t||n.err_code&&t&&t.includes(n.err_code));else{var r;z.error({message:"Request error",description:null!==(r=null==n?void 0:n.err_msg)&&void 0!==r?r:"The interface is abnormal. Please try again later"})}}return[null,n.data,n,e]}).catch(e=>(z.error({message:"Request error",description:e.message}),[e,null,null,null])),V=()=>e_("/api/v1/chat/dialogue/scenes"),U=e=>e_("/api/v1/chat/dialogue/new",e),W=()=>ej("/api/v1/chat/db/list"),K=()=>ej("/api/v1/chat/db/support/type"),q=e=>e_("/api/v1/chat/db/delete?db_name=".concat(e)),G=e=>e_("/api/v1/chat/db/edit",e),X=e=>e_("/api/v1/chat/db/add",e),Y=e=>e_("/api/v1/chat/db/test/connect",e),J=()=>ej("/api/v1/chat/dialogue/list"),Q=()=>ej("/api/v1/model/types"),ee=e=>e_("/api/v1/chat/mode/params/list?chat_mode=".concat(e)),et=e=>ej("/api/v1/chat/dialogue/messages/history?con_uid=".concat(e)),en=e=>{let{convUid:t,chatMode:n,data:r,config:o,model:i}=e;return e_("/api/v1/chat/mode/params/file/load?conv_uid=".concat(t,"&chat_mode=").concat(n,"&model_name=").concat(i),r,{headers:{"Content-Type":"multipart/form-data"},...o})},er=e=>e_("/api/v1/chat/dialogue/delete?con_uid=".concat(e)),eo=e=>e_("/knowledge/".concat(e,"/arguments"),{}),ei=(e,t)=>e_("/knowledge/".concat(e,"/argument/save"),t),ea=()=>e_("/knowledge/space/list",{}),el=(e,t)=>e_("/knowledge/".concat(e,"/document/list"),t),es=(e,t)=>e_("/knowledge/".concat(e,"/document/add"),t),ec=e=>e_("/knowledge/space/add",e),eu=(e,t)=>e_("/knowledge/".concat(e,"/document/sync"),t),ef=(e,t)=>e_("/knowledge/".concat(e,"/document/upload"),t),ed=(e,t)=>e_("/knowledge/".concat(e,"/chunk/list"),t),ep=(e,t)=>e_("/knowledge/".concat(e,"/document/delete"),t),eh=e=>e_("/knowledge/space/delete",e),em=()=>ej("/api/v1/worker/model/list"),eg=e=>e_("/api/v1/worker/model/stop",e),ev=e=>e_("/api/v1/worker/model/start",e),ey=()=>ej("/api/v1/worker/model/params"),eb=e=>e_("/api/v1/agent/query",e),ex=e=>e_("/api/v1/agent/hub/update",null!=e?e:{channel:"",url:"",branch:"",authorization:""}),ew=e=>e_("/api/v1/agent/my",void 0,{params:{user:e}}),eC=(e,t)=>e_("/api/v1/agent/install",void 0,{params:{plugin_name:e,user:t},timeout:6e4}),eE=(e,t)=>e_("/api/v1/agent/uninstall",void 0,{params:{plugin_name:e,user:t},timeout:6e4}),eS=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1?arguments[1]:void 0,n=arguments.length>2?arguments[2]:void 0;return e_("/api/v1/personal/agent/upload",t,{params:{user:e},headers:{"Content-Type":"multipart/form-data"},...n})},e$=()=>ej("/api/v1/feedback/select",void 0),eO=(e,t)=>ej("/api/v1/feedback/find?conv_uid=".concat(e,"&conv_index=").concat(t),void 0),ek=e=>{let{data:t,config:n}=e;return e_("/api/v1/feedback/commit",t,{headers:{"Content-Type":"application/json"},...n})};var eZ=n(83454);let eP=o.Z.create({baseURL:null!==(r=eZ.env.API_BASE_URL)&&void 0!==r?r:"",timeout:1e4}),ej=(e,t,n)=>eP.get(e,{params:t,...n}),e_=(e,t,n)=>eP.post(e,t,n)},32665:function(e,t,n){"use strict";function r(e){}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"clientHookInServerComponentError",{enumerable:!0,get:function(){return r}}),n(38754),n(67294),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},41219:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{ReadonlyURLSearchParams:function(){return p},useSearchParams:function(){return h},usePathname:function(){return m},ServerInsertedHTMLContext:function(){return s.ServerInsertedHTMLContext},useServerInsertedHTML:function(){return s.useServerInsertedHTML},useRouter:function(){return g},useParams:function(){return v},useSelectedLayoutSegments:function(){return y},useSelectedLayoutSegment:function(){return b},redirect:function(){return c.redirect},notFound:function(){return u.notFound}});let r=n(67294),o=n(27473),i=n(35802),a=n(32665),l=n(43512),s=n(98751),c=n(96885),u=n(86323),f=Symbol("internal for urlsearchparams readonly");function d(){return Error("ReadonlyURLSearchParams cannot be modified")}class p{[Symbol.iterator](){return this[f][Symbol.iterator]()}append(){throw d()}delete(){throw d()}set(){throw d()}sort(){throw d()}constructor(e){this[f]=e,this.entries=e.entries.bind(e),this.forEach=e.forEach.bind(e),this.get=e.get.bind(e),this.getAll=e.getAll.bind(e),this.has=e.has.bind(e),this.keys=e.keys.bind(e),this.values=e.values.bind(e),this.toString=e.toString.bind(e)}}function h(){(0,a.clientHookInServerComponentError)("useSearchParams");let e=(0,r.useContext)(i.SearchParamsContext),t=(0,r.useMemo)(()=>e?new p(e):null,[e]);return t}function m(){return(0,a.clientHookInServerComponentError)("usePathname"),(0,r.useContext)(i.PathnameContext)}function g(){(0,a.clientHookInServerComponentError)("useRouter");let e=(0,r.useContext)(o.AppRouterContext);if(null===e)throw Error("invariant expected app router to be mounted");return e}function v(){(0,a.clientHookInServerComponentError)("useParams");let e=(0,r.useContext)(o.GlobalLayoutRouterContext);return e?function e(t,n){void 0===n&&(n={});let r=t[1];for(let t of Object.values(r)){let r=t[0],o=Array.isArray(r),i=o?r[1]:r;!i||i.startsWith("__PAGE__")||(o&&(n[r[0]]=r[1]),n=e(t,n))}return n}(e.tree):null}function y(e){void 0===e&&(e="children"),(0,a.clientHookInServerComponentError)("useSelectedLayoutSegments");let{tree:t}=(0,r.useContext)(o.LayoutRouterContext);return function e(t,n,r,o){let i;if(void 0===r&&(r=!0),void 0===o&&(o=[]),r)i=t[1][n];else{var a;let e=t[1];i=null!=(a=e.children)?a:Object.values(e)[0]}if(!i)return o;let s=i[0],c=(0,l.getSegmentValue)(s);return!c||c.startsWith("__PAGE__")?o:(o.push(c),e(i,n,!1,o))}(t,e)}function b(e){void 0===e&&(e="children"),(0,a.clientHookInServerComponentError)("useSelectedLayoutSegment");let t=y(e);return 0===t.length?null:t[0]}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},86323:function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{notFound:function(){return r},isNotFoundError:function(){return o}});let n="NEXT_NOT_FOUND";function r(){let e=Error(n);throw e.digest=n,e}function o(e){return(null==e?void 0:e.digest)===n}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},96885:function(e,t,n){"use strict";var r,o;Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{RedirectType:function(){return r},getRedirectError:function(){return l},redirect:function(){return s},isRedirectError:function(){return c},getURLFromRedirectError:function(){return u},getRedirectTypeFromError:function(){return f}});let i=n(68214),a="NEXT_REDIRECT";function l(e,t){let n=Error(a);n.digest=a+";"+t+";"+e;let r=i.requestAsyncStorage.getStore();return r&&(n.mutableCookies=r.mutableCookies),n}function s(e,t){throw void 0===t&&(t="replace"),l(e,t)}function c(e){if("string"!=typeof(null==e?void 0:e.digest))return!1;let[t,n,r]=e.digest.split(";",3);return t===a&&("replace"===n||"push"===n)&&"string"==typeof r}function u(e){return c(e)?e.digest.split(";",3)[2]:null}function f(e){if(!c(e))throw Error("Not a redirect error");return e.digest.split(";",3)[1]}(o=r||(r={})).push="push",o.replace="replace",("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},43512:function(e,t){"use strict";function n(e){return Array.isArray(e)?e[1]:e}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"getSegmentValue",{enumerable:!0,get:function(){return n}}),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},29382:function(e,t){"use strict";var n,r;Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{PrefetchKind:function(){return n},ACTION_REFRESH:function(){return o},ACTION_NAVIGATE:function(){return i},ACTION_RESTORE:function(){return a},ACTION_SERVER_PATCH:function(){return l},ACTION_PREFETCH:function(){return s},ACTION_FAST_REFRESH:function(){return c},ACTION_SERVER_ACTION:function(){return u}});let o="refresh",i="navigate",a="restore",l="server-patch",s="prefetch",c="fast-refresh",u="server-action";(r=n||(n={})).AUTO="auto",r.FULL="full",r.TEMPORARY="temporary",("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},75476:function(e,t){"use strict";function n(e,t,n,r){return!1}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"getDomainLocale",{enumerable:!0,get:function(){return n}}),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},69873:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return y}});let r=n(38754),o=n(61757),i=o._(n(67294)),a=r._(n(68965)),l=n(38083),s=n(2478),c=n(76226);n(59941);let u=r._(n(31720)),f={deviceSizes:[640,750,828,1080,1200,1920,2048,3840],imageSizes:[16,32,48,64,96,128,256,384],path:"/_next/image/",loader:"default",dangerouslyAllowSVG:!1,unoptimized:!0};function d(e){return void 0!==e.default}function p(e){return void 0===e?e:"number"==typeof e?Number.isFinite(e)?e:NaN:"string"==typeof e&&/^[0-9]+$/.test(e)?parseInt(e,10):NaN}function h(e,t,n,r,o,i,a){if(!e||e["data-loaded-src"]===t)return;e["data-loaded-src"]=t;let l="decode"in e?e.decode():Promise.resolve();l.catch(()=>{}).then(()=>{if(e.parentElement&&e.isConnected){if("blur"===n&&i(!0),null==r?void 0:r.current){let t=new Event("load");Object.defineProperty(t,"target",{writable:!1,value:e});let n=!1,o=!1;r.current({...t,nativeEvent:t,currentTarget:e,target:e,isDefaultPrevented:()=>n,isPropagationStopped:()=>o,persist:()=>{},preventDefault:()=>{n=!0,t.preventDefault()},stopPropagation:()=>{o=!0,t.stopPropagation()}})}(null==o?void 0:o.current)&&o.current(e)}})}function m(e){let[t,n]=i.version.split("."),r=parseInt(t,10),o=parseInt(n,10);return r>18||18===r&&o>=3?{fetchPriority:e}:{fetchpriority:e}}let g=(0,i.forwardRef)((e,t)=>{let{imgAttributes:n,heightInt:r,widthInt:o,qualityInt:a,className:l,imgStyle:s,blurStyle:c,isLazy:u,fetchPriority:f,fill:d,placeholder:p,loading:g,srcString:v,config:y,unoptimized:b,loader:x,onLoadRef:w,onLoadingCompleteRef:C,setBlurComplete:E,setShowAltText:S,onLoad:$,onError:O,...k}=e;return g=u?"lazy":g,i.default.createElement("img",{...k,...m(f),loading:g,width:o,height:r,decoding:"async","data-nimg":d?"fill":"1",className:l,style:{...s,...c},...n,ref:(0,i.useCallback)(e=>{t&&("function"==typeof t?t(e):"object"==typeof t&&(t.current=e)),e&&(O&&(e.src=e.src),e.complete&&h(e,v,p,w,C,E,b))},[v,p,w,C,E,O,b,t]),onLoad:e=>{let t=e.currentTarget;h(t,v,p,w,C,E,b)},onError:e=>{S(!0),"blur"===p&&E(!0),O&&O(e)}})}),v=(0,i.forwardRef)((e,t)=>{var n;let r,o,{src:h,sizes:v,unoptimized:y=!1,priority:b=!1,loading:x,className:w,quality:C,width:E,height:S,fill:$,style:O,onLoad:k,onLoadingComplete:Z,placeholder:P="empty",blurDataURL:j,fetchPriority:_,layout:R,objectFit:A,objectPosition:N,lazyBoundary:T,lazyRoot:M,...I}=e,F=(0,i.useContext)(c.ImageConfigContext),L=(0,i.useMemo)(()=>{let e=f||F||s.imageConfigDefault,t=[...e.deviceSizes,...e.imageSizes].sort((e,t)=>e-t),n=e.deviceSizes.sort((e,t)=>e-t);return{...e,allSizes:t,deviceSizes:n}},[F]),B=I.loader||u.default;delete I.loader;let D="__next_img_default"in B;if(D){if("custom"===L.loader)throw Error('Image with src "'+h+'" is missing "loader" prop.\nRead more: https://nextjs.org/docs/messages/next-image-missing-loader')}else{let e=B;B=t=>{let{config:n,...r}=t;return e(r)}}if(R){"fill"===R&&($=!0);let e={intrinsic:{maxWidth:"100%",height:"auto"},responsive:{width:"100%",height:"auto"}}[R];e&&(O={...O,...e});let t={responsive:"100vw",fill:"100vw"}[R];t&&!v&&(v=t)}let z="",H=p(E),V=p(S);if("object"==typeof(n=h)&&(d(n)||void 0!==n.src)){let e=d(h)?h.default:h;if(!e.src)throw Error("An object should only be passed to the image component src parameter if it comes from a static image import. It must include src. Received "+JSON.stringify(e));if(!e.height||!e.width)throw Error("An object should only be passed to the image component src parameter if it comes from a static image import. It must include height and width. Received "+JSON.stringify(e));if(r=e.blurWidth,o=e.blurHeight,j=j||e.blurDataURL,z=e.src,!$){if(H||V){if(H&&!V){let t=H/e.width;V=Math.round(e.height*t)}else if(!H&&V){let t=V/e.height;H=Math.round(e.width*t)}}else H=e.width,V=e.height}}let U=!b&&("lazy"===x||void 0===x);(!(h="string"==typeof h?h:z)||h.startsWith("data:")||h.startsWith("blob:"))&&(y=!0,U=!1),L.unoptimized&&(y=!0),D&&h.endsWith(".svg")&&!L.dangerouslyAllowSVG&&(y=!0),b&&(_="high");let[W,K]=(0,i.useState)(!1),[q,G]=(0,i.useState)(!1),X=p(C),Y=Object.assign($?{position:"absolute",height:"100%",width:"100%",left:0,top:0,right:0,bottom:0,objectFit:A,objectPosition:N}:{},q?{}:{color:"transparent"},O),J="blur"===P&&j&&!W?{backgroundSize:Y.objectFit||"cover",backgroundPosition:Y.objectPosition||"50% 50%",backgroundRepeat:"no-repeat",backgroundImage:'url("data:image/svg+xml;charset=utf-8,'+(0,l.getImageBlurSvg)({widthInt:H,heightInt:V,blurWidth:r,blurHeight:o,blurDataURL:j,objectFit:Y.objectFit})+'")'}:{},Q=function(e){let{config:t,src:n,unoptimized:r,width:o,quality:i,sizes:a,loader:l}=e;if(r)return{src:n,srcSet:void 0,sizes:void 0};let{widths:s,kind:c}=function(e,t,n){let{deviceSizes:r,allSizes:o}=e;if(n){let e=/(^|\s)(1?\d?\d)vw/g,t=[];for(let r;r=e.exec(n);r)t.push(parseInt(r[2]));if(t.length){let e=.01*Math.min(...t);return{widths:o.filter(t=>t>=r[0]*e),kind:"w"}}return{widths:o,kind:"w"}}if("number"!=typeof t)return{widths:r,kind:"w"};let i=[...new Set([t,2*t].map(e=>o.find(t=>t>=e)||o[o.length-1]))];return{widths:i,kind:"x"}}(t,o,a),u=s.length-1;return{sizes:a||"w"!==c?a:"100vw",srcSet:s.map((e,r)=>l({config:t,src:n,quality:i,width:e})+" "+("w"===c?e:r+1)+c).join(", "),src:l({config:t,src:n,quality:i,width:s[u]})}}({config:L,src:h,unoptimized:y,width:H,quality:X,sizes:v,loader:B}),ee=h,et=(0,i.useRef)(k);(0,i.useEffect)(()=>{et.current=k},[k]);let en=(0,i.useRef)(Z);(0,i.useEffect)(()=>{en.current=Z},[Z]);let er={isLazy:U,imgAttributes:Q,heightInt:V,widthInt:H,qualityInt:X,className:w,imgStyle:Y,blurStyle:J,loading:x,config:L,fetchPriority:_,fill:$,unoptimized:y,placeholder:P,loader:B,srcString:ee,onLoadRef:et,onLoadingCompleteRef:en,setBlurComplete:K,setShowAltText:G,...I};return i.default.createElement(i.default.Fragment,null,i.default.createElement(g,{...er,ref:t}),b?i.default.createElement(a.default,null,i.default.createElement("link",{key:"__nimg-"+Q.src+Q.srcSet+Q.sizes,rel:"preload",as:"image",href:Q.srcSet?void 0:Q.src,imageSrcSet:Q.srcSet,imageSizes:Q.sizes,crossOrigin:I.crossOrigin,referrerPolicy:I.referrerPolicy,...m(_)})):null)}),y=v;("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},9940:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return x}});let r=n(38754),o=r._(n(67294)),i=n(65722),a=n(65723),l=n(28904),s=n(95514),c=n(27521),u=n(44293),f=n(27473),d=n(81307),p=n(75476),h=n(66318),m=n(29382),g=new Set;function v(e,t,n,r,o,i){if(!i&&!(0,a.isLocalURL)(t))return;if(!r.bypassPrefetchedCheck){let o=void 0!==r.locale?r.locale:"locale"in e?e.locale:void 0,i=t+"%"+n+"%"+o;if(g.has(i))return;g.add(i)}let l=i?e.prefetch(t,o):e.prefetch(t,n,r);Promise.resolve(l).catch(e=>{})}function y(e){return"string"==typeof e?e:(0,l.formatUrl)(e)}let b=o.default.forwardRef(function(e,t){let n,r;let{href:l,as:g,children:b,prefetch:x=null,passHref:w,replace:C,shallow:E,scroll:S,locale:$,onClick:O,onMouseEnter:k,onTouchStart:Z,legacyBehavior:P=!1,...j}=e;n=b,P&&("string"==typeof n||"number"==typeof n)&&(n=o.default.createElement("a",null,n));let _=!1!==x,R=null===x?m.PrefetchKind.AUTO:m.PrefetchKind.FULL,A=o.default.useContext(u.RouterContext),N=o.default.useContext(f.AppRouterContext),T=null!=A?A:N,M=!A,{href:I,as:F}=o.default.useMemo(()=>{if(!A){let e=y(l);return{href:e,as:g?y(g):e}}let[e,t]=(0,i.resolveHref)(A,l,!0);return{href:e,as:g?(0,i.resolveHref)(A,g):t||e}},[A,l,g]),L=o.default.useRef(I),B=o.default.useRef(F);P&&(r=o.default.Children.only(n));let D=P?r&&"object"==typeof r&&r.ref:t,[z,H,V]=(0,d.useIntersection)({rootMargin:"200px"}),U=o.default.useCallback(e=>{(B.current!==F||L.current!==I)&&(V(),B.current=F,L.current=I),z(e),D&&("function"==typeof D?D(e):"object"==typeof D&&(D.current=e))},[F,D,I,V,z]);o.default.useEffect(()=>{T&&H&&_&&v(T,I,F,{locale:$},{kind:R},M)},[F,I,H,$,_,null==A?void 0:A.locale,T,M,R]);let W={ref:U,onClick(e){P||"function"!=typeof O||O(e),P&&r.props&&"function"==typeof r.props.onClick&&r.props.onClick(e),T&&!e.defaultPrevented&&function(e,t,n,r,i,l,s,c,u,f){let{nodeName:d}=e.currentTarget,p="A"===d.toUpperCase();if(p&&(function(e){let t=e.currentTarget,n=t.getAttribute("target");return n&&"_self"!==n||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||e.nativeEvent&&2===e.nativeEvent.which}(e)||!u&&!(0,a.isLocalURL)(n)))return;e.preventDefault();let h=()=>{"beforePopState"in t?t[i?"replace":"push"](n,r,{shallow:l,locale:c,scroll:s}):t[i?"replace":"push"](r||n,{forceOptimisticNavigation:!f})};u?o.default.startTransition(h):h()}(e,T,I,F,C,E,S,$,M,_)},onMouseEnter(e){P||"function"!=typeof k||k(e),P&&r.props&&"function"==typeof r.props.onMouseEnter&&r.props.onMouseEnter(e),T&&(_||!M)&&v(T,I,F,{locale:$,priority:!0,bypassPrefetchedCheck:!0},{kind:R},M)},onTouchStart(e){P||"function"!=typeof Z||Z(e),P&&r.props&&"function"==typeof r.props.onTouchStart&&r.props.onTouchStart(e),T&&(_||!M)&&v(T,I,F,{locale:$,priority:!0,bypassPrefetchedCheck:!0},{kind:R},M)}};if((0,s.isAbsoluteUrl)(F))W.href=F;else if(!P||w||"a"===r.type&&!("href"in r.props)){let e=void 0!==$?$:null==A?void 0:A.locale,t=(null==A?void 0:A.isLocaleDomain)&&(0,p.getDomainLocale)(F,e,null==A?void 0:A.locales,null==A?void 0:A.domainLocales);W.href=t||(0,h.addBasePath)((0,c.addLocale)(F,e,null==A?void 0:A.defaultLocale))}return P?o.default.cloneElement(r,W):o.default.createElement("a",{...j,...W},n)}),x=b;("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},81307:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"useIntersection",{enumerable:!0,get:function(){return s}});let r=n(67294),o=n(82997),i="function"==typeof IntersectionObserver,a=new Map,l=[];function s(e){let{rootRef:t,rootMargin:n,disabled:s}=e,c=s||!i,[u,f]=(0,r.useState)(!1),d=(0,r.useRef)(null),p=(0,r.useCallback)(e=>{d.current=e},[]);(0,r.useEffect)(()=>{if(i){if(c||u)return;let e=d.current;if(e&&e.tagName){let r=function(e,t,n){let{id:r,observer:o,elements:i}=function(e){let t;let n={root:e.root||null,margin:e.rootMargin||""},r=l.find(e=>e.root===n.root&&e.margin===n.margin);if(r&&(t=a.get(r)))return t;let o=new Map,i=new IntersectionObserver(e=>{e.forEach(e=>{let t=o.get(e.target),n=e.isIntersecting||e.intersectionRatio>0;t&&n&&t(n)})},e);return t={id:n,observer:i,elements:o},l.push(n),a.set(n,t),t}(n);return i.set(e,t),o.observe(e),function(){if(i.delete(e),o.unobserve(e),0===i.size){o.disconnect(),a.delete(r);let e=l.findIndex(e=>e.root===r.root&&e.margin===r.margin);e>-1&&l.splice(e,1)}}}(e,e=>e&&f(e),{root:null==t?void 0:t.current,rootMargin:n});return r}}else if(!u){let e=(0,o.requestIdleCallback)(()=>f(!0));return()=>(0,o.cancelIdleCallback)(e)}},[c,n,t,u,d.current]);let h=(0,r.useCallback)(()=>{f(!1)},[]);return[p,u,h]}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},38083:function(e,t){"use strict";function n(e){let{widthInt:t,heightInt:n,blurWidth:r,blurHeight:o,blurDataURL:i,objectFit:a}=e,l=r||t,s=o||n,c=i.startsWith("data:image/jpeg")?"%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%":"";return l&&s?"%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 "+l+" "+s+"'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='"+(r&&o?"1":"20")+"'/%3E"+c+"%3C/filter%3E%3Cimage preserveAspectRatio='none' filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='"+i+"'/%3E%3C/svg%3E":"%3Csvg xmlns='http%3A//www.w3.org/2000/svg'%3E%3Cimage style='filter:blur(20px)' preserveAspectRatio='"+("contain"===a?"xMidYMid":"cover"===a?"xMidYMid slice":"none")+"' x='0' y='0' height='100%25' width='100%25' href='"+i+"'/%3E%3C/svg%3E"}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"getImageBlurSvg",{enumerable:!0,get:function(){return n}})},31720:function(e,t){"use strict";function n(e){let{config:t,src:n,width:r,quality:o}=e;return t.path+"?url="+encodeURIComponent(n)+"&w="+r+"&q="+(o||75)}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return r}}),n.__next_img_default=!0;let r=n},98751:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{ServerInsertedHTMLContext:function(){return i},useServerInsertedHTML:function(){return a}});let r=n(61757),o=r._(n(67294)),i=o.default.createContext(null);function a(e){let t=(0,o.useContext)(i);t&&t(e)}},37262:function(e,t,n){"use strict";let r,o;n.r(t),n.d(t,{default:function(){return eM}});var i=n(85893),a=n(67294),l=n(41468),s=n(50489),c=n(98399),u=function(){return(0,i.jsx)("svg",{width:"1em",height:"1em",fill:"currentColor",viewBox:"0 0 1024 1024",children:(0,i.jsx)("path",{d:"M593.054 120.217C483.656 148.739 402.91 248.212 402.91 366.546c0 140.582 113.962 254.544 254.544 254.544 118.334 0 217.808-80.746 246.328-190.144C909.17 457.12 912 484.23 912 512c0 220.914-179.086 400-400 400S112 732.914 112 512s179.086-400 400-400c27.77 0 54.88 2.83 81.054 8.217z","p-id":"5941"})})},f=function(){return(0,i.jsx)("svg",{width:"1em",height:"1em",fill:"currentColor",viewBox:"0 0 1024 1024",children:(0,i.jsx)("path",{d:"M554.6 64h-85.4v128h85.4V64z m258.2 87.4L736 228.2l59.8 59.8 76.8-76.8-59.8-59.8z m-601.6 0l-59.8 59.8 76.8 76.8 59.8-59.8-76.8-76.8zM512 256c-140.8 0-256 115.2-256 256s115.2 256 256 256 256-115.2 256-256-115.2-256-256-256z m448 213.4h-128v85.4h128v-85.4z m-768 0H64v85.4h128v-85.4zM795.8 736L736 795.8l76.8 76.8 59.8-59.8-76.8-76.8z m-567.6 0l-76.8 76.8 59.8 59.8 76.8-76.8-59.8-59.8z m326.4 96h-85.4v128h85.4v-128z","p-id":"7802"})})},d=n(59766),p=n(87462),h=n(63366),m=n(71387),g=n(70917);function v(e){let{styles:t,defaultTheme:n={}}=e,r="function"==typeof t?e=>t(null==e||0===Object.keys(e).length?n:e):t;return(0,i.jsx)(g.xB,{styles:r})}var y=n(56760),b=n(71927);let x="mode",w="color-scheme",C="data-color-scheme";function E(e){if("undefined"!=typeof window&&"system"===e){let e=window.matchMedia("(prefers-color-scheme: dark)");return e.matches?"dark":"light"}}function S(e,t){return"light"===e.mode||"system"===e.mode&&"light"===e.systemMode?t("light"):"dark"===e.mode||"system"===e.mode&&"dark"===e.systemMode?t("dark"):void 0}function $(e,t){let n;if("undefined"!=typeof window){try{(n=localStorage.getItem(e)||void 0)||localStorage.setItem(e,t)}catch(e){}return n||t}}let O=["colorSchemes","components","generateCssVars","cssVarPrefix"];var k=n(1812),Z=n(13951),P=n(2548);let{CssVarsProvider:j,useColorScheme:_,getInitColorSchemeScript:R}=function(e){let{themeId:t,theme:n={},attribute:r=C,modeStorageKey:o=x,colorSchemeStorageKey:l=w,defaultMode:s="light",defaultColorScheme:c,disableTransitionOnChange:u=!1,resolveTheme:f,excludeVariablesFromRoot:g}=e;n.colorSchemes&&("string"!=typeof c||n.colorSchemes[c])&&("object"!=typeof c||n.colorSchemes[null==c?void 0:c.light])&&("object"!=typeof c||n.colorSchemes[null==c?void 0:c.dark])||console.error(`MUI: \`${c}\` does not exist in \`theme.colorSchemes\`.`);let k=a.createContext(void 0),Z="string"==typeof c?c:c.light,P="string"==typeof c?c:c.dark;return{CssVarsProvider:function({children:e,theme:m=n,modeStorageKey:C=o,colorSchemeStorageKey:Z=l,attribute:P=r,defaultMode:j=s,defaultColorScheme:_=c,disableTransitionOnChange:R=u,storageWindow:A="undefined"==typeof window?void 0:window,documentNode:N="undefined"==typeof document?void 0:document,colorSchemeNode:T="undefined"==typeof document?void 0:document.documentElement,colorSchemeSelector:M=":root",disableNestedContext:I=!1,disableStyleSheetGeneration:F=!1}){let L=a.useRef(!1),B=(0,y.Z)(),D=a.useContext(k),z=!!D&&!I,H=m[t],V=H||m,{colorSchemes:U={},components:W={},generateCssVars:K=()=>({vars:{},css:{}}),cssVarPrefix:q}=V,G=(0,h.Z)(V,O),X=Object.keys(U),Y="string"==typeof _?_:_.light,J="string"==typeof _?_:_.dark,{mode:Q,setMode:ee,systemMode:et,lightColorScheme:en,darkColorScheme:er,colorScheme:eo,setColorScheme:ei}=function(e){let{defaultMode:t="light",defaultLightColorScheme:n,defaultDarkColorScheme:r,supportedColorSchemes:o=[],modeStorageKey:i=x,colorSchemeStorageKey:l=w,storageWindow:s="undefined"==typeof window?void 0:window}=e,c=o.join(","),[u,f]=a.useState(()=>{let e=$(i,t),o=$(`${l}-light`,n),a=$(`${l}-dark`,r);return{mode:e,systemMode:E(e),lightColorScheme:o,darkColorScheme:a}}),d=S(u,e=>"light"===e?u.lightColorScheme:"dark"===e?u.darkColorScheme:void 0),h=a.useCallback(e=>{f(n=>{if(e===n.mode)return n;let r=e||t;try{localStorage.setItem(i,r)}catch(e){}return(0,p.Z)({},n,{mode:r,systemMode:E(r)})})},[i,t]),m=a.useCallback(e=>{e?"string"==typeof e?e&&!c.includes(e)?console.error(`\`${e}\` does not exist in \`theme.colorSchemes\`.`):f(t=>{let n=(0,p.Z)({},t);return S(t,t=>{try{localStorage.setItem(`${l}-${t}`,e)}catch(e){}"light"===t&&(n.lightColorScheme=e),"dark"===t&&(n.darkColorScheme=e)}),n}):f(t=>{let o=(0,p.Z)({},t),i=null===e.light?n:e.light,a=null===e.dark?r:e.dark;if(i){if(c.includes(i)){o.lightColorScheme=i;try{localStorage.setItem(`${l}-light`,i)}catch(e){}}else console.error(`\`${i}\` does not exist in \`theme.colorSchemes\`.`)}if(a){if(c.includes(a)){o.darkColorScheme=a;try{localStorage.setItem(`${l}-dark`,a)}catch(e){}}else console.error(`\`${a}\` does not exist in \`theme.colorSchemes\`.`)}return o}):f(e=>{try{localStorage.setItem(`${l}-light`,n),localStorage.setItem(`${l}-dark`,r)}catch(e){}return(0,p.Z)({},e,{lightColorScheme:n,darkColorScheme:r})})},[c,l,n,r]),g=a.useCallback(e=>{"system"===u.mode&&f(t=>(0,p.Z)({},t,{systemMode:null!=e&&e.matches?"dark":"light"}))},[u.mode]),v=a.useRef(g);return v.current=g,a.useEffect(()=>{let e=(...e)=>v.current(...e),t=window.matchMedia("(prefers-color-scheme: dark)");return t.addListener(e),e(t),()=>t.removeListener(e)},[]),a.useEffect(()=>{let e=e=>{let n=e.newValue;"string"==typeof e.key&&e.key.startsWith(l)&&(!n||c.match(n))&&(e.key.endsWith("light")&&m({light:n}),e.key.endsWith("dark")&&m({dark:n})),e.key===i&&(!n||["light","dark","system"].includes(n))&&h(n||t)};if(s)return s.addEventListener("storage",e),()=>s.removeEventListener("storage",e)},[m,h,i,l,c,t,s]),(0,p.Z)({},u,{colorScheme:d,setMode:h,setColorScheme:m})}({supportedColorSchemes:X,defaultLightColorScheme:Y,defaultDarkColorScheme:J,modeStorageKey:C,colorSchemeStorageKey:Z,defaultMode:j,storageWindow:A}),ea=Q,el=eo;z&&(ea=D.mode,el=D.colorScheme);let es=ea||("system"===j?s:j),ec=el||("dark"===es?J:Y),{css:eu,vars:ef}=K(),ed=(0,p.Z)({},G,{components:W,colorSchemes:U,cssVarPrefix:q,vars:ef,getColorSchemeSelector:e=>`[${P}="${e}"] &`}),ep={},eh={};Object.entries(U).forEach(([e,t])=>{let{css:n,vars:r}=K(e);ed.vars=(0,d.Z)(ed.vars,r),e===ec&&(Object.keys(t).forEach(e=>{t[e]&&"object"==typeof t[e]?ed[e]=(0,p.Z)({},ed[e],t[e]):ed[e]=t[e]}),ed.palette&&(ed.palette.colorScheme=e));let o="string"==typeof _?_:"dark"===j?_.dark:_.light;if(e===o){if(g){let t={};g(q).forEach(e=>{t[e]=n[e],delete n[e]}),ep[`[${P}="${e}"]`]=t}ep[`${M}, [${P}="${e}"]`]=n}else eh[`${":root"===M?"":M}[${P}="${e}"]`]=n}),ed.vars=(0,d.Z)(ed.vars,ef),a.useEffect(()=>{el&&T&&T.setAttribute(P,el)},[el,P,T]),a.useEffect(()=>{let e;if(R&&L.current&&N){let t=N.createElement("style");t.appendChild(N.createTextNode("*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}")),N.head.appendChild(t),window.getComputedStyle(N.body),e=setTimeout(()=>{N.head.removeChild(t)},1)}return()=>{clearTimeout(e)}},[el,R,N]),a.useEffect(()=>(L.current=!0,()=>{L.current=!1}),[]);let em=a.useMemo(()=>({mode:ea,systemMode:et,setMode:ee,lightColorScheme:en,darkColorScheme:er,colorScheme:el,setColorScheme:ei,allColorSchemes:X}),[X,el,er,en,ea,ei,ee,et]),eg=!0;(F||z&&(null==B?void 0:B.cssVarPrefix)===q)&&(eg=!1);let ev=(0,i.jsxs)(a.Fragment,{children:[eg&&(0,i.jsxs)(a.Fragment,{children:[(0,i.jsx)(v,{styles:{[M]:eu}}),(0,i.jsx)(v,{styles:ep}),(0,i.jsx)(v,{styles:eh})]}),(0,i.jsx)(b.Z,{themeId:H?t:void 0,theme:f?f(ed):ed,children:e})]});return z?ev:(0,i.jsx)(k.Provider,{value:em,children:ev})},useColorScheme:()=>{let e=a.useContext(k);if(!e)throw Error((0,m.Z)(19));return e},getInitColorSchemeScript:e=>(function(e){let{defaultMode:t="light",defaultLightColorScheme:n="light",defaultDarkColorScheme:r="dark",modeStorageKey:o=x,colorSchemeStorageKey:a=w,attribute:l=C,colorSchemeNode:s="document.documentElement"}=e||{};return(0,i.jsx)("script",{dangerouslySetInnerHTML:{__html:`(function() { try { + */var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,i=n?Symbol.for("react.fragment"):60107,a=n?Symbol.for("react.strict_mode"):60108,l=n?Symbol.for("react.profiler"):60114,s=n?Symbol.for("react.provider"):60109,c=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,f=n?Symbol.for("react.concurrent_mode"):60111,d=n?Symbol.for("react.forward_ref"):60112,p=n?Symbol.for("react.suspense"):60113,h=n?Symbol.for("react.suspense_list"):60120,m=n?Symbol.for("react.memo"):60115,g=n?Symbol.for("react.lazy"):60116,v=n?Symbol.for("react.block"):60121,y=n?Symbol.for("react.fundamental"):60117,b=n?Symbol.for("react.responder"):60118,x=n?Symbol.for("react.scope"):60119;function w(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case u:case f:case i:case l:case a:case p:return e;default:switch(e=e&&e.$$typeof){case c:case d:case g:case m:case s:return e;default:return t}}case o:return t}}}function C(e){return w(e)===f}t.AsyncMode=u,t.ConcurrentMode=f,t.ContextConsumer=c,t.ContextProvider=s,t.Element=r,t.ForwardRef=d,t.Fragment=i,t.Lazy=g,t.Memo=m,t.Portal=o,t.Profiler=l,t.StrictMode=a,t.Suspense=p,t.isAsyncMode=function(e){return C(e)||w(e)===u},t.isConcurrentMode=C,t.isContextConsumer=function(e){return w(e)===c},t.isContextProvider=function(e){return w(e)===s},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return w(e)===d},t.isFragment=function(e){return w(e)===i},t.isLazy=function(e){return w(e)===g},t.isMemo=function(e){return w(e)===m},t.isPortal=function(e){return w(e)===o},t.isProfiler=function(e){return w(e)===l},t.isStrictMode=function(e){return w(e)===a},t.isSuspense=function(e){return w(e)===p},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===i||e===f||e===l||e===a||e===p||e===h||"object"==typeof e&&null!==e&&(e.$$typeof===g||e.$$typeof===m||e.$$typeof===s||e.$$typeof===c||e.$$typeof===d||e.$$typeof===y||e.$$typeof===b||e.$$typeof===x||e.$$typeof===v)},t.typeOf=w},21296:function(e,t,n){"use strict";e.exports=n(96103)},62705:function(e,t,n){var r=n(55639).Symbol;e.exports=r},44239:function(e,t,n){var r=n(62705),o=n(89607),i=n(2333),a=r?r.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":a&&a in Object(e)?o(e):i(e)}},27561:function(e,t,n){var r=n(67990),o=/^\s+/;e.exports=function(e){return e?e.slice(0,r(e)+1).replace(o,""):e}},31957:function(e,t,n){var r="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g;e.exports=r},89607:function(e,t,n){var r=n(62705),o=Object.prototype,i=o.hasOwnProperty,a=o.toString,l=r?r.toStringTag:void 0;e.exports=function(e){var t=i.call(e,l),n=e[l];try{e[l]=void 0;var r=!0}catch(e){}var o=a.call(e);return r&&(t?e[l]=n:delete e[l]),o}},2333:function(e){var t=Object.prototype.toString;e.exports=function(e){return t.call(e)}},55639:function(e,t,n){var r=n(31957),o="object"==typeof self&&self&&self.Object===Object&&self,i=r||o||Function("return this")();e.exports=i},67990:function(e){var t=/\s/;e.exports=function(e){for(var n=e.length;n--&&t.test(e.charAt(n)););return n}},23279:function(e,t,n){var r=n(13218),o=n(7771),i=n(14841),a=Math.max,l=Math.min;e.exports=function(e,t,n){var s,c,u,f,d,p,h=0,m=!1,g=!1,v=!0;if("function"!=typeof e)throw TypeError("Expected a function");function y(t){var n=s,r=c;return s=c=void 0,h=t,f=e.apply(r,n)}function b(e){var n=e-p,r=e-h;return void 0===p||n>=t||n<0||g&&r>=u}function x(){var e,n,r,i=o();if(b(i))return w(i);d=setTimeout(x,(e=i-p,n=i-h,r=t-e,g?l(r,u-n):r))}function w(e){return(d=void 0,v&&s)?y(e):(s=c=void 0,f)}function C(){var e,n=o(),r=b(n);if(s=arguments,c=this,p=n,r){if(void 0===d)return h=e=p,d=setTimeout(x,t),m?y(e):f;if(g)return clearTimeout(d),d=setTimeout(x,t),y(p)}return void 0===d&&(d=setTimeout(x,t)),f}return t=i(t)||0,r(n)&&(m=!!n.leading,u=(g="maxWait"in n)?a(i(n.maxWait)||0,t):u,v="trailing"in n?!!n.trailing:v),C.cancel=function(){void 0!==d&&clearTimeout(d),h=0,s=p=c=d=void 0},C.flush=function(){return void 0===d?f:w(o())},C}},13218:function(e){e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},37005:function(e){e.exports=function(e){return null!=e&&"object"==typeof e}},33448:function(e,t,n){var r=n(44239),o=n(37005);e.exports=function(e){return"symbol"==typeof e||o(e)&&"[object Symbol]"==r(e)}},7771:function(e,t,n){var r=n(55639);e.exports=function(){return r.Date.now()}},23493:function(e,t,n){var r=n(23279),o=n(13218);e.exports=function(e,t,n){var i=!0,a=!0;if("function"!=typeof e)throw TypeError("Expected a function");return o(n)&&(i="leading"in n?!!n.leading:i,a="trailing"in n?!!n.trailing:a),r(e,t,{leading:i,maxWait:t,trailing:a})}},14841:function(e,t,n){var r=n(27561),o=n(13218),i=n(33448),a=0/0,l=/^[-+]0x[0-9a-f]+$/i,s=/^0b[01]+$/i,c=/^0o[0-7]+$/i,u=parseInt;e.exports=function(e){if("number"==typeof e)return e;if(i(e))return a;if(o(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=o(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=r(e);var n=s.test(e);return n||c.test(e)?u(e.slice(2),n?2:8):l.test(e)?a:+e}},83454:function(e,t,n){"use strict";var r,o;e.exports=(null==(r=n.g.process)?void 0:r.env)&&"object"==typeof(null==(o=n.g.process)?void 0:o.env)?n.g.process:n(77663)},6840:function(e,t,n){(window.__NEXT_P=window.__NEXT_P||[]).push(["/_app",function(){return n(37262)}])},41468:function(e,t,n){"use strict";n.d(t,{R:function(){return c},p:function(){return s}});var r=n(85893),o=n(67294),i=n(50489),a=n(577),l=n(39332);let s=(0,o.createContext)({scene:"",chatId:"",modelList:[],model:"",dbParam:void 0,dialogueList:[],agentList:[],setAgentList:()=>{},setModel:()=>{},setIsContract:()=>{},setIsMenuExpand:()=>{},setDbParam:()=>void 0,queryDialogueList:()=>{},refreshDialogList:()=>{}}),c=e=>{var t,n,c;let{children:u}=e,f=(0,l.useSearchParams)(),d=null!==(t=null==f?void 0:f.get("id"))&&void 0!==t?t:"",p=null!==(n=null==f?void 0:f.get("scene"))&&void 0!==n?n:"",h=null!==(c=null==f?void 0:f.get("db_param"))&&void 0!==c?c:"",[m,g]=(0,o.useState)(!1),[v,y]=(0,o.useState)(""),[b,x]=(0,o.useState)("chat_dashboard"!==p),[w,C]=(0,o.useState)(h),[E,S]=(0,o.useState)([]),{run:$,data:O=[],refresh:k}=(0,a.Z)(async()=>{let[,e]=await (0,i.Vx)((0,i.iP)());return null!=e?e:[]},{manual:!0}),{data:Z=[]}=(0,a.Z)(async()=>{let[,e]=await (0,i.Vx)((0,i.Vw)());return null!=e?e:[]});(0,o.useEffect)(()=>{y(Z[0])},[Z,null==Z?void 0:Z.length]);let P=(0,o.useMemo)(()=>O.find(e=>e.conv_uid===d),[d,O]);return(0,r.jsx)(s.Provider,{value:{isContract:m,isMenuExpand:b,scene:p,chatId:d,modelList:Z,model:v,dbParam:w||h,dialogueList:O,agentList:E,setAgentList:S,setModel:y,setIsContract:g,setIsMenuExpand:x,setDbParam:C,queryDialogueList:$,refreshDialogList:k,currentDialogue:P},children:u})}},58989:function(e,t,n){"use strict";n.d(t,{Z:function(){return D}});let r={type:"logger",log(e){this.output("log",e)},warn(e){this.output("warn",e)},error(e){this.output("error",e)},output(e,t){console&&console[e]&&console[e].apply(console,t)}};class o{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.init(e,t)}init(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.prefix=t.prefix||"i18next:",this.logger=e||r,this.options=t,this.debug=t.debug}log(){for(var e=arguments.length,t=Array(e),n=0;n{this.observers[e]=this.observers[e]||[],this.observers[e].push(t)}),this}off(e,t){if(this.observers[e]){if(!t){delete this.observers[e];return}this.observers[e]=this.observers[e].filter(e=>e!==t)}}emit(e){for(var t=arguments.length,n=Array(t>1?t-1:0),r=1;r{e(...n)})}if(this.observers["*"]){let t=[].concat(this.observers["*"]);t.forEach(t=>{t.apply(t,[e,...n])})}}}function l(){let e,t;let n=new Promise((n,r)=>{e=n,t=r});return n.resolve=e,n.reject=t,n}function s(e){return null==e?"":""+e}function c(e,t,n){function r(e){return e&&e.indexOf("###")>-1?e.replace(/###/g,"."):e}function o(){return!e||"string"==typeof e}let i="string"!=typeof t?[].concat(t):t.split(".");for(;i.length>1;){if(o())return{};let t=r(i.shift());!e[t]&&n&&(e[t]=new n),e=Object.prototype.hasOwnProperty.call(e,t)?e[t]:{}}return o()?{}:{obj:e,k:r(i.shift())}}function u(e,t,n){let{obj:r,k:o}=c(e,t,Object);r[o]=n}function f(e,t){let{obj:n,k:r}=c(e,t);if(n)return n[r]}function d(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}var p={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};function h(e){return"string"==typeof e?e.replace(/[&<>"'\/]/g,e=>p[e]):e}let m=[" ",",","?","!",";"];function g(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:".";if(!e)return;if(e[t])return e[t];let r=t.split(n),o=e;for(let e=0;ee+i;)i++,l=o[a=r.slice(e,e+i).join(n)];if(void 0===l)return;if(null===l)return null;if(t.endsWith(a)){if("string"==typeof l)return l;if(a&&"string"==typeof l[a])return l[a]}let s=r.slice(e+i).join(n);if(s)return g(l,s,n);return}o=o[r[e]]}return o}function v(e){return e&&e.indexOf("_")>0?e.replace("_","-"):e}class y extends a{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{ns:["translation"],defaultNS:"translation"};super(),this.data=e||{},this.options=t,void 0===this.options.keySeparator&&(this.options.keySeparator="."),void 0===this.options.ignoreJSONStructure&&(this.options.ignoreJSONStructure=!0)}addNamespaces(e){0>this.options.ns.indexOf(e)&&this.options.ns.push(e)}removeNamespaces(e){let t=this.options.ns.indexOf(e);t>-1&&this.options.ns.splice(t,1)}getResource(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},o=void 0!==r.keySeparator?r.keySeparator:this.options.keySeparator,i=void 0!==r.ignoreJSONStructure?r.ignoreJSONStructure:this.options.ignoreJSONStructure,a=[e,t];n&&"string"!=typeof n&&(a=a.concat(n)),n&&"string"==typeof n&&(a=a.concat(o?n.split(o):n)),e.indexOf(".")>-1&&(a=e.split("."));let l=f(this.data,a);return l||!i||"string"!=typeof n?l:g(this.data&&this.data[e]&&this.data[e][t],n,o)}addResource(e,t,n,r){let o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{silent:!1},i=void 0!==o.keySeparator?o.keySeparator:this.options.keySeparator,a=[e,t];n&&(a=a.concat(i?n.split(i):n)),e.indexOf(".")>-1&&(a=e.split("."),r=t,t=a[1]),this.addNamespaces(t),u(this.data,a,r),o.silent||this.emit("added",e,t,n,r)}addResources(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{silent:!1};for(let r in n)("string"==typeof n[r]||"[object Array]"===Object.prototype.toString.apply(n[r]))&&this.addResource(e,t,r,n[r],{silent:!0});r.silent||this.emit("added",e,t,n)}addResourceBundle(e,t,n,r,o){let i=arguments.length>5&&void 0!==arguments[5]?arguments[5]:{silent:!1},a=[e,t];e.indexOf(".")>-1&&(a=e.split("."),r=n,n=t,t=a[1]),this.addNamespaces(t);let l=f(this.data,a)||{};r?function e(t,n,r){for(let o in n)"__proto__"!==o&&"constructor"!==o&&(o in t?"string"==typeof t[o]||t[o]instanceof String||"string"==typeof n[o]||n[o]instanceof String?r&&(t[o]=n[o]):e(t[o],n[o],r):t[o]=n[o]);return t}(l,n,o):l={...l,...n},u(this.data,a,l),i.silent||this.emit("added",e,t,n)}removeResourceBundle(e,t){this.hasResourceBundle(e,t)&&delete this.data[e][t],this.removeNamespaces(t),this.emit("removed",e,t)}hasResourceBundle(e,t){return void 0!==this.getResource(e,t)}getResourceBundle(e,t){return(t||(t=this.options.defaultNS),"v1"===this.options.compatibilityAPI)?{...this.getResource(e,t)}:this.getResource(e,t)}getDataByLanguage(e){return this.data[e]}hasLanguageSomeTranslations(e){let t=this.getDataByLanguage(e),n=t&&Object.keys(t)||[];return!!n.find(e=>t[e]&&Object.keys(t[e]).length>0)}toJSON(){return this.data}}var b={processors:{},addPostProcessor(e){this.processors[e.name]=e},handle(e,t,n,r,o){return e.forEach(e=>{this.processors[e]&&(t=this.processors[e].process(t,n,r,o))}),t}};let x={};class w extends a{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),function(e,t,n){e.forEach(e=>{t[e]&&(n[e]=t[e])})}(["resourceStore","languageUtils","pluralResolver","interpolator","backendConnector","i18nFormat","utils"],e,this),this.options=t,void 0===this.options.keySeparator&&(this.options.keySeparator="."),this.logger=i.create("translator")}changeLanguage(e){e&&(this.language=e)}exists(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{interpolation:{}};if(null==e)return!1;let n=this.resolve(e,t);return n&&void 0!==n.res}extractFromKey(e,t){let n=void 0!==t.nsSeparator?t.nsSeparator:this.options.nsSeparator;void 0===n&&(n=":");let r=void 0!==t.keySeparator?t.keySeparator:this.options.keySeparator,o=t.ns||this.options.defaultNS||[],i=n&&e.indexOf(n)>-1,a=!this.options.userDefinedKeySeparator&&!t.keySeparator&&!this.options.userDefinedNsSeparator&&!t.nsSeparator&&!function(e,t,n){t=t||"",n=n||"";let r=m.filter(e=>0>t.indexOf(e)&&0>n.indexOf(e));if(0===r.length)return!0;let o=RegExp(`(${r.map(e=>"?"===e?"\\?":e).join("|")})`),i=!o.test(e);if(!i){let t=e.indexOf(n);t>0&&!o.test(e.substring(0,t))&&(i=!0)}return i}(e,n,r);if(i&&!a){let t=e.match(this.interpolator.nestingRegexp);if(t&&t.length>0)return{key:e,namespaces:o};let i=e.split(n);(n!==r||n===r&&this.options.ns.indexOf(i[0])>-1)&&(o=i.shift()),e=i.join(r)}return"string"==typeof o&&(o=[o]),{key:e,namespaces:o}}translate(e,t,n){if("object"!=typeof t&&this.options.overloadTranslationOptionHandler&&(t=this.options.overloadTranslationOptionHandler(arguments)),"object"==typeof t&&(t={...t}),t||(t={}),null==e)return"";Array.isArray(e)||(e=[String(e)]);let r=void 0!==t.returnDetails?t.returnDetails:this.options.returnDetails,o=void 0!==t.keySeparator?t.keySeparator:this.options.keySeparator,{key:i,namespaces:a}=this.extractFromKey(e[e.length-1],t),l=a[a.length-1],s=t.lng||this.language,c=t.appendNamespaceToCIMode||this.options.appendNamespaceToCIMode;if(s&&"cimode"===s.toLowerCase()){if(c){let e=t.nsSeparator||this.options.nsSeparator;return r?{res:`${l}${e}${i}`,usedKey:i,exactUsedKey:i,usedLng:s,usedNS:l}:`${l}${e}${i}`}return r?{res:i,usedKey:i,exactUsedKey:i,usedLng:s,usedNS:l}:i}let u=this.resolve(e,t),f=u&&u.res,d=u&&u.usedKey||i,p=u&&u.exactUsedKey||i,h=Object.prototype.toString.apply(f),m=void 0!==t.joinArrays?t.joinArrays:this.options.joinArrays,g=!this.i18nFormat||this.i18nFormat.handleAsObject,v="string"!=typeof f&&"boolean"!=typeof f&&"number"!=typeof f;if(g&&f&&v&&0>["[object Number]","[object Function]","[object RegExp]"].indexOf(h)&&!("string"==typeof m&&"[object Array]"===h)){if(!t.returnObjects&&!this.options.returnObjects){this.options.returnedObjectHandler||this.logger.warn("accessing an object - but returnObjects options is not enabled!");let e=this.options.returnedObjectHandler?this.options.returnedObjectHandler(d,f,{...t,ns:a}):`key '${i} (${this.language})' returned an object instead of string.`;return r?(u.res=e,u):e}if(o){let e="[object Array]"===h,n=e?[]:{},r=e?p:d;for(let e in f)if(Object.prototype.hasOwnProperty.call(f,e)){let i=`${r}${o}${e}`;n[e]=this.translate(i,{...t,joinArrays:!1,ns:a}),n[e]===i&&(n[e]=f[e])}f=n}}else if(g&&"string"==typeof m&&"[object Array]"===h)(f=f.join(m))&&(f=this.extendTranslation(f,e,t,n));else{let r=!1,a=!1,c=void 0!==t.count&&"string"!=typeof t.count,d=w.hasDefaultValue(t),p=c?this.pluralResolver.getSuffix(s,t.count,t):"",h=t.ordinal&&c?this.pluralResolver.getSuffix(s,t.count,{ordinal:!1}):"",m=t[`defaultValue${p}`]||t[`defaultValue${h}`]||t.defaultValue;!this.isValidLookup(f)&&d&&(r=!0,f=m),this.isValidLookup(f)||(a=!0,f=i);let g=t.missingKeyNoValueFallbackToKey||this.options.missingKeyNoValueFallbackToKey,v=g&&a?void 0:f,y=d&&m!==f&&this.options.updateMissing;if(a||r||y){if(this.logger.log(y?"updateKey":"missingKey",s,l,i,y?m:f),o){let e=this.resolve(i,{...t,keySeparator:!1});e&&e.res&&this.logger.warn("Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.")}let e=[],n=this.languageUtils.getFallbackCodes(this.options.fallbackLng,t.lng||this.language);if("fallback"===this.options.saveMissingTo&&n&&n[0])for(let t=0;t{let o=d&&r!==f?r:v;this.options.missingKeyHandler?this.options.missingKeyHandler(e,l,n,o,y,t):this.backendConnector&&this.backendConnector.saveMissing&&this.backendConnector.saveMissing(e,l,n,o,y,t),this.emit("missingKey",e,l,n,f)};this.options.saveMissing&&(this.options.saveMissingPlurals&&c?e.forEach(e=>{this.pluralResolver.getSuffixes(e,t).forEach(n=>{r([e],i+n,t[`defaultValue${n}`]||m)})}):r(e,i,m))}f=this.extendTranslation(f,e,t,u,n),a&&f===i&&this.options.appendNamespaceToMissingKey&&(f=`${l}:${i}`),(a||r)&&this.options.parseMissingKeyHandler&&(f="v1"!==this.options.compatibilityAPI?this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey?`${l}:${i}`:i,r?f:void 0):this.options.parseMissingKeyHandler(f))}return r?(u.res=f,u):f}extendTranslation(e,t,n,r,o){var i=this;if(this.i18nFormat&&this.i18nFormat.parse)e=this.i18nFormat.parse(e,{...this.options.interpolation.defaultVariables,...n},n.lng||this.language||r.usedLng,r.usedNS,r.usedKey,{resolved:r});else if(!n.skipInterpolation){let a;n.interpolation&&this.interpolator.init({...n,interpolation:{...this.options.interpolation,...n.interpolation}});let l="string"==typeof e&&(n&&n.interpolation&&void 0!==n.interpolation.skipOnVariables?n.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables);if(l){let t=e.match(this.interpolator.nestingRegexp);a=t&&t.length}let s=n.replace&&"string"!=typeof n.replace?n.replace:n;if(this.options.interpolation.defaultVariables&&(s={...this.options.interpolation.defaultVariables,...s}),e=this.interpolator.interpolate(e,s,n.lng||this.language,n),l){let t=e.match(this.interpolator.nestingRegexp),r=t&&t.length;a1&&void 0!==arguments[1]?arguments[1]:{};return"string"==typeof e&&(e=[e]),e.forEach(e=>{if(this.isValidLookup(t))return;let l=this.extractFromKey(e,a),s=l.key;n=s;let c=l.namespaces;this.options.fallbackNS&&(c=c.concat(this.options.fallbackNS));let u=void 0!==a.count&&"string"!=typeof a.count,f=u&&!a.ordinal&&0===a.count&&this.pluralResolver.shouldUseIntlApi(),d=void 0!==a.context&&("string"==typeof a.context||"number"==typeof a.context)&&""!==a.context,p=a.lngs?a.lngs:this.languageUtils.toResolveHierarchy(a.lng||this.language,a.fallbackLng);c.forEach(e=>{this.isValidLookup(t)||(i=e,!x[`${p[0]}-${e}`]&&this.utils&&this.utils.hasLoadedNamespace&&!this.utils.hasLoadedNamespace(i)&&(x[`${p[0]}-${e}`]=!0,this.logger.warn(`key "${n}" for languages "${p.join(", ")}" won't get resolved as namespace "${i}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!")),p.forEach(n=>{let i;if(this.isValidLookup(t))return;o=n;let l=[s];if(this.i18nFormat&&this.i18nFormat.addLookupKeys)this.i18nFormat.addLookupKeys(l,s,n,e,a);else{let e;u&&(e=this.pluralResolver.getSuffix(n,a.count,a));let t=`${this.options.pluralSeparator}zero`,r=`${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;if(u&&(l.push(s+e),a.ordinal&&0===e.indexOf(r)&&l.push(s+e.replace(r,this.options.pluralSeparator)),f&&l.push(s+t)),d){let n=`${s}${this.options.contextSeparator}${a.context}`;l.push(n),u&&(l.push(n+e),a.ordinal&&0===e.indexOf(r)&&l.push(n+e.replace(r,this.options.pluralSeparator)),f&&l.push(n+t))}}for(;i=l.pop();)this.isValidLookup(t)||(r=i,t=this.getResource(n,e,i,a))}))})}),{res:t,usedKey:n,exactUsedKey:r,usedLng:o,usedNS:i}}isValidLookup(e){return void 0!==e&&!(!this.options.returnNull&&null===e)&&!(!this.options.returnEmptyString&&""===e)}getResource(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return this.i18nFormat&&this.i18nFormat.getResource?this.i18nFormat.getResource(e,t,n,r):this.resourceStore.getResource(e,t,n,r)}static hasDefaultValue(e){let t="defaultValue";for(let n in e)if(Object.prototype.hasOwnProperty.call(e,n)&&t===n.substring(0,t.length)&&void 0!==e[n])return!0;return!1}}function C(e){return e.charAt(0).toUpperCase()+e.slice(1)}class E{constructor(e){this.options=e,this.supportedLngs=this.options.supportedLngs||!1,this.logger=i.create("languageUtils")}getScriptPartFromCode(e){if(!(e=v(e))||0>e.indexOf("-"))return null;let t=e.split("-");return 2===t.length?null:(t.pop(),"x"===t[t.length-1].toLowerCase())?null:this.formatLanguageCode(t.join("-"))}getLanguagePartFromCode(e){if(!(e=v(e))||0>e.indexOf("-"))return e;let t=e.split("-");return this.formatLanguageCode(t[0])}formatLanguageCode(e){if("string"==typeof e&&e.indexOf("-")>-1){let t=["hans","hant","latn","cyrl","cans","mong","arab"],n=e.split("-");return this.options.lowerCaseLng?n=n.map(e=>e.toLowerCase()):2===n.length?(n[0]=n[0].toLowerCase(),n[1]=n[1].toUpperCase(),t.indexOf(n[1].toLowerCase())>-1&&(n[1]=C(n[1].toLowerCase()))):3===n.length&&(n[0]=n[0].toLowerCase(),2===n[1].length&&(n[1]=n[1].toUpperCase()),"sgn"!==n[0]&&2===n[2].length&&(n[2]=n[2].toUpperCase()),t.indexOf(n[1].toLowerCase())>-1&&(n[1]=C(n[1].toLowerCase())),t.indexOf(n[2].toLowerCase())>-1&&(n[2]=C(n[2].toLowerCase()))),n.join("-")}return this.options.cleanCode||this.options.lowerCaseLng?e.toLowerCase():e}isSupportedCode(e){return("languageOnly"===this.options.load||this.options.nonExplicitSupportedLngs)&&(e=this.getLanguagePartFromCode(e)),!this.supportedLngs||!this.supportedLngs.length||this.supportedLngs.indexOf(e)>-1}getBestMatchFromCodes(e){let t;return e?(e.forEach(e=>{if(t)return;let n=this.formatLanguageCode(e);(!this.options.supportedLngs||this.isSupportedCode(n))&&(t=n)}),!t&&this.options.supportedLngs&&e.forEach(e=>{if(t)return;let n=this.getLanguagePartFromCode(e);if(this.isSupportedCode(n))return t=n;t=this.options.supportedLngs.find(e=>{if(e===n||!(0>e.indexOf("-")&&0>n.indexOf("-"))&&0===e.indexOf(n))return e})}),t||(t=this.getFallbackCodes(this.options.fallbackLng)[0]),t):null}getFallbackCodes(e,t){if(!e)return[];if("function"==typeof e&&(e=e(t)),"string"==typeof e&&(e=[e]),"[object Array]"===Object.prototype.toString.apply(e))return e;if(!t)return e.default||[];let n=e[t];return n||(n=e[this.getScriptPartFromCode(t)]),n||(n=e[this.formatLanguageCode(t)]),n||(n=e[this.getLanguagePartFromCode(t)]),n||(n=e.default),n||[]}toResolveHierarchy(e,t){let n=this.getFallbackCodes(t||this.options.fallbackLng||[],e),r=[],o=e=>{e&&(this.isSupportedCode(e)?r.push(e):this.logger.warn(`rejecting language code not found in supportedLngs: ${e}`))};return"string"==typeof e&&(e.indexOf("-")>-1||e.indexOf("_")>-1)?("languageOnly"!==this.options.load&&o(this.formatLanguageCode(e)),"languageOnly"!==this.options.load&&"currentOnly"!==this.options.load&&o(this.getScriptPartFromCode(e)),"currentOnly"!==this.options.load&&o(this.getLanguagePartFromCode(e))):"string"==typeof e&&o(this.formatLanguageCode(e)),n.forEach(e=>{0>r.indexOf(e)&&o(this.formatLanguageCode(e))}),r}}let S=[{lngs:["ach","ak","am","arn","br","fil","gun","ln","mfe","mg","mi","oc","pt","pt-BR","tg","tl","ti","tr","uz","wa"],nr:[1,2],fc:1},{lngs:["af","an","ast","az","bg","bn","ca","da","de","dev","el","en","eo","es","et","eu","fi","fo","fur","fy","gl","gu","ha","hi","hu","hy","ia","it","kk","kn","ku","lb","mai","ml","mn","mr","nah","nap","nb","ne","nl","nn","no","nso","pa","pap","pms","ps","pt-PT","rm","sco","se","si","so","son","sq","sv","sw","ta","te","tk","ur","yo"],nr:[1,2],fc:2},{lngs:["ay","bo","cgg","fa","ht","id","ja","jbo","ka","km","ko","ky","lo","ms","sah","su","th","tt","ug","vi","wo","zh"],nr:[1],fc:3},{lngs:["be","bs","cnr","dz","hr","ru","sr","uk"],nr:[1,2,5],fc:4},{lngs:["ar"],nr:[0,1,2,3,11,100],fc:5},{lngs:["cs","sk"],nr:[1,2,5],fc:6},{lngs:["csb","pl"],nr:[1,2,5],fc:7},{lngs:["cy"],nr:[1,2,3,8],fc:8},{lngs:["fr"],nr:[1,2],fc:9},{lngs:["ga"],nr:[1,2,3,7,11],fc:10},{lngs:["gd"],nr:[1,2,3,20],fc:11},{lngs:["is"],nr:[1,2],fc:12},{lngs:["jv"],nr:[0,1],fc:13},{lngs:["kw"],nr:[1,2,3,4],fc:14},{lngs:["lt"],nr:[1,2,10],fc:15},{lngs:["lv"],nr:[1,2,0],fc:16},{lngs:["mk"],nr:[1,2],fc:17},{lngs:["mnk"],nr:[0,1,2],fc:18},{lngs:["mt"],nr:[1,2,11,20],fc:19},{lngs:["or"],nr:[2,1],fc:2},{lngs:["ro"],nr:[1,2,20],fc:20},{lngs:["sl"],nr:[5,1,2,3],fc:21},{lngs:["he","iw"],nr:[1,2,20,21],fc:22}],$={1:function(e){return Number(e>1)},2:function(e){return Number(1!=e)},3:function(e){return 0},4:function(e){return Number(e%10==1&&e%100!=11?0:e%10>=2&&e%10<=4&&(e%100<10||e%100>=20)?1:2)},5:function(e){return Number(0==e?0:1==e?1:2==e?2:e%100>=3&&e%100<=10?3:e%100>=11?4:5)},6:function(e){return Number(1==e?0:e>=2&&e<=4?1:2)},7:function(e){return Number(1==e?0:e%10>=2&&e%10<=4&&(e%100<10||e%100>=20)?1:2)},8:function(e){return Number(1==e?0:2==e?1:8!=e&&11!=e?2:3)},9:function(e){return Number(e>=2)},10:function(e){return Number(1==e?0:2==e?1:e<7?2:e<11?3:4)},11:function(e){return Number(1==e||11==e?0:2==e||12==e?1:e>2&&e<20?2:3)},12:function(e){return Number(e%10!=1||e%100==11)},13:function(e){return Number(0!==e)},14:function(e){return Number(1==e?0:2==e?1:3==e?2:3)},15:function(e){return Number(e%10==1&&e%100!=11?0:e%10>=2&&(e%100<10||e%100>=20)?1:2)},16:function(e){return Number(e%10==1&&e%100!=11?0:0!==e?1:2)},17:function(e){return Number(1==e||e%10==1&&e%100!=11?0:1)},18:function(e){return Number(0==e?0:1==e?1:2)},19:function(e){return Number(1==e?0:0==e||e%100>1&&e%100<11?1:e%100>10&&e%100<20?2:3)},20:function(e){return Number(1==e?0:0==e||e%100>0&&e%100<20?1:2)},21:function(e){return Number(e%100==1?1:e%100==2?2:e%100==3||e%100==4?3:0)},22:function(e){return Number(1==e?0:2==e?1:(e<0||e>10)&&e%10==0?2:3)}},O=["v1","v2","v3"],k=["v4"],Z={zero:0,one:1,two:2,few:3,many:4,other:5};class P{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.languageUtils=e,this.options=t,this.logger=i.create("pluralResolver"),(!this.options.compatibilityJSON||k.includes(this.options.compatibilityJSON))&&("undefined"==typeof Intl||!Intl.PluralRules)&&(this.options.compatibilityJSON="v3",this.logger.error("Your environment seems not to be Intl API compatible, use an Intl.PluralRules polyfill. Will fallback to the compatibilityJSON v3 format handling.")),this.rules=function(){let e={};return S.forEach(t=>{t.lngs.forEach(n=>{e[n]={numbers:t.nr,plurals:$[t.fc]}})}),e}()}addRule(e,t){this.rules[e]=t}getRule(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(this.shouldUseIntlApi())try{return new Intl.PluralRules(v(e),{type:t.ordinal?"ordinal":"cardinal"})}catch{return}return this.rules[e]||this.rules[this.languageUtils.getLanguagePartFromCode(e)]}needsPlural(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=this.getRule(e,t);return this.shouldUseIntlApi()?n&&n.resolvedOptions().pluralCategories.length>1:n&&n.numbers.length>1}getPluralFormsOfKey(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return this.getSuffixes(e,n).map(e=>`${t}${e}`)}getSuffixes(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=this.getRule(e,t);return n?this.shouldUseIntlApi()?n.resolvedOptions().pluralCategories.sort((e,t)=>Z[e]-Z[t]).map(e=>`${this.options.prepend}${t.ordinal?`ordinal${this.options.prepend}`:""}${e}`):n.numbers.map(n=>this.getSuffix(e,n,t)):[]}getSuffix(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=this.getRule(e,n);return r?this.shouldUseIntlApi()?`${this.options.prepend}${n.ordinal?`ordinal${this.options.prepend}`:""}${r.select(t)}`:this.getSuffixRetroCompatible(r,t):(this.logger.warn(`no plural rule found for: ${e}`),"")}getSuffixRetroCompatible(e,t){let n=e.noAbs?e.plurals(t):e.plurals(Math.abs(t)),r=e.numbers[n];this.options.simplifyPluralSuffix&&2===e.numbers.length&&1===e.numbers[0]&&(2===r?r="plural":1===r&&(r=""));let o=()=>this.options.prepend&&r.toString()?this.options.prepend+r.toString():r.toString();return"v1"===this.options.compatibilityJSON?1===r?"":"number"==typeof r?`_plural_${r.toString()}`:o():"v2"===this.options.compatibilityJSON||this.options.simplifyPluralSuffix&&2===e.numbers.length&&1===e.numbers[0]?o():this.options.prepend&&n.toString()?this.options.prepend+n.toString():n.toString()}shouldUseIntlApi(){return!O.includes(this.options.compatibilityJSON)}}function j(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:".",o=!(arguments.length>4)||void 0===arguments[4]||arguments[4],i=function(e,t,n){let r=f(e,n);return void 0!==r?r:f(t,n)}(e,t,n);return!i&&o&&"string"==typeof n&&void 0===(i=g(e,n,r))&&(i=g(t,n,r)),i}class _{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.logger=i.create("interpolator"),this.options=e,this.format=e.interpolation&&e.interpolation.format||(e=>e),this.init(e)}init(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e.interpolation||(e.interpolation={escapeValue:!0});let t=e.interpolation;this.escape=void 0!==t.escape?t.escape:h,this.escapeValue=void 0===t.escapeValue||t.escapeValue,this.useRawValueToEscape=void 0!==t.useRawValueToEscape&&t.useRawValueToEscape,this.prefix=t.prefix?d(t.prefix):t.prefixEscaped||"{{",this.suffix=t.suffix?d(t.suffix):t.suffixEscaped||"}}",this.formatSeparator=t.formatSeparator?t.formatSeparator:t.formatSeparator||",",this.unescapePrefix=t.unescapeSuffix?"":t.unescapePrefix||"-",this.unescapeSuffix=this.unescapePrefix?"":t.unescapeSuffix||"",this.nestingPrefix=t.nestingPrefix?d(t.nestingPrefix):t.nestingPrefixEscaped||d("$t("),this.nestingSuffix=t.nestingSuffix?d(t.nestingSuffix):t.nestingSuffixEscaped||d(")"),this.nestingOptionsSeparator=t.nestingOptionsSeparator?t.nestingOptionsSeparator:t.nestingOptionsSeparator||",",this.maxReplaces=t.maxReplaces?t.maxReplaces:1e3,this.alwaysFormat=void 0!==t.alwaysFormat&&t.alwaysFormat,this.resetRegExp()}reset(){this.options&&this.init(this.options)}resetRegExp(){let e=`${this.prefix}(.+?)${this.suffix}`;this.regexp=RegExp(e,"g");let t=`${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`;this.regexpUnescape=RegExp(t,"g");let n=`${this.nestingPrefix}(.+?)${this.nestingSuffix}`;this.nestingRegexp=RegExp(n,"g")}interpolate(e,t,n,r){let o,i,a;let l=this.options&&this.options.interpolation&&this.options.interpolation.defaultVariables||{};function c(e){return e.replace(/\$/g,"$$$$")}let u=e=>{if(0>e.indexOf(this.formatSeparator)){let o=j(t,l,e,this.options.keySeparator,this.options.ignoreJSONStructure);return this.alwaysFormat?this.format(o,void 0,n,{...r,...t,interpolationkey:e}):o}let o=e.split(this.formatSeparator),i=o.shift().trim(),a=o.join(this.formatSeparator).trim();return this.format(j(t,l,i,this.options.keySeparator,this.options.ignoreJSONStructure),a,n,{...r,...t,interpolationkey:i})};this.resetRegExp();let f=r&&r.missingInterpolationHandler||this.options.missingInterpolationHandler,d=r&&r.interpolation&&void 0!==r.interpolation.skipOnVariables?r.interpolation.skipOnVariables:this.options.interpolation.skipOnVariables,p=[{regex:this.regexpUnescape,safeValue:e=>c(e)},{regex:this.regexp,safeValue:e=>this.escapeValue?c(this.escape(e)):c(e)}];return p.forEach(t=>{for(a=0;o=t.regex.exec(e);){let n=o[1].trim();if(void 0===(i=u(n))){if("function"==typeof f){let t=f(e,o,r);i="string"==typeof t?t:""}else if(r&&Object.prototype.hasOwnProperty.call(r,n))i="";else if(d){i=o[0];continue}else this.logger.warn(`missed to pass in variable ${n} for interpolating ${e}`),i=""}else"string"==typeof i||this.useRawValueToEscape||(i=s(i));let l=t.safeValue(i);if(e=e.replace(o[0],l),d?(t.regex.lastIndex+=i.length,t.regex.lastIndex-=o[0].length):t.regex.lastIndex=0,++a>=this.maxReplaces)break}}),e}nest(e,t){let n,r,o,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};function a(e,t){let n=this.nestingOptionsSeparator;if(0>e.indexOf(n))return e;let r=e.split(RegExp(`${n}[ ]*{`)),i=`{${r[1]}`;e=r[0],i=this.interpolate(i,o);let a=i.match(/'/g),l=i.match(/"/g);(a&&a.length%2==0&&!l||l.length%2!=0)&&(i=i.replace(/'/g,'"'));try{o=JSON.parse(i),t&&(o={...t,...o})}catch(t){return this.logger.warn(`failed parsing options string in nesting for key ${e}`,t),`${e}${n}${i}`}return delete o.defaultValue,e}for(;n=this.nestingRegexp.exec(e);){let l=[];(o=(o={...i}).replace&&"string"!=typeof o.replace?o.replace:o).applyPostProcessor=!1,delete o.defaultValue;let c=!1;if(-1!==n[0].indexOf(this.formatSeparator)&&!/{.*}/.test(n[1])){let e=n[1].split(this.formatSeparator).map(e=>e.trim());n[1]=e.shift(),l=e,c=!0}if((r=t(a.call(this,n[1].trim(),o),o))&&n[0]===e&&"string"!=typeof r)return r;"string"!=typeof r&&(r=s(r)),r||(this.logger.warn(`missed to resolve ${n[1]} for nesting ${e}`),r=""),c&&(r=l.reduce((e,t)=>this.format(e,t,i.lng,{...i,interpolationkey:n[1].trim()}),r.trim())),e=e.replace(n[0],r),this.regexp.lastIndex=0}return e}}function R(e){let t={};return function(n,r,o){let i=r+JSON.stringify(o),a=t[i];return a||(a=e(v(r),o),t[i]=a),a(n)}}class A{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.logger=i.create("formatter"),this.options=e,this.formats={number:R((e,t)=>{let n=new Intl.NumberFormat(e,{...t});return e=>n.format(e)}),currency:R((e,t)=>{let n=new Intl.NumberFormat(e,{...t,style:"currency"});return e=>n.format(e)}),datetime:R((e,t)=>{let n=new Intl.DateTimeFormat(e,{...t});return e=>n.format(e)}),relativetime:R((e,t)=>{let n=new Intl.RelativeTimeFormat(e,{...t});return e=>n.format(e,t.range||"day")}),list:R((e,t)=>{let n=new Intl.ListFormat(e,{...t});return e=>n.format(e)})},this.init(e)}init(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{interpolation:{}},n=t.interpolation;this.formatSeparator=n.formatSeparator?n.formatSeparator:n.formatSeparator||","}add(e,t){this.formats[e.toLowerCase().trim()]=t}addCached(e,t){this.formats[e.toLowerCase().trim()]=R(t)}format(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},o=t.split(this.formatSeparator),i=o.reduce((e,t)=>{let{formatName:o,formatOptions:i}=function(e){let t=e.toLowerCase().trim(),n={};if(e.indexOf("(")>-1){let r=e.split("(");t=r[0].toLowerCase().trim();let o=r[1].substring(0,r[1].length-1);if("currency"===t&&0>o.indexOf(":"))n.currency||(n.currency=o.trim());else if("relativetime"===t&&0>o.indexOf(":"))n.range||(n.range=o.trim());else{let e=o.split(";");e.forEach(e=>{if(!e)return;let[t,...r]=e.split(":"),o=r.join(":").trim().replace(/^'+|'+$/g,"");n[t.trim()]||(n[t.trim()]=o),"false"===o&&(n[t.trim()]=!1),"true"===o&&(n[t.trim()]=!0),isNaN(o)||(n[t.trim()]=parseInt(o,10))})}}return{formatName:t,formatOptions:n}}(t);if(this.formats[o]){let t=e;try{let a=r&&r.formatParams&&r.formatParams[r.interpolationkey]||{},l=a.locale||a.lng||r.locale||r.lng||n;t=this.formats[o](e,l,{...i,...r,...a})}catch(e){this.logger.warn(e)}return t}return this.logger.warn(`there was no format function for ${o}`),e},e);return i}}class N extends a{constructor(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};super(),this.backend=e,this.store=t,this.services=n,this.languageUtils=n.languageUtils,this.options=r,this.logger=i.create("backendConnector"),this.waitingReads=[],this.maxParallelReads=r.maxParallelReads||10,this.readingCalls=0,this.maxRetries=r.maxRetries>=0?r.maxRetries:5,this.retryTimeout=r.retryTimeout>=1?r.retryTimeout:350,this.state={},this.queue=[],this.backend&&this.backend.init&&this.backend.init(n,r.backend,r)}queueLoad(e,t,n,r){let o={},i={},a={},l={};return e.forEach(e=>{let r=!0;t.forEach(t=>{let a=`${e}|${t}`;!n.reload&&this.store.hasResourceBundle(e,t)?this.state[a]=2:this.state[a]<0||(1===this.state[a]?void 0===i[a]&&(i[a]=!0):(this.state[a]=1,r=!1,void 0===i[a]&&(i[a]=!0),void 0===o[a]&&(o[a]=!0),void 0===l[t]&&(l[t]=!0)))}),r||(a[e]=!0)}),(Object.keys(o).length||Object.keys(i).length)&&this.queue.push({pending:i,pendingCount:Object.keys(i).length,loaded:{},errors:[],callback:r}),{toLoad:Object.keys(o),pending:Object.keys(i),toLoadLanguages:Object.keys(a),toLoadNamespaces:Object.keys(l)}}loaded(e,t,n){let r=e.split("|"),o=r[0],i=r[1];t&&this.emit("failedLoading",o,i,t),n&&this.store.addResourceBundle(o,i,n),this.state[e]=t?-1:2;let a={};this.queue.forEach(n=>{(function(e,t,n,r){let{obj:o,k:i}=c(e,t,Object);o[i]=o[i]||[],r&&(o[i]=o[i].concat(n)),r||o[i].push(n)})(n.loaded,[o],i),void 0!==n.pending[e]&&(delete n.pending[e],n.pendingCount--),t&&n.errors.push(t),0!==n.pendingCount||n.done||(Object.keys(n.loaded).forEach(e=>{a[e]||(a[e]={});let t=n.loaded[e];t.length&&t.forEach(t=>{void 0===a[e][t]&&(a[e][t]=!0)})}),n.done=!0,n.errors.length?n.callback(n.errors):n.callback())}),this.emit("loaded",a),this.queue=this.queue.filter(e=>!e.done)}read(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:this.retryTimeout,i=arguments.length>5?arguments[5]:void 0;if(!e.length)return i(null,{});if(this.readingCalls>=this.maxParallelReads){this.waitingReads.push({lng:e,ns:t,fcName:n,tried:r,wait:o,callback:i});return}this.readingCalls++;let a=(a,l)=>{if(this.readingCalls--,this.waitingReads.length>0){let e=this.waitingReads.shift();this.read(e.lng,e.ns,e.fcName,e.tried,e.wait,e.callback)}if(a&&l&&r{this.read.call(this,e,t,n,r+1,2*o,i)},o);return}i(a,l)},l=this.backend[n].bind(this.backend);if(2===l.length){try{let n=l(e,t);n&&"function"==typeof n.then?n.then(e=>a(null,e)).catch(a):a(null,n)}catch(e){a(e)}return}return l(e,t,a)}prepareLoading(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=arguments.length>3?arguments[3]:void 0;if(!this.backend)return this.logger.warn("No backend was added via i18next.use. Will not load resources."),r&&r();"string"==typeof e&&(e=this.languageUtils.toResolveHierarchy(e)),"string"==typeof t&&(t=[t]);let o=this.queueLoad(e,t,n,r);if(!o.toLoad.length)return o.pending.length||r(),null;o.toLoad.forEach(e=>{this.loadOne(e)})}load(e,t,n){this.prepareLoading(e,t,{},n)}reload(e,t,n){this.prepareLoading(e,t,{reload:!0},n)}loadOne(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=e.split("|"),r=n[0],o=n[1];this.read(r,o,"read",void 0,void 0,(n,i)=>{n&&this.logger.warn(`${t}loading namespace ${o} for language ${r} failed`,n),!n&&i&&this.logger.log(`${t}loaded namespace ${o} for language ${r}`,i),this.loaded(e,n,i)})}saveMissing(e,t,n,r,o){let i=arguments.length>5&&void 0!==arguments[5]?arguments[5]:{},a=arguments.length>6&&void 0!==arguments[6]?arguments[6]:()=>{};if(this.services.utils&&this.services.utils.hasLoadedNamespace&&!this.services.utils.hasLoadedNamespace(t)){this.logger.warn(`did not save key "${n}" as the namespace "${t}" was not yet loaded`,"This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!");return}if(null!=n&&""!==n){if(this.backend&&this.backend.create){let l={...i,isUpdate:o},s=this.backend.create.bind(this.backend);if(s.length<6)try{let o;(o=5===s.length?s(e,t,n,r,l):s(e,t,n,r))&&"function"==typeof o.then?o.then(e=>a(null,e)).catch(a):a(null,o)}catch(e){a(e)}else s(e,t,n,r,a,l)}e&&e[0]&&this.store.addResource(e[0],t,n,r)}}}function T(){return{debug:!1,initImmediate:!0,ns:["translation"],defaultNS:["translation"],fallbackLng:["dev"],fallbackNS:!1,supportedLngs:!1,nonExplicitSupportedLngs:!1,load:"all",preload:!1,simplifyPluralSuffix:!0,keySeparator:".",nsSeparator:":",pluralSeparator:"_",contextSeparator:"_",partialBundledLanguages:!1,saveMissing:!1,updateMissing:!1,saveMissingTo:"fallback",saveMissingPlurals:!0,missingKeyHandler:!1,missingInterpolationHandler:!1,postProcess:!1,postProcessPassResolved:!1,returnNull:!1,returnEmptyString:!0,returnObjects:!1,joinArrays:!1,returnedObjectHandler:!1,parseMissingKeyHandler:!1,appendNamespaceToMissingKey:!1,appendNamespaceToCIMode:!1,overloadTranslationOptionHandler:function(e){let t={};if("object"==typeof e[1]&&(t=e[1]),"string"==typeof e[1]&&(t.defaultValue=e[1]),"string"==typeof e[2]&&(t.tDescription=e[2]),"object"==typeof e[2]||"object"==typeof e[3]){let n=e[3]||e[2];Object.keys(n).forEach(e=>{t[e]=n[e]})}return t},interpolation:{escapeValue:!0,format:(e,t,n,r)=>e,prefix:"{{",suffix:"}}",formatSeparator:",",unescapePrefix:"-",nestingPrefix:"$t(",nestingSuffix:")",nestingOptionsSeparator:",",maxReplaces:1e3,skipOnVariables:!0}}}function M(e){return"string"==typeof e.ns&&(e.ns=[e.ns]),"string"==typeof e.fallbackLng&&(e.fallbackLng=[e.fallbackLng]),"string"==typeof e.fallbackNS&&(e.fallbackNS=[e.fallbackNS]),e.supportedLngs&&0>e.supportedLngs.indexOf("cimode")&&(e.supportedLngs=e.supportedLngs.concat(["cimode"])),e}function I(){}class F extends a{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0;if(super(),this.options=M(e),this.services={},this.logger=i,this.modules={external:[]},!function(e){let t=Object.getOwnPropertyNames(Object.getPrototypeOf(e));t.forEach(t=>{"function"==typeof e[t]&&(e[t]=e[t].bind(e))})}(this),t&&!this.isInitialized&&!e.isClone){if(!this.options.initImmediate)return this.init(e,t),this;setTimeout(()=>{this.init(e,t)},0)}}init(){var e=this;let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=arguments.length>1?arguments[1]:void 0;"function"==typeof t&&(n=t,t={}),!t.defaultNS&&!1!==t.defaultNS&&t.ns&&("string"==typeof t.ns?t.defaultNS=t.ns:0>t.ns.indexOf("translation")&&(t.defaultNS=t.ns[0]));let r=T();function o(e){return e?"function"==typeof e?new e:e:null}if(this.options={...r,...this.options,...M(t)},"v1"!==this.options.compatibilityAPI&&(this.options.interpolation={...r.interpolation,...this.options.interpolation}),void 0!==t.keySeparator&&(this.options.userDefinedKeySeparator=t.keySeparator),void 0!==t.nsSeparator&&(this.options.userDefinedNsSeparator=t.nsSeparator),!this.options.isClone){let t;this.modules.logger?i.init(o(this.modules.logger),this.options):i.init(null,this.options),this.modules.formatter?t=this.modules.formatter:"undefined"!=typeof Intl&&(t=A);let n=new E(this.options);this.store=new y(this.options.resources,this.options);let a=this.services;a.logger=i,a.resourceStore=this.store,a.languageUtils=n,a.pluralResolver=new P(n,{prepend:this.options.pluralSeparator,compatibilityJSON:this.options.compatibilityJSON,simplifyPluralSuffix:this.options.simplifyPluralSuffix}),t&&(!this.options.interpolation.format||this.options.interpolation.format===r.interpolation.format)&&(a.formatter=o(t),a.formatter.init(a,this.options),this.options.interpolation.format=a.formatter.format.bind(a.formatter)),a.interpolator=new _(this.options),a.utils={hasLoadedNamespace:this.hasLoadedNamespace.bind(this)},a.backendConnector=new N(o(this.modules.backend),a.resourceStore,a,this.options),a.backendConnector.on("*",function(t){for(var n=arguments.length,r=Array(n>1?n-1:0),o=1;o1?n-1:0),o=1;o{e.init&&e.init(this)})}if(this.format=this.options.interpolation.format,n||(n=I),this.options.fallbackLng&&!this.services.languageDetector&&!this.options.lng){let e=this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);e.length>0&&"dev"!==e[0]&&(this.options.lng=e[0])}this.services.languageDetector||this.options.lng||this.logger.warn("init: no languageDetector is used and no lng is defined"),["getResource","hasResourceBundle","getResourceBundle","getDataByLanguage"].forEach(t=>{this[t]=function(){return e.store[t](...arguments)}}),["addResource","addResources","addResourceBundle","removeResourceBundle"].forEach(t=>{this[t]=function(){return e.store[t](...arguments),e}});let a=l(),s=()=>{let e=(e,t)=>{this.isInitialized&&!this.initializedStoreOnce&&this.logger.warn("init: i18next is already initialized. You should call init just once!"),this.isInitialized=!0,this.options.isClone||this.logger.log("initialized",this.options),this.emit("initialized",this.options),a.resolve(t),n(e,t)};if(this.languages&&"v1"!==this.options.compatibilityAPI&&!this.isInitialized)return e(null,this.t.bind(this));this.changeLanguage(this.options.lng,e)};return this.options.resources||!this.options.initImmediate?s():setTimeout(s,0),a}loadResources(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:I,n=t,r="string"==typeof e?e:this.language;if("function"==typeof e&&(n=e),!this.options.resources||this.options.partialBundledLanguages){if(r&&"cimode"===r.toLowerCase()&&(!this.options.preload||0===this.options.preload.length))return n();let e=[],t=t=>{if(!t||"cimode"===t)return;let n=this.services.languageUtils.toResolveHierarchy(t);n.forEach(t=>{"cimode"!==t&&0>e.indexOf(t)&&e.push(t)})};if(r)t(r);else{let e=this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);e.forEach(e=>t(e))}this.options.preload&&this.options.preload.forEach(e=>t(e)),this.services.backendConnector.load(e,this.options.ns,e=>{e||this.resolvedLanguage||!this.language||this.setResolvedLanguage(this.language),n(e)})}else n(null)}reloadResources(e,t,n){let r=l();return e||(e=this.languages),t||(t=this.options.ns),n||(n=I),this.services.backendConnector.reload(e,t,e=>{r.resolve(),n(e)}),r}use(e){if(!e)throw Error("You are passing an undefined module! Please check the object you are passing to i18next.use()");if(!e.type)throw Error("You are passing a wrong module! Please check the object you are passing to i18next.use()");return"backend"===e.type&&(this.modules.backend=e),("logger"===e.type||e.log&&e.warn&&e.error)&&(this.modules.logger=e),"languageDetector"===e.type&&(this.modules.languageDetector=e),"i18nFormat"===e.type&&(this.modules.i18nFormat=e),"postProcessor"===e.type&&b.addPostProcessor(e),"formatter"===e.type&&(this.modules.formatter=e),"3rdParty"===e.type&&this.modules.external.push(e),this}setResolvedLanguage(e){if(e&&this.languages&&!(["cimode","dev"].indexOf(e)>-1))for(let e=0;e-1)&&this.store.hasLanguageSomeTranslations(t)){this.resolvedLanguage=t;break}}}changeLanguage(e,t){var n=this;this.isLanguageChangingTo=e;let r=l();this.emit("languageChanging",e);let o=e=>{this.language=e,this.languages=this.services.languageUtils.toResolveHierarchy(e),this.resolvedLanguage=void 0,this.setResolvedLanguage(e)},i=(e,i)=>{i?(o(i),this.translator.changeLanguage(i),this.isLanguageChangingTo=void 0,this.emit("languageChanged",i),this.logger.log("languageChanged",i)):this.isLanguageChangingTo=void 0,r.resolve(function(){return n.t(...arguments)}),t&&t(e,function(){return n.t(...arguments)})},a=t=>{e||t||!this.services.languageDetector||(t=[]);let n="string"==typeof t?t:this.services.languageUtils.getBestMatchFromCodes(t);n&&(this.language||o(n),this.translator.language||this.translator.changeLanguage(n),this.services.languageDetector&&this.services.languageDetector.cacheUserLanguage&&this.services.languageDetector.cacheUserLanguage(n)),this.loadResources(n,e=>{i(e,n)})};return e||!this.services.languageDetector||this.services.languageDetector.async?!e&&this.services.languageDetector&&this.services.languageDetector.async?0===this.services.languageDetector.detect.length?this.services.languageDetector.detect().then(a):this.services.languageDetector.detect(a):a(e):a(this.services.languageDetector.detect()),r}getFixedT(e,t,n){var r=this;let o=function(e,t){let i,a;if("object"!=typeof t){for(var l=arguments.length,s=Array(l>2?l-2:0),c=2;c`${i.keyPrefix}${u}${e}`):i.keyPrefix?`${i.keyPrefix}${u}${e}`:e,r.t(a,i)};return"string"==typeof e?o.lng=e:o.lngs=e,o.ns=t,o.keyPrefix=n,o}t(){return this.translator&&this.translator.translate(...arguments)}exists(){return this.translator&&this.translator.exists(...arguments)}setDefaultNamespace(e){this.options.defaultNS=e}hasLoadedNamespace(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!this.isInitialized)return this.logger.warn("hasLoadedNamespace: i18next was not initialized",this.languages),!1;if(!this.languages||!this.languages.length)return this.logger.warn("hasLoadedNamespace: i18n.languages were undefined or empty",this.languages),!1;let n=t.lng||this.resolvedLanguage||this.languages[0],r=!!this.options&&this.options.fallbackLng,o=this.languages[this.languages.length-1];if("cimode"===n.toLowerCase())return!0;let i=(e,t)=>{let n=this.services.backendConnector.state[`${e}|${t}`];return -1===n||2===n};if(t.precheck){let e=t.precheck(this,i);if(void 0!==e)return e}return!!(this.hasResourceBundle(n,e)||!this.services.backendConnector.backend||this.options.resources&&!this.options.partialBundledLanguages||i(n,e)&&(!r||i(o,e)))}loadNamespaces(e,t){let n=l();return this.options.ns?("string"==typeof e&&(e=[e]),e.forEach(e=>{0>this.options.ns.indexOf(e)&&this.options.ns.push(e)}),this.loadResources(e=>{n.resolve(),t&&t(e)}),n):(t&&t(),Promise.resolve())}loadLanguages(e,t){let n=l();"string"==typeof e&&(e=[e]);let r=this.options.preload||[],o=e.filter(e=>0>r.indexOf(e));return o.length?(this.options.preload=r.concat(o),this.loadResources(e=>{n.resolve(),t&&t(e)}),n):(t&&t(),Promise.resolve())}dir(e){if(e||(e=this.resolvedLanguage||(this.languages&&this.languages.length>0?this.languages[0]:this.language)),!e)return"rtl";let t=this.services&&this.services.languageUtils||new E(T());return["ar","shu","sqr","ssh","xaa","yhd","yud","aao","abh","abv","acm","acq","acw","acx","acy","adf","ads","aeb","aec","afb","ajp","apc","apd","arb","arq","ars","ary","arz","auz","avl","ayh","ayl","ayn","ayp","bbz","pga","he","iw","ps","pbt","pbu","pst","prp","prd","ug","ur","ydd","yds","yih","ji","yi","hbo","men","xmn","fa","jpr","peo","pes","prs","dv","sam","ckb"].indexOf(t.getLanguagePartFromCode(e))>-1||e.toLowerCase().indexOf("-arab")>1?"rtl":"ltr"}static createInstance(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0;return new F(e,t)}cloneInstance(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:I,n=e.forkResourceStore;n&&delete e.forkResourceStore;let r={...this.options,...e,isClone:!0},o=new F(r);return(void 0!==e.debug||void 0!==e.prefix)&&(o.logger=o.logger.clone(e)),["store","services","language"].forEach(e=>{o[e]=this[e]}),o.services={...this.services},o.services.utils={hasLoadedNamespace:o.hasLoadedNamespace.bind(o)},n&&(o.store=new y(this.store.data,r),o.services.resourceStore=o.store),o.translator=new w(o.services,r),o.translator.on("*",function(e){for(var t=arguments.length,n=Array(t>1?t-1:0),r=1;r{let{componentCls:t,width:n,notificationMarginEdge:r}=e,o=new y.E4("antNotificationTopFadeIn",{"0%":{marginTop:"-100%",opacity:0},"100%":{marginTop:0,opacity:1}}),i=new y.E4("antNotificationBottomFadeIn",{"0%":{marginBottom:"-100%",opacity:0},"100%":{marginBottom:0,opacity:1}}),a=new y.E4("antNotificationLeftFadeIn",{"0%":{right:{_skip_check_:!0,value:n},opacity:0},"100%":{right:{_skip_check_:!0,value:0},opacity:1}});return{[`&${t}-top, &${t}-bottom`]:{marginInline:0},[`&${t}-top`]:{[`${t}-fade-enter${t}-fade-enter-active, ${t}-fade-appear${t}-fade-appear-active`]:{animationName:o}},[`&${t}-bottom`]:{[`${t}-fade-enter${t}-fade-enter-active, ${t}-fade-appear${t}-fade-appear-active`]:{animationName:i}},[`&${t}-topLeft, &${t}-bottomLeft`]:{marginInlineEnd:0,marginInlineStart:r,[`${t}-fade-enter${t}-fade-enter-active, ${t}-fade-appear${t}-fade-appear-active`]:{animationName:a}}}};let E=e=>{let{iconCls:t,componentCls:n,boxShadow:r,fontSizeLG:o,notificationMarginBottom:i,borderRadiusLG:a,colorSuccess:l,colorInfo:s,colorWarning:c,colorError:u,colorTextHeading:f,notificationBg:d,notificationPadding:p,notificationMarginEdge:h,motionDurationMid:m,motionEaseInOut:g,fontSize:v,lineHeight:x,width:w,notificationIconSize:E,colorText:S}=e,$=`${n}-notice`,O=new y.E4("antNotificationFadeIn",{"0%":{left:{_skip_check_:!0,value:w},opacity:0},"100%":{left:{_skip_check_:!0,value:0},opacity:1}}),k=new y.E4("antNotificationFadeOut",{"0%":{maxHeight:e.animationMaxHeight,marginBottom:i,opacity:1},"100%":{maxHeight:0,marginBottom:0,paddingTop:0,paddingBottom:0,opacity:0}}),Z={position:"relative",width:w,maxWidth:`calc(100vw - ${2*h}px)`,marginBottom:i,marginInlineStart:"auto",padding:p,overflow:"hidden",lineHeight:x,wordWrap:"break-word",background:d,borderRadius:a,boxShadow:r,[`${n}-close-icon`]:{fontSize:v,cursor:"pointer"},[`${$}-message`]:{marginBottom:e.marginXS,color:f,fontSize:o,lineHeight:e.lineHeightLG},[`${$}-description`]:{fontSize:v,color:S},[`&${$}-closable ${$}-message`]:{paddingInlineEnd:e.paddingLG},[`${$}-with-icon ${$}-message`]:{marginBottom:e.marginXS,marginInlineStart:e.marginSM+E,fontSize:o},[`${$}-with-icon ${$}-description`]:{marginInlineStart:e.marginSM+E,fontSize:v},[`${$}-icon`]:{position:"absolute",fontSize:E,lineHeight:0,[`&-success${t}`]:{color:l},[`&-info${t}`]:{color:s},[`&-warning${t}`]:{color:c},[`&-error${t}`]:{color:u}},[`${$}-close`]:{position:"absolute",top:e.notificationPaddingVertical,insetInlineEnd:e.notificationPaddingHorizontal,color:e.colorIcon,outline:"none",width:e.notificationCloseButtonSize,height:e.notificationCloseButtonSize,borderRadius:e.borderRadiusSM,transition:`background-color ${e.motionDurationMid}, color ${e.motionDurationMid}`,display:"flex",alignItems:"center",justifyContent:"center","&:hover":{color:e.colorIconHover,backgroundColor:e.wireframe?"transparent":e.colorFillContent}},[`${$}-btn`]:{float:"right",marginTop:e.marginSM}};return[{[n]:Object.assign(Object.assign(Object.assign(Object.assign({},(0,b.Wf)(e)),{position:"fixed",zIndex:e.zIndexPopup,marginInlineEnd:h,[`${n}-hook-holder`]:{position:"relative"},[`&${n}-top, &${n}-bottom`]:{[$]:{marginInline:"auto auto"}},[`&${n}-topLeft, &${n}-bottomLeft`]:{[$]:{marginInlineEnd:"auto",marginInlineStart:0}},[`${n}-fade-enter, ${n}-fade-appear`]:{animationDuration:e.motionDurationMid,animationTimingFunction:g,animationFillMode:"both",opacity:0,animationPlayState:"paused"},[`${n}-fade-leave`]:{animationTimingFunction:g,animationFillMode:"both",animationDuration:m,animationPlayState:"paused"},[`${n}-fade-enter${n}-fade-enter-active, ${n}-fade-appear${n}-fade-appear-active`]:{animationName:O,animationPlayState:"running"},[`${n}-fade-leave${n}-fade-leave-active`]:{animationName:k,animationPlayState:"running"}}),C(e)),{"&-rtl":{direction:"rtl",[`${$}-btn`]:{float:"left"}}})},{[n]:{[$]:Object.assign({},Z)}},{[`${$}-pure-panel`]:Object.assign(Object.assign({},Z),{margin:0})}]};var S=(0,x.Z)("Notification",e=>{let t=e.paddingMD,n=e.paddingLG,r=(0,w.TS)(e,{notificationBg:e.colorBgElevated,notificationPaddingVertical:t,notificationPaddingHorizontal:n,notificationIconSize:e.fontSizeLG*e.lineHeightLG,notificationCloseButtonSize:.55*e.controlHeightLG,notificationMarginBottom:e.margin,notificationPadding:`${e.paddingMD}px ${e.paddingContentHorizontalLG}px`,notificationMarginEdge:e.marginLG,animationMaxHeight:150});return[E(r)]},e=>({zIndexPopup:e.zIndexPopupBase+50,width:384})),$=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&0>t.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,r=Object.getOwnPropertySymbols(e);ot.indexOf(r[o])&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]]);return n};function O(e,t){return null===t||!1===t?null:t||i.createElement("span",{className:`${e}-close-x`},i.createElement(u.Z,{className:`${e}-close-icon`}))}d.Z,s.Z,c.Z,f.Z,p.Z;let k={success:s.Z,info:d.Z,error:c.Z,warning:f.Z},Z=e=>{let{prefixCls:t,icon:n,type:r,message:o,description:a,btn:l,role:s="alert"}=e,c=null;return n?c=i.createElement("span",{className:`${t}-icon`},n):r&&(c=i.createElement(k[r]||null,{className:m()(`${t}-icon`,`${t}-icon-${r}`)})),i.createElement("div",{className:m()({[`${t}-with-icon`]:c}),role:s},c,i.createElement("div",{className:`${t}-message`},o),i.createElement("div",{className:`${t}-description`},a),l&&i.createElement("div",{className:`${t}-btn`},l))};var P=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&0>t.indexOf(r)&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,r=Object.getOwnPropertySymbols(e);ot.indexOf(r[o])&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]]);return n};let j=e=>{let{children:t,prefixCls:n}=e,[,r]=S(n);return i.createElement(g.JB,{classNames:{list:r,notice:r}},t)},_=(e,t)=>{let{prefixCls:n,key:r}=t;return i.createElement(j,{prefixCls:n,key:r},e)},R=i.forwardRef((e,t)=>{let{top:n,bottom:r,prefixCls:o,getContainer:a,maxCount:l,rtl:s,onAllRemoved:c}=e,{getPrefixCls:u,getPopupContainer:f,notification:d}=i.useContext(v.E_),p=o||u("notification"),[h,y]=(0,g.lm)({prefixCls:p,style:e=>(function(e,t,n){let r;switch(e){case"top":r={left:"50%",transform:"translateX(-50%)",right:"auto",top:t,bottom:"auto"};break;case"topLeft":r={left:0,top:t,bottom:"auto"};break;case"topRight":r={right:0,top:t,bottom:"auto"};break;case"bottom":r={left:"50%",transform:"translateX(-50%)",right:"auto",top:"auto",bottom:n};break;case"bottomLeft":r={left:0,top:"auto",bottom:n};break;default:r={right:0,top:"auto",bottom:n}}return r})(e,null!=n?n:24,null!=r?r:24),className:()=>m()({[`${p}-rtl`]:s}),motion:()=>({motionName:`${p}-fade`}),closable:!0,closeIcon:O(p),duration:4.5,getContainer:()=>(null==a?void 0:a())||(null==f?void 0:f())||document.body,maxCount:l,onAllRemoved:c,renderNotifications:_});return i.useImperativeHandle(t,()=>Object.assign(Object.assign({},h),{prefixCls:p,notification:d})),y});function A(e){let t=i.useRef(null),n=i.useMemo(()=>{let n=n=>{var r;if(!t.current)return;let{open:o,prefixCls:a,notification:l}=t.current,s=`${a}-notice`,{message:c,description:u,icon:f,type:d,btn:p,className:h,style:g,role:v="alert",closeIcon:y}=n,b=P(n,["message","description","icon","type","btn","className","style","role","closeIcon"]),x=O(s,y);return o(Object.assign(Object.assign({placement:null!==(r=null==e?void 0:e.placement)&&void 0!==r?r:"topRight"},b),{content:i.createElement(Z,{prefixCls:s,icon:f,type:d,message:c,description:u,btn:p,role:v}),className:m()(d&&`${s}-${d}`,h,null==l?void 0:l.className),style:Object.assign(Object.assign({},null==l?void 0:l.style),g),closeIcon:x,closable:!!x}))},r={open:n,destroy:e=>{var n,r;void 0!==e?null===(n=t.current)||void 0===n||n.close(e):null===(r=t.current)||void 0===r||r.destroy()}};return["success","info","warning","error"].forEach(e=>{r[e]=t=>n(Object.assign(Object.assign({},t),{type:e}))}),r},[]);return[n,i.createElement(R,Object.assign({key:"notification-holder"},e,{ref:t}))]}let N=null,T=e=>e(),M=[],I={};function F(){let{prefixCls:e,getContainer:t,rtl:n,maxCount:r,top:o,bottom:i}=I,a=null!=e?e:(0,l.w6)().getPrefixCls("notification"),s=(null==t?void 0:t())||document.body;return{prefixCls:a,getContainer:()=>s,rtl:n,maxCount:r,top:o,bottom:i}}let L=i.forwardRef((e,t)=>{let[n,r]=i.useState(F),[o,a]=A(n),s=(0,l.w6)(),c=s.getRootPrefixCls(),u=s.getIconPrefixCls(),f=s.getTheme(),d=()=>{r(F)};return i.useEffect(d,[]),i.useImperativeHandle(t,()=>{let e=Object.assign({},o);return Object.keys(e).forEach(t=>{e[t]=function(){return d(),o[t].apply(o,arguments)}}),{instance:e,sync:d}}),i.createElement(l.ZP,{prefixCls:c,iconPrefixCls:u,theme:f},a)});function B(){if(!N){let e=document.createDocumentFragment(),t={fragment:e};N=t,T(()=>{(0,a.s)(i.createElement(L,{ref:e=>{let{instance:n,sync:r}=e||{};Promise.resolve().then(()=>{!t.instance&&n&&(t.instance=n,t.sync=r,B())})}}),e)});return}N.instance&&(M.forEach(e=>{switch(e.type){case"open":T(()=>{N.instance.open(Object.assign(Object.assign({},I),e.config))});break;case"destroy":T(()=>{null==N||N.instance.destroy(e.key)})}}),M=[])}function D(e){M.push({type:"open",config:e}),B()}let z={open:D,destroy:function(e){M.push({type:"destroy",key:e}),B()},config:function(e){I=Object.assign(Object.assign({},I),e),T(()=>{var e;null===(e=null==N?void 0:N.sync)||void 0===e||e.call(N)})},useNotification:function(e){return A(e)},_InternalPanelDoNotUseOrYouWillBeFired:e=>{let{prefixCls:t,className:n,icon:r,type:o,message:a,description:l,btn:s,closable:c=!0,closeIcon:u}=e,f=$(e,["prefixCls","className","icon","type","message","description","btn","closable","closeIcon"]),{getPrefixCls:d}=i.useContext(v.E_),p=t||d("notification"),h=`${p}-notice`,[,y]=S(p);return i.createElement(g.qX,Object.assign({},f,{prefixCls:p,className:m()(n,y,`${h}-pure-panel`),eventKey:"pure",duration:null,closable:c,closeIcon:O(p,u),content:i.createElement(Z,{prefixCls:h,icon:r,type:o,message:a,description:l,btn:s})}))}};["success","info","warning","error"].forEach(e=>{z[e]=t=>D(Object.assign(Object.assign({},t),{type:e}))});let H=(e,t)=>e.then(e=>{let{data:n}=e;if(!n)throw Error("Network Error!");if(!n.success){if("*"===t||n.err_code&&t&&t.includes(n.err_code));else{var r;z.error({message:"Request error",description:null!==(r=null==n?void 0:n.err_msg)&&void 0!==r?r:"The interface is abnormal. Please try again later"})}}return[null,n.data,n,e]}).catch(e=>(z.error({message:"Request error",description:e.message}),[e,null,null,null])),V=()=>eR("/api/v1/chat/dialogue/scenes"),U=e=>eR("/api/v1/chat/dialogue/new",e),W=()=>e_("/api/v1/chat/db/list"),K=()=>e_("/api/v1/chat/db/support/type"),q=e=>eR("/api/v1/chat/db/delete?db_name=".concat(e)),G=e=>eR("/api/v1/chat/db/edit",e),X=e=>eR("/api/v1/chat/db/add",e),Y=e=>eR("/api/v1/chat/db/test/connect",e),J=()=>e_("/api/v1/chat/dialogue/list"),Q=()=>e_("/api/v1/model/types"),ee=e=>eR("/api/v1/chat/mode/params/list?chat_mode=".concat(e)),et=e=>e_("/api/v1/chat/dialogue/messages/history?con_uid=".concat(e)),en=e=>{let{convUid:t,chatMode:n,data:r,config:o,model:i}=e;return eR("/api/v1/chat/mode/params/file/load?conv_uid=".concat(t,"&chat_mode=").concat(n,"&model_name=").concat(i),r,{headers:{"Content-Type":"multipart/form-data"},...o})},er=e=>eR("/api/v1/chat/dialogue/delete?con_uid=".concat(e)),eo=e=>eR("/knowledge/".concat(e,"/arguments"),{}),ei=(e,t)=>eR("/knowledge/".concat(e,"/argument/save"),t),ea=()=>eR("/knowledge/space/list",{}),el=(e,t)=>eR("/knowledge/".concat(e,"/document/list"),t),es=(e,t)=>eR("/knowledge/".concat(e,"/document/add"),t),ec=e=>eR("/knowledge/space/add",e),eu=(e,t)=>eR("/knowledge/".concat(e,"/document/sync"),t),ef=(e,t)=>eR("/knowledge/".concat(e,"/document/upload"),t),ed=(e,t)=>eR("/knowledge/".concat(e,"/chunk/list"),t),ep=(e,t)=>eR("/knowledge/".concat(e,"/document/delete"),t),eh=e=>eR("/knowledge/space/delete",e),em=()=>e_("/api/v1/worker/model/list"),eg=e=>eR("/api/v1/worker/model/stop",e),ev=e=>eR("/api/v1/worker/model/start",e),ey=()=>e_("/api/v1/worker/model/params"),eb=e=>eR("/api/v1/agent/query",e),ex=e=>eR("/api/v1/agent/hub/update",null!=e?e:{channel:"",url:"",branch:"",authorization:""}),ew=e=>eR("/api/v1/agent/my",void 0,{params:{user:e}}),eC=(e,t)=>eR("/api/v1/agent/install",void 0,{params:{plugin_name:e,user:t},timeout:6e4}),eE=(e,t)=>eR("/api/v1/agent/uninstall",void 0,{params:{plugin_name:e,user:t},timeout:6e4}),eS=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1?arguments[1]:void 0,n=arguments.length>2?arguments[2]:void 0;return eR("/api/v1/personal/agent/upload",t,{params:{user:e},headers:{"Content-Type":"multipart/form-data"},...n})},e$=()=>e_("/api/v1/feedback/select",void 0),eO=(e,t)=>e_("/api/v1/feedback/find?conv_uid=".concat(e,"&conv_index=").concat(t),void 0),ek=e=>{let{data:t,config:n}=e;return eR("/api/v1/feedback/commit",t,{headers:{"Content-Type":"application/json"},...n})};var eZ=n(83454);let eP=o.Z.create({baseURL:null!==(r=eZ.env.API_BASE_URL)&&void 0!==r?r:""}),ej=["/db/add","/db/test/connect","/db/summary","/params/file/load","/chat/prepare","/model/start","/model/stop","/editor/sql/run","/sql/editor/submit","/editor/chart/run","/chart/editor/submit","/document/upload","/document/sync","/agent/install","/agent/uninstall","/personal/agent/upload"];eP.interceptors.request.use(e=>{let t=ej.some(t=>{var n;return null===(n=e.url)||void 0===n?void 0:n.endsWith(t)});return e.timeout=t?6e4:1e4,e});let e_=(e,t,n)=>eP.get(e,{params:t,...n}),eR=(e,t,n)=>eP.post(e,t,n)},32665:function(e,t,n){"use strict";function r(e){}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"clientHookInServerComponentError",{enumerable:!0,get:function(){return r}}),n(38754),n(67294),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},41219:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{ReadonlyURLSearchParams:function(){return p},useSearchParams:function(){return h},usePathname:function(){return m},ServerInsertedHTMLContext:function(){return s.ServerInsertedHTMLContext},useServerInsertedHTML:function(){return s.useServerInsertedHTML},useRouter:function(){return g},useParams:function(){return v},useSelectedLayoutSegments:function(){return y},useSelectedLayoutSegment:function(){return b},redirect:function(){return c.redirect},notFound:function(){return u.notFound}});let r=n(67294),o=n(27473),i=n(35802),a=n(32665),l=n(43512),s=n(98751),c=n(96885),u=n(86323),f=Symbol("internal for urlsearchparams readonly");function d(){return Error("ReadonlyURLSearchParams cannot be modified")}class p{[Symbol.iterator](){return this[f][Symbol.iterator]()}append(){throw d()}delete(){throw d()}set(){throw d()}sort(){throw d()}constructor(e){this[f]=e,this.entries=e.entries.bind(e),this.forEach=e.forEach.bind(e),this.get=e.get.bind(e),this.getAll=e.getAll.bind(e),this.has=e.has.bind(e),this.keys=e.keys.bind(e),this.values=e.values.bind(e),this.toString=e.toString.bind(e)}}function h(){(0,a.clientHookInServerComponentError)("useSearchParams");let e=(0,r.useContext)(i.SearchParamsContext),t=(0,r.useMemo)(()=>e?new p(e):null,[e]);return t}function m(){return(0,a.clientHookInServerComponentError)("usePathname"),(0,r.useContext)(i.PathnameContext)}function g(){(0,a.clientHookInServerComponentError)("useRouter");let e=(0,r.useContext)(o.AppRouterContext);if(null===e)throw Error("invariant expected app router to be mounted");return e}function v(){(0,a.clientHookInServerComponentError)("useParams");let e=(0,r.useContext)(o.GlobalLayoutRouterContext);return e?function e(t,n){void 0===n&&(n={});let r=t[1];for(let t of Object.values(r)){let r=t[0],o=Array.isArray(r),i=o?r[1]:r;!i||i.startsWith("__PAGE__")||(o&&(n[r[0]]=r[1]),n=e(t,n))}return n}(e.tree):null}function y(e){void 0===e&&(e="children"),(0,a.clientHookInServerComponentError)("useSelectedLayoutSegments");let{tree:t}=(0,r.useContext)(o.LayoutRouterContext);return function e(t,n,r,o){let i;if(void 0===r&&(r=!0),void 0===o&&(o=[]),r)i=t[1][n];else{var a;let e=t[1];i=null!=(a=e.children)?a:Object.values(e)[0]}if(!i)return o;let s=i[0],c=(0,l.getSegmentValue)(s);return!c||c.startsWith("__PAGE__")?o:(o.push(c),e(i,n,!1,o))}(t,e)}function b(e){void 0===e&&(e="children"),(0,a.clientHookInServerComponentError)("useSelectedLayoutSegment");let t=y(e);return 0===t.length?null:t[0]}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},86323:function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{notFound:function(){return r},isNotFoundError:function(){return o}});let n="NEXT_NOT_FOUND";function r(){let e=Error(n);throw e.digest=n,e}function o(e){return(null==e?void 0:e.digest)===n}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},96885:function(e,t,n){"use strict";var r,o;Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{RedirectType:function(){return r},getRedirectError:function(){return l},redirect:function(){return s},isRedirectError:function(){return c},getURLFromRedirectError:function(){return u},getRedirectTypeFromError:function(){return f}});let i=n(68214),a="NEXT_REDIRECT";function l(e,t){let n=Error(a);n.digest=a+";"+t+";"+e;let r=i.requestAsyncStorage.getStore();return r&&(n.mutableCookies=r.mutableCookies),n}function s(e,t){throw void 0===t&&(t="replace"),l(e,t)}function c(e){if("string"!=typeof(null==e?void 0:e.digest))return!1;let[t,n,r]=e.digest.split(";",3);return t===a&&("replace"===n||"push"===n)&&"string"==typeof r}function u(e){return c(e)?e.digest.split(";",3)[2]:null}function f(e){if(!c(e))throw Error("Not a redirect error");return e.digest.split(";",3)[1]}(o=r||(r={})).push="push",o.replace="replace",("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},43512:function(e,t){"use strict";function n(e){return Array.isArray(e)?e[1]:e}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"getSegmentValue",{enumerable:!0,get:function(){return n}}),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},29382:function(e,t){"use strict";var n,r;Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{PrefetchKind:function(){return n},ACTION_REFRESH:function(){return o},ACTION_NAVIGATE:function(){return i},ACTION_RESTORE:function(){return a},ACTION_SERVER_PATCH:function(){return l},ACTION_PREFETCH:function(){return s},ACTION_FAST_REFRESH:function(){return c},ACTION_SERVER_ACTION:function(){return u}});let o="refresh",i="navigate",a="restore",l="server-patch",s="prefetch",c="fast-refresh",u="server-action";(r=n||(n={})).AUTO="auto",r.FULL="full",r.TEMPORARY="temporary",("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},75476:function(e,t){"use strict";function n(e,t,n,r){return!1}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"getDomainLocale",{enumerable:!0,get:function(){return n}}),("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},69873:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return y}});let r=n(38754),o=n(61757),i=o._(n(67294)),a=r._(n(68965)),l=n(38083),s=n(2478),c=n(76226);n(59941);let u=r._(n(31720)),f={deviceSizes:[640,750,828,1080,1200,1920,2048,3840],imageSizes:[16,32,48,64,96,128,256,384],path:"/_next/image/",loader:"default",dangerouslyAllowSVG:!1,unoptimized:!0};function d(e){return void 0!==e.default}function p(e){return void 0===e?e:"number"==typeof e?Number.isFinite(e)?e:NaN:"string"==typeof e&&/^[0-9]+$/.test(e)?parseInt(e,10):NaN}function h(e,t,n,r,o,i,a){if(!e||e["data-loaded-src"]===t)return;e["data-loaded-src"]=t;let l="decode"in e?e.decode():Promise.resolve();l.catch(()=>{}).then(()=>{if(e.parentElement&&e.isConnected){if("blur"===n&&i(!0),null==r?void 0:r.current){let t=new Event("load");Object.defineProperty(t,"target",{writable:!1,value:e});let n=!1,o=!1;r.current({...t,nativeEvent:t,currentTarget:e,target:e,isDefaultPrevented:()=>n,isPropagationStopped:()=>o,persist:()=>{},preventDefault:()=>{n=!0,t.preventDefault()},stopPropagation:()=>{o=!0,t.stopPropagation()}})}(null==o?void 0:o.current)&&o.current(e)}})}function m(e){let[t,n]=i.version.split("."),r=parseInt(t,10),o=parseInt(n,10);return r>18||18===r&&o>=3?{fetchPriority:e}:{fetchpriority:e}}let g=(0,i.forwardRef)((e,t)=>{let{imgAttributes:n,heightInt:r,widthInt:o,qualityInt:a,className:l,imgStyle:s,blurStyle:c,isLazy:u,fetchPriority:f,fill:d,placeholder:p,loading:g,srcString:v,config:y,unoptimized:b,loader:x,onLoadRef:w,onLoadingCompleteRef:C,setBlurComplete:E,setShowAltText:S,onLoad:$,onError:O,...k}=e;return g=u?"lazy":g,i.default.createElement("img",{...k,...m(f),loading:g,width:o,height:r,decoding:"async","data-nimg":d?"fill":"1",className:l,style:{...s,...c},...n,ref:(0,i.useCallback)(e=>{t&&("function"==typeof t?t(e):"object"==typeof t&&(t.current=e)),e&&(O&&(e.src=e.src),e.complete&&h(e,v,p,w,C,E,b))},[v,p,w,C,E,O,b,t]),onLoad:e=>{let t=e.currentTarget;h(t,v,p,w,C,E,b)},onError:e=>{S(!0),"blur"===p&&E(!0),O&&O(e)}})}),v=(0,i.forwardRef)((e,t)=>{var n;let r,o,{src:h,sizes:v,unoptimized:y=!1,priority:b=!1,loading:x,className:w,quality:C,width:E,height:S,fill:$,style:O,onLoad:k,onLoadingComplete:Z,placeholder:P="empty",blurDataURL:j,fetchPriority:_,layout:R,objectFit:A,objectPosition:N,lazyBoundary:T,lazyRoot:M,...I}=e,F=(0,i.useContext)(c.ImageConfigContext),L=(0,i.useMemo)(()=>{let e=f||F||s.imageConfigDefault,t=[...e.deviceSizes,...e.imageSizes].sort((e,t)=>e-t),n=e.deviceSizes.sort((e,t)=>e-t);return{...e,allSizes:t,deviceSizes:n}},[F]),B=I.loader||u.default;delete I.loader;let D="__next_img_default"in B;if(D){if("custom"===L.loader)throw Error('Image with src "'+h+'" is missing "loader" prop.\nRead more: https://nextjs.org/docs/messages/next-image-missing-loader')}else{let e=B;B=t=>{let{config:n,...r}=t;return e(r)}}if(R){"fill"===R&&($=!0);let e={intrinsic:{maxWidth:"100%",height:"auto"},responsive:{width:"100%",height:"auto"}}[R];e&&(O={...O,...e});let t={responsive:"100vw",fill:"100vw"}[R];t&&!v&&(v=t)}let z="",H=p(E),V=p(S);if("object"==typeof(n=h)&&(d(n)||void 0!==n.src)){let e=d(h)?h.default:h;if(!e.src)throw Error("An object should only be passed to the image component src parameter if it comes from a static image import. It must include src. Received "+JSON.stringify(e));if(!e.height||!e.width)throw Error("An object should only be passed to the image component src parameter if it comes from a static image import. It must include height and width. Received "+JSON.stringify(e));if(r=e.blurWidth,o=e.blurHeight,j=j||e.blurDataURL,z=e.src,!$){if(H||V){if(H&&!V){let t=H/e.width;V=Math.round(e.height*t)}else if(!H&&V){let t=V/e.height;H=Math.round(e.width*t)}}else H=e.width,V=e.height}}let U=!b&&("lazy"===x||void 0===x);(!(h="string"==typeof h?h:z)||h.startsWith("data:")||h.startsWith("blob:"))&&(y=!0,U=!1),L.unoptimized&&(y=!0),D&&h.endsWith(".svg")&&!L.dangerouslyAllowSVG&&(y=!0),b&&(_="high");let[W,K]=(0,i.useState)(!1),[q,G]=(0,i.useState)(!1),X=p(C),Y=Object.assign($?{position:"absolute",height:"100%",width:"100%",left:0,top:0,right:0,bottom:0,objectFit:A,objectPosition:N}:{},q?{}:{color:"transparent"},O),J="blur"===P&&j&&!W?{backgroundSize:Y.objectFit||"cover",backgroundPosition:Y.objectPosition||"50% 50%",backgroundRepeat:"no-repeat",backgroundImage:'url("data:image/svg+xml;charset=utf-8,'+(0,l.getImageBlurSvg)({widthInt:H,heightInt:V,blurWidth:r,blurHeight:o,blurDataURL:j,objectFit:Y.objectFit})+'")'}:{},Q=function(e){let{config:t,src:n,unoptimized:r,width:o,quality:i,sizes:a,loader:l}=e;if(r)return{src:n,srcSet:void 0,sizes:void 0};let{widths:s,kind:c}=function(e,t,n){let{deviceSizes:r,allSizes:o}=e;if(n){let e=/(^|\s)(1?\d?\d)vw/g,t=[];for(let r;r=e.exec(n);r)t.push(parseInt(r[2]));if(t.length){let e=.01*Math.min(...t);return{widths:o.filter(t=>t>=r[0]*e),kind:"w"}}return{widths:o,kind:"w"}}if("number"!=typeof t)return{widths:r,kind:"w"};let i=[...new Set([t,2*t].map(e=>o.find(t=>t>=e)||o[o.length-1]))];return{widths:i,kind:"x"}}(t,o,a),u=s.length-1;return{sizes:a||"w"!==c?a:"100vw",srcSet:s.map((e,r)=>l({config:t,src:n,quality:i,width:e})+" "+("w"===c?e:r+1)+c).join(", "),src:l({config:t,src:n,quality:i,width:s[u]})}}({config:L,src:h,unoptimized:y,width:H,quality:X,sizes:v,loader:B}),ee=h,et=(0,i.useRef)(k);(0,i.useEffect)(()=>{et.current=k},[k]);let en=(0,i.useRef)(Z);(0,i.useEffect)(()=>{en.current=Z},[Z]);let er={isLazy:U,imgAttributes:Q,heightInt:V,widthInt:H,qualityInt:X,className:w,imgStyle:Y,blurStyle:J,loading:x,config:L,fetchPriority:_,fill:$,unoptimized:y,placeholder:P,loader:B,srcString:ee,onLoadRef:et,onLoadingCompleteRef:en,setBlurComplete:K,setShowAltText:G,...I};return i.default.createElement(i.default.Fragment,null,i.default.createElement(g,{...er,ref:t}),b?i.default.createElement(a.default,null,i.default.createElement("link",{key:"__nimg-"+Q.src+Q.srcSet+Q.sizes,rel:"preload",as:"image",href:Q.srcSet?void 0:Q.src,imageSrcSet:Q.srcSet,imageSizes:Q.sizes,crossOrigin:I.crossOrigin,referrerPolicy:I.referrerPolicy,...m(_)})):null)}),y=v;("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},9940:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return x}});let r=n(38754),o=r._(n(67294)),i=n(65722),a=n(65723),l=n(28904),s=n(95514),c=n(27521),u=n(44293),f=n(27473),d=n(81307),p=n(75476),h=n(66318),m=n(29382),g=new Set;function v(e,t,n,r,o,i){if(!i&&!(0,a.isLocalURL)(t))return;if(!r.bypassPrefetchedCheck){let o=void 0!==r.locale?r.locale:"locale"in e?e.locale:void 0,i=t+"%"+n+"%"+o;if(g.has(i))return;g.add(i)}let l=i?e.prefetch(t,o):e.prefetch(t,n,r);Promise.resolve(l).catch(e=>{})}function y(e){return"string"==typeof e?e:(0,l.formatUrl)(e)}let b=o.default.forwardRef(function(e,t){let n,r;let{href:l,as:g,children:b,prefetch:x=null,passHref:w,replace:C,shallow:E,scroll:S,locale:$,onClick:O,onMouseEnter:k,onTouchStart:Z,legacyBehavior:P=!1,...j}=e;n=b,P&&("string"==typeof n||"number"==typeof n)&&(n=o.default.createElement("a",null,n));let _=!1!==x,R=null===x?m.PrefetchKind.AUTO:m.PrefetchKind.FULL,A=o.default.useContext(u.RouterContext),N=o.default.useContext(f.AppRouterContext),T=null!=A?A:N,M=!A,{href:I,as:F}=o.default.useMemo(()=>{if(!A){let e=y(l);return{href:e,as:g?y(g):e}}let[e,t]=(0,i.resolveHref)(A,l,!0);return{href:e,as:g?(0,i.resolveHref)(A,g):t||e}},[A,l,g]),L=o.default.useRef(I),B=o.default.useRef(F);P&&(r=o.default.Children.only(n));let D=P?r&&"object"==typeof r&&r.ref:t,[z,H,V]=(0,d.useIntersection)({rootMargin:"200px"}),U=o.default.useCallback(e=>{(B.current!==F||L.current!==I)&&(V(),B.current=F,L.current=I),z(e),D&&("function"==typeof D?D(e):"object"==typeof D&&(D.current=e))},[F,D,I,V,z]);o.default.useEffect(()=>{T&&H&&_&&v(T,I,F,{locale:$},{kind:R},M)},[F,I,H,$,_,null==A?void 0:A.locale,T,M,R]);let W={ref:U,onClick(e){P||"function"!=typeof O||O(e),P&&r.props&&"function"==typeof r.props.onClick&&r.props.onClick(e),T&&!e.defaultPrevented&&function(e,t,n,r,i,l,s,c,u,f){let{nodeName:d}=e.currentTarget,p="A"===d.toUpperCase();if(p&&(function(e){let t=e.currentTarget,n=t.getAttribute("target");return n&&"_self"!==n||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||e.nativeEvent&&2===e.nativeEvent.which}(e)||!u&&!(0,a.isLocalURL)(n)))return;e.preventDefault();let h=()=>{"beforePopState"in t?t[i?"replace":"push"](n,r,{shallow:l,locale:c,scroll:s}):t[i?"replace":"push"](r||n,{forceOptimisticNavigation:!f})};u?o.default.startTransition(h):h()}(e,T,I,F,C,E,S,$,M,_)},onMouseEnter(e){P||"function"!=typeof k||k(e),P&&r.props&&"function"==typeof r.props.onMouseEnter&&r.props.onMouseEnter(e),T&&(_||!M)&&v(T,I,F,{locale:$,priority:!0,bypassPrefetchedCheck:!0},{kind:R},M)},onTouchStart(e){P||"function"!=typeof Z||Z(e),P&&r.props&&"function"==typeof r.props.onTouchStart&&r.props.onTouchStart(e),T&&(_||!M)&&v(T,I,F,{locale:$,priority:!0,bypassPrefetchedCheck:!0},{kind:R},M)}};if((0,s.isAbsoluteUrl)(F))W.href=F;else if(!P||w||"a"===r.type&&!("href"in r.props)){let e=void 0!==$?$:null==A?void 0:A.locale,t=(null==A?void 0:A.isLocaleDomain)&&(0,p.getDomainLocale)(F,e,null==A?void 0:A.locales,null==A?void 0:A.domainLocales);W.href=t||(0,h.addBasePath)((0,c.addLocale)(F,e,null==A?void 0:A.defaultLocale))}return P?o.default.cloneElement(r,W):o.default.createElement("a",{...j,...W},n)}),x=b;("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},81307:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"useIntersection",{enumerable:!0,get:function(){return s}});let r=n(67294),o=n(82997),i="function"==typeof IntersectionObserver,a=new Map,l=[];function s(e){let{rootRef:t,rootMargin:n,disabled:s}=e,c=s||!i,[u,f]=(0,r.useState)(!1),d=(0,r.useRef)(null),p=(0,r.useCallback)(e=>{d.current=e},[]);(0,r.useEffect)(()=>{if(i){if(c||u)return;let e=d.current;if(e&&e.tagName){let r=function(e,t,n){let{id:r,observer:o,elements:i}=function(e){let t;let n={root:e.root||null,margin:e.rootMargin||""},r=l.find(e=>e.root===n.root&&e.margin===n.margin);if(r&&(t=a.get(r)))return t;let o=new Map,i=new IntersectionObserver(e=>{e.forEach(e=>{let t=o.get(e.target),n=e.isIntersecting||e.intersectionRatio>0;t&&n&&t(n)})},e);return t={id:n,observer:i,elements:o},l.push(n),a.set(n,t),t}(n);return i.set(e,t),o.observe(e),function(){if(i.delete(e),o.unobserve(e),0===i.size){o.disconnect(),a.delete(r);let e=l.findIndex(e=>e.root===r.root&&e.margin===r.margin);e>-1&&l.splice(e,1)}}}(e,e=>e&&f(e),{root:null==t?void 0:t.current,rootMargin:n});return r}}else if(!u){let e=(0,o.requestIdleCallback)(()=>f(!0));return()=>(0,o.cancelIdleCallback)(e)}},[c,n,t,u,d.current]);let h=(0,r.useCallback)(()=>{f(!1)},[]);return[p,u,h]}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},38083:function(e,t){"use strict";function n(e){let{widthInt:t,heightInt:n,blurWidth:r,blurHeight:o,blurDataURL:i,objectFit:a}=e,l=r||t,s=o||n,c=i.startsWith("data:image/jpeg")?"%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='1 1'/%3E%3C/feComponentTransfer%3E%":"";return l&&s?"%3Csvg xmlns='http%3A//www.w3.org/2000/svg' viewBox='0 0 "+l+" "+s+"'%3E%3Cfilter id='b' color-interpolation-filters='sRGB'%3E%3CfeGaussianBlur stdDeviation='"+(r&&o?"1":"20")+"'/%3E"+c+"%3C/filter%3E%3Cimage preserveAspectRatio='none' filter='url(%23b)' x='0' y='0' height='100%25' width='100%25' href='"+i+"'/%3E%3C/svg%3E":"%3Csvg xmlns='http%3A//www.w3.org/2000/svg'%3E%3Cimage style='filter:blur(20px)' preserveAspectRatio='"+("contain"===a?"xMidYMid":"cover"===a?"xMidYMid slice":"none")+"' x='0' y='0' height='100%25' width='100%25' href='"+i+"'/%3E%3C/svg%3E"}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"getImageBlurSvg",{enumerable:!0,get:function(){return n}})},31720:function(e,t){"use strict";function n(e){let{config:t,src:n,width:r,quality:o}=e;return t.path+"?url="+encodeURIComponent(n)+"&w="+r+"&q="+(o||75)}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"default",{enumerable:!0,get:function(){return r}}),n.__next_img_default=!0;let r=n},98751:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{ServerInsertedHTMLContext:function(){return i},useServerInsertedHTML:function(){return a}});let r=n(61757),o=r._(n(67294)),i=o.default.createContext(null);function a(e){let t=(0,o.useContext)(i);t&&t(e)}},37262:function(e,t,n){"use strict";let r,o;n.r(t),n.d(t,{default:function(){return eM}});var i=n(85893),a=n(67294),l=n(41468),s=n(50489),c=n(98399),u=function(){return(0,i.jsx)("svg",{width:"1em",height:"1em",fill:"currentColor",viewBox:"0 0 1024 1024",children:(0,i.jsx)("path",{d:"M593.054 120.217C483.656 148.739 402.91 248.212 402.91 366.546c0 140.582 113.962 254.544 254.544 254.544 118.334 0 217.808-80.746 246.328-190.144C909.17 457.12 912 484.23 912 512c0 220.914-179.086 400-400 400S112 732.914 112 512s179.086-400 400-400c27.77 0 54.88 2.83 81.054 8.217z","p-id":"5941"})})},f=function(){return(0,i.jsx)("svg",{width:"1em",height:"1em",fill:"currentColor",viewBox:"0 0 1024 1024",children:(0,i.jsx)("path",{d:"M554.6 64h-85.4v128h85.4V64z m258.2 87.4L736 228.2l59.8 59.8 76.8-76.8-59.8-59.8z m-601.6 0l-59.8 59.8 76.8 76.8 59.8-59.8-76.8-76.8zM512 256c-140.8 0-256 115.2-256 256s115.2 256 256 256 256-115.2 256-256-115.2-256-256-256z m448 213.4h-128v85.4h128v-85.4z m-768 0H64v85.4h128v-85.4zM795.8 736L736 795.8l76.8 76.8 59.8-59.8-76.8-76.8z m-567.6 0l-76.8 76.8 59.8 59.8 76.8-76.8-59.8-59.8z m326.4 96h-85.4v128h85.4v-128z","p-id":"7802"})})},d=n(59766),p=n(87462),h=n(63366),m=n(71387),g=n(70917);function v(e){let{styles:t,defaultTheme:n={}}=e,r="function"==typeof t?e=>t(null==e||0===Object.keys(e).length?n:e):t;return(0,i.jsx)(g.xB,{styles:r})}var y=n(56760),b=n(71927);let x="mode",w="color-scheme",C="data-color-scheme";function E(e){if("undefined"!=typeof window&&"system"===e){let e=window.matchMedia("(prefers-color-scheme: dark)");return e.matches?"dark":"light"}}function S(e,t){return"light"===e.mode||"system"===e.mode&&"light"===e.systemMode?t("light"):"dark"===e.mode||"system"===e.mode&&"dark"===e.systemMode?t("dark"):void 0}function $(e,t){let n;if("undefined"!=typeof window){try{(n=localStorage.getItem(e)||void 0)||localStorage.setItem(e,t)}catch(e){}return n||t}}let O=["colorSchemes","components","generateCssVars","cssVarPrefix"];var k=n(1812),Z=n(13951),P=n(2548);let{CssVarsProvider:j,useColorScheme:_,getInitColorSchemeScript:R}=function(e){let{themeId:t,theme:n={},attribute:r=C,modeStorageKey:o=x,colorSchemeStorageKey:l=w,defaultMode:s="light",defaultColorScheme:c,disableTransitionOnChange:u=!1,resolveTheme:f,excludeVariablesFromRoot:g}=e;n.colorSchemes&&("string"!=typeof c||n.colorSchemes[c])&&("object"!=typeof c||n.colorSchemes[null==c?void 0:c.light])&&("object"!=typeof c||n.colorSchemes[null==c?void 0:c.dark])||console.error(`MUI: \`${c}\` does not exist in \`theme.colorSchemes\`.`);let k=a.createContext(void 0),Z="string"==typeof c?c:c.light,P="string"==typeof c?c:c.dark;return{CssVarsProvider:function({children:e,theme:m=n,modeStorageKey:C=o,colorSchemeStorageKey:Z=l,attribute:P=r,defaultMode:j=s,defaultColorScheme:_=c,disableTransitionOnChange:R=u,storageWindow:A="undefined"==typeof window?void 0:window,documentNode:N="undefined"==typeof document?void 0:document,colorSchemeNode:T="undefined"==typeof document?void 0:document.documentElement,colorSchemeSelector:M=":root",disableNestedContext:I=!1,disableStyleSheetGeneration:F=!1}){let L=a.useRef(!1),B=(0,y.Z)(),D=a.useContext(k),z=!!D&&!I,H=m[t],V=H||m,{colorSchemes:U={},components:W={},generateCssVars:K=()=>({vars:{},css:{}}),cssVarPrefix:q}=V,G=(0,h.Z)(V,O),X=Object.keys(U),Y="string"==typeof _?_:_.light,J="string"==typeof _?_:_.dark,{mode:Q,setMode:ee,systemMode:et,lightColorScheme:en,darkColorScheme:er,colorScheme:eo,setColorScheme:ei}=function(e){let{defaultMode:t="light",defaultLightColorScheme:n,defaultDarkColorScheme:r,supportedColorSchemes:o=[],modeStorageKey:i=x,colorSchemeStorageKey:l=w,storageWindow:s="undefined"==typeof window?void 0:window}=e,c=o.join(","),[u,f]=a.useState(()=>{let e=$(i,t),o=$(`${l}-light`,n),a=$(`${l}-dark`,r);return{mode:e,systemMode:E(e),lightColorScheme:o,darkColorScheme:a}}),d=S(u,e=>"light"===e?u.lightColorScheme:"dark"===e?u.darkColorScheme:void 0),h=a.useCallback(e=>{f(n=>{if(e===n.mode)return n;let r=e||t;try{localStorage.setItem(i,r)}catch(e){}return(0,p.Z)({},n,{mode:r,systemMode:E(r)})})},[i,t]),m=a.useCallback(e=>{e?"string"==typeof e?e&&!c.includes(e)?console.error(`\`${e}\` does not exist in \`theme.colorSchemes\`.`):f(t=>{let n=(0,p.Z)({},t);return S(t,t=>{try{localStorage.setItem(`${l}-${t}`,e)}catch(e){}"light"===t&&(n.lightColorScheme=e),"dark"===t&&(n.darkColorScheme=e)}),n}):f(t=>{let o=(0,p.Z)({},t),i=null===e.light?n:e.light,a=null===e.dark?r:e.dark;if(i){if(c.includes(i)){o.lightColorScheme=i;try{localStorage.setItem(`${l}-light`,i)}catch(e){}}else console.error(`\`${i}\` does not exist in \`theme.colorSchemes\`.`)}if(a){if(c.includes(a)){o.darkColorScheme=a;try{localStorage.setItem(`${l}-dark`,a)}catch(e){}}else console.error(`\`${a}\` does not exist in \`theme.colorSchemes\`.`)}return o}):f(e=>{try{localStorage.setItem(`${l}-light`,n),localStorage.setItem(`${l}-dark`,r)}catch(e){}return(0,p.Z)({},e,{lightColorScheme:n,darkColorScheme:r})})},[c,l,n,r]),g=a.useCallback(e=>{"system"===u.mode&&f(t=>(0,p.Z)({},t,{systemMode:null!=e&&e.matches?"dark":"light"}))},[u.mode]),v=a.useRef(g);return v.current=g,a.useEffect(()=>{let e=(...e)=>v.current(...e),t=window.matchMedia("(prefers-color-scheme: dark)");return t.addListener(e),e(t),()=>t.removeListener(e)},[]),a.useEffect(()=>{let e=e=>{let n=e.newValue;"string"==typeof e.key&&e.key.startsWith(l)&&(!n||c.match(n))&&(e.key.endsWith("light")&&m({light:n}),e.key.endsWith("dark")&&m({dark:n})),e.key===i&&(!n||["light","dark","system"].includes(n))&&h(n||t)};if(s)return s.addEventListener("storage",e),()=>s.removeEventListener("storage",e)},[m,h,i,l,c,t,s]),(0,p.Z)({},u,{colorScheme:d,setMode:h,setColorScheme:m})}({supportedColorSchemes:X,defaultLightColorScheme:Y,defaultDarkColorScheme:J,modeStorageKey:C,colorSchemeStorageKey:Z,defaultMode:j,storageWindow:A}),ea=Q,el=eo;z&&(ea=D.mode,el=D.colorScheme);let es=ea||("system"===j?s:j),ec=el||("dark"===es?J:Y),{css:eu,vars:ef}=K(),ed=(0,p.Z)({},G,{components:W,colorSchemes:U,cssVarPrefix:q,vars:ef,getColorSchemeSelector:e=>`[${P}="${e}"] &`}),ep={},eh={};Object.entries(U).forEach(([e,t])=>{let{css:n,vars:r}=K(e);ed.vars=(0,d.Z)(ed.vars,r),e===ec&&(Object.keys(t).forEach(e=>{t[e]&&"object"==typeof t[e]?ed[e]=(0,p.Z)({},ed[e],t[e]):ed[e]=t[e]}),ed.palette&&(ed.palette.colorScheme=e));let o="string"==typeof _?_:"dark"===j?_.dark:_.light;if(e===o){if(g){let t={};g(q).forEach(e=>{t[e]=n[e],delete n[e]}),ep[`[${P}="${e}"]`]=t}ep[`${M}, [${P}="${e}"]`]=n}else eh[`${":root"===M?"":M}[${P}="${e}"]`]=n}),ed.vars=(0,d.Z)(ed.vars,ef),a.useEffect(()=>{el&&T&&T.setAttribute(P,el)},[el,P,T]),a.useEffect(()=>{let e;if(R&&L.current&&N){let t=N.createElement("style");t.appendChild(N.createTextNode("*{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}")),N.head.appendChild(t),window.getComputedStyle(N.body),e=setTimeout(()=>{N.head.removeChild(t)},1)}return()=>{clearTimeout(e)}},[el,R,N]),a.useEffect(()=>(L.current=!0,()=>{L.current=!1}),[]);let em=a.useMemo(()=>({mode:ea,systemMode:et,setMode:ee,lightColorScheme:en,darkColorScheme:er,colorScheme:el,setColorScheme:ei,allColorSchemes:X}),[X,el,er,en,ea,ei,ee,et]),eg=!0;(F||z&&(null==B?void 0:B.cssVarPrefix)===q)&&(eg=!1);let ev=(0,i.jsxs)(a.Fragment,{children:[eg&&(0,i.jsxs)(a.Fragment,{children:[(0,i.jsx)(v,{styles:{[M]:eu}}),(0,i.jsx)(v,{styles:ep}),(0,i.jsx)(v,{styles:eh})]}),(0,i.jsx)(b.Z,{themeId:H?t:void 0,theme:f?f(ed):ed,children:e})]});return z?ev:(0,i.jsx)(k.Provider,{value:em,children:ev})},useColorScheme:()=>{let e=a.useContext(k);if(!e)throw Error((0,m.Z)(19));return e},getInitColorSchemeScript:e=>(function(e){let{defaultMode:t="light",defaultLightColorScheme:n="light",defaultDarkColorScheme:r="dark",modeStorageKey:o=x,colorSchemeStorageKey:a=w,attribute:l=C,colorSchemeNode:s="document.documentElement"}=e||{};return(0,i.jsx)("script",{dangerouslySetInnerHTML:{__html:`(function() { try { var mode = localStorage.getItem('${o}') || '${t}'; var cssColorScheme = mode; var colorScheme = ''; diff --git a/pilot/server/static/_next/static/chunks/pages/database-2066e1a37e227df6.js b/pilot/server/static/_next/static/chunks/pages/database-2066e1a37e227df6.js new file mode 100644 index 000000000..45ac1569a --- /dev/null +++ b/pilot/server/static/_next/static/chunks/pages/database-2066e1a37e227df6.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[498],{55286:function(e,a,s){(window.__NEXT_P=window.__NEXT_P||[]).push(["/database",function(){return s(92572)}])},45247:function(e,a,s){"use strict";var l=s(85893),t=s(50888);a.Z=function(e){let{visible:a}=e;return a?(0,l.jsx)("div",{className:"absolute w-full h-full top-0 left-0 flex justify-center items-center z-10 bg-white dark:bg-black bg-opacity-50 dark:bg-opacity-50 backdrop-blur-sm text-3xl animate-fade animate-duration-200",children:(0,l.jsx)(t.Z,{})}):null}},92572:function(e,a,s){"use strict";s.r(a),s.d(a,{default:function(){return q},isFileDb:function(){return F}});var l=s(85893),t=s(67294),n=s(2093),r=s(12069),i=s(2453),c=s(71577),o=s(40411),d=s(85265),b=s(85813),m=s(32983),u=s(39479),p=s(51009),h=s(59566),f=s(48928),x=s(50489),y=s(67421),j=function(e){let{open:a,choiceDBType:s,dbTypeList:n,editValue:o,dbNames:d,onClose:b,onSuccess:m}=e,[j,g]=(0,t.useState)(!1),{t:w}=(0,y.$G)(),[_]=u.Z.useForm(),N=u.Z.useWatch("db_type",_),k=(0,t.useMemo)(()=>F(n,N),[n,N]);(0,t.useEffect)(()=>{s&&_.setFieldValue("db_type",s)},[s]),(0,t.useEffect)(()=>{o&&_.setFieldsValue({...o})},[o]),(0,t.useEffect)(()=>{a||_.resetFields()},[a]);let Z=async e=>{let{db_host:a,db_path:s,db_port:l,...t}=e;if(!o&&d.some(e=>e===t.db_name)){i.ZP.error("The database already exists!");return}let n={db_host:k?void 0:a,db_port:k?void 0:l,file_path:k?s:void 0,...t};g(!0);try{let[e]=await (0,x.Vx)((0,x.KS)(n));if(e)return;let[a]=await (0,x.Vx)((o?x.mR:x.b_)(n));if(a){i.ZP.error(a.message);return}i.ZP.success("success"),null==m||m()}catch(e){i.ZP.error(e.message)}finally{g(!1)}},v=(0,t.useMemo)(()=>!!o||!!s,[o,s]);return(0,l.jsx)(r.default,{open:a,width:400,title:w(o?"Edit":"create_database"),maskClosable:!1,footer:null,onCancel:b,children:(0,l.jsxs)(u.Z,{form:_,className:"pt-2",labelCol:{span:6},labelAlign:"left",onFinish:Z,children:[(0,l.jsx)(u.Z.Item,{name:"db_type",label:"DB Type",className:"mb-3",rules:[{required:!0}],children:(0,l.jsx)(p.default,{"aria-readonly":v,disabled:v,options:n})}),(0,l.jsx)(u.Z.Item,{name:"db_name",label:"DB Name",className:"mb-3",rules:[{required:!0}],children:(0,l.jsx)(h.default,{readOnly:!!o,disabled:!!o})}),!0===k&&(0,l.jsx)(u.Z.Item,{name:"db_path",label:"Path",className:"mb-3",rules:[{required:!0}],children:(0,l.jsx)(h.default,{})}),!1===k&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(u.Z.Item,{name:"db_user",label:"Username",className:"mb-3",rules:[{required:!0}],children:(0,l.jsx)(h.default,{})}),(0,l.jsx)(u.Z.Item,{name:"db_pwd",label:"Password",className:"mb-3",rules:[{required:!0}],children:(0,l.jsx)(h.default,{type:"password"})}),(0,l.jsx)(u.Z.Item,{name:"db_host",label:"Host",className:"mb-3",rules:[{required:!0}],children:(0,l.jsx)(h.default,{})}),(0,l.jsx)(u.Z.Item,{name:"db_port",label:"Port",className:"mb-3",rules:[{required:!0}],children:(0,l.jsx)(f.Z,{min:1,step:1,max:65535})})]}),(0,l.jsx)(u.Z.Item,{name:"comment",label:"Remark",className:"mb-3",children:(0,l.jsx)(h.default,{})}),(0,l.jsxs)(u.Z.Item,{className:"flex flex-row-reverse pt-1 mb-0",children:[(0,l.jsx)(c.ZP,{htmlType:"submit",type:"primary",size:"middle",className:"mr-1",loading:j,children:"Save"}),(0,l.jsx)(c.ZP,{size:"middle",onClick:b,children:"Cancel"})]})]})})},g=s(83062),w=s(25675),_=s.n(w),N=function(e){let{src:a,label:s}=e;return(0,l.jsx)(_(),{className:"w-11 h-11 rounded-full mr-4 border border-gray-200 object-contain bg-white",width:44,height:44,src:a,alt:s||"db-icon"})},k=function(e){let{info:a,onClick:s}=e,n=(0,t.useCallback)(()=>{a.disabled||null==s||s()},[a.disabled,s]);return(0,l.jsxs)("div",{className:"relative flex flex-col py-4 px-4 w-72 h-32 cursor-pointer rounded-lg justify-between text-black bg-white border-gray-200 border hover:shadow-md dark:border-gray-600 dark:bg-black dark:text-white dark:hover:border-white transition-all ".concat(a.disabled?"grayscale cursor-no-drop":""),onClick:n,children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)(N,{src:a.icon,label:a.label}),(0,l.jsx)("div",{className:"flex flex-col",children:(0,l.jsx)("h2",{className:"text-sm font-semibold",children:a.label})})]}),(0,l.jsx)(g.Z,{title:a.desc,children:(0,l.jsx)("p",{className:"text-sm text-gray-500 font-normal line-clamp-2",children:a.desc})})]})},Z=s(24969),v=s(36531),C=s(27704),S=s(45247);let P={mysql:{label:"MySQL",icon:"/icons/mysql.png",desc:"Fast, reliable, scalable open-source relational database management system."},mssql:{label:"MSSQL",icon:"/icons/mssql.png",desc:"Powerful, scalable, secure relational database system by Microsoft."},duckdb:{label:"DuckDB",icon:"/icons/duckdb.png",desc:"In-memory analytical database with efficient query processing."},sqlite:{label:"Sqlite",icon:"/icons/sqlite.png",desc:"Lightweight embedded relational database with simplicity and portability."},clickhouse:{label:"ClickHouse",icon:"/icons/clickhouse.png",desc:"Columnar database for high-performance analytics and real-time queries."},oracle:{label:"Oracle",icon:"/icons/oracle.png",desc:"Robust, scalable, secure relational database widely used in enterprises."},access:{label:"Access",icon:"/icons/access.png",desc:"Easy-to-use relational database for small-scale applications by Microsoft."},mongodb:{label:"MongoDB",icon:"/icons/mongodb.png",desc:"Flexible, scalable NoSQL document database for web and mobile apps."},db2:{label:"DB2",icon:"/icons/db2.png",desc:"Scalable, secure relational database system developed by IBM."},hbase:{label:"HBase",icon:"/icons/hbase.png",desc:"Distributed, scalable NoSQL database for large structured/semi-structured data."},redis:{label:"Redis",icon:"/icons/redis.png",desc:"Fast, versatile in-memory data structure store as cache, DB, or broker."},cassandra:{label:"Cassandra",icon:"/icons/cassandra.png",desc:"Scalable, fault-tolerant distributed NoSQL database for large data."},couchbase:{label:"Couchbase",icon:"/icons/couchbase.png",desc:"High-performance NoSQL document database with distributed architecture."},postgresql:{label:"PostgreSQL",icon:"/icons/postgresql.png",desc:"Powerful open-source relational database with extensibility and SQL standards."},spark:{label:"Spark",icon:"/icons/spark.png",desc:"Unified engine for large-scale data analytics."}};function F(e,a){var s;return null===(s=e.find(e=>e.value===a))||void 0===s?void 0:s.isFileDb}var q=function(){let[e,a]=(0,t.useState)([]),[s,u]=(0,t.useState)([]),[p,h]=(0,t.useState)(!1),[f,y]=(0,t.useState)({open:!1}),[g,w]=(0,t.useState)({open:!1}),_=async()=>{let[e,a]=await (0,x.Vx)((0,x.Jm)());u(null!=a?a:[])},N=async()=>{h(!0);let[e,s]=await (0,x.Vx)((0,x.Bw)());a(null!=s?s:[]),h(!1)},F=(0,t.useMemo)(()=>{let e=s.map(e=>{let{db_type:a,is_file_db:s}=e;return{...P[a],value:a,isFileDb:s}}),a=Object.keys(P).filter(a=>!e.some(e=>e.value===a)).map(e=>({...P[e],value:P[e].label,disabled:!0}));return[...e,...a]},[s]),q=e=>{y({open:!0,info:e})},D=e=>{r.default.confirm({title:"Tips",content:"Do you Want to delete the ".concat(e.db_name,"?"),onOk:()=>new Promise(async(a,s)=>{try{let[l]=await (0,x.Vx)((0,x.J5)(e.db_name));if(l){i.ZP.error(l.message),s();return}i.ZP.success("success"),N(),a()}catch(e){s()}})})},E=(0,t.useMemo)(()=>{let a=F.reduce((a,s)=>(a[s.value]=e.filter(e=>e.db_type===s.value),a),{});return a},[e,F]);(0,n.Z)(async()=>{await N(),await _()},[]);let T=a=>{let s=e.filter(e=>e.db_type===a.value);w({open:!0,dbList:s,name:a.label,type:a.value})};return(0,l.jsxs)("div",{className:"relative p-6 px-12 bg-[#FAFAFA] dark:bg-transparent min-h-full overflow-y-auto",children:[(0,l.jsx)(S.Z,{visible:p}),(0,l.jsx)("div",{className:"mb-4",children:(0,l.jsx)(c.ZP,{type:"primary",className:"flex items-center",icon:(0,l.jsx)(Z.Z,{}),onClick:()=>{y({open:!0})},children:"Create"})}),(0,l.jsx)("div",{className:"flex flex-wrap",children:F.map(e=>(0,l.jsx)(o.Z,{className:"mr-4 mb-4",count:E[e.value].length,children:(0,l.jsx)(k,{info:e,onClick:()=>{T(e)}})},e.value))}),(0,l.jsx)(j,{open:f.open,dbTypeList:F,choiceDBType:f.dbType,editValue:f.info,dbNames:e.map(e=>e.db_name),onSuccess:()=>{y({open:!1}),N()},onClose:()=>{y({open:!1})}}),(0,l.jsx)(d.Z,{title:g.name,placement:"right",onClose:()=>{w({open:!1})},open:g.open,children:g.type&&E[g.type]&&E[g.type].length?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(c.ZP,{type:"primary",className:"mb-4 flex items-center",icon:(0,l.jsx)(Z.Z,{}),onClick:()=>{y({open:!0,dbType:g.type})},children:"Create"}),E[g.type].map(e=>(0,l.jsxs)(b.Z,{title:e.db_name,extra:(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(v.Z,{className:"mr-2",style:{color:"#1b7eff"},onClick:()=>{q(e)}}),(0,l.jsx)(C.Z,{style:{color:"#ff1b2e"},onClick:()=>{D(e)}})]}),className:"mb-4",children:[e.db_path?(0,l.jsxs)("p",{children:["path: ",e.db_path]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)("p",{children:["host: ",e.db_host]}),(0,l.jsxs)("p",{children:["username: ",e.db_user]}),(0,l.jsxs)("p",{children:["port: ",e.db_port]})]}),(0,l.jsxs)("p",{children:["remark: ",e.comment]})]},e.db_name))]}):(0,l.jsx)(m.Z,{image:m.Z.PRESENTED_IMAGE_DEFAULT,children:(0,l.jsx)(c.ZP,{type:"primary",className:"flex items-center mx-auto",icon:(0,l.jsx)(Z.Z,{}),onClick:()=>{y({open:!0,dbType:g.type})},children:"Create Now"})})})]})}}},function(e){e.O(0,[44,479,9,442,813,411,928,643,774,888,179],function(){return e(e.s=55286)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/pilot/server/static/_next/static/chunks/pages/database-ed7e37a49de751e1.js b/pilot/server/static/_next/static/chunks/pages/database-ed7e37a49de751e1.js deleted file mode 100644 index 16a5e1921..000000000 --- a/pilot/server/static/_next/static/chunks/pages/database-ed7e37a49de751e1.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[498],{55286:function(e,a,s){(window.__NEXT_P=window.__NEXT_P||[]).push(["/database",function(){return s(92572)}])},45247:function(e,a,s){"use strict";var l=s(85893),t=s(50888);a.Z=function(e){let{visible:a}=e;return a?(0,l.jsx)("div",{className:"absolute w-full h-full top-0 left-0 flex justify-center items-center z-10 bg-white dark:bg-black bg-opacity-50 dark:bg-opacity-50 backdrop-blur-sm text-3xl animate-fade animate-duration-200",children:(0,l.jsx)(t.Z,{})}):null}},92572:function(e,a,s){"use strict";s.r(a),s.d(a,{default:function(){return q},isFileDb:function(){return F}});var l=s(85893),t=s(67294),n=s(2093),r=s(12069),i=s(2453),c=s(71577),o=s(40411),d=s(85265),b=s(85813),m=s(32983),u=s(39479),p=s(51009),h=s(59566),x=s(48928),f=s(50489),y=s(67421),g=function(e){let{open:a,choiceDBType:s,dbTypeList:n,editValue:o,dbNames:d,onClose:b,onSuccess:m}=e,[g,j]=(0,t.useState)(!1),{t:w}=(0,y.$G)(),[N]=u.Z.useForm(),_=u.Z.useWatch("db_type",N),k=(0,t.useMemo)(()=>F(n,_),[n,_]);(0,t.useEffect)(()=>{s&&N.setFieldValue("db_type",s)},[s]),(0,t.useEffect)(()=>{o&&N.setFieldsValue({...o})},[o]),(0,t.useEffect)(()=>{a||N.resetFields()},[a]);let Z=async e=>{let{db_host:a,db_path:s,db_port:l,...t}=e;if(!o&&d.some(e=>e===t.db_name)){i.ZP.error("The database already exists!");return}let n={db_host:k?void 0:a,db_port:k?void 0:l,file_path:k?s:void 0,...t};j(!0);try{let[e]=await (0,f.Vx)((0,f.KS)(n));if(e)return;let[a]=await (0,f.Vx)((o?f.mR:f.b_)(n));if(a){i.ZP.error(a.message);return}i.ZP.success("success"),null==m||m()}catch(e){i.ZP.error(e.message)}finally{j(!1)}},v=(0,t.useMemo)(()=>!!o||!!s,[o,s]);return(0,l.jsx)(r.default,{open:a,width:400,title:w(o?"Edit":"create_database"),maskClosable:!1,footer:null,onCancel:b,children:(0,l.jsxs)(u.Z,{form:N,className:"pt-2",labelCol:{span:6},labelAlign:"left",onFinish:Z,children:[(0,l.jsx)(u.Z.Item,{name:"db_type",label:"DB Type",className:"mb-3",rules:[{required:!0}],children:(0,l.jsx)(p.default,{"aria-readonly":v,disabled:v,options:n})}),(0,l.jsx)(u.Z.Item,{name:"db_name",label:"DB Name",className:"mb-3",rules:[{required:!0}],children:(0,l.jsx)(h.default,{readOnly:!!o,disabled:!!o})}),!0===k&&(0,l.jsx)(u.Z.Item,{name:"db_path",label:"Path",className:"mb-3",rules:[{required:!0}],children:(0,l.jsx)(h.default,{})}),!1===k&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(u.Z.Item,{name:"db_user",label:"Username",className:"mb-3",rules:[{required:!0}],children:(0,l.jsx)(h.default,{})}),(0,l.jsx)(u.Z.Item,{name:"db_pwd",label:"Password",className:"mb-3",rules:[{required:!0}],children:(0,l.jsx)(h.default,{type:"password"})}),(0,l.jsx)(u.Z.Item,{name:"db_host",label:"Host",className:"mb-3",rules:[{required:!0}],children:(0,l.jsx)(h.default,{})}),(0,l.jsx)(u.Z.Item,{name:"db_port",label:"Port",className:"mb-3",rules:[{required:!0}],children:(0,l.jsx)(x.Z,{min:1,step:1,max:65535})})]}),(0,l.jsx)(u.Z.Item,{name:"comment",label:"Remark",className:"mb-3",children:(0,l.jsx)(h.default,{})}),(0,l.jsxs)(u.Z.Item,{className:"flex flex-row-reverse pt-1 mb-0",children:[(0,l.jsx)(c.ZP,{htmlType:"submit",type:"primary",size:"middle",className:"mr-1",loading:g,children:"Save"}),(0,l.jsx)(c.ZP,{size:"middle",onClick:b,children:"Cancel"})]})]})})},j=s(83062),w=s(25675),N=s.n(w),_=function(e){let{src:a,label:s}=e;return(0,l.jsx)(N(),{className:"w-11 h-11 rounded-full mr-4 border border-gray-200 object-contain bg-white",width:44,height:44,src:a,alt:s||"db-icon"})},k=function(e){let{info:a,onClick:s}=e,n=(0,t.useCallback)(()=>{a.disabled||null==s||s()},[a.disabled,s]);return(0,l.jsxs)("div",{className:"relative flex flex-col py-4 px-4 w-72 h-32 cursor-pointer rounded-lg justify-between text-black bg-white border-gray-200 border hover:shadow-md dark:border-gray-600 dark:bg-black dark:text-white dark:hover:border-white transition-all ".concat(a.disabled?"grayscale":""),onClick:n,children:[(0,l.jsxs)("div",{className:"flex items-center",children:[(0,l.jsx)(_,{src:a.icon,label:a.label}),(0,l.jsxs)("div",{className:"flex flex-col",children:[(0,l.jsx)("h2",{className:"text-sm font-semibold",children:a.label}),a.disabled&&(0,l.jsx)("div",{className:"mt-[2px] rounded-full font-normal bg-gray-100 text-xs h-5 flex items-center px-2 dark:bg-gray-800",children:"Comming soon"})]})]}),(0,l.jsx)(j.Z,{title:a.desc,children:(0,l.jsx)("p",{className:"text-sm text-gray-500 font-normal line-clamp-2",children:a.desc})})]})},Z=s(24969),v=s(36531),C=s(27704),S=s(45247);let P={mysql:{label:"MySQL",icon:"/icons/mysql.png",desc:"Fast, reliable, scalable open-source relational database management system."},mssql:{label:"MSSQL",icon:"/icons/mssql.png",desc:"Powerful, scalable, secure relational database system by Microsoft."},duckdb:{label:"DuckDB",icon:"/icons/duckdb.png",desc:"In-memory analytical database with efficient query processing."},sqlite:{label:"Sqlite",icon:"/icons/sqlite.png",desc:"Lightweight embedded relational database with simplicity and portability."},clickhouse:{label:"ClickHouse",icon:"/icons/clickhouse.png",desc:"Columnar database for high-performance analytics and real-time queries."},oracle:{label:"Oracle",icon:"/icons/oracle.png",desc:"Robust, scalable, secure relational database widely used in enterprises."},access:{label:"Access",icon:"/icons/access.png",desc:"Easy-to-use relational database for small-scale applications by Microsoft."},mongodb:{label:"MongoDB",icon:"/icons/mongodb.png",desc:"Flexible, scalable NoSQL document database for web and mobile apps."},db2:{label:"DB2",icon:"/icons/db2.png",desc:"Scalable, secure relational database system developed by IBM."},hbase:{label:"HBase",icon:"/icons/hbase.png",desc:"Distributed, scalable NoSQL database for large structured/semi-structured data."},redis:{label:"Redis",icon:"/icons/redis.png",desc:"Fast, versatile in-memory data structure store as cache, DB, or broker."},cassandra:{label:"Cassandra",icon:"/icons/cassandra.png",desc:"Scalable, fault-tolerant distributed NoSQL database for large data."},couchbase:{label:"Couchbase",icon:"/icons/couchbase.png",desc:"High-performance NoSQL document database with distributed architecture."},postgresql:{label:"PostgreSQL",icon:"/icons/postgresql.png",desc:"Powerful open-source relational database with extensibility and SQL standards."},spark:{label:"Spark",icon:"/icons/spark.png",desc:"Unified engine for large-scale data analytics."}};function F(e,a){var s;return null===(s=e.find(e=>e.value===a))||void 0===s?void 0:s.isFileDb}var q=function(){let[e,a]=(0,t.useState)([]),[s,u]=(0,t.useState)([]),[p,h]=(0,t.useState)(!1),[x,y]=(0,t.useState)({open:!1}),[j,w]=(0,t.useState)({open:!1}),N=async()=>{let[e,a]=await (0,f.Vx)((0,f.Jm)());u(null!=a?a:[])},_=async()=>{h(!0);let[e,s]=await (0,f.Vx)((0,f.Bw)());a(null!=s?s:[]),h(!1)},F=(0,t.useMemo)(()=>{let e=s.map(e=>{let{db_type:a,is_file_db:s}=e;return{...P[a],value:a,isFileDb:s}}),a=Object.keys(P).filter(a=>!e.some(e=>e.value===a)).map(e=>({...P[e],value:P[e].label,disabled:!0}));return[...e,...a]},[s]),q=e=>{y({open:!0,info:e})},D=e=>{r.default.confirm({title:"Tips",content:"Do you Want to delete the ".concat(e.db_name,"?"),onOk:()=>new Promise(async(a,s)=>{try{let[l]=await (0,f.Vx)((0,f.J5)(e.db_name));if(l){i.ZP.error(l.message),s();return}i.ZP.success("success"),_(),a()}catch(e){s()}})})},E=(0,t.useMemo)(()=>{let a=F.reduce((a,s)=>(a[s.value]=e.filter(e=>e.db_type===s.value),a),{});return a},[e,F]);(0,n.Z)(async()=>{await _(),await N()},[]);let T=a=>{let s=e.filter(e=>e.db_type===a.value);w({open:!0,dbList:s,name:a.label,type:a.value})};return(0,l.jsxs)("div",{className:"relative p-6 px-12 bg-[#FAFAFA] dark:bg-transparent min-h-full overflow-y-auto",children:[(0,l.jsx)(S.Z,{visible:p}),(0,l.jsx)("div",{className:"mb-4",children:(0,l.jsx)(c.ZP,{type:"primary",className:"flex items-center",icon:(0,l.jsx)(Z.Z,{}),onClick:()=>{y({open:!0})},children:"Create"})}),(0,l.jsx)("div",{className:"flex flex-wrap",children:F.map(e=>(0,l.jsx)(o.Z,{className:"mr-4 mb-4",count:E[e.value].length,children:(0,l.jsx)(k,{info:e,onClick:()=>{T(e)}})},e.value))}),(0,l.jsx)(g,{open:x.open,dbTypeList:F,choiceDBType:x.dbType,editValue:x.info,dbNames:e.map(e=>e.db_name),onSuccess:()=>{y({open:!1}),_()},onClose:()=>{y({open:!1})}}),(0,l.jsx)(d.Z,{title:j.name,placement:"right",onClose:()=>{w({open:!1})},open:j.open,children:j.type&&E[j.type]&&E[j.type].length?(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(c.ZP,{type:"primary",className:"mb-4 flex items-center",icon:(0,l.jsx)(Z.Z,{}),onClick:()=>{y({open:!0,dbType:j.type})},children:"Create"}),E[j.type].map(e=>(0,l.jsxs)(b.Z,{title:e.db_name,extra:(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(v.Z,{className:"mr-2",style:{color:"#1b7eff"},onClick:()=>{q(e)}}),(0,l.jsx)(C.Z,{style:{color:"#ff1b2e"},onClick:()=>{D(e)}})]}),className:"mb-4",children:[e.db_path?(0,l.jsxs)("p",{children:["path: ",e.db_path]}):(0,l.jsxs)(l.Fragment,{children:[(0,l.jsxs)("p",{children:["host: ",e.db_host]}),(0,l.jsxs)("p",{children:["username: ",e.db_user]}),(0,l.jsxs)("p",{children:["port: ",e.db_port]})]}),(0,l.jsxs)("p",{children:["remark: ",e.comment]})]},e.db_name))]}):(0,l.jsx)(m.Z,{image:m.Z.PRESENTED_IMAGE_DEFAULT,children:(0,l.jsx)(c.ZP,{type:"primary",className:"flex items-center mx-auto",icon:(0,l.jsx)(Z.Z,{}),onClick:()=>{y({open:!0,dbType:j.type})},children:"Create Now"})})})]})}}},function(e){e.O(0,[44,479,9,442,813,411,928,643,774,888,179],function(){return e(e.s=55286)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/pilot/server/static/_next/static/chunks/pages/knowledge-40fc3593b22ec10a.js b/pilot/server/static/_next/static/chunks/pages/knowledge-40fc3593b22ec10a.js new file mode 100644 index 000000000..1172920a9 --- /dev/null +++ b/pilot/server/static/_next/static/chunks/pages/knowledge-40fc3593b22ec10a.js @@ -0,0 +1 @@ +(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[265],{54681:function(e,t,l){(window.__NEXT_P=window.__NEXT_P||[]).push(["/knowledge",function(){return l(4223)}])},47207:function(e,t,l){"use strict";l.d(t,{Z:function(){return c}});var s=l(85893),a=l(27595),n=l(27329),i=l(68346);function c(e){let{type:t}=e;return"TEXT"===t?(0,s.jsx)(a.Z,{className:"text-[#2AA3FF] mr-2 !text-lg"}):"DOCUMENT"===t?(0,s.jsx)(n.Z,{className:"text-[#2AA3FF] mr-2 !text-lg"}):(0,s.jsx)(i.Z,{className:"text-[#2AA3FF] mr-2 !text-lg"})}},4223:function(e,t,l){"use strict";l.r(t),l.d(t,{default:function(){return es}});var s=l(85893),a=l(67294),n=l(24969),i=l(71577),c=l(12069),r=l(3363),o=l(46735),d=l(74627),m=l(40411),u=l(11163),x=l(25675),h=l.n(x),p=l(28058),_=l(31484),j=l(78346),f=l(83062),b=l(66309),g=l(85813),N=l(32983),Z=l(42075),w=l(96074),y=l(75081),k=l(31326),v=l(88008),P=l(27704),T=l(18754),S=l(50489),C=l(30381),F=l.n(C),D=l(59566),E=l(71230),I=l(15746),A=l(39479),V=l(44442),z=l(67421),O=l(31545),q=l(6321);let{TextArea:U}=D.default;function M(e){let{space:t,argumentsShow:l,setArgumentsShow:n}=e,{t:r}=(0,z.$G)(),[o,d]=(0,a.useState)(),[m,u]=(0,a.useState)(!1),x=async()=>{let[e,l]=await (0,S.Vx)((0,S.Tu)(t.name));d(l)};(0,a.useEffect)(()=>{x()},[t.name]);let h=[{key:"Embedding",label:(0,s.jsxs)("div",{children:[(0,s.jsx)(O.Z,{}),r("Embedding")]}),children:(0,s.jsxs)(E.Z,{gutter:24,children:[(0,s.jsx)(I.Z,{span:12,offset:0,children:(0,s.jsx)(A.Z.Item,{tooltip:r("the_top_k_vectors"),rules:[{required:!0}],label:r("topk"),name:["embedding","topk"],children:(0,s.jsx)(D.default,{className:"mb-5 h-12"})})}),(0,s.jsx)(I.Z,{span:12,children:(0,s.jsx)(A.Z.Item,{tooltip:r("Set_a_threshold_score"),rules:[{required:!0}],label:r("recall_score"),name:["embedding","recall_score"],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:r("Please_input_the_owner")})})}),(0,s.jsx)(I.Z,{span:12,children:(0,s.jsx)(A.Z.Item,{tooltip:r("Recall_Type"),rules:[{required:!0}],label:r("recall_type"),name:["embedding","recall_type"],children:(0,s.jsx)(D.default,{className:"mb-5 h-12"})})}),(0,s.jsx)(I.Z,{span:12,children:(0,s.jsx)(A.Z.Item,{tooltip:r("A_model_used"),rules:[{required:!0}],label:r("model"),name:["embedding","model"],children:(0,s.jsx)(D.default,{className:"mb-5 h-12"})})}),(0,s.jsx)(I.Z,{span:12,children:(0,s.jsx)(A.Z.Item,{tooltip:r("The_size_of_the_data_chunks"),rules:[{required:!0}],label:r("chunk_size"),name:["embedding","chunk_size"],children:(0,s.jsx)(D.default,{className:"mb-5 h-12"})})}),(0,s.jsx)(I.Z,{span:12,children:(0,s.jsx)(A.Z.Item,{tooltip:r("The_amount_of_overlap"),rules:[{required:!0}],label:r("chunk_overlap"),name:["embedding","chunk_overlap"],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:r("Please_input_the_description")})})})]})},{key:"Prompt",label:(0,s.jsxs)("div",{children:[(0,s.jsx)(q.Z,{}),r("Prompt")]}),children:(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(A.Z.Item,{tooltip:r("A_contextual_parameter"),label:r("scene"),name:["prompt","scene"],children:(0,s.jsx)(U,{rows:4,className:"mb-2"})}),(0,s.jsx)(A.Z.Item,{tooltip:r("structure_or_format"),label:r("template"),name:["prompt","template"],children:(0,s.jsx)(U,{rows:7,className:"mb-2"})}),(0,s.jsx)(A.Z.Item,{tooltip:r("The_maximum_number_of_tokens"),label:r("max_token"),name:["prompt","max_token"],children:(0,s.jsx)(D.default,{className:"mb-2"})})]})}],p=async e=>{u(!0);let[l,s,a]=await (0,S.Vx)((0,S.iH)(t.name,{argument:JSON.stringify(e)}));u(!1),(null==a?void 0:a.success)&&n(!1)};return(0,s.jsx)(c.default,{width:850,open:l,onCancel:()=>{n(!1)},footer:null,children:(0,s.jsx)(y.Z,{spinning:m,children:(0,s.jsxs)(A.Z,{size:"large",className:"mt-4",layout:"vertical",name:"basic",initialValues:{...o},autoComplete:"off",onFinish:p,children:[(0,s.jsx)(V.Z,{items:h}),(0,s.jsxs)("div",{className:"mt-3 mb-3",children:[(0,s.jsx)(i.ZP,{htmlType:"submit",type:"primary",className:"mr-6",children:r("Submit")}),(0,s.jsx)(i.ZP,{onClick:()=>{n(!1)},children:r("close")})]})]})})})}var G=l(47207);let{confirm:R}=c.default;function H(e){let{space:t}=e,{t:l}=(0,z.$G)(),c=(0,u.useRouter)(),[r,o]=(0,a.useState)(!1),[d,m]=(0,a.useState)([]),[x,h]=(0,a.useState)(!1),_=e=>{R({title:l("Tips"),icon:(0,s.jsx)(p.Z,{}),content:"".concat(l("Del_Document_Tips"),"?"),okText:"Yes",okType:"danger",cancelText:"No",async onOk(){await D(e)}})};async function j(){o(!0);let[e,l]=await (0,S.Vx)((0,S._Q)(t.name,{page:1,page_size:20}));o(!1),m(null==l?void 0:l.data)}let C=async(e,t)=>{await (0,S.Vx)((0,S.Hx)(e,{doc_ids:[t]}))},D=async l=>{await (0,S.Vx)((0,S.n3)(t.name,{doc_name:l.doc_name})),j(),e.onDeleteDoc()},E=()=>{e.onAddDoc(t.name)},I=(e,t)=>{let l;switch(e){case"TODO":l="gold";break;case"RUNNING":l="#2db7f5";break;case"FINISHED":l="#87d068";break;default:l="f50"}return(0,s.jsx)(f.Z,{title:t,children:(0,s.jsx)(b.Z,{color:l,children:e})})};return(0,a.useEffect)(()=>{j()},[t]),(0,s.jsxs)("div",{className:"collapse-container pt-2 px-4",children:[(0,s.jsxs)(Z.Z,{children:[(0,s.jsx)(i.ZP,{size:"middle",type:"primary",className:"flex items-center",icon:(0,s.jsx)(n.Z,{}),onClick:E,children:l("Add_Datasource")}),(0,s.jsx)(i.ZP,{size:"middle",className:"flex items-center mx-2",icon:(0,s.jsx)(T.Z,{}),onClick:()=>{h(!0)},children:"Arguments"})]}),(0,s.jsx)(w.Z,{}),(0,s.jsx)(y.Z,{spinning:r,children:(null==d?void 0:d.length)>0?(0,s.jsx)("div",{className:"max-h-96 mt-3 grid grid-cols-1 gap-x-6 gap-y-5 sm:grid-cols-2 lg:grid-cols-3 xl:gap-x-5 overflow-auto",children:d.map(e=>(0,s.jsxs)(g.Z,{className:" dark:bg-[#484848] relative shrink-0 grow-0 cursor-pointer rounded-[10px] border border-gray-200 border-solid w-full",title:(0,s.jsx)(f.Z,{title:e.doc_name,children:(0,s.jsxs)("div",{className:"truncate ",children:[(0,s.jsx)(G.Z,{type:e.doc_type}),(0,s.jsx)("span",{children:e.doc_name})]})}),extra:(0,s.jsxs)("div",{className:"mx-3",children:[(0,s.jsx)(f.Z,{title:"detail",children:(0,s.jsx)(k.Z,{className:"mr-2 !text-lg",style:{color:"#1b7eff",fontSize:"20px"},onClick:()=>{c.push("/knowledge/chunk/?spaceName=".concat(t.name,"&id=").concat(e.id))}})}),(0,s.jsx)(f.Z,{title:"Sync",children:(0,s.jsx)(v.Z,{className:"mr-2 !text-lg",style:{color:"#1b7eff",fontSize:"20px"},onClick:()=>{C(t.name,e.id)}})}),(0,s.jsx)(f.Z,{title:"Delete",children:(0,s.jsx)(P.Z,{className:"text-[#ff1b2e] !text-lg",onClick:()=>{_(e)}})})]}),children:[(0,s.jsxs)("p",{className:"mt-2 font-semibold ",children:[l("Size"),":"]}),(0,s.jsxs)("p",{children:[e.chunk_size," chunks"]}),(0,s.jsxs)("p",{className:"mt-2 font-semibold ",children:[l("Last_Synch"),":"]}),(0,s.jsx)("p",{children:F()(e.last_sync).format("YYYY-MM-DD HH:MM:SS")}),(0,s.jsx)("p",{className:"mt-2 mb-2",children:I(e.status,e.result)})]},e.id))}):(0,s.jsx)(N.Z,{image:N.Z.PRESENTED_IMAGE_DEFAULT,children:(0,s.jsx)(i.ZP,{type:"primary",className:"flex items-center mx-auto",icon:(0,s.jsx)(n.Z,{}),onClick:E,children:"Create Now"})})}),(0,s.jsx)(M,{space:t,argumentsShow:x,setArgumentsShow:h})]})}var L=l(19284);let{confirm:Y}=c.default;function $(e){var t;let l=(0,u.useRouter)(),{t:a}=(0,z.$G)(),{space:n,getSpaces:c}=e,r=()=>{Y({title:a("Tips"),icon:(0,s.jsx)(p.Z,{}),content:"".concat(a("Del_Knowledge_Tips"),"?"),okText:"Yes",okType:"danger",cancelText:"No",async onOk(){await (0,S.Vx)((0,S.XK)({name:null==n?void 0:n.name})),c()}})},x=async e=>{e.stopPropagation();let[t,s]=await (0,S.Vx)((0,S.sW)({chat_mode:"chat_knowledge"}));(null==s?void 0:s.conv_uid)&&l.push("/chat?scene=chat_knowledge&id=".concat(null==s?void 0:s.conv_uid,"&db_param=").concat(n.name))};return(0,s.jsx)(o.ZP,{theme:{components:{Popover:{zIndexPopup:90}}},children:(0,s.jsx)(d.Z,{className:"dark:hover:border-white transition-all hover:shadow-md bg-[#FFFFFF] dark:bg-[#484848] cursor-pointer rounded-[10px] border border-gray-200 border-solid",placement:"bottom",trigger:"click",content:(0,s.jsx)(H,{space:n,onAddDoc:e.onAddDoc,onDeleteDoc:function(){c()}}),children:(0,s.jsxs)(m.Z,{className:"mr-4 mb-4 min-w-[200px] sm:w-60 lg:w-72",count:n.docs||0,children:[(0,s.jsxs)("div",{className:"flex justify-between mx-6 mt-3",children:[(0,s.jsxs)("div",{className:"text-lg font-bold text-black truncate",children:[(t=n.vector_type,(0,s.jsx)(h(),{className:"rounded-full w-8 h-8 border border-gray-200 object-contain bg-white inline-block",width:36,height:136,src:L.l[t]||"/models/knowledge-default.jpg",alt:"llm"})),(0,s.jsx)("span",{className:"dark:text-white ml-2",children:null==n?void 0:n.name})]}),(0,s.jsx)(_.Z,{onClick:e=>{e.stopPropagation(),e.nativeEvent.stopImmediatePropagation(),r()},twoToneColor:"#CD2029",className:"!text-2xl"})]}),(0,s.jsxs)("div",{className:"text-sm mt-2 p-6 pt-2 h-40",children:[(0,s.jsxs)("p",{className:"font-semibold",children:[a("Owner"),":"]}),(0,s.jsx)("p",{className:" truncate",children:null==n?void 0:n.owner}),(0,s.jsxs)("p",{className:"font-semibold mt-2",children:[a("Description"),":"]}),(0,s.jsx)("p",{className:" line-clamp-2",children:null==n?void 0:n.desc}),(0,s.jsx)("p",{className:"font-semibold mt-2",children:"Last modify:"}),(0,s.jsx)("p",{className:" truncate",children:F()(n.gmt_modified).format("YYYY-MM-DD HH:MM:SS")})]}),(0,s.jsx)("div",{className:"flex justify-center",children:(0,s.jsx)(i.ZP,{size:"middle",onClick:x,className:"mr-4 dark:text-white mb-2",shape:"round",icon:(0,s.jsx)(j.Z,{}),children:a("Chat")})})]})})})}var X=l(31365),K=l(2453),W=l(72269),B=l(64082);let{Dragger:J}=X.default,{TextArea:Q}=D.default;function ee(e){let{handleStepChange:t,spaceName:l,docType:n}=e,{t:c}=(0,z.$G)(),[r]=A.Z.useForm(),[o,d]=(0,a.useState)(!1),m=async e=>{let s;let{synchChecked:a,docName:i,textSource:c,originFileObj:r,text:o,webPageUrl:m}=e;switch(d(!0),n){case"webPage":s=await (0,S.Vx)((0,S.H_)(l,{doc_name:i,content:m,doc_type:"URL"}));break;case"file":let x=new FormData;x.append("doc_name",i||r.file.name),x.append("doc_file",r.file),x.append("doc_type","DOCUMENT"),s=await (0,S.Vx)((0,S.iG)(l,x));break;default:s=await (0,S.Vx)((0,S.H_)(l,{doc_name:i,source:c,content:o,doc_type:"TEXT"}))}a&&(null==u||u(l,null==s?void 0:s[1])),d(!1),t({label:"finish"})},u=async(e,t)=>{await (0,S.Vx)((0,S.Hx)(e,{doc_ids:[t]}))},x=e=>{let{file:t,fileList:l}=e;r.getFieldsValue().docName||r.setFieldValue("docName",t.name),0===l.length&&r.setFieldValue("originFileObj",null)},h=()=>{let e=r.getFieldsValue().originFileObj;return!!e&&(K.ZP.warning(c("Limit_Upload_File_Count_Tips")),X.default.LIST_IGNORE)},p=()=>(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(A.Z.Item,{label:"".concat(c("Text_Source"),":"),name:"textSource",rules:[{required:!0,message:c("Please_input_the_text_source")}],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:c("Please_input_the_text_source")})}),(0,s.jsx)(A.Z.Item,{label:"".concat(c("Text"),":"),name:"text",rules:[{required:!0,message:c("Please_input_the_description")}],children:(0,s.jsx)(Q,{rows:4})})]}),_=()=>(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(A.Z.Item,{label:"".concat(c("Web_Page_URL"),":"),name:"webPageUrl",rules:[{required:!0,message:c("Please_input_the_owner")}],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:c("Please_input_the_Web_Page_URL")})})}),j=()=>(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(A.Z.Item,{name:"originFileObj",rules:[{required:!0,message:c("Please_input_the_owner")}],children:(0,s.jsxs)(J,{onChange:x,beforeUpload:h,multiple:!1,accept:".pdf,.ppt,.pptx,.xls,.xlsx,.doc,.docx,.txt,.md",children:[(0,s.jsx)("p",{className:"ant-upload-drag-icon",children:(0,s.jsx)(B.Z,{})}),(0,s.jsx)("p",{style:{color:"rgb(22, 108, 255)",fontSize:"20px"},children:c("Select_or_Drop_file")}),(0,s.jsx)("p",{className:"ant-upload-hint",style:{color:"rgb(22, 108, 255)"},children:"PDF, PowerPoint, Excel, Word, Text, Markdown,"})]})})});return(0,s.jsx)(y.Z,{spinning:o,children:(0,s.jsxs)(A.Z,{form:r,size:"large",className:"mt-4",layout:"vertical",name:"basic",initialValues:{remember:!0},autoComplete:"off",onFinish:m,children:[(0,s.jsx)(A.Z.Item,{label:"".concat(c("Name"),":"),name:"docName",rules:[{required:!0,message:c("Please_input_the_name")}],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:c("Please_input_the_name")})}),(()=>{switch(n){case"webPage":return _();case"file":return j();default:return p()}})(),(0,s.jsx)(A.Z.Item,{label:"".concat(c("Synch"),":"),name:"synchChecked",initialValue:!0,children:(0,s.jsx)(W.Z,{className:"bg-slate-400",defaultChecked:!0})}),(0,s.jsxs)(A.Z.Item,{children:[(0,s.jsx)(i.ZP,{onClick:()=>{t({label:"back"})},className:"mr-4",children:"".concat(c("Back"))}),(0,s.jsx)(i.ZP,{type:"primary",htmlType:"submit",children:c("Finish")})]})]})})}function et(e){let{t}=(0,z.$G)(),{handleStepChange:l}=e,[n,c]=(0,a.useState)(!1),r=async e=>{let{spaceName:t,owner:s,description:a}=e;c(!0);let[n,i,r]=await (0,S.Vx)((0,S.be)({name:t,vector_type:"Chroma",owner:s,desc:a}));c(!1),(null==r?void 0:r.success)&&l({label:"forward",spaceName:t})};return(0,s.jsx)(y.Z,{spinning:n,children:(0,s.jsxs)(A.Z,{size:"large",className:"mt-4",layout:"vertical",name:"basic",initialValues:{remember:!0},autoComplete:"off",onFinish:r,children:[(0,s.jsx)(A.Z.Item,{label:t("Knowledge_Space_Name"),name:"spaceName",rules:[{required:!0,message:t("Please_input_the_name")},()=>({validator:(e,l)=>/[^\u4e00-\u9fa50-9a-zA-Z_-]/.test(l)?Promise.reject(Error(t("the_name_can_only_contain"))):Promise.resolve()})],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:t("Please_input_the_name")})}),(0,s.jsx)(A.Z.Item,{label:t("Owner"),name:"owner",rules:[{required:!0,message:t("Please_input_the_owner")}],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:t("Please_input_the_owner")})}),(0,s.jsx)(A.Z.Item,{label:t("Description"),name:"description",rules:[{required:!0,message:t("Please_input_the_description")}],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:t("Please_input_the_description")})}),(0,s.jsx)(A.Z.Item,{children:(0,s.jsx)(i.ZP,{type:"primary",htmlType:"submit",children:t("Next")})})]})})}function el(e){let{t}=(0,z.$G)(),{handleStepChange:l}=e,a=[{type:"text",title:t("Text"),subTitle:t("Fill your raw text"),iconType:"TEXT"},{type:"webPage",title:t("URL"),subTitle:t("Fetch_the_content_of_a_URL"),iconType:"WEBPAGE"},{type:"file",title:t("Document"),subTitle:t("Upload_a_document"),iconType:"DOCUMENT"}];return(0,s.jsx)(s.Fragment,{children:a.map((e,t)=>(0,s.jsxs)(g.Z,{className:"mt-4 mb-4 cursor-pointer",onClick:()=>{l({label:"forward",docType:e.type})},children:[(0,s.jsxs)("div",{className:"font-semibold",children:[(0,s.jsx)(G.Z,{type:e.iconType}),e.title]}),(0,s.jsx)("div",{children:e.subTitle})]},t))})}var es=()=>{let[e,t]=(0,a.useState)([]),[l,o]=(0,a.useState)(!1),[d,m]=(0,a.useState)(0),[u,x]=(0,a.useState)(""),[h,p]=(0,a.useState)(""),{t:_}=(0,z.$G)(),j=[{title:_("Knowledge_Space_Config")},{title:_("Choose_a_Datasource_type")},{title:_("Setup_the_Datasource")}];async function f(){let[e,l]=await (0,S.Vx)((0,S.Vm)());t(l)}(0,a.useEffect)(()=>{f()},[]);let b=e=>{let{label:t,spaceName:l,docType:s}=e;"finish"===t?(o(!1),f(),x(""),p("")):"forward"===t?(0===d&&f(),m(e=>e+1)):m(e=>e-1),l&&x(l),s&&p(s)};function g(e){x(e),m(1),o(!0)}return(0,s.jsxs)("div",{className:"bg-[#FAFAFA] dark:bg-[#212121] w-full h-full",children:[(0,s.jsxs)("div",{className:"page-body p-6 px-12 h-full overflow-auto",children:[(0,s.jsx)(i.ZP,{type:"primary",className:"flex items-center",icon:(0,s.jsx)(n.Z,{}),onClick:()=>{o(!0)},children:"Create"}),(0,s.jsx)("div",{className:"flex flex-wrap mt-4",children:null==e?void 0:e.map(e=>(0,s.jsx)($,{space:e,onAddDoc:g,getSpaces:f},e.id))})]}),(0,s.jsxs)(c.default,{title:"Add Knowledge",centered:!0,open:l,destroyOnClose:!0,onCancel:()=>{o(!1)},width:1e3,afterClose:()=>{m(0)},footer:null,children:[(0,s.jsx)(r.Z,{current:d,items:j}),0===d&&(0,s.jsx)(et,{handleStepChange:b}),1===d&&(0,s.jsx)(el,{handleStepChange:b}),2===d&&(0,s.jsx)(ee,{spaceName:u,docType:h,handleStepChange:b})]})]})}}},function(e){e.O(0,[885,44,479,442,365,813,411,63,774,888,179],function(){return e(e.s=54681)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/pilot/server/static/_next/static/chunks/pages/knowledge-c73b240310994685.js b/pilot/server/static/_next/static/chunks/pages/knowledge-c73b240310994685.js deleted file mode 100644 index 9f2b2cfe0..000000000 --- a/pilot/server/static/_next/static/chunks/pages/knowledge-c73b240310994685.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[265],{54681:function(e,t,l){(window.__NEXT_P=window.__NEXT_P||[]).push(["/knowledge",function(){return l(4223)}])},47207:function(e,t,l){"use strict";l.d(t,{Z:function(){return c}});var s=l(85893),a=l(27595),n=l(27329),i=l(68346);function c(e){let{type:t}=e;return"TEXT"===t?(0,s.jsx)(a.Z,{className:"text-[#2AA3FF] mr-2 !text-lg"}):"DOCUMENT"===t?(0,s.jsx)(n.Z,{className:"text-[#2AA3FF] mr-2 !text-lg"}):(0,s.jsx)(i.Z,{className:"text-[#2AA3FF] mr-2 !text-lg"})}},4223:function(e,t,l){"use strict";l.r(t),l.d(t,{default:function(){return es}});var s=l(85893),a=l(67294),n=l(24969),i=l(71577),c=l(12069),r=l(3363),o=l(46735),d=l(74627),m=l(40411),u=l(11163),x=l(25675),h=l.n(x),p=l(28058),_=l(31484),j=l(78346),f=l(83062),b=l(66309),g=l(85813),N=l(32983),Z=l(42075),w=l(96074),y=l(75081),k=l(31326),v=l(88008),T=l(27704),P=l(18754),S=l(50489),C=l(30381),F=l.n(C),D=l(59566),E=l(71230),I=l(15746),A=l(39479),V=l(44442),z=l(67421),O=l(31545),q=l(6321);let{TextArea:U}=D.default;function M(e){let{space:t,argumentsShow:l,setArgumentsShow:n}=e,{t:r}=(0,z.$G)(),[o,d]=(0,a.useState)(),[m,u]=(0,a.useState)(!1),x=async()=>{let[e,l]=await (0,S.Vx)((0,S.Tu)(t.name));d(l)};(0,a.useEffect)(()=>{x()},[t.name]);let h=[{key:"Embedding",label:(0,s.jsxs)("div",{children:[(0,s.jsx)(O.Z,{}),r("Embedding")]}),children:(0,s.jsxs)(E.Z,{gutter:24,children:[(0,s.jsx)(I.Z,{span:12,offset:0,children:(0,s.jsx)(A.Z.Item,{tooltip:r("the_top_k_vectors"),rules:[{required:!0}],label:r("topk"),name:["embedding","topk"],children:(0,s.jsx)(D.default,{className:"mb-5 h-12"})})}),(0,s.jsx)(I.Z,{span:12,children:(0,s.jsx)(A.Z.Item,{tooltip:r("Set_a_threshold_score"),rules:[{required:!0}],label:r("recall_score"),name:["embedding","recall_score"],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:r("Please_input_the_owner")})})}),(0,s.jsx)(I.Z,{span:12,children:(0,s.jsx)(A.Z.Item,{tooltip:r("Recall_Type"),rules:[{required:!0}],label:r("recall_type"),name:["embedding","recall_type"],children:(0,s.jsx)(D.default,{className:"mb-5 h-12"})})}),(0,s.jsx)(I.Z,{span:12,children:(0,s.jsx)(A.Z.Item,{tooltip:r("A_model_used"),rules:[{required:!0}],label:r("model"),name:["embedding","model"],children:(0,s.jsx)(D.default,{className:"mb-5 h-12"})})}),(0,s.jsx)(I.Z,{span:12,children:(0,s.jsx)(A.Z.Item,{tooltip:r("The_size_of_the_data_chunks"),rules:[{required:!0}],label:r("chunk_size"),name:["embedding","chunk_size"],children:(0,s.jsx)(D.default,{className:"mb-5 h-12"})})}),(0,s.jsx)(I.Z,{span:12,children:(0,s.jsx)(A.Z.Item,{tooltip:r("The_amount_of_overlap"),rules:[{required:!0}],label:r("chunk_overlap"),name:["embedding","chunk_overlap"],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:r("Please_input_the_description")})})})]})},{key:"Prompt",label:(0,s.jsxs)("div",{children:[(0,s.jsx)(q.Z,{}),r("Embedding")]}),children:(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(A.Z.Item,{tooltip:r("A_contextual_parameter"),label:r("scene"),name:["prompt","scene"],children:(0,s.jsx)(U,{rows:4,className:"mb-2"})}),(0,s.jsx)(A.Z.Item,{tooltip:r("structure_or_format"),label:r("template"),name:["prompt","template"],children:(0,s.jsx)(U,{rows:7,className:"mb-2"})}),(0,s.jsx)(A.Z.Item,{tooltip:r("The_maximum_number_of_tokens"),label:r("max_token"),name:["prompt","max_token"],children:(0,s.jsx)(D.default,{className:"mb-2"})})]})}],p=async e=>{u(!0);let[l,s,a]=await (0,S.Vx)((0,S.iH)(t.name,{argument:JSON.stringify(e)}));u(!1),(null==a?void 0:a.success)&&n(!1)};return(0,s.jsx)(c.default,{width:850,open:l,onCancel:()=>{n(!1)},footer:null,children:(0,s.jsx)(y.Z,{spinning:m,children:(0,s.jsxs)(A.Z,{size:"large",className:"mt-4",layout:"vertical",name:"basic",initialValues:{...o},autoComplete:"off",onFinish:p,children:[(0,s.jsx)(V.Z,{items:h}),(0,s.jsxs)("div",{className:"mt-3 mb-3",children:[(0,s.jsx)(i.ZP,{htmlType:"submit",type:"primary",className:"mr-6",children:r("Submit")}),(0,s.jsx)(i.ZP,{onClick:()=>{n(!1)},children:r("close")})]})]})})})}var G=l(47207);let{confirm:R}=c.default;function H(e){let{space:t}=e,{t:l}=(0,z.$G)(),c=(0,u.useRouter)(),[r,o]=(0,a.useState)(!1),[d,m]=(0,a.useState)([]),[x,h]=(0,a.useState)(!1),_=e=>{R({title:l("Tips"),icon:(0,s.jsx)(p.Z,{}),content:"".concat(l("Del_Document_Tips"),"?"),okText:"Yes",okType:"danger",cancelText:"No",async onOk(){await D(e)}})};async function j(){o(!0);let[e,l]=await (0,S.Vx)((0,S._Q)(t.name,{page:1,page_size:20}));o(!1),m(null==l?void 0:l.data)}let C=async(e,t)=>{await (0,S.Vx)((0,S.Hx)(e,{doc_ids:[t]}))},D=async l=>{await (0,S.Vx)((0,S.n3)(t.name,{doc_name:l.doc_name})),j(),e.onDeleteDoc()},E=()=>{e.onAddDoc(t.name)},I=(e,t)=>{let l;switch(e){case"TODO":l="gold";break;case"RUNNING":l="#2db7f5";break;case"FINISHED":l="#87d068";break;default:l="f50"}return(0,s.jsx)(f.Z,{title:t,children:(0,s.jsx)(b.Z,{color:l,children:e})})};return(0,a.useEffect)(()=>{j()},[t]),(0,s.jsxs)("div",{className:"collapse-container pt-2 px-4",children:[(0,s.jsxs)(Z.Z,{children:[(0,s.jsx)(i.ZP,{size:"middle",type:"primary",className:"flex items-center",icon:(0,s.jsx)(n.Z,{}),onClick:E,children:l("Add_Datasource")}),(0,s.jsx)(i.ZP,{size:"middle",className:"flex items-center mx-2",icon:(0,s.jsx)(P.Z,{}),onClick:()=>{h(!0)},children:"Arguments"})]}),(0,s.jsx)(w.Z,{}),(0,s.jsx)(y.Z,{spinning:r,children:(null==d?void 0:d.length)>0?(0,s.jsx)("div",{className:"max-h-96 mt-3 grid grid-cols-1 gap-x-6 gap-y-5 sm:grid-cols-2 lg:grid-cols-3 xl:gap-x-5 overflow-auto",children:d.map(e=>(0,s.jsxs)(g.Z,{className:" dark:bg-[#484848] relative shrink-0 grow-0 cursor-pointer rounded-[10px] border border-gray-200 border-solid w-full",title:(0,s.jsx)(f.Z,{title:e.doc_name,children:(0,s.jsxs)("div",{className:"truncate ",children:[(0,s.jsx)(G.Z,{type:e.doc_type}),(0,s.jsx)("span",{children:e.doc_name})]})}),extra:(0,s.jsxs)("div",{className:"mx-3",children:[(0,s.jsx)(f.Z,{title:"detail",children:(0,s.jsx)(k.Z,{className:"mr-2 !text-lg",style:{color:"#1b7eff",fontSize:"20px"},onClick:()=>{c.push("/knowledge/chunk/?spaceName=".concat(t.name,"&id=").concat(e.id))}})}),(0,s.jsx)(f.Z,{title:"Sync",children:(0,s.jsx)(v.Z,{className:"mr-2 !text-lg",style:{color:"#1b7eff",fontSize:"20px"},onClick:()=>{C(t.name,e.id)}})}),(0,s.jsx)(f.Z,{title:"Delete",children:(0,s.jsx)(T.Z,{className:"text-[#ff1b2e] !text-lg",onClick:()=>{_(e)}})})]}),children:[(0,s.jsxs)("p",{className:"mt-2 font-semibold ",children:[l("Size"),":"]}),(0,s.jsxs)("p",{children:[e.chunk_size," chunks"]}),(0,s.jsxs)("p",{className:"mt-2 font-semibold ",children:[l("Last_Synch"),":"]}),(0,s.jsx)("p",{children:F()(e.last_sync).format("YYYY-MM-DD HH:MM:SS")}),(0,s.jsx)("p",{className:"mt-2 mb-2",children:I(e.status,e.result)})]},e.id))}):(0,s.jsx)(N.Z,{image:N.Z.PRESENTED_IMAGE_DEFAULT,children:(0,s.jsx)(i.ZP,{type:"primary",className:"flex items-center mx-auto",icon:(0,s.jsx)(n.Z,{}),onClick:E,children:"Create Now"})})}),(0,s.jsx)(M,{space:t,argumentsShow:x,setArgumentsShow:h})]})}var L=l(19284);let{confirm:Y}=c.default;function $(e){var t;let l=(0,u.useRouter)(),{t:a}=(0,z.$G)(),{space:n,getSpaces:c}=e,r=()=>{Y({title:a("Tips"),icon:(0,s.jsx)(p.Z,{}),content:"".concat(a("Del_Knowledge_Tips"),"?"),okText:"Yes",okType:"danger",cancelText:"No",async onOk(){await (0,S.Vx)((0,S.XK)({name:null==n?void 0:n.name})),c()}})},x=async e=>{e.stopPropagation();let[t,s]=await (0,S.Vx)((0,S.sW)({chat_mode:"chat_knowledge"}));(null==s?void 0:s.conv_uid)&&l.push("/chat?scene=chat_knowledge&id=".concat(null==s?void 0:s.conv_uid,"&db_param=").concat(n.name))};return(0,s.jsx)(o.ZP,{theme:{components:{Popover:{zIndexPopup:90}}},children:(0,s.jsx)(d.Z,{className:"dark:hover:border-white transition-all hover:shadow-md bg-[#FFFFFF] dark:bg-[#484848] cursor-pointer rounded-[10px] border border-gray-200 border-solid",placement:"bottom",trigger:"click",content:(0,s.jsx)(H,{space:n,onAddDoc:e.onAddDoc,onDeleteDoc:function(){c()}}),children:(0,s.jsxs)(m.Z,{className:"mr-4 mb-4 min-w-[200px] sm:w-60 lg:w-72",count:n.docs||0,children:[(0,s.jsxs)("div",{className:"flex justify-between mx-6 mt-3",children:[(0,s.jsxs)("div",{className:"text-lg font-bold text-black truncate",children:[(t=n.vector_type,(0,s.jsx)(h(),{className:"rounded-full w-8 h-8 border border-gray-200 object-contain bg-white inline-block",width:36,height:136,src:L.l[t]||"/models/knowledge-default.jpg",alt:"llm"})),(0,s.jsx)("span",{className:"dark:text-white ml-2",children:null==n?void 0:n.name})]}),(0,s.jsx)(_.Z,{onClick:e=>{e.stopPropagation(),e.nativeEvent.stopImmediatePropagation(),r()},twoToneColor:"#CD2029",className:"!text-2xl"})]}),(0,s.jsxs)("div",{className:"text-sm mt-2 p-6 pt-2 h-40",children:[(0,s.jsxs)("p",{className:"font-semibold",children:[a("Owner"),":"]}),(0,s.jsx)("p",{className:" truncate",children:null==n?void 0:n.owner}),(0,s.jsxs)("p",{className:"font-semibold mt-2",children:[a("Description"),":"]}),(0,s.jsx)("p",{className:" line-clamp-2",children:null==n?void 0:n.desc}),(0,s.jsx)("p",{className:"font-semibold mt-2",children:"Last modify:"}),(0,s.jsx)("p",{className:" truncate",children:F()(n.gmt_modified).format("YYYY-MM-DD HH:MM:SS")})]}),(0,s.jsx)("div",{className:"flex justify-center",children:(0,s.jsx)(i.ZP,{size:"middle",onClick:x,className:"mr-4 dark:text-white mb-2",shape:"round",icon:(0,s.jsx)(j.Z,{}),children:a("Chat")})})]})})})}var X=l(31365),K=l(2453),W=l(72269),B=l(64082);let{Dragger:J}=X.default,{TextArea:Q}=D.default;function ee(e){let{handleStepChange:t,spaceName:l,docType:n}=e,{t:c}=(0,z.$G)(),[r]=A.Z.useForm(),[o,d]=(0,a.useState)(!1),m=async e=>{let s;let{synchChecked:a,docName:i,textSource:c,originFileObj:r,text:o,webPageUrl:m}=e;switch(d(!0),n){case"webPage":s=await (0,S.Vx)((0,S.H_)(l,{doc_name:i,content:m,doc_type:"URL"}));break;case"file":let x=new FormData;x.append("doc_name",i||r.file.name),x.append("doc_file",r.file),x.append("doc_type","DOCUMENT"),s=await (0,S.Vx)((0,S.iG)(l,x));break;default:s=await (0,S.Vx)((0,S.H_)(l,{doc_name:i,source:c,content:o,doc_type:"TEXT"}))}a&&(null==u||u(l,null==s?void 0:s[1])),d(!1),t({label:"finish"})},u=async(e,t)=>{await (0,S.Vx)((0,S.Hx)(e,{doc_ids:[t]}))},x=e=>{let{file:t,fileList:l}=e;r.getFieldsValue().docName||r.setFieldValue("docName",t.name),0===l.length&&r.setFieldValue("originFileObj",null)},h=()=>{let e=r.getFieldsValue().originFileObj;return!!e&&(K.ZP.warning(c("Limit_Upload_File_Count_Tips")),X.default.LIST_IGNORE)},p=()=>(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(A.Z.Item,{label:"".concat(c("Text_Source"),":"),name:"textSource",rules:[{required:!0,message:c("Please_input_the_text_source")}],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:c("Please_input_the_text_source")})}),(0,s.jsx)(A.Z.Item,{label:"".concat(c("Text"),":"),name:"text",rules:[{required:!0,message:c("Please_input_the_description")}],children:(0,s.jsx)(Q,{rows:4})})]}),_=()=>(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(A.Z.Item,{label:"".concat(c("Web_Page_URL"),":"),name:"webPageUrl",rules:[{required:!0,message:c("Please_input_the_owner")}],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:c("Please_input_the_Web_Page_URL")})})}),j=()=>(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(A.Z.Item,{name:"originFileObj",rules:[{required:!0,message:c("Please_input_the_owner")}],children:(0,s.jsxs)(J,{onChange:x,beforeUpload:h,multiple:!1,accept:".pdf,.ppt,.pptx,.xls,.xlsx,.doc,.docx,.txt,.md",children:[(0,s.jsx)("p",{className:"ant-upload-drag-icon",children:(0,s.jsx)(B.Z,{})}),(0,s.jsx)("p",{style:{color:"rgb(22, 108, 255)",fontSize:"20px"},children:c("Select_or_Drop_file")}),(0,s.jsx)("p",{className:"ant-upload-hint",style:{color:"rgb(22, 108, 255)"},children:"PDF, PowerPoint, Excel, Word, Text, Markdown,"})]})})});return(0,s.jsx)(y.Z,{spinning:o,children:(0,s.jsxs)(A.Z,{form:r,size:"large",className:"mt-4",layout:"vertical",name:"basic",initialValues:{remember:!0},autoComplete:"off",onFinish:m,children:[(0,s.jsx)(A.Z.Item,{label:"".concat(c("Name"),":"),name:"docName",rules:[{required:!0,message:c("Please_input_the_name")}],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:c("Please_input_the_name")})}),(()=>{switch(n){case"webPage":return _();case"file":return j();default:return p()}})(),(0,s.jsx)(A.Z.Item,{label:"".concat(c("Synch"),":"),name:"synchChecked",initialValue:!0,children:(0,s.jsx)(W.Z,{className:"bg-slate-400",defaultChecked:!0})}),(0,s.jsxs)(A.Z.Item,{children:[(0,s.jsx)(i.ZP,{onClick:()=>{t({label:"back"})},className:"mr-4",children:"".concat(c("Back"))}),(0,s.jsx)(i.ZP,{type:"primary",htmlType:"submit",children:c("Finish")})]})]})})}function et(e){let{t}=(0,z.$G)(),{handleStepChange:l}=e,[n,c]=(0,a.useState)(!1),r=async e=>{let{spaceName:t,owner:s,description:a}=e;c(!0);let[n,i,r]=await (0,S.Vx)((0,S.be)({name:t,vector_type:"Chroma",owner:s,desc:a}));c(!1),(null==r?void 0:r.success)&&l({label:"forward",spaceName:t})};return(0,s.jsx)(y.Z,{spinning:n,children:(0,s.jsxs)(A.Z,{size:"large",className:"mt-4",layout:"vertical",name:"basic",initialValues:{remember:!0},autoComplete:"off",onFinish:r,children:[(0,s.jsx)(A.Z.Item,{label:t("Knowledge_Space_Name"),name:"spaceName",rules:[{required:!0,message:t("Please_input_the_name")},()=>({validator:(e,l)=>/[^\u4e00-\u9fa50-9a-zA-Z_-]/.test(l)?Promise.reject(Error(t("the_name_can_only_contain"))):Promise.resolve()})],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:t("Please_input_the_name")})}),(0,s.jsx)(A.Z.Item,{label:t("Owner"),name:"owner",rules:[{required:!0,message:t("Please_input_the_owner")}],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:t("Please_input_the_owner")})}),(0,s.jsx)(A.Z.Item,{label:t("Description"),name:"description",rules:[{required:!0,message:t("Please_input_the_description")}],children:(0,s.jsx)(D.default,{className:"mb-5 h-12",placeholder:t("Please_input_the_description")})}),(0,s.jsx)(A.Z.Item,{children:(0,s.jsx)(i.ZP,{type:"primary",htmlType:"submit",children:t("Next")})})]})})}function el(e){let{t}=(0,z.$G)(),{handleStepChange:l}=e,a=[{type:"text",title:t("Text"),subTitle:t("Fill your raw text"),iconType:"TEXT"},{type:"webPage",title:t("URL"),subTitle:t("Fetch_the_content_of_a_URL"),iconType:"WEBPAGE"},{type:"file",title:t("Document"),subTitle:t("Upload_a_document"),iconType:"DOCUMENT"}];return(0,s.jsx)(s.Fragment,{children:a.map((e,t)=>(0,s.jsxs)(g.Z,{className:"mt-4 mb-4 cursor-pointer",onClick:()=>{l({label:"forward",docType:e.type})},children:[(0,s.jsxs)("div",{className:"font-semibold",children:[(0,s.jsx)(G.Z,{type:e.iconType}),e.title]}),(0,s.jsx)("div",{children:e.subTitle})]},t))})}var es=()=>{let[e,t]=(0,a.useState)([]),[l,o]=(0,a.useState)(!1),[d,m]=(0,a.useState)(0),[u,x]=(0,a.useState)(""),[h,p]=(0,a.useState)(""),{t:_}=(0,z.$G)(),j=[{title:_("Knowledge_Space_Config")},{title:_("Choose_a_Datasource_type")},{title:_("Setup_the_Datasource")}];async function f(){let[e,l]=await (0,S.Vx)((0,S.Vm)());t(l)}(0,a.useEffect)(()=>{f()},[]);let b=e=>{let{label:t,spaceName:l,docType:s}=e;"finish"===t?(o(!1),f(),x(""),p("")):"forward"===t?(0===d&&f(),m(e=>e+1)):m(e=>e-1),l&&x(l),s&&p(s)};function g(e){x(e),m(1),o(!0)}return(0,s.jsxs)("div",{className:"bg-[#FAFAFA] dark:bg-[#212121] w-full h-full",children:[(0,s.jsxs)("div",{className:"page-body p-6 px-12 h-full overflow-auto",children:[(0,s.jsx)(i.ZP,{type:"primary",className:"flex items-center",icon:(0,s.jsx)(n.Z,{}),onClick:()=>{o(!0)},children:"Create"}),(0,s.jsx)("div",{className:"flex flex-wrap mt-4",children:null==e?void 0:e.map(e=>(0,s.jsx)($,{space:e,onAddDoc:g,getSpaces:f},e.id))})]}),(0,s.jsxs)(c.default,{title:"Add Knowledge",centered:!0,open:l,destroyOnClose:!0,onCancel:()=>{o(!1)},width:1e3,afterClose:()=>{m(0)},footer:null,children:[(0,s.jsx)(r.Z,{current:d,items:j}),0===d&&(0,s.jsx)(et,{handleStepChange:b}),1===d&&(0,s.jsx)(el,{handleStepChange:b}),2===d&&(0,s.jsx)(ee,{spaceName:u,docType:h,handleStepChange:b})]})]})}}},function(e){e.O(0,[885,44,479,442,365,813,411,63,774,888,179],function(){return e(e.s=54681)}),_N_E=e.O()}]); \ No newline at end of file diff --git a/pilot/server/static/_next/static/chunks/webpack-fbcb320c82fd7041.js b/pilot/server/static/_next/static/chunks/webpack-77553ab117b6c794.js similarity index 60% rename from pilot/server/static/_next/static/chunks/webpack-fbcb320c82fd7041.js rename to pilot/server/static/_next/static/chunks/webpack-77553ab117b6c794.js index 0b2de09b3..d917d76bf 100644 --- a/pilot/server/static/_next/static/chunks/webpack-fbcb320c82fd7041.js +++ b/pilot/server/static/_next/static/chunks/webpack-77553ab117b6c794.js @@ -1 +1 @@ -!function(){"use strict";var e,t,n,r,o,u,c,i,a,f,s,d,l={},b={};function p(e){var t=b[e];if(void 0!==t)return t.exports;var n=b[e]={id:e,loaded:!1,exports:{}},r=!0;try{l[e].call(n.exports,n,n.exports,p),r=!1}finally{r&&delete b[e]}return n.loaded=!0,n.exports}p.m=l,p.amdO={},e=[],p.O=function(t,n,r,o){if(n){o=o||0;for(var u=e.length;u>0&&e[u-1][2]>o;u--)e[u]=e[u-1];e[u]=[n,r,o];return}for(var c=1/0,u=0;u=o&&Object.keys(p.O).every(function(e){return p.O[e](n[a])})?n.splice(a--,1):(i=!1,o0&&e[u-1][2]>o;u--)e[u]=e[u-1];e[u]=[n,r,o];return}for(var a=1/0,u=0;u=o&&Object.keys(p.O).every(function(e){return p.O[e](n[c])})?n.splice(c--,1):(i=!1,o:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overflow-y-scroll{overflow-y:scroll}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-\[10px\]{border-radius:10px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.rounded-br{border-bottom-right-radius:.25rem}.rounded-tl-md{border-top-left-radius:.375rem}.rounded-tr{border-top-right-radius:.25rem}.rounded-tr-md{border-top-right-radius:.375rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-solid{border-style:solid}.border-dashed{border-style:dashed}.border-none{border-style:none}.border-\[\#f0f0f0\]{--tw-border-opacity:1;border-color:rgb(240 240 240/var(--tw-border-opacity))}.border-\[var\(--joy-palette-divider\)\]{border-color:var(--joy-palette-divider)}.border-blue-600{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity))}.border-gray-100{--tw-border-opacity:1;border-color:rgb(243 244 246/var(--tw-border-opacity))}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity))}.border-slate-300{--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity))}.bg-\[\#E6F4FF\]{--tw-bg-opacity:1;background-color:rgb(230 244 255/var(--tw-bg-opacity))}.bg-\[\#FAFAFA\]{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity))}.bg-\[\#FFFFFF\]{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-\[\#fafafa\]{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.bg-gray-500{--tw-bg-opacity:1;background-color:rgb(107 114 128/var(--tw-bg-opacity))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity))}.bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.bg-green-500{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity))}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity))}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-slate-400{--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-opacity-50{--tw-bg-opacity:0.5}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-\[\#31afff\]{--tw-gradient-from:#31afff var(--tw-gradient-from-position);--tw-gradient-to:rgba(49,175,255,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.to-\[\#1677ff\]{--tw-gradient-to:#1677ff var(--tw-gradient-to-position)}.object-contain{-o-object-fit:contain;object-fit:contain}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-0{padding-left:0;padding-right:0}.px-12{padding-left:3rem;padding-right:3rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.px-\[6px\]{padding-left:6px;padding-right:6px}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-\[2px\]{padding-top:2px;padding-bottom:2px}.pb-4{padding-bottom:1rem}.pb-6{padding-bottom:1.5rem}.pb-8{padding-bottom:2rem}.pl-0{padding-left:0}.pl-0\.5{padding-left:.125rem}.pl-2{padding-left:.5rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.\!text-left{text-align:left!important}.\!text-2xl{font-size:1.5rem!important;line-height:2rem!important}.\!text-3xl{font-size:1.875rem!important;line-height:2.25rem!important}.\!text-lg{font-size:1.125rem!important;line-height:1.75rem!important}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-normal{font-weight:400}.font-semibold{font-weight:600}.leading-6{line-height:1.5rem}.leading-7{line-height:1.75rem}.leading-8{line-height:2rem}.\!text-\[\#878c93\]{--tw-text-opacity:1!important;color:rgb(135 140 147/var(--tw-text-opacity))!important}.\!text-green-600{--tw-text-opacity:1!important;color:rgb(22 163 74/var(--tw-text-opacity))!important}.\!text-orange-600{--tw-text-opacity:1!important;color:rgb(234 88 12/var(--tw-text-opacity))!important}.\!text-red-600{--tw-text-opacity:1!important;color:rgb(220 38 38/var(--tw-text-opacity))!important}.text-\[\#1677FE\]{--tw-text-opacity:1;color:rgb(22 119 254/var(--tw-text-opacity))}.text-\[\#1677ff\]{--tw-text-opacity:1;color:rgb(22 119 255/var(--tw-text-opacity))}.text-\[\#2AA3FF\]{--tw-text-opacity:1;color:rgb(42 163 255/var(--tw-text-opacity))}.text-\[\#ff1b2e\]{--tw-text-opacity:1;color:rgb(255 27 46/var(--tw-text-opacity))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}.text-gray-100{--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity))}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}.text-slate-900{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.opacity-0{opacity:0}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.grayscale{--tw-grayscale:grayscale(100%)}.filter,.grayscale{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-\[width\]{transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.animate-duration-200{animation-duration:.2s}.animate-duration-300{animation-duration:.3s}body{margin:0;color:var(--joy-palette-text-primary,var(--joy-palette-neutral-800,#25252d));font-family:var(--joy-fontFamily-body,var(--joy-Josefin Sans,sans-serif));font-size:var(--joy-fontSize-md,1rem);line-height:var(--joy-lineHeight-md,1.5);background-color:var(--joy-palette-background-body)}body .ant-btn-primary{background-color:#1677ff}.ant-pagination .ant-pagination-next *,.ant-pagination .ant-pagination-prev *{color:#279bff!important}.ant-pagination .ant-pagination-item a{color:#b0b0bf}.ant-pagination .ant-pagination-item.ant-pagination-item-active{background-color:#279bff!important}.ant-pagination .ant-pagination-item.ant-pagination-item-active a{color:#fff!important}table tr td{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}::-webkit-scrollbar{display:none}::-webkit-scrollbar-track{background:#f1f1f1}::-webkit-scrollbar-thumb{background:#888}::-webkit-scrollbar-thumb:hover{background:#555}.dark :where(.css-dev-only-do-not-override-18iikkb).ant-tabs .ant-tabs-tab-btn{color:#fff}:where(.css-dev-only-do-not-override-18iikkb).ant-form-item .ant-form-item-label>label{height:36px}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:-top-8:after{content:var(--tw-content);top:-2rem}.after\:h-8:after{content:var(--tw-content);height:2rem}.after\:w-full:after{content:var(--tw-content);width:100%}.after\:bg-gradient-to-t:after{content:var(--tw-content);background-image:linear-gradient(to top,var(--tw-gradient-stops))}.after\:from-white:after{content:var(--tw-content);--tw-gradient-from:#fff var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.after\:to-transparent:after{content:var(--tw-content);--tw-gradient-to:transparent var(--tw-gradient-to-position)}.hover\:bg-slate-100:hover{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.hover\:\!text-gray-200:hover{--tw-text-opacity:1!important;color:rgb(229 231 235/var(--tw-text-opacity))!important}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.group\/item:hover .group-hover\/item\:opacity-100{opacity:1}:is(.dark .dark\:border-gray-600){--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity))}:is(.dark .dark\:border-gray-700){--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}:is(.dark .dark\:border-white){--tw-border-opacity:1;border-color:rgb(255 255 255/var(--tw-border-opacity))}:is(.dark .dark\:bg-\[\#1A1E26\]){--tw-bg-opacity:1;background-color:rgb(26 30 38/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#212121\]){--tw-bg-opacity:1;background-color:rgb(33 33 33/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#353539\]){--tw-bg-opacity:1;background-color:rgb(53 53 57/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#484848\]){--tw-bg-opacity:1;background-color:rgb(72 72 72/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#4E4F56\]){--tw-bg-opacity:1;background-color:rgb(78 79 86/var(--tw-bg-opacity))}:is(.dark .dark\:bg-black){--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-100){--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-800){--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-900){--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}:is(.dark .dark\:bg-slate-800){--tw-bg-opacity:1;background-color:rgb(30 41 59/var(--tw-bg-opacity))}:is(.dark .dark\:bg-transparent){background-color:transparent}:is(.dark .dark\:bg-opacity-50){--tw-bg-opacity:0.5}:is(.dark .dark\:bg-gradient-to-r){background-image:linear-gradient(to right,var(--tw-gradient-stops))}:is(.dark .dark\:from-\[\#6a6a6a\]){--tw-gradient-from:#6a6a6a var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,42%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}:is(.dark .dark\:to-\[\#80868f\]){--tw-gradient-to:#80868f var(--tw-gradient-to-position)}:is(.dark .dark\:text-blue-400){--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-100){--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-200){--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-300){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-400){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-800){--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}:is(.dark .dark\:text-slate-300){--tw-text-opacity:1;color:rgb(203 213 225/var(--tw-text-opacity))}:is(.dark .dark\:text-white){--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}:is(.dark .dark\:after\:from-\[\#212121\]):after{content:var(--tw-content);--tw-gradient-from:#212121 var(--tw-gradient-from-position);--tw-gradient-to:rgba(33,33,33,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}:is(.dark .dark\:hover\:border-white:hover){--tw-border-opacity:1;border-color:rgb(255 255 255/var(--tw-border-opacity))}:is(.dark .dark\:hover\:bg-\[\#353539\]:hover){--tw-bg-opacity:1;background-color:rgb(53 53 57/var(--tw-bg-opacity))}@media not all and (min-width:768px){.max-md\:hidden{display:none}}@media (min-width:640px){.sm\:mr-4{margin-right:1rem}.sm\:inline-block{display:inline-block}.sm\:w-1\/2{width:50%}.sm\:w-60{width:15rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:py-6{padding-top:1.5rem;padding-bottom:1.5rem}.sm\:pb-10{padding-bottom:2.5rem}.sm\:pt-6{padding-top:1.5rem}.sm\:text-base{font-size:1rem;line-height:1.5rem}.sm\:leading-7{line-height:1.75rem}}@media (min-width:768px){.md\:-m-3{margin:-.75rem}.md\:mt-4{margin-top:1rem}.md\:block{display:block}.md\:w-1\/2{width:50%}.md\:gap-4{gap:1rem}.md\:p-3{padding:.75rem}.md\:p-6{padding:1.5rem}.md\:px-4{padding-left:1rem;padding-right:1rem}.md\:px-6{padding-left:1.5rem;padding-right:1.5rem}.md\:pt-10{padding-top:2.5rem}.md\:pt-4{padding-top:1rem}}@media (min-width:1024px){.lg\:w-1\/3{width:33.333333%}.lg\:w-72{width:18rem}.lg\:w-full{width:100%}.lg\:max-w-\[80\%\]{max-width:80%}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (min-width:1280px){.xl\:h-full{height:100%}.xl\:w-1\/4{width:25%}.xl\:w-3\/4{width:75%}.xl\:w-full{width:100%}.xl\:gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.xl\:border-l{border-left-width:1px}.xl\:border-t-0{border-top-width:0}.xl\:pl-4{padding-left:1rem}.xl\:pr-4{padding-right:1rem}}#nprogress{pointer-events:none}#nprogress .bar{background:var(--joy-palette-primary-500,#096bde);position:fixed;z-index:10031;top:0;left:0;width:100%;height:3px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px var(--joy-palette-primary-500,#096bde),0 0 5px var(--joy-palette-primary-500,#096bde);opacity:1;transform:rotate(3deg) translateY(-4px)} \ No newline at end of file diff --git a/pilot/server/static/_next/static/css/d07b94ffd4f33c05.css b/pilot/server/static/_next/static/css/d07b94ffd4f33c05.css new file mode 100644 index 000000000..ab5ef8da0 --- /dev/null +++ b/pilot/server/static/_next/static/css/d07b94ffd4f33c05.css @@ -0,0 +1,3 @@ +/* +! tailwindcss v3.3.2 | MIT License | https://tailwindcss.com +*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Josefin Sans,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.\!visible{visibility:visible!important}.visible{visibility:visible}.invisible{visibility:hidden}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.bottom-0{bottom:0}.bottom-32{bottom:8rem}.bottom-4{bottom:1rem}.left-0{left:0}.right-3{right:.75rem}.right-4{right:1rem}.top-0{top:0}.top-2{top:.5rem}.top-4{top:1rem}.z-10{z-index:10}.-m-1{margin:-.25rem}.m-6{margin:1.5rem}.\!my-6{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-3{margin-left:.75rem;margin-right:.75rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0{margin-top:0;margin-bottom:0}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.\!mb-2{margin-bottom:.5rem!important}.mb-0{margin-bottom:0}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-8{margin-bottom:2rem}.ml-10{margin-left:2.5rem}.ml-2{margin-left:.5rem}.ml-4{margin-left:1rem}.ml-5{margin-left:1.25rem}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mr-4{margin-right:1rem}.mr-6{margin-right:1.5rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-8{margin-top:2rem}.line-clamp-1{-webkit-line-clamp:1}.line-clamp-1,.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical}.line-clamp-2{-webkit-line-clamp:2}.block{display:block}.inline-block{display:inline-block}.\!inline{display:inline!important}.inline{display:inline}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-2\/5{height:40%}.h-3\/5{height:60%}.h-32{height:8rem}.h-4{height:1rem}.h-40{height:10rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-96{height:24rem}.h-\[300px\]{height:300px}.h-\[46px\]{height:46px}.h-\[500px\]{height:500px}.h-full{height:100%}.h-screen{height:100vh}.max-h-96{max-height:24rem}.max-h-full{max-height:100%}.max-h-screen{max-height:100vh}.min-h-\[1rem\]{min-height:1rem}.min-h-full{min-height:100%}.w-11{width:2.75rem}.w-12{width:3rem}.w-20{width:5rem}.w-36{width:9rem}.w-48{width:12rem}.w-52{width:13rem}.w-60{width:15rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-\[63px\]{width:63px}.w-full{width:100%}.w-screen{width:100vw}.min-w-0{min-width:0}.min-w-\[200px\]{min-width:200px}.min-w-\[240px\]{min-width:240px}.min-w-min{min-width:-moz-min-content;min-width:min-content}.max-w-3xl{max-width:48rem}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow-0{flex-grow:0}.rotate-90{--tw-rotate:90deg}.rotate-90,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes fade{0%{opacity:0}to{opacity:1}}.animate-fade{animation:fade 1s both}.cursor-no-drop{cursor:no-drop}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-around{justify-content:space-around}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-y-5{row-gap:1.25rem}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overflow-y-scroll{overflow-y:scroll}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-\[10px\]{border-radius:10px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.rounded-br{border-bottom-right-radius:.25rem}.rounded-tl-md{border-top-left-radius:.375rem}.rounded-tr{border-top-right-radius:.25rem}.rounded-tr-md{border-top-right-radius:.375rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t,.border-t-\[1px\]{border-top-width:1px}.border-solid{border-style:solid}.border-dashed{border-style:dashed}.border-none{border-style:none}.border-\[\#f0f0f0\]{--tw-border-opacity:1;border-color:rgb(240 240 240/var(--tw-border-opacity))}.border-\[var\(--joy-palette-divider\)\]{border-color:var(--joy-palette-divider)}.border-blue-600{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity))}.border-gray-100{--tw-border-opacity:1;border-color:rgb(243 244 246/var(--tw-border-opacity))}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.border-slate-300{--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity))}.bg-\[\#E6F4FF\]{--tw-bg-opacity:1;background-color:rgb(230 244 255/var(--tw-bg-opacity))}.bg-\[\#FAFAFA\]{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity))}.bg-\[\#FFFFFF\]{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-\[\#fafafa\]{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.bg-gray-500{--tw-bg-opacity:1;background-color:rgb(107 114 128/var(--tw-bg-opacity))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity))}.bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.bg-green-500{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity))}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity))}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-slate-400{--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-opacity-50{--tw-bg-opacity:0.5}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-\[\#31afff\]{--tw-gradient-from:#31afff var(--tw-gradient-from-position);--tw-gradient-to:rgba(49,175,255,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.to-\[\#1677ff\]{--tw-gradient-to:#1677ff var(--tw-gradient-to-position)}.object-contain{-o-object-fit:contain;object-fit:contain}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-0{padding-left:0;padding-right:0}.px-12{padding-left:3rem;padding-right:3rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.px-\[6px\]{padding-left:6px;padding-right:6px}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-\[2px\]{padding-top:2px;padding-bottom:2px}.pb-4{padding-bottom:1rem}.pb-6{padding-bottom:1.5rem}.pb-8{padding-bottom:2rem}.pl-0{padding-left:0}.pl-0\.5{padding-left:.125rem}.pl-2{padding-left:.5rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.\!text-left{text-align:left!important}.\!text-2xl{font-size:1.5rem!important;line-height:2rem!important}.\!text-3xl{font-size:1.875rem!important;line-height:2.25rem!important}.\!text-lg{font-size:1.125rem!important;line-height:1.75rem!important}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-normal{font-weight:400}.font-semibold{font-weight:600}.leading-6{line-height:1.5rem}.leading-7{line-height:1.75rem}.leading-8{line-height:2rem}.\!text-\[\#878c93\]{--tw-text-opacity:1!important;color:rgb(135 140 147/var(--tw-text-opacity))!important}.\!text-green-600{--tw-text-opacity:1!important;color:rgb(22 163 74/var(--tw-text-opacity))!important}.\!text-orange-600{--tw-text-opacity:1!important;color:rgb(234 88 12/var(--tw-text-opacity))!important}.\!text-red-600{--tw-text-opacity:1!important;color:rgb(220 38 38/var(--tw-text-opacity))!important}.text-\[\#1677FE\]{--tw-text-opacity:1;color:rgb(22 119 254/var(--tw-text-opacity))}.text-\[\#1677ff\]{--tw-text-opacity:1;color:rgb(22 119 255/var(--tw-text-opacity))}.text-\[\#2AA3FF\]{--tw-text-opacity:1;color:rgb(42 163 255/var(--tw-text-opacity))}.text-\[\#ff1b2e\]{--tw-text-opacity:1;color:rgb(255 27 46/var(--tw-text-opacity))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.text-blue-400{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}.text-gray-100{--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity))}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}.text-slate-900{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.opacity-0{opacity:0}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.grayscale{--tw-grayscale:grayscale(100%)}.filter,.grayscale{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-\[width\]{transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.animate-duration-200{animation-duration:.2s}.animate-duration-300{animation-duration:.3s}body{margin:0;color:var(--joy-palette-text-primary,var(--joy-palette-neutral-800,#25252d));font-family:var(--joy-fontFamily-body,var(--joy-Josefin Sans,sans-serif));font-size:var(--joy-fontSize-md,1rem);line-height:var(--joy-lineHeight-md,1.5);background-color:var(--joy-palette-background-body)}body .ant-btn-primary{background-color:#1677ff}.ant-pagination .ant-pagination-next *,.ant-pagination .ant-pagination-prev *{color:#279bff!important}.ant-pagination .ant-pagination-item a{color:#b0b0bf}.ant-pagination .ant-pagination-item.ant-pagination-item-active{background-color:#279bff!important}.ant-pagination .ant-pagination-item.ant-pagination-item-active a{color:#fff!important}table tr td{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}::-webkit-scrollbar{display:none}::-webkit-scrollbar-track{background:#f1f1f1}::-webkit-scrollbar-thumb{background:#888}::-webkit-scrollbar-thumb:hover{background:#555}.dark :where(.css-dev-only-do-not-override-18iikkb).ant-tabs .ant-tabs-tab-btn{color:#fff}:where(.css-dev-only-do-not-override-18iikkb).ant-form-item .ant-form-item-label>label{height:36px}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:-top-8:after{content:var(--tw-content);top:-2rem}.after\:h-8:after{content:var(--tw-content);height:2rem}.after\:w-full:after{content:var(--tw-content);width:100%}.after\:bg-gradient-to-t:after{content:var(--tw-content);background-image:linear-gradient(to top,var(--tw-gradient-stops))}.after\:from-white:after{content:var(--tw-content);--tw-gradient-from:#fff var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.after\:to-transparent:after{content:var(--tw-content);--tw-gradient-to:transparent var(--tw-gradient-to-position)}.hover\:bg-slate-100:hover{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.hover\:\!text-gray-200:hover{--tw-text-opacity:1!important;color:rgb(229 231 235/var(--tw-text-opacity))!important}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.group\/item:hover .group-hover\/item\:opacity-100{opacity:1}:is(.dark .dark\:border-gray-600){--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity))}:is(.dark .dark\:border-gray-700){--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}:is(.dark .dark\:border-white){--tw-border-opacity:1;border-color:rgb(255 255 255/var(--tw-border-opacity))}:is(.dark .dark\:bg-\[\#1A1E26\]){--tw-bg-opacity:1;background-color:rgb(26 30 38/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#212121\]){--tw-bg-opacity:1;background-color:rgb(33 33 33/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#353539\]){--tw-bg-opacity:1;background-color:rgb(53 53 57/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#484848\]){--tw-bg-opacity:1;background-color:rgb(72 72 72/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#4E4F56\]){--tw-bg-opacity:1;background-color:rgb(78 79 86/var(--tw-bg-opacity))}:is(.dark .dark\:bg-black){--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-100){--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-900){--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}:is(.dark .dark\:bg-slate-800){--tw-bg-opacity:1;background-color:rgb(30 41 59/var(--tw-bg-opacity))}:is(.dark .dark\:bg-transparent){background-color:transparent}:is(.dark .dark\:bg-opacity-50){--tw-bg-opacity:0.5}:is(.dark .dark\:bg-gradient-to-r){background-image:linear-gradient(to right,var(--tw-gradient-stops))}:is(.dark .dark\:from-\[\#6a6a6a\]){--tw-gradient-from:#6a6a6a var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,42%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}:is(.dark .dark\:to-\[\#80868f\]){--tw-gradient-to:#80868f var(--tw-gradient-to-position)}:is(.dark .dark\:text-blue-400){--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-100){--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-200){--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-300){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-400){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-800){--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}:is(.dark .dark\:text-slate-300){--tw-text-opacity:1;color:rgb(203 213 225/var(--tw-text-opacity))}:is(.dark .dark\:text-white){--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}:is(.dark .dark\:after\:from-\[\#212121\]):after{content:var(--tw-content);--tw-gradient-from:#212121 var(--tw-gradient-from-position);--tw-gradient-to:rgba(33,33,33,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}:is(.dark .dark\:hover\:border-white:hover){--tw-border-opacity:1;border-color:rgb(255 255 255/var(--tw-border-opacity))}:is(.dark .dark\:hover\:bg-\[\#353539\]:hover){--tw-bg-opacity:1;background-color:rgb(53 53 57/var(--tw-bg-opacity))}@media not all and (min-width:768px){.max-md\:hidden{display:none}}@media (min-width:640px){.sm\:mr-4{margin-right:1rem}.sm\:inline-block{display:inline-block}.sm\:w-1\/2{width:50%}.sm\:w-60{width:15rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:py-4{padding-top:1rem;padding-bottom:1rem}.sm\:pb-10{padding-bottom:2.5rem}.sm\:pt-6{padding-top:1.5rem}.sm\:text-base{font-size:1rem;line-height:1.5rem}.sm\:leading-7{line-height:1.75rem}}@media (min-width:768px){.md\:-m-3{margin:-.75rem}.md\:block{display:block}.md\:w-1\/2{width:50%}.md\:gap-4{gap:1rem}.md\:p-3{padding:.75rem}.md\:p-6{padding:1.5rem}.md\:px-4{padding-left:1rem;padding-right:1rem}.md\:px-6{padding-left:1.5rem;padding-right:1.5rem}.md\:pt-10{padding-top:2.5rem}}@media (min-width:1024px){.lg\:w-1\/3{width:33.333333%}.lg\:w-72{width:18rem}.lg\:w-full{width:100%}.lg\:max-w-\[80\%\]{max-width:80%}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (min-width:1280px){.xl\:h-full{height:100%}.xl\:w-1\/4{width:25%}.xl\:w-3\/4{width:75%}.xl\:w-full{width:100%}.xl\:gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.xl\:border-l{border-left-width:1px}.xl\:border-t-0{border-top-width:0}.xl\:pl-4{padding-left:1rem}.xl\:pr-4{padding-right:1rem}}#nprogress{pointer-events:none}#nprogress .bar{background:var(--joy-palette-primary-500,#096bde);position:fixed;z-index:10031;top:0;left:0;width:100%;height:3px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px var(--joy-palette-primary-500,#096bde),0 0 5px var(--joy-palette-primary-500,#096bde);opacity:1;transform:rotate(3deg) translateY(-4px)} \ No newline at end of file diff --git a/pilot/server/static/agent/index.html b/pilot/server/static/agent/index.html index c2a4517ca..f404e1b83 100644 --- a/pilot/server/static/agent/index.html +++ b/pilot/server/static/agent/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/pilot/server/static/chat/[scene]/[id]/index.html b/pilot/server/static/chat/[scene]/[id]/index.html index e54d94c6f..225fbdada 100644 --- a/pilot/server/static/chat/[scene]/[id]/index.html +++ b/pilot/server/static/chat/[scene]/[id]/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/pilot/server/static/chat/index.html b/pilot/server/static/chat/index.html index b54d6a995..001194af6 100644 --- a/pilot/server/static/chat/index.html +++ b/pilot/server/static/chat/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/pilot/server/static/database/index.html b/pilot/server/static/database/index.html index b5a8b240b..e6572f6e8 100644 --- a/pilot/server/static/database/index.html +++ b/pilot/server/static/database/index.html @@ -1 +1 @@ -
MySQL

MySQL

Comming soon

Fast, reliable, scalable open-source relational database management system.

MSSQL

MSSQL

Comming soon

Powerful, scalable, secure relational database system by Microsoft.

DuckDB

DuckDB

Comming soon

In-memory analytical database with efficient query processing.

Sqlite

Sqlite

Comming soon

Lightweight embedded relational database with simplicity and portability.

ClickHouse

ClickHouse

Comming soon

Columnar database for high-performance analytics and real-time queries.

Oracle

Oracle

Comming soon

Robust, scalable, secure relational database widely used in enterprises.

Access

Access

Comming soon

Easy-to-use relational database for small-scale applications by Microsoft.

MongoDB

MongoDB

Comming soon

Flexible, scalable NoSQL document database for web and mobile apps.

DB2

DB2

Comming soon

Scalable, secure relational database system developed by IBM.

HBase

HBase

Comming soon

Distributed, scalable NoSQL database for large structured/semi-structured data.

Redis

Redis

Comming soon

Fast, versatile in-memory data structure store as cache, DB, or broker.

Cassandra

Cassandra

Comming soon

Scalable, fault-tolerant distributed NoSQL database for large data.

Couchbase

Couchbase

Comming soon

High-performance NoSQL document database with distributed architecture.

PostgreSQL

PostgreSQL

Comming soon

Powerful open-source relational database with extensibility and SQL standards.

Spark

Spark

Comming soon

Unified engine for large-scale data analytics.

\ No newline at end of file +
MySQL

MySQL

Fast, reliable, scalable open-source relational database management system.

MSSQL

MSSQL

Powerful, scalable, secure relational database system by Microsoft.

DuckDB

DuckDB

In-memory analytical database with efficient query processing.

Sqlite

Sqlite

Lightweight embedded relational database with simplicity and portability.

ClickHouse

ClickHouse

Columnar database for high-performance analytics and real-time queries.

Oracle

Oracle

Robust, scalable, secure relational database widely used in enterprises.

Access

Access

Easy-to-use relational database for small-scale applications by Microsoft.

MongoDB

MongoDB

Flexible, scalable NoSQL document database for web and mobile apps.

DB2

DB2

Scalable, secure relational database system developed by IBM.

HBase

HBase

Distributed, scalable NoSQL database for large structured/semi-structured data.

Redis

Redis

Fast, versatile in-memory data structure store as cache, DB, or broker.

Cassandra

Cassandra

Scalable, fault-tolerant distributed NoSQL database for large data.

Couchbase

Couchbase

High-performance NoSQL document database with distributed architecture.

PostgreSQL

PostgreSQL

Powerful open-source relational database with extensibility and SQL standards.

Spark

Spark

Unified engine for large-scale data analytics.

\ No newline at end of file diff --git a/pilot/server/static/index.html b/pilot/server/static/index.html index 7f9854512..b6bb6988c 100644 --- a/pilot/server/static/index.html +++ b/pilot/server/static/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/pilot/server/static/knowledge/chunk/index.html b/pilot/server/static/knowledge/chunk/index.html index d433f8455..54f5d89d1 100644 --- a/pilot/server/static/knowledge/chunk/index.html +++ b/pilot/server/static/knowledge/chunk/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/pilot/server/static/knowledge/index.html b/pilot/server/static/knowledge/index.html index 002abb7da..d6b7ff5e0 100644 --- a/pilot/server/static/knowledge/index.html +++ b/pilot/server/static/knowledge/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/pilot/server/static/models/index.html b/pilot/server/static/models/index.html index 976255961..4faeabdda 100644 --- a/pilot/server/static/models/index.html +++ b/pilot/server/static/models/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/pilot/server/static/prompt/index.html b/pilot/server/static/prompt/index.html index 399c4565c..f844c93a1 100644 --- a/pilot/server/static/prompt/index.html +++ b/pilot/server/static/prompt/index.html @@ -1 +1 @@ -
NameSceneSub SceneContentOperation
No data
\ No newline at end of file +
NameSceneSub SceneContentOperation
No data
\ No newline at end of file From 463b97fa1747b968c99b7341e6401109c0356b91 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Fri, 3 Nov 2023 18:04:36 +0800 Subject: [PATCH 43/57] doc:css --- docs/_static/css/examples.css | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/_static/css/examples.css b/docs/_static/css/examples.css index bb641d751..d1f416d15 100644 --- a/docs/_static/css/examples.css +++ b/docs/_static/css/examples.css @@ -1,8 +1,3 @@ -:root { - --ray-example-gallery-gap-x: 18px; - --ray-example-gallery-gap-y: 22px; - --sidebar-top: 5em; -} #site-navigation { width: 330px !important; From 76975d95accdeacf650396023f18729924d5c0de Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Sat, 4 Nov 2023 00:42:19 +0800 Subject: [PATCH 44/57] feat:knowledge refernce --- pilot/server/static/404.html | 2 +- pilot/server/static/404/index.html | 2 +- .../server/static/_next/static/chunks/604.3bbbeaa2c767e7dc.js | 1 - .../server/static/_next/static/chunks/604.8b28a3b59fbde616.js | 1 + .../{_app-41ccdddf1de778e7.js => _app-4f11192f855510e0.js} | 0 ...webpack-77553ab117b6c794.js => webpack-e014d2ade73ca4a8.js} | 2 +- pilot/server/static/_next/static/css/54555572d8a5a0b4.css | 3 +++ pilot/server/static/_next/static/css/d07b94ffd4f33c05.css | 3 --- .../_buildManifest.js | 0 .../_ssgManifest.js | 0 pilot/server/static/agent/index.html | 2 +- pilot/server/static/chat/[scene]/[id]/index.html | 2 +- pilot/server/static/chat/index.html | 2 +- pilot/server/static/database/index.html | 2 +- pilot/server/static/index.html | 2 +- pilot/server/static/knowledge/chunk/index.html | 2 +- pilot/server/static/knowledge/index.html | 2 +- pilot/server/static/models/index.html | 2 +- pilot/server/static/prompt/index.html | 2 +- 19 files changed, 16 insertions(+), 16 deletions(-) delete mode 100644 pilot/server/static/_next/static/chunks/604.3bbbeaa2c767e7dc.js create mode 100644 pilot/server/static/_next/static/chunks/604.8b28a3b59fbde616.js rename pilot/server/static/_next/static/chunks/pages/{_app-41ccdddf1de778e7.js => _app-4f11192f855510e0.js} (100%) rename pilot/server/static/_next/static/chunks/{webpack-77553ab117b6c794.js => webpack-e014d2ade73ca4a8.js} (62%) create mode 100644 pilot/server/static/_next/static/css/54555572d8a5a0b4.css delete mode 100644 pilot/server/static/_next/static/css/d07b94ffd4f33c05.css rename pilot/server/static/_next/static/{Kx09a-jiuL7Kdi7fpiNnT => jB-omw05-Lu2nmO_jWRqA}/_buildManifest.js (100%) rename pilot/server/static/_next/static/{Kx09a-jiuL7Kdi7fpiNnT => jB-omw05-Lu2nmO_jWRqA}/_ssgManifest.js (100%) diff --git a/pilot/server/static/404.html b/pilot/server/static/404.html index cb2ecf3aa..c7f7cd10a 100644 --- a/pilot/server/static/404.html +++ b/pilot/server/static/404.html @@ -1 +1 @@ -404: This page could not be found

404

This page could not be found.

\ No newline at end of file +404: This page could not be found

404

This page could not be found.

\ No newline at end of file diff --git a/pilot/server/static/404/index.html b/pilot/server/static/404/index.html index cb2ecf3aa..c7f7cd10a 100644 --- a/pilot/server/static/404/index.html +++ b/pilot/server/static/404/index.html @@ -1 +1 @@ -404: This page could not be found

404

This page could not be found.

\ No newline at end of file +404: This page could not be found

404

This page could not be found.

\ No newline at end of file diff --git a/pilot/server/static/_next/static/chunks/604.3bbbeaa2c767e7dc.js b/pilot/server/static/_next/static/chunks/604.3bbbeaa2c767e7dc.js deleted file mode 100644 index ec5108c66..000000000 --- a/pilot/server/static/_next/static/chunks/604.3bbbeaa2c767e7dc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[604],{24093:function(e,l,t){t.r(l),t.d(l,{default:function(){return ev}});var r=t(85893),a=t(67294),s=t(2093),n=t(1375),o=t(2453),i=t(58989),c=t(83454),d=e=>{let{queryAgentURL:l="/api/v1/chat/completions"}=e,t=(0,a.useMemo)(()=>new AbortController,[]),r=(0,a.useCallback)(async e=>{let{context:r,data:a,chatId:s,onMessage:d,onClose:u,onDone:x,onError:m}=e;if(!r){o.ZP.warning(i.Z.t("NoContextTip"));return}let h={...a,conv_uid:s,user_input:r};if(!h.conv_uid){o.ZP.error("conv_uid 不存在,请刷新后重试");return}try{var p;await (0,n.L)("".concat(null!==(p=c.env.API_BASE_URL)&&void 0!==p?p:"").concat(l),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(h),signal:t.signal,openWhenHidden:!0,async onopen(e){if(e.ok&&e.headers.get("content-type")===n.a)return},onclose(){t.abort(),null==u||u()},onerror(e){throw Error(e)},onmessage:e=>{var l;let t=null===(l=e.data)||void 0===l?void 0:l.replaceAll("\\n","\n");"[DONE]"===t?null==x||x():(null==t?void 0:t.startsWith("[ERROR]"))?null==m||m(null==t?void 0:t.replace("[ERROR]","")):null==d||d(t)}})}catch(e){t.abort(),null==m||m("Sorry, We meet some error, please try agin later.",e)}},[l]);return(0,a.useEffect)(()=>()=>{t.abort()},[]),r},u=t(39332),x=t(99513),m=t(24019),h=t(50888),p=t(97937),g=t(63606),v=t(50228),f=t(87547),b=t(89035),j=t(33035),y=t(12767),w=t(94184),Z=t.n(w),_=t(66309),N=t(81799),k=t(41468),C=t(57132),S=t(29158),P=t(98165),R=t(79166),E=t(93179),O=t(71577),D=t(38426),M=t(20640),I=t.n(M);let L={code(e){var l;let{inline:t,node:a,className:s,children:n,style:i,...c}=e,d=/language-(\w+)/.exec(s||"");return!t&&d?(0,r.jsxs)("div",{className:"relative",children:[(0,r.jsx)(O.ZP,{className:"absolute right-3 top-2 text-gray-300 hover:!text-gray-200 bg-gray-700",type:"text",icon:(0,r.jsx)(C.Z,{}),onClick:()=>{let e=I()(n);o.ZP[e?"success":"error"](e?"Copy success":"Copy failed")}}),(0,r.jsx)(E.Z,{language:null!==(l=null==d?void 0:d[1])&&void 0!==l?l:"javascript",style:R.Z,children:n})]}):(0,r.jsx)("code",{...c,style:i,className:"px-[6px] py-[2px] rounded bg-gray-700 text-gray-100 dark:bg-gray-100 dark:text-gray-800 text-sm",children:n})},ul(e){let{children:l}=e;return(0,r.jsx)("ul",{className:"py-1",children:l})},ol(e){let{children:l}=e;return(0,r.jsx)("ol",{className:"py-1",children:l})},li(e){let{children:l,ordered:t}=e;return(0,r.jsx)("li",{className:"text-sm leading-7 ml-5 pl-2 text-gray-600 dark:text-gray-300 ".concat(t?"list-decimal":"list-disc"),children:l})},table(e){let{children:l}=e;return(0,r.jsx)("table",{className:"my-2 rounded-tl-md rounded-tr-md max-w-full bg-white dark:bg-gray-900 text-sm rounded-lg overflow-hidden",children:l})},thead(e){let{children:l}=e;return(0,r.jsx)("thead",{className:"bg-[#fafafa] dark:bg-black font-semibold",children:l})},th(e){let{children:l}=e;return(0,r.jsx)("th",{className:"!text-left p-4",children:l})},td(e){let{children:l}=e;return(0,r.jsx)("td",{className:"p-4 border-t border-[#f0f0f0] dark:border-gray-700",children:l})},h1(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-2xl font-bold my-4 border-b border-slate-300 pb-4",children:l})},h2(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-xl font-bold my-3",children:l})},h3(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-lg font-semibold my-2",children:l})},h4(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-base font-semibold my-1",children:l})},a(e){let{children:l,href:t}=e;return(0,r.jsxs)("div",{className:"inline-block text-blue-600 dark:text-blue-400",children:[(0,r.jsx)(S.Z,{className:"mr-1"}),(0,r.jsx)("a",{href:t,target:"_blank",children:l})]})},img(e){let{src:l,alt:t}=e;return(0,r.jsx)("div",{children:(0,r.jsx)(D.Z,{className:"min-h-[1rem] max-w-full max-h-full border rounded",src:l,alt:t,placeholder:(0,r.jsx)(_.Z,{icon:(0,r.jsx)(P.Z,{spin:!0}),color:"processing",children:"Image Loading..."}),fallback:"/images/fallback.png"})})},blockquote(e){let{children:l}=e;return(0,r.jsx)("blockquote",{className:"py-4 px-6 border-l-4 border-blue-600 rounded bg-white my-2 text-gray-500 dark:bg-slate-800 dark:text-gray-200 dark:border-white shadow-sm",children:l})},references(e){let l,{children:t}=e;try{l=JSON.parse(t)}catch(e){return console.log(e),(0,r.jsx)("p",{className:"text-sm",children:"Render Reference Error!"})}let a=null==l?void 0:l.references;return!a||(null==a?void 0:a.length)<1?null:(0,r.jsxs)("div",{className:"border-t-[1px] border-gray-300 mt-3 py-2",children:[(0,r.jsxs)("p",{className:"text-sm text-gray-500 dark:text-gray-400 mb-2",children:[(0,r.jsx)(S.Z,{className:"mr-2"}),(0,r.jsx)("span",{className:"font-semibold",children:l.title})]}),a.map((e,l)=>{var t;return(0,r.jsxs)("p",{className:"text-sm text-blue-400 dark:text-blue-400 font-normal block ml-4",children:[(0,r.jsx)("span",{className:"mr-4",children:e.name}),null==e?void 0:null===(t=e.pages)||void 0===t?void 0:t.map((l,t)=>(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("span",{children:l},"file_page_".concat(t)),t<(null==e?void 0:e.pages.length)-1&&(0,r.jsx)("span",{children:","},"file_page__".concat(t))]}))]},"file_".concat(l))})]})}},A={todo:{bgClass:"bg-gray-500",icon:(0,r.jsx)(m.Z,{className:"ml-2"})},runing:{bgClass:"bg-blue-500",icon:(0,r.jsx)(h.Z,{className:"ml-2"})},failed:{bgClass:"bg-red-500",icon:(0,r.jsx)(p.Z,{className:"ml-2"})},completed:{bgClass:"bg-green-500",icon:(0,r.jsx)(g.Z,{className:"ml-2"})}};function F(e){return e.replaceAll("\\n","\n").replace(/]+)>/gi,"").replace(/]+)>/gi,"")}var T=(0,a.memo)(function(e){let{children:l,content:t,isChartChat:s,onLinkClick:n}=e,{scene:o}=(0,a.useContext)(k.p),{context:i,model_name:c,role:d}=t,u="view"===d,{relations:x,value:m,cachePlguinContext:h}=(0,a.useMemo)(()=>{if("string"!=typeof i)return{relations:[],value:"",cachePlguinContext:[]};let[e,l]=i.split(" relations:"),t=l?l.split(","):[],r=[],a=0,s=e.replace(/]*>[^<]*<\/dbgpt-view>/gi,e=>{try{var l;console.log(e);let t=e.replaceAll("\n","\\n").replace(/<[^>]*>|<\/[^>]*>/gm,""),s=JSON.parse(t),n="".concat(a,"");return r.push({...s,result:F(null!==(l=s.result)&&void 0!==l?l:"")}),a++,n}catch(l){return console.log(l.message,l),e}});return{relations:t,cachePlguinContext:r,value:s}},[i]),p=(0,a.useMemo)(()=>({"custom-view"(e){var l;let{children:t}=e,a=+t.toString();if(!h[a])return t;let{name:s,status:n,err_msg:o,result:i}=h[a],{bgClass:c,icon:d}=null!==(l=A[n])&&void 0!==l?l:{};return(0,r.jsxs)("div",{className:"bg-white dark:bg-[#212121] rounded-lg overflow-hidden my-2 flex flex-col lg:max-w-[80%]",children:[(0,r.jsxs)("div",{className:Z()("flex px-4 md:px-6 py-2 items-center text-white text-sm",c),children:[s,d]}),i?(0,r.jsx)("div",{className:"px-4 md:px-6 py-4 text-sm",children:(0,r.jsx)(j.D,{components:L,rehypePlugins:[y.Z],children:null!=i?i:""})}):(0,r.jsx)("div",{className:"px-4 md:px-6 py-4 text-sm",children:o})]})}}),[i,h]);return(0,r.jsxs)("div",{className:Z()("relative flex flex-wrap w-full px-2 sm:px-4 py-2 sm:py-4 rounded-xl break-words",{"bg-slate-100 dark:bg-[#353539]":u,"lg:w-full xl:w-full pl-0":["chat_with_db_execute","chat_dashboard"].includes(o)}),children:[(0,r.jsx)("div",{className:"mr-2 flex flex-shrink-0 items-center justify-center h-7 w-7 rounded-full text-lg sm:mr-4",children:u?(0,N.A)(c)||(0,r.jsx)(v.Z,{}):(0,r.jsx)(f.Z,{})}),(0,r.jsxs)("div",{className:"flex-1 overflow-hidden items-center text-md leading-8",children:[!u&&"string"==typeof i&&i,u&&s&&"object"==typeof i&&(0,r.jsxs)("div",{children:["[".concat(i.template_name,"]: "),(0,r.jsxs)("span",{className:"text-[#1677ff] cursor-pointer",onClick:n,children:[(0,r.jsx)(b.Z,{className:"mr-1"}),i.template_introduce||"More Details"]})]}),u&&"string"==typeof i&&(0,r.jsx)(j.D,{components:{...L,...p},rehypePlugins:[y.Z],children:F(m)}),!!(null==x?void 0:x.length)&&(0,r.jsx)("div",{className:"flex flex-wrap mt-2",children:null==x?void 0:x.map((e,l)=>(0,r.jsx)(_.Z,{color:"#108ee9",children:e},e+l))})]}),l]})}),H=t(59301),J=t(41132),V=t(74312),$=t(3414),q=t(72868),z=t(59562),W=t(14553),G=t(25359),B=t(7203),K=t(48665),Q=t(26047),U=t(99056),X=t(57814),Y=t(63955),ee=t(33028),el=t(40911),et=t(66478),er=t(83062),ea=t(50489),es=t(67421),en=e=>{var l;let{conv_index:t,question:s,knowledge_space:n}=e,{t:i}=(0,es.$G)(),{chatId:c}=(0,a.useContext)(k.p),[d,u]=(0,a.useState)(""),[x,m]=(0,a.useState)(4),[h,p]=(0,a.useState)(""),g=(0,a.useRef)(null),[v,f]=o.ZP.useMessage(),[b,j]=(0,a.useState)({});(0,a.useEffect)(()=>{(0,ea.Vx)((0,ea.Lu)()).then(e=>{var l;console.log(e),j(null!==(l=e[1])&&void 0!==l?l:{})}).catch(e=>{console.log(e)})},[]);let y=(0,a.useCallback)((e,l)=>{l?(0,ea.Vx)((0,ea.Eb)(c,t)).then(e=>{var l,t,r,a;let s=null!==(l=e[1])&&void 0!==l?l:{};u(null!==(t=s.ques_type)&&void 0!==t?t:""),m(parseInt(null!==(r=s.score)&&void 0!==r?r:"4")),p(null!==(a=s.messages)&&void 0!==a?a:"")}).catch(e=>{console.log(e)}):(u(""),m(4),p(""))},[c,t]),w=(0,V.Z)($.Z)(e=>{let{theme:l}=e;return{backgroundColor:"dark"===l.palette.mode?"#FBFCFD":"#0E0E10",...l.typography["body-sm"],padding:l.spacing(1),display:"flex",alignItems:"center",justifyContent:"center",borderRadius:4,width:"100%",height:"100%"}});return(0,r.jsxs)(q.L,{onOpenChange:y,children:[f,(0,r.jsx)(er.Z,{title:i("Rating"),children:(0,r.jsx)(z.Z,{slots:{root:W.ZP},slotProps:{root:{variant:"plain",color:"primary"}},sx:{borderRadius:40},children:(0,r.jsx)(H.Z,{})})}),(0,r.jsxs)(G.Z,{children:[(0,r.jsx)(B.Z,{disabled:!0,sx:{minHeight:0}}),(0,r.jsx)(K.Z,{sx:{width:"100%",maxWidth:350,display:"grid",gap:3,padding:1},children:(0,r.jsx)("form",{onSubmit:e=>{e.preventDefault();let l={conv_uid:c,conv_index:t,question:s,knowledge_space:n,score:x,ques_type:d,messages:h};console.log(l),(0,ea.Vx)((0,ea.VC)({data:l})).then(e=>{v.open({type:"success",content:"save success"})}).catch(e=>{v.open({type:"error",content:"save error"})})},children:(0,r.jsxs)(Q.Z,{container:!0,spacing:.5,columns:13,sx:{flexGrow:1},children:[(0,r.jsx)(Q.Z,{xs:3,children:(0,r.jsx)(w,{children:i("Q_A_Category")})}),(0,r.jsx)(Q.Z,{xs:10,children:(0,r.jsx)(U.Z,{action:g,value:d,placeholder:"Choose one…",onChange:(e,l)=>u(null!=l?l:""),...d&&{endDecorator:(0,r.jsx)(W.ZP,{size:"sm",variant:"plain",color:"neutral",onMouseDown:e=>{e.stopPropagation()},onClick:()=>{var e;u(""),null===(e=g.current)||void 0===e||e.focusVisible()},children:(0,r.jsx)(J.Z,{})}),indicator:null},sx:{width:"100%"},children:null===(l=Object.keys(b))||void 0===l?void 0:l.map(e=>(0,r.jsx)(X.Z,{value:e,children:b[e]},e))})}),(0,r.jsx)(Q.Z,{xs:3,children:(0,r.jsx)(w,{children:(0,r.jsx)(er.Z,{title:(0,r.jsx)(K.Z,{children:(0,r.jsx)("div",{children:i("feed_back_desc")})}),variant:"solid",placement:"left",children:i("Q_A_Rating")})})}),(0,r.jsx)(Q.Z,{xs:10,sx:{pl:0,ml:0},children:(0,r.jsx)(Y.Z,{"aria-label":"Custom",step:1,min:0,max:5,valueLabelFormat:function(e){return({0:i("Lowest"),1:i("Missed"),2:i("Lost"),3:i("Incorrect"),4:i("Verbose"),5:i("Best")})[e]},valueLabelDisplay:"on",marks:[{value:0,label:"0"},{value:1,label:"1"},{value:2,label:"2"},{value:3,label:"3"},{value:4,label:"4"},{value:5,label:"5"}],sx:{width:"90%",pt:3,m:2,ml:1},onChange:e=>{var l;return m(null===(l=e.target)||void 0===l?void 0:l.value)},value:x})}),(0,r.jsx)(Q.Z,{xs:13,children:(0,r.jsx)(ee.Z,{placeholder:i("Please_input_the_text"),value:h,onChange:e=>p(e.target.value),minRows:2,maxRows:4,endDecorator:(0,r.jsx)(el.ZP,{level:"body-xs",sx:{ml:"auto"},children:i("input_count")+h.length+i("input_unit")}),sx:{width:"100%",fontSize:14}})}),(0,r.jsx)(Q.Z,{xs:13,children:(0,r.jsx)(et.Z,{type:"submit",variant:"outlined",sx:{width:"100%",height:"100%"},children:i("submit")})})]})})})]})]})},eo=t(32983),ei=t(12069),ec=t(96486),ed=t.n(ec),eu=t(38954),ex=t(98399),em=e=>{var l;let{messages:t,onSubmit:n}=e,{dbParam:i,currentDialogue:c,scene:d,model:m,refreshDialogList:h,chatId:p,agentList:g}=(0,a.useContext)(k.p),{t:v}=(0,es.$G)(),f=(0,u.useSearchParams)(),b=null!==(l=f&&f.get("spaceNameOriginal"))&&void 0!==l?l:"",[j,y]=(0,a.useState)(!1),[w,_]=(0,a.useState)(!1),[S,P]=(0,a.useState)(t),[R,E]=(0,a.useState)(""),O=(0,a.useRef)(null),D=(0,a.useMemo)(()=>"chat_dashboard"===d,[d]),M=(0,a.useMemo)(()=>{switch(d){case"chat_agent":return g.join(",");case"chat_excel":return null==c?void 0:c.select_param;default:return b||i}},[d,g,c,i,b]),L=async e=>{if(!j&&e.trim())try{y(!0),await n(e,{select_param:null!=M?M:""})}finally{y(!1)}},A=e=>{try{return JSON.parse(e)}catch(l){return e}},[F,H]=o.ZP.useMessage(),J=async e=>{let l=null==e?void 0:e.replace(/\trelations:.*/g,""),t=I()(l);t?l?F.open({type:"success",content:v("Copy_success")}):F.open({type:"warning",content:v("Copy_nothing")}):F.open({type:"error",content:v("Copry_error")})};return(0,s.Z)(async()=>{let e=(0,ex.a_)();e&&e.id===p&&(await L(e.message),h(),localStorage.removeItem(ex.rU))},[p]),(0,a.useEffect)(()=>{let e=t;D&&(e=ed().cloneDeep(t).map(e=>((null==e?void 0:e.role)==="view"&&"string"==typeof(null==e?void 0:e.context)&&(e.context=A(null==e?void 0:e.context)),e))),P(e.filter(e=>["view","human"].includes(e.role)))},[D,t]),(0,a.useEffect)(()=>{setTimeout(()=>{var e;null===(e=O.current)||void 0===e||e.scrollTo(0,O.current.scrollHeight)},50)},[t]),(0,r.jsxs)(r.Fragment,{children:[H,(0,r.jsx)("div",{ref:O,className:"flex flex-1 overflow-y-auto pb-8 w-full flex-col",children:(0,r.jsx)("div",{className:"flex items-center flex-1 flex-col text-sm leading-6 text-slate-900 dark:text-slate-300 sm:text-base sm:leading-7",children:S.length?S.map((e,l)=>{var t;return(0,r.jsx)(T,{content:e,isChartChat:D,onLinkClick:()=>{_(!0),E(JSON.stringify(null==e?void 0:e.context,null,2))},children:"view"===e.role&&(0,r.jsxs)("div",{className:"flex w-full flex-row-reverse pt-2 border-t border-gray-200",children:[(0,r.jsx)(en,{conv_index:Math.ceil((l+1)/2),question:null===(t=null==S?void 0:S.filter(l=>(null==l?void 0:l.role)==="human"&&(null==l?void 0:l.order)===e.order)[0])||void 0===t?void 0:t.context,knowledge_space:b||i||""}),(0,r.jsx)(er.Z,{title:v("Copy"),children:(0,r.jsx)(et.Z,{onClick:()=>J(null==e?void 0:e.context),slots:{root:W.ZP},slotProps:{root:{variant:"plain",color:"primary"}},sx:{borderRadius:40},children:(0,r.jsx)(C.Z,{})})})]})},l)}):(0,r.jsx)(eo.Z,{image:"/empty.png",imageStyle:{width:320,height:320,margin:"0 auto",maxWidth:"100%",maxHeight:"100%"},className:"flex items-center justify-center flex-col h-full w-full",description:"Start a conversation"})})}),(0,r.jsx)("div",{className:Z()("relative after:absolute after:-top-8 after:h-8 after:w-full after:bg-gradient-to-t after:from-white after:to-transparent dark:after:from-[#212121]",{"cursor-not-allowed":"chat_excel"===d&&!(null==c?void 0:c.select_param)}),children:(0,r.jsxs)("div",{className:"flex flex-wrap w-full py-2 sm:pt-6 sm:pb-10",children:[m&&(0,r.jsx)("div",{className:"mr-2 flex items-center h-10",children:(0,N.A)(m)}),(0,r.jsx)(eu.Z,{loading:j,onSubmit:L})]})}),(0,r.jsx)(ei.default,{title:"JSON Editor",open:w,width:"60%",cancelButtonProps:{hidden:!0},onOk:()=>{_(!1)},onCancel:()=>{_(!1)},children:(0,r.jsx)(x.Z,{className:"w-full h-[500px]",language:"json",value:R})})]})},eh=t(70803),ep=t(39156),eg=t(45247),ev=()=>{var e;let l=(0,u.useSearchParams)(),{scene:t,chatId:n,model:o,setModel:i}=(0,a.useContext)(k.p),c=d({}),x=null!==(e=l&&l.get("initMessage"))&&void 0!==e?e:"",[m,h]=(0,a.useState)(!1),[p,g]=(0,a.useState)(),[v,f]=(0,a.useState)([]),b=async()=>{h(!0);let[,e]=await (0,ea.Vx)((0,ea.$i)(n));f(null!=e?e:[]),h(!1)},j=e=>{var l;let t=null===(l=e[e.length-1])||void 0===l?void 0:l.context;if(t)try{let e=JSON.parse(t);g((null==e?void 0:e.template_name)==="report"?null==e?void 0:e.charts:void 0)}catch(e){g(void 0)}};(0,s.Z)(async()=>{let e=(0,ex.a_)();e&&e.id===n||await b()},[x,n]),(0,a.useEffect)(()=>{var e,l;if(!v.length)return;let t=null===(e=null===(l=v.filter(e=>"view"===e.role))||void 0===l?void 0:l.slice(-1))||void 0===e?void 0:e[0];(null==t?void 0:t.model_name)&&i(t.model_name),j(v)},[v.length]);let y=(0,a.useCallback)((e,l)=>new Promise(r=>{let a=[...v,{role:"human",context:e,model_name:o,order:0,time_stamp:0},{role:"view",context:"",model_name:o,order:0,time_stamp:0}],s=a.length-1;f([...a]),c({context:e,data:{...l,chat_mode:t||"chat_normal",model_name:o},chatId:n,onMessage:e=>{a[s].context=e,f([...a])},onDone:()=>{j(a),r()},onClose:()=>{j(a),r()},onError:e=>{a[s].context=e,f([...a]),r()}})}),[v,c,o]);return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(eg.Z,{visible:m}),(0,r.jsx)(eh.Z,{refreshHistory:b,modelChange:e=>{i(e)}}),(0,r.jsxs)("div",{className:"px-4 flex flex-1 flex-wrap overflow-hidden relative",children:[!!(null==p?void 0:p.length)&&(0,r.jsx)("div",{className:"w-full xl:w-3/4 h-3/5 xl:pr-4 xl:h-full overflow-y-auto",children:(0,r.jsx)(ep.Z,{chartsData:p})}),!(null==p?void 0:p.length)&&"chat_dashboard"===t&&(0,r.jsx)(eo.Z,{image:"/empty.png",imageStyle:{width:320,height:320,margin:"0 auto",maxWidth:"100%",maxHeight:"100%"},className:"w-full xl:w-3/4 h-3/5 xl:h-full pt-0 md:pt-10"}),(0,r.jsx)("div",{className:Z()("flex flex-1 flex-col overflow-hidden",{"px-0 xl:pl-4 h-2/5 xl:h-full border-t xl:border-t-0 xl:border-l":"chat_dashboard"===t,"h-full lg:px-8":"chat_dashboard"!==t}),children:(0,r.jsx)(em,{messages:v,onSubmit:y})})]})]})}},38954:function(e,l,t){t.d(l,{Z:function(){return j}});var r=t(85893),a=t(27496),s=t(59566),n=t(71577),o=t(67294),i=t(2487),c=t(83062),d=t(2453),u=t(74627),x=t(39479),m=t(51009),h=t(58299),p=t(577),g=t(30119),v=t(67421);let f=e=>{let{data:l,loading:t,submit:a,close:s}=e,{t:n}=(0,v.$G)(),o=e=>()=>{a(e),s()};return(0,r.jsx)("div",{style:{maxHeight:400,overflow:"auto"},children:(0,r.jsx)(i.Z,{dataSource:null==l?void 0:l.data,loading:t,rowKey:e=>e.prompt_name,renderItem:e=>(0,r.jsx)(i.Z.Item,{onClick:o(e.content),children:(0,r.jsx)(c.Z,{title:e.content,children:(0,r.jsx)(i.Z.Item.Meta,{style:{cursor:"copy"},title:e.prompt_name,description:n("Prompt_Info_Scene")+":".concat(e.chat_scene,",")+n("Prompt_Info_Sub_Scene")+":".concat(e.sub_chat_scene)})})},e.prompt_name)})})};var b=e=>{let{submit:l}=e,{t}=(0,v.$G)(),[a,s]=(0,o.useState)(!1),[n,i]=(0,o.useState)("common"),{data:b,loading:j}=(0,p.Z)(()=>(0,g.PR)("/prompt/list",{prompt_type:n}),{refreshDeps:[n],onError:e=>{d.ZP.error(null==e?void 0:e.message)}});return(0,r.jsx)(u.Z,{title:(0,r.jsx)(x.Z.Item,{label:"Prompt "+t("Type"),children:(0,r.jsx)(m.default,{style:{width:130},value:n,onChange:e=>{i(e)},options:[{label:t("Public")+" Prompts",value:"common"},{label:t("Private")+" Prompts",value:"private"}]})}),content:(0,r.jsx)(f,{data:b,loading:j,submit:l,close:()=>{s(!1)}}),placement:"topRight",trigger:"click",open:a,onOpenChange:e=>{s(e)},children:(0,r.jsx)(c.Z,{title:t("Click_Select")+" Prompt",children:(0,r.jsx)(h.Z,{className:"bottom-32"})})})},j=function(e){let{children:l,loading:t,onSubmit:i,...c}=e,[d,u]=(0,o.useState)("");return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.default.TextArea,{className:"flex-1",size:"large",value:d,autoSize:{minRows:1,maxRows:4},...c,onPressEnter:e=>{if(d.trim()&&13===e.keyCode){if(e.shiftKey){u(e=>e+"\n");return}i(d),setTimeout(()=>{u("")},0)}},onChange:e=>{if("number"==typeof c.maxLength){u(e.target.value.substring(0,c.maxLength));return}u(e.target.value)}}),(0,r.jsx)(n.ZP,{className:"ml-2 flex items-center justify-center",size:"large",type:"text",loading:t,icon:(0,r.jsx)(a.Z,{}),onClick:()=>{i(d)}}),(0,r.jsx)(b,{submit:e=>{u(d+e)}}),l]})}},45247:function(e,l,t){var r=t(85893),a=t(50888);l.Z=function(e){let{visible:l}=e;return l?(0,r.jsx)("div",{className:"absolute w-full h-full top-0 left-0 flex justify-center items-center z-10 bg-white dark:bg-black bg-opacity-50 dark:bg-opacity-50 backdrop-blur-sm text-3xl animate-fade animate-duration-200",children:(0,r.jsx)(a.Z,{})}):null}}}]); \ No newline at end of file diff --git a/pilot/server/static/_next/static/chunks/604.8b28a3b59fbde616.js b/pilot/server/static/_next/static/chunks/604.8b28a3b59fbde616.js new file mode 100644 index 000000000..eeee04cbc --- /dev/null +++ b/pilot/server/static/_next/static/chunks/604.8b28a3b59fbde616.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[604],{24093:function(e,l,t){t.r(l),t.d(l,{default:function(){return ev}});var r=t(85893),a=t(67294),s=t(2093),n=t(1375),o=t(2453),i=t(58989),c=t(83454),d=e=>{let{queryAgentURL:l="/api/v1/chat/completions"}=e,t=(0,a.useMemo)(()=>new AbortController,[]),r=(0,a.useCallback)(async e=>{let{context:r,data:a,chatId:s,onMessage:d,onClose:u,onDone:x,onError:m}=e;if(!r){o.ZP.warning(i.Z.t("NoContextTip"));return}let h={...a,conv_uid:s,user_input:r};if(!h.conv_uid){o.ZP.error("conv_uid 不存在,请刷新后重试");return}try{var p;await (0,n.L)("".concat(null!==(p=c.env.API_BASE_URL)&&void 0!==p?p:"").concat(l),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(h),signal:t.signal,openWhenHidden:!0,async onopen(e){if(e.ok&&e.headers.get("content-type")===n.a)return},onclose(){t.abort(),null==u||u()},onerror(e){throw Error(e)},onmessage:e=>{var l;let t=null===(l=e.data)||void 0===l?void 0:l.replaceAll("\\n","\n");"[DONE]"===t?null==x||x():(null==t?void 0:t.startsWith("[ERROR]"))?null==m||m(null==t?void 0:t.replace("[ERROR]","")):null==d||d(t)}})}catch(e){t.abort(),null==m||m("Sorry, We meet some error, please try agin later.",e)}},[l]);return(0,a.useEffect)(()=>()=>{t.abort()},[]),r},u=t(39332),x=t(99513),m=t(24019),h=t(50888),p=t(97937),g=t(63606),v=t(50228),f=t(87547),j=t(89035),b=t(33035),y=t(12767),w=t(94184),Z=t.n(w),_=t(66309),N=t(81799),k=t(41468),C=t(57132),S=t(29158),P=t(98165),R=t(79166),E=t(93179),O=t(71577),D=t(38426),M=t(20640),I=t.n(M);let L={code(e){var l;let{inline:t,node:a,className:s,children:n,style:i,...c}=e,d=/language-(\w+)/.exec(s||"");return!t&&d?(0,r.jsxs)("div",{className:"relative",children:[(0,r.jsx)(O.ZP,{className:"absolute right-3 top-2 text-gray-300 hover:!text-gray-200 bg-gray-700",type:"text",icon:(0,r.jsx)(C.Z,{}),onClick:()=>{let e=I()(n);o.ZP[e?"success":"error"](e?"Copy success":"Copy failed")}}),(0,r.jsx)(E.Z,{language:null!==(l=null==d?void 0:d[1])&&void 0!==l?l:"javascript",style:R.Z,children:n})]}):(0,r.jsx)("code",{...c,style:i,className:"px-[6px] py-[2px] rounded bg-gray-700 text-gray-100 dark:bg-gray-100 dark:text-gray-800 text-sm",children:n})},ul(e){let{children:l}=e;return(0,r.jsx)("ul",{className:"py-1",children:l})},ol(e){let{children:l}=e;return(0,r.jsx)("ol",{className:"py-1",children:l})},li(e){let{children:l,ordered:t}=e;return(0,r.jsx)("li",{className:"text-sm leading-7 ml-5 pl-2 text-gray-600 dark:text-gray-300 ".concat(t?"list-decimal":"list-disc"),children:l})},table(e){let{children:l}=e;return(0,r.jsx)("table",{className:"my-2 rounded-tl-md rounded-tr-md max-w-full bg-white dark:bg-gray-900 text-sm rounded-lg overflow-hidden",children:l})},thead(e){let{children:l}=e;return(0,r.jsx)("thead",{className:"bg-[#fafafa] dark:bg-black font-semibold",children:l})},th(e){let{children:l}=e;return(0,r.jsx)("th",{className:"!text-left p-4",children:l})},td(e){let{children:l}=e;return(0,r.jsx)("td",{className:"p-4 border-t border-[#f0f0f0] dark:border-gray-700",children:l})},h1(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-2xl font-bold my-4 border-b border-slate-300 pb-4",children:l})},h2(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-xl font-bold my-3",children:l})},h3(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-lg font-semibold my-2",children:l})},h4(e){let{children:l}=e;return(0,r.jsx)("h3",{className:"text-base font-semibold my-1",children:l})},a(e){let{children:l,href:t}=e;return(0,r.jsxs)("div",{className:"inline-block text-blue-600 dark:text-blue-400",children:[(0,r.jsx)(S.Z,{className:"mr-1"}),(0,r.jsx)("a",{href:t,target:"_blank",children:l})]})},img(e){let{src:l,alt:t}=e;return(0,r.jsx)("div",{children:(0,r.jsx)(D.Z,{className:"min-h-[1rem] max-w-full max-h-full border rounded",src:l,alt:t,placeholder:(0,r.jsx)(_.Z,{icon:(0,r.jsx)(P.Z,{spin:!0}),color:"processing",children:"Image Loading..."}),fallback:"/images/fallback.png"})})},blockquote(e){let{children:l}=e;return(0,r.jsx)("blockquote",{className:"py-4 px-6 border-l-4 border-blue-600 rounded bg-white my-2 text-gray-500 dark:bg-slate-800 dark:text-gray-200 dark:border-white shadow-sm",children:l})},references(e){let l,{children:t}=e;try{l=JSON.parse(t)}catch(e){return console.log(e),(0,r.jsx)("p",{className:"text-sm",children:"Render Reference Error!"})}let a=null==l?void 0:l.references;return!a||(null==a?void 0:a.length)<1?null:(0,r.jsxs)("div",{className:"border-t-[1px] border-gray-300 mt-3 py-2",children:[(0,r.jsxs)("p",{className:"text-sm text-gray-500 dark:text-gray-400 mb-2",children:[(0,r.jsx)(S.Z,{className:"mr-2"}),(0,r.jsx)("span",{className:"font-semibold",children:l.title})]}),a.map((e,l)=>{var t;return(0,r.jsxs)("p",{className:"text-sm font-normal block ml-2 h-6 leading-6 overflow-hidden",children:[(0,r.jsxs)("span",{className:"inline-block w-6",children:["[",l+1,"]"]}),(0,r.jsx)("span",{className:"mr-4 text-blue-400",children:e.name}),null==e?void 0:null===(t=e.pages)||void 0===t?void 0:t.map((l,t)=>(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("span",{children:l},"file_page_".concat(t)),t<(null==e?void 0:e.pages.length)-1&&(0,r.jsx)("span",{children:","},"file_page__".concat(t))]}))]},"file_".concat(l))})]})}},A={todo:{bgClass:"bg-gray-500",icon:(0,r.jsx)(m.Z,{className:"ml-2"})},runing:{bgClass:"bg-blue-500",icon:(0,r.jsx)(h.Z,{className:"ml-2"})},failed:{bgClass:"bg-red-500",icon:(0,r.jsx)(p.Z,{className:"ml-2"})},completed:{bgClass:"bg-green-500",icon:(0,r.jsx)(g.Z,{className:"ml-2"})}};function F(e){return e.replaceAll("\\n","\n").replace(/]+)>/gi,"
").replace(/]+)>/gi,"")}var T=(0,a.memo)(function(e){let{children:l,content:t,isChartChat:s,onLinkClick:n}=e,{scene:o}=(0,a.useContext)(k.p),{context:i,model_name:c,role:d}=t,u="view"===d,{relations:x,value:m,cachePlguinContext:h}=(0,a.useMemo)(()=>{if("string"!=typeof i)return{relations:[],value:"",cachePlguinContext:[]};let[e,l]=i.split(" relations:"),t=l?l.split(","):[],r=[],a=0,s=e.replace(/]*>[^<]*<\/dbgpt-view>/gi,e=>{try{var l;console.log(e);let t=e.replaceAll("\n","\\n").replace(/<[^>]*>|<\/[^>]*>/gm,""),s=JSON.parse(t),n="".concat(a,"");return r.push({...s,result:F(null!==(l=s.result)&&void 0!==l?l:"")}),a++,n}catch(l){return console.log(l.message,l),e}});return{relations:t,cachePlguinContext:r,value:s}},[i]),p=(0,a.useMemo)(()=>({"custom-view"(e){var l;let{children:t}=e,a=+t.toString();if(!h[a])return t;let{name:s,status:n,err_msg:o,result:i}=h[a],{bgClass:c,icon:d}=null!==(l=A[n])&&void 0!==l?l:{};return(0,r.jsxs)("div",{className:"bg-white dark:bg-[#212121] rounded-lg overflow-hidden my-2 flex flex-col lg:max-w-[80%]",children:[(0,r.jsxs)("div",{className:Z()("flex px-4 md:px-6 py-2 items-center text-white text-sm",c),children:[s,d]}),i?(0,r.jsx)("div",{className:"px-4 md:px-6 py-4 text-sm",children:(0,r.jsx)(b.D,{components:L,rehypePlugins:[y.Z],children:null!=i?i:""})}):(0,r.jsx)("div",{className:"px-4 md:px-6 py-4 text-sm",children:o})]})}}),[i,h]);return(0,r.jsxs)("div",{className:Z()("relative flex flex-wrap w-full px-2 sm:px-4 py-2 sm:py-4 rounded-xl break-words",{"bg-slate-100 dark:bg-[#353539]":u,"lg:w-full xl:w-full pl-0":["chat_with_db_execute","chat_dashboard"].includes(o)}),children:[(0,r.jsx)("div",{className:"mr-2 flex flex-shrink-0 items-center justify-center h-7 w-7 rounded-full text-lg sm:mr-4",children:u?(0,N.A)(c)||(0,r.jsx)(v.Z,{}):(0,r.jsx)(f.Z,{})}),(0,r.jsxs)("div",{className:"flex-1 overflow-hidden items-center text-md leading-8",children:[!u&&"string"==typeof i&&i,u&&s&&"object"==typeof i&&(0,r.jsxs)("div",{children:["[".concat(i.template_name,"]: "),(0,r.jsxs)("span",{className:"text-[#1677ff] cursor-pointer",onClick:n,children:[(0,r.jsx)(j.Z,{className:"mr-1"}),i.template_introduce||"More Details"]})]}),u&&"string"==typeof i&&(0,r.jsx)(b.D,{components:{...L,...p},rehypePlugins:[y.Z],children:F(m)}),!!(null==x?void 0:x.length)&&(0,r.jsx)("div",{className:"flex flex-wrap mt-2",children:null==x?void 0:x.map((e,l)=>(0,r.jsx)(_.Z,{color:"#108ee9",children:e},e+l))})]}),l]})}),H=t(59301),J=t(41132),V=t(74312),$=t(3414),q=t(72868),z=t(59562),W=t(14553),G=t(25359),B=t(7203),K=t(48665),Q=t(26047),U=t(99056),X=t(57814),Y=t(63955),ee=t(33028),el=t(40911),et=t(66478),er=t(83062),ea=t(50489),es=t(67421),en=e=>{var l;let{conv_index:t,question:s,knowledge_space:n}=e,{t:i}=(0,es.$G)(),{chatId:c}=(0,a.useContext)(k.p),[d,u]=(0,a.useState)(""),[x,m]=(0,a.useState)(4),[h,p]=(0,a.useState)(""),g=(0,a.useRef)(null),[v,f]=o.ZP.useMessage(),[j,b]=(0,a.useState)({});(0,a.useEffect)(()=>{(0,ea.Vx)((0,ea.Lu)()).then(e=>{var l;console.log(e),b(null!==(l=e[1])&&void 0!==l?l:{})}).catch(e=>{console.log(e)})},[]);let y=(0,a.useCallback)((e,l)=>{l?(0,ea.Vx)((0,ea.Eb)(c,t)).then(e=>{var l,t,r,a;let s=null!==(l=e[1])&&void 0!==l?l:{};u(null!==(t=s.ques_type)&&void 0!==t?t:""),m(parseInt(null!==(r=s.score)&&void 0!==r?r:"4")),p(null!==(a=s.messages)&&void 0!==a?a:"")}).catch(e=>{console.log(e)}):(u(""),m(4),p(""))},[c,t]),w=(0,V.Z)($.Z)(e=>{let{theme:l}=e;return{backgroundColor:"dark"===l.palette.mode?"#FBFCFD":"#0E0E10",...l.typography["body-sm"],padding:l.spacing(1),display:"flex",alignItems:"center",justifyContent:"center",borderRadius:4,width:"100%",height:"100%"}});return(0,r.jsxs)(q.L,{onOpenChange:y,children:[f,(0,r.jsx)(er.Z,{title:i("Rating"),children:(0,r.jsx)(z.Z,{slots:{root:W.ZP},slotProps:{root:{variant:"plain",color:"primary"}},sx:{borderRadius:40},children:(0,r.jsx)(H.Z,{})})}),(0,r.jsxs)(G.Z,{children:[(0,r.jsx)(B.Z,{disabled:!0,sx:{minHeight:0}}),(0,r.jsx)(K.Z,{sx:{width:"100%",maxWidth:350,display:"grid",gap:3,padding:1},children:(0,r.jsx)("form",{onSubmit:e=>{e.preventDefault();let l={conv_uid:c,conv_index:t,question:s,knowledge_space:n,score:x,ques_type:d,messages:h};console.log(l),(0,ea.Vx)((0,ea.VC)({data:l})).then(e=>{v.open({type:"success",content:"save success"})}).catch(e=>{v.open({type:"error",content:"save error"})})},children:(0,r.jsxs)(Q.Z,{container:!0,spacing:.5,columns:13,sx:{flexGrow:1},children:[(0,r.jsx)(Q.Z,{xs:3,children:(0,r.jsx)(w,{children:i("Q_A_Category")})}),(0,r.jsx)(Q.Z,{xs:10,children:(0,r.jsx)(U.Z,{action:g,value:d,placeholder:"Choose one…",onChange:(e,l)=>u(null!=l?l:""),...d&&{endDecorator:(0,r.jsx)(W.ZP,{size:"sm",variant:"plain",color:"neutral",onMouseDown:e=>{e.stopPropagation()},onClick:()=>{var e;u(""),null===(e=g.current)||void 0===e||e.focusVisible()},children:(0,r.jsx)(J.Z,{})}),indicator:null},sx:{width:"100%"},children:null===(l=Object.keys(j))||void 0===l?void 0:l.map(e=>(0,r.jsx)(X.Z,{value:e,children:j[e]},e))})}),(0,r.jsx)(Q.Z,{xs:3,children:(0,r.jsx)(w,{children:(0,r.jsx)(er.Z,{title:(0,r.jsx)(K.Z,{children:(0,r.jsx)("div",{children:i("feed_back_desc")})}),variant:"solid",placement:"left",children:i("Q_A_Rating")})})}),(0,r.jsx)(Q.Z,{xs:10,sx:{pl:0,ml:0},children:(0,r.jsx)(Y.Z,{"aria-label":"Custom",step:1,min:0,max:5,valueLabelFormat:function(e){return({0:i("Lowest"),1:i("Missed"),2:i("Lost"),3:i("Incorrect"),4:i("Verbose"),5:i("Best")})[e]},valueLabelDisplay:"on",marks:[{value:0,label:"0"},{value:1,label:"1"},{value:2,label:"2"},{value:3,label:"3"},{value:4,label:"4"},{value:5,label:"5"}],sx:{width:"90%",pt:3,m:2,ml:1},onChange:e=>{var l;return m(null===(l=e.target)||void 0===l?void 0:l.value)},value:x})}),(0,r.jsx)(Q.Z,{xs:13,children:(0,r.jsx)(ee.Z,{placeholder:i("Please_input_the_text"),value:h,onChange:e=>p(e.target.value),minRows:2,maxRows:4,endDecorator:(0,r.jsx)(el.ZP,{level:"body-xs",sx:{ml:"auto"},children:i("input_count")+h.length+i("input_unit")}),sx:{width:"100%",fontSize:14}})}),(0,r.jsx)(Q.Z,{xs:13,children:(0,r.jsx)(et.Z,{type:"submit",variant:"outlined",sx:{width:"100%",height:"100%"},children:i("submit")})})]})})})]})]})},eo=t(32983),ei=t(12069),ec=t(96486),ed=t.n(ec),eu=t(38954),ex=t(98399),em=e=>{var l;let{messages:t,onSubmit:n}=e,{dbParam:i,currentDialogue:c,scene:d,model:m,refreshDialogList:h,chatId:p,agentList:g}=(0,a.useContext)(k.p),{t:v}=(0,es.$G)(),f=(0,u.useSearchParams)(),j=null!==(l=f&&f.get("spaceNameOriginal"))&&void 0!==l?l:"",[b,y]=(0,a.useState)(!1),[w,_]=(0,a.useState)(!1),[S,P]=(0,a.useState)(t),[R,E]=(0,a.useState)(""),O=(0,a.useRef)(null),D=(0,a.useMemo)(()=>"chat_dashboard"===d,[d]),M=(0,a.useMemo)(()=>{switch(d){case"chat_agent":return g.join(",");case"chat_excel":return null==c?void 0:c.select_param;default:return j||i}},[d,g,c,i,j]),L=async e=>{if(!b&&e.trim())try{y(!0),await n(e,{select_param:null!=M?M:""})}finally{y(!1)}},A=e=>{try{return JSON.parse(e)}catch(l){return e}},[F,H]=o.ZP.useMessage(),J=async e=>{let l=null==e?void 0:e.replace(/\trelations:.*/g,""),t=I()(l);t?l?F.open({type:"success",content:v("Copy_success")}):F.open({type:"warning",content:v("Copy_nothing")}):F.open({type:"error",content:v("Copry_error")})};return(0,s.Z)(async()=>{let e=(0,ex.a_)();e&&e.id===p&&(await L(e.message),h(),localStorage.removeItem(ex.rU))},[p]),(0,a.useEffect)(()=>{let e=t;D&&(e=ed().cloneDeep(t).map(e=>((null==e?void 0:e.role)==="view"&&"string"==typeof(null==e?void 0:e.context)&&(e.context=A(null==e?void 0:e.context)),e))),P(e.filter(e=>["view","human"].includes(e.role)))},[D,t]),(0,a.useEffect)(()=>{setTimeout(()=>{var e;null===(e=O.current)||void 0===e||e.scrollTo(0,O.current.scrollHeight)},50)},[t]),(0,r.jsxs)(r.Fragment,{children:[H,(0,r.jsx)("div",{ref:O,className:"flex flex-1 overflow-y-auto pb-8 w-full flex-col",children:(0,r.jsx)("div",{className:"flex items-center flex-1 flex-col text-sm leading-6 text-slate-900 dark:text-slate-300 sm:text-base sm:leading-7",children:S.length?S.map((e,l)=>{var t;return(0,r.jsx)(T,{content:e,isChartChat:D,onLinkClick:()=>{_(!0),E(JSON.stringify(null==e?void 0:e.context,null,2))},children:"view"===e.role&&(0,r.jsxs)("div",{className:"flex w-full flex-row-reverse pt-2 border-t border-gray-200",children:[(0,r.jsx)(en,{conv_index:Math.ceil((l+1)/2),question:null===(t=null==S?void 0:S.filter(l=>(null==l?void 0:l.role)==="human"&&(null==l?void 0:l.order)===e.order)[0])||void 0===t?void 0:t.context,knowledge_space:j||i||""}),(0,r.jsx)(er.Z,{title:v("Copy"),children:(0,r.jsx)(et.Z,{onClick:()=>J(null==e?void 0:e.context),slots:{root:W.ZP},slotProps:{root:{variant:"plain",color:"primary"}},sx:{borderRadius:40},children:(0,r.jsx)(C.Z,{})})})]})},l)}):(0,r.jsx)(eo.Z,{image:"/empty.png",imageStyle:{width:320,height:320,margin:"0 auto",maxWidth:"100%",maxHeight:"100%"},className:"flex items-center justify-center flex-col h-full w-full",description:"Start a conversation"})})}),(0,r.jsx)("div",{className:Z()("relative after:absolute after:-top-8 after:h-8 after:w-full after:bg-gradient-to-t after:from-white after:to-transparent dark:after:from-[#212121]",{"cursor-not-allowed":"chat_excel"===d&&!(null==c?void 0:c.select_param)}),children:(0,r.jsxs)("div",{className:"flex flex-wrap w-full py-2 sm:pt-6 sm:pb-10",children:[m&&(0,r.jsx)("div",{className:"mr-2 flex items-center h-10",children:(0,N.A)(m)}),(0,r.jsx)(eu.Z,{loading:b,onSubmit:L})]})}),(0,r.jsx)(ei.default,{title:"JSON Editor",open:w,width:"60%",cancelButtonProps:{hidden:!0},onOk:()=>{_(!1)},onCancel:()=>{_(!1)},children:(0,r.jsx)(x.Z,{className:"w-full h-[500px]",language:"json",value:R})})]})},eh=t(70803),ep=t(39156),eg=t(45247),ev=()=>{var e;let l=(0,u.useSearchParams)(),{scene:t,chatId:n,model:o,setModel:i}=(0,a.useContext)(k.p),c=d({}),x=null!==(e=l&&l.get("initMessage"))&&void 0!==e?e:"",[m,h]=(0,a.useState)(!1),[p,g]=(0,a.useState)(),[v,f]=(0,a.useState)([]),j=async()=>{h(!0);let[,e]=await (0,ea.Vx)((0,ea.$i)(n));f(null!=e?e:[]),h(!1)},b=e=>{var l;let t=null===(l=e[e.length-1])||void 0===l?void 0:l.context;if(t)try{let e=JSON.parse(t);g((null==e?void 0:e.template_name)==="report"?null==e?void 0:e.charts:void 0)}catch(e){g(void 0)}};(0,s.Z)(async()=>{let e=(0,ex.a_)();e&&e.id===n||await j()},[x,n]),(0,a.useEffect)(()=>{var e,l;if(!v.length)return;let t=null===(e=null===(l=v.filter(e=>"view"===e.role))||void 0===l?void 0:l.slice(-1))||void 0===e?void 0:e[0];(null==t?void 0:t.model_name)&&i(t.model_name),b(v)},[v.length]);let y=(0,a.useCallback)((e,l)=>new Promise(r=>{let a=[...v,{role:"human",context:e,model_name:o,order:0,time_stamp:0},{role:"view",context:"",model_name:o,order:0,time_stamp:0}],s=a.length-1;f([...a]),c({context:e,data:{...l,chat_mode:t||"chat_normal",model_name:o},chatId:n,onMessage:e=>{a[s].context=e,f([...a])},onDone:()=>{b(a),r()},onClose:()=>{b(a),r()},onError:e=>{a[s].context=e,f([...a]),r()}})}),[v,c,o]);return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(eg.Z,{visible:m}),(0,r.jsx)(eh.Z,{refreshHistory:j,modelChange:e=>{i(e)}}),(0,r.jsxs)("div",{className:"px-4 flex flex-1 flex-wrap overflow-hidden relative",children:[!!(null==p?void 0:p.length)&&(0,r.jsx)("div",{className:"w-full xl:w-3/4 h-3/5 xl:pr-4 xl:h-full overflow-y-auto",children:(0,r.jsx)(ep.Z,{chartsData:p})}),!(null==p?void 0:p.length)&&"chat_dashboard"===t&&(0,r.jsx)(eo.Z,{image:"/empty.png",imageStyle:{width:320,height:320,margin:"0 auto",maxWidth:"100%",maxHeight:"100%"},className:"w-full xl:w-3/4 h-3/5 xl:h-full pt-0 md:pt-10"}),(0,r.jsx)("div",{className:Z()("flex flex-1 flex-col overflow-hidden",{"px-0 xl:pl-4 h-2/5 xl:h-full border-t xl:border-t-0 xl:border-l":"chat_dashboard"===t,"h-full lg:px-8":"chat_dashboard"!==t}),children:(0,r.jsx)(em,{messages:v,onSubmit:y})})]})]})}},38954:function(e,l,t){t.d(l,{Z:function(){return b}});var r=t(85893),a=t(27496),s=t(59566),n=t(71577),o=t(67294),i=t(2487),c=t(83062),d=t(2453),u=t(74627),x=t(39479),m=t(51009),h=t(58299),p=t(577),g=t(30119),v=t(67421);let f=e=>{let{data:l,loading:t,submit:a,close:s}=e,{t:n}=(0,v.$G)(),o=e=>()=>{a(e),s()};return(0,r.jsx)("div",{style:{maxHeight:400,overflow:"auto"},children:(0,r.jsx)(i.Z,{dataSource:null==l?void 0:l.data,loading:t,rowKey:e=>e.prompt_name,renderItem:e=>(0,r.jsx)(i.Z.Item,{onClick:o(e.content),children:(0,r.jsx)(c.Z,{title:e.content,children:(0,r.jsx)(i.Z.Item.Meta,{style:{cursor:"copy"},title:e.prompt_name,description:n("Prompt_Info_Scene")+":".concat(e.chat_scene,",")+n("Prompt_Info_Sub_Scene")+":".concat(e.sub_chat_scene)})})},e.prompt_name)})})};var j=e=>{let{submit:l}=e,{t}=(0,v.$G)(),[a,s]=(0,o.useState)(!1),[n,i]=(0,o.useState)("common"),{data:j,loading:b}=(0,p.Z)(()=>(0,g.PR)("/prompt/list",{prompt_type:n}),{refreshDeps:[n],onError:e=>{d.ZP.error(null==e?void 0:e.message)}});return(0,r.jsx)(u.Z,{title:(0,r.jsx)(x.Z.Item,{label:"Prompt "+t("Type"),children:(0,r.jsx)(m.default,{style:{width:130},value:n,onChange:e=>{i(e)},options:[{label:t("Public")+" Prompts",value:"common"},{label:t("Private")+" Prompts",value:"private"}]})}),content:(0,r.jsx)(f,{data:j,loading:b,submit:l,close:()=>{s(!1)}}),placement:"topRight",trigger:"click",open:a,onOpenChange:e=>{s(e)},children:(0,r.jsx)(c.Z,{title:t("Click_Select")+" Prompt",children:(0,r.jsx)(h.Z,{className:"bottom-32"})})})},b=function(e){let{children:l,loading:t,onSubmit:i,...c}=e,[d,u]=(0,o.useState)("");return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.default.TextArea,{className:"flex-1",size:"large",value:d,autoSize:{minRows:1,maxRows:4},...c,onPressEnter:e=>{if(d.trim()&&13===e.keyCode){if(e.shiftKey){u(e=>e+"\n");return}i(d),setTimeout(()=>{u("")},0)}},onChange:e=>{if("number"==typeof c.maxLength){u(e.target.value.substring(0,c.maxLength));return}u(e.target.value)}}),(0,r.jsx)(n.ZP,{className:"ml-2 flex items-center justify-center",size:"large",type:"text",loading:t,icon:(0,r.jsx)(a.Z,{}),onClick:()=>{i(d)}}),(0,r.jsx)(j,{submit:e=>{u(d+e)}}),l]})}},45247:function(e,l,t){var r=t(85893),a=t(50888);l.Z=function(e){let{visible:l}=e;return l?(0,r.jsx)("div",{className:"absolute w-full h-full top-0 left-0 flex justify-center items-center z-10 bg-white dark:bg-black bg-opacity-50 dark:bg-opacity-50 backdrop-blur-sm text-3xl animate-fade animate-duration-200",children:(0,r.jsx)(a.Z,{})}):null}}}]); \ No newline at end of file diff --git a/pilot/server/static/_next/static/chunks/pages/_app-41ccdddf1de778e7.js b/pilot/server/static/_next/static/chunks/pages/_app-4f11192f855510e0.js similarity index 100% rename from pilot/server/static/_next/static/chunks/pages/_app-41ccdddf1de778e7.js rename to pilot/server/static/_next/static/chunks/pages/_app-4f11192f855510e0.js diff --git a/pilot/server/static/_next/static/chunks/webpack-77553ab117b6c794.js b/pilot/server/static/_next/static/chunks/webpack-e014d2ade73ca4a8.js similarity index 62% rename from pilot/server/static/_next/static/chunks/webpack-77553ab117b6c794.js rename to pilot/server/static/_next/static/chunks/webpack-e014d2ade73ca4a8.js index d917d76bf..a26a1a051 100644 --- a/pilot/server/static/_next/static/chunks/webpack-77553ab117b6c794.js +++ b/pilot/server/static/_next/static/chunks/webpack-e014d2ade73ca4a8.js @@ -1 +1 @@ -!function(){"use strict";var e,t,n,r,o,u,a,i,c,f,s,d,l={},b={};function p(e){var t=b[e];if(void 0!==t)return t.exports;var n=b[e]={id:e,loaded:!1,exports:{}},r=!0;try{l[e].call(n.exports,n,n.exports,p),r=!1}finally{r&&delete b[e]}return n.loaded=!0,n.exports}p.m=l,p.amdO={},e=[],p.O=function(t,n,r,o){if(n){o=o||0;for(var u=e.length;u>0&&e[u-1][2]>o;u--)e[u]=e[u-1];e[u]=[n,r,o];return}for(var a=1/0,u=0;u=o&&Object.keys(p.O).every(function(e){return p.O[e](n[c])})?n.splice(c--,1):(i=!1,o0&&e[u-1][2]>o;u--)e[u]=e[u-1];e[u]=[n,r,o];return}for(var c=1/0,u=0;u=o&&Object.keys(p.O).every(function(e){return p.O[e](n[a])})?n.splice(a--,1):(i=!1,o:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overflow-y-scroll{overflow-y:scroll}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-\[10px\]{border-radius:10px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.rounded-br{border-bottom-right-radius:.25rem}.rounded-tl-md{border-top-left-radius:.375rem}.rounded-tr{border-top-right-radius:.25rem}.rounded-tr-md{border-top-right-radius:.375rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t,.border-t-\[1px\]{border-top-width:1px}.border-solid{border-style:solid}.border-dashed{border-style:dashed}.border-none{border-style:none}.border-\[\#f0f0f0\]{--tw-border-opacity:1;border-color:rgb(240 240 240/var(--tw-border-opacity))}.border-\[var\(--joy-palette-divider\)\]{border-color:var(--joy-palette-divider)}.border-blue-600{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity))}.border-gray-100{--tw-border-opacity:1;border-color:rgb(243 244 246/var(--tw-border-opacity))}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.border-slate-300{--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity))}.bg-\[\#E6F4FF\]{--tw-bg-opacity:1;background-color:rgb(230 244 255/var(--tw-bg-opacity))}.bg-\[\#FAFAFA\]{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity))}.bg-\[\#FFFFFF\]{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-\[\#fafafa\]{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.bg-gray-500{--tw-bg-opacity:1;background-color:rgb(107 114 128/var(--tw-bg-opacity))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity))}.bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.bg-green-500{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity))}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity))}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-slate-400{--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-opacity-50{--tw-bg-opacity:0.5}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-\[\#31afff\]{--tw-gradient-from:#31afff var(--tw-gradient-from-position);--tw-gradient-to:rgba(49,175,255,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.to-\[\#1677ff\]{--tw-gradient-to:#1677ff var(--tw-gradient-to-position)}.object-contain{-o-object-fit:contain;object-fit:contain}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-0{padding-left:0;padding-right:0}.px-12{padding-left:3rem;padding-right:3rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.px-\[6px\]{padding-left:6px;padding-right:6px}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-\[2px\]{padding-top:2px;padding-bottom:2px}.pb-4{padding-bottom:1rem}.pb-6{padding-bottom:1.5rem}.pb-8{padding-bottom:2rem}.pl-0{padding-left:0}.pl-0\.5{padding-left:.125rem}.pl-2{padding-left:.5rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.\!text-left{text-align:left!important}.\!text-2xl{font-size:1.5rem!important;line-height:2rem!important}.\!text-3xl{font-size:1.875rem!important;line-height:2.25rem!important}.\!text-lg{font-size:1.125rem!important;line-height:1.75rem!important}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-normal{font-weight:400}.font-semibold{font-weight:600}.leading-6{line-height:1.5rem}.leading-7{line-height:1.75rem}.leading-8{line-height:2rem}.\!text-\[\#878c93\]{--tw-text-opacity:1!important;color:rgb(135 140 147/var(--tw-text-opacity))!important}.\!text-green-600{--tw-text-opacity:1!important;color:rgb(22 163 74/var(--tw-text-opacity))!important}.\!text-orange-600{--tw-text-opacity:1!important;color:rgb(234 88 12/var(--tw-text-opacity))!important}.\!text-red-600{--tw-text-opacity:1!important;color:rgb(220 38 38/var(--tw-text-opacity))!important}.text-\[\#1677FE\]{--tw-text-opacity:1;color:rgb(22 119 254/var(--tw-text-opacity))}.text-\[\#1677ff\]{--tw-text-opacity:1;color:rgb(22 119 255/var(--tw-text-opacity))}.text-\[\#2AA3FF\]{--tw-text-opacity:1;color:rgb(42 163 255/var(--tw-text-opacity))}.text-\[\#ff1b2e\]{--tw-text-opacity:1;color:rgb(255 27 46/var(--tw-text-opacity))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.text-blue-400{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}.text-gray-100{--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity))}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}.text-slate-900{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.opacity-0{opacity:0}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.grayscale{--tw-grayscale:grayscale(100%)}.filter,.grayscale{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-\[width\]{transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.animate-duration-200{animation-duration:.2s}.animate-duration-300{animation-duration:.3s}body{margin:0;color:var(--joy-palette-text-primary,var(--joy-palette-neutral-800,#25252d));font-family:var(--joy-fontFamily-body,var(--joy-Josefin Sans,sans-serif));font-size:var(--joy-fontSize-md,1rem);line-height:var(--joy-lineHeight-md,1.5);background-color:var(--joy-palette-background-body)}body .ant-btn-primary{background-color:#1677ff}.ant-pagination .ant-pagination-next *,.ant-pagination .ant-pagination-prev *{color:#279bff!important}.ant-pagination .ant-pagination-item a{color:#b0b0bf}.ant-pagination .ant-pagination-item.ant-pagination-item-active{background-color:#279bff!important}.ant-pagination .ant-pagination-item.ant-pagination-item-active a{color:#fff!important}table tr td{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}::-webkit-scrollbar{display:none}::-webkit-scrollbar-track{background:#f1f1f1}::-webkit-scrollbar-thumb{background:#888}::-webkit-scrollbar-thumb:hover{background:#555}.dark :where(.css-dev-only-do-not-override-18iikkb).ant-tabs .ant-tabs-tab-btn{color:#fff}:where(.css-dev-only-do-not-override-18iikkb).ant-form-item .ant-form-item-label>label{height:36px}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:-top-8:after{content:var(--tw-content);top:-2rem}.after\:h-8:after{content:var(--tw-content);height:2rem}.after\:w-full:after{content:var(--tw-content);width:100%}.after\:bg-gradient-to-t:after{content:var(--tw-content);background-image:linear-gradient(to top,var(--tw-gradient-stops))}.after\:from-white:after{content:var(--tw-content);--tw-gradient-from:#fff var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.after\:to-transparent:after{content:var(--tw-content);--tw-gradient-to:transparent var(--tw-gradient-to-position)}.hover\:bg-slate-100:hover{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.hover\:\!text-gray-200:hover{--tw-text-opacity:1!important;color:rgb(229 231 235/var(--tw-text-opacity))!important}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.group\/item:hover .group-hover\/item\:opacity-100{opacity:1}:is(.dark .dark\:border-gray-600){--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity))}:is(.dark .dark\:border-gray-700){--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}:is(.dark .dark\:border-white){--tw-border-opacity:1;border-color:rgb(255 255 255/var(--tw-border-opacity))}:is(.dark .dark\:bg-\[\#1A1E26\]){--tw-bg-opacity:1;background-color:rgb(26 30 38/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#212121\]){--tw-bg-opacity:1;background-color:rgb(33 33 33/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#353539\]){--tw-bg-opacity:1;background-color:rgb(53 53 57/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#484848\]){--tw-bg-opacity:1;background-color:rgb(72 72 72/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#4E4F56\]){--tw-bg-opacity:1;background-color:rgb(78 79 86/var(--tw-bg-opacity))}:is(.dark .dark\:bg-black){--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-100){--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-900){--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}:is(.dark .dark\:bg-slate-800){--tw-bg-opacity:1;background-color:rgb(30 41 59/var(--tw-bg-opacity))}:is(.dark .dark\:bg-transparent){background-color:transparent}:is(.dark .dark\:bg-opacity-50){--tw-bg-opacity:0.5}:is(.dark .dark\:bg-gradient-to-r){background-image:linear-gradient(to right,var(--tw-gradient-stops))}:is(.dark .dark\:from-\[\#6a6a6a\]){--tw-gradient-from:#6a6a6a var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,42%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}:is(.dark .dark\:to-\[\#80868f\]){--tw-gradient-to:#80868f var(--tw-gradient-to-position)}:is(.dark .dark\:text-blue-400){--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-100){--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-200){--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-300){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-400){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-800){--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}:is(.dark .dark\:text-slate-300){--tw-text-opacity:1;color:rgb(203 213 225/var(--tw-text-opacity))}:is(.dark .dark\:text-white){--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}:is(.dark .dark\:after\:from-\[\#212121\]):after{content:var(--tw-content);--tw-gradient-from:#212121 var(--tw-gradient-from-position);--tw-gradient-to:rgba(33,33,33,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}:is(.dark .dark\:hover\:border-white:hover){--tw-border-opacity:1;border-color:rgb(255 255 255/var(--tw-border-opacity))}:is(.dark .dark\:hover\:bg-\[\#353539\]:hover){--tw-bg-opacity:1;background-color:rgb(53 53 57/var(--tw-bg-opacity))}@media not all and (min-width:768px){.max-md\:hidden{display:none}}@media (min-width:640px){.sm\:mr-4{margin-right:1rem}.sm\:inline-block{display:inline-block}.sm\:w-1\/2{width:50%}.sm\:w-60{width:15rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:py-4{padding-top:1rem;padding-bottom:1rem}.sm\:pb-10{padding-bottom:2.5rem}.sm\:pt-6{padding-top:1.5rem}.sm\:text-base{font-size:1rem;line-height:1.5rem}.sm\:leading-7{line-height:1.75rem}}@media (min-width:768px){.md\:-m-3{margin:-.75rem}.md\:block{display:block}.md\:w-1\/2{width:50%}.md\:gap-4{gap:1rem}.md\:p-3{padding:.75rem}.md\:p-6{padding:1.5rem}.md\:px-4{padding-left:1rem;padding-right:1rem}.md\:px-6{padding-left:1.5rem;padding-right:1.5rem}.md\:pt-10{padding-top:2.5rem}}@media (min-width:1024px){.lg\:w-1\/3{width:33.333333%}.lg\:w-72{width:18rem}.lg\:w-full{width:100%}.lg\:max-w-\[80\%\]{max-width:80%}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (min-width:1280px){.xl\:h-full{height:100%}.xl\:w-1\/4{width:25%}.xl\:w-3\/4{width:75%}.xl\:w-full{width:100%}.xl\:gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.xl\:border-l{border-left-width:1px}.xl\:border-t-0{border-top-width:0}.xl\:pl-4{padding-left:1rem}.xl\:pr-4{padding-right:1rem}}#nprogress{pointer-events:none}#nprogress .bar{background:var(--joy-palette-primary-500,#096bde);position:fixed;z-index:10031;top:0;left:0;width:100%;height:3px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px var(--joy-palette-primary-500,#096bde),0 0 5px var(--joy-palette-primary-500,#096bde);opacity:1;transform:rotate(3deg) translateY(-4px)} \ No newline at end of file diff --git a/pilot/server/static/_next/static/css/d07b94ffd4f33c05.css b/pilot/server/static/_next/static/css/d07b94ffd4f33c05.css deleted file mode 100644 index ab5ef8da0..000000000 --- a/pilot/server/static/_next/static/css/d07b94ffd4f33c05.css +++ /dev/null @@ -1,3 +0,0 @@ -/* -! tailwindcss v3.3.2 | MIT License | https://tailwindcss.com -*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Josefin Sans,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.\!visible{visibility:visible!important}.visible{visibility:visible}.invisible{visibility:hidden}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.bottom-0{bottom:0}.bottom-32{bottom:8rem}.bottom-4{bottom:1rem}.left-0{left:0}.right-3{right:.75rem}.right-4{right:1rem}.top-0{top:0}.top-2{top:.5rem}.top-4{top:1rem}.z-10{z-index:10}.-m-1{margin:-.25rem}.m-6{margin:1.5rem}.\!my-6{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-3{margin-left:.75rem;margin-right:.75rem}.mx-4{margin-left:1rem;margin-right:1rem}.mx-6{margin-left:1.5rem;margin-right:1.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0{margin-top:0;margin-bottom:0}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.\!mb-2{margin-bottom:.5rem!important}.mb-0{margin-bottom:0}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.mb-8{margin-bottom:2rem}.ml-10{margin-left:2.5rem}.ml-2{margin-left:.5rem}.ml-4{margin-left:1rem}.ml-5{margin-left:1.25rem}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mr-4{margin-right:1rem}.mr-6{margin-right:1.5rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-8{margin-top:2rem}.line-clamp-1{-webkit-line-clamp:1}.line-clamp-1,.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical}.line-clamp-2{-webkit-line-clamp:2}.block{display:block}.inline-block{display:inline-block}.\!inline{display:inline!important}.inline{display:inline}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-2\/5{height:40%}.h-3\/5{height:60%}.h-32{height:8rem}.h-4{height:1rem}.h-40{height:10rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-96{height:24rem}.h-\[300px\]{height:300px}.h-\[46px\]{height:46px}.h-\[500px\]{height:500px}.h-full{height:100%}.h-screen{height:100vh}.max-h-96{max-height:24rem}.max-h-full{max-height:100%}.max-h-screen{max-height:100vh}.min-h-\[1rem\]{min-height:1rem}.min-h-full{min-height:100%}.w-11{width:2.75rem}.w-12{width:3rem}.w-20{width:5rem}.w-36{width:9rem}.w-48{width:12rem}.w-52{width:13rem}.w-60{width:15rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-72{width:18rem}.w-8{width:2rem}.w-\[63px\]{width:63px}.w-full{width:100%}.w-screen{width:100vw}.min-w-0{min-width:0}.min-w-\[200px\]{min-width:200px}.min-w-\[240px\]{min-width:240px}.min-w-min{min-width:-moz-min-content;min-width:min-content}.max-w-3xl{max-width:48rem}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow-0{flex-grow:0}.rotate-90{--tw-rotate:90deg}.rotate-90,.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes fade{0%{opacity:0}to{opacity:1}}.animate-fade{animation:fade 1s both}.cursor-no-drop{cursor:no-drop}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-around{justify-content:space-around}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-6{-moz-column-gap:1.5rem;column-gap:1.5rem}.gap-y-5{row-gap:1.25rem}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.overflow-y-scroll{overflow-y:scroll}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-\[10px\]{border-radius:10px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.rounded-br{border-bottom-right-radius:.25rem}.rounded-tl-md{border-top-left-radius:.375rem}.rounded-tr{border-top-right-radius:.25rem}.rounded-tr-md{border-top-right-radius:.375rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t,.border-t-\[1px\]{border-top-width:1px}.border-solid{border-style:solid}.border-dashed{border-style:dashed}.border-none{border-style:none}.border-\[\#f0f0f0\]{--tw-border-opacity:1;border-color:rgb(240 240 240/var(--tw-border-opacity))}.border-\[var\(--joy-palette-divider\)\]{border-color:var(--joy-palette-divider)}.border-blue-600{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity))}.border-gray-100{--tw-border-opacity:1;border-color:rgb(243 244 246/var(--tw-border-opacity))}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.border-slate-300{--tw-border-opacity:1;border-color:rgb(203 213 225/var(--tw-border-opacity))}.bg-\[\#E6F4FF\]{--tw-bg-opacity:1;background-color:rgb(230 244 255/var(--tw-bg-opacity))}.bg-\[\#FAFAFA\]{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity))}.bg-\[\#FFFFFF\]{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-\[\#fafafa\]{--tw-bg-opacity:1;background-color:rgb(250 250 250/var(--tw-bg-opacity))}.bg-blue-500{--tw-bg-opacity:1;background-color:rgb(59 130 246/var(--tw-bg-opacity))}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.bg-gray-500{--tw-bg-opacity:1;background-color:rgb(107 114 128/var(--tw-bg-opacity))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity))}.bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.bg-green-500{--tw-bg-opacity:1;background-color:rgb(34 197 94/var(--tw-bg-opacity))}.bg-red-500{--tw-bg-opacity:1;background-color:rgb(239 68 68/var(--tw-bg-opacity))}.bg-slate-100{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.bg-slate-400{--tw-bg-opacity:1;background-color:rgb(148 163 184/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-opacity-50{--tw-bg-opacity:0.5}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-\[\#31afff\]{--tw-gradient-from:#31afff var(--tw-gradient-from-position);--tw-gradient-to:rgba(49,175,255,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.to-\[\#1677ff\]{--tw-gradient-to:#1677ff var(--tw-gradient-to-position)}.object-contain{-o-object-fit:contain;object-fit:contain}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-0{padding-left:0;padding-right:0}.px-12{padding-left:3rem;padding-right:3rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.px-\[6px\]{padding-left:6px;padding-right:6px}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-\[2px\]{padding-top:2px;padding-bottom:2px}.pb-4{padding-bottom:1rem}.pb-6{padding-bottom:1.5rem}.pb-8{padding-bottom:2rem}.pl-0{padding-left:0}.pl-0\.5{padding-left:.125rem}.pl-2{padding-left:.5rem}.pt-0{padding-top:0}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.\!text-left{text-align:left!important}.\!text-2xl{font-size:1.5rem!important;line-height:2rem!important}.\!text-3xl{font-size:1.875rem!important;line-height:2.25rem!important}.\!text-lg{font-size:1.125rem!important;line-height:1.75rem!important}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-normal{font-weight:400}.font-semibold{font-weight:600}.leading-6{line-height:1.5rem}.leading-7{line-height:1.75rem}.leading-8{line-height:2rem}.\!text-\[\#878c93\]{--tw-text-opacity:1!important;color:rgb(135 140 147/var(--tw-text-opacity))!important}.\!text-green-600{--tw-text-opacity:1!important;color:rgb(22 163 74/var(--tw-text-opacity))!important}.\!text-orange-600{--tw-text-opacity:1!important;color:rgb(234 88 12/var(--tw-text-opacity))!important}.\!text-red-600{--tw-text-opacity:1!important;color:rgb(220 38 38/var(--tw-text-opacity))!important}.text-\[\#1677FE\]{--tw-text-opacity:1;color:rgb(22 119 254/var(--tw-text-opacity))}.text-\[\#1677ff\]{--tw-text-opacity:1;color:rgb(22 119 255/var(--tw-text-opacity))}.text-\[\#2AA3FF\]{--tw-text-opacity:1;color:rgb(42 163 255/var(--tw-text-opacity))}.text-\[\#ff1b2e\]{--tw-text-opacity:1;color:rgb(255 27 46/var(--tw-text-opacity))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.text-blue-400{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity))}.text-gray-100{--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity))}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}.text-slate-900{--tw-text-opacity:1;color:rgb(15 23 42/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.opacity-0{opacity:0}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.grayscale{--tw-grayscale:grayscale(100%)}.filter,.grayscale{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-\[width\]{transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.animate-duration-200{animation-duration:.2s}.animate-duration-300{animation-duration:.3s}body{margin:0;color:var(--joy-palette-text-primary,var(--joy-palette-neutral-800,#25252d));font-family:var(--joy-fontFamily-body,var(--joy-Josefin Sans,sans-serif));font-size:var(--joy-fontSize-md,1rem);line-height:var(--joy-lineHeight-md,1.5);background-color:var(--joy-palette-background-body)}body .ant-btn-primary{background-color:#1677ff}.ant-pagination .ant-pagination-next *,.ant-pagination .ant-pagination-prev *{color:#279bff!important}.ant-pagination .ant-pagination-item a{color:#b0b0bf}.ant-pagination .ant-pagination-item.ant-pagination-item-active{background-color:#279bff!important}.ant-pagination .ant-pagination-item.ant-pagination-item-active a{color:#fff!important}table tr td{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}::-webkit-scrollbar{display:none}::-webkit-scrollbar-track{background:#f1f1f1}::-webkit-scrollbar-thumb{background:#888}::-webkit-scrollbar-thumb:hover{background:#555}.dark :where(.css-dev-only-do-not-override-18iikkb).ant-tabs .ant-tabs-tab-btn{color:#fff}:where(.css-dev-only-do-not-override-18iikkb).ant-form-item .ant-form-item-label>label{height:36px}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:-top-8:after{content:var(--tw-content);top:-2rem}.after\:h-8:after{content:var(--tw-content);height:2rem}.after\:w-full:after{content:var(--tw-content);width:100%}.after\:bg-gradient-to-t:after{content:var(--tw-content);background-image:linear-gradient(to top,var(--tw-gradient-stops))}.after\:from-white:after{content:var(--tw-content);--tw-gradient-from:#fff var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,100%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.after\:to-transparent:after{content:var(--tw-content);--tw-gradient-to:transparent var(--tw-gradient-to-position)}.hover\:bg-slate-100:hover{--tw-bg-opacity:1;background-color:rgb(241 245 249/var(--tw-bg-opacity))}.hover\:\!text-gray-200:hover{--tw-text-opacity:1!important;color:rgb(229 231 235/var(--tw-text-opacity))!important}.hover\:shadow-md:hover{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.group\/item:hover .group-hover\/item\:opacity-100{opacity:1}:is(.dark .dark\:border-gray-600){--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity))}:is(.dark .dark\:border-gray-700){--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}:is(.dark .dark\:border-white){--tw-border-opacity:1;border-color:rgb(255 255 255/var(--tw-border-opacity))}:is(.dark .dark\:bg-\[\#1A1E26\]){--tw-bg-opacity:1;background-color:rgb(26 30 38/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#212121\]){--tw-bg-opacity:1;background-color:rgb(33 33 33/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#353539\]){--tw-bg-opacity:1;background-color:rgb(53 53 57/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#484848\]){--tw-bg-opacity:1;background-color:rgb(72 72 72/var(--tw-bg-opacity))}:is(.dark .dark\:bg-\[\#4E4F56\]){--tw-bg-opacity:1;background-color:rgb(78 79 86/var(--tw-bg-opacity))}:is(.dark .dark\:bg-black){--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-100){--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}:is(.dark .dark\:bg-gray-900){--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}:is(.dark .dark\:bg-slate-800){--tw-bg-opacity:1;background-color:rgb(30 41 59/var(--tw-bg-opacity))}:is(.dark .dark\:bg-transparent){background-color:transparent}:is(.dark .dark\:bg-opacity-50){--tw-bg-opacity:0.5}:is(.dark .dark\:bg-gradient-to-r){background-image:linear-gradient(to right,var(--tw-gradient-stops))}:is(.dark .dark\:from-\[\#6a6a6a\]){--tw-gradient-from:#6a6a6a var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,42%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}:is(.dark .dark\:to-\[\#80868f\]){--tw-gradient-to:#80868f var(--tw-gradient-to-position)}:is(.dark .dark\:text-blue-400){--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-100){--tw-text-opacity:1;color:rgb(243 244 246/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-200){--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-300){--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-400){--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}:is(.dark .dark\:text-gray-800){--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}:is(.dark .dark\:text-slate-300){--tw-text-opacity:1;color:rgb(203 213 225/var(--tw-text-opacity))}:is(.dark .dark\:text-white){--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}:is(.dark .dark\:after\:from-\[\#212121\]):after{content:var(--tw-content);--tw-gradient-from:#212121 var(--tw-gradient-from-position);--tw-gradient-to:rgba(33,33,33,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}:is(.dark .dark\:hover\:border-white:hover){--tw-border-opacity:1;border-color:rgb(255 255 255/var(--tw-border-opacity))}:is(.dark .dark\:hover\:bg-\[\#353539\]:hover){--tw-bg-opacity:1;background-color:rgb(53 53 57/var(--tw-bg-opacity))}@media not all and (min-width:768px){.max-md\:hidden{display:none}}@media (min-width:640px){.sm\:mr-4{margin-right:1rem}.sm\:inline-block{display:inline-block}.sm\:w-1\/2{width:50%}.sm\:w-60{width:15rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:px-4{padding-left:1rem;padding-right:1rem}.sm\:py-4{padding-top:1rem;padding-bottom:1rem}.sm\:pb-10{padding-bottom:2.5rem}.sm\:pt-6{padding-top:1.5rem}.sm\:text-base{font-size:1rem;line-height:1.5rem}.sm\:leading-7{line-height:1.75rem}}@media (min-width:768px){.md\:-m-3{margin:-.75rem}.md\:block{display:block}.md\:w-1\/2{width:50%}.md\:gap-4{gap:1rem}.md\:p-3{padding:.75rem}.md\:p-6{padding:1.5rem}.md\:px-4{padding-left:1rem;padding-right:1rem}.md\:px-6{padding-left:1.5rem;padding-right:1.5rem}.md\:pt-10{padding-top:2.5rem}}@media (min-width:1024px){.lg\:w-1\/3{width:33.333333%}.lg\:w-72{width:18rem}.lg\:w-full{width:100%}.lg\:max-w-\[80\%\]{max-width:80%}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (min-width:1280px){.xl\:h-full{height:100%}.xl\:w-1\/4{width:25%}.xl\:w-3\/4{width:75%}.xl\:w-full{width:100%}.xl\:gap-x-5{-moz-column-gap:1.25rem;column-gap:1.25rem}.xl\:border-l{border-left-width:1px}.xl\:border-t-0{border-top-width:0}.xl\:pl-4{padding-left:1rem}.xl\:pr-4{padding-right:1rem}}#nprogress{pointer-events:none}#nprogress .bar{background:var(--joy-palette-primary-500,#096bde);position:fixed;z-index:10031;top:0;left:0;width:100%;height:3px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px var(--joy-palette-primary-500,#096bde),0 0 5px var(--joy-palette-primary-500,#096bde);opacity:1;transform:rotate(3deg) translateY(-4px)} \ No newline at end of file diff --git a/pilot/server/static/_next/static/Kx09a-jiuL7Kdi7fpiNnT/_buildManifest.js b/pilot/server/static/_next/static/jB-omw05-Lu2nmO_jWRqA/_buildManifest.js similarity index 100% rename from pilot/server/static/_next/static/Kx09a-jiuL7Kdi7fpiNnT/_buildManifest.js rename to pilot/server/static/_next/static/jB-omw05-Lu2nmO_jWRqA/_buildManifest.js diff --git a/pilot/server/static/_next/static/Kx09a-jiuL7Kdi7fpiNnT/_ssgManifest.js b/pilot/server/static/_next/static/jB-omw05-Lu2nmO_jWRqA/_ssgManifest.js similarity index 100% rename from pilot/server/static/_next/static/Kx09a-jiuL7Kdi7fpiNnT/_ssgManifest.js rename to pilot/server/static/_next/static/jB-omw05-Lu2nmO_jWRqA/_ssgManifest.js diff --git a/pilot/server/static/agent/index.html b/pilot/server/static/agent/index.html index f404e1b83..554b3a8ed 100644 --- a/pilot/server/static/agent/index.html +++ b/pilot/server/static/agent/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/pilot/server/static/chat/[scene]/[id]/index.html b/pilot/server/static/chat/[scene]/[id]/index.html index 225fbdada..ba2239061 100644 --- a/pilot/server/static/chat/[scene]/[id]/index.html +++ b/pilot/server/static/chat/[scene]/[id]/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/pilot/server/static/chat/index.html b/pilot/server/static/chat/index.html index 001194af6..e252adfad 100644 --- a/pilot/server/static/chat/index.html +++ b/pilot/server/static/chat/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/pilot/server/static/database/index.html b/pilot/server/static/database/index.html index e6572f6e8..6bec61824 100644 --- a/pilot/server/static/database/index.html +++ b/pilot/server/static/database/index.html @@ -1 +1 @@ -
MySQL

MySQL

Fast, reliable, scalable open-source relational database management system.

MSSQL

MSSQL

Powerful, scalable, secure relational database system by Microsoft.

DuckDB

DuckDB

In-memory analytical database with efficient query processing.

Sqlite

Sqlite

Lightweight embedded relational database with simplicity and portability.

ClickHouse

ClickHouse

Columnar database for high-performance analytics and real-time queries.

Oracle

Oracle

Robust, scalable, secure relational database widely used in enterprises.

Access

Access

Easy-to-use relational database for small-scale applications by Microsoft.

MongoDB

MongoDB

Flexible, scalable NoSQL document database for web and mobile apps.

DB2

DB2

Scalable, secure relational database system developed by IBM.

HBase

HBase

Distributed, scalable NoSQL database for large structured/semi-structured data.

Redis

Redis

Fast, versatile in-memory data structure store as cache, DB, or broker.

Cassandra

Cassandra

Scalable, fault-tolerant distributed NoSQL database for large data.

Couchbase

Couchbase

High-performance NoSQL document database with distributed architecture.

PostgreSQL

PostgreSQL

Powerful open-source relational database with extensibility and SQL standards.

Spark

Spark

Unified engine for large-scale data analytics.

\ No newline at end of file +
MySQL

MySQL

Fast, reliable, scalable open-source relational database management system.

MSSQL

MSSQL

Powerful, scalable, secure relational database system by Microsoft.

DuckDB

DuckDB

In-memory analytical database with efficient query processing.

Sqlite

Sqlite

Lightweight embedded relational database with simplicity and portability.

ClickHouse

ClickHouse

Columnar database for high-performance analytics and real-time queries.

Oracle

Oracle

Robust, scalable, secure relational database widely used in enterprises.

Access

Access

Easy-to-use relational database for small-scale applications by Microsoft.

MongoDB

MongoDB

Flexible, scalable NoSQL document database for web and mobile apps.

DB2

DB2

Scalable, secure relational database system developed by IBM.

HBase

HBase

Distributed, scalable NoSQL database for large structured/semi-structured data.

Redis

Redis

Fast, versatile in-memory data structure store as cache, DB, or broker.

Cassandra

Cassandra

Scalable, fault-tolerant distributed NoSQL database for large data.

Couchbase

Couchbase

High-performance NoSQL document database with distributed architecture.

PostgreSQL

PostgreSQL

Powerful open-source relational database with extensibility and SQL standards.

Spark

Spark

Unified engine for large-scale data analytics.

\ No newline at end of file diff --git a/pilot/server/static/index.html b/pilot/server/static/index.html index b6bb6988c..853e854f0 100644 --- a/pilot/server/static/index.html +++ b/pilot/server/static/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/pilot/server/static/knowledge/chunk/index.html b/pilot/server/static/knowledge/chunk/index.html index 54f5d89d1..ef5e03325 100644 --- a/pilot/server/static/knowledge/chunk/index.html +++ b/pilot/server/static/knowledge/chunk/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/pilot/server/static/knowledge/index.html b/pilot/server/static/knowledge/index.html index d6b7ff5e0..6d7888a46 100644 --- a/pilot/server/static/knowledge/index.html +++ b/pilot/server/static/knowledge/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/pilot/server/static/models/index.html b/pilot/server/static/models/index.html index 4faeabdda..013ec1acd 100644 --- a/pilot/server/static/models/index.html +++ b/pilot/server/static/models/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/pilot/server/static/prompt/index.html b/pilot/server/static/prompt/index.html index f844c93a1..ffd05375a 100644 --- a/pilot/server/static/prompt/index.html +++ b/pilot/server/static/prompt/index.html @@ -1 +1 @@ -
NameSceneSub SceneContentOperation
No data
\ No newline at end of file +
NameSceneSub SceneContentOperation
No data
\ No newline at end of file From 23347d52a9217d1ea62211ea8a17c6887eb86ec6 Mon Sep 17 00:00:00 2001 From: FangYin Cheng Date: Fri, 3 Nov 2023 23:32:12 +0800 Subject: [PATCH 45/57] feat(core): More trace record for DB-GPT --- pilot/scene/base_chat.py | 60 +++++++++++++++++++++++++--- pilot/scene/chat_normal/chat.py | 2 + pilot/utils/tracer/__init__.py | 2 + pilot/utils/tracer/tracer_cli.py | 65 +++++++++++++++++-------------- pilot/utils/tracer/tracer_impl.py | 35 +++++++++++++++-- 5 files changed, 125 insertions(+), 39 deletions(-) diff --git a/pilot/scene/base_chat.py b/pilot/scene/base_chat.py index 34f294c31..294bd04ca 100644 --- a/pilot/scene/base_chat.py +++ b/pilot/scene/base_chat.py @@ -13,6 +13,7 @@ from pilot.scene.base_message import ModelMessage, ModelMessageRoleType from pilot.scene.message import OnceConversation from pilot.utils import get_or_create_event_loop from pilot.utils.executor_utils import ExecutorFactory, blocking_func_to_async +from pilot.utils.tracer import root_tracer, trace from pydantic import Extra from pilot.memory.chat_history.chat_hisotry_factory import ChatHistory @@ -38,6 +39,7 @@ class BaseChat(ABC): arbitrary_types_allowed = True + @trace("BaseChat.__init__") def __init__(self, chat_param: Dict): """Chat Module Initialization Args: @@ -175,6 +177,14 @@ class BaseChat(ABC): except StopAsyncIteration: return True # 迭代器已经执行结束 + def _get_span_metadata(self, payload: Dict) -> Dict: + metadata = {k: v for k, v in payload.items()} + del metadata["prompt"] + metadata["messages"] = list( + map(lambda m: m if isinstance(m, dict) else m.dict(), metadata["messages"]) + ) + return metadata + async def stream_call(self): # TODO Retry when server connection error payload = await self.__call_base() @@ -182,6 +192,10 @@ class BaseChat(ABC): self.skip_echo_len = len(payload.get("prompt").replace("", " ")) + 11 logger.info(f"Requert: \n{payload}") ai_response_text = "" + span = root_tracer.start_span( + "BaseChat.stream_call", metadata=self._get_span_metadata(payload) + ) + payload["span_id"] = span.span_id try: from pilot.model.cluster import WorkerManagerFactory @@ -199,6 +213,7 @@ class BaseChat(ABC): self.current_message.add_ai_message(msg) view_msg = self.knowledge_reference_call(msg) self.current_message.add_view_message(view_msg) + span.end() except Exception as e: print(traceback.format_exc()) logger.error("model response parase faild!" + str(e)) @@ -206,12 +221,17 @@ class BaseChat(ABC): f"""ERROR!{str(e)}\n {ai_response_text} """ ) ### store current conversation + span.end(metadata={"error": str(e)}) self.memory.append(self.current_message) async def nostream_call(self): payload = await self.__call_base() logger.info(f"Request: \n{payload}") ai_response_text = "" + span = root_tracer.start_span( + "BaseChat.nostream_call", metadata=self._get_span_metadata(payload) + ) + payload["span_id"] = span.span_id try: from pilot.model.cluster import WorkerManagerFactory @@ -219,7 +239,8 @@ class BaseChat(ABC): ComponentType.WORKER_MANAGER_FACTORY, WorkerManagerFactory ).create() - model_output = await worker_manager.generate(payload) + with root_tracer.start_span("BaseChat.invoke_worker_manager.generate"): + model_output = await worker_manager.generate(payload) ### output parse ai_response_text = ( @@ -234,11 +255,18 @@ class BaseChat(ABC): ai_response_text ) ) - ### run - # result = self.do_action(prompt_define_response) - result = await blocking_func_to_async( - self._executor, self.do_action, prompt_define_response - ) + metadata = { + "model_output": model_output.to_dict(), + "ai_response_text": ai_response_text, + "prompt_define_response": self._parse_prompt_define_response( + prompt_define_response + ), + } + with root_tracer.start_span("BaseChat.do_action", metadata=metadata): + ### run + result = await blocking_func_to_async( + self._executor, self.do_action, prompt_define_response + ) ### llm speaker speak_to_user = self.get_llm_speak(prompt_define_response) @@ -255,12 +283,14 @@ class BaseChat(ABC): view_message = view_message.replace("\n", "\\n") self.current_message.add_view_message(view_message) + span.end() except Exception as e: print(traceback.format_exc()) logger.error("model response parase faild!" + str(e)) self.current_message.add_view_message( f"""ERROR!{str(e)}\n {ai_response_text} """ ) + span.end(metadata={"error": str(e)}) ### store dialogue self.memory.append(self.current_message) return self.current_ai_response() @@ -513,3 +543,21 @@ class BaseChat(ABC): """ pass + + def _parse_prompt_define_response(self, prompt_define_response: Any) -> Any: + if not prompt_define_response: + return "" + if isinstance(prompt_define_response, str) or isinstance( + prompt_define_response, dict + ): + return prompt_define_response + if isinstance(prompt_define_response, tuple): + if hasattr(prompt_define_response, "_asdict"): + # namedtuple + return prompt_define_response._asdict() + else: + return dict( + zip(range(len(prompt_define_response)), prompt_define_response) + ) + else: + return prompt_define_response diff --git a/pilot/scene/chat_normal/chat.py b/pilot/scene/chat_normal/chat.py index 5999d5c3c..0191ef943 100644 --- a/pilot/scene/chat_normal/chat.py +++ b/pilot/scene/chat_normal/chat.py @@ -5,6 +5,7 @@ from pilot.scene.base import ChatScene from pilot.configs.config import Config from pilot.scene.chat_normal.prompt import prompt +from pilot.utils.tracer import root_tracer, trace CFG = Config() @@ -21,6 +22,7 @@ class ChatNormal(BaseChat): chat_param=chat_param, ) + @trace() async def generate_input_values(self) -> Dict: input_values = {"input": self.current_user_input} return input_values diff --git a/pilot/utils/tracer/__init__.py b/pilot/utils/tracer/__init__.py index 16509ff43..cdb536f79 100644 --- a/pilot/utils/tracer/__init__.py +++ b/pilot/utils/tracer/__init__.py @@ -10,6 +10,7 @@ from pilot.utils.tracer.base import ( from pilot.utils.tracer.span_storage import MemorySpanStorage, FileSpanStorage from pilot.utils.tracer.tracer_impl import ( root_tracer, + trace, initialize_tracer, DefaultTracer, TracerManager, @@ -26,6 +27,7 @@ __all__ = [ "MemorySpanStorage", "FileSpanStorage", "root_tracer", + "trace", "initialize_tracer", "DefaultTracer", "TracerManager", diff --git a/pilot/utils/tracer/tracer_cli.py b/pilot/utils/tracer/tracer_cli.py index 7df18f516..859fa4022 100644 --- a/pilot/utils/tracer/tracer_cli.py +++ b/pilot/utils/tracer/tracer_cli.py @@ -340,36 +340,43 @@ def chat( table.add_row(["echo", metadata.get("echo")]) elif "error" in metadata: table.add_row(["BaseChat Error", metadata.get("error")]) - if op == "BaseChat.nostream_call" and not sp["end_time"]: - if "model_output" in metadata: - table.add_row( - [ - "BaseChat model_output", - split_string_by_terminal_width( - metadata.get("model_output").get("text"), - split=split_long_text, - ), - ] - ) - if "ai_response_text" in metadata: - table.add_row( - [ - "BaseChat ai_response_text", - split_string_by_terminal_width( - metadata.get("ai_response_text"), split=split_long_text - ), - ] - ) - if "prompt_define_response" in metadata: - table.add_row( - [ - "BaseChat prompt_define_response", - split_string_by_terminal_width( - metadata.get("prompt_define_response"), - split=split_long_text, - ), - ] + if op == "BaseChat.do_action" and not sp["end_time"]: + if "model_output" in metadata: + table.add_row( + [ + "BaseChat model_output", + split_string_by_terminal_width( + metadata.get("model_output").get("text"), + split=split_long_text, + ), + ] + ) + if "ai_response_text" in metadata: + table.add_row( + [ + "BaseChat ai_response_text", + split_string_by_terminal_width( + metadata.get("ai_response_text"), split=split_long_text + ), + ] + ) + if "prompt_define_response" in metadata: + prompt_define_response = metadata.get("prompt_define_response") or "" + if isinstance(prompt_define_response, dict) or isinstance( + prompt_define_response, type([]) + ): + prompt_define_response = json.dumps( + prompt_define_response, ensure_ascii=False ) + table.add_row( + [ + "BaseChat prompt_define_response", + split_string_by_terminal_width( + prompt_define_response, + split=split_long_text, + ), + ] + ) if op == "DefaultModelWorker_call.generate_stream_func": if not sp["end_time"]: table.add_row(["llm_adapter", metadata.get("llm_adapter")]) diff --git a/pilot/utils/tracer/tracer_impl.py b/pilot/utils/tracer/tracer_impl.py index bda25ab4d..2358863bf 100644 --- a/pilot/utils/tracer/tracer_impl.py +++ b/pilot/utils/tracer/tracer_impl.py @@ -1,6 +1,9 @@ from typing import Dict, Optional from contextvars import ContextVar from functools import wraps +import asyncio +import inspect + from pilot.component import SystemApp, ComponentType from pilot.utils.tracer.base import ( @@ -154,18 +157,42 @@ class TracerManager: root_tracer: TracerManager = TracerManager() -def trace(operation_name: str, **trace_kwargs): +def trace(operation_name: Optional[str] = None, **trace_kwargs): def decorator(func): @wraps(func) - async def wrapper(*args, **kwargs): - with root_tracer.start_span(operation_name, **trace_kwargs): + def sync_wrapper(*args, **kwargs): + name = ( + operation_name if operation_name else _parse_operation_name(func, *args) + ) + with root_tracer.start_span(name, **trace_kwargs): + return func(*args, **kwargs) + + @wraps(func) + async def async_wrapper(*args, **kwargs): + name = ( + operation_name if operation_name else _parse_operation_name(func, *args) + ) + with root_tracer.start_span(name, **trace_kwargs): return await func(*args, **kwargs) - return wrapper + if asyncio.iscoroutinefunction(func): + return async_wrapper + else: + return sync_wrapper return decorator +def _parse_operation_name(func, *args): + self_name = None + if inspect.signature(func).parameters.get("self"): + self_name = args[0].__class__.__name__ + func_name = func.__name__ + if self_name: + return f"{self_name}.{func_name}" + return func_name + + def initialize_tracer( system_app: SystemApp, tracer_filename: str, From 8764d4e2e4191735fa2ec759ddf5d48de3dd1f73 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Sat, 4 Nov 2023 15:56:50 +0800 Subject: [PATCH 46/57] doc:llm rest api --- README.md | 4 +- README.zh.md | 6 +- docs/getting_started/install/deploy.rst | 2 + .../application/chatdb/chatdb.po | 92 ++++++----- .../application/chatexcel/chatexcel.po | 52 +++--- .../application/dashboard/dashboard.po | 68 ++++---- .../getting_started/install/deploy.po | 151 +++++++++--------- .../zh_CN/LC_MESSAGES/modules/plugins.po | 44 ++--- 8 files changed, 228 insertions(+), 191 deletions(-) diff --git a/README.md b/README.md index 3f1e8109f..61fdf994d 100644 --- a/README.md +++ b/README.md @@ -75,8 +75,8 @@ Run on an RTX 4090 GPU. ![Windows](https://img.shields.io/badge/Windows-0078D6?style=for-the-badge&logo=windows&logoColor=white) [**Usage Tutorial**](https://db-gpt.readthedocs.io/en/latest/getting_started/install/deploy/deploy.html) -- [**Install**](https://db-gpt.readthedocs.io/en/latest/getting_started/install/deploy/deploy.html) - - [**Install Step by Step**](https://db-gpt.readthedocs.io/en/latest/getting_started/install/deploy/deploy.html) +- [**Install**](https://db-gpt.readthedocs.io/en/latest/getting_started/install/deploy.html) + - [**Install Step by Step**](https://db-gpt.readthedocs.io/en/latest/getting_started/install/deploy.html) - [**Docker Install**](https://db-gpt.readthedocs.io/en/latest/getting_started/install/docker/docker.html) - [**Docker Compose**](https://db-gpt.readthedocs.io/en/latest/getting_started/install/docker_compose/docker_compose.html) - [**How to Use**](https://db-gpt.readthedocs.io/en/latest/getting_started/application/chatdb/chatdb.html) diff --git a/README.zh.md b/README.zh.md index dca465541..115427e9e 100644 --- a/README.zh.md +++ b/README.zh.md @@ -91,9 +91,9 @@ DB-GPT 是一个开源的以数据库为基础的GPT实验项目,使用本地 ![macOS](https://img.shields.io/badge/mac%20os-000000?style=for-the-badge&logo=macos&logoColor=F0F0F0) ![Windows](https://img.shields.io/badge/Windows-0078D6?style=for-the-badge&logo=windows&logoColor=white) -[**教程**](https://db-gpt.readthedocs.io/en/latest/getting_started/install/deploy/deploy.html) -- [**安装**](https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-cn/zh_CN/latest/getting_started/install/deploy/deploy.html) - - [**Install Step by Step**](https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-cn/zh_CN/latest/getting_started/install/deploy/deploy.html) +[**教程**](https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-cn/zh-cn/latest/getting_started/install/deploy.html) +- [**安装**](https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-cn/zh-cn/latest/getting_started/install/deploy.html) + - [**Install Step by Step**](https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-cn/zh-cn/latest/getting_started/install/deploy.html) - [**Docker安装**](https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-cn/zh_CN/latest/getting_started/install/docker/docker.html) - [**Docker Compose安装**](https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-cn/zh_CN/latest/getting_started/install/docker_compose/docker_compose.html) - [**产品使用手册**](https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-cn/zh_CN/latest/getting_started/application/chatdb/chatdb.html) diff --git a/docs/getting_started/install/deploy.rst b/docs/getting_started/install/deploy.rst index acb643d4a..4d7d0d211 100644 --- a/docs/getting_started/install/deploy.rst +++ b/docs/getting_started/install/deploy.rst @@ -216,6 +216,8 @@ If you are low hardware requirements you can install DB-GPT by Using third-part or git clone https://huggingface.co/moka-ai/m3e-large + Now DB-GPT support LLM REST API TYPE: + .. note:: * OpenAI diff --git a/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatdb/chatdb.po b/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatdb/chatdb.po index 5e8e7cd1c..d9fbb60a9 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatdb/chatdb.po +++ b/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatdb/chatdb.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 👏👏 0.3.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-03 15:25+0800\n" +"POT-Creation-Date: 2023-11-03 15:33+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -38,55 +38,67 @@ msgstr "" "plugins demonstration](../../../../assets/chat_data/chat_data.jpg)" #: ../../getting_started/application/chatdb/chatdb.md:3 -#: ../../getting_started/application/chatdb/chatdb.md:27 -#: ../../getting_started/application/chatdb/chatdb.md:31 -#: ../../getting_started/application/chatdb/chatdb.md:35 -#: ../../getting_started/application/chatdb/chatdb.md:50 -#: ../../getting_started/application/chatdb/chatdb.md:55 -#: ../../getting_started/application/chatdb/chatdb.md:61 +#: ../../getting_started/application/chatdb/chatdb.md:26 +#: ../../getting_started/application/chatdb/chatdb.md:30 +#: ../../getting_started/application/chatdb/chatdb.md:34 +#: ../../getting_started/application/chatdb/chatdb.md:49 +#: ../../getting_started/application/chatdb/chatdb.md:54 +#: ../../getting_started/application/chatdb/chatdb.md:60 #: 1467691a6012498795a94a14f7eba307 32315140835948c58e1721c7e2fa88a9 -#: 3b8e3c3396ff47348105a6dec9e755ba 6b116d2bac2d43faa4cbcbd0c4151344 -#: a314854e9be945dd88ad241bfa340870 d94d5f0e608f4399a0e10d593f0ab1da -#: e0ca6ec1841040bc828ce2ef29c387b6 +#: 3b8e3c3396ff47348105a6dec9e755ba a314854e9be945dd88ad241bfa340870 +#: d94d5f0e608f4399a0e10d593f0ab1da e0ca6ec1841040bc828ce2ef29c387b6 msgid "db plugins demonstration" msgstr "db plugins demonstration" -#: ../../getting_started/application/chatdb/chatdb.md:8 +#: ../../getting_started/application/chatdb/chatdb.md:7 #: 67cb0954cfa54e629b75cf9a241f6b9d -msgid "" -"The LLM (Language Model) suitable for the ChatData scene is * " -"chatgpt3.5. * chatgpt4. * Vicuna-v1.5." -msgstr "ChatData场景适用的LLM * " -"chatgpt3.5. * chatgpt4. * Vicuna-v1.5." +#, fuzzy +msgid "The LLM (Language Model) suitable for the ChatData scene is" +msgstr "ChatData场景适用的LLM * chatgpt3.5. * chatgpt4. * Vicuna-v1.5." -#: ../../getting_started/application/chatdb/chatdb.md:14 +#: ../../getting_started/application/chatdb/chatdb.md:8 +#: c973e19574e2405a96eb003c64063bfc +msgid "chatgpt3.5." +msgstr "" + +#: ../../getting_started/application/chatdb/chatdb.md:9 +#: 649b2382378c416591db7038a269c33b +msgid "chatgpt4." +msgstr "" + +#: ../../getting_started/application/chatdb/chatdb.md:10 +#: fac49de88fe3409f818193b953714cb9 +msgid "Vicuna-v1.5." +msgstr "" + +#: ../../getting_started/application/chatdb/chatdb.md:13 #: 8bd004993a834b0797ebcb5b6a6b1a23 msgid "1.Choose Datasource" msgstr "1.Choose Datasource" -#: ../../getting_started/application/chatdb/chatdb.md:16 +#: ../../getting_started/application/chatdb/chatdb.md:15 #: 34abfdced7804b51a212c0e567ffda6b msgid "" "If you are using DB-GPT for the first time, you need to add a data source" " and set the relevant connection information for the data source." msgstr "如果你是第一次使用DB-GPT, 首先需要添加数据源,设置数据源的相关连接信息" -#: ../../getting_started/application/chatdb/chatdb.md:20 +#: ../../getting_started/application/chatdb/chatdb.md:19 #: 3a8d16a8a32c4ac5affbd8093677b4f8 msgid "there are some example data in DB-GPT-NEW/DB-GPT/docker/examples" msgstr "在DB-GPT-NEW/DB-GPT/docker/examples有数据示例" -#: ../../getting_started/application/chatdb/chatdb.md:22 +#: ../../getting_started/application/chatdb/chatdb.md:21 #: 2c3333a2705648148f79623c220d90cd msgid "you can execute sql script to generate data." msgstr "你可以通过执行sql脚本生成测试数据" -#: ../../getting_started/application/chatdb/chatdb.md:25 +#: ../../getting_started/application/chatdb/chatdb.md:24 #: 4994182137574d14a3eefb421ceccd8e msgid "1.1 Datasource management" msgstr "1.1 Datasource management" -#: ../../getting_started/application/chatdb/chatdb.md:27 +#: ../../getting_started/application/chatdb/chatdb.md:26 #: 94680e1487d84092abc51a7da9bf1075 msgid "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" @@ -95,12 +107,12 @@ msgstr "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/7678f07e-9eee-40a9-b980-5b3978a0ed52)" -#: ../../getting_started/application/chatdb/chatdb.md:29 +#: ../../getting_started/application/chatdb/chatdb.md:28 #: 236dbd6d6cb4467593bf30597ecb215c msgid "1.2 Connection management" msgstr "1.2 Connection管理" -#: ../../getting_started/application/chatdb/chatdb.md:31 +#: ../../getting_started/application/chatdb/chatdb.md:30 #: 6611193e600c4452ac8a9769c6230590 msgid "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" @@ -109,12 +121,12 @@ msgstr "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/25b8f5a9-d322-459e-a8b2-bfe8cb42bdd6)" -#: ../../getting_started/application/chatdb/chatdb.md:33 +#: ../../getting_started/application/chatdb/chatdb.md:32 #: 7cceb9703af54970bee4a50fb07d4509 msgid "1.3 Add Datasource" msgstr "1.3 添加Datasource" -#: ../../getting_started/application/chatdb/chatdb.md:35 +#: ../../getting_started/application/chatdb/chatdb.md:34 #: 83c9e18cb87b4f0d9b0ce5e68b7fea77 msgid "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" @@ -123,53 +135,53 @@ msgstr "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/19ce31a7-4061-4da8-a9cb-efca396cc085)" -#: ../../getting_started/application/chatdb/chatdb.md:38 +#: ../../getting_started/application/chatdb/chatdb.md:37 #: 143fb04274cd486687c5766179f6103e msgid "now DB-GPT support Datasource Type" msgstr "DB-GPT支持数据源类型" -#: ../../getting_started/application/chatdb/chatdb.md:40 +#: ../../getting_started/application/chatdb/chatdb.md:39 #: 8bcf83e66b2d4d858407fc2b21b8fe85 msgid "Mysql" msgstr "Mysql" -#: ../../getting_started/application/chatdb/chatdb.md:41 +#: ../../getting_started/application/chatdb/chatdb.md:40 #: cd74abd5d6f4410ca001a3de2685e768 msgid "Sqlite" msgstr "Sqlite" -#: ../../getting_started/application/chatdb/chatdb.md:42 +#: ../../getting_started/application/chatdb/chatdb.md:41 #: fc5e01baba43449f8c3eb9b4b36a0ed8 msgid "DuckDB" msgstr "DuckDB" -#: ../../getting_started/application/chatdb/chatdb.md:43 +#: ../../getting_started/application/chatdb/chatdb.md:42 #: 10b6fe2153cd4ceba949687a54c3a68c msgid "Clickhouse" msgstr "Clickhouse" -#: ../../getting_started/application/chatdb/chatdb.md:44 +#: ../../getting_started/application/chatdb/chatdb.md:43 #: 9ce0a41784f041d39138a81099c386e9 #, fuzzy msgid "Mssql" msgstr "Mysql" -#: ../../getting_started/application/chatdb/chatdb.md:45 +#: ../../getting_started/application/chatdb/chatdb.md:44 #: 4af6eb835e954e0d937e98b308fb512b msgid "Spark" msgstr "Spark" -#: ../../getting_started/application/chatdb/chatdb.md:48 +#: ../../getting_started/application/chatdb/chatdb.md:47 #: 8aaa3a73090b4805b2dddf1cc355d83c msgid "2.ChatData" msgstr "2.ChatData" -#: ../../getting_started/application/chatdb/chatdb.md:49 +#: ../../getting_started/application/chatdb/chatdb.md:48 #: a34c79c99bd34233ae92d3090ff0b877 msgid "Preview Mode" msgstr "Preview Mode" -#: ../../getting_started/application/chatdb/chatdb.md:50 +#: ../../getting_started/application/chatdb/chatdb.md:49 #: 39e31a2a01494d4191d415a2240e026d #, fuzzy msgid "" @@ -182,12 +194,12 @@ msgstr "" "设置数据源成功后就可以和数据库进行对话了。你可以让它帮你生成SQL,也可以和问它数据库元数据的相关信息。 ![db plugins " "demonstration](../../../../assets/chat_data/chatdata_eg.png)" -#: ../../getting_started/application/chatdb/chatdb.md:54 +#: ../../getting_started/application/chatdb/chatdb.md:53 #: 999c78e8b604493a8190b0e1258d0da4 msgid "Editor Mode" msgstr "Editor Mode" -#: ../../getting_started/application/chatdb/chatdb.md:55 +#: ../../getting_started/application/chatdb/chatdb.md:54 #: e4a61d1e62c743f8b13dbed92ec265ba msgid "" "In Editor Mode, you can edit your sql and execute it. ![db plugins " @@ -198,12 +210,12 @@ msgstr "" "/eosphoros-ai/DB-" "GPT/assets/13723926/1a896dc1-7c0e-4354-8629-30357ffd8d7f)" -#: ../../getting_started/application/chatdb/chatdb.md:59 +#: ../../getting_started/application/chatdb/chatdb.md:58 #: b3a0d94083524d249f97dd426e1e1f26 msgid "3.ChatDB" msgstr "3.ChatDB" -#: ../../getting_started/application/chatdb/chatdb.md:61 +#: ../../getting_started/application/chatdb/chatdb.md:60 #: 8f4bd453447f48019a597eb3e4a59875 msgid "" "![db plugins demonstration](https://github.com/eosphoros-ai/DB-" diff --git a/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatexcel/chatexcel.po b/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatexcel/chatexcel.po index 35e8fc9ef..08f842573 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatexcel/chatexcel.po +++ b/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/chatexcel/chatexcel.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 👏👏 0.3.6\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-03 15:25+0800\n" +"POT-Creation-Date: 2023-11-03 15:33+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -20,7 +20,7 @@ msgstr "" "Generated-By: Babel 2.12.1\n" #: ../../getting_started/application/chatexcel/chatexcel.md:1 -#: ../../getting_started/application/chatexcel/chatexcel.md:15 +#: ../../getting_started/application/chatexcel/chatexcel.md:14 #: 5e9c1de21de240839a510b9e05afcba1 96556d6d1d734f67ab15e548c9fdce2f msgid "ChatExcel" msgstr "" @@ -36,42 +36,48 @@ msgid "" msgstr "使用自然语言进行Excel数据的分析处理" #: ../../getting_started/application/chatexcel/chatexcel.md:3 -#: ../../getting_started/application/chatexcel/chatexcel.md:19 -#: ../../getting_started/application/chatexcel/chatexcel.md:23 -#: ../../getting_started/application/chatexcel/chatexcel.md:27 -#: 05b68001df5449869515898742ba2b3a 13c354703dfd4a8487d2c4e5bf4abd73 -#: 286462d6d79b4189bcd9d17937a96233 5aac360c20ea4ad189539e28e5e1c70f -#: 7009abd113244cc5badb8e90837dc9af 7eb17d02534d4f77b7602f3756da0d5e -#: be04d49fc14641b8b0d17c1e9d02973b f5c1cfd0f77d4199a45988114174c67f +#: ../../getting_started/application/chatexcel/chatexcel.md:18 +#: ../../getting_started/application/chatexcel/chatexcel.md:22 +#: ../../getting_started/application/chatexcel/chatexcel.md:26 +#: 286462d6d79b4189bcd9d17937a96233 7009abd113244cc5badb8e90837dc9af +#: 7eb17d02534d4f77b7602f3756da0d5e f5c1cfd0f77d4199a45988114174c67f msgid "db plugins demonstration" msgstr "" -#: ../../getting_started/application/chatexcel/chatexcel.md:7 +#: ../../getting_started/application/chatexcel/chatexcel.md:6 #: 338f0b19314f4026b84a670d35056e6c -msgid "" -"The LLM (Language Model) suitable for the ChatExcel scene is * " -"chatgpt3.5. * chatgpt4." -msgstr "ChatExcel场景适用的LLM 是 scene is * " -"chatgpt3.5. * chatgpt4." +#, fuzzy +msgid "The LLM (Language Model) suitable for the ChatExcel scene is" +msgstr "ChatExcel场景适用的LLM 是 scene is * chatgpt3.5. * chatgpt4." -#: ../../getting_started/application/chatexcel/chatexcel.md:12 +#: ../../getting_started/application/chatexcel/chatexcel.md:7 +#: bc09e8af60b64a8fbeecedb927a5a854 +msgid "chatgpt3.5." +msgstr "" + +#: ../../getting_started/application/chatexcel/chatexcel.md:8 +#: e840c31d671946c190e27e1b7dd28647 +msgid "chatgpt4." +msgstr "" + +#: ../../getting_started/application/chatexcel/chatexcel.md:11 #: 2a710e2650bb44ef9d4a1ee4b8225a35 msgid "1.Select And Upload Excel or CSV File" msgstr "" -#: ../../getting_started/application/chatexcel/chatexcel.md:13 +#: ../../getting_started/application/chatexcel/chatexcel.md:12 #: df48b1003f3640cfa621e416f0405e8d msgid "Select your excel or csv file to upload and start the conversation." msgstr "选择你的Excel或者CSV文件上传开始对话" -#: ../../getting_started/application/chatexcel/chatexcel.md:17 +#: ../../getting_started/application/chatexcel/chatexcel.md:16 #: 7ef5d5ebb634406ea4b566bbf5e30fd7 msgid "" "The ChatExcel function supports Excel and CSV format files, select the " "corresponding file to use." msgstr "ChatExcel功能支持Excel和CSV格式的文件,选择对应格式的文件开始使用" -#: ../../getting_started/application/chatexcel/chatexcel.md:19 +#: ../../getting_started/application/chatexcel/chatexcel.md:18 #: 40c79b71820f44439b1f541db2be9dd9 msgid "" "![db plugins " @@ -79,12 +85,12 @@ msgid "" "plugins demonstration](../../../../assets/chat_excel/chat_excel_3.png)" msgstr "" -#: ../../getting_started/application/chatexcel/chatexcel.md:22 +#: ../../getting_started/application/chatexcel/chatexcel.md:21 #: 0dd469b6f56a442485392346065e345d msgid "2.Wait for Data Processing" msgstr "等待数据处理" -#: ../../getting_started/application/chatexcel/chatexcel.md:23 +#: ../../getting_started/application/chatexcel/chatexcel.md:22 #: 0e9213342664465187981d6fea41e7ba msgid "" "After the data is uploaded, it will first learn and process the data " @@ -92,12 +98,12 @@ msgid "" "demonstration](../../../../assets/chat_excel/chat_excel_4.png)" msgstr "等待数据上传完成,会自动进行数据结构的学习和处理" -#: ../../getting_started/application/chatexcel/chatexcel.md:26 +#: ../../getting_started/application/chatexcel/chatexcel.md:25 #: dd2047d1199542f7abda4767b953cfac msgid "3.Use Data Analysis Calculation" msgstr "开始使用数据分析计算" -#: ../../getting_started/application/chatexcel/chatexcel.md:27 +#: ../../getting_started/application/chatexcel/chatexcel.md:26 #: 4e168def205743c898586e99e34d3e18 msgid "" "Now you can use natural language to analyze and query data in the dialog " diff --git a/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/dashboard/dashboard.po b/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/dashboard/dashboard.po index 3c5397242..7ec08a868 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/dashboard/dashboard.po +++ b/docs/locales/zh_CN/LC_MESSAGES/getting_started/application/dashboard/dashboard.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 👏👏 0.3.5\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-03 15:25+0800\n" +"POT-Creation-Date: 2023-11-03 15:33+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -33,45 +33,53 @@ msgid "" " language and gain insights into their respective areas of business." msgstr "DB-GPT Dashboard目的是赋能数据分析人员。DB-GPT通过提供智能报表技术,使得业务分析人员可以直接使用简单的自然语言进行自助分析。" -#: ../../getting_started/application/dashboard/dashboard.md:8 +#: ../../getting_started/application/dashboard/dashboard.md:7 #: 3ce90998ab9547fc95105f0000e232da -msgid "" -"The LLM (Language Model) suitable for the Dashboard scene is * " -"chatgpt3.5. * chatgpt4." -msgstr "Dashboard场景适用的LLM是 * " -"chatgpt3.5. * chatgpt4." +#, fuzzy +msgid "The LLM (Language Model) suitable for the Dashboard scene is" +msgstr "Dashboard场景适用的LLM是 * chatgpt3.5. * chatgpt4." -#: ../../getting_started/application/dashboard/dashboard.md:14 +#: ../../getting_started/application/dashboard/dashboard.md:8 +#: be8fe8f9d9344e64acf51e54f8a17d7c +msgid "chatgpt3.5." +msgstr "" + +#: ../../getting_started/application/dashboard/dashboard.md:9 +#: 82ef8f03db3f4741a92113a485a40599 +msgid "chatgpt4." +msgstr "" + +#: ../../getting_started/application/dashboard/dashboard.md:13 #: da3aaa82126942058e72c472e2495641 msgid "Dashboard now support Datasource Type" msgstr "Dashboard目前支持的数据源类型" -#: ../../getting_started/application/dashboard/dashboard.md:15 +#: ../../getting_started/application/dashboard/dashboard.md:14 #: d21cfc9594a24b69a5040f60cba00abb msgid "Mysql" msgstr "Mysql" -#: ../../getting_started/application/dashboard/dashboard.md:16 +#: ../../getting_started/application/dashboard/dashboard.md:15 #: fc0e345321e84de5b9a96107fef5467e msgid "Sqlite" msgstr "Sqlite" -#: ../../getting_started/application/dashboard/dashboard.md:17 +#: ../../getting_started/application/dashboard/dashboard.md:16 #: f5cc4387997441b88a9f10ba9b35b621 msgid "DuckDB" msgstr "DuckDB" -#: ../../getting_started/application/dashboard/dashboard.md:19 +#: ../../getting_started/application/dashboard/dashboard.md:18 #: d8a86c3d05f84df0aa63c88f5dbfbd78 msgid "Steps to Dashboard In DB-GPT" msgstr "Dashboard使用步骤" -#: ../../getting_started/application/dashboard/dashboard.md:21 +#: ../../getting_started/application/dashboard/dashboard.md:20 #: dbf7b3f73677411a8e660f8d90c11e05 msgid "1 add datasource" msgstr "1.添加数据源" -#: ../../getting_started/application/dashboard/dashboard.md:23 +#: ../../getting_started/application/dashboard/dashboard.md:22 #: 70a599bc716a4af2b5a07a40de6fed9d #, fuzzy msgid "" @@ -82,17 +90,17 @@ msgid "" "8c36-213b1c6fb5dd)" msgstr "如果你是第一次使用Dashboard,需要构造测试数据,DB-GPT在pilot/mock_datas/提供了测试数据,只需要将数据源进行添加即可" -#: ../../getting_started/application/dashboard/dashboard.md:23 +#: ../../getting_started/application/dashboard/dashboard.md:22 #: e38d15f091264563840cf15f0a2fe97c msgid "add_datasource" msgstr "添加数据源" -#: ../../getting_started/application/dashboard/dashboard.md:27 +#: ../../getting_started/application/dashboard/dashboard.md:26 #: c6e87a5b20bb439ab1b3dc88e764d20b msgid "2.Choose Dashboard Mode" msgstr "2.进入Dashboard" -#: ../../getting_started/application/dashboard/dashboard.md:29 +#: ../../getting_started/application/dashboard/dashboard.md:28 #: 54c25766650546998d3aaa3655f5275b msgid "" "![create_space](https://github.com/eosphoros-ai/DB-" @@ -101,17 +109,17 @@ msgstr "" "![create_space](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/5e888880-0e97-4b60-8e5c-b7e7224197f0)" -#: ../../getting_started/application/dashboard/dashboard.md:29 +#: ../../getting_started/application/dashboard/dashboard.md:28 #: ea1781528db04000ab4a72308c7be97e msgid "create_space" msgstr "create_space" -#: ../../getting_started/application/dashboard/dashboard.md:31 +#: ../../getting_started/application/dashboard/dashboard.md:30 #: 5de9b0f0853443368d90e42114e99d6e msgid "3.Select Datasource" msgstr "3.选择数据源" -#: ../../getting_started/application/dashboard/dashboard.md:33 +#: ../../getting_started/application/dashboard/dashboard.md:32 #: 3d4c429c4660414a8d5c44dea0ea0192 msgid "" "![document](https://github.com/eosphoros-ai/DB-" @@ -120,18 +128,18 @@ msgstr "" "![document](https://github.com/eosphoros-ai/DB-" "GPT/assets/13723926/da2ac8b5-eca4-48ef-938f-f9dc1ca711b3)" -#: ../../getting_started/application/dashboard/dashboard.md:33 -#: ../../getting_started/application/dashboard/dashboard.md:37 -#: 338912391ae441328549accdb6d5522b 68ce490680fe4ed4a3c844c4c5b3fbd2 +#: ../../getting_started/application/dashboard/dashboard.md:32 +#: ../../getting_started/application/dashboard/dashboard.md:36 +#: 338912391ae441328549accdb6d5522b msgid "document" msgstr "document" -#: ../../getting_started/application/dashboard/dashboard.md:35 +#: ../../getting_started/application/dashboard/dashboard.md:34 #: 2c0fd7e79393417aa218908c5cc89461 msgid "4.Input your analysis goals" msgstr "4.输入分析目标" -#: ../../getting_started/application/dashboard/dashboard.md:37 +#: ../../getting_started/application/dashboard/dashboard.md:36 #: fb0bb655581a4109a5510240e54db006 #, fuzzy msgid "" @@ -144,18 +152,18 @@ msgstr "" "![document](https://github.com/eosphoros-ai/DB-GPT/assets/13723926" "/3d14a2da-165e-4b2f-a921-325c20fe5ae9)" -#: ../../getting_started/application/dashboard/dashboard.md:37 -#: ../../getting_started/application/dashboard/dashboard.md:41 -#: 17a72b7849a6458aa97182b72baad188 44680217a9794eddb97bcb98593a1071 +#: ../../getting_started/application/dashboard/dashboard.md:36 +#: ../../getting_started/application/dashboard/dashboard.md:40 +#: 44680217a9794eddb97bcb98593a1071 msgid "db plugins demonstration" msgstr "" -#: ../../getting_started/application/dashboard/dashboard.md:40 +#: ../../getting_started/application/dashboard/dashboard.md:39 #: 4a9a8eac8e77465a9519b532afdfd1b7 msgid "5.Adjust and modify your report" msgstr "5.调整" -#: ../../getting_started/application/dashboard/dashboard.md:41 +#: ../../getting_started/application/dashboard/dashboard.md:40 #: b56da5e50ced4085bb376caa26e50e78 msgid "" "![db plugins " diff --git a/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po b/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po index 38a88cc6f..2947c34c8 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po +++ b/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 👏👏 0.4.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-03 15:25+0800\n" +"POT-Creation-Date: 2023-11-04 15:08+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -90,7 +90,7 @@ msgid "macos:brew install git-lfs" msgstr "" #: ../../getting_started/install/deploy.rst:58 -#: ../../getting_started/install/deploy.rst:221 +#: ../../getting_started/install/deploy.rst:223 #: 9c601ee0c06646d58cbd2c2fff342cb5 d3fe6c712b4145d0856487c65057c2a0 msgid "OpenAI" msgstr "OpenAI" @@ -102,13 +102,13 @@ msgid "Download embedding model" msgstr "下载embedding model" #: ../../getting_started/install/deploy.rst:72 -#: ../../getting_started/install/deploy.rst:229 +#: ../../getting_started/install/deploy.rst:231 #: 953d6931627641b985588abf8b6ad9fd d52e287164ca44f79709f4645a1bb774 msgid "Configure LLM_MODEL and PROXY_API_URL and API_KEY in `.env` file" msgstr "在`.env`文件设置LLM_MODEL and PROXY_API_URL and API_KEY" #: ../../getting_started/install/deploy.rst:82 -#: ../../getting_started/install/deploy.rst:280 +#: ../../getting_started/install/deploy.rst:282 #: 6dc89616c0bf46a898a49606d1349039 e30b7458fc0d46e8bcf0ec61a2be2e19 msgid "Make sure your .env configuration is not overwritten" msgstr "认.env文件不会被覆盖\"" @@ -214,7 +214,7 @@ msgid "**Configure LLM_MODEL in `.env` file**" msgstr "" #: ../../getting_started/install/deploy.rst:131 -#: ../../getting_started/install/deploy.rst:226 +#: ../../getting_started/install/deploy.rst:228 #: 022addaea4ea432584b8a27ea83a9dc4 7a95d25c58d2491e855dff42f6d3a686 msgid "Baichuan" msgstr "" @@ -256,37 +256,42 @@ msgstr "将chatglm模型目录修改为\"chatglm2-6b\"" msgid "Other LLM API" msgstr "" -#: ../../getting_started/install/deploy.rst:222 +#: ../../getting_started/install/deploy.rst:219 +#: 3df3d5e0e4f64813a7ca2adccd056c4a +msgid "Now DB-GPT support LLM REST API TYPE:" +msgstr "目前DB-GPT支持的大模型REST API类型:" + +#: ../../getting_started/install/deploy.rst:224 #: 4f7cb7a3f324410d8a34ba96d7c9536a msgid "Azure" msgstr "" -#: ../../getting_started/install/deploy.rst:223 +#: ../../getting_started/install/deploy.rst:225 #: ee6cbe48a8094637b6b8a049446042c6 msgid "Aliyun tongyi" msgstr "" -#: ../../getting_started/install/deploy.rst:224 +#: ../../getting_started/install/deploy.rst:226 #: a3d9c061b0f440258be88cc3143b1887 msgid "Baidu wenxin" msgstr "" -#: ../../getting_started/install/deploy.rst:225 +#: ../../getting_started/install/deploy.rst:227 #: 176001fb6eaf448f9eca1abd256b3ef4 msgid "Zhipu" msgstr "" -#: ../../getting_started/install/deploy.rst:227 +#: ../../getting_started/install/deploy.rst:229 #: 17fecc140be2474ea1566d44641a27c0 msgid "Bard" msgstr "" -#: ../../getting_started/install/deploy.rst:282 +#: ../../getting_started/install/deploy.rst:284 #: bc34832cec754984a40c4d01526f0f83 msgid "llama.cpp" msgstr "" -#: ../../getting_started/install/deploy.rst:284 +#: ../../getting_started/install/deploy.rst:286 #: aa4b14e726dc447f92dec48f38a3d770 msgid "" "DB-GPT already supports `llama.cpp " @@ -296,24 +301,24 @@ msgstr "" "DB-GPT 已经支持了 `llama.cpp `_ via " "`llama-cpp-python `_ ." -#: ../../getting_started/install/deploy.rst:286 +#: ../../getting_started/install/deploy.rst:288 #: e97a868ad05b48ee8d25017457c1b7ee msgid "**Preparing Model Files**" msgstr "**准备Model文件**" -#: ../../getting_started/install/deploy.rst:288 +#: ../../getting_started/install/deploy.rst:290 #: 8efc7824082545a4a98ebbd6b12fa00f msgid "" "To use llama.cpp, you need to prepare a gguf format model file, and there" " are two common ways to obtain it, you can choose either:" msgstr "使用 llama.cpp,你需要准备 gguf 格式的文件,你可以通过以下两种方法获取" -#: ../../getting_started/install/deploy.rst:290 +#: ../../getting_started/install/deploy.rst:292 #: 5b9f3a35779c4f89a4b9051904c5f7d8 msgid "**1. Download a pre-converted model file.**" msgstr "**1.下载已转换的模型文件.**" -#: ../../getting_started/install/deploy.rst:292 +#: ../../getting_started/install/deploy.rst:294 #: e15f33a2e5fc4caaa9ad2e10cabf9d32 msgid "" "Suppose you want to use [Vicuna 13B v1.5](https://huggingface.co/lmsys" @@ -328,12 +333,12 @@ msgstr "" "13B-v1.5-GGUF)下载已转换的文件,只需要一个文件。将其下载到models目录并将其重命名为 `ggml-" "model-q4_0.gguf`。" -#: ../../getting_started/install/deploy.rst:298 +#: ../../getting_started/install/deploy.rst:300 #: 81ab603cd9b94cabb48add9541590b8b msgid "**2. Convert It Yourself**" msgstr "**2. 自行转换**" -#: ../../getting_started/install/deploy.rst:300 +#: ../../getting_started/install/deploy.rst:302 #: f9b46aa70a0842d6acc7e837c8b27778 msgid "" "You can convert the model file yourself according to the instructions in " @@ -345,31 +350,31 @@ msgstr "" "#prepare-data--run)中的说明自行转换模型文件,并把转换后的文件放在models目录中,并重命名为`ggml-" "model-q4_0.gguf`。" -#: ../../getting_started/install/deploy.rst:302 +#: ../../getting_started/install/deploy.rst:304 #: 5278c05568dd4ad688bcc181e45caa18 msgid "**Installing Dependencies**" msgstr "**安装依赖**" -#: ../../getting_started/install/deploy.rst:304 +#: ../../getting_started/install/deploy.rst:306 #: bd67bf651a9a4096a37e73851b5fad98 msgid "" "llama.cpp is an optional dependency in DB-GPT, and you can manually " "install it using the following command:" msgstr "llama.cpp在DB-GPT中是可选安装项, 你可以通过以下命令进行安装" -#: ../../getting_started/install/deploy.rst:311 +#: ../../getting_started/install/deploy.rst:313 #: 71ed6ae4d0aa4d3ca27ebfffc42a5095 msgid "**3.Modifying the Configuration File**" msgstr "**3.修改配置文件**" -#: ../../getting_started/install/deploy.rst:313 +#: ../../getting_started/install/deploy.rst:315 #: a0a2fdb799524ef4938df2c306536e2a msgid "Next, you can directly modify your `.env` file to enable llama.cpp." msgstr "修改`.env`文件使用llama.cpp" -#: ../../getting_started/install/deploy.rst:320 -#: ../../getting_started/install/deploy.rst:388 -#: 03694cbb7dfa432cb32116925357f008 07594f3e3e2e4d0f86b243629df5699e +#: ../../getting_started/install/deploy.rst:322 +#: ../../getting_started/install/deploy.rst:390 +#: 03694cbb7dfa432cb32116925357f008 msgid "" "Then you can run it according to `Run `_" @@ -377,55 +382,53 @@ msgstr "" "然后你可以根据[运行](https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-" "cn/zh_CN/latest/getting_started/install/deploy/deploy.html#run)来运行" -#: ../../getting_started/install/deploy.rst:323 +#: ../../getting_started/install/deploy.rst:325 #: c9bbc15ea2fc4562bdf87a4e099600a0 msgid "**More Configurations**" msgstr "**更多配置文件**" -#: ../../getting_started/install/deploy.rst:325 +#: ../../getting_started/install/deploy.rst:327 #: 9beff887d8554d1dac169de93625c1b2 msgid "" "In DB-GPT, the model configuration can be done through `{model " "name}_{config key}`." msgstr "在DB-GPT中,模型配置可以通过`{模型名称}_{配置名}` 来配置。" -#: ../../getting_started/install/deploy.rst:327 +#: ../../getting_started/install/deploy.rst:329 #: 6cad64bcc9f141de85479203b21f7f9e msgid "More Configurations" msgstr "**更多配置文件**" -#: ../../getting_started/install/deploy.rst:331 +#: ../../getting_started/install/deploy.rst:333 #: de97b0d5b59c4bfabbd47b7e1766cc70 msgid "Environment Variable Key" msgstr "环境变量Key" -#: ../../getting_started/install/deploy.rst:332 +#: ../../getting_started/install/deploy.rst:334 #: 76afa3655f644576b54b4422bad3fcad msgid "Default" msgstr "默认值" -#: ../../getting_started/install/deploy.rst:333 +#: ../../getting_started/install/deploy.rst:335 #: 0dcabfeeb4874e08ba53d4b4aa6a1d73 msgid "Description" msgstr "描述" -#: ../../getting_started/install/deploy.rst:334 +#: ../../getting_started/install/deploy.rst:336 #: c1670aec27cf4c068d825456817d7667 msgid "llama_cpp_prompt_template" msgstr "" -#: ../../getting_started/install/deploy.rst:335 -#: ../../getting_started/install/deploy.rst:338 -#: ../../getting_started/install/deploy.rst:344 -#: ../../getting_started/install/deploy.rst:350 -#: ../../getting_started/install/deploy.rst:356 -#: 1e13d43ba3574c33afa7e44d1643171b 355e51a688a0463f881ffce1a6cb0934 -#: 3775eb80762c4c6189efcaf62ee25556 49c8f875066f49c6aac195805f88e4a9 -#: 4d4358e00a31419b96d937cbbb4d9943 +#: ../../getting_started/install/deploy.rst:337 +#: ../../getting_started/install/deploy.rst:340 +#: ../../getting_started/install/deploy.rst:346 +#: ../../getting_started/install/deploy.rst:352 +#: ../../getting_started/install/deploy.rst:358 +#: 49c8f875066f49c6aac195805f88e4a9 msgid "None" msgstr "" -#: ../../getting_started/install/deploy.rst:336 +#: ../../getting_started/install/deploy.rst:338 #: bb31e19533e5434b832d5975bf579dc3 msgid "" "Prompt template name, now support: zero_shot, vicuna_v1.1,alpaca,llama-2" @@ -435,27 +438,27 @@ msgstr "" "Prompt template 现在可以支持`zero_shot, vicuna_v1.1,alpaca,llama-2,baichuan-" "chat,internlm-chat`, 如果是None, 可以根据模型路径来自动获取模型 Prompt template" -#: ../../getting_started/install/deploy.rst:337 +#: ../../getting_started/install/deploy.rst:339 #: 38ed23e19e2a47cf8fbacb035cfe1292 msgid "llama_cpp_model_path" msgstr "" -#: ../../getting_started/install/deploy.rst:339 +#: ../../getting_started/install/deploy.rst:341 #: eb069fdfdfeb4b17b723ee6733ba50c2 msgid "Model path" msgstr "模型路径" -#: ../../getting_started/install/deploy.rst:340 +#: ../../getting_started/install/deploy.rst:342 #: 348d3ff3e4f44ceb99aadead11f5cca5 msgid "llama_cpp_n_gpu_layers" msgstr "" -#: ../../getting_started/install/deploy.rst:341 +#: ../../getting_started/install/deploy.rst:343 #: 007deecf593b4553b6ca8df3e9240a28 msgid "1000000000" msgstr "" -#: ../../getting_started/install/deploy.rst:342 +#: ../../getting_started/install/deploy.rst:344 #: 4da435c417f0482581895bf4d052a6a1 msgid "" "Number of layers to offload to the GPU, Set this to 1000000000 to offload" @@ -463,123 +466,123 @@ msgid "" " number, eg: 10" msgstr "要将多少网络层转移到GPU上,将其设置为1000000000以将所有层转移到GPU上。如果您的 GPU 内存不足,可以设置较低的数字,例如:10。" -#: ../../getting_started/install/deploy.rst:343 +#: ../../getting_started/install/deploy.rst:345 #: 4f186505ea81467590cf817d116e6879 msgid "llama_cpp_n_threads" msgstr "" -#: ../../getting_started/install/deploy.rst:345 +#: ../../getting_started/install/deploy.rst:347 #: b94dc2fb2cd14a4a8f38ba95b05fbb5b msgid "" "Number of threads to use. If None, the number of threads is automatically" " determined" msgstr "要使用的线程数量。如果为None,则线程数量将自动确定。" -#: ../../getting_started/install/deploy.rst:346 +#: ../../getting_started/install/deploy.rst:348 #: 867f2357430440eba4e749a8a39bff18 msgid "llama_cpp_n_batch" msgstr "" -#: ../../getting_started/install/deploy.rst:347 +#: ../../getting_started/install/deploy.rst:349 #: 78516f7b23264147bae11e13426097eb msgid "512" msgstr "" -#: ../../getting_started/install/deploy.rst:348 +#: ../../getting_started/install/deploy.rst:350 #: c2ec97ffef3e4a70afef6634e78801a2 msgid "Maximum number of prompt tokens to batch together when calling llama_eval" msgstr "在调用llama_eval时,批处理在一起的prompt tokens的最大数量" -#: ../../getting_started/install/deploy.rst:349 +#: ../../getting_started/install/deploy.rst:351 #: 29ad3c5ab7134da49d6fca3b42d734d6 msgid "llama_cpp_n_gqa" msgstr "" -#: ../../getting_started/install/deploy.rst:351 +#: ../../getting_started/install/deploy.rst:353 #: e5bc322b0c824465b1adbd162838a3b7 msgid "Grouped-query attention. Must be 8 for llama-2 70b." msgstr "对于 llama-2 70B 模型,Grouped-query attention 必须为8。" -#: ../../getting_started/install/deploy.rst:352 +#: ../../getting_started/install/deploy.rst:354 #: 43e7d412238a4f0ba8227938d9fa4172 msgid "llama_cpp_rms_norm_eps" msgstr "" -#: ../../getting_started/install/deploy.rst:353 +#: ../../getting_started/install/deploy.rst:355 #: 6328db04645b4b089593291e2ca13f79 msgid "5e-06" msgstr "" -#: ../../getting_started/install/deploy.rst:354 +#: ../../getting_started/install/deploy.rst:356 #: 6c8bf631cece42fa86954f5cf2d75503 msgid "5e-6 is a good value for llama-2 models." msgstr "对于llama-2模型来说,5e-6是一个不错的值。" -#: ../../getting_started/install/deploy.rst:355 +#: ../../getting_started/install/deploy.rst:357 #: 22ebee39fe8b4cc18378447cac67e631 msgid "llama_cpp_cache_capacity" msgstr "" -#: ../../getting_started/install/deploy.rst:357 +#: ../../getting_started/install/deploy.rst:359 #: 4dc98bede90f4237829f65513e4adf61 msgid "Maximum cache capacity. Examples: 2000MiB, 2GiB" msgstr "模型缓存最大值. 例如: 2000MiB, 2GiB" -#: ../../getting_started/install/deploy.rst:358 +#: ../../getting_started/install/deploy.rst:360 #: bead617b5af943dab0bc1209823d3c22 msgid "llama_cpp_prefer_cpu" msgstr "" -#: ../../getting_started/install/deploy.rst:359 +#: ../../getting_started/install/deploy.rst:361 #: 8efb44f1cfc54b1a8b3ca8ea138113ee msgid "False" msgstr "" -#: ../../getting_started/install/deploy.rst:360 +#: ../../getting_started/install/deploy.rst:362 #: b854e6a44c8348ceb72ac382b73ceec5 msgid "" "If a GPU is available, it will be preferred by default, unless " "prefer_cpu=False is configured." msgstr "如果有可用的GPU,默认情况下会优先使用GPU,除非配置了 prefer_cpu=False。" -#: ../../getting_started/install/deploy.rst:363 +#: ../../getting_started/install/deploy.rst:365 #: 41b0440eb0074e5fa8c87dd404efe0ce msgid "vllm" msgstr "" -#: ../../getting_started/install/deploy.rst:365 +#: ../../getting_started/install/deploy.rst:367 #: 6fc445675bf74b2ea2fe0c7f2a64db69 msgid "vLLM is a fast and easy-to-use library for LLM inference and serving." msgstr "\"vLLM 是一个快速且易于使用的 LLM 推理和服务的库。" -#: ../../getting_started/install/deploy.rst:367 +#: ../../getting_started/install/deploy.rst:369 #: aab5f913d29445c4b345180b8793ebc7 msgid "**Running vLLM**" msgstr "**运行vLLM**" -#: ../../getting_started/install/deploy.rst:369 +#: ../../getting_started/install/deploy.rst:371 #: a9560d697821404cb0abdabf9f479645 msgid "**1.Installing Dependencies**" msgstr "**1.安装依赖**" -#: ../../getting_started/install/deploy.rst:371 +#: ../../getting_started/install/deploy.rst:373 #: b008224d4f314e5c988335262c95a42e msgid "" "vLLM is an optional dependency in DB-GPT, and you can manually install it" " using the following command:" msgstr "vLLM 在 DB-GPT 是一个可选依赖, 你可以使用下面的命令手动安装它:" -#: ../../getting_started/install/deploy.rst:377 +#: ../../getting_started/install/deploy.rst:379 #: 7dc0c8e996124177935a4e0d9ef19837 msgid "**2.Modifying the Configuration File**" msgstr "**2.修改配置文件**" -#: ../../getting_started/install/deploy.rst:379 +#: ../../getting_started/install/deploy.rst:381 #: 49667576b44c46bf87d5bf4d207dd63a msgid "Next, you can directly modify your .env file to enable vllm." msgstr "你可以直接修改你的 `.env` 文件" -#: ../../getting_started/install/deploy.rst:386 +#: ../../getting_started/install/deploy.rst:388 #: f16a78f0ee6545babab0d66f12654c0a msgid "" "You can view the models supported by vLLM `here " @@ -590,27 +593,27 @@ msgstr "" "[这里](https://vllm.readthedocs.io/en/latest/models/supported_models.html" "#supported-models) 查看 vLLM 支持的模型。" -#: ../../getting_started/install/deploy.rst:395 +#: ../../getting_started/install/deploy.rst:397 #: f7ae366723e9494d8177eeb963ba0ed9 msgid "3.Prepare sql example(Optional)" msgstr "3.准备 sql example(可选)" -#: ../../getting_started/install/deploy.rst:396 +#: ../../getting_started/install/deploy.rst:398 #: d302aac8ddb346598fc9d73e0f6c2cbc msgid "**(Optional) load examples into SQLite**" msgstr "**(可选) load examples into SQLite**" -#: ../../getting_started/install/deploy.rst:403 +#: ../../getting_started/install/deploy.rst:405 #: ae2a315e40854f27a074f2c0f2506014 msgid "On windows platform:" msgstr "" -#: ../../getting_started/install/deploy.rst:410 +#: ../../getting_started/install/deploy.rst:412 #: 36b4b7a813844af3a4ec8062b39059a3 msgid "4.Run db-gpt server" msgstr "4.运行db-gpt server" -#: ../../getting_started/install/deploy.rst:416 +#: ../../getting_started/install/deploy.rst:418 #: e56f15e563484027b7efb2147c9b71a7 msgid "**Open http://localhost:5000 with your browser to see the product.**" msgstr "打开浏览器访问http://localhost:5000" diff --git a/docs/locales/zh_CN/LC_MESSAGES/modules/plugins.po b/docs/locales/zh_CN/LC_MESSAGES/modules/plugins.po index 98bc4241d..662d7051d 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/modules/plugins.po +++ b/docs/locales/zh_CN/LC_MESSAGES/modules/plugins.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 0.3.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-03 15:25+0800\n" +"POT-Creation-Date: 2023-11-03 15:33+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -35,56 +35,62 @@ msgstr "" "Agent与插件能力是大模型能否自动化的核心,在本的项目中,原生支持插件模式,大模型可以自动化完成目标。 同时为了充分发挥社区的优势" ",本项目中所用的插件原生支持Auto-GPT插件生态,即Auto-GPT的插件可以直接在我们的项目中运行。" -#: ../../modules/plugins.md:6 625763bc41fe417c8e4ea03ab2f8fdfc -msgid "" -"The LLM (Language Model) suitable for the Plugin scene is * " -"chatgpt3.5. * chatgpt4." -msgstr "Plugin场景适用的LLM是 * " -"chatgpt3.5. * chatgpt4." +#: ../../modules/plugins.md:5 625763bc41fe417c8e4ea03ab2f8fdfc +#, fuzzy +msgid "The LLM (Language Model) suitable for the Plugin scene is" +msgstr "Plugin场景适用的LLM是 * chatgpt3.5. * chatgpt4." -#: ../../modules/plugins.md:11 8c539e139f6648b2bef5dc683b8e093c +#: ../../modules/plugins.md:6 b3bd64693a4f4bf8b64b9224d3e1532e +msgid "chatgpt3.5." +msgstr "" + +#: ../../modules/plugins.md:7 46d9220e63384594b54c2c176077d962 +msgid "chatgpt4." +msgstr "" + +#: ../../modules/plugins.md:10 8c539e139f6648b2bef5dc683b8e093c #, fuzzy msgid "Local Plugins" msgstr "插件" -#: ../../modules/plugins.md:13 2cc7ba992d524913b3377cad3bf747d3 +#: ../../modules/plugins.md:12 2cc7ba992d524913b3377cad3bf747d3 msgid "1.1 How to write local plugins." msgstr "" -#: ../../modules/plugins.md:15 eddffc1d2c434e45890a9befa1bb5160 +#: ../../modules/plugins.md:14 eddffc1d2c434e45890a9befa1bb5160 msgid "" "Local plugins use the Auto-GPT plugin template. A simple example is as " "follows: first write a plugin file called \"sql_executor.py\"." msgstr "" -#: ../../modules/plugins.md:45 06efbea552bb4dc7828d842b779e41d4 +#: ../../modules/plugins.md:44 06efbea552bb4dc7828d842b779e41d4 msgid "" "Then set the \"can_handle_post_prompt\" method of the plugin template to " "True. In the \"post_prompt\" method, write the prompt information and the" " mapped plugin function." msgstr "" -#: ../../modules/plugins.md:87 afd3cfb379bb463e97e515ae65790830 +#: ../../modules/plugins.md:86 afd3cfb379bb463e97e515ae65790830 msgid "1.2 How to use local plugins" msgstr "" -#: ../../modules/plugins.md:89 f43a70e4cb5c4846a5bb8df3853021ba +#: ../../modules/plugins.md:88 f43a70e4cb5c4846a5bb8df3853021ba msgid "" "Pack your plugin project into `your-plugin.zip` and place it in the " "`/plugins/` directory of the DB-GPT project. After starting the " "webserver, you can select and use it in the `Plugin Model` section." msgstr "" -#: ../../modules/plugins.md:92 8269458bd7f5480dbc56100865eb1eb0 +#: ../../modules/plugins.md:91 8269458bd7f5480dbc56100865eb1eb0 #, fuzzy msgid "Public Plugins" msgstr "插件" -#: ../../modules/plugins.md:94 ec5bb7b6b2cf464d8b8400f3dfd9a50e +#: ../../modules/plugins.md:93 ec5bb7b6b2cf464d8b8400f3dfd9a50e msgid "1.1 How to use public plugins" msgstr "" -#: ../../modules/plugins.md:96 3025a85c905c49b6b2ac3f5c39c84c93 +#: ../../modules/plugins.md:95 3025a85c905c49b6b2ac3f5c39c84c93 msgid "" "By default, after launching the webserver, plugins from the public plugin" " library `DB-GPT-Plugins` will be automatically loaded. For more details," @@ -92,17 +98,17 @@ msgid "" "Plugins)" msgstr "" -#: ../../modules/plugins.md:98 e73d7779df254ba49fe7123ce06353aa +#: ../../modules/plugins.md:97 e73d7779df254ba49fe7123ce06353aa msgid "1.2 Contribute to the DB-GPT-Plugins repository" msgstr "" -#: ../../modules/plugins.md:100 3297fb00dfc940e8a614c3858640cfe5 +#: ../../modules/plugins.md:99 3297fb00dfc940e8a614c3858640cfe5 msgid "" "Please refer to the plugin development process in the public plugin " "library, and put the configuration parameters in `.plugin_env`" msgstr "" -#: ../../modules/plugins.md:102 13280b270b304e139ed67e5b0dafa5b4 +#: ../../modules/plugins.md:101 13280b270b304e139ed67e5b0dafa5b4 msgid "" "We warmly welcome everyone to contribute plugins to the public plugin " "library!" From 59ac4ee5486627dbd39faf076b9ff801a8b6c4df Mon Sep 17 00:00:00 2001 From: FangYin Cheng Date: Sat, 4 Nov 2023 18:08:28 +0800 Subject: [PATCH 47/57] feat(core): Support pass span id to threadpool --- assets/schema/knowledge_management.sql | 1 + pilot/scene/base_chat.py | 9 +++++- pilot/scene/chat_agent/chat.py | 7 ++++- pilot/scene/chat_dashboard/chat.py | 2 ++ .../chat_excel/excel_analyze/chat.py | 9 +++++- .../chat_excel/excel_learning/chat.py | 2 ++ pilot/scene/chat_db/auto_execute/chat.py | 29 ++++++++++++------- .../scene/chat_db/auto_execute/out_parser.py | 3 ++ pilot/scene/chat_db/professional_qa/chat.py | 2 ++ pilot/scene/chat_execution/chat.py | 2 ++ .../chat_knowledge/inner_db_summary/chat.py | 2 ++ pilot/scene/chat_knowledge/v1/chat.py | 2 ++ pilot/utils/executor_utils.py | 11 +++++-- pilot/utils/tracer/tracer_cli.py | 7 +++-- 14 files changed, 70 insertions(+), 18 deletions(-) diff --git a/assets/schema/knowledge_management.sql b/assets/schema/knowledge_management.sql index e38f731d6..a6f1bc478 100644 --- a/assets/schema/knowledge_management.sql +++ b/assets/schema/knowledge_management.sql @@ -34,6 +34,7 @@ CREATE TABLE `knowledge_document` ( `content` LONGTEXT NOT NULL COMMENT 'knowledge embedding sync result', `result` TEXT NULL COMMENT 'knowledge content', `vector_ids` LONGTEXT NULL COMMENT 'vector_ids', + `summary` LONGTEXT NULL COMMENT 'knowledge summary', `gmt_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'created time', `gmt_modified` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'update time', PRIMARY KEY (`id`), diff --git a/pilot/scene/base_chat.py b/pilot/scene/base_chat.py index 294bd04ca..4529d3cb4 100644 --- a/pilot/scene/base_chat.py +++ b/pilot/scene/base_chat.py @@ -145,7 +145,14 @@ class BaseChat(ABC): ) self.current_message.tokens = 0 if self.prompt_template.template: - current_prompt = self.prompt_template.format(**input_values) + metadata = { + "template_scene": self.prompt_template.template_scene, + "input_values": input_values, + } + with root_tracer.start_span( + "BaseChat.__call_base.prompt_template.format", metadata=metadata + ): + current_prompt = self.prompt_template.format(**input_values) self.current_message.add_system_message(current_prompt) llm_messages = self.generate_llm_messages() diff --git a/pilot/scene/chat_agent/chat.py b/pilot/scene/chat_agent/chat.py index d9a8f60c1..81af1b3b1 100644 --- a/pilot/scene/chat_agent/chat.py +++ b/pilot/scene/chat_agent/chat.py @@ -11,6 +11,7 @@ from pilot.common.string_utils import extract_content from .prompt import prompt from pilot.component import ComponentType from pilot.base_modules.agent.controller import ModuleAgent +from pilot.utils.tracer import root_tracer, trace CFG = Config() @@ -51,6 +52,7 @@ class ChatAgent(BaseChat): self.api_call = ApiCall(plugin_generator=self.plugins_prompt_generator) + @trace() async def generate_input_values(self) -> Dict[str, str]: input_values = { "user_goal": self.current_user_input, @@ -63,7 +65,10 @@ class ChatAgent(BaseChat): def stream_plugin_call(self, text): text = text.replace("\n", " ") - return self.api_call.run(text) + with root_tracer.start_span( + "ChatAgent.stream_plugin_call.api_call", metadata={"text": text} + ): + return self.api_call.run(text) def __list_to_prompt_str(self, list: List) -> str: return "\n".join(f"{i + 1 + 1}. {item}" for i, item in enumerate(list)) diff --git a/pilot/scene/chat_dashboard/chat.py b/pilot/scene/chat_dashboard/chat.py index 211aa7c04..6771fb3fc 100644 --- a/pilot/scene/chat_dashboard/chat.py +++ b/pilot/scene/chat_dashboard/chat.py @@ -13,6 +13,7 @@ from pilot.scene.chat_dashboard.data_preparation.report_schma import ( from pilot.scene.chat_dashboard.prompt import prompt from pilot.scene.chat_dashboard.data_loader import DashboardDataLoader from pilot.utils.executor_utils import blocking_func_to_async +from pilot.utils.tracer import root_tracer, trace CFG = Config() @@ -53,6 +54,7 @@ class ChatDashboard(BaseChat): data = f.read() return json.loads(data) + @trace() async def generate_input_values(self) -> Dict: try: from pilot.summary.db_summary_client import DBSummaryClient diff --git a/pilot/scene/chat_data/chat_excel/excel_analyze/chat.py b/pilot/scene/chat_data/chat_excel/excel_analyze/chat.py index 064e7586c..fefc8142c 100644 --- a/pilot/scene/chat_data/chat_excel/excel_analyze/chat.py +++ b/pilot/scene/chat_data/chat_excel/excel_analyze/chat.py @@ -14,6 +14,7 @@ from pilot.scene.chat_data.chat_excel.excel_learning.chat import ExcelLearning from pilot.common.path_utils import has_path from pilot.configs.model_config import LLM_MODEL_CONFIG, KNOWLEDGE_UPLOAD_ROOT_PATH from pilot.base_modules.agent.common.schema import Status +from pilot.utils.tracer import root_tracer, trace CFG = Config() @@ -62,6 +63,7 @@ class ChatExcel(BaseChat): # ] return "\n".join(f"{i+1}. {item}" for i, item in enumerate(command_strings)) + @trace() async def generate_input_values(self) -> Dict: input_values = { "user_input": self.current_user_input, @@ -88,4 +90,9 @@ class ChatExcel(BaseChat): def stream_plugin_call(self, text): text = text.replace("\n", " ") - return self.api_call.run_display_sql(text, self.excel_reader.get_df_by_sql_ex) + with root_tracer.start_span( + "ChatExcel.stream_plugin_call.run_display_sql", metadata={"text": text} + ): + return self.api_call.run_display_sql( + text, self.excel_reader.get_df_by_sql_ex + ) diff --git a/pilot/scene/chat_data/chat_excel/excel_learning/chat.py b/pilot/scene/chat_data/chat_excel/excel_learning/chat.py index f05221eba..7d1730ad0 100644 --- a/pilot/scene/chat_data/chat_excel/excel_learning/chat.py +++ b/pilot/scene/chat_data/chat_excel/excel_learning/chat.py @@ -13,6 +13,7 @@ from pilot.scene.chat_data.chat_excel.excel_learning.prompt import prompt from pilot.scene.chat_data.chat_excel.excel_reader import ExcelReader from pilot.json_utils.utilities import DateTimeEncoder from pilot.utils.executor_utils import blocking_func_to_async +from pilot.utils.tracer import root_tracer, trace CFG = Config() @@ -44,6 +45,7 @@ class ExcelLearning(BaseChat): if parent_mode: self.current_message.chat_mode = parent_mode.value() + @trace() async def generate_input_values(self) -> Dict: # colunms, datas = self.excel_reader.get_sample_data() colunms, datas = await blocking_func_to_async( diff --git a/pilot/scene/chat_db/auto_execute/chat.py b/pilot/scene/chat_db/auto_execute/chat.py index d9b901772..4d4bf3c0c 100644 --- a/pilot/scene/chat_db/auto_execute/chat.py +++ b/pilot/scene/chat_db/auto_execute/chat.py @@ -6,6 +6,7 @@ from pilot.common.sql_database import Database from pilot.configs.config import Config from pilot.scene.chat_db.auto_execute.prompt import prompt from pilot.utils.executor_utils import blocking_func_to_async +from pilot.utils.tracer import root_tracer, trace CFG = Config() @@ -35,10 +36,13 @@ class ChatWithDbAutoExecute(BaseChat): raise ValueError( f"{ChatScene.ChatWithDbExecute.value} mode should chose db!" ) - - self.database = CFG.LOCAL_DB_MANAGE.get_connect(self.db_name) + with root_tracer.start_span( + "ChatWithDbAutoExecute.get_connect", metadata={"db_name": self.db_name} + ): + self.database = CFG.LOCAL_DB_MANAGE.get_connect(self.db_name) self.top_k: int = 200 + @trace() async def generate_input_values(self) -> Dict: """ generate input values @@ -55,13 +59,14 @@ class ChatWithDbAutoExecute(BaseChat): # query=self.current_user_input, # topk=CFG.KNOWLEDGE_SEARCH_TOP_SIZE, # ) - table_infos = await blocking_func_to_async( - self._executor, - client.get_db_summary, - self.db_name, - self.current_user_input, - CFG.KNOWLEDGE_SEARCH_TOP_SIZE, - ) + with root_tracer.start_span("ChatWithDbAutoExecute.get_db_summary"): + table_infos = await blocking_func_to_async( + self._executor, + client.get_db_summary, + self.db_name, + self.current_user_input, + CFG.KNOWLEDGE_SEARCH_TOP_SIZE, + ) except Exception as e: print("db summary find error!" + str(e)) if not table_infos: @@ -80,4 +85,8 @@ class ChatWithDbAutoExecute(BaseChat): def do_action(self, prompt_response): print(f"do_action:{prompt_response}") - return self.database.run(prompt_response.sql) + with root_tracer.start_span( + "ChatWithDbAutoExecute.do_action.run_sql", + metadata=prompt_response.to_dict(), + ): + return self.database.run(prompt_response.sql) diff --git a/pilot/scene/chat_db/auto_execute/out_parser.py b/pilot/scene/chat_db/auto_execute/out_parser.py index 577cac1ef..e583d945a 100644 --- a/pilot/scene/chat_db/auto_execute/out_parser.py +++ b/pilot/scene/chat_db/auto_execute/out_parser.py @@ -12,6 +12,9 @@ class SqlAction(NamedTuple): sql: str thoughts: Dict + def to_dict(self) -> Dict[str, Dict]: + return {"sql": self.sql, "thoughts": self.thoughts} + logger = logging.getLogger(__name__) diff --git a/pilot/scene/chat_db/professional_qa/chat.py b/pilot/scene/chat_db/professional_qa/chat.py index 5ae76d37d..fde28d91b 100644 --- a/pilot/scene/chat_db/professional_qa/chat.py +++ b/pilot/scene/chat_db/professional_qa/chat.py @@ -6,6 +6,7 @@ from pilot.common.sql_database import Database from pilot.configs.config import Config from pilot.scene.chat_db.professional_qa.prompt import prompt from pilot.utils.executor_utils import blocking_func_to_async +from pilot.utils.tracer import root_tracer, trace CFG = Config() @@ -39,6 +40,7 @@ class ChatWithDbQA(BaseChat): else len(self.tables) ) + @trace() async def generate_input_values(self) -> Dict: table_info = "" dialect = "mysql" diff --git a/pilot/scene/chat_execution/chat.py b/pilot/scene/chat_execution/chat.py index bdd78d7b7..2615918ff 100644 --- a/pilot/scene/chat_execution/chat.py +++ b/pilot/scene/chat_execution/chat.py @@ -6,6 +6,7 @@ from pilot.configs.config import Config from pilot.base_modules.agent.commands.command import execute_command from pilot.base_modules.agent import PluginPromptGenerator from .prompt import prompt +from pilot.utils.tracer import root_tracer, trace CFG = Config() @@ -50,6 +51,7 @@ class ChatWithPlugin(BaseChat): self.plugins_prompt_generator ) + @trace() async def generate_input_values(self) -> Dict: input_values = { "input": self.current_user_input, diff --git a/pilot/scene/chat_knowledge/inner_db_summary/chat.py b/pilot/scene/chat_knowledge/inner_db_summary/chat.py index 07a64aea9..f7c81bd77 100644 --- a/pilot/scene/chat_knowledge/inner_db_summary/chat.py +++ b/pilot/scene/chat_knowledge/inner_db_summary/chat.py @@ -4,6 +4,7 @@ from pilot.scene.base import ChatScene from pilot.configs.config import Config from pilot.scene.chat_knowledge.inner_db_summary.prompt import prompt +from pilot.utils.tracer import root_tracer, trace CFG = Config() @@ -31,6 +32,7 @@ class InnerChatDBSummary(BaseChat): self.db_input = db_select self.db_summary = db_summary + @trace() async def generate_input_values(self) -> Dict: input_values = { "db_input": self.db_input, diff --git a/pilot/scene/chat_knowledge/v1/chat.py b/pilot/scene/chat_knowledge/v1/chat.py index d57b32b25..a9c63b268 100644 --- a/pilot/scene/chat_knowledge/v1/chat.py +++ b/pilot/scene/chat_knowledge/v1/chat.py @@ -15,6 +15,7 @@ from pilot.configs.model_config import ( from pilot.scene.chat_knowledge.v1.prompt import prompt from pilot.server.knowledge.service import KnowledgeService from pilot.utils.executor_utils import blocking_func_to_async +from pilot.utils.tracer import root_tracer, trace CFG = Config() @@ -92,6 +93,7 @@ class ChatKnowledge(BaseChat): """return reference""" return text + f"\n\n{self.parse_source_view(self.sources)}" + @trace() async def generate_input_values(self) -> Dict: if self.space_context: self.prompt_template.template_define = self.space_context["prompt"]["scene"] diff --git a/pilot/utils/executor_utils.py b/pilot/utils/executor_utils.py index 2aac0d04d..26ee3c66e 100644 --- a/pilot/utils/executor_utils.py +++ b/pilot/utils/executor_utils.py @@ -1,5 +1,6 @@ from typing import Callable, Awaitable, Any import asyncio +import contextvars from abc import ABC, abstractmethod from concurrent.futures import Executor, ThreadPoolExecutor from functools import partial @@ -55,6 +56,12 @@ async def blocking_func_to_async( """ if asyncio.iscoroutinefunction(func): raise ValueError(f"The function {func} is not blocking function") + + # This function will be called within the new thread, capturing the current context + ctx = contextvars.copy_context() + + def run_with_context(): + return ctx.run(partial(func, *args, **kwargs)) + loop = asyncio.get_event_loop() - sync_function_noargs = partial(func, *args, **kwargs) - return await loop.run_in_executor(executor, sync_function_noargs) + return await loop.run_in_executor(executor, run_with_context) diff --git a/pilot/utils/tracer/tracer_cli.py b/pilot/utils/tracer/tracer_cli.py index 859fa4022..3fb9cba31 100644 --- a/pilot/utils/tracer/tracer_cli.py +++ b/pilot/utils/tracer/tracer_cli.py @@ -303,8 +303,6 @@ def chat( print(table.get_formatted_string(out_format=output, **out_kwargs)) if sys_table: print(sys_table.get_formatted_string(out_format=output, **out_kwargs)) - if hide_conv: - return if not found_trace_id: print(f"Can't found conversation with trace_id: {trace_id}") @@ -315,9 +313,12 @@ def chat( trace_spans = [s for s in reversed(trace_spans)] hierarchy = _build_trace_hierarchy(trace_spans) if tree: - print("\nInvoke Trace Tree:\n") + print(f"\nInvoke Trace Tree(trace_id: {trace_id}):\n") _print_trace_hierarchy(hierarchy) + if hide_conv: + return + trace_spans = _get_ordered_trace_from(hierarchy) table = PrettyTable(["Key", "Value Value"], title="Chat Trace Details") split_long_text = output == "text" From 0210c1c9257d54820db9fc9c6ce9baeb5cd3f6b1 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Sun, 5 Nov 2023 13:24:01 +0800 Subject: [PATCH 48/57] doc:hide use cases --- docs/index.rst | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 6a43c2534..9215b21a2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -91,35 +91,6 @@ It's very important for DB-GPT, DB-GPT also provide standard, extendable interfa ./modules/knowledge.rst ./modules/vector.rst -Use Cases ---------- - -| Best Practices and built-in implementations for common DB-GPT use cases: - -- `Sql generation and diagnosis <./use_cases/sql_generation_and_diagnosis.html>`_: SQL generation and diagnosis. - -- `knownledge Based QA <./use_cases/knownledge_based_qa.html>`_: A important scene for user to chat with database documents, codes, bugs and schemas. - -- `Chatbots <./use_cases/chatbots.html>`_: Language model love to chat, use multi models to chat. - -- `Querying Database Data <./use_cases/query_database_data.html>`_: Query and Analysis data from databases and give charts. - -- `Interacting with apis <./use_cases/interacting_with_api.html>`_: Interact with apis, such as create a table, deploy a database cluster, create a database and so on. - -- `Tool use with plugins <./use_cases/tool_use_with_plugin>`_: According to Plugin use tools to manage databases autonomoly. - -.. toctree:: - :maxdepth: 2 - :caption: Use Cases - :name: use_cases - :hidden: - - ./use_cases/sql_generation_and_diagnosis.md - ./use_cases/knownledge_based_qa.md - ./use_cases/chatbots.md - ./use_cases/query_database_data.md - ./use_cases/interacting_with_api.md - ./use_cases/tool_use_with_plugin.md Reference ----------- From 8ad723c098bd59b98de79e7a4bf25735f6add893 Mon Sep 17 00:00:00 2001 From: aries_ckt <916701291@qq.com> Date: Mon, 6 Nov 2023 13:54:20 +0800 Subject: [PATCH 49/57] chore:wechat update --- assets/wechat.jpg | Bin 206792 -> 245491 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/assets/wechat.jpg b/assets/wechat.jpg index ec465785c48264626c9fb04b51dde1cd09fd7769..1da14706799d9d36997e6e1d8969a00ee02add79 100644 GIT binary patch literal 245491 zcmdqJ2UHVX*DpRase*K=p$bYxEBxg-#&N=(+eRlcnJu*j` zBxu*^Q|6~278VFH1Ah>620CLB;_C%LmX^>y2!gmERu&>X${`V_vVlUYK*;d{Dk+}*Tvi8B=#0L6cugmFZ?uQPYFt=pi?g1Qsx0U~H?i!Sd zA4`HN*cb0{KU;xM;FzK=IgxV80}?e>5F-fsWvpbl?S0YL*A+kLGtauW|lnzr~?HCo*v?$-L( zegA2T$HOzw9sEKE=YIF=H*SJOQ3q}7;G5UC+hL$Basx~Xv>$D^z5mh9+itu4qy6sh zdoG+e2KV%Uww$|Bt z*P*MBD|8!@gRCK)|H=Kjf8TEmVZq(Ep&Q^iZ^#F_37$C)u59<<3EJk+HOL*(gw#P> z8`=*}?d^32&w_(G^l$5@{;z8h(-3r&z+^J(|8?y&0fNf)A&BSwzpkksf*?U&2X>Duo=={|6 zbzpF4cw}^pI5Rspzwqt*kHsa*`o^!{)J^!$);3)%5Zgb<0-yh&?BCHP2&n0pq`DJ-Cx1!E@vZ&jQFFayOx--g@ZPNax z?0=20@c%8!{z=%s=o*KN!4BU(SiwIwR#w0&HgK>562QT+gX8aG$G;t%e;-`i2lqb@ zCg|kv9#~n~!9VUD96SE`+y8QdISCY)Hj@bPv9SPQViSbW5OUy0P8_8A|G>%Y|9^;< zFaM5~*Q@^5u-6nTD--h5y|^Xi)O&iaiyoU#34sDJ-iv6mB?eY)Z_FR}OGkY`#cbB- zmn%^>cZJy7r|fl0HdacmBR=)?lq+IA&Z%(EXm3u_HzpK)8Q*My|1o8>hY8In7c-%C z4HS7r0N#sbNOiPM)0L{T5tA1JQ9h;b2{WT8^7-j4{iIj|Z0?7qKQyHqupvB7Oz0Ga zqR)i5HN2TnvJcx#y4p`He2bGVQi~+a&0-ND$37;c@P!HSe_%r4sZ8igLzpEK`e@<6 zgytO~*ei~ffymrvLL3@QC^rPoU_uX4E16Jd6~3hmP0AsRc4>X><5tzK<9zOcpVU*F*iYI@c)3B+k12opNC1|KvvL?L;1@^J%jU%QbQ986+3&2lDUNnfihc|PAYwr+eMAT2gr zQ(jeRsaDSOTKY;)&sm5)OO-7@hY*L3WkTfJ-YuED9d%hr zEGf~CPM(`~aOS9~YPhK`(udt2#p-VP)l^k8fUAT0@P!{yC9Xlzv=3c^jR9|fNZyMku!*Hyh^N;JuDuFJwN|U8? zFly1H+#^;WwTPzXcSBqB?&#$fHT|_Gh3lTyHYTl>VlLT7Eki8*s)Zy>un4ON?$WSOpr`IR#-(?znz&pd3Q z)Ds*K{^e!@o;0NeE9u7@qTYm@@0$@Vh}O&X)2OB*=$>bwbtmOyv=xCL*v;Q8arJ7ae6HMZd)I6%g@-W}FA&O|q>Yy^_=`T&X%xnWVRJ)*t<`HbH;1WTMdbFIdtUI*3ukGb zlN;H3=L0x^Eu{-?ntt`anM}5~tfQʿ*@{pyo$hKS}L)T(h{jdsWTZ-h@wsO8RN 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

uXKU4!>?RjQ@!7-M+6aRH(anGP&T0Wn5?ge-%9z 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

s8*3e(Mu$9amuK0Vr$U&R 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Â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�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 L{mBgd$It%<>7F}Y From 73bf6453ac4cfab80e8761e0d53428e0cb3633b2 Mon Sep 17 00:00:00 2001 From: Alpha Hinex Date: Mon, 6 Nov 2023 14:38:10 +0800 Subject: [PATCH 50/57] Fix typo in base_chat.py --- pilot/scene/base_chat.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pilot/scene/base_chat.py b/pilot/scene/base_chat.py index 4529d3cb4..86fe8f859 100644 --- a/pilot/scene/base_chat.py +++ b/pilot/scene/base_chat.py @@ -382,7 +382,7 @@ class BaseChat(ABC): text += self.__load_example_messages() ### Load History - text += self.__load_histroy_messages() + text += self.__load_history_messages() ### Load User Input text += self.__load_user_message() @@ -408,7 +408,7 @@ class BaseChat(ABC): messages += self.__load_example_messages(str_message=False) ### Load History - messages += self.__load_histroy_messages(str_message=False) + messages += self.__load_history_messages(str_message=False) ### Load User Input messages += self.__load_user_message(str_message=False) @@ -464,7 +464,7 @@ class BaseChat(ABC): ) return example_text if str_message else example_messages - def __load_histroy_messages(self, str_message: bool = True): + def __load_history_messages(self, str_message: bool = True): history_text = "" history_messages = [] if self.prompt_template.need_historical_messages: From 352867dc718649d8a3b94bb77f588b5e16ff08c5 Mon Sep 17 00:00:00 2001 From: Alpha Hinex Date: Mon, 6 Nov 2023 15:13:55 +0800 Subject: [PATCH 51/57] Fix 'InvalidParameter:User and assistant need to appear alternately in the message' issue --- pilot/model/proxy/llms/tongyi.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/pilot/model/proxy/llms/tongyi.py b/pilot/model/proxy/llms/tongyi.py index fb826e49c..13031e96f 100644 --- a/pilot/model/proxy/llms/tongyi.py +++ b/pilot/model/proxy/llms/tongyi.py @@ -36,7 +36,7 @@ def tongyi_generate_stream( if message.role == ModelMessageRoleType.HUMAN: history.append({"role": "user", "content": message.content}) for message in messages: - if message.role == ModelMessageRoleType.SYSTEM: + if message.role == ModelMessageRoleType.SYSTEM or message.role == ModelMessageRoleType.HUMAN: history.append({"role": "user", "content": message.content}) # elif message.role == ModelMessageRoleType.HUMAN: # history.append({"role": "user", "content": message.content}) @@ -45,17 +45,24 @@ def tongyi_generate_stream( else: pass - # temp_his = history[::-1] - temp_his = history + temp_his = history[::-1] last_user_input = None for m in temp_his: if m["role"] == "user": last_user_input = m break - if last_user_input: + temp_his = history + prompt_input = None + for m in temp_his: + if m["role"] == "user": + prompt_input = m + break + + if last_user_input and prompt_input and last_user_input != prompt_input: history.remove(last_user_input) - history.append(last_user_input) + history.remove(prompt_input) + history.append(prompt_input) gen = Generation() res = gen.call( From 5accaa44beeb2f560ba19d7f4f2ac562b4a9b4f3 Mon Sep 17 00:00:00 2001 From: FangYin Cheng Date: Mon, 6 Nov 2023 18:56:25 +0800 Subject: [PATCH 52/57] feat(core): Support custom trace storage --- pilot/model/cluster/worker/manager.py | 1 + pilot/model/parameter.py | 18 +++ pilot/server/base.py | 6 + pilot/server/dbgpt_server.py | 6 +- pilot/utils/tracer/__init__.py | 7 +- pilot/utils/tracer/base.py | 7 +- pilot/utils/tracer/span_storage.py | 117 ++++++++++++------ pilot/utils/tracer/tests/test_span_storage.py | 95 +++++++------- pilot/utils/tracer/tracer_impl.py | 17 ++- 9 files changed, 189 insertions(+), 85 deletions(-) diff --git a/pilot/model/cluster/worker/manager.py b/pilot/model/cluster/worker/manager.py index 2dcfb086e..d67519f59 100644 --- a/pilot/model/cluster/worker/manager.py +++ b/pilot/model/cluster/worker/manager.py @@ -1021,6 +1021,7 @@ def run_worker_manager( system_app, os.path.join(LOGDIR, worker_params.tracer_file), root_operation_name="DB-GPT-WorkerManager-Entry", + tracer_storage_cls=worker_params.tracer_storage_cls, ) _start_local_worker(worker_manager, worker_params) diff --git a/pilot/model/parameter.py b/pilot/model/parameter.py index e21de1c42..79558e02c 100644 --- a/pilot/model/parameter.py +++ b/pilot/model/parameter.py @@ -88,6 +88,12 @@ class ModelControllerParameters(BaseParameters): "help": "The filename to store tracer span records", }, ) + tracer_storage_cls: Optional[str] = field( + default=None, + metadata={ + "help": "The storage class to storage tracer span records", + }, + ) @dataclass @@ -138,6 +144,12 @@ class ModelAPIServerParameters(BaseParameters): "help": "The filename to store tracer span records", }, ) + tracer_storage_cls: Optional[str] = field( + default=None, + metadata={ + "help": "The storage class to storage tracer span records", + }, + ) @dataclass @@ -226,6 +238,12 @@ class ModelWorkerParameters(BaseModelParameters): "help": "The filename to store tracer span records", }, ) + tracer_storage_cls: Optional[str] = field( + default=None, + metadata={ + "help": "The storage class to storage tracer span records", + }, + ) @dataclass diff --git a/pilot/server/base.py b/pilot/server/base.py index 71faeb821..488c919c3 100644 --- a/pilot/server/base.py +++ b/pilot/server/base.py @@ -147,6 +147,12 @@ class WebWerverParameters(BaseParameters): "help": "The filename to store tracer span records", }, ) + tracer_storage_cls: Optional[str] = field( + default=None, + metadata={ + "help": "The storage class to storage tracer span records", + }, + ) disable_alembic_upgrade: Optional[bool] = field( default=False, metadata={ diff --git a/pilot/server/dbgpt_server.py b/pilot/server/dbgpt_server.py index e94526b9a..c26803cfd 100644 --- a/pilot/server/dbgpt_server.py +++ b/pilot/server/dbgpt_server.py @@ -195,7 +195,11 @@ def run_uvicorn(param: WebWerverParameters): def run_webserver(param: WebWerverParameters = None): if not param: param = _get_webserver_params() - initialize_tracer(system_app, os.path.join(LOGDIR, param.tracer_file)) + initialize_tracer( + system_app, + os.path.join(LOGDIR, param.tracer_file), + tracer_storage_cls=param.tracer_storage_cls, + ) with root_tracer.start_span( "run_webserver", diff --git a/pilot/utils/tracer/__init__.py b/pilot/utils/tracer/__init__.py index cdb536f79..6f77cfd6c 100644 --- a/pilot/utils/tracer/__init__.py +++ b/pilot/utils/tracer/__init__.py @@ -7,7 +7,11 @@ from pilot.utils.tracer.base import ( SpanStorageType, TracerContext, ) -from pilot.utils.tracer.span_storage import MemorySpanStorage, FileSpanStorage +from pilot.utils.tracer.span_storage import ( + MemorySpanStorage, + FileSpanStorage, + SpanStorageContainer, +) from pilot.utils.tracer.tracer_impl import ( root_tracer, trace, @@ -26,6 +30,7 @@ __all__ = [ "TracerContext", "MemorySpanStorage", "FileSpanStorage", + "SpanStorageContainer", "root_tracer", "trace", "initialize_tracer", diff --git a/pilot/utils/tracer/base.py b/pilot/utils/tracer/base.py index e227d6314..625e9aabd 100644 --- a/pilot/utils/tracer/base.py +++ b/pilot/utils/tracer/base.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Dict, Callable, Optional +from typing import Dict, Callable, Optional, List from dataclasses import dataclass from abc import ABC, abstractmethod from enum import Enum @@ -121,6 +121,11 @@ class SpanStorage(BaseComponent, ABC): def append_span(self, span: Span): """Store the given span. This needs to be implemented by subclasses.""" + def append_span_batch(self, spans: List[Span]): + """Store the span batch""" + for span in spans: + self.append_span(span) + class Tracer(BaseComponent, ABC): """Abstract base class for tracing operations. diff --git a/pilot/utils/tracer/span_storage.py b/pilot/utils/tracer/span_storage.py index 3070fb834..57321a316 100644 --- a/pilot/utils/tracer/span_storage.py +++ b/pilot/utils/tracer/span_storage.py @@ -5,11 +5,12 @@ import datetime import threading import queue import logging +from typing import Optional, List +from concurrent.futures import Executor, ThreadPoolExecutor from pilot.component import SystemApp from pilot.utils.tracer.base import Span, SpanStorage - logger = logging.getLogger(__name__) @@ -24,8 +25,81 @@ class MemorySpanStorage(SpanStorage): self.spans.append(span) +class SpanStorageContainer(SpanStorage): + def __init__( + self, + system_app: SystemApp | None = None, + batch_size=10, + flush_interval=10, + executor: Executor = None, + ): + super().__init__(system_app) + if not executor: + executor = ThreadPoolExecutor(thread_name_prefix="trace_storage_sync_") + self.executor = executor + self.storages: List[SpanStorage] = [] + self.last_date = ( + datetime.datetime.now().date() + ) # Store the current date for checking date changes + self.queue = queue.Queue() + self.batch_size = batch_size + self.flush_interval = flush_interval + self.last_flush_time = time.time() + self.flush_signal_queue = queue.Queue() + self.flush_thread = threading.Thread( + target=self._flush_to_storages, daemon=True + ) + self.flush_thread.start() + + def append_storage(self, storage: SpanStorage): + """Append sotrage to container + + Args: + storage ([`SpanStorage`]): The storage to be append to current container + """ + self.storages.append(storage) + + def append_span(self, span: Span): + self.queue.put(span) + if self.queue.qsize() >= self.batch_size: + try: + self.flush_signal_queue.put_nowait(True) + except queue.Full: + pass # If the signal queue is full, it's okay. The flush thread will handle it. + + def _flush_to_storages(self): + while True: + interval = time.time() - self.last_flush_time + if interval < self.flush_interval: + try: + self.flush_signal_queue.get( + block=True, timeout=self.flush_interval - interval + ) + except Exception: + # Timeout + pass + + spans_to_write = [] + while not self.queue.empty(): + spans_to_write.append(self.queue.get()) + for s in self.storages: + + def append_and_ignore_error( + storage: SpanStorage, spans_to_write: List[SpanStorage] + ): + try: + storage.append_span_batch(spans_to_write) + except Exception as e: + logger.warn( + f"Append spans to storage {str(storage)} failed: {str(e)}, span_data: {spans_to_write}" + ) + + self.executor.submit(append_and_ignore_error, s, spans_to_write) + self.last_flush_time = time.time() + + class FileSpanStorage(SpanStorage): - def __init__(self, filename: str, batch_size=10, flush_interval=10): + def __init__(self, filename: str): super().__init__() self.filename = filename # Split filename into prefix and suffix @@ -36,29 +110,18 @@ class FileSpanStorage(SpanStorage): datetime.datetime.now().date() ) # Store the current date for checking date changes self.queue = queue.Queue() - self.batch_size = batch_size - self.flush_interval = flush_interval - self.last_flush_time = time.time() - self.flush_signal_queue = queue.Queue() if not os.path.exists(filename): # New file if not exist os.makedirs(os.path.dirname(filename), exist_ok=True) with open(filename, "a"): pass - self.flush_thread = threading.Thread(target=self._flush_to_file, daemon=True) - self.flush_thread.start() def append_span(self, span: Span): - span_data = span.to_dict() - logger.debug(f"append span: {span_data}") - self.queue.put(span_data) + self._write_to_file([span]) - if self.queue.qsize() >= self.batch_size: - try: - self.flush_signal_queue.put_nowait(True) - except queue.Full: - pass # If the signal queue is full, it's okay. The flush thread will handle it. + def append_span_batch(self, spans: List[Span]): + self._write_to_file(spans) def _get_dated_filename(self, date: datetime.date) -> str: """Return the filename based on a specific date.""" @@ -73,31 +136,15 @@ class FileSpanStorage(SpanStorage): os.rename(self.filename, self._get_dated_filename(self.last_date)) self.last_date = current_date - def _write_to_file(self): + def _write_to_file(self, spans: List[Span]): self._roll_over_if_needed() - spans_to_write = [] - while not self.queue.empty(): - spans_to_write.append(self.queue.get()) with open(self.filename, "a") as file: - for span_data in spans_to_write: + for span in spans: + span_data = span.to_dict() try: file.write(json.dumps(span_data, ensure_ascii=False) + "\n") except Exception as e: logger.warning( f"Write span to file failed: {str(e)}, span_data: {span_data}" ) - - def _flush_to_file(self): - while True: - interval = time.time() - self.last_flush_time - if interval < self.flush_interval: - try: - self.flush_signal_queue.get( - block=True, timeout=self.flush_interval - interval - ) - except Exception: - # Timeout - pass - self._write_to_file() - self.last_flush_time = time.time() diff --git a/pilot/utils/tracer/tests/test_span_storage.py b/pilot/utils/tracer/tests/test_span_storage.py index 9ca727995..6da0797fc 100644 --- a/pilot/utils/tracer/tests/test_span_storage.py +++ b/pilot/utils/tracer/tests/test_span_storage.py @@ -7,44 +7,53 @@ import time from unittest.mock import patch from datetime import datetime, timedelta -from pilot.utils.tracer import SpanStorage, FileSpanStorage, Span, SpanType +from pilot.utils.tracer import ( + SpanStorage, + FileSpanStorage, + Span, + SpanType, + SpanStorageContainer, +) @pytest.fixture def storage(request): if not request or not hasattr(request, "param"): - batch_size = 10 - flush_interval = 10 file_does_not_exist = False else: - batch_size = request.param.get("batch_size", 10) - flush_interval = request.param.get("flush_interval", 10) file_does_not_exist = request.param.get("file_does_not_exist", False) if file_does_not_exist: with tempfile.TemporaryDirectory() as tmp_dir: filename = os.path.join(tmp_dir, "non_existent_file.jsonl") - storage_instance = FileSpanStorage( - filename, batch_size=batch_size, flush_interval=flush_interval - ) + storage_instance = FileSpanStorage(filename) yield storage_instance else: with tempfile.NamedTemporaryFile(delete=True) as tmp_file: filename = tmp_file.name - storage_instance = FileSpanStorage( - filename, batch_size=batch_size, flush_interval=flush_interval - ) + storage_instance = FileSpanStorage(filename) yield storage_instance +@pytest.fixture +def storage_container(request): + if not request or not hasattr(request, "param"): + batch_size = 10 + flush_interval = 10 + else: + batch_size = request.param.get("batch_size", 10) + flush_interval = request.param.get("flush_interval", 10) + storage_container = SpanStorageContainer( + batch_size=batch_size, flush_interval=flush_interval + ) + yield storage_container + + def read_spans_from_file(filename): with open(filename, "r") as f: return [json.loads(line) for line in f.readlines()] -@pytest.mark.parametrize( - "storage", [{"batch_size": 1, "flush_interval": 5}], indirect=True -) def test_write_span(storage: SpanStorage): span = Span("1", "a", SpanType.BASE, "b", "op1") storage.append_span(span) @@ -55,9 +64,6 @@ def test_write_span(storage: SpanStorage): assert spans_in_file[0]["trace_id"] == "1" -@pytest.mark.parametrize( - "storage", [{"batch_size": 1, "flush_interval": 5}], indirect=True -) def test_incremental_write(storage: SpanStorage): span1 = Span("1", "a", SpanType.BASE, "b", "op1") span2 = Span("2", "c", SpanType.BASE, "d", "op2") @@ -70,9 +76,6 @@ def test_incremental_write(storage: SpanStorage): assert len(spans_in_file) == 2 -@pytest.mark.parametrize( - "storage", [{"batch_size": 2, "flush_interval": 5}], indirect=True -) def test_sync_and_async_append(storage: SpanStorage): span = Span("1", "a", SpanType.BASE, "b", "op1") @@ -88,27 +91,7 @@ def test_sync_and_async_append(storage: SpanStorage): assert len(spans_in_file) == 2 -@pytest.mark.asyncio -async def test_flush_policy(storage: SpanStorage): - span = Span("1", "a", SpanType.BASE, "b", "op1") - - for _ in range(storage.batch_size - 1): - storage.append_span(span) - - spans_in_file = read_spans_from_file(storage.filename) - assert len(spans_in_file) == 0 - - # Trigger batch write - storage.append_span(span) - await asyncio.sleep(0.1) - - spans_in_file = read_spans_from_file(storage.filename) - assert len(spans_in_file) == storage.batch_size - - -@pytest.mark.parametrize( - "storage", [{"batch_size": 2, "file_does_not_exist": True}], indirect=True -) +@pytest.mark.parametrize("storage", [{"file_does_not_exist": True}], indirect=True) def test_non_existent_file(storage: SpanStorage): span = Span("1", "a", SpanType.BASE, "b", "op1") span2 = Span("2", "c", SpanType.BASE, "d", "op2") @@ -116,7 +99,7 @@ def test_non_existent_file(storage: SpanStorage): time.sleep(0.1) spans_in_file = read_spans_from_file(storage.filename) - assert len(spans_in_file) == 0 + assert len(spans_in_file) == 1 storage.append_span(span2) time.sleep(0.1) @@ -126,9 +109,7 @@ def test_non_existent_file(storage: SpanStorage): assert spans_in_file[1]["trace_id"] == "2" -@pytest.mark.parametrize( - "storage", [{"batch_size": 1, "file_does_not_exist": True}], indirect=True -) +@pytest.mark.parametrize("storage", [{"file_does_not_exist": True}], indirect=True) def test_log_rollover(storage: SpanStorage): # mock start date mock_start_date = datetime(2023, 10, 18, 23, 59) @@ -167,3 +148,27 @@ def test_log_rollover(storage: SpanStorage): spans_in_dated_file = read_spans_from_file(dated_filename) assert len(spans_in_dated_file) == 1 assert spans_in_dated_file[0]["trace_id"] == "1" + + +@pytest.mark.asyncio +@pytest.mark.parametrize("storage_container", [{"batch_size": 5}], indirect=True) +async def test_container_flush_policy( + storage_container: SpanStorageContainer, storage: FileSpanStorage +): + storage_container.append_storage(storage) + span = Span("1", "a", SpanType.BASE, "b", "op1") + + filename = storage.filename + + for _ in range(storage_container.batch_size - 1): + storage_container.append_span(span) + + spans_in_file = read_spans_from_file(filename) + assert len(spans_in_file) == 0 + + # Trigger batch write + storage_container.append_span(span) + await asyncio.sleep(0.1) + + spans_in_file = read_spans_from_file(filename) + assert len(spans_in_file) == storage_container.batch_size diff --git a/pilot/utils/tracer/tracer_impl.py b/pilot/utils/tracer/tracer_impl.py index 2358863bf..6bbad084c 100644 --- a/pilot/utils/tracer/tracer_impl.py +++ b/pilot/utils/tracer/tracer_impl.py @@ -3,6 +3,7 @@ from contextvars import ContextVar from functools import wraps import asyncio import inspect +import logging from pilot.component import SystemApp, ComponentType @@ -15,6 +16,9 @@ from pilot.utils.tracer.base import ( TracerContext, ) from pilot.utils.tracer.span_storage import MemorySpanStorage +from pilot.utils.module_utils import import_from_checked_string + +logger = logging.getLogger(__name__) class DefaultTracer(Tracer): @@ -197,10 +201,11 @@ def initialize_tracer( system_app: SystemApp, tracer_filename: str, root_operation_name: str = "DB-GPT-Web-Entry", + tracer_storage_cls: str = None, ): if not system_app: return - from pilot.utils.tracer.span_storage import FileSpanStorage + from pilot.utils.tracer.span_storage import FileSpanStorage, SpanStorageContainer trace_context_var = ContextVar( "trace_context", @@ -208,7 +213,15 @@ def initialize_tracer( ) tracer = DefaultTracer(system_app) - system_app.register_instance(FileSpanStorage(tracer_filename)) + storage_container = SpanStorageContainer(system_app) + storage_container.append_storage(FileSpanStorage(tracer_filename)) + + if tracer_storage_cls: + logger.info(f"Begin parse storage class {tracer_storage_cls}") + storage = import_from_checked_string(tracer_storage_cls, SpanStorage) + storage_container.append_storage(storage()) + + system_app.register_instance(storage_container) system_app.register_instance(tracer) root_tracer.initialize(system_app, trace_context_var) if system_app.app: From b380761571e1e76794b9e8546f33028a78936fa8 Mon Sep 17 00:00:00 2001 From: FangYin Cheng Date: Mon, 6 Nov 2023 19:55:12 +0800 Subject: [PATCH 53/57] docs: Modify install document --- docker/base/Dockerfile | 4 +- docs/getting_started/install/deploy.rst | 12 +- .../getting_started/install/deploy.po | 569 +++++++++--------- docs/locales/zh_CN/LC_MESSAGES/index.po | 172 +++--- 4 files changed, 394 insertions(+), 363 deletions(-) diff --git a/docker/base/Dockerfile b/docker/base/Dockerfile index 63486e260..e4fad9697 100644 --- a/docker/base/Dockerfile +++ b/docker/base/Dockerfile @@ -28,7 +28,9 @@ WORKDIR /app # RUN pip3 install -i $PIP_INDEX_URL ".[all]" RUN pip3 install --upgrade pip -i $PIP_INDEX_URL \ - && pip3 install -i $PIP_INDEX_URL ".[$DB_GPT_INSTALL_MODEL]" + && pip3 install -i $PIP_INDEX_URL ".[$DB_GPT_INSTALL_MODEL]" \ + # install openai for proxyllm + && pip3 install -i $PIP_INDEX_URL ".[openai]" RUN (if [ "${LANGUAGE}" = "zh" ]; \ # language is zh, download zh_core_web_sm from github diff --git a/docs/getting_started/install/deploy.rst b/docs/getting_started/install/deploy.rst index 4d7d0d211..075a07403 100644 --- a/docs/getting_started/install/deploy.rst +++ b/docs/getting_started/install/deploy.rst @@ -57,6 +57,12 @@ If you are low hardware requirements you can install DB-GPT by Using third-part .. tab:: OpenAI + Installing Dependencies + + .. code-block:: + + pip install -e ".[openai]" + Download embedding model .. code-block:: shell @@ -69,7 +75,7 @@ If you are low hardware requirements you can install DB-GPT by Using third-part or git clone https://huggingface.co/moka-ai/m3e-large - Configure LLM_MODEL and PROXY_API_URL and API_KEY in `.env` file + Configure LLM_MODEL, PROXY_API_URL and API_KEY in `.env` file .. code-block:: shell @@ -291,7 +297,7 @@ If you are low hardware requirements you can install DB-GPT by Using third-part **1. Download a pre-converted model file.** - Suppose you want to use [Vicuna 13B v1.5](https://huggingface.co/lmsys/vicuna-13b-v1.5), you can download the file already converted from [TheBloke/vicuna-13B-v1.5-GGUF](https://huggingface.co/TheBloke/vicuna-13B-v1.5-GGUF), only one file is needed. Download it to the `models` directory and rename it to `ggml-model-q4_0.gguf`. + Suppose you want to use `Vicuna 13B v1.5 `_ , you can download the file already converted from `TheBloke/vicuna-13B-v1.5-GGUF `_ , only one file is needed. Download it to the `models` directory and rename it to `ggml-model-q4_0.gguf`. .. code-block:: @@ -299,7 +305,7 @@ If you are low hardware requirements you can install DB-GPT by Using third-part **2. Convert It Yourself** - You can convert the model file yourself according to the instructions in [llama.cpp#prepare-data--run](https://github.com/ggerganov/llama.cpp#prepare-data--run), and put the converted file in the models directory and rename it to `ggml-model-q4_0.gguf`. + You can convert the model file yourself according to the instructions in `llama.cpp#prepare-data--run `_ , and put the converted file in the models directory and rename it to `ggml-model-q4_0.gguf`. **Installing Dependencies** diff --git a/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po b/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po index 2947c34c8..f4c85b8b4 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po +++ b/docs/locales/zh_CN/LC_MESSAGES/getting_started/install/deploy.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 👏👏 0.4.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-04 15:08+0800\n" +"POT-Creation-Date: 2023-11-06 19:38+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -19,27 +19,27 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.12.1\n" -#: ../../getting_started/install/deploy.rst:4 bb7e1a7b70624a3d91804c5ce2d5216b +#: ../../getting_started/install/deploy.rst:4 f3ea3305f122460aaa11999edc4b5de6 msgid "Installation From Source" msgstr "源码安装" -#: ../../getting_started/install/deploy.rst:6 7524477e8b8a456b8e2b942621a6b225 +#: ../../getting_started/install/deploy.rst:6 bb941f2bd56d4eb48f7c4f75ebd74176 msgid "To get started, install DB-GPT with the following steps." msgstr "按照以下步骤进行安装" -#: ../../getting_started/install/deploy.rst:10 871cdb0a7e004668b518168461d76945 +#: ../../getting_started/install/deploy.rst:10 27a1e092c1f945ceb9946ebdaf89b600 msgid "1.Preparation" msgstr "1.准备" -#: ../../getting_started/install/deploy.rst:11 d845f48ec05a4bb7a5b0f95a0644029d +#: ../../getting_started/install/deploy.rst:11 5c5bfbdc74a14c3b9b1f1ed66617cac8 msgid "**Download DB-GPT**" msgstr "**下载DB-GPT项目**" -#: ../../getting_started/install/deploy.rst:17 85df7bb2b73141058ba0ca5a73e46701 +#: ../../getting_started/install/deploy.rst:17 3065ee2f34f9417598a37fd699a4863e msgid "**Install Miniconda**" msgstr "**安装Miniconda**" -#: ../../getting_started/install/deploy.rst:19 b7b3e120ded344d09fb2d7a3a7903497 +#: ../../getting_started/install/deploy.rst:19 f9f3a653ffb8447284686aa37a7bb79a msgid "" "We use Sqlite as default database, so there is no need for database " "installation. If you choose to connect to other databases, you can " @@ -50,386 +50,397 @@ msgid "" "`_" msgstr "" "目前使用Sqlite作为默认数据库,因此DB-" -"GPT快速部署不需要部署相关数据库服务。如果你想使用其他数据库,需要先部署相关数据库服务。我们目前使用Miniconda进行python环境和包依赖管理[安装" -" Miniconda](https://docs.conda.io/en/latest/miniconda.html)" +"GPT快速部署不需要部署相关数据库服务。如果你想使用其他数据库,需要先部署相关数据库服务。我们目前使用Miniconda进行python环境和包依赖管理。`如何安装" +" Miniconda `_ 。" -#: ../../getting_started/install/deploy.rst:36 a5e34db6a6b8450c8a1f35377a1dc93b +#: ../../getting_started/install/deploy.rst:36 a2cd2fdd1d16421f9cbe341040b153b6 msgid "2.Deploy LLM Service" msgstr "2.部署LLM服务" -#: ../../getting_started/install/deploy.rst:37 5c49829b086e4d5fbcb5a971a34fa3b5 +#: ../../getting_started/install/deploy.rst:37 180a121e3c994a92a917ace80bf12386 msgid "" "DB-GPT can be deployed on servers with low hardware requirements or on " "servers with high hardware requirements." msgstr "DB-GPT可以部署在对硬件要求不高的服务器,也可以部署在对硬件要求高的服务器" -#: ../../getting_started/install/deploy.rst:39 7c2f7e2b49054d17850942bef9570c45 +#: ../../getting_started/install/deploy.rst:39 395608515c0348d5849030b58da7b659 msgid "" "If you are low hardware requirements you can install DB-GPT by Using " "third-part LLM REST API Service OpenAI, Azure, tongyi." -msgstr "Low hardware requirements模式适用于对接第三方模型服务的api,比如OpenAI, 通义千问, 文心.cpp。" +msgstr "低硬件要求模式适用于对接第三方模型服务的 API,比如 OpenAI、通义千问、 文心一言等。" -#: ../../getting_started/install/deploy.rst:43 8c392e63073a47698e38456c5994ff25 +#: ../../getting_started/install/deploy.rst:43 e29297e61e2e4d05ba88f0e1c2b1f365 msgid "As our project has the ability to achieve OpenAI performance of over 85%," msgstr "使用OpenAI服务可以让DB-GPT准确率达到85%" -#: ../../getting_started/install/deploy.rst:48 148f8d85c02345219ac535003fe05fca +#: ../../getting_started/install/deploy.rst:48 d0d70d51e8684c2891c58a6da4941a52 msgid "Notice make sure you have install git-lfs" msgstr "确认是否已经安装git-lfs" -#: ../../getting_started/install/deploy.rst:50 7f719273d1ff4d888376030531a560c4 +#: ../../getting_started/install/deploy.rst:50 0d2781fd38eb467ebad2a3c310a344e6 msgid "centos:yum install git-lfs" msgstr "" -#: ../../getting_started/install/deploy.rst:52 f5c2035bca214e3fbef2b70be0e76247 +#: ../../getting_started/install/deploy.rst:52 1574ea24ad6443409070aa3a1f7abe87 msgid "ubuntu:apt-get install git-lfs" msgstr "" -#: ../../getting_started/install/deploy.rst:54 cb1b52b9323e4e9fbccfd3c42067a568 +#: ../../getting_started/install/deploy.rst:54 ad86473d5c87447091c713f45cbfed0e msgid "macos:brew install git-lfs" msgstr "" #: ../../getting_started/install/deploy.rst:58 -#: ../../getting_started/install/deploy.rst:223 -#: 9c601ee0c06646d58cbd2c2fff342cb5 d3fe6c712b4145d0856487c65057c2a0 +#: ../../getting_started/install/deploy.rst:229 +#: 3dd1e40f33924faab63634907a7f6511 dce32420face4ab2b99caf7f3900ede9 msgid "OpenAI" msgstr "OpenAI" -#: ../../getting_started/install/deploy.rst:60 -#: ../../getting_started/install/deploy.rst:207 -#: 5e0e84bd11084d158e18b702022aaa96 6a9c9830e5184eac8b6b7425780f4a3e +#: ../../getting_started/install/deploy.rst:60 1f66400540114de2820761ef80137805 +msgid "Installing Dependencies" +msgstr "安装依赖" + +#: ../../getting_started/install/deploy.rst:66 +#: ../../getting_started/install/deploy.rst:213 +#: 31b856a6fc094334a37914c046cb1bb1 42b2f6d36ca4487f8e31d59bba123fca msgid "Download embedding model" -msgstr "下载embedding model" +msgstr "下载 embedding 模型" -#: ../../getting_started/install/deploy.rst:72 -#: ../../getting_started/install/deploy.rst:231 -#: 953d6931627641b985588abf8b6ad9fd d52e287164ca44f79709f4645a1bb774 -msgid "Configure LLM_MODEL and PROXY_API_URL and API_KEY in `.env` file" -msgstr "在`.env`文件设置LLM_MODEL and PROXY_API_URL and API_KEY" +#: ../../getting_started/install/deploy.rst:78 f970fb69e47c40d7bda381ec6f045829 +msgid "Configure LLM_MODEL, PROXY_API_URL and API_KEY in `.env` file" +msgstr "在 `.env` 文件中设置 LLM_MODEL、PROXY_API_URL 和 API_KEY" -#: ../../getting_started/install/deploy.rst:82 -#: ../../getting_started/install/deploy.rst:282 -#: 6dc89616c0bf46a898a49606d1349039 e30b7458fc0d46e8bcf0ec61a2be2e19 +#: ../../getting_started/install/deploy.rst:88 +#: ../../getting_started/install/deploy.rst:288 +#: 6ca04c88fc60480db2ebdc9b234a0bbb 709cfe74c45c4eff83a7d77bb30b4a2b msgid "Make sure your .env configuration is not overwritten" -msgstr "认.env文件不会被覆盖\"" +msgstr "确保你的 .env 文件不会被覆盖" -#: ../../getting_started/install/deploy.rst:85 7adce7ac878d4b1ab9249d840d302520 +#: ../../getting_started/install/deploy.rst:91 147aea0d753f44588f4a0c56002334ab msgid "Vicuna" msgstr "Vicuna" -#: ../../getting_started/install/deploy.rst:86 44a32c4cd0b140838b49f739d68ff42d +#: ../../getting_started/install/deploy.rst:92 6a0bd60c4ca2478cb0f3d85aff70cd3b msgid "" "`Vicuna-v1.5 `_ based on " "llama-2 has been released, we recommend you set `LLM_MODEL=vicuna-" "13b-v1.5` to try this model)" msgstr "" +"基于 llama-2 的模型 `Vicuna-v1.5 `_ 已经发布,我们推荐你通过配置 `LLM_MODEL=vicuna-13b-v1.5` 来尝试这个模型" -#: ../../getting_started/install/deploy.rst:88 f4991de79c434961b0ee777cf42dc491 +#: ../../getting_started/install/deploy.rst:94 6a111c2ef31f41d4b737cf8b6f36fb16 msgid "vicuna-v1.5 hardware requirements" -msgstr "" +msgstr "vicuna-v1.5 的硬件要求" -#: ../../getting_started/install/deploy.rst:92 -#: ../../getting_started/install/deploy.rst:137 -#: 596405ba21d046c993c18d0bcaf95048 ca993a5f1b194707bbe3d5d6e9d670d8 +#: ../../getting_started/install/deploy.rst:98 +#: ../../getting_started/install/deploy.rst:143 +#: dc24c0238ce141df8bdce26cc0e2ddbb e04f1ea4b36940f3a28b66cdff7b702e msgid "Model" -msgstr "" - -#: ../../getting_started/install/deploy.rst:93 -#: ../../getting_started/install/deploy.rst:138 -#: 8437bb47daa94ca8a43b0eadc1286842 d040d964198d4c95afa6dd0d86586cc2 -msgid "Quantize" -msgstr "" - -#: ../../getting_started/install/deploy.rst:94 -#: ../../getting_started/install/deploy.rst:139 -#: 453bc4416d89421699d90d940498b9ac 5de996bb955f4c6ca8d5651985ced255 -msgid "VRAM Size" -msgstr "" - -#: ../../getting_started/install/deploy.rst:95 -#: ../../getting_started/install/deploy.rst:98 077d52b8588e4ddd956acb7ff86bc458 -#: fcf0ca75422343d19b12502fb7746f08 -msgid "vicuna-7b-v1.5" -msgstr "" - -#: ../../getting_started/install/deploy.rst:96 -#: ../../getting_started/install/deploy.rst:102 -#: ../../getting_started/install/deploy.rst:141 -#: ../../getting_started/install/deploy.rst:147 -#: 799b310b76454f79a261300253a9bb75 bd98df81ec8941b69c7d1de107154b1b -#: ca71731754f545d589e506cb53e6f042 d4023553e4384cc4955ef5bf4dc4d05b -msgid "4-bit" -msgstr "" - -#: ../../getting_started/install/deploy.rst:97 -#: ../../getting_started/install/deploy.rst:142 -#: adfc22d9c6394046bb632831a4a3b066 e4e7762c714a49828da630a5f9d641dc -msgid "8 GB" -msgstr "" +msgstr "模型" #: ../../getting_started/install/deploy.rst:99 -#: ../../getting_started/install/deploy.rst:105 #: ../../getting_started/install/deploy.rst:144 -#: ../../getting_started/install/deploy.rst:150 -#: 0d6bd1c4a6464df38723de978c09e8bc 106e20f7727f43d280b7560dc0f19bbc -#: 5a95691d1d134638bffa478daf2577a0 f8add03506244306b1ac6e10c5a2bc1f -msgid "8-bit" -msgstr "" +#: b6473e65ca1a437a84226531be4da26d e0a2f7580685480aa13ca462418764d3 +msgid "Quantize" +msgstr "量化" #: ../../getting_started/install/deploy.rst:100 -#: ../../getting_started/install/deploy.rst:103 #: ../../getting_started/install/deploy.rst:145 -#: ../../getting_started/install/deploy.rst:148 -#: 03222e6a682e406bb56c21025412fbe5 2eb88af3efb74fb79899d7818a79d177 -#: 9705b9d7d2084f0b8867f6aeec66251b bca6e5151e244a318f4c2078c3f82118 -msgid "12 GB" -msgstr "" +#: 56471c3b174d4adf9e8cb5bebaa300a6 d82297b8b9c148c3906d8ee4ed10d8a0 +msgid "VRAM Size" +msgstr "显存" #: ../../getting_started/install/deploy.rst:101 #: ../../getting_started/install/deploy.rst:104 -#: 1596cbb77c954d1db00e2fa283d66a9a c6e8dc1600d14ee5a47f45f75ec709f4 -msgid "vicuna-13b-v1.5" +#: 1214432602fe47a28479ce3e21a7d88b 51838e72e42248f199653f1bf08c8155 +msgid "vicuna-7b-v1.5" +msgstr "" + +#: ../../getting_started/install/deploy.rst:102 +#: ../../getting_started/install/deploy.rst:108 +#: ../../getting_started/install/deploy.rst:147 +#: ../../getting_started/install/deploy.rst:153 +#: a64439f4e6f64c42bb76fbb819556784 ed95f498641e4a0f976318df608a1d67 +#: fc400814509048b4a1cbe1e07c539285 ff7a8cb2cce8438cb6cb0d80dabfc2b5 +msgid "4-bit" +msgstr "" + +#: ../../getting_started/install/deploy.rst:103 +#: ../../getting_started/install/deploy.rst:148 +#: 2726e8a278c34e6db59147e9f66f2436 5feab5755a41403c9d641da697de4651 +msgid "8 GB" +msgstr "" + +#: ../../getting_started/install/deploy.rst:105 +#: ../../getting_started/install/deploy.rst:111 +#: ../../getting_started/install/deploy.rst:150 +#: ../../getting_started/install/deploy.rst:156 +#: 1984406682da4da3ad7b275e44085d07 2f027d838d0c46409e54c066d7983aae +#: 5c5878fe64944872b6769f075fedca05 e2507408a9c5423988e17b7029b487e4 +msgid "8-bit" msgstr "" #: ../../getting_started/install/deploy.rst:106 +#: ../../getting_started/install/deploy.rst:109 #: ../../getting_started/install/deploy.rst:151 -#: 00ee98593b7f4b29b5d97fa5a323bfa1 0169214dcf8d46c791b3482c81283fa0 +#: ../../getting_started/install/deploy.rst:154 +#: 332f50702c7b46e79ea0af5cbf86c6d5 381d23253cfd40109bacefca6a179f91 +#: aafe2423c25546e789e4804e3fd91d1d cc56990a58e941d6ba023cbd4dca0357 +msgid "12 GB" +msgstr "" + +#: ../../getting_started/install/deploy.rst:107 +#: ../../getting_started/install/deploy.rst:110 +#: 1f14e2fa6d41493cb208f55eddff9773 6457f6307d8546beb5f2fb69c30922d8 +msgid "vicuna-13b-v1.5" +msgstr "" + +#: ../../getting_started/install/deploy.rst:112 +#: ../../getting_started/install/deploy.rst:157 +#: e24d3a36b5ce4cfe861dce2d1c4db592 f2e66b2da7954aaab0ee526b25a371f5 msgid "20 GB" msgstr "" -#: ../../getting_started/install/deploy.rst:122 -#: ../../getting_started/install/deploy.rst:169 -#: ../../getting_started/install/deploy.rst:195 -#: 852f800e380c44d3b1b5bdaa881406b7 89ddd6c4a4874f4f8b7f051d797e364a -#: a2b4436f8fcb44ada3b5bf5c1099e646 +#: ../../getting_started/install/deploy.rst:128 +#: ../../getting_started/install/deploy.rst:175 +#: ../../getting_started/install/deploy.rst:201 +#: 1719c11f92874c47a87c00c634b9fad8 4596fcbe415d42fdbb29b92964fae070 +#: e639ae6076a64b7b9de08527966e4550 msgid "The model files are large and will take a long time to download." -msgstr "" +msgstr "这个模型权重文件比较大,需要花费较长时间来下载。" -#: ../../getting_started/install/deploy.rst:124 -#: ../../getting_started/install/deploy.rst:171 -#: ../../getting_started/install/deploy.rst:197 -#: 18ccf7acdf3045588a19866c0161f44b 3d3d93649ec943c8b2b725807e969cbf -#: 6205975466f54d8fbf8e30b58df6b9c2 +#: ../../getting_started/install/deploy.rst:130 +#: ../../getting_started/install/deploy.rst:177 +#: ../../getting_started/install/deploy.rst:203 +#: 4ec1492d389f403ebd9dd805fcaac68e ac6c68e2bf9b47c694ea8e0506014b10 +#: e39be72282e64760903aaba45f8effb8 msgid "**Configure LLM_MODEL in `.env` file**" -msgstr "" +msgstr "**在 `.env` 文件中配置 LLM_MODEL**" -#: ../../getting_started/install/deploy.rst:131 -#: ../../getting_started/install/deploy.rst:228 -#: 022addaea4ea432584b8a27ea83a9dc4 7a95d25c58d2491e855dff42f6d3a686 +#: ../../getting_started/install/deploy.rst:137 +#: ../../getting_started/install/deploy.rst:234 +#: 7ce4e2253ef24a7ea890ade04ce36682 b9d5bf4fa09649c4a098503132ce7c0c msgid "Baichuan" -msgstr "" +msgstr "百川" -#: ../../getting_started/install/deploy.rst:133 -#: b5374f6d0ca44ee9bd984c0198515861 +#: ../../getting_started/install/deploy.rst:139 +#: ffdad6a70558457fa825bad4d811100d msgid "Baichuan hardware requirements" -msgstr "" - -#: ../../getting_started/install/deploy.rst:140 -#: ../../getting_started/install/deploy.rst:143 -#: 6a5e6034c185455d81e8ba5349dbc191 9d0109817c524747909417924bb0bd31 -msgid "baichuan-7b" -msgstr "" +msgstr "百川 的硬件要求" #: ../../getting_started/install/deploy.rst:146 #: ../../getting_started/install/deploy.rst:149 -#: b3300ed57f0c4ed98816652ea4a5c3c8 d57e98b46fb14f649d6ac8df27edcfd8 +#: 59d9b64f54d34971a68e93e3101def06 a66ce354d8f143ce920303241cd8947e +msgid "baichuan-7b" +msgstr "" + +#: ../../getting_started/install/deploy.rst:152 +#: ../../getting_started/install/deploy.rst:155 +#: c530662259ca4ec5b03a18e4b690e17a fa3af65ecca54daab961f55729bbc40e msgid "baichuan-13b" msgstr "" -#: ../../getting_started/install/deploy.rst:173 -#: ac684ccbea7d4f5380c43ad02a1b7231 +#: ../../getting_started/install/deploy.rst:179 +#: efd73637994a4b7c97ef3557e1f3161c msgid "please rename Baichuan path to \"baichuan2-13b\" or \"baichuan2-7b\"" msgstr "将Baichuan模型目录修改为\"baichuan2-13b\" 或 \"baichuan2-7b\"" -#: ../../getting_started/install/deploy.rst:179 -#: d2e283112ed1440b93510c331922b37c +#: ../../getting_started/install/deploy.rst:185 +#: 435a3f0d0fe84b49a7305e2c0f51a5df msgid "ChatGLM" msgstr "" -#: ../../getting_started/install/deploy.rst:199 -#: ae30d065461e446e86b02d3903108a02 -msgid "please rename chatglm model path to \"chatglm2-6b\"" -msgstr "将chatglm模型目录修改为\"chatglm2-6b\"" - #: ../../getting_started/install/deploy.rst:205 -#: 81a8983e89c4400abc20080c86865c02 +#: 165e23d3d40d4756b5a6a2580d015213 +msgid "please rename chatglm model path to \"chatglm2-6b\"" +msgstr "将 chatglm 模型目录修改为\"chatglm2-6b\"" + +#: ../../getting_started/install/deploy.rst:211 +#: b651ebb5e0424b8992bc8b49d2280bee msgid "Other LLM API" -msgstr "" +msgstr "其它模型 API" -#: ../../getting_started/install/deploy.rst:219 -#: 3df3d5e0e4f64813a7ca2adccd056c4a +#: ../../getting_started/install/deploy.rst:225 +#: 4eabdc25f4a34676b3ece620c88d866f msgid "Now DB-GPT support LLM REST API TYPE:" -msgstr "目前DB-GPT支持的大模型REST API类型:" +msgstr "目前DB-GPT支持的大模型 REST API 类型:" -#: ../../getting_started/install/deploy.rst:224 -#: 4f7cb7a3f324410d8a34ba96d7c9536a +#: ../../getting_started/install/deploy.rst:230 +#: d361963cc3404e5ca55a823f1f1f545c msgid "Azure" msgstr "" -#: ../../getting_started/install/deploy.rst:225 -#: ee6cbe48a8094637b6b8a049446042c6 +#: ../../getting_started/install/deploy.rst:231 +#: 3b0f17c74aaa4bbd9db935973fa1c36b msgid "Aliyun tongyi" msgstr "" -#: ../../getting_started/install/deploy.rst:226 -#: a3d9c061b0f440258be88cc3143b1887 +#: ../../getting_started/install/deploy.rst:232 +#: 7c4c457a499943b8804e31046551006d msgid "Baidu wenxin" msgstr "" -#: ../../getting_started/install/deploy.rst:227 -#: 176001fb6eaf448f9eca1abd256b3ef4 +#: ../../getting_started/install/deploy.rst:233 +#: ac1880a995184295acf07fff987d7c56 msgid "Zhipu" msgstr "" -#: ../../getting_started/install/deploy.rst:229 -#: 17fecc140be2474ea1566d44641a27c0 +#: ../../getting_started/install/deploy.rst:235 +#: 6927500d7d3445b7b1981da1df4e1666 msgid "Bard" msgstr "" -#: ../../getting_started/install/deploy.rst:284 -#: bc34832cec754984a40c4d01526f0f83 +#: ../../getting_started/install/deploy.rst:237 +#: 419d564de18c485780d9336b852735b6 +msgid "Configure LLM_MODEL and PROXY_API_URL and API_KEY in `.env` file" +msgstr "在`.env`文件设置 LLM_MODEL、PROXY_API_URL和 API_KEY" + +#: ../../getting_started/install/deploy.rst:290 +#: 71d5203682e24e2e896e4b9913471f78 msgid "llama.cpp" msgstr "" -#: ../../getting_started/install/deploy.rst:286 -#: aa4b14e726dc447f92dec48f38a3d770 +#: ../../getting_started/install/deploy.rst:292 +#: 36a2b82f711a4c0f9491aca9c84d3c91 msgid "" "DB-GPT already supports `llama.cpp " "`_ via `llama-cpp-python " "`_ ." msgstr "" -"DB-GPT 已经支持了 `llama.cpp `_ via " -"`llama-cpp-python `_ ." +"DB-GPT 已经通过 `llama-cpp-python `_ 支持了 `llama.cpp `_ 。" -#: ../../getting_started/install/deploy.rst:288 -#: e97a868ad05b48ee8d25017457c1b7ee +#: ../../getting_started/install/deploy.rst:294 +#: 439064115dca4ae08d8e60041f2ffe17 msgid "**Preparing Model Files**" -msgstr "**准备Model文件**" +msgstr "**准备模型文件**" -#: ../../getting_started/install/deploy.rst:290 -#: 8efc7824082545a4a98ebbd6b12fa00f +#: ../../getting_started/install/deploy.rst:296 +#: 7291d6fa20b34942926e7765c01f25c9 msgid "" "To use llama.cpp, you need to prepare a gguf format model file, and there" " are two common ways to obtain it, you can choose either:" -msgstr "使用 llama.cpp,你需要准备 gguf 格式的文件,你可以通过以下两种方法获取" +msgstr "为了使用 llama.cpp,你需要准备 gguf 格式的文件,你可以通过以下两种方法获取" -#: ../../getting_started/install/deploy.rst:292 -#: 5b9f3a35779c4f89a4b9051904c5f7d8 +#: ../../getting_started/install/deploy.rst:298 +#: 45752f3f5dd847469da0c5edddc530fa msgid "**1. Download a pre-converted model file.**" msgstr "**1.下载已转换的模型文件.**" -#: ../../getting_started/install/deploy.rst:294 -#: e15f33a2e5fc4caaa9ad2e10cabf9d32 +#: ../../getting_started/install/deploy.rst:300 +#: c451db2157ff49b2b4992aed9907ddfa msgid "" -"Suppose you want to use [Vicuna 13B v1.5](https://huggingface.co/lmsys" -"/vicuna-13b-v1.5), you can download the file already converted from " -"[TheBloke/vicuna-13B-v1.5-GGUF](https://huggingface.co/TheBloke/vicuna-" -"13B-v1.5-GGUF), only one file is needed. Download it to the `models` " +"Suppose you want to use `Vicuna 13B v1.5 `_ , you can download the file already converted from " +"`TheBloke/vicuna-13B-v1.5-GGUF `_ , only one file is needed. Download it to the `models` " "directory and rename it to `ggml-model-q4_0.gguf`." msgstr "" -"假设您想使用[Vicuna 13B v1.5](https://huggingface.co/lmsys/vicuna-" -"13b-v1.5)您可以从[TheBloke/vicuna-" -"13B-v1.5-GGUF](https://huggingface.co/TheBloke/vicuna-" -"13B-v1.5-GGUF)下载已转换的文件,只需要一个文件。将其下载到models目录并将其重命名为 `ggml-" +"假设您想使用 `Vicuna 13B v1.5 `_ 您可以从 `TheBloke/vicuna-" +"13B-v1.5-GGUF `_ 下载已转换的文件,只需要一个文件。将其下载到models目录并将其重命名为 `ggml-" "model-q4_0.gguf`。" -#: ../../getting_started/install/deploy.rst:300 -#: 81ab603cd9b94cabb48add9541590b8b +#: ../../getting_started/install/deploy.rst:306 +#: f5b92b51622b43d398b3dc13a5892c29 msgid "**2. Convert It Yourself**" msgstr "**2. 自行转换**" -#: ../../getting_started/install/deploy.rst:302 -#: f9b46aa70a0842d6acc7e837c8b27778 +#: ../../getting_started/install/deploy.rst:308 +#: 8838ae6dcecf44ecad3fd963980c8eb3 msgid "" "You can convert the model file yourself according to the instructions in " -"[llama.cpp#prepare-data--run](https://github.com/ggerganov/llama.cpp" -"#prepare-data--run), and put the converted file in the models directory " -"and rename it to `ggml-model-q4_0.gguf`." +"`llama.cpp#prepare-data--run `_ , and put the converted file in the models " +"directory and rename it to `ggml-model-q4_0.gguf`." msgstr "" -"您可以根据[llama.cpp#prepare-data--run](https://github.com/ggerganov/llama.cpp" -"#prepare-data--run)中的说明自行转换模型文件,并把转换后的文件放在models目录中,并重命名为`ggml-" +"您可以根据 `llama.cpp#prepare-data--run `_ 中的说明自行转换模型文件,并把转换后的文件放在models目录中,并重命名为`ggml-" "model-q4_0.gguf`。" -#: ../../getting_started/install/deploy.rst:304 -#: 5278c05568dd4ad688bcc181e45caa18 +#: ../../getting_started/install/deploy.rst:310 +#: 3fe28d6e5eaa4bdf9c5c44a914c3577c msgid "**Installing Dependencies**" msgstr "**安装依赖**" -#: ../../getting_started/install/deploy.rst:306 -#: bd67bf651a9a4096a37e73851b5fad98 +#: ../../getting_started/install/deploy.rst:312 +#: bdc10d2e88cc4c3f84a8c4a8dc2037a9 msgid "" "llama.cpp is an optional dependency in DB-GPT, and you can manually " "install it using the following command:" msgstr "llama.cpp在DB-GPT中是可选安装项, 你可以通过以下命令进行安装" -#: ../../getting_started/install/deploy.rst:313 -#: 71ed6ae4d0aa4d3ca27ebfffc42a5095 +#: ../../getting_started/install/deploy.rst:319 +#: 9c136493448b43b5b27f66af74ff721e msgid "**3.Modifying the Configuration File**" msgstr "**3.修改配置文件**" -#: ../../getting_started/install/deploy.rst:315 -#: a0a2fdb799524ef4938df2c306536e2a +#: ../../getting_started/install/deploy.rst:321 +#: c835a7dee1dd409fb861e7b886c6dc5b msgid "Next, you can directly modify your `.env` file to enable llama.cpp." msgstr "修改`.env`文件使用llama.cpp" -#: ../../getting_started/install/deploy.rst:322 -#: ../../getting_started/install/deploy.rst:390 -#: 03694cbb7dfa432cb32116925357f008 +#: ../../getting_started/install/deploy.rst:328 +#: ../../getting_started/install/deploy.rst:396 +#: 296e6d08409544918fee0c31b1bf195c a81e5d882faf4722b0e10d53f635f53c msgid "" "Then you can run it according to `Run `_" msgstr "" -"然后你可以根据[运行](https://db-gpt.readthedocs.io/projects/db-gpt-docs-zh-" -"cn/zh_CN/latest/getting_started/install/deploy/deploy.html#run)来运行" +"然后你可以根据 `运行 `_ 来运行。" -#: ../../getting_started/install/deploy.rst:325 -#: c9bbc15ea2fc4562bdf87a4e099600a0 +#: ../../getting_started/install/deploy.rst:331 +#: 0f7f487ee11a4e01a95f7c504f0469ba msgid "**More Configurations**" msgstr "**更多配置文件**" -#: ../../getting_started/install/deploy.rst:327 -#: 9beff887d8554d1dac169de93625c1b2 +#: ../../getting_started/install/deploy.rst:333 +#: b0f9964497f64fb5b3740099232cd72b msgid "" "In DB-GPT, the model configuration can be done through `{model " "name}_{config key}`." msgstr "在DB-GPT中,模型配置可以通过`{模型名称}_{配置名}` 来配置。" -#: ../../getting_started/install/deploy.rst:329 -#: 6cad64bcc9f141de85479203b21f7f9e +#: ../../getting_started/install/deploy.rst:335 +#: 7c225de4fe9d4dd3a3c2b2a33802e656 msgid "More Configurations" msgstr "**更多配置文件**" -#: ../../getting_started/install/deploy.rst:333 -#: de97b0d5b59c4bfabbd47b7e1766cc70 +#: ../../getting_started/install/deploy.rst:339 +#: 5cc1671910314796a9ce0b5107d3c9fe msgid "Environment Variable Key" msgstr "环境变量Key" -#: ../../getting_started/install/deploy.rst:334 -#: 76afa3655f644576b54b4422bad3fcad +#: ../../getting_started/install/deploy.rst:340 +#: 4359ed4e11bb47ad89a605cbf9016cd5 msgid "Default" msgstr "默认值" -#: ../../getting_started/install/deploy.rst:335 -#: 0dcabfeeb4874e08ba53d4b4aa6a1d73 +#: ../../getting_started/install/deploy.rst:341 +#: 5cf0efc6d1014665bb9dbdae96bf2726 msgid "Description" msgstr "描述" -#: ../../getting_started/install/deploy.rst:336 -#: c1670aec27cf4c068d825456817d7667 +#: ../../getting_started/install/deploy.rst:342 +#: e7c291f80a9a40fa90d642901eca02c6 msgid "llama_cpp_prompt_template" msgstr "" -#: ../../getting_started/install/deploy.rst:337 -#: ../../getting_started/install/deploy.rst:340 +#: ../../getting_started/install/deploy.rst:343 #: ../../getting_started/install/deploy.rst:346 #: ../../getting_started/install/deploy.rst:352 #: ../../getting_started/install/deploy.rst:358 -#: 49c8f875066f49c6aac195805f88e4a9 +#: ../../getting_started/install/deploy.rst:364 +#: 07dc7fc4e51e4d9faf8e5221bcf03ee0 549f3c57a2e9427880e457e653ce1182 +#: 7ad961957f7b49d08e4aff347749b78d c1eab368175c4fa88fe0b471919523b2 +#: e2e0bf9903484972b6d20e6837010029 msgid "None" msgstr "" -#: ../../getting_started/install/deploy.rst:338 -#: bb31e19533e5434b832d5975bf579dc3 +#: ../../getting_started/install/deploy.rst:344 +#: 6b5044a2009f432c92fcd65db42506d8 msgid "" "Prompt template name, now support: zero_shot, vicuna_v1.1,alpaca,llama-2" ",baichuan-chat,internlm-chat, If None, the prompt template is " @@ -438,183 +449,183 @@ msgstr "" "Prompt template 现在可以支持`zero_shot, vicuna_v1.1,alpaca,llama-2,baichuan-" "chat,internlm-chat`, 如果是None, 可以根据模型路径来自动获取模型 Prompt template" -#: ../../getting_started/install/deploy.rst:339 -#: 38ed23e19e2a47cf8fbacb035cfe1292 +#: ../../getting_started/install/deploy.rst:345 +#: e01c860441ad43b88c0a8d012f97d2d8 msgid "llama_cpp_model_path" msgstr "" -#: ../../getting_started/install/deploy.rst:341 -#: eb069fdfdfeb4b17b723ee6733ba50c2 +#: ../../getting_started/install/deploy.rst:347 +#: 1cb68d772e454812a1a0c6de4950b8ce msgid "Model path" msgstr "模型路径" -#: ../../getting_started/install/deploy.rst:342 -#: 348d3ff3e4f44ceb99aadead11f5cca5 +#: ../../getting_started/install/deploy.rst:348 +#: 6dac03820edb4fbd8a0856405e84c5bc msgid "llama_cpp_n_gpu_layers" msgstr "" -#: ../../getting_started/install/deploy.rst:343 -#: 007deecf593b4553b6ca8df3e9240a28 +#: ../../getting_started/install/deploy.rst:349 +#: 8cd5607b7941427f9a342ca7a00e5778 msgid "1000000000" msgstr "" -#: ../../getting_started/install/deploy.rst:344 -#: 4da435c417f0482581895bf4d052a6a1 +#: ../../getting_started/install/deploy.rst:350 +#: 61c9297656da434aa7ac2b49cf61ea9d msgid "" "Number of layers to offload to the GPU, Set this to 1000000000 to offload" " all layers to the GPU. If your GPU VRAM is not enough, you can set a low" " number, eg: 10" msgstr "要将多少网络层转移到GPU上,将其设置为1000000000以将所有层转移到GPU上。如果您的 GPU 内存不足,可以设置较低的数字,例如:10。" -#: ../../getting_started/install/deploy.rst:345 -#: 4f186505ea81467590cf817d116e6879 +#: ../../getting_started/install/deploy.rst:351 +#: 8c2d2182557a483aa2fda590c24faaf3 msgid "llama_cpp_n_threads" msgstr "" -#: ../../getting_started/install/deploy.rst:347 -#: b94dc2fb2cd14a4a8f38ba95b05fbb5b +#: ../../getting_started/install/deploy.rst:353 +#: cc442f61ffc442ecbd98c1e7f5598e1a msgid "" "Number of threads to use. If None, the number of threads is automatically" " determined" msgstr "要使用的线程数量。如果为None,则线程数量将自动确定。" -#: ../../getting_started/install/deploy.rst:348 -#: 867f2357430440eba4e749a8a39bff18 +#: ../../getting_started/install/deploy.rst:354 +#: 8d5e917d86f048348106e6923638a0c2 msgid "llama_cpp_n_batch" msgstr "" -#: ../../getting_started/install/deploy.rst:349 -#: 78516f7b23264147bae11e13426097eb +#: ../../getting_started/install/deploy.rst:355 +#: ee2719a0a8cd4a77846cffd8e675638f msgid "512" msgstr "" -#: ../../getting_started/install/deploy.rst:350 -#: c2ec97ffef3e4a70afef6634e78801a2 +#: ../../getting_started/install/deploy.rst:356 +#: 845b354315384762a611ad2daa539d57 msgid "Maximum number of prompt tokens to batch together when calling llama_eval" msgstr "在调用llama_eval时,批处理在一起的prompt tokens的最大数量" -#: ../../getting_started/install/deploy.rst:351 -#: 29ad3c5ab7134da49d6fca3b42d734d6 +#: ../../getting_started/install/deploy.rst:357 +#: a95e788bfa5f46f3bcd6356dfd9f87eb msgid "llama_cpp_n_gqa" msgstr "" -#: ../../getting_started/install/deploy.rst:353 -#: e5bc322b0c824465b1adbd162838a3b7 +#: ../../getting_started/install/deploy.rst:359 +#: 23ad9b5f34b5440bb90b2b21bab25763 msgid "Grouped-query attention. Must be 8 for llama-2 70b." msgstr "对于 llama-2 70B 模型,Grouped-query attention 必须为8。" -#: ../../getting_started/install/deploy.rst:354 -#: 43e7d412238a4f0ba8227938d9fa4172 +#: ../../getting_started/install/deploy.rst:360 +#: 9ce25b7966fc40ec8be47ecfaf5f9994 msgid "llama_cpp_rms_norm_eps" msgstr "" -#: ../../getting_started/install/deploy.rst:355 -#: 6328db04645b4b089593291e2ca13f79 +#: ../../getting_started/install/deploy.rst:361 +#: 58365f0d36af447ba976213646018431 msgid "5e-06" msgstr "" -#: ../../getting_started/install/deploy.rst:356 -#: 6c8bf631cece42fa86954f5cf2d75503 +#: ../../getting_started/install/deploy.rst:362 +#: d00b742a759140b795ba5949f1ce9a36 msgid "5e-6 is a good value for llama-2 models." msgstr "对于llama-2模型来说,5e-6是一个不错的值。" -#: ../../getting_started/install/deploy.rst:357 -#: 22ebee39fe8b4cc18378447cac67e631 +#: ../../getting_started/install/deploy.rst:363 +#: b9972e9b19354f55a5e6d9c50513a620 msgid "llama_cpp_cache_capacity" msgstr "" -#: ../../getting_started/install/deploy.rst:359 -#: 4dc98bede90f4237829f65513e4adf61 +#: ../../getting_started/install/deploy.rst:365 +#: 3c98c5396dd74db8b6d70fc50fa0754f msgid "Maximum cache capacity. Examples: 2000MiB, 2GiB" msgstr "模型缓存最大值. 例如: 2000MiB, 2GiB" -#: ../../getting_started/install/deploy.rst:360 -#: bead617b5af943dab0bc1209823d3c22 +#: ../../getting_started/install/deploy.rst:366 +#: 4277e155992c4442b69d665d6269bed6 msgid "llama_cpp_prefer_cpu" msgstr "" -#: ../../getting_started/install/deploy.rst:361 -#: 8efb44f1cfc54b1a8b3ca8ea138113ee +#: ../../getting_started/install/deploy.rst:367 +#: 049169c1210a4ecabb25702ed813ea0a msgid "False" msgstr "" -#: ../../getting_started/install/deploy.rst:362 -#: b854e6a44c8348ceb72ac382b73ceec5 +#: ../../getting_started/install/deploy.rst:368 +#: 60a39e93e7874491a93893de78b7d37e msgid "" "If a GPU is available, it will be preferred by default, unless " "prefer_cpu=False is configured." msgstr "如果有可用的GPU,默认情况下会优先使用GPU,除非配置了 prefer_cpu=False。" -#: ../../getting_started/install/deploy.rst:365 -#: 41b0440eb0074e5fa8c87dd404efe0ce +#: ../../getting_started/install/deploy.rst:371 +#: 7c86780fbf634de8873afd439389cf89 msgid "vllm" msgstr "" -#: ../../getting_started/install/deploy.rst:367 -#: 6fc445675bf74b2ea2fe0c7f2a64db69 +#: ../../getting_started/install/deploy.rst:373 +#: e2827892e43d420c85b8b83c4855d197 msgid "vLLM is a fast and easy-to-use library for LLM inference and serving." -msgstr "\"vLLM 是一个快速且易于使用的 LLM 推理和服务的库。" +msgstr "vLLM 是一个快速且易于使用的 LLM 推理和服务的库。" -#: ../../getting_started/install/deploy.rst:369 -#: aab5f913d29445c4b345180b8793ebc7 +#: ../../getting_started/install/deploy.rst:375 +#: 81bbfa3876a74244acc82d295803fdd4 msgid "**Running vLLM**" msgstr "**运行vLLM**" -#: ../../getting_started/install/deploy.rst:371 -#: a9560d697821404cb0abdabf9f479645 +#: ../../getting_started/install/deploy.rst:377 +#: 75bc518b444c417ba4d9c15246549327 msgid "**1.Installing Dependencies**" msgstr "**1.安装依赖**" -#: ../../getting_started/install/deploy.rst:373 -#: b008224d4f314e5c988335262c95a42e +#: ../../getting_started/install/deploy.rst:379 +#: 725c620b0a5045c1a64a3b2a2e9b48f3 msgid "" "vLLM is an optional dependency in DB-GPT, and you can manually install it" " using the following command:" msgstr "vLLM 在 DB-GPT 是一个可选依赖, 你可以使用下面的命令手动安装它:" -#: ../../getting_started/install/deploy.rst:379 -#: 7dc0c8e996124177935a4e0d9ef19837 +#: ../../getting_started/install/deploy.rst:385 +#: 6f4b540107764f3592cc07cf170e4911 msgid "**2.Modifying the Configuration File**" msgstr "**2.修改配置文件**" -#: ../../getting_started/install/deploy.rst:381 -#: 49667576b44c46bf87d5bf4d207dd63a +#: ../../getting_started/install/deploy.rst:387 +#: b8576a1572674c4890e09b73e02cf0e8 msgid "Next, you can directly modify your .env file to enable vllm." msgstr "你可以直接修改你的 `.env` 文件" -#: ../../getting_started/install/deploy.rst:388 -#: f16a78f0ee6545babab0d66f12654c0a +#: ../../getting_started/install/deploy.rst:394 +#: b006745f3aee4651aaa0cf79081b5d7f msgid "" "You can view the models supported by vLLM `here " "`_" msgstr "" -"你可以在 " -"[这里](https://vllm.readthedocs.io/en/latest/models/supported_models.html" -"#supported-models) 查看 vLLM 支持的模型。" +"你可以在 `这里 " +"`_ 查看 vLLM 支持的模型。" -#: ../../getting_started/install/deploy.rst:397 -#: f7ae366723e9494d8177eeb963ba0ed9 +#: ../../getting_started/install/deploy.rst:403 +#: bc8057ee75e14737bf8fca3ceb555dac msgid "3.Prepare sql example(Optional)" msgstr "3.准备 sql example(可选)" -#: ../../getting_started/install/deploy.rst:398 -#: d302aac8ddb346598fc9d73e0f6c2cbc +#: ../../getting_started/install/deploy.rst:404 +#: 9b0b9112237c4b3aaa1dd5d704ea32e6 msgid "**(Optional) load examples into SQLite**" -msgstr "**(可选) load examples into SQLite**" +msgstr "**(可选) 加载样例数据到 SQLite 数据库中**" -#: ../../getting_started/install/deploy.rst:405 -#: ae2a315e40854f27a074f2c0f2506014 +#: ../../getting_started/install/deploy.rst:411 +#: 0815e13b96264ffcba1526c82ba2e7c8 msgid "On windows platform:" -msgstr "" +msgstr "在 Windows 平台:" -#: ../../getting_started/install/deploy.rst:412 -#: 36b4b7a813844af3a4ec8062b39059a3 +#: ../../getting_started/install/deploy.rst:418 +#: 577a4167ecac4fa88586961f225f0487 msgid "4.Run db-gpt server" msgstr "4.运行db-gpt server" -#: ../../getting_started/install/deploy.rst:418 -#: e56f15e563484027b7efb2147c9b71a7 +#: ../../getting_started/install/deploy.rst:424 +#: a9f96b064b674f80824257b4b0a18e2a msgid "**Open http://localhost:5000 with your browser to see the product.**" msgstr "打开浏览器访问http://localhost:5000" @@ -633,3 +644,9 @@ msgstr "打开浏览器访问http://localhost:5000" #~ " LLM model." #~ msgstr "" +#~ msgid "百川" +#~ msgstr "" + +#~ msgid "百川 硬件要求" +#~ msgstr "" + diff --git a/docs/locales/zh_CN/LC_MESSAGES/index.po b/docs/locales/zh_CN/LC_MESSAGES/index.po index d210535e7..1badfc0e4 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/index.po +++ b/docs/locales/zh_CN/LC_MESSAGES/index.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: DB-GPT 0.3.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-25 23:56+0800\n" +"POT-Creation-Date: 2023-11-06 19:00+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_CN\n" @@ -19,31 +19,27 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.12.1\n" -#: ../../index.rst:34 ../../index.rst:45 71dd3acc56354242aad5a920c2805328 +#: ../../index.rst:34 ../../index.rst:45 8bc3a47457a34995816985436034e233 msgid "Getting Started" msgstr "开始" -#: ../../index.rst:60 ../../index.rst:81 0f2fc16a44b043019556f5f3e0d0e2c0 +#: ../../index.rst:60 ../../index.rst:81 1a4e8a5dc7754967a0af9fb3d2e53017 msgid "Modules" msgstr "模块" -#: ../../index.rst:95 ../../index.rst:111 2624521b920a4b3b9eac3fec76635ab8 -msgid "Use Cases" -msgstr "示例" - -#: ../../index.rst:125 ../../index.rst:128 accec2bb9c5149f184a87e03955d6b22 +#: ../../index.rst:96 ../../index.rst:99 c815772ae8514f0c9b26911b0dd73f54 msgid "Reference" msgstr "参考" -#: ../../index.rst:138 ../../index.rst:144 26278dabd4944d1a9f14330e83935162 +#: ../../index.rst:109 ../../index.rst:115 dabe4c3409df489f84e4ec588f2b34a5 msgid "Resources" msgstr "资源" -#: ../../index.rst:7 9277d505dda74ae0862cd09d05cf5e63 +#: ../../index.rst:7 7626b01b253546ac83ca0cf130dfa091 msgid "Welcome to DB-GPT!" msgstr "欢迎来到DB-GPT中文文档" -#: ../../index.rst:8 9fa76a01965746978a00ac411fca13a8 +#: ../../index.rst:8 6037e5e0d7f7428ba92315a91ccfd53f msgid "" "As large models are released and iterated upon, they are becoming " "increasingly intelligent. However, in the process of using large models, " @@ -61,7 +57,7 @@ msgstr "" ",我们启动了DB-" "GPT项目,为所有基于数据库的场景构建一个完整的私有大模型解决方案。该方案“”支持本地部署,既可应用于“独立私有环境”,又可根据业务模块进行“独立部署”和“隔离”,确保“大模型”的能力绝对私有、安全、可控。" -#: ../../index.rst:10 b12b6f91c5664f61aa9e4d7cd500b922 +#: ../../index.rst:10 ab2a181d517047e6992171786c83f8e3 msgid "" "**DB-GPT** is an experimental open-source project that uses localized GPT" " large models to interact with your data and environment. With this " @@ -71,39 +67,39 @@ msgstr "" "DB-GPT 是一个开源的以数据库为基础的GPT实验项目,使用本地化的GPT大模型与您的数据和环境进行交互,无数据泄露风险100% 私密,100%" " 安全。" -#: ../../index.rst:12 7032e17191394f7090141927644fb512 +#: ../../index.rst:12 9cfb7515430d49af8a1ca47f60264a58 msgid "**Features**" msgstr "特性" -#: ../../index.rst:13 5a7a8e5eace34d5f9a4f779bf5122928 +#: ../../index.rst:13 2a1f84e455c84d9ca66c65f92e5b0d78 msgid "" "Currently, we have released multiple key features, which are listed below" " to demonstrate our current capabilities:" msgstr "目前我们已经发布了多种关键的特性,这里一一列举展示一下当前发布的能力。" -#: ../../index.rst:15 5d0f67aacb8b4bc893a306ccbd6a3778 +#: ../../index.rst:15 43de30ce92da4c3cbe43ae4e4c9f1869 msgid "SQL language capabilities - SQL generation - SQL diagnosis" msgstr "SQL语言能力 - SQL生成 - SQL诊断" -#: ../../index.rst:19 556eaf756fec431ca5c453208292ab4f +#: ../../index.rst:19 edfeef5284e7426a9e551e782bc5702c msgid "" "Private domain Q&A and data processing - Database knowledge Q&A - Data " "processing" msgstr "私有领域问答与数据处理 - 数据库知识问答 - 数据处理" -#: ../../index.rst:23 5148ad898ec041858eddbeaa646d3f1b +#: ../../index.rst:23 7a42f17049b943f88dd8f17baa440144 msgid "" "Plugins - Support custom plugin execution tasks and natively support the " "Auto-GPT plugin, such as:" msgstr "插件模型 - 支持自定义插件执行任务,并原生支持Auto-GPT插件,例如:* SQL自动执行,获取查询结果 * 自动爬取学习知识" -#: ../../index.rst:26 34c7ff33bc1c401480603a5197ecb1c4 +#: ../../index.rst:26 8b48d7b60bbc439da50a624c4048e6f6 msgid "" "Unified vector storage/indexing of knowledge base - Support for " "unstructured data such as PDF, Markdown, CSV, and WebURL" msgstr "知识库统一向量存储/索引 - 非结构化数据支持包括PDF、MarkDown、CSV、WebURL" -#: ../../index.rst:29 9d7095e5b08249e6bb5c724929537e6c +#: ../../index.rst:29 97df482893924bd18e9a101922e7c374 #, fuzzy msgid "" "Multi LLMs Support - Supports multiple large language models, currently " @@ -111,63 +107,63 @@ msgid "" "codet5p" msgstr "多模型支持 - 支持多种大语言模型, 当前已支持Vicuna(7b,13b), ChatGLM-6b(int4, int8)" -#: ../../index.rst:35 caa368eab40e4efb953865740a3c9018 +#: ../../index.rst:35 1ef26ead30ed4b7fb966c8a17307cdc5 msgid "" "How to get started using DB-GPT to interact with your data and " "environment." msgstr "开始使用DB-GPT与您的数据环境进行交互。" -#: ../../index.rst:36 34cecad11f8b4a3e96bfa0a31814e3d2 +#: ../../index.rst:36 3b44ab3576944bf6aa221f35bc051f4e #, fuzzy msgid "`Quickstart Guide <./getting_started/getting_started.html>`_" msgstr "`使用指南 <./getting_started/getting_started.html>`_" -#: ../../index.rst:38 892598cdc16d45c68383033b08b7233f +#: ../../index.rst:38 430cb239cdce42a0b62db46aba3f3bdb msgid "Concepts and terminology" msgstr "相关概念" -#: ../../index.rst:40 887cc43a3a134aba96eb7ca11e5ca86f +#: ../../index.rst:40 ded4d9f80066498e90ba6214520013f7 #, fuzzy msgid "`Concepts and Terminology <./getting_started/concepts.html>`_" msgstr "`相关概念 <./getting_started/concepts.html>`_" -#: ../../index.rst:42 133e25c7dce046b1ab262489ecb60b4a +#: ../../index.rst:42 cd662e53621e474d901146813c750044 msgid "Coming soon..." msgstr "" -#: ../../index.rst:44 a9e0812d32714a6f81ed75aa70f0c20e +#: ../../index.rst:44 15edba57f1de44af8aff76735a2593de msgid "`Tutorials <.getting_started/tutorials.html>`_" msgstr "`教程 <.getting_started/tutorials.html>`_" -#: ../../index.rst:62 4fccfd3082174f58926a9811f39e4d96 +#: ../../index.rst:62 779454b29d8e4e6eb21497025922d1b8 msgid "" "These modules are the core abstractions with which we can interact with " "data and environment smoothly." msgstr "这些模块是我们可以与数据和环境顺利地进行交互的核心组成。" -#: ../../index.rst:63 ecac40207ada454e9a68356f575dbca9 +#: ../../index.rst:63 bcd0e8c88c7b4807a91dd442416bec19 msgid "" "It's very important for DB-GPT, DB-GPT also provide standard, extendable " "interfaces." msgstr "DB-GPT还提供了标准的、可扩展的接口。" -#: ../../index.rst:65 9d852bed582449e89dc13312ddf29eed +#: ../../index.rst:65 1e785dc6925045e8ba106cf4a3b17cac msgid "" "The docs for each module contain quickstart examples, how to guides, " "reference docs, and conceptual guides." msgstr "每个模块的文档都包含快速入门的例子、操作指南、参考文档和相关概念等内容。" -#: ../../index.rst:67 3167446539de449aba2de694fe901bcf +#: ../../index.rst:67 9c9fddd14bfd40339889f5d1f0b04163 msgid "The modules are as follows" msgstr "组成模块如下:" -#: ../../index.rst:69 442683a5f154429da87f452e49bcbb5c +#: ../../index.rst:69 4a19083cadd04b8e8b649a622e0ceccd msgid "" "`LLMs <./modules/llms.html>`_: Supported multi models management and " "integrations." msgstr "`LLMs <./modules/llms.html>`_:基于FastChat提供大模型的运行环境。支持多模型管理和集成。 " -#: ../../index.rst:71 3cf320b6199e4ce78235bce8b1be60a2 +#: ../../index.rst:71 436a139225574aa5b066a1835d38238d msgid "" "`Prompts <./modules/prompts.html>`_: Prompt management, optimization, and" " serialization for multi database." @@ -175,86 +171,41 @@ msgstr "" "`Prompt自动生成与优化 <./modules/prompts.html>`_: 自动化生成高质量的Prompt " ",并进行优化,提高系统的响应效率" -#: ../../index.rst:73 4f29ed67ea2a4a3ca824ac8b8b33cae6 +#: ../../index.rst:73 6c53edfb2e494c5fba6efb5ade48c310 msgid "`Plugins <./modules/plugins.html>`_: Plugins management, scheduler." msgstr "`Agent与插件: <./modules/plugins.html>`_:提供Agent和插件机制,使得用户可以自定义并增强系统的行为。" -#: ../../index.rst:75 d651f9d93bb54b898ef97407501cc6cf +#: ../../index.rst:75 6328760e8faf4e8296f3e1edd486316c #, fuzzy msgid "" "`Knowledge <./modules/knowledge.html>`_: Knowledge management, embedding," " and search." msgstr "`知识库能力: <./modules/knowledge.html>`_: 支持私域知识库问答能力, " -#: ../../index.rst:77 fd6dd2adcd844baa84602b650d89e507 +#: ../../index.rst:77 da272ccf56e3498d92009ac7101b0c45 msgid "" "`Connections <./modules/connections.html>`_: Supported multi databases " "connection. management connections and interact with this." msgstr "`连接模块 <./modules/connections.html>`_: 用于连接不同的模块和数据源,实现数据的流转和交互 " -#: ../../index.rst:79 7e388a9d8c044169923508ccdeb2d9a5 +#: ../../index.rst:79 1a0551f62d9d418a9dec267fbcb49af0 #, fuzzy msgid "`Vector <./modules/vector.html>`_: Supported multi vector database." msgstr "`LLMs <./modules/llms.html>`_:基于FastChat提供大模型的运行环境。支持多模型管理和集成。 " -#: ../../index.rst:97 9d37bf061a784d5ca92d1de33b0834f3 -msgid "Best Practices and built-in implementations for common DB-GPT use cases:" -msgstr "DB-GPT用例的最佳实践和内置方法:" - -#: ../../index.rst:99 ba264bbe31d24c7887a30cbd5442e157 -msgid "" -"`Sql generation and diagnosis " -"<./use_cases/sql_generation_and_diagnosis.html>`_: SQL generation and " -"diagnosis." -msgstr "`Sql生成和诊断 <./use_cases/sql_generation_and_diagnosis.html>`_: Sql生成和诊断。" - -#: ../../index.rst:101 1166f6aeba064a3990d4b0caa87db274 -msgid "" -"`knownledge Based QA <./use_cases/knownledge_based_qa.html>`_: A " -"important scene for user to chat with database documents, codes, bugs and" -" schemas." -msgstr "`知识库问答 <./use_cases/knownledge_based_qa.html>`_: 用户与数据库文档、代码和bug聊天的重要场景\"" - -#: ../../index.rst:103 b32610ada3a0440e9b029b8dffe7c79e -msgid "" -"`Chatbots <./use_cases/chatbots.html>`_: Language model love to chat, use" -" multi models to chat." -msgstr "`聊天机器人 <./use_cases/chatbots.html>`_: 使用多模型进行对话" - -#: ../../index.rst:105 d9348b8112df4839ab14a74a42b63715 -msgid "" -"`Querying Database Data <./use_cases/query_database_data.html>`_: Query " -"and Analysis data from databases and give charts." -msgstr "`查询数据库数据 <./use_cases/query_database_data.html>`_:从数据库中查询和分析数据并给出图表。" - -#: ../../index.rst:107 ef978dc1f4254e5eb4ca487c31c03f7c -msgid "" -"`Interacting with apis <./use_cases/interacting_with_api.html>`_: " -"Interact with apis, such as create a table, deploy a database cluster, " -"create a database and so on." -msgstr "" -"`API交互 <./use_cases/interacting_with_api.html>`_: " -"与API交互,例如创建表、部署数据库集群、创建数据库等。" - -#: ../../index.rst:109 49a549d7d38f493ba48e162785b4ac5d -msgid "" -"`Tool use with plugins <./use_cases/tool_use_with_plugin>`_: According to" -" Plugin use tools to manage databases autonomoly." -msgstr "`插件工具 <./use_cases/tool_use_with_plugin>`_: 根据插件使用工具自主管理数据库。" - -#: ../../index.rst:126 db86500484fa4f14918b0ad4e5a7326d +#: ../../index.rst:97 9aceee0dbe1e4f7da499ac6aab23aea2 msgid "" "Full documentation on all methods, classes, installation methods, and " "integration setups for DB-GPT." msgstr "关于DB-GPT的所有方法、类、安装方法和集成设置的完整文档。" -#: ../../index.rst:140 a44abbb370a841658801bb2729fa62c9 +#: ../../index.rst:111 c9a729f4e1964894bae215793647ab75 msgid "" "Additional resources we think may be useful as you develop your " "application!" msgstr "“我们认为在您开发应用程序时可能有用的其他资源!”" -#: ../../index.rst:142 4d0da8471db240dba842949b6796be7a +#: ../../index.rst:113 06e6e4b7776c405fa94ae7b59253162d msgid "" "`Discord `_: if your have some problem or " "ideas, you can talk from discord." @@ -272,3 +223,58 @@ msgstr "`Discord `_:如果您有任何问题,可 #~ msgid "Guides for how other companies/products can be used with DB-GPT" #~ msgstr "其他公司/产品如何与DB-GPT一起使用的方法指南" +#~ msgid "Use Cases" +#~ msgstr "示例" + +#~ msgid "" +#~ "Best Practices and built-in " +#~ "implementations for common DB-GPT use" +#~ " cases:" +#~ msgstr "DB-GPT用例的最佳实践和内置方法:" + +#~ msgid "" +#~ "`Sql generation and diagnosis " +#~ "<./use_cases/sql_generation_and_diagnosis.html>`_: SQL " +#~ "generation and diagnosis." +#~ msgstr "`Sql生成和诊断 <./use_cases/sql_generation_and_diagnosis.html>`_: Sql生成和诊断。" + +#~ msgid "" +#~ "`knownledge Based QA " +#~ "<./use_cases/knownledge_based_qa.html>`_: A important " +#~ "scene for user to chat with " +#~ "database documents, codes, bugs and " +#~ "schemas." +#~ msgstr "" +#~ "`知识库问答 <./use_cases/knownledge_based_qa.html>`_: " +#~ "用户与数据库文档、代码和bug聊天的重要场景\"" + +#~ msgid "" +#~ "`Chatbots <./use_cases/chatbots.html>`_: Language " +#~ "model love to chat, use multi " +#~ "models to chat." +#~ msgstr "`聊天机器人 <./use_cases/chatbots.html>`_: 使用多模型进行对话" + +#~ msgid "" +#~ "`Querying Database Data " +#~ "<./use_cases/query_database_data.html>`_: Query and " +#~ "Analysis data from databases and give" +#~ " charts." +#~ msgstr "`查询数据库数据 <./use_cases/query_database_data.html>`_:从数据库中查询和分析数据并给出图表。" + +#~ msgid "" +#~ "`Interacting with apis " +#~ "<./use_cases/interacting_with_api.html>`_: Interact with" +#~ " apis, such as create a table, " +#~ "deploy a database cluster, create a " +#~ "database and so on." +#~ msgstr "" +#~ "`API交互 <./use_cases/interacting_with_api.html>`_: " +#~ "与API交互,例如创建表、部署数据库集群、创建数据库等。" + +#~ msgid "" +#~ "`Tool use with plugins " +#~ "<./use_cases/tool_use_with_plugin>`_: According to " +#~ "Plugin use tools to manage databases " +#~ "autonomoly." +#~ msgstr "`插件工具 <./use_cases/tool_use_with_plugin>`_: 根据插件使用工具自主管理数据库。" + From d62048ef1e995130f2a6bca077a66e283fd66e60 Mon Sep 17 00:00:00 2001 From: FangYin Cheng Date: Mon, 6 Nov 2023 19:55:57 +0800 Subject: [PATCH 54/57] chore: Format code --- pilot/model/proxy/llms/tongyi.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pilot/model/proxy/llms/tongyi.py b/pilot/model/proxy/llms/tongyi.py index 13031e96f..e101db47e 100644 --- a/pilot/model/proxy/llms/tongyi.py +++ b/pilot/model/proxy/llms/tongyi.py @@ -36,7 +36,10 @@ def tongyi_generate_stream( if message.role == ModelMessageRoleType.HUMAN: history.append({"role": "user", "content": message.content}) for message in messages: - if message.role == ModelMessageRoleType.SYSTEM or message.role == ModelMessageRoleType.HUMAN: + if ( + message.role == ModelMessageRoleType.SYSTEM + or message.role == ModelMessageRoleType.HUMAN + ): history.append({"role": "user", "content": message.content}) # elif message.role == ModelMessageRoleType.HUMAN: # history.append({"role": "user", "content": message.content}) From f8cb208dc47f9f18b79e0d6bcd787ead49157bd4 Mon Sep 17 00:00:00 2001 From: dulin <1909703981@qq.com> Date: Tue, 7 Nov 2023 16:56:23 +0800 Subject: [PATCH 55/57] 1. group_concat() not supported in clickhouse, use arrayStringConcat+groupArray instead --- pilot/connections/rdbms/conn_clickhouse.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pilot/connections/rdbms/conn_clickhouse.py b/pilot/connections/rdbms/conn_clickhouse.py index 0433b4b76..a64950877 100644 --- a/pilot/connections/rdbms/conn_clickhouse.py +++ b/pilot/connections/rdbms/conn_clickhouse.py @@ -106,3 +106,13 @@ class ClickhouseConnect(RDBMSDatabase): return [ (table_comment[0], table_comment[1]) for table_comment in table_comments ] + + def table_simple_info(self): + # group_concat() not supported in clickhouse, use arrayStringConcat+groupArray instead; and quotes need to be escaped + _sql = f""" + select concat(TABLE_NAME, \'(\' , arrayStringConcat(groupArray(column_name),\'-\'), \')\') as schema_info + from information_schema.COLUMNS where table_schema=\'{self.get_current_db_name()}\' group by TABLE_NAME; """ + + cursor = self.session.execute(text(_sql)) + results = cursor.fetchall() + return results From 4806e16d5f76f9776261138f2739bbaa52d4874f Mon Sep 17 00:00:00 2001 From: oushu1zhangxiangxuan1 Date: Thu, 12 Oct 2023 11:21:58 +0800 Subject: [PATCH 56/57] env param doc bugfix --- .../install/environment/environment.md | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/docs/getting_started/install/environment/environment.md b/docs/getting_started/install/environment/environment.md index 021bbe861..11aec8d40 100644 --- a/docs/getting_started/install/environment/environment.md +++ b/docs/getting_started/install/environment/environment.md @@ -6,7 +6,9 @@ LLM Model Name, see /pilot/configs/model_config.LLM_MODEL_CONFIG * LLM_MODEL=vicuna-13b MODEL_SERVER_ADDRESS + * MODEL_SERVER=http://127.0.0.1:8000 + LIMIT_MODEL_CONCURRENCY * LIMIT_MODEL_CONCURRENCY=5 @@ -84,21 +86,6 @@ embedding recall max token ,2000 * WEAVIATE_URL=https://kt-region-m8hcy0wc.weaviate.network ``` -```{admonition} Vector Store SETTINGS -#### Chroma -* VECTOR_STORE_TYPE=Chroma -#### MILVUS -* VECTOR_STORE_TYPE=Milvus -* MILVUS_URL=127.0.0.1 -* MILVUS_PORT=19530 -* MILVUS_USERNAME -* MILVUS_PASSWORD -* MILVUS_SECURE= - -#### WEAVIATE -* WEAVIATE_URL=https://kt-region-m8hcy0wc.weaviate.network -``` - ```{admonition} Multi-GPU Setting See https://developer.nvidia.com/blog/cuda-pro-tip-control-gpu-visibility-cuda_visible_devices/ If CUDA_VISIBLE_DEVICES is not configured, all available gpus will be used From c4ae0fd98172ab20f11a4508023ad5746a01af28 Mon Sep 17 00:00:00 2001 From: JohnSaxon Date: Tue, 17 Oct 2023 10:33:35 +0800 Subject: [PATCH 57/57] typos fix --- pilot/base_modules/agent/plugins_util.py | 2 +- pilot/connections/rdbms/conn_clickhouse.py | 6 ++--- pilot/openapi/api_v1/api_v1.py | 10 ++++---- pilot/openapi/api_v1/editor/api_editor_v1.py | 18 +++++++------- pilot/openapi/api_view_model.py | 4 ++-- pilot/openapi/base.py | 2 +- pilot/scene/base_chat.py | 2 +- pilot/scene/chat_dashboard/data_loader.py | 4 ++-- pilot/scene/chat_dashboard/prompt.py | 6 ++--- .../chat_excel/excel_analyze/prompt.py | 6 ++--- .../chat_excel/excel_learning/prompt.py | 6 ++--- pilot/scene/chat_db/auto_execute/prompt.py | 6 ++--- .../chat_db/auto_execute/prompt_baichuan.py | 6 ++--- pilot/scene/chat_db/professional_qa/prompt.py | 6 ++--- .../chat_knowledge/inner_db_summary/prompt.py | 6 ++--- pilot/scene/chat_knowledge/v1/prompt.py | 6 ++--- .../scene/chat_knowledge/v1/prompt_chatglm.py | 6 ++--- pilot/scene/chat_normal/prompt.py | 6 ++--- pilot/server/knowledge/api.py | 24 +++++++++---------- pilot/server/llm_manage/api.py | 14 +++++------ pilot/server/prompt/api.py | 10 ++++---- 21 files changed, 78 insertions(+), 78 deletions(-) diff --git a/pilot/base_modules/agent/plugins_util.py b/pilot/base_modules/agent/plugins_util.py index cf8fb8df3..b5f12c5eb 100644 --- a/pilot/base_modules/agent/plugins_util.py +++ b/pilot/base_modules/agent/plugins_util.py @@ -111,7 +111,7 @@ def load_native_plugins(cfg: Config): print("save file") cfg.set_plugins(scan_plugins(cfg.debug_mode)) else: - print("get file faild,response code:", response.status_code) + print("get file failed,response code:", response.status_code) except Exception as e: print("load plugin from git exception!" + str(e)) diff --git a/pilot/connections/rdbms/conn_clickhouse.py b/pilot/connections/rdbms/conn_clickhouse.py index a64950877..b2762556a 100644 --- a/pilot/connections/rdbms/conn_clickhouse.py +++ b/pilot/connections/rdbms/conn_clickhouse.py @@ -106,13 +106,13 @@ class ClickhouseConnect(RDBMSDatabase): return [ (table_comment[0], table_comment[1]) for table_comment in table_comments ] - + def table_simple_info(self): # group_concat() not supported in clickhouse, use arrayStringConcat+groupArray instead; and quotes need to be escaped _sql = f""" select concat(TABLE_NAME, \'(\' , arrayStringConcat(groupArray(column_name),\'-\'), \')\') as schema_info - from information_schema.COLUMNS where table_schema=\'{self.get_current_db_name()}\' group by TABLE_NAME; """ - + from information_schema.COLUMNS where table_schema=\'{self.get_current_db_name()}\' group by TABLE_NAME; """ + cursor = self.session.execute(text(_sql)) results = cursor.fetchall() return results diff --git a/pilot/openapi/api_v1/api_v1.py b/pilot/openapi/api_v1/api_v1.py index 23cba7948..d33bd1df1 100644 --- a/pilot/openapi/api_v1/api_v1.py +++ b/pilot/openapi/api_v1/api_v1.py @@ -172,7 +172,7 @@ async def test_connect(db_config: DBConfig = Body()): CFG.LOCAL_DB_MANAGE.test_connect(db_config) return Result.succ(True) except Exception as e: - return Result.faild(code="E1001", msg=str(e)) + return Result.failed(code="E1001", msg=str(e)) @router.post("/v1/chat/db/summary", response_model=Result[bool]) @@ -305,7 +305,7 @@ async def params_load( return Result.succ(get_hist_messages(conv_uid)) except Exception as e: logger.error("excel load error!", e) - return Result.faild(code="E000X", msg=f"File Load Error {e}") + return Result.failed(code="E000X", msg=f"File Load Error {e}") @router.post("/v1/chat/dialogue/delete") @@ -352,7 +352,7 @@ async def get_chat_instance(dialogue: ConversationVo = Body()) -> BaseChat: if not ChatScene.is_valid_mode(dialogue.chat_mode): raise StopAsyncIteration( - Result.faild("Unsupported Chat Mode," + dialogue.chat_mode + "!") + Result.failed("Unsupported Chat Mode," + dialogue.chat_mode + "!") ) chat_param = { @@ -430,7 +430,7 @@ async def model_types(controller: BaseModelController = Depends(get_model_contro return Result.succ(list(types)) except Exception as e: - return Result.faild(code="E000X", msg=f"controller model types error {e}") + return Result.failed(code="E000X", msg=f"controller model types error {e}") @router.get("/v1/model/supports") @@ -440,7 +440,7 @@ async def model_supports(worker_manager: WorkerManager = Depends(get_worker_mana models = await worker_manager.supported_models() return Result.succ(FlatSupportedModel.from_supports(models)) except Exception as e: - return Result.faild(code="E000X", msg=f"Fetch supportd models error {e}") + return Result.failed(code="E000X", msg=f"Fetch supportd models error {e}") async def no_stream_generator(chat): diff --git a/pilot/openapi/api_v1/editor/api_editor_v1.py b/pilot/openapi/api_v1/editor/api_editor_v1.py index e41998942..86b98c9a0 100644 --- a/pilot/openapi/api_v1/editor/api_editor_v1.py +++ b/pilot/openapi/api_v1/editor/api_editor_v1.py @@ -107,7 +107,7 @@ async def get_editor_sql(con_uid: str, round: int): .replace("\n", " ") ) return Result.succ(json.loads(context)) - return Result.faild(msg="not have sql!") + return Result.failed(msg="not have sql!") @router.post("/v1/editor/sql/run", response_model=Result[SqlRunData]) @@ -116,7 +116,7 @@ async def editor_sql_run(run_param: dict = Body()): db_name = run_param["db_name"] sql = run_param["sql"] if not db_name and not sql: - return Result.faild("SQL run param error!") + return Result.failed("SQL run param error!") conn = CFG.LOCAL_DB_MANAGE.get_connect(db_name) try: @@ -169,7 +169,7 @@ async def sql_editor_submit(sql_edit_context: ChatSqlEditContext = Body()): ) history_mem.update(history_messages) return Result.succ(None) - return Result.faild(msg="Edit Faild!") + return Result.failed(msg="Edit Failed!") @router.get("/v1/editor/chart/list", response_model=Result[ChartList]) @@ -191,7 +191,7 @@ async def get_editor_chart_list(con_uid: str): charts=json.loads(element["data"]["content"]), ) return Result.succ(chart_list) - return Result.faild(msg="Not have charts!") + return Result.failed(msg="Not have charts!") @router.post("/v1/editor/chart/info", response_model=Result[ChartDetail]) @@ -210,7 +210,7 @@ async def get_editor_chart_info(param: dict = Body()): logger.error( "this dashboard dialogue version too old, can't support editor!" ) - return Result.faild( + return Result.failed( msg="this dashboard dialogue version too old, can't support editor!" ) for element in last_round["messages"]: @@ -234,7 +234,7 @@ async def get_editor_chart_info(param: dict = Body()): ) return Result.succ(detail) - return Result.faild(msg="Can't Find Chart Detail Info!") + return Result.failed(msg="Can't Find Chart Detail Info!") @router.post("/v1/editor/chart/run", response_model=Result[ChartRunData]) @@ -244,7 +244,7 @@ async def editor_chart_run(run_param: dict = Body()): sql = run_param["sql"] chart_type = run_param["chart_type"] if not db_name and not sql: - return Result.faild("SQL run param error!") + return Result.failed("SQL run param error!") try: dashboard_data_loader: DashboardDataLoader = DashboardDataLoader() db_conn = CFG.LOCAL_DB_MANAGE.get_connect(db_name) @@ -334,7 +334,7 @@ async def chart_editor_submit(chart_edit_context: ChatChartEditContext = Body()) ) except Exception as e: logger.error(f"edit chart exception!{str(e)}", e) - return Result.faild(msg=f"Edit chart exception!{str(e)}") + return Result.failed(msg=f"Edit chart exception!{str(e)}") history_mem.update(history_messages) return Result.succ(None) - return Result.faild(msg="Edit Faild!") + return Result.failed(msg="Edit Failed!") diff --git a/pilot/openapi/api_view_model.py b/pilot/openapi/api_view_model.py index 60065f2f2..af1aa4b9c 100644 --- a/pilot/openapi/api_view_model.py +++ b/pilot/openapi/api_view_model.py @@ -17,11 +17,11 @@ class Result(Generic[T], BaseModel): return Result(success=True, err_code=None, err_msg=None, data=data) @classmethod - def faild(cls, msg): + def failed(cls, msg): return Result(success=False, err_code="E000X", err_msg=msg, data=None) @classmethod - def faild(cls, code, msg): + def failed(cls, code, msg): return Result(success=False, err_code=code, err_msg=msg, data=None) diff --git a/pilot/openapi/base.py b/pilot/openapi/base.py index 506254ec7..d8c814787 100644 --- a/pilot/openapi/base.py +++ b/pilot/openapi/base.py @@ -7,4 +7,4 @@ async def validation_exception_handler(request: Request, exc: RequestValidationE message = "" for error in exc.errors(): message += ".".join(error.get("loc")) + ":" + error.get("msg") + ";" - return Result.faild(code="E0001", msg=message) + return Result.failed(code="E0001", msg=message) diff --git a/pilot/scene/base_chat.py b/pilot/scene/base_chat.py index 86fe8f859..24ec1c928 100644 --- a/pilot/scene/base_chat.py +++ b/pilot/scene/base_chat.py @@ -223,7 +223,7 @@ class BaseChat(ABC): span.end() except Exception as e: print(traceback.format_exc()) - logger.error("model response parase faild!" + str(e)) + logger.error("model response parase failed!" + str(e)) self.current_message.add_view_message( f"""ERROR!{str(e)}\n {ai_response_text} """ ) diff --git a/pilot/scene/chat_dashboard/data_loader.py b/pilot/scene/chat_dashboard/data_loader.py index faabe542a..970fc92dd 100644 --- a/pilot/scene/chat_dashboard/data_loader.py +++ b/pilot/scene/chat_dashboard/data_loader.py @@ -52,8 +52,8 @@ class DashboardDataLoader: values.append(value_item) return field_names, values except Exception as e: - logger.debug("Prepare Chart Data Faild!" + str(e)) - raise ValueError("Prepare Chart Data Faild!") + logger.debug("Prepare Chart Data Failed!" + str(e)) + raise ValueError("Prepare Chart Data Failed!") def get_chart_values_by_db(self, db_name: str, chart_sql: str): logger.info(f"get_chart_values_by_db:{db_name},{chart_sql}") diff --git a/pilot/scene/chat_dashboard/prompt.py b/pilot/scene/chat_dashboard/prompt.py index 9fed97f8f..7f1dd4090 100644 --- a/pilot/scene/chat_dashboard/prompt.py +++ b/pilot/scene/chat_dashboard/prompt.py @@ -42,7 +42,7 @@ RESPONSE_FORMAT = [ PROMPT_SEP = SeparatorStyle.SINGLE.value -PROMPT_NEED_NEED_STREAM_OUT = False +PROMPT_NEED_STREAM_OUT = False prompt = PromptTemplate( template_scene=ChatScene.ChatDashboard.value(), @@ -50,9 +50,9 @@ prompt = PromptTemplate( response_format=json.dumps(RESPONSE_FORMAT, indent=4), template_define=PROMPT_SCENE_DEFINE, template=_DEFAULT_TEMPLATE, - stream_out=PROMPT_NEED_NEED_STREAM_OUT, + stream_out=PROMPT_NEED_STREAM_OUT, output_parser=ChatDashboardOutputParser( - sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_NEED_STREAM_OUT + sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_STREAM_OUT ), ) CFG.prompt_template_registry.register(prompt, is_default=True) diff --git a/pilot/scene/chat_data/chat_excel/excel_analyze/prompt.py b/pilot/scene/chat_data/chat_excel/excel_analyze/prompt.py index 23c86bd4d..c1dfdfee3 100644 --- a/pilot/scene/chat_data/chat_excel/excel_analyze/prompt.py +++ b/pilot/scene/chat_data/chat_excel/excel_analyze/prompt.py @@ -51,7 +51,7 @@ _PROMPT_SCENE_DEFINE = ( PROMPT_SEP = SeparatorStyle.SINGLE.value -PROMPT_NEED_NEED_STREAM_OUT = True +PROMPT_NEED_STREAM_OUT = True # Temperature is a configuration hyperparameter that controls the randomness of language model output. # A high temperature produces more unpredictable and creative results, while a low temperature produces more common and conservative output. @@ -63,9 +63,9 @@ prompt = PromptTemplate( input_variables=["user_input", "table_name", "disply_type"], template_define=_PROMPT_SCENE_DEFINE, template=_DEFAULT_TEMPLATE, - stream_out=PROMPT_NEED_NEED_STREAM_OUT, + stream_out=PROMPT_NEED_STREAM_OUT, output_parser=ChatExcelOutputParser( - sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_NEED_STREAM_OUT + sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_STREAM_OUT ), need_historical_messages=True, # example_selector=sql_data_example, diff --git a/pilot/scene/chat_data/chat_excel/excel_learning/prompt.py b/pilot/scene/chat_data/chat_excel/excel_learning/prompt.py index aefd96a71..df17aec6b 100644 --- a/pilot/scene/chat_data/chat_excel/excel_learning/prompt.py +++ b/pilot/scene/chat_data/chat_excel/excel_learning/prompt.py @@ -67,7 +67,7 @@ PROMPT_SCENE_DEFINE = ( PROMPT_SEP = SeparatorStyle.SINGLE.value -PROMPT_NEED_NEED_STREAM_OUT = False +PROMPT_NEED_STREAM_OUT = False # Temperature is a configuration hyperparameter that controls the randomness of language model output. # A high temperature produces more unpredictable and creative results, while a low temperature produces more common and conservative output. @@ -80,9 +80,9 @@ prompt = PromptTemplate( response_format=json.dumps(RESPONSE_FORMAT_SIMPLE, ensure_ascii=False, indent=4), template_define=PROMPT_SCENE_DEFINE, template=_DEFAULT_TEMPLATE, - stream_out=PROMPT_NEED_NEED_STREAM_OUT, + stream_out=PROMPT_NEED_STREAM_OUT, output_parser=LearningExcelOutputParser( - sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_NEED_STREAM_OUT + sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_STREAM_OUT ), # example_selector=sql_data_example, temperature=PROMPT_TEMPERATURE, diff --git a/pilot/scene/chat_db/auto_execute/prompt.py b/pilot/scene/chat_db/auto_execute/prompt.py index abc889cec..9b4bcb6a5 100644 --- a/pilot/scene/chat_db/auto_execute/prompt.py +++ b/pilot/scene/chat_db/auto_execute/prompt.py @@ -33,7 +33,7 @@ RESPONSE_FORMAT_SIMPLE = { PROMPT_SEP = SeparatorStyle.SINGLE.value -PROMPT_NEED_NEED_STREAM_OUT = False +PROMPT_NEED_STREAM_OUT = False # Temperature is a configuration hyperparameter that controls the randomness of language model output. # A high temperature produces more unpredictable and creative results, while a low temperature produces more common and conservative output. @@ -46,9 +46,9 @@ prompt = PromptTemplate( response_format=json.dumps(RESPONSE_FORMAT_SIMPLE, ensure_ascii=False, indent=4), template_define=PROMPT_SCENE_DEFINE, template=_DEFAULT_TEMPLATE, - stream_out=PROMPT_NEED_NEED_STREAM_OUT, + stream_out=PROMPT_NEED_STREAM_OUT, output_parser=DbChatOutputParser( - sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_NEED_STREAM_OUT + sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_STREAM_OUT ), # example_selector=sql_data_example, temperature=PROMPT_TEMPERATURE, diff --git a/pilot/scene/chat_db/auto_execute/prompt_baichuan.py b/pilot/scene/chat_db/auto_execute/prompt_baichuan.py index 95aa962fa..4888cbd7f 100644 --- a/pilot/scene/chat_db/auto_execute/prompt_baichuan.py +++ b/pilot/scene/chat_db/auto_execute/prompt_baichuan.py @@ -36,7 +36,7 @@ RESPONSE_FORMAT_SIMPLE = { PROMPT_SEP = SeparatorStyle.SINGLE.value -PROMPT_NEED_NEED_STREAM_OUT = False +PROMPT_NEED_STREAM_OUT = False # Temperature is a configuration hyperparameter that controls the randomness of language model output. # A high temperature produces more unpredictable and creative results, while a low temperature produces more common and conservative output. @@ -50,9 +50,9 @@ prompt = PromptTemplate( template_is_strict=False, template_define=PROMPT_SCENE_DEFINE, template=_DEFAULT_TEMPLATE, - stream_out=PROMPT_NEED_NEED_STREAM_OUT, + stream_out=PROMPT_NEED_STREAM_OUT, output_parser=DbChatOutputParser( - sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_NEED_STREAM_OUT + sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_STREAM_OUT ), # example_selector=sql_data_example, temperature=PROMPT_TEMPERATURE, diff --git a/pilot/scene/chat_db/professional_qa/prompt.py b/pilot/scene/chat_db/professional_qa/prompt.py index ca4110398..c84f2eb7a 100644 --- a/pilot/scene/chat_db/professional_qa/prompt.py +++ b/pilot/scene/chat_db/professional_qa/prompt.py @@ -54,7 +54,7 @@ _DEFAULT_TEMPLATE = ( PROMPT_SEP = SeparatorStyle.SINGLE.value -PROMPT_NEED_NEED_STREAM_OUT = True +PROMPT_NEED_STREAM_OUT = True prompt = PromptTemplate( template_scene=ChatScene.ChatWithDbQA.value(), @@ -62,9 +62,9 @@ prompt = PromptTemplate( response_format=None, template_define=PROMPT_SCENE_DEFINE, template=_DEFAULT_TEMPLATE, - stream_out=PROMPT_NEED_NEED_STREAM_OUT, + stream_out=PROMPT_NEED_STREAM_OUT, output_parser=NormalChatOutputParser( - sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_NEED_STREAM_OUT + sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_STREAM_OUT ), ) diff --git a/pilot/scene/chat_knowledge/inner_db_summary/prompt.py b/pilot/scene/chat_knowledge/inner_db_summary/prompt.py index 924fab2c6..3f81906c0 100644 --- a/pilot/scene/chat_knowledge/inner_db_summary/prompt.py +++ b/pilot/scene/chat_knowledge/inner_db_summary/prompt.py @@ -33,7 +33,7 @@ RESPONSE_FORMAT = {"table": ["orders", "products"]} PROMPT_SEP = SeparatorStyle.SINGLE.value -PROMPT_NEED_NEED_STREAM_OUT = False +PROMPT_NEED_STREAM_OUT = False prompt = PromptTemplate( template_scene=ChatScene.InnerChatDBSummary.value(), @@ -41,9 +41,9 @@ prompt = PromptTemplate( response_format=json.dumps(RESPONSE_FORMAT, indent=4), template_define=PROMPT_SCENE_DEFINE, template=_DEFAULT_TEMPLATE + PROMPT_RESPONSE, - stream_out=PROMPT_NEED_NEED_STREAM_OUT, + stream_out=PROMPT_NEED_STREAM_OUT, output_parser=NormalChatOutputParser( - sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_NEED_STREAM_OUT + sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_STREAM_OUT ), ) diff --git a/pilot/scene/chat_knowledge/v1/prompt.py b/pilot/scene/chat_knowledge/v1/prompt.py index 394906562..ea55fca5a 100644 --- a/pilot/scene/chat_knowledge/v1/prompt.py +++ b/pilot/scene/chat_knowledge/v1/prompt.py @@ -33,7 +33,7 @@ _DEFAULT_TEMPLATE = ( PROMPT_SEP = SeparatorStyle.SINGLE.value -PROMPT_NEED_NEED_STREAM_OUT = True +PROMPT_NEED_STREAM_OUT = True prompt = PromptTemplate( template_scene=ChatScene.ChatKnowledge.value(), @@ -41,9 +41,9 @@ prompt = PromptTemplate( response_format=None, template_define=PROMPT_SCENE_DEFINE, template=_DEFAULT_TEMPLATE, - stream_out=PROMPT_NEED_NEED_STREAM_OUT, + stream_out=PROMPT_NEED_STREAM_OUT, output_parser=NormalChatOutputParser( - sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_NEED_STREAM_OUT + sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_STREAM_OUT ), ) diff --git a/pilot/scene/chat_knowledge/v1/prompt_chatglm.py b/pilot/scene/chat_knowledge/v1/prompt_chatglm.py index 7f66c1e6f..898699e89 100644 --- a/pilot/scene/chat_knowledge/v1/prompt_chatglm.py +++ b/pilot/scene/chat_knowledge/v1/prompt_chatglm.py @@ -33,7 +33,7 @@ _DEFAULT_TEMPLATE = ( PROMPT_SEP = SeparatorStyle.SINGLE.value -PROMPT_NEED_NEED_STREAM_OUT = True +PROMPT_NEED_STREAM_OUT = True prompt = PromptTemplate( template_scene=ChatScene.ChatKnowledge.value(), @@ -41,9 +41,9 @@ prompt = PromptTemplate( response_format=None, template_define=None, template=_DEFAULT_TEMPLATE, - stream_out=PROMPT_NEED_NEED_STREAM_OUT, + stream_out=PROMPT_NEED_STREAM_OUT, output_parser=NormalChatOutputParser( - sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_NEED_STREAM_OUT + sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_STREAM_OUT ), ) diff --git a/pilot/scene/chat_normal/prompt.py b/pilot/scene/chat_normal/prompt.py index ad0724874..dae412987 100644 --- a/pilot/scene/chat_normal/prompt.py +++ b/pilot/scene/chat_normal/prompt.py @@ -11,7 +11,7 @@ CFG = Config() PROMPT_SEP = SeparatorStyle.SINGLE.value -PROMPT_NEED_NEED_STREAM_OUT = True +PROMPT_NEED_STREAM_OUT = True prompt = PromptTemplate( template_scene=ChatScene.ChatNormal.value(), @@ -19,9 +19,9 @@ prompt = PromptTemplate( response_format=None, template_define=PROMPT_SCENE_DEFINE, template=None, - stream_out=PROMPT_NEED_NEED_STREAM_OUT, + stream_out=PROMPT_NEED_STREAM_OUT, output_parser=NormalChatOutputParser( - sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_NEED_STREAM_OUT + sep=PROMPT_SEP, is_stream_out=PROMPT_NEED_STREAM_OUT ), ) diff --git a/pilot/server/knowledge/api.py b/pilot/server/knowledge/api.py index 8e5e52b58..58b290d58 100644 --- a/pilot/server/knowledge/api.py +++ b/pilot/server/knowledge/api.py @@ -45,7 +45,7 @@ def space_add(request: KnowledgeSpaceRequest): knowledge_space_service.create_knowledge_space(request) return Result.succ([]) except Exception as e: - return Result.faild(code="E000X", msg=f"space add error {e}") + return Result.failed(code="E000X", msg=f"space add error {e}") @router.post("/knowledge/space/list") @@ -54,7 +54,7 @@ def space_list(request: KnowledgeSpaceRequest): try: return Result.succ(knowledge_space_service.get_knowledge_space(request)) except Exception as e: - return Result.faild(code="E000X", msg=f"space list error {e}") + return Result.failed(code="E000X", msg=f"space list error {e}") @router.post("/knowledge/space/delete") @@ -63,7 +63,7 @@ def space_delete(request: KnowledgeSpaceRequest): try: return Result.succ(knowledge_space_service.delete_space(request.name)) except Exception as e: - return Result.faild(code="E000X", msg=f"space list error {e}") + return Result.failed(code="E000X", msg=f"space list error {e}") @router.post("/knowledge/{space_name}/arguments") @@ -72,7 +72,7 @@ def arguments(space_name: str): try: return Result.succ(knowledge_space_service.arguments(space_name)) except Exception as e: - return Result.faild(code="E000X", msg=f"space list error {e}") + return Result.failed(code="E000X", msg=f"space list error {e}") @router.post("/knowledge/{space_name}/argument/save") @@ -83,7 +83,7 @@ def arguments_save(space_name: str, argument_request: SpaceArgumentRequest): knowledge_space_service.argument_save(space_name, argument_request) ) except Exception as e: - return Result.faild(code="E000X", msg=f"space list error {e}") + return Result.failed(code="E000X", msg=f"space list error {e}") @router.post("/knowledge/{space_name}/document/add") @@ -97,7 +97,7 @@ def document_add(space_name: str, request: KnowledgeDocumentRequest): ) # return Result.succ([]) except Exception as e: - return Result.faild(code="E000X", msg=f"document add error {e}") + return Result.failed(code="E000X", msg=f"document add error {e}") @router.post("/knowledge/{space_name}/document/list") @@ -108,7 +108,7 @@ def document_list(space_name: str, query_request: DocumentQueryRequest): knowledge_space_service.get_knowledge_documents(space_name, query_request) ) except Exception as e: - return Result.faild(code="E000X", msg=f"document list error {e}") + return Result.failed(code="E000X", msg=f"document list error {e}") @router.post("/knowledge/{space_name}/document/delete") @@ -119,7 +119,7 @@ def document_delete(space_name: str, query_request: DocumentQueryRequest): knowledge_space_service.delete_document(space_name, query_request.doc_name) ) except Exception as e: - return Result.faild(code="E000X", msg=f"document list error {e}") + return Result.failed(code="E000X", msg=f"document list error {e}") @router.post("/knowledge/{space_name}/document/upload") @@ -156,9 +156,9 @@ async def document_upload( ) ) # return Result.succ([]) - return Result.faild(code="E000X", msg=f"doc_file is None") + return Result.failed(code="E000X", msg=f"doc_file is None") except Exception as e: - return Result.faild(code="E000X", msg=f"document add error {e}") + return Result.failed(code="E000X", msg=f"document add error {e}") @router.post("/knowledge/{space_name}/document/sync") @@ -170,7 +170,7 @@ def document_sync(space_name: str, request: DocumentSyncRequest): ) return Result.succ([]) except Exception as e: - return Result.faild(code="E000X", msg=f"document sync error {e}") + return Result.failed(code="E000X", msg=f"document sync error {e}") @router.post("/knowledge/{space_name}/chunk/list") @@ -179,7 +179,7 @@ def document_list(space_name: str, query_request: ChunkQueryRequest): try: return Result.succ(knowledge_space_service.get_document_chunks(query_request)) except Exception as e: - return Result.faild(code="E000X", msg=f"document chunk list error {e}") + return Result.failed(code="E000X", msg=f"document chunk list error {e}") @router.post("/knowledge/{vector_name}/query") diff --git a/pilot/server/llm_manage/api.py b/pilot/server/llm_manage/api.py index f5602d3c4..617018642 100644 --- a/pilot/server/llm_manage/api.py +++ b/pilot/server/llm_manage/api.py @@ -33,9 +33,9 @@ async def model_params(): params.append(model_dict) return Result.succ(params) if not worker_instance: - return Result.faild(code="E000X", msg=f"can not find worker manager") + return Result.failed(code="E000X", msg=f"can not find worker manager") except Exception as e: - return Result.faild(code="E000X", msg=f"model stop failed {e}") + return Result.failed(code="E000X", msg=f"model stop failed {e}") @router.get("/v1/worker/model/list") @@ -78,7 +78,7 @@ async def model_list(): return Result.succ(responses) except Exception as e: - return Result.faild(code="E000X", msg=f"model list error {e}") + return Result.failed(code="E000X", msg=f"model list error {e}") @router.post("/v1/worker/model/stop") @@ -91,11 +91,11 @@ async def model_stop(request: WorkerStartupRequest): ComponentType.WORKER_MANAGER_FACTORY, WorkerManagerFactory ).create() if not worker_manager: - return Result.faild(code="E000X", msg=f"can not find worker manager") + return Result.failed(code="E000X", msg=f"can not find worker manager") request.params = {} return Result.succ(await worker_manager.model_shutdown(request)) except Exception as e: - return Result.faild(code="E000X", msg=f"model stop failed {e}") + return Result.failed(code="E000X", msg=f"model stop failed {e}") @router.post("/v1/worker/model/start") @@ -106,7 +106,7 @@ async def model_start(request: WorkerStartupRequest): ComponentType.WORKER_MANAGER_FACTORY, WorkerManagerFactory ).create() if not worker_manager: - return Result.faild(code="E000X", msg=f"can not find worker manager") + return Result.failed(code="E000X", msg=f"can not find worker manager") return Result.succ(await worker_manager.model_startup(request)) except Exception as e: - return Result.faild(code="E000X", msg=f"model start failed {e}") + return Result.failed(code="E000X", msg=f"model start failed {e}") diff --git a/pilot/server/prompt/api.py b/pilot/server/prompt/api.py index b94546891..0be4140a7 100644 --- a/pilot/server/prompt/api.py +++ b/pilot/server/prompt/api.py @@ -11,12 +11,12 @@ prompt_manage_service = PromptManageService() @router.post("/prompt/add") def prompt_add(request: PromptManageRequest): - print(f"/space/add params: {request}") + print(f"/prompt/add params: {request}") try: prompt_manage_service.create_prompt(request) return Result.succ([]) except Exception as e: - return Result.faild(code="E010X", msg=f"prompt add error {e}") + return Result.failed(code="E010X", msg=f"prompt add error {e}") @router.post("/prompt/list") @@ -25,7 +25,7 @@ def prompt_list(request: PromptManageRequest): try: return Result.succ(prompt_manage_service.get_prompts(request)) except Exception as e: - return Result.faild(code="E010X", msg=f"prompt list error {e}") + return Result.failed(code="E010X", msg=f"prompt list error {e}") @router.post("/prompt/update") @@ -34,7 +34,7 @@ def prompt_update(request: PromptManageRequest): try: return Result.succ(prompt_manage_service.update_prompt(request)) except Exception as e: - return Result.faild(code="E010X", msg=f"prompt update error {e}") + return Result.failed(code="E010X", msg=f"prompt update error {e}") @router.post("/prompt/delete") @@ -43,4 +43,4 @@ def prompt_delete(request: PromptManageRequest): try: return Result.succ(prompt_manage_service.delete_prompt(request.prompt_name)) except Exception as e: - return Result.faild(code="E010X", msg=f"prompt delete error {e}") + return Result.failed(code="E010X", msg=f"prompt delete error {e}")