From 69a1b56e8950f9fccc98c79626f1ca16848f8079 Mon Sep 17 00:00:00 2001
From: H <43509927+guoyuhao2330@users.noreply.github.com>
Date: Mon, 15 Jul 2024 17:38:41 +0800
Subject: [PATCH 01/11] Update wikipedia.py
---
graph/component/wikipedia.py | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/graph/component/wikipedia.py b/graph/component/wikipedia.py
index 9e67875961e..48abefaf6e7 100644
--- a/graph/component/wikipedia.py
+++ b/graph/component/wikipedia.py
@@ -30,9 +30,16 @@ class WikipediaParam(ComponentParamBase):
def __init__(self):
super().__init__()
self.top_n = 10
+ self.lang = 'en'
def check(self):
self.check_positive_integer(self.top_n, "Top N")
+ self.check_valid_value(self.lang, "Wikipedia languages",
+ ['af', 'pl', 'ar', 'ast', 'az', 'bg', 'nan', 'bn', 'be', 'ca', 'cs', 'cy', 'da', 'de',
+ 'et', 'el', 'en', 'es', 'eo', 'eu', 'fa', 'fr', 'gl', 'ko', 'hy', 'hi', 'hr', 'id',
+ 'it', 'he', 'ka', 'lld', 'la', 'lv', 'lt', 'hu', 'mk', 'arz', 'ms', 'min', 'my', 'nl',
+ 'ja', 'nb', 'nn', 'ce', 'uz', 'pt', 'kk', 'ro', 'ru', 'ceb', 'sk', 'sl', 'sr', 'sh',
+ 'fi', 'sv', 'ta', 'tt', 'th', 'tg', 'azb', 'tr', 'uk', 'ur', 'vi', 'war', 'zh', 'yue'])
class Wikipedia(ComponentBase, ABC):
@@ -45,9 +52,11 @@ def _run(self, history, **kwargs):
return Wikipedia.be_output(self._param.no)
wiki_res = []
- for wiki_key in wikipedia.search(ans, results=self._param.top_n):
+ wikipedia.set_lang(self._param.lang)
+ wiki_engine = wikipedia
+ for wiki_key in wiki_engine.search(ans, results=self._param.top_n):
try:
- page = wikipedia.page(title=wiki_key, auto_suggest=False)
+ page = wiki_engine.page(title=wiki_key, auto_suggest=False)
wiki_res.append({"content": '' + page.title + ' ' + page.summary})
except Exception as e:
print(e)
From 268c0c7eb7fb7df47600341af51ca37a3241411e Mon Sep 17 00:00:00 2001
From: H <43509927+guoyuhao2330@users.noreply.github.com>
Date: Wed, 17 Jul 2024 15:37:28 +0800
Subject: [PATCH 02/11] Update requirements.txt
---
requirements.txt | 176 ++++++++++++++---------------------------------
1 file changed, 51 insertions(+), 125 deletions(-)
diff --git a/requirements.txt b/requirements.txt
index 43eddf5b18f..9d02e96486e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,153 +1,79 @@
-accelerate==0.27.2
-aiohttp==3.9.5
-aiosignal==1.3.1
-annotated-types==0.6.0
-anyio==4.3.0
-argon2-cffi==23.1.0
-argon2-cffi-bindings==21.2.0
Aspose.Slides==24.2.0
-attrs==23.2.0
-blinker==1.7.0
-cachelib==0.12.0
+BCEmbedding==0.1.3
+boto3==1.34.140
+botocore==1.34.140
cachetools==5.3.3
-certifi==2024.2.2
-cffi==1.16.0
-charset-normalizer==3.3.2
-click==8.1.7
-coloredlogs==15.0.1
-cryptography==42.0.5
+chardet==5.2.0
+cn2an==0.5.22
dashscope==1.14.1
-datasets==2.17.1
datrie==0.8.2
demjson3==3.0.6
-dill==0.3.8
-distro==1.9.0
-elastic-transport==8.12.0
+discord.py==2.3.2
+duckduckgo_search==6.1.9
+elastic_transport==8.12.0
elasticsearch==8.12.1
-elasticsearch-dsl==8.12.0
-et-xmlfile==1.1.0
-filelock==3.13.1
+elasticsearch_dsl==8.12.0
fastembed==0.2.6
-FlagEmbedding==1.2.5
-Flask==3.0.2
-Flask-Cors==4.0.0
-Flask-Login==0.6.3
-Flask-Session==0.6.0
-flatbuffers==23.5.26
-frozenlist==1.4.1
-fsspec==2023.10.0
-h11==0.14.0
+fasttext==0.9.3
+filelock==3.15.4
+FlagEmbedding==1.2.10
+Flask==3.0.3
+Flask_Cors==4.0.0
+Flask_Login==0.6.3
+flask_session==0.8.0
+groq==0.9.0
hanziconv==0.3.2
-httpcore==1.0.4
+html_text==0.6.2
httpx==0.27.0
-huggingface-hub==0.20.3
-humanfriendly==10.0
-idna==3.6
-install==1.3.5
+huggingface_hub==0.20.3
+infinity_emb==0.0.51
itsdangerous==2.1.2
-Jinja2==3.1.3
-joblib==1.3.2
-lxml==5.1.0
-MarkupSafe==2.1.5
+Markdown==3.6
minio==7.2.4
-mpmath==1.3.0
-multidict==6.0.5
-multiprocess==0.70.16
-networkx==3.2.1
+mistralai==0.4.2
nltk==3.8.1
numpy==1.26.4
-nvidia-cublas-cu12==12.1.3.1
-nvidia-cuda-cupti-cu12==12.1.105
-nvidia-cuda-nvrtc-cu12==12.1.105
-nvidia-cuda-runtime-cu12==12.1.105
-nvidia-cudnn-cu12==8.9.2.26
-nvidia-cufft-cu12==11.0.2.54
-nvidia-curand-cu12==10.3.2.106
-nvidia-cusolver-cu12==11.4.5.107
-nvidia-cusparse-cu12==12.1.0.106
-nvidia-nccl-cu12==2.19.3
-nvidia-nvjitlink-cu12==12.3.101
-nvidia-nvtx-cu12==12.1.105
-ollama==0.1.9
-onnxruntime-gpu==1.17.1
-openai==1.12.0
-opencv-python==4.9.0.80
+ollama==0.2.1
+onnxruntime==1.17.3
+onnxruntime_gpu==1.17.1
+openai==1.35.14
+opencv_python==4.9.0.80
+opencv_python_headless==4.9.0.80
openpyxl==3.1.2
-packaging==23.2
-pandas==2.2.1
-pdfminer.six==20221105
+pandas==2.2.2
pdfplumber==0.10.4
peewee==3.17.1
-pillow==10.3.0
-protobuf==4.25.3
-psutil==5.9.8
-pyarrow==15.0.0
-pyarrow-hotfix==0.6
+Pillow==10.4.0
+pipreqs==0.5.0
+protobuf==5.27.2
pyclipper==1.3.0.post5
-pycparser==2.21
-pycryptodome
-pycryptodome-test-vectors
-pycryptodomex
-pydantic==2.6.2
-pydantic_core==2.16.3
-PyJWT==2.8.0
-PyMySQL==1.1.1
+pycryptodomex==3.20.0
PyPDF2==3.0.1
-pypdfium2==4.27.0
-python-dateutil==2.8.2
-python-docx==1.1.0
+pytest==8.2.2
python-dotenv==1.0.1
-python-pptx==0.6.23
-PyYAML==6.0.1
+python_dateutil==2.8.2
+python_pptx==0.6.23
+readability_lxml==0.8.1
redis==5.0.3
-regex==2023.12.25
-requests==2.31.0
-ruamel.yaml==0.18.6
-ruamel.yaml.clib==0.2.8
-safetensors==0.4.2
-scikit-learn==1.4.1.post1
-scipy==1.12.0
-sentence-transformers==2.4.0
-shapely==2.0.3
+Requests==2.32.3
+roman_numbers==1.0.2
+ruamel.base==1.0.0
+scikit_learn==1.4.1.post1
+selenium==4.22.0
+setuptools==69.5.1
+Shapely==2.0.5
six==1.16.0
-sniffio==1.3.1
StrEnum==0.4.15
-sympy==1.12
-threadpoolctl==3.3.0
tika==2.6.0
tiktoken==0.6.0
-tokenizers==0.15.2
-torch==2.2.1
-tqdm==4.66.2
+torch==2.3.0
transformers==4.38.1
-triton==2.2.0
-typing_extensions==4.10.0
-tzdata==2024.1
-urllib3==2.2.1
+umap==0.1.1
+volcengine==1.0.146
+webdriver_manager==4.0.1
Werkzeug==3.0.3
-xgboost==2.0.3
-XlsxWriter==3.2.0
+wikipedia==1.4.0
+word2number==1.1
+xgboost==2.1.0
xpinyin==0.7.6
-xxhash==3.4.1
-yarl==1.9.4
zhipuai==2.0.1
-BCEmbedding
-loguru==0.7.2
-umap-learn
-fasttext==0.9.2
-pybind11==2.13.1
-volcengine==1.0.141
-readability-lxml==0.8.1
-html_text==0.6.2
-selenium==4.21.0
-webdriver-manager==4.0.1
-cn2an==0.5.22
-roman-numbers==1.0.2
-word2number==1.1
-markdown==3.6
-mistralai==0.4.2
-boto3==1.34.140
-duckduckgo_search==6.1.9
-google-generativeai==0.7.2
-groq==0.9.0
-wikipedia==1.4.0
From 92cf45134adabff305b38d2f7fea9d768a030995 Mon Sep 17 00:00:00 2001
From: H <43509927+guoyuhao2330@users.noreply.github.com>
Date: Fri, 19 Jul 2024 18:23:24 +0800
Subject: [PATCH 03/11] Update llm_service.py
---
api/db/services/llm_service.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/api/db/services/llm_service.py b/api/db/services/llm_service.py
index 5906927b7bc..a994d6103eb 100644
--- a/api/db/services/llm_service.py
+++ b/api/db/services/llm_service.py
@@ -70,7 +70,7 @@ def model_instance(cls, tenant_id, llm_type,
elif llm_type == LLMType.SPEECH2TEXT.value:
mdlnm = tenant.asr_id
elif llm_type == LLMType.IMAGE2TEXT.value:
- mdlnm = tenant.img2txt_id
+ mdlnm = tenant.img2txt_id if not llm_name else llm_name
elif llm_type == LLMType.CHAT.value:
mdlnm = tenant.llm_id if not llm_name else llm_name
elif llm_type == LLMType.RERANK:
From ad5a5b8bed32a47c073f0484feb235bcff6e94cd Mon Sep 17 00:00:00 2001
From: H <43509927+guoyuhao2330@users.noreply.github.com>
Date: Fri, 19 Jul 2024 18:24:37 +0800
Subject: [PATCH 04/11] Update index.tsx
---
web/src/components/llm-setting-items/index.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/web/src/components/llm-setting-items/index.tsx b/web/src/components/llm-setting-items/index.tsx
index a8365d616e8..c31d7aabeea 100644
--- a/web/src/components/llm-setting-items/index.tsx
+++ b/web/src/components/llm-setting-items/index.tsx
@@ -46,7 +46,7 @@ const LlmSettingItems = ({ prefix, formItemLayout = {} }: IProps) => {
{...formItemLayout}
rules={[{ required: true, message: t('modelMessage') }]}
>
-
+
Date: Mon, 22 Jul 2024 18:27:56 +0800
Subject: [PATCH 05/11] Update init_data.py
---
api/db/init_data.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/api/db/init_data.py b/api/db/init_data.py
index 0acfe7b12a5..61fd0e6de01 100644
--- a/api/db/init_data.py
+++ b/api/db/init_data.py
@@ -121,6 +121,8 @@ def init_llm_factory():
LLMFactoriesService.filter_delete([LLMFactoriesService.model.name == "QAnything"])
LLMService.filter_delete([LLMService.model.fid == "QAnything"])
TenantLLMService.filter_update([TenantLLMService.model.llm_factory == "QAnything"], {"llm_factory": "Youdao"})
+ TenantService.filter_update([1 == 1], {
+ "parser_ids": "naive:General,qa:Q&A,resume:Resume,manual:Manual,table:Table,paper:Paper,book:Book,laws:Laws,presentation:Presentation,picture:Picture,one:One,audio:Audio"})
## insert openai two embedding models to the current openai user.
print("Start to insert 2 OpenAI embedding models...")
tenant_ids = set([row["tenant_id"] for row in TenantLLMService.get_openai_models()])
From addfea5f889c6464e904c68357589ed32f6562d1 Mon Sep 17 00:00:00 2001
From: H <43509927+guoyuhao2330@users.noreply.github.com>
Date: Thu, 8 Aug 2024 16:45:54 +0800
Subject: [PATCH 06/11] Update __init__.py
---
agent/component/__init__.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/agent/component/__init__.py b/agent/component/__init__.py
index 43fa3eeb803..ccd59f9e93c 100644
--- a/agent/component/__init__.py
+++ b/agent/component/__init__.py
@@ -20,6 +20,7 @@
from .deepl import DeepL, DeepLParam
from .github import GitHub, GitHubParam
from .baidufanyi import BaiduFanyi, BaiduFanyiParam
+from .qweather import QWeather, QWeatherParam
def component_class(class_name):
m = importlib.import_module("agent.component")
From 7ce918d2e363521078da3d43b8e08c3b02864990 Mon Sep 17 00:00:00 2001
From: H <43509927+guoyuhao2330@users.noreply.github.com>
Date: Fri, 9 Aug 2024 16:08:04 +0800
Subject: [PATCH 07/11] Update api_app.py
---
api/apps/api_app.py | 279 +++++++++++++++++++++++++++++++-------------
1 file changed, 200 insertions(+), 79 deletions(-)
diff --git a/api/apps/api_app.py b/api/apps/api_app.py
index 8d7f00e8bc1..1017499d09b 100644
--- a/api/apps/api_app.py
+++ b/api/apps/api_app.py
@@ -39,6 +39,10 @@
from api.utils.file_utils import filename_type, thumbnail
from rag.utils.minio_conn import MINIO
+from api.db.services.canvas_service import CanvasTemplateService, UserCanvasService
+from agent.canvas import Canvas
+from functools import partial
+
def generate_confirmation_token(tenent_id):
serializer = URLSafeTimedSerializer(tenent_id)
@@ -46,7 +50,6 @@ def generate_confirmation_token(tenent_id):
@manager.route('/new_token', methods=['POST'])
-@validate_request("dialog_id")
@login_required
def new_token():
req = request.json
@@ -57,12 +60,17 @@ def new_token():
tenant_id = tenants[0].tenant_id
obj = {"tenant_id": tenant_id, "token": generate_confirmation_token(tenant_id),
- "dialog_id": req["dialog_id"],
"create_time": current_timestamp(),
"create_date": datetime_format(datetime.now()),
"update_time": None,
"update_date": None
}
+ if req.get("canvas_ids"):
+ obj["dialog_id"] = req["canvas_ids"]
+ obj["source"] = "agent"
+ else:
+ obj["dialog_id"] = req["dialog_id"]
+
if not APITokenService.save(**obj):
return get_data_error_result(retmsg="Fail to new a dialog!")
@@ -112,15 +120,15 @@ def stats():
"from_date",
(datetime.now() -
timedelta(
- days=7)).strftime("%Y-%m-%d 24:00:00")),
+ days=7)).strftime("%Y-%m-%d 24:00:00")),
request.args.get(
"to_date",
datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
res = {
"pv": [(o["dt"], o["pv"]) for o in objs],
"uv": [(o["dt"], o["uv"]) for o in objs],
- "speed": [(o["dt"], float(o["tokens"])/(float(o["duration"]+0.1))) for o in objs],
- "tokens": [(o["dt"], float(o["tokens"])/1000.) for o in objs],
+ "speed": [(o["dt"], float(o["tokens"]) / (float(o["duration"] + 0.1))) for o in objs],
+ "tokens": [(o["dt"], float(o["tokens"]) / 1000.) for o in objs],
"round": [(o["dt"], o["round"]) for o in objs],
"thumb_up": [(o["dt"], o["thumb_up"]) for o in objs]
}
@@ -138,21 +146,39 @@ def set_conversation():
data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR)
req = request.json
try:
- e, dia = DialogService.get_by_id(objs[0].dialog_id)
- if not e:
- return get_data_error_result(retmsg="Dialog not found")
- conv = {
- "id": get_uuid(),
- "dialog_id": dia.id,
- "user_id": request.args.get("user_id", ""),
- "message": [{"role": "assistant", "content": dia.prompt_config["prologue"]}]
- }
- API4ConversationService.save(**conv)
- e, conv = API4ConversationService.get_by_id(conv["id"])
- if not e:
- return get_data_error_result(retmsg="Fail to new a conversation!")
- conv = conv.to_dict()
- return get_json_result(data=conv)
+ if objs[0].source == "agent":
+ e, c = UserCanvasService.get_by_id(objs[0].dialog_id)
+ if not e:
+ return server_error_response("canvas not found.")
+ conv = {
+ "id": get_uuid(),
+ "dialog_id": c.id,
+ "user_id": request.args.get("user_id", ""),
+ "message": [{"role": "assistant", "content": "Hi there!"}],
+ "source": "agent"
+ }
+ API4ConversationService.save(**conv)
+ e, conv = API4ConversationService.get_by_id(conv["id"])
+ if not e:
+ return get_data_error_result(retmsg="Fail to new a conversation!")
+ conv = conv.to_dict()
+ return get_json_result(data=conv)
+ else:
+ e, dia = DialogService.get_by_id(objs[0].dialog_id)
+ if not e:
+ return get_data_error_result(retmsg="Dialog not found")
+ conv = {
+ "id": get_uuid(),
+ "dialog_id": dia.id,
+ "user_id": request.args.get("user_id", ""),
+ "message": [{"role": "assistant", "content": dia.prompt_config["prologue"]}]
+ }
+ API4ConversationService.save(**conv)
+ e, conv = API4ConversationService.get_by_id(conv["id"])
+ if not e:
+ return get_data_error_result(retmsg="Fail to new a conversation!")
+ conv = conv.to_dict()
+ return get_json_result(data=conv)
except Exception as e:
return server_error_response(e)
@@ -161,7 +187,8 @@ def set_conversation():
@validate_request("conversation_id", "messages")
def completion():
token = request.headers.get('Authorization').split()[1]
- if not APIToken.query(token=token):
+ objs = APIToken.query(token=token)
+ if not objs:
return get_json_result(
data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR)
req = request.json
@@ -179,65 +206,159 @@ def completion():
msg.append({"role": m["role"], "content": m["content"]})
try:
- conv.message.append(msg[-1])
- e, dia = DialogService.get_by_id(conv.dialog_id)
- if not e:
- return get_data_error_result(retmsg="Dialog not found!")
- del req["conversation_id"]
- del req["messages"]
+ if conv.source == "agent":
+ stream = req.get("stream", True)
+ conv.message.append(msg[-1])
+ e, cvs = UserCanvasService.get_by_id(conv.dialog_id)
+ if not e:
+ return server_error_response("canvas not found.")
+ del req["conversation_id"]
+ del req["messages"]
- if not conv.reference:
- conv.reference = []
- conv.message.append({"role": "assistant", "content": ""})
- conv.reference.append({"chunks": [], "doc_aggs": []})
+ if not isinstance(cvs.dsl, str):
+ cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False)
- def fillin_conv(ans):
- nonlocal conv
if not conv.reference:
- conv.reference.append(ans["reference"])
- else: conv.reference[-1] = ans["reference"]
- conv.message[-1] = {"role": "assistant", "content": ans["answer"]}
-
- def rename_field(ans):
- reference = ans['reference']
- if not isinstance(reference, dict):
- return
- for chunk_i in reference.get('chunks', []):
- if 'docnm_kwd' in chunk_i:
- chunk_i['doc_name'] = chunk_i['docnm_kwd']
- chunk_i.pop('docnm_kwd')
-
- def stream():
- nonlocal dia, msg, req, conv
- try:
- for ans in chat(dia, msg, True, **req):
- fillin_conv(ans)
- rename_field(ans)
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans}, ensure_ascii=False) + "\n\n"
- API4ConversationService.append_message(conv.id, conv.to_dict())
- except Exception as e:
- yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e),
- "data": {"answer": "**ERROR**: "+str(e), "reference": []}},
- ensure_ascii=False) + "\n\n"
- yield "data:"+json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n"
-
- if req.get("stream", True):
- resp = Response(stream(), mimetype="text/event-stream")
- resp.headers.add_header("Cache-control", "no-cache")
- resp.headers.add_header("Connection", "keep-alive")
- resp.headers.add_header("X-Accel-Buffering", "no")
- resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
- return resp
- else:
- answer = None
- for ans in chat(dia, msg, **req):
- answer = ans
+ conv.reference = []
+ conv.message.append({"role": "assistant", "content": ""})
+ conv.reference.append({"chunks": [], "doc_aggs": []})
+
+ def fillin_conv(ans):
+ nonlocal conv
+ if not conv.reference:
+ conv.reference.append(ans["reference"])
+ else:
+ conv.reference[-1] = ans["reference"]
+ conv.message[-1] = {"role": "assistant", "content": ans["answer"]}
+
+ def rename_field(ans):
+ reference = ans['reference']
+ if not isinstance(reference, dict):
+ return
+ for chunk_i in reference.get('chunks', []):
+ if 'docnm_kwd' in chunk_i:
+ chunk_i['doc_name'] = chunk_i['docnm_kwd']
+ chunk_i.pop('docnm_kwd')
+
+ final_ans = {"reference": [], "content": ""}
+ canvas = Canvas(cvs.dsl, objs[0].tenant_id)
+
+ canvas.messages.append(msg[-1])
+ canvas.add_user_input(msg[-1]["content"])
+ answer = canvas.run(stream=stream)
+
+ assert answer is not None, "Nothing. Is it over?"
+
+ if stream:
+ assert isinstance(answer, partial), "Nothing. Is it over?"
+
+ def sse():
+ nonlocal answer, cvs, conv
+ try:
+ for ans in answer():
+ for k in ans.keys():
+ final_ans[k] = ans[k]
+ ans = {"answer": ans["content"], "reference": ans.get("reference", [])}
+ fillin_conv(ans)
+ rename_field(ans)
+ yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans},
+ ensure_ascii=False) + "\n\n"
+
+ canvas.messages.append({"role": "assistant", "content": final_ans["content"]})
+ if final_ans.get("reference"):
+ canvas.reference.append(final_ans["reference"])
+ cvs.dsl = json.loads(str(canvas))
+ API4ConversationService.append_message(conv.id, conv.to_dict())
+ except Exception as e:
+ yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e),
+ "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
+ ensure_ascii=False) + "\n\n"
+ yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n"
+
+ resp = Response(sse(), mimetype="text/event-stream")
+ resp.headers.add_header("Cache-control", "no-cache")
+ resp.headers.add_header("Connection", "keep-alive")
+ resp.headers.add_header("X-Accel-Buffering", "no")
+ resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
+ return resp
+
+ final_ans["content"] = "\n".join(answer["content"]) if "content" in answer else ""
+ canvas.messages.append({"role": "assistant", "content": final_ans["content"]})
+ if final_ans.get("reference"):
+ canvas.reference.append(final_ans["reference"])
+ cvs.dsl = json.loads(str(canvas))
+
+ result = None
+ for ans in answer():
+ ans = {"answer": ans["content"], "reference": ans.get("reference", [])}
+ result = ans
fillin_conv(ans)
API4ConversationService.append_message(conv.id, conv.to_dict())
break
+ rename_field(result)
+ return get_json_result(data=result)
+ else:
+ conv.message.append(msg[-1])
+ e, dia = DialogService.get_by_id(conv.dialog_id)
+ if not e:
+ return get_data_error_result(retmsg="Dialog not found!")
+ del req["conversation_id"]
+ del req["messages"]
+
+ if not conv.reference:
+ conv.reference = []
+ conv.message.append({"role": "assistant", "content": ""})
+ conv.reference.append({"chunks": [], "doc_aggs": []})
+
+ def fillin_conv(ans):
+ nonlocal conv
+ if not conv.reference:
+ conv.reference.append(ans["reference"])
+ else:
+ conv.reference[-1] = ans["reference"]
+ conv.message[-1] = {"role": "assistant", "content": ans["answer"]}
+
+ def rename_field(ans):
+ reference = ans['reference']
+ if not isinstance(reference, dict):
+ return
+ for chunk_i in reference.get('chunks', []):
+ if 'docnm_kwd' in chunk_i:
+ chunk_i['doc_name'] = chunk_i['docnm_kwd']
+ chunk_i.pop('docnm_kwd')
+
+ def stream():
+ nonlocal dia, msg, req, conv
+ try:
+ for ans in chat(dia, msg, True, **req):
+ fillin_conv(ans)
+ rename_field(ans)
+ yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans},
+ ensure_ascii=False) + "\n\n"
+ API4ConversationService.append_message(conv.id, conv.to_dict())
+ except Exception as e:
+ yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e),
+ "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
+ ensure_ascii=False) + "\n\n"
+ yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n"
+
+ if req.get("stream", True):
+ resp = Response(stream(), mimetype="text/event-stream")
+ resp.headers.add_header("Cache-control", "no-cache")
+ resp.headers.add_header("Connection", "keep-alive")
+ resp.headers.add_header("X-Accel-Buffering", "no")
+ resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
+ return resp
+ else:
+ answer = None
+ for ans in chat(dia, msg, **req):
+ answer = ans
+ fillin_conv(ans)
+ API4ConversationService.append_message(conv.id, conv.to_dict())
+ break
- rename_field(answer)
- return get_json_result(data=answer)
+ rename_field(answer)
+ return get_json_result(data=answer)
except Exception as e:
return server_error_response(e)
@@ -332,7 +453,7 @@ def upload():
"thumbnail": thumbnail(filename, blob)
}
- form_data=request.form
+ form_data = request.form
if "parser_id" in form_data.keys():
if request.form.get("parser_id").strip() in list(vars(ParserType).values())[1:-3]:
doc["parser_id"] = request.form.get("parser_id").strip()
@@ -361,7 +482,7 @@ def upload():
if not tenant_id:
return get_data_error_result(retmsg="Tenant not found!")
- #e, doc = DocumentService.get_by_id(doc["id"])
+ # e, doc = DocumentService.get_by_id(doc["id"])
TaskService.filter_delete([Task.doc_id == doc["id"]])
e, doc = DocumentService.get_by_id(doc["id"])
doc = doc.to_dict()
@@ -369,7 +490,7 @@ def upload():
bucket, name = File2DocumentService.get_minio_address(doc_id=doc["id"])
queue_tasks(doc, bucket, name)
except Exception as e:
- return server_error_response(e)
+ return server_error_response(e)
return get_json_result(data=doc_result.to_json())
@@ -448,7 +569,7 @@ def list_kb_docs():
docs = [{"doc_id": doc['id'], "doc_name": doc['name']} for doc in docs]
return get_json_result(data={"total": tol, "docs": docs})
-
+
except Exception as e:
return server_error_response(e)
@@ -549,7 +670,8 @@ def fillin_conv(ans):
nonlocal conv
if not conv.reference:
conv.reference.append(ans["reference"])
- else: conv.reference[-1] = ans["reference"]
+ else:
+ conv.reference[-1] = ans["reference"]
conv.message[-1] = {"role": "assistant", "content": ans["answer"]}
data_type_picture = {
@@ -638,4 +760,3 @@ def retrieval():
return get_json_result(data=False, retmsg=f'No chunk found! Check the chunk status please!',
retcode=RetCode.DATA_ERROR)
return server_error_response(e)
-
From b51f9fd52423ced09aa92903090748dcf7a60e4e Mon Sep 17 00:00:00 2001
From: H <43509927+guoyuhao2330@users.noreply.github.com>
Date: Fri, 9 Aug 2024 16:12:57 +0800
Subject: [PATCH 08/11] Update db_models.py
---
api/db/db_models.py | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/api/db/db_models.py b/api/db/db_models.py
index 267c34b7be6..9df1580d354 100644
--- a/api/db/db_models.py
+++ b/api/db/db_models.py
@@ -858,6 +858,7 @@ class APIToken(DataBaseModel):
tenant_id = CharField(max_length=32, null=False, index=True)
token = CharField(max_length=255, null=False, index=True)
dialog_id = CharField(max_length=32, null=False, index=True)
+ source = CharField(max_length=16, null=True, help_text="none|agent|dialog", index=True)
class Meta:
db_table = "api_token"
@@ -871,6 +872,7 @@ class API4Conversation(DataBaseModel):
message = JSONField(null=True)
reference = JSONField(null=True, default=[])
tokens = IntegerField(default=0)
+ source = CharField(max_length=16, null=True, help_text="none|agent|dialog", index=True)
duration = FloatField(default=0, index=True)
round = IntegerField(default=0, index=True)
@@ -949,3 +951,17 @@ def migrate_db():
)
except Exception as e:
pass
+ try:
+ migrate(
+ migrator.add_column('api_token', 'source',
+ CharField(max_length=16, null=True, help_text="none|agent|dialog", index=True))
+ )
+ except Exception as e:
+ pass
+ try:
+ migrate(
+ migrator.add_column('api_4_conversation', 'source',
+ CharField(max_length=16, null=True, help_text="none|agent|dialog", index=True))
+ )
+ except Exception as e:
+ pass
From 30c227659d2ec8674e1ac457c582be81f56aa8a4 Mon Sep 17 00:00:00 2001
From: H <43509927+guoyuhao2330@users.noreply.github.com>
Date: Fri, 9 Aug 2024 16:24:54 +0800
Subject: [PATCH 09/11] Update api_app.py
---
api/apps/api_app.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/api/apps/api_app.py b/api/apps/api_app.py
index 1017499d09b..2b85d6fa2f2 100644
--- a/api/apps/api_app.py
+++ b/api/apps/api_app.py
@@ -65,8 +65,8 @@ def new_token():
"update_time": None,
"update_date": None
}
- if req.get("canvas_ids"):
- obj["dialog_id"] = req["canvas_ids"]
+ if req.get("canvas_id"):
+ obj["dialog_id"] = req["canvas_id"]
obj["source"] = "agent"
else:
obj["dialog_id"] = req["dialog_id"]
From ecbf5075cfb22cba5d08939d26bcb5ab512fde98 Mon Sep 17 00:00:00 2001
From: H <43509927+guoyuhao2330@users.noreply.github.com>
Date: Fri, 9 Aug 2024 16:31:58 +0800
Subject: [PATCH 10/11] Update api_app.py
---
api/apps/api_app.py | 69 +++++++++++++++++----------------------------
1 file changed, 26 insertions(+), 43 deletions(-)
diff --git a/api/apps/api_app.py b/api/apps/api_app.py
index 2b85d6fa2f2..2db920cb044 100644
--- a/api/apps/api_app.py
+++ b/api/apps/api_app.py
@@ -205,6 +205,23 @@ def completion():
continue
msg.append({"role": m["role"], "content": m["content"]})
+ def fillin_conv(ans):
+ nonlocal conv
+ if not conv.reference:
+ conv.reference.append(ans["reference"])
+ else:
+ conv.reference[-1] = ans["reference"]
+ conv.message[-1] = {"role": "assistant", "content": ans["answer"]}
+
+ def rename_field(ans):
+ reference = ans['reference']
+ if not isinstance(reference, dict):
+ return
+ for chunk_i in reference.get('chunks', []):
+ if 'docnm_kwd' in chunk_i:
+ chunk_i['doc_name'] = chunk_i['docnm_kwd']
+ chunk_i.pop('docnm_kwd')
+
try:
if conv.source == "agent":
stream = req.get("stream", True)
@@ -223,23 +240,6 @@ def completion():
conv.message.append({"role": "assistant", "content": ""})
conv.reference.append({"chunks": [], "doc_aggs": []})
- def fillin_conv(ans):
- nonlocal conv
- if not conv.reference:
- conv.reference.append(ans["reference"])
- else:
- conv.reference[-1] = ans["reference"]
- conv.message[-1] = {"role": "assistant", "content": ans["answer"]}
-
- def rename_field(ans):
- reference = ans['reference']
- if not isinstance(reference, dict):
- return
- for chunk_i in reference.get('chunks', []):
- if 'docnm_kwd' in chunk_i:
- chunk_i['doc_name'] = chunk_i['docnm_kwd']
- chunk_i.pop('docnm_kwd')
-
final_ans = {"reference": [], "content": ""}
canvas = Canvas(cvs.dsl, objs[0].tenant_id)
@@ -310,23 +310,6 @@ def sse():
conv.message.append({"role": "assistant", "content": ""})
conv.reference.append({"chunks": [], "doc_aggs": []})
- def fillin_conv(ans):
- nonlocal conv
- if not conv.reference:
- conv.reference.append(ans["reference"])
- else:
- conv.reference[-1] = ans["reference"]
- conv.message[-1] = {"role": "assistant", "content": ans["answer"]}
-
- def rename_field(ans):
- reference = ans['reference']
- if not isinstance(reference, dict):
- return
- for chunk_i in reference.get('chunks', []):
- if 'docnm_kwd' in chunk_i:
- chunk_i['doc_name'] = chunk_i['docnm_kwd']
- chunk_i.pop('docnm_kwd')
-
def stream():
nonlocal dia, msg, req, conv
try:
@@ -349,16 +332,16 @@ def stream():
resp.headers.add_header("X-Accel-Buffering", "no")
resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
return resp
- else:
- answer = None
- for ans in chat(dia, msg, **req):
- answer = ans
- fillin_conv(ans)
- API4ConversationService.append_message(conv.id, conv.to_dict())
- break
+
+ answer = None
+ for ans in chat(dia, msg, **req):
+ answer = ans
+ fillin_conv(ans)
+ API4ConversationService.append_message(conv.id, conv.to_dict())
+ break
- rename_field(answer)
- return get_json_result(data=answer)
+ rename_field(answer)
+ return get_json_result(data=answer)
except Exception as e:
return server_error_response(e)
From eb2c31a6553689d35f53286cf62618fe722c4af7 Mon Sep 17 00:00:00 2001
From: H <43509927+guoyuhao2330@users.noreply.github.com>
Date: Fri, 9 Aug 2024 16:50:25 +0800
Subject: [PATCH 11/11] Update api_app.py
---
api/apps/api_app.py | 90 +++++++++++++++++++++------------------------
1 file changed, 41 insertions(+), 49 deletions(-)
diff --git a/api/apps/api_app.py b/api/apps/api_app.py
index 2db920cb044..eb9bd6c520e 100644
--- a/api/apps/api_app.py
+++ b/api/apps/api_app.py
@@ -158,10 +158,6 @@ def set_conversation():
"source": "agent"
}
API4ConversationService.save(**conv)
- e, conv = API4ConversationService.get_by_id(conv["id"])
- if not e:
- return get_data_error_result(retmsg="Fail to new a conversation!")
- conv = conv.to_dict()
return get_json_result(data=conv)
else:
e, dia = DialogService.get_by_id(objs[0].dialog_id)
@@ -174,10 +170,6 @@ def set_conversation():
"message": [{"role": "assistant", "content": dia.prompt_config["prologue"]}]
}
API4ConversationService.save(**conv)
- e, conv = API4ConversationService.get_by_id(conv["id"])
- if not e:
- return get_data_error_result(retmsg="Fail to new a conversation!")
- conv = conv.to_dict()
return get_json_result(data=conv)
except Exception as e:
return server_error_response(e)
@@ -297,51 +289,51 @@ def sse():
break
rename_field(result)
return get_json_result(data=result)
- else:
- conv.message.append(msg[-1])
- e, dia = DialogService.get_by_id(conv.dialog_id)
- if not e:
- return get_data_error_result(retmsg="Dialog not found!")
- del req["conversation_id"]
- del req["messages"]
+
+ #******************For dialog******************
+ conv.message.append(msg[-1])
+ e, dia = DialogService.get_by_id(conv.dialog_id)
+ if not e:
+ return get_data_error_result(retmsg="Dialog not found!")
+ del req["conversation_id"]
+ del req["messages"]
- if not conv.reference:
- conv.reference = []
- conv.message.append({"role": "assistant", "content": ""})
- conv.reference.append({"chunks": [], "doc_aggs": []})
+ if not conv.reference:
+ conv.reference = []
+ conv.message.append({"role": "assistant", "content": ""})
+ conv.reference.append({"chunks": [], "doc_aggs": []})
- def stream():
- nonlocal dia, msg, req, conv
- try:
- for ans in chat(dia, msg, True, **req):
- fillin_conv(ans)
- rename_field(ans)
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans},
- ensure_ascii=False) + "\n\n"
- API4ConversationService.append_message(conv.id, conv.to_dict())
- except Exception as e:
- yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e),
- "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
+ def stream():
+ nonlocal dia, msg, req, conv
+ try:
+ for ans in chat(dia, msg, True, **req):
+ fillin_conv(ans)
+ rename_field(ans)
+ yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans},
ensure_ascii=False) + "\n\n"
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n"
-
- if req.get("stream", True):
- resp = Response(stream(), mimetype="text/event-stream")
- resp.headers.add_header("Cache-control", "no-cache")
- resp.headers.add_header("Connection", "keep-alive")
- resp.headers.add_header("X-Accel-Buffering", "no")
- resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
- return resp
-
- answer = None
- for ans in chat(dia, msg, **req):
- answer = ans
- fillin_conv(ans)
API4ConversationService.append_message(conv.id, conv.to_dict())
- break
-
- rename_field(answer)
- return get_json_result(data=answer)
+ except Exception as e:
+ yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e),
+ "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
+ ensure_ascii=False) + "\n\n"
+ yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n"
+
+ if req.get("stream", True):
+ resp = Response(stream(), mimetype="text/event-stream")
+ resp.headers.add_header("Cache-control", "no-cache")
+ resp.headers.add_header("Connection", "keep-alive")
+ resp.headers.add_header("X-Accel-Buffering", "no")
+ resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
+ return resp
+
+ answer = None
+ for ans in chat(dia, msg, **req):
+ answer = ans
+ fillin_conv(ans)
+ API4ConversationService.append_message(conv.id, conv.to_dict())
+ break
+ rename_field(answer)
+ return get_json_result(data=answer)
except Exception as e:
return server_error_response(e)