liuhua
liuhua
commited on
Commit
·
40a1db3
1
Parent(s):
7b36ea6
Refactor Chat API (#2804)
Browse files### What problem does this PR solve?
Refactor Chat API
### Type of change
- [x] Refactoring
---------
Co-authored-by: liuhua <10215101452@stu.ecun.edu.cn>
- api/apps/sdk/{assistant.py → chat.py} +287 -304
- api/apps/sdk/dataset.py +19 -27
- api/db/services/dialog_service.py +25 -3
- api/http_api.md +385 -92
- api/python_api_reference.md +61 -100
- api/utils/api_utils.py +3 -4
- sdk/python/ragflow/__init__.py +1 -1
- sdk/python/ragflow/modules/base.py +4 -4
- sdk/python/ragflow/modules/{assistant.py → chat.py} +8 -16
- sdk/python/ragflow/ragflow.py +25 -24
- sdk/python/test/t_assistant.py +0 -68
- sdk/python/test/t_chat.py +56 -0
- sdk/python/test/t_dataset.py +2 -2
api/apps/sdk/{assistant.py → chat.py}
RENAMED
@@ -1,304 +1,287 @@
|
|
1 |
-
#
|
2 |
-
# Copyright 2024 The InfiniFlow Authors. All Rights Reserved.
|
3 |
-
#
|
4 |
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
5 |
-
# you may not use this file except in compliance with the License.
|
6 |
-
# You may obtain a copy of the License at
|
7 |
-
#
|
8 |
-
# http://www.apache.org/licenses/LICENSE-2.0
|
9 |
-
#
|
10 |
-
# Unless required by applicable law or agreed to in writing, software
|
11 |
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
12 |
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13 |
-
# See the License for the specific language governing permissions and
|
14 |
-
# limitations under the License.
|
15 |
-
#
|
16 |
-
from flask import request
|
17 |
-
|
18 |
-
from api.db import StatusEnum
|
19 |
-
from api.db.db_models import TenantLLM
|
20 |
-
from api.db.services.dialog_service import DialogService
|
21 |
-
from api.db.services.knowledgebase_service import KnowledgebaseService
|
22 |
-
from api.db.services.llm_service import LLMService, TenantLLMService
|
23 |
-
from api.db.services.user_service import TenantService
|
24 |
-
from api.settings import RetCode
|
25 |
-
from api.utils import get_uuid
|
26 |
-
from api.utils.api_utils import
|
27 |
-
from api.utils.api_utils import
|
28 |
-
|
29 |
-
|
30 |
-
@
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
"
|
61 |
-
"
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
for
|
68 |
-
if
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
req["
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
res[
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
req =
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
return
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
res["
|
286 |
-
|
287 |
-
|
288 |
-
"keywords_similarity_weight": res["vector_similarity_weight"],
|
289 |
-
"top_n": res["top_n"],
|
290 |
-
"rerank_model": res['rerank_id']}
|
291 |
-
res["prompt"].update(new_dict)
|
292 |
-
for key in key_list:
|
293 |
-
del res[key]
|
294 |
-
res["llm"] = res.pop("llm_setting")
|
295 |
-
res["llm"]["model_name"] = res.pop("llm_id")
|
296 |
-
kb_list = []
|
297 |
-
for kb_id in res["kb_ids"]:
|
298 |
-
kb = KnowledgebaseService.query(id=kb_id)
|
299 |
-
kb_list.append(kb[0].to_json())
|
300 |
-
del res["kb_ids"]
|
301 |
-
res["knowledgebases"] = kb_list
|
302 |
-
res["avatar"] = res.pop("icon")
|
303 |
-
list_assts.append(res)
|
304 |
-
return get_json_result(data=list_assts)
|
|
|
1 |
+
#
|
2 |
+
# Copyright 2024 The InfiniFlow Authors. All Rights Reserved.
|
3 |
+
#
|
4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5 |
+
# you may not use this file except in compliance with the License.
|
6 |
+
# You may obtain a copy of the License at
|
7 |
+
#
|
8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9 |
+
#
|
10 |
+
# Unless required by applicable law or agreed to in writing, software
|
11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13 |
+
# See the License for the specific language governing permissions and
|
14 |
+
# limitations under the License.
|
15 |
+
#
|
16 |
+
from flask import request
|
17 |
+
|
18 |
+
from api.db import StatusEnum
|
19 |
+
from api.db.db_models import TenantLLM
|
20 |
+
from api.db.services.dialog_service import DialogService
|
21 |
+
from api.db.services.knowledgebase_service import KnowledgebaseService
|
22 |
+
from api.db.services.llm_service import LLMService, TenantLLMService
|
23 |
+
from api.db.services.user_service import TenantService
|
24 |
+
from api.settings import RetCode
|
25 |
+
from api.utils import get_uuid
|
26 |
+
from api.utils.api_utils import get_error_data_result, token_required
|
27 |
+
from api.utils.api_utils import get_result
|
28 |
+
|
29 |
+
@manager.route('/chat', methods=['POST'])
|
30 |
+
@token_required
|
31 |
+
def create(tenant_id):
|
32 |
+
req=request.json
|
33 |
+
if not req.get("knowledgebases"):
|
34 |
+
return get_error_data_result(retmsg="knowledgebases are required")
|
35 |
+
kb_list = []
|
36 |
+
for kb in req.get("knowledgebases"):
|
37 |
+
if not kb["id"]:
|
38 |
+
return get_error_data_result(retmsg="knowledgebase needs id")
|
39 |
+
if not KnowledgebaseService.query(id=kb["id"], tenant_id=tenant_id):
|
40 |
+
return get_error_data_result(retmsg="you do not own the knowledgebase")
|
41 |
+
# if not DocumentService.query(kb_id=kb["id"]):
|
42 |
+
# return get_error_data_result(retmsg="There is a invalid knowledgebase")
|
43 |
+
kb_list.append(kb["id"])
|
44 |
+
req["kb_ids"] = kb_list
|
45 |
+
# llm
|
46 |
+
llm = req.get("llm")
|
47 |
+
if llm:
|
48 |
+
if "model_name" in llm:
|
49 |
+
req["llm_id"] = llm.pop("model_name")
|
50 |
+
req["llm_setting"] = req.pop("llm")
|
51 |
+
e, tenant = TenantService.get_by_id(tenant_id)
|
52 |
+
if not e:
|
53 |
+
return get_error_data_result(retmsg="Tenant not found!")
|
54 |
+
# prompt
|
55 |
+
prompt = req.get("prompt")
|
56 |
+
key_mapping = {"parameters": "variables",
|
57 |
+
"prologue": "opener",
|
58 |
+
"quote": "show_quote",
|
59 |
+
"system": "prompt",
|
60 |
+
"rerank_id": "rerank_model",
|
61 |
+
"vector_similarity_weight": "keywords_similarity_weight"}
|
62 |
+
key_list = ["similarity_threshold", "vector_similarity_weight", "top_n", "rerank_id"]
|
63 |
+
if prompt:
|
64 |
+
for new_key, old_key in key_mapping.items():
|
65 |
+
if old_key in prompt:
|
66 |
+
prompt[new_key] = prompt.pop(old_key)
|
67 |
+
for key in key_list:
|
68 |
+
if key in prompt:
|
69 |
+
req[key] = prompt.pop(key)
|
70 |
+
req["prompt_config"] = req.pop("prompt")
|
71 |
+
# init
|
72 |
+
req["id"] = get_uuid()
|
73 |
+
req["description"] = req.get("description", "A helpful Assistant")
|
74 |
+
req["icon"] = req.get("avatar", "")
|
75 |
+
req["top_n"] = req.get("top_n", 6)
|
76 |
+
req["top_k"] = req.get("top_k", 1024)
|
77 |
+
req["rerank_id"] = req.get("rerank_id", "")
|
78 |
+
if req.get("llm_id"):
|
79 |
+
if not TenantLLMService.query(llm_name=req["llm_id"]):
|
80 |
+
return get_error_data_result(retmsg="the model_name does not exist.")
|
81 |
+
else:
|
82 |
+
req["llm_id"] = tenant.llm_id
|
83 |
+
if not req.get("name"):
|
84 |
+
return get_error_data_result(retmsg="name is required.")
|
85 |
+
if DialogService.query(name=req["name"], tenant_id=tenant_id, status=StatusEnum.VALID.value):
|
86 |
+
return get_error_data_result(retmsg="Duplicated chat name in creating dataset.")
|
87 |
+
# tenant_id
|
88 |
+
if req.get("tenant_id"):
|
89 |
+
return get_error_data_result(retmsg="tenant_id must not be provided.")
|
90 |
+
req["tenant_id"] = tenant_id
|
91 |
+
# prompt more parameter
|
92 |
+
default_prompt = {
|
93 |
+
"system": """你是一个智能助手,请总结知识库的内容来回答问题,请列举知识库中的数据详细回答。当所有知识库内容都与问题无关时,你的回答必须包括“知识库中未找到您要的答案!”这句话。回答需要考虑聊天历史。
|
94 |
+
以下是知识库:
|
95 |
+
{knowledge}
|
96 |
+
以上是知识库。""",
|
97 |
+
"prologue": "您好,我是您的助手小樱,长得可爱又善良,can I help you?",
|
98 |
+
"parameters": [
|
99 |
+
{"key": "knowledge", "optional": False}
|
100 |
+
],
|
101 |
+
"empty_response": "Sorry! 知识库中未找到相关内容!"
|
102 |
+
}
|
103 |
+
key_list_2 = ["system", "prologue", "parameters", "empty_response"]
|
104 |
+
if "prompt_config" not in req:
|
105 |
+
req['prompt_config'] = {}
|
106 |
+
for key in key_list_2:
|
107 |
+
temp = req['prompt_config'].get(key)
|
108 |
+
if not temp:
|
109 |
+
req['prompt_config'][key] = default_prompt[key]
|
110 |
+
for p in req['prompt_config']["parameters"]:
|
111 |
+
if p["optional"]:
|
112 |
+
continue
|
113 |
+
if req['prompt_config']["system"].find("{%s}" % p["key"]) < 0:
|
114 |
+
return get_error_data_result(
|
115 |
+
retmsg="Parameter '{}' is not used".format(p["key"]))
|
116 |
+
# save
|
117 |
+
if not DialogService.save(**req):
|
118 |
+
return get_error_data_result(retmsg="Fail to new a chat!")
|
119 |
+
# response
|
120 |
+
e, res = DialogService.get_by_id(req["id"])
|
121 |
+
if not e:
|
122 |
+
return get_error_data_result(retmsg="Fail to new a chat!")
|
123 |
+
res = res.to_json()
|
124 |
+
renamed_dict = {}
|
125 |
+
for key, value in res["prompt_config"].items():
|
126 |
+
new_key = key_mapping.get(key, key)
|
127 |
+
renamed_dict[new_key] = value
|
128 |
+
res["prompt"] = renamed_dict
|
129 |
+
del res["prompt_config"]
|
130 |
+
new_dict = {"similarity_threshold": res["similarity_threshold"],
|
131 |
+
"keywords_similarity_weight": res["vector_similarity_weight"],
|
132 |
+
"top_n": res["top_n"],
|
133 |
+
"rerank_model": res['rerank_id']}
|
134 |
+
res["prompt"].update(new_dict)
|
135 |
+
for key in key_list:
|
136 |
+
del res[key]
|
137 |
+
res["llm"] = res.pop("llm_setting")
|
138 |
+
res["llm"]["model_name"] = res.pop("llm_id")
|
139 |
+
del res["kb_ids"]
|
140 |
+
res["knowledgebases"] = req["knowledgebases"]
|
141 |
+
res["avatar"] = res.pop("icon")
|
142 |
+
return get_result(data=res)
|
143 |
+
|
144 |
+
@manager.route('/chat/<chat_id>', methods=['PUT'])
|
145 |
+
@token_required
|
146 |
+
def update(tenant_id,chat_id):
|
147 |
+
if not DialogService.query(tenant_id=tenant_id, id=chat_id, status=StatusEnum.VALID.value):
|
148 |
+
return get_error_data_result(retmsg='You do not own the chat')
|
149 |
+
req =request.json
|
150 |
+
if "knowledgebases" in req:
|
151 |
+
if not req.get("knowledgebases"):
|
152 |
+
return get_error_data_result(retmsg="knowledgebases can't be empty value")
|
153 |
+
kb_list = []
|
154 |
+
for kb in req.get("knowledgebases"):
|
155 |
+
if not kb["id"]:
|
156 |
+
return get_error_data_result(retmsg="knowledgebase needs id")
|
157 |
+
if not KnowledgebaseService.query(id=kb["id"], tenant_id=tenant_id):
|
158 |
+
return get_error_data_result(retmsg="you do not own the knowledgebase")
|
159 |
+
# if not DocumentService.query(kb_id=kb["id"]):
|
160 |
+
# return get_error_data_result(retmsg="There is a invalid knowledgebase")
|
161 |
+
kb_list.append(kb["id"])
|
162 |
+
req["kb_ids"] = kb_list
|
163 |
+
llm = req.get("llm")
|
164 |
+
if llm:
|
165 |
+
if "model_name" in llm:
|
166 |
+
req["llm_id"] = llm.pop("model_name")
|
167 |
+
req["llm_setting"] = req.pop("llm")
|
168 |
+
e, tenant = TenantService.get_by_id(tenant_id)
|
169 |
+
if not e:
|
170 |
+
return get_error_data_result(retmsg="Tenant not found!")
|
171 |
+
# prompt
|
172 |
+
prompt = req.get("prompt")
|
173 |
+
key_mapping = {"parameters": "variables",
|
174 |
+
"prologue": "opener",
|
175 |
+
"quote": "show_quote",
|
176 |
+
"system": "prompt",
|
177 |
+
"rerank_id": "rerank_model",
|
178 |
+
"vector_similarity_weight": "keywords_similarity_weight"}
|
179 |
+
key_list = ["similarity_threshold", "vector_similarity_weight", "top_n", "rerank_id"]
|
180 |
+
if prompt:
|
181 |
+
for new_key, old_key in key_mapping.items():
|
182 |
+
if old_key in prompt:
|
183 |
+
prompt[new_key] = prompt.pop(old_key)
|
184 |
+
for key in key_list:
|
185 |
+
if key in prompt:
|
186 |
+
req[key] = prompt.pop(key)
|
187 |
+
req["prompt_config"] = req.pop("prompt")
|
188 |
+
e, res = DialogService.get_by_id(chat_id)
|
189 |
+
res = res.to_json()
|
190 |
+
if "llm_id" in req:
|
191 |
+
if not TenantLLMService.query(llm_name=req["llm_id"]):
|
192 |
+
return get_error_data_result(retmsg="the model_name does not exist.")
|
193 |
+
if "name" in req:
|
194 |
+
if not req.get("name"):
|
195 |
+
return get_error_data_result(retmsg="name is not empty.")
|
196 |
+
if req["name"].lower() != res["name"].lower() \
|
197 |
+
and len(
|
198 |
+
DialogService.query(name=req["name"], tenant_id=tenant_id, status=StatusEnum.VALID.value)) > 0:
|
199 |
+
return get_error_data_result(retmsg="Duplicated chat name in updating dataset.")
|
200 |
+
if "prompt_config" in req:
|
201 |
+
res["prompt_config"].update(req["prompt_config"])
|
202 |
+
for p in res["prompt_config"]["parameters"]:
|
203 |
+
if p["optional"]:
|
204 |
+
continue
|
205 |
+
if res["prompt_config"]["system"].find("{%s}" % p["key"]) < 0:
|
206 |
+
return get_error_data_result(retmsg="Parameter '{}' is not used".format(p["key"]))
|
207 |
+
if "llm_setting" in req:
|
208 |
+
res["llm_setting"].update(req["llm_setting"])
|
209 |
+
req["prompt_config"] = res["prompt_config"]
|
210 |
+
req["llm_setting"] = res["llm_setting"]
|
211 |
+
# avatar
|
212 |
+
if "avatar" in req:
|
213 |
+
req["icon"] = req.pop("avatar")
|
214 |
+
if "knowledgebases" in req:
|
215 |
+
req.pop("knowledgebases")
|
216 |
+
if not DialogService.update_by_id(chat_id, req):
|
217 |
+
return get_error_data_result(retmsg="Chat not found!")
|
218 |
+
return get_result()
|
219 |
+
|
220 |
+
|
221 |
+
@manager.route('/chat', methods=['DELETE'])
|
222 |
+
@token_required
|
223 |
+
def delete(tenant_id):
|
224 |
+
req = request.json
|
225 |
+
ids = req.get("ids")
|
226 |
+
if not ids:
|
227 |
+
return get_error_data_result(retmsg="ids are required")
|
228 |
+
for id in ids:
|
229 |
+
if not DialogService.query(tenant_id=tenant_id, id=id, status=StatusEnum.VALID.value):
|
230 |
+
return get_error_data_result(retmsg=f"You don't own the chat {id}")
|
231 |
+
temp_dict = {"status": StatusEnum.INVALID.value}
|
232 |
+
DialogService.update_by_id(id, temp_dict)
|
233 |
+
return get_result()
|
234 |
+
|
235 |
+
@manager.route('/chat', methods=['GET'])
|
236 |
+
@token_required
|
237 |
+
def list(tenant_id):
|
238 |
+
id = request.args.get("id")
|
239 |
+
name = request.args.get("name")
|
240 |
+
chat = DialogService.query(id=id,name=name,status=StatusEnum.VALID.value)
|
241 |
+
if not chat:
|
242 |
+
return get_error_data_result(retmsg="The chat doesn't exist")
|
243 |
+
page_number = int(request.args.get("page", 1))
|
244 |
+
items_per_page = int(request.args.get("page_size", 1024))
|
245 |
+
orderby = request.args.get("orderby", "create_time")
|
246 |
+
if request.args.get("desc") == "False":
|
247 |
+
desc = False
|
248 |
+
else:
|
249 |
+
desc = True
|
250 |
+
chats = DialogService.get_list(tenant_id,page_number,items_per_page,orderby,desc,id,name)
|
251 |
+
if not chats:
|
252 |
+
return get_result(data=[])
|
253 |
+
list_assts = []
|
254 |
+
renamed_dict = {}
|
255 |
+
key_mapping = {"parameters": "variables",
|
256 |
+
"prologue": "opener",
|
257 |
+
"quote": "show_quote",
|
258 |
+
"system": "prompt",
|
259 |
+
"rerank_id": "rerank_model",
|
260 |
+
"vector_similarity_weight": "keywords_similarity_weight"}
|
261 |
+
key_list = ["similarity_threshold", "vector_similarity_weight", "top_n", "rerank_id"]
|
262 |
+
for res in chats:
|
263 |
+
for key, value in res["prompt_config"].items():
|
264 |
+
new_key = key_mapping.get(key, key)
|
265 |
+
renamed_dict[new_key] = value
|
266 |
+
res["prompt"] = renamed_dict
|
267 |
+
del res["prompt_config"]
|
268 |
+
new_dict = {"similarity_threshold": res["similarity_threshold"],
|
269 |
+
"keywords_similarity_weight": res["vector_similarity_weight"],
|
270 |
+
"top_n": res["top_n"],
|
271 |
+
"rerank_model": res['rerank_id']}
|
272 |
+
res["prompt"].update(new_dict)
|
273 |
+
for key in key_list:
|
274 |
+
del res[key]
|
275 |
+
res["llm"] = res.pop("llm_setting")
|
276 |
+
res["llm"]["model_name"] = res.pop("llm_id")
|
277 |
+
kb_list = []
|
278 |
+
for kb_id in res["kb_ids"]:
|
279 |
+
kb = KnowledgebaseService.query(id=kb_id)
|
280 |
+
if not kb :
|
281 |
+
return get_error_data_result(retmsg=f"Don't exist the kb {kb_id}")
|
282 |
+
kb_list.append(kb[0].to_json())
|
283 |
+
del res["kb_ids"]
|
284 |
+
res["knowledgebases"] = kb_list
|
285 |
+
res["avatar"] = res.pop("icon")
|
286 |
+
list_assts.append(res)
|
287 |
+
return get_result(data=list_assts)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
api/apps/sdk/dataset.py
CHANGED
@@ -73,35 +73,24 @@ def create(tenant_id):
|
|
73 |
@token_required
|
74 |
def delete(tenant_id):
|
75 |
req = request.json
|
76 |
-
names=req.get("names")
|
77 |
ids = req.get("ids")
|
78 |
-
if not ids
|
79 |
return get_error_data_result(
|
80 |
-
retmsg="ids
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
id_list.append(kbs[0].id)
|
88 |
-
if ids:
|
89 |
-
for id in ids:
|
90 |
-
kbs=KnowledgebaseService.query(id=id,tenant_id=tenant_id)
|
91 |
-
if not kbs:
|
92 |
-
return get_error_data_result(retmsg=f"You don't own the dataset {id}")
|
93 |
-
id_list.extend(ids)
|
94 |
-
for id in id_list:
|
95 |
-
for doc in DocumentService.query(kb_id=id):
|
96 |
-
if not DocumentService.remove_document(doc, tenant_id):
|
97 |
-
return get_error_data_result(
|
98 |
-
retmsg="Remove document error.(Database error)")
|
99 |
-
f2d = File2DocumentService.get_by_document_id(doc.id)
|
100 |
-
FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id])
|
101 |
-
File2DocumentService.delete_by_document_id(doc.id)
|
102 |
-
if not KnowledgebaseService.delete_by_id(id):
|
103 |
return get_error_data_result(
|
104 |
-
retmsg="
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
return get_result(retcode=RetCode.SUCCESS)
|
106 |
|
107 |
@manager.route('/dataset/<dataset_id>', methods=['PUT'])
|
@@ -161,7 +150,10 @@ def list(tenant_id):
|
|
161 |
page_number = int(request.args.get("page", 1))
|
162 |
items_per_page = int(request.args.get("page_size", 1024))
|
163 |
orderby = request.args.get("orderby", "create_time")
|
164 |
-
|
|
|
|
|
|
|
165 |
tenants = TenantService.get_joined_tenants_by_user_id(tenant_id)
|
166 |
kbs = KnowledgebaseService.get_list(
|
167 |
[m["tenant_id"] for m in tenants], tenant_id, page_number, items_per_page, orderby, desc, id, name)
|
|
|
73 |
@token_required
|
74 |
def delete(tenant_id):
|
75 |
req = request.json
|
|
|
76 |
ids = req.get("ids")
|
77 |
+
if not ids:
|
78 |
return get_error_data_result(
|
79 |
+
retmsg="ids are required")
|
80 |
+
for id in ids:
|
81 |
+
kbs = KnowledgebaseService.query(id=id, tenant_id=tenant_id)
|
82 |
+
if not kbs:
|
83 |
+
return get_error_data_result(retmsg=f"You don't own the dataset {id}")
|
84 |
+
for doc in DocumentService.query(kb_id=id):
|
85 |
+
if not DocumentService.remove_document(doc, tenant_id):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
return get_error_data_result(
|
87 |
+
retmsg="Remove document error.(Database error)")
|
88 |
+
f2d = File2DocumentService.get_by_document_id(doc.id)
|
89 |
+
FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id])
|
90 |
+
File2DocumentService.delete_by_document_id(doc.id)
|
91 |
+
if not KnowledgebaseService.delete_by_id(id):
|
92 |
+
return get_error_data_result(
|
93 |
+
retmsg="Delete dataset error.(Database serror)")
|
94 |
return get_result(retcode=RetCode.SUCCESS)
|
95 |
|
96 |
@manager.route('/dataset/<dataset_id>', methods=['PUT'])
|
|
|
150 |
page_number = int(request.args.get("page", 1))
|
151 |
items_per_page = int(request.args.get("page_size", 1024))
|
152 |
orderby = request.args.get("orderby", "create_time")
|
153 |
+
if request.args.get("desc") == "False":
|
154 |
+
desc = False
|
155 |
+
else:
|
156 |
+
desc = True
|
157 |
tenants = TenantService.get_joined_tenants_by_user_id(tenant_id)
|
158 |
kbs = KnowledgebaseService.get_list(
|
159 |
[m["tenant_id"] for m in tenants], tenant_id, page_number, items_per_page, orderby, desc, id, name)
|
api/db/services/dialog_service.py
CHANGED
@@ -19,8 +19,8 @@ import json
|
|
19 |
import re
|
20 |
from copy import deepcopy
|
21 |
from timeit import default_timer as timer
|
22 |
-
from api.db import LLMType, ParserType
|
23 |
-
from api.db.db_models import Dialog, Conversation
|
24 |
from api.db.services.common_service import CommonService
|
25 |
from api.db.services.knowledgebase_service import KnowledgebaseService
|
26 |
from api.db.services.llm_service import LLMService, TenantLLMService, LLMBundle
|
@@ -35,6 +35,28 @@ from api.utils.file_utils import get_project_base_directory
|
|
35 |
class DialogService(CommonService):
|
36 |
model = Dialog
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
|
39 |
class ConversationService(CommonService):
|
40 |
model = Conversation
|
@@ -85,7 +107,7 @@ def llm_id2llm_type(llm_id):
|
|
85 |
for llm in llm_factory["llm"]:
|
86 |
if llm_id == llm["llm_name"]:
|
87 |
return llm["model_type"].strip(",")[-1]
|
88 |
-
|
89 |
|
90 |
def chat(dialog, messages, stream=True, **kwargs):
|
91 |
assert messages[-1]["role"] == "user", "The last content of this conversation is not from user."
|
|
|
19 |
import re
|
20 |
from copy import deepcopy
|
21 |
from timeit import default_timer as timer
|
22 |
+
from api.db import LLMType, ParserType,StatusEnum
|
23 |
+
from api.db.db_models import Dialog, Conversation,DB
|
24 |
from api.db.services.common_service import CommonService
|
25 |
from api.db.services.knowledgebase_service import KnowledgebaseService
|
26 |
from api.db.services.llm_service import LLMService, TenantLLMService, LLMBundle
|
|
|
35 |
class DialogService(CommonService):
|
36 |
model = Dialog
|
37 |
|
38 |
+
@classmethod
|
39 |
+
@DB.connection_context()
|
40 |
+
def get_list(cls, tenant_id,
|
41 |
+
page_number, items_per_page, orderby, desc, id , name):
|
42 |
+
chats = cls.model.select()
|
43 |
+
if id:
|
44 |
+
chats = chats.where(cls.model.id == id)
|
45 |
+
if name:
|
46 |
+
chats = chats.where(cls.model.name == name)
|
47 |
+
chats = chats.where(
|
48 |
+
(cls.model.tenant_id == tenant_id)
|
49 |
+
& (cls.model.status == StatusEnum.VALID.value)
|
50 |
+
)
|
51 |
+
if desc:
|
52 |
+
chats = chats.order_by(cls.model.getter_by(orderby).desc())
|
53 |
+
else:
|
54 |
+
chats = chats.order_by(cls.model.getter_by(orderby).asc())
|
55 |
+
|
56 |
+
chats = chats.paginate(page_number, items_per_page)
|
57 |
+
|
58 |
+
return list(chats.dicts())
|
59 |
+
|
60 |
|
61 |
class ConversationService(CommonService):
|
62 |
model = Conversation
|
|
|
107 |
for llm in llm_factory["llm"]:
|
108 |
if llm_id == llm["llm_name"]:
|
109 |
return llm["model_type"].strip(",")[-1]
|
110 |
+
|
111 |
|
112 |
def chat(dialog, messages, stream=True, **kwargs):
|
113 |
assert messages[-1]["role"] == "user", "The last content of this conversation is not from user."
|
api/http_api.md
CHANGED
@@ -149,11 +149,11 @@ The error response includes a JSON object like the following:
|
|
149 |
}
|
150 |
```
|
151 |
|
152 |
-
## Delete
|
153 |
|
154 |
**DELETE** `/api/v1/dataset`
|
155 |
|
156 |
-
Deletes datasets by ids
|
157 |
|
158 |
### Request
|
159 |
|
@@ -163,7 +163,6 @@ Deletes datasets by ids or names.
|
|
163 |
- `content-Type: application/json`
|
164 |
- 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
165 |
- Body:
|
166 |
-
- `"names"`: `List[string]`
|
167 |
- `"ids"`: `List[string]`
|
168 |
|
169 |
|
@@ -176,18 +175,15 @@ curl --request DELETE \
|
|
176 |
--header 'Content-Type: application/json' \
|
177 |
--header 'Authorization: Bearer {YOUR_ACCESS_TOKEN}' \
|
178 |
--data '{
|
179 |
-
"
|
180 |
}'
|
181 |
```
|
182 |
|
183 |
#### Request parameters
|
184 |
|
185 |
-
- `"names"`: (*Body parameter*)
|
186 |
-
Dataset names to delete.
|
187 |
- `"ids"`: (*Body parameter*)
|
188 |
Dataset IDs to delete.
|
189 |
|
190 |
-
`"names"` and `"ids"` are exclusive.
|
191 |
|
192 |
### Response
|
193 |
|
@@ -318,7 +314,7 @@ curl --request GET \
|
|
318 |
A boolean flag indicating whether the sorting should be in descending order.
|
319 |
- `name`: (*Path parameter*)
|
320 |
Dataset name
|
321 |
-
-
|
322 |
The ID of the dataset to be retrieved.
|
323 |
- `"name"`: (*Path parameter*)
|
324 |
The name of the dataset to be retrieved.
|
@@ -996,10 +992,18 @@ Create a chat
|
|
996 |
### Request
|
997 |
|
998 |
- Method: POST
|
999 |
-
- URL:
|
1000 |
- Headers:
|
1001 |
- `content-Type: application/json`
|
1002 |
- 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1003 |
|
1004 |
#### Request example
|
1005 |
|
@@ -1009,135 +1013,424 @@ curl --request POST \
|
|
1009 |
--header 'Content-Type: application/json' \
|
1010 |
--header 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
1011 |
--data-binary '{
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
"permission": "me",
|
1037 |
-
"tenant_id": "4fb0cd625f9311efba4a0242ac120006"
|
1038 |
-
}
|
1039 |
-
],
|
1040 |
-
"language": "English",
|
1041 |
-
"llm": {
|
1042 |
-
"frequency_penalty": 0.7,
|
1043 |
-
"max_tokens": 512,
|
1044 |
-
"model_name": "deepseek-chat",
|
1045 |
-
"presence_penalty": 0.4,
|
1046 |
-
"temperature": 0.1,
|
1047 |
-
"top_p": 0.3
|
1048 |
-
},
|
1049 |
-
"name": "Miss R",
|
1050 |
-
"prompt": {
|
1051 |
-
"empty_response": "Sorry! Can't find the context!",
|
1052 |
-
"keywords_similarity_weight": 0.7,
|
1053 |
-
"opener": "Hi! I am your assistant, what can I do for you?",
|
1054 |
-
"prompt": "You are an intelligent assistant. Please summarize the content of the knowledge base to answer the question. Please list the data in the knowledge base and answer in detail. When all knowledge base content is irrelevant to the question, your answer must include the sentence 'The answer you are looking for is not found in the knowledge base!' Answers need to consider chat history.\nHere is the knowledge base:\n{knowledge}\nThe above is the knowledge base.",
|
1055 |
-
"rerank_model": "",
|
1056 |
-
"show_quote": true,
|
1057 |
-
"similarity_threshold": 0.2,
|
1058 |
-
"top_n": 8,
|
1059 |
-
"variables": [
|
1060 |
-
{
|
1061 |
-
"key": "knowledge",
|
1062 |
-
"optional": true
|
1063 |
-
}
|
1064 |
-
]
|
1065 |
-
},
|
1066 |
-
"prompt_type": "simple",
|
1067 |
-
"status": "1",
|
1068 |
-
"top_k": 1024,
|
1069 |
-
"update_date": "Wed, 04 Sep 2024 10:08:01 GMT",
|
1070 |
-
"update_time": 1725444481128
|
1071 |
}'
|
1072 |
```
|
1073 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1074 |
## Update chat
|
1075 |
|
1076 |
-
**PUT** `/api/v1/chat`
|
1077 |
|
1078 |
Update a chat
|
1079 |
|
1080 |
### Request
|
1081 |
|
1082 |
- Method: PUT
|
1083 |
-
- URL:
|
1084 |
- Headers:
|
1085 |
- `content-Type: application/json`
|
1086 |
- 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
1087 |
-
|
|
|
1088 |
#### Request example
|
1089 |
-
|
1090 |
curl --request PUT \
|
1091 |
-
--url http://{address}/api/v1/chat \
|
1092 |
--header 'Content-Type: application/json' \
|
1093 |
--header 'Authorization: Bearer {YOUR_ACCESS_TOKEN}' \
|
1094 |
-
--data
|
1095 |
-
"id":"554e96746aaa11efb06b0242ac120005",
|
1096 |
"name":"Test"
|
1097 |
}'
|
|
|
|
|
|
|
1098 |
|
1099 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1100 |
|
1101 |
-
**DELETE** `/api/v1/chat
|
1102 |
|
1103 |
-
Delete
|
1104 |
|
1105 |
### Request
|
1106 |
|
1107 |
-
- Method:
|
1108 |
-
- URL:
|
1109 |
- Headers:
|
1110 |
- `content-Type: application/json`
|
1111 |
- 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
1112 |
-
|
|
|
1113 |
#### Request example
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
|
|
1117 |
--header 'Content-Type: application/json' \
|
1118 |
-
--header 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
|
|
|
|
|
|
1119 |
}'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1120 |
|
1121 |
-
## List
|
1122 |
|
1123 |
-
**GET** `/api/v1/chat`
|
1124 |
|
1125 |
-
List
|
1126 |
|
1127 |
### Request
|
1128 |
|
1129 |
- Method: GET
|
1130 |
-
- URL:
|
1131 |
- Headers:
|
1132 |
-
- `content-Type: application/json`
|
1133 |
- 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
1134 |
|
1135 |
#### Request example
|
1136 |
|
|
|
1137 |
curl --request GET \
|
1138 |
-
--url http://{address}/api/v1/chat \
|
1139 |
-
--header 'Content-Type: application/json' \
|
1140 |
--header 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1141 |
|
1142 |
## Create a chat session
|
1143 |
|
|
|
149 |
}
|
150 |
```
|
151 |
|
152 |
+
## Delete datasets
|
153 |
|
154 |
**DELETE** `/api/v1/dataset`
|
155 |
|
156 |
+
Deletes datasets by ids.
|
157 |
|
158 |
### Request
|
159 |
|
|
|
163 |
- `content-Type: application/json`
|
164 |
- 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
165 |
- Body:
|
|
|
166 |
- `"ids"`: `List[string]`
|
167 |
|
168 |
|
|
|
175 |
--header 'Content-Type: application/json' \
|
176 |
--header 'Authorization: Bearer {YOUR_ACCESS_TOKEN}' \
|
177 |
--data '{
|
178 |
+
"ids": ["test_1", "test_2"]
|
179 |
}'
|
180 |
```
|
181 |
|
182 |
#### Request parameters
|
183 |
|
|
|
|
|
184 |
- `"ids"`: (*Body parameter*)
|
185 |
Dataset IDs to delete.
|
186 |
|
|
|
187 |
|
188 |
### Response
|
189 |
|
|
|
314 |
A boolean flag indicating whether the sorting should be in descending order.
|
315 |
- `name`: (*Path parameter*)
|
316 |
Dataset name
|
317 |
+
- `"id"`: (*Path parameter*)
|
318 |
The ID of the dataset to be retrieved.
|
319 |
- `"name"`: (*Path parameter*)
|
320 |
The name of the dataset to be retrieved.
|
|
|
992 |
### Request
|
993 |
|
994 |
- Method: POST
|
995 |
+
- URL: `http://{address}/api/v1/chat`
|
996 |
- Headers:
|
997 |
- `content-Type: application/json`
|
998 |
- 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
999 |
+
- Body:
|
1000 |
+
- `"name"`: `string`
|
1001 |
+
- `"avatar"`: `string`
|
1002 |
+
- `"knowledgebases"`: `List[DataSet]`
|
1003 |
+
- `"id"`: `string`
|
1004 |
+
- `"llm"`: `LLM`
|
1005 |
+
- `"prompt"`: `Prompt`
|
1006 |
+
|
1007 |
|
1008 |
#### Request example
|
1009 |
|
|
|
1013 |
--header 'Content-Type: application/json' \
|
1014 |
--header 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
1015 |
--data-binary '{
|
1016 |
+
"knowledgebases": [
|
1017 |
+
{
|
1018 |
+
"avatar": null,
|
1019 |
+
"chunk_count": 0,
|
1020 |
+
"description": null,
|
1021 |
+
"document_count": 0,
|
1022 |
+
"embedding_model": "",
|
1023 |
+
"id": "0b2cbc8c877f11ef89070242ac120005",
|
1024 |
+
"language": "English",
|
1025 |
+
"name": "Test_assistant",
|
1026 |
+
"parse_method": "naive",
|
1027 |
+
"parser_config": {
|
1028 |
+
"pages": [
|
1029 |
+
[
|
1030 |
+
1,
|
1031 |
+
1000000
|
1032 |
+
]
|
1033 |
+
]
|
1034 |
+
},
|
1035 |
+
"permission": "me",
|
1036 |
+
"tenant_id": "4fb0cd625f9311efba4a0242ac120006"
|
1037 |
+
}
|
1038 |
+
],
|
1039 |
+
"name":"new_chat_1"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1040 |
}'
|
1041 |
```
|
1042 |
|
1043 |
+
#### Request parameters
|
1044 |
+
|
1045 |
+
- `"name"`: (*Body parameter*)
|
1046 |
+
The name of the created chat.
|
1047 |
+
- `"assistant"`
|
1048 |
+
|
1049 |
+
- `"avatar"`: (*Body parameter*)
|
1050 |
+
The icon of the created chat.
|
1051 |
+
- `"path"`
|
1052 |
+
|
1053 |
+
- `"knowledgebases"`: (*Body parameter*)
|
1054 |
+
Select knowledgebases associated.
|
1055 |
+
- `["kb1"]`
|
1056 |
+
|
1057 |
+
- `"id"`: (*Body parameter*)
|
1058 |
+
The id of the created chat.
|
1059 |
+
- `""`
|
1060 |
+
|
1061 |
+
- `"llm"`: (*Body parameter*)
|
1062 |
+
The LLM of the created chat.
|
1063 |
+
- If the value is `None`, a dictionary with default values will be generated.
|
1064 |
+
|
1065 |
+
- `"prompt"`: (*Body parameter*)
|
1066 |
+
The prompt of the created chat.
|
1067 |
+
- If the value is `None`, a dictionary with default values will be generated.
|
1068 |
+
|
1069 |
+
---
|
1070 |
+
|
1071 |
+
##### Chat.LLM parameters:
|
1072 |
+
|
1073 |
+
- `"model_name"`: (*Body parameter*)
|
1074 |
+
Large language chat model.
|
1075 |
+
- If it is `None`, it will return the user's default model.
|
1076 |
+
|
1077 |
+
- `"temperature"`: (*Body parameter*)
|
1078 |
+
Controls the randomness of predictions by the model. A lower temperature makes the model more confident, while a higher temperature makes it more creative and diverse.
|
1079 |
+
- `0.1`
|
1080 |
+
|
1081 |
+
- `"top_p"`: (*Body parameter*)
|
1082 |
+
Also known as "nucleus sampling," it focuses on the most likely words, cutting off the less probable ones.
|
1083 |
+
- `0.3`
|
1084 |
+
|
1085 |
+
- `"presence_penalty"`: (*Body parameter*)
|
1086 |
+
Discourages the model from repeating the same information by penalizing repeated content.
|
1087 |
+
- `0.4`
|
1088 |
+
|
1089 |
+
- `"frequency_penalty"`: (*Body parameter*)
|
1090 |
+
Reduces the model’s tendency to repeat words frequently.
|
1091 |
+
- `0.7`
|
1092 |
+
|
1093 |
+
- `"max_tokens"`: (*Body parameter*)
|
1094 |
+
Sets the maximum length of the model’s output, measured in tokens (words or pieces of words).
|
1095 |
+
- `512`
|
1096 |
+
|
1097 |
+
---
|
1098 |
+
|
1099 |
+
##### Chat.Prompt parameters:
|
1100 |
+
|
1101 |
+
- `"similarity_threshold"`: (*Body parameter*)
|
1102 |
+
Filters out chunks with similarity below this threshold.
|
1103 |
+
- `0.2`
|
1104 |
+
|
1105 |
+
- `"keywords_similarity_weight"`: (*Body parameter*)
|
1106 |
+
Weighted keywords similarity and vector cosine similarity; the sum of weights is 1.0.
|
1107 |
+
- `0.7`
|
1108 |
+
|
1109 |
+
- `"top_n"`: (*Body parameter*)
|
1110 |
+
Only the top N chunks above the similarity threshold will be fed to LLMs.
|
1111 |
+
- `8`
|
1112 |
+
|
1113 |
+
- `"variables"`: (*Body parameter*)
|
1114 |
+
Variables help with different chat strategies by filling in the 'System' part of the prompt.
|
1115 |
+
- `[{"key": "knowledge", "optional": True}]`
|
1116 |
+
|
1117 |
+
- `"rerank_model"`: (*Body parameter*)
|
1118 |
+
If empty, it uses vector cosine similarity; otherwise, it uses rerank score.
|
1119 |
+
- `""`
|
1120 |
+
|
1121 |
+
- `"empty_response"`: (*Body parameter*)
|
1122 |
+
If nothing is retrieved, this will be used as the response. Leave blank if LLM should provide its own opinion.
|
1123 |
+
- `None`
|
1124 |
+
|
1125 |
+
- `"opener"`: (*Body parameter*)
|
1126 |
+
The welcome message for clients.
|
1127 |
+
- `"Hi! I'm your assistant, what can I do for you?"`
|
1128 |
+
|
1129 |
+
- `"show_quote"`: (*Body parameter*)
|
1130 |
+
Indicates whether the source of the original text should be displayed.
|
1131 |
+
- `True`
|
1132 |
+
|
1133 |
+
- `"prompt"`: (*Body parameter*)
|
1134 |
+
Instructions for LLM to follow when answering questions, such as character design or answer length.
|
1135 |
+
- `"You are an intelligent assistant. Please summarize the content of the knowledge base to answer the question. Please list the data in the knowledge base and answer in detail. When all knowledge base content is irrelevant to the question, your answer must include the sentence 'The answer you are looking for is not found in the knowledge base!' Answers need to consider chat history. Here is the knowledge base: {knowledge} The above is the knowledge base."`
|
1136 |
+
### Response
|
1137 |
+
Success:
|
1138 |
+
```json
|
1139 |
+
{
|
1140 |
+
"code": 0,
|
1141 |
+
"data": {
|
1142 |
+
"avatar": "",
|
1143 |
+
"create_date": "Fri, 11 Oct 2024 03:23:24 GMT",
|
1144 |
+
"create_time": 1728617004635,
|
1145 |
+
"description": "A helpful Assistant",
|
1146 |
+
"do_refer": "1",
|
1147 |
+
"id": "2ca4b22e878011ef88fe0242ac120005",
|
1148 |
+
"knowledgebases": [
|
1149 |
+
{
|
1150 |
+
"avatar": null,
|
1151 |
+
"chunk_count": 0,
|
1152 |
+
"description": null,
|
1153 |
+
"document_count": 0,
|
1154 |
+
"embedding_model": "",
|
1155 |
+
"id": "0b2cbc8c877f11ef89070242ac120005",
|
1156 |
+
"language": "English",
|
1157 |
+
"name": "Test_assistant",
|
1158 |
+
"parse_method": "naive",
|
1159 |
+
"parser_config": {
|
1160 |
+
"pages": [
|
1161 |
+
[
|
1162 |
+
1,
|
1163 |
+
1000000
|
1164 |
+
]
|
1165 |
+
]
|
1166 |
+
},
|
1167 |
+
"permission": "me",
|
1168 |
+
"tenant_id": "4fb0cd625f9311efba4a0242ac120006"
|
1169 |
+
}
|
1170 |
+
],
|
1171 |
+
"language": "English",
|
1172 |
+
"llm": {
|
1173 |
+
"frequency_penalty": 0.7,
|
1174 |
+
"max_tokens": 512,
|
1175 |
+
"model_name": "deepseek-chat___OpenAI-API@OpenAI-API-Compatible",
|
1176 |
+
"presence_penalty": 0.4,
|
1177 |
+
"temperature": 0.1,
|
1178 |
+
"top_p": 0.3
|
1179 |
+
},
|
1180 |
+
"name": "new_chat_1",
|
1181 |
+
"prompt": {
|
1182 |
+
"empty_response": "Sorry! 知识库中未找到相关内容!",
|
1183 |
+
"keywords_similarity_weight": 0.3,
|
1184 |
+
"opener": "您好,我是您的助手小樱,长得可爱又善良,can I help you?",
|
1185 |
+
"prompt": "你是一个智能助手,请总结知识库的内容来回答问题,请列举知识库中的数据详细回答。当所有知识库内容都与问题无关时,你的回答必须包括“知识库中未找到您要的答案!”这句话。回答需要考虑聊天历史。\n 以下是知识库:\n {knowledge}\n 以上是知识库。",
|
1186 |
+
"rerank_model": "",
|
1187 |
+
"similarity_threshold": 0.2,
|
1188 |
+
"top_n": 6,
|
1189 |
+
"variables": [
|
1190 |
+
{
|
1191 |
+
"key": "knowledge",
|
1192 |
+
"optional": false
|
1193 |
+
}
|
1194 |
+
]
|
1195 |
+
},
|
1196 |
+
"prompt_type": "simple",
|
1197 |
+
"status": "1",
|
1198 |
+
"tenant_id": "69736c5e723611efb51b0242ac120007",
|
1199 |
+
"top_k": 1024,
|
1200 |
+
"update_date": "Fri, 11 Oct 2024 03:23:24 GMT",
|
1201 |
+
"update_time": 1728617004635
|
1202 |
+
}
|
1203 |
+
}
|
1204 |
+
```
|
1205 |
+
Error:
|
1206 |
+
```json
|
1207 |
+
{
|
1208 |
+
"code": 102,
|
1209 |
+
"message": "Duplicated chat name in creating dataset."
|
1210 |
+
}
|
1211 |
+
```
|
1212 |
+
|
1213 |
## Update chat
|
1214 |
|
1215 |
+
**PUT** `/api/v1/chat/{chat_id}`
|
1216 |
|
1217 |
Update a chat
|
1218 |
|
1219 |
### Request
|
1220 |
|
1221 |
- Method: PUT
|
1222 |
+
- URL: `http://{address}/api/v1/chat/{chat_id}`
|
1223 |
- Headers:
|
1224 |
- `content-Type: application/json`
|
1225 |
- 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
1226 |
+
- Body: (Refer to the "Create chat" for the complete structure of the request body.)
|
1227 |
+
|
1228 |
#### Request example
|
1229 |
+
```bash
|
1230 |
curl --request PUT \
|
1231 |
+
--url http://{address}/api/v1/chat/{chat_id} \
|
1232 |
--header 'Content-Type: application/json' \
|
1233 |
--header 'Authorization: Bearer {YOUR_ACCESS_TOKEN}' \
|
1234 |
+
--data '{
|
|
|
1235 |
"name":"Test"
|
1236 |
}'
|
1237 |
+
```
|
1238 |
+
#### Parameters
|
1239 |
+
(Refer to the "Create chat" for the complete structure of the request parameters.)
|
1240 |
|
1241 |
+
### Response
|
1242 |
+
Success
|
1243 |
+
```json
|
1244 |
+
{
|
1245 |
+
"code": 0
|
1246 |
+
}
|
1247 |
+
```
|
1248 |
+
Error
|
1249 |
+
```json
|
1250 |
+
{
|
1251 |
+
"code": 102,
|
1252 |
+
"message": "Duplicated chat name in updating dataset."
|
1253 |
+
}
|
1254 |
+
```
|
1255 |
+
|
1256 |
+
## Delete chats
|
1257 |
|
1258 |
+
**DELETE** `/api/v1/chat`
|
1259 |
|
1260 |
+
Delete chats
|
1261 |
|
1262 |
### Request
|
1263 |
|
1264 |
+
- Method: DELETE
|
1265 |
+
- URL: `http://{address}/api/v1/chat`
|
1266 |
- Headers:
|
1267 |
- `content-Type: application/json`
|
1268 |
- 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
1269 |
+
- Body:
|
1270 |
+
- `ids`: List[string]
|
1271 |
#### Request example
|
1272 |
+
```bash
|
1273 |
+
# Either id or name must be provided, but not both.
|
1274 |
+
curl --request DELETE \
|
1275 |
+
--url http://{address}/api/v1/chat \
|
1276 |
--header 'Content-Type: application/json' \
|
1277 |
+
--header 'Authorization: Bearer {YOUR_ACCESS_TOKEN}' \
|
1278 |
+
--data '{
|
1279 |
+
"ids": ["test_1", "test_2"]
|
1280 |
+
}'
|
1281 |
}'
|
1282 |
+
```
|
1283 |
+
#### Request parameters:
|
1284 |
+
|
1285 |
+
- `"ids"`: (*Body parameter*)
|
1286 |
+
IDs of the chats to be deleted.
|
1287 |
+
- `None`
|
1288 |
+
### Response
|
1289 |
+
Success
|
1290 |
+
```json
|
1291 |
+
{
|
1292 |
+
"code": 0
|
1293 |
+
}
|
1294 |
+
```
|
1295 |
+
Error
|
1296 |
+
```json
|
1297 |
+
{
|
1298 |
+
"code": 102,
|
1299 |
+
"message": "ids are required"
|
1300 |
+
}
|
1301 |
+
```
|
1302 |
|
1303 |
+
## List chats
|
1304 |
|
1305 |
+
**GET** `/api/v1/chat?page={page}&page_size={page_size}&orderby={orderby}&desc={desc}&name={dataset_name}&id={dataset_id}`
|
1306 |
|
1307 |
+
List chats based on filter criteria.
|
1308 |
|
1309 |
### Request
|
1310 |
|
1311 |
- Method: GET
|
1312 |
+
- URL: `http://{address}/api/v1/chat?page={page}&page_size={page_size}&orderby={orderby}&desc={desc}&name={dataset_name}&id={dataset_id}`
|
1313 |
- Headers:
|
|
|
1314 |
- 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
1315 |
|
1316 |
#### Request example
|
1317 |
|
1318 |
+
```bash
|
1319 |
curl --request GET \
|
1320 |
+
--url http://{address}/api/v1/chat?page={page}&page_size={page_size}&orderby={orderby}&desc={desc}&name={dataset_name}&id={dataset_id} \
|
|
|
1321 |
--header 'Authorization: Bearer {YOUR_ACCESS_TOKEN}'
|
1322 |
+
```
|
1323 |
+
|
1324 |
+
#### Request parameters
|
1325 |
+
- `"page"`: (*Path parameter*)
|
1326 |
+
The current page number to retrieve from the paginated data. This parameter determines which set of records will be fetched.
|
1327 |
+
- `1`
|
1328 |
+
|
1329 |
+
- `"page_size"`: (*Path parameter*)
|
1330 |
+
The number of records to retrieve per page. This controls how many records will be included in each page.
|
1331 |
+
- `1024`
|
1332 |
+
|
1333 |
+
- `"orderby"`: (*Path parameter*)
|
1334 |
+
The field by which the records should be sorted. This specifies the attribute or column used to order the results.
|
1335 |
+
- `"create_time"`
|
1336 |
+
|
1337 |
+
- `"desc"`: (*Path parameter*)
|
1338 |
+
A boolean flag indicating whether the sorting should be in descending order.
|
1339 |
+
- `True`
|
1340 |
+
|
1341 |
+
- `"id"`: (*Path parameter*)
|
1342 |
+
The ID of the chat to be retrieved.
|
1343 |
+
- `None`
|
1344 |
+
|
1345 |
+
- `"name"`: (*Path parameter*)
|
1346 |
+
The name of the chat to be retrieved.
|
1347 |
+
- `None`
|
1348 |
+
|
1349 |
+
### Response
|
1350 |
+
Success
|
1351 |
+
```json
|
1352 |
+
{
|
1353 |
+
"code": 0,
|
1354 |
+
"data": [
|
1355 |
+
{
|
1356 |
+
"avatar": "",
|
1357 |
+
"create_date": "Fri, 11 Oct 2024 03:23:24 GMT",
|
1358 |
+
"create_time": 1728617004635,
|
1359 |
+
"description": "A helpful Assistant",
|
1360 |
+
"do_refer": "1",
|
1361 |
+
"id": "2ca4b22e878011ef88fe0242ac120005",
|
1362 |
+
"knowledgebases": [
|
1363 |
+
{
|
1364 |
+
"avatar": "",
|
1365 |
+
"chunk_num": 0,
|
1366 |
+
"create_date": "Fri, 11 Oct 2024 03:15:18 GMT",
|
1367 |
+
"create_time": 1728616518986,
|
1368 |
+
"created_by": "69736c5e723611efb51b0242ac120007",
|
1369 |
+
"description": "",
|
1370 |
+
"doc_num": 0,
|
1371 |
+
"embd_id": "BAAI/bge-large-zh-v1.5",
|
1372 |
+
"id": "0b2cbc8c877f11ef89070242ac120005",
|
1373 |
+
"language": "English",
|
1374 |
+
"name": "test_delete_chat",
|
1375 |
+
"parser_config": {
|
1376 |
+
"chunk_token_count": 128,
|
1377 |
+
"delimiter": "\n!?。;!?",
|
1378 |
+
"layout_recognize": true,
|
1379 |
+
"task_page_size": 12
|
1380 |
+
},
|
1381 |
+
"parser_id": "naive",
|
1382 |
+
"permission": "me",
|
1383 |
+
"similarity_threshold": 0.2,
|
1384 |
+
"status": "1",
|
1385 |
+
"tenant_id": "69736c5e723611efb51b0242ac120007",
|
1386 |
+
"token_num": 0,
|
1387 |
+
"update_date": "Fri, 11 Oct 2024 04:01:31 GMT",
|
1388 |
+
"update_time": 1728619291228,
|
1389 |
+
"vector_similarity_weight": 0.3
|
1390 |
+
}
|
1391 |
+
],
|
1392 |
+
"language": "English",
|
1393 |
+
"llm": {
|
1394 |
+
"frequency_penalty": 0.7,
|
1395 |
+
"max_tokens": 512,
|
1396 |
+
"model_name": "deepseek-chat___OpenAI-API@OpenAI-API-Compatible",
|
1397 |
+
"presence_penalty": 0.4,
|
1398 |
+
"temperature": 0.1,
|
1399 |
+
"top_p": 0.3
|
1400 |
+
},
|
1401 |
+
"name": "Test",
|
1402 |
+
"prompt": {
|
1403 |
+
"empty_response": "Sorry! 知识库中未找到相关内容!",
|
1404 |
+
"keywords_similarity_weight": 0.3,
|
1405 |
+
"opener": "您好,我是您的助手小樱,长得可爱又善良,can I help you?",
|
1406 |
+
"prompt": "你是一个智能助手,请总结知识库的内容来回答问题,请列举知识库中的数据详细回答。当所有知识库内容都与问题无关时,你的回答必须包括“知识库中未找到您要的答案!”这句话。回答需要考虑聊天历史。\n 以下是知识库:\n {knowledge}\n 以上是知识库。",
|
1407 |
+
"rerank_model": "",
|
1408 |
+
"similarity_threshold": 0.2,
|
1409 |
+
"top_n": 6,
|
1410 |
+
"variables": [
|
1411 |
+
{
|
1412 |
+
"key": "knowledge",
|
1413 |
+
"optional": false
|
1414 |
+
}
|
1415 |
+
]
|
1416 |
+
},
|
1417 |
+
"prompt_type": "simple",
|
1418 |
+
"status": "1",
|
1419 |
+
"tenant_id": "69736c5e723611efb51b0242ac120007",
|
1420 |
+
"top_k": 1024,
|
1421 |
+
"update_date": "Fri, 11 Oct 2024 03:47:58 GMT",
|
1422 |
+
"update_time": 1728618478392
|
1423 |
+
}
|
1424 |
+
]
|
1425 |
+
}
|
1426 |
+
```
|
1427 |
+
Error
|
1428 |
+
```json
|
1429 |
+
{
|
1430 |
+
"code": 102,
|
1431 |
+
"message": "The chat doesn't exist"
|
1432 |
+
}
|
1433 |
+
```
|
1434 |
|
1435 |
## Create a chat session
|
1436 |
|
api/python_api_reference.md
CHANGED
@@ -107,7 +107,7 @@ ds = rag.create_dataset(name="kb_1")
|
|
107 |
## Delete knowledge bases
|
108 |
|
109 |
```python
|
110 |
-
RAGFlow.
|
111 |
```
|
112 |
Deletes knowledge bases.
|
113 |
### Parameters
|
@@ -116,11 +116,7 @@ Deletes knowledge bases.
|
|
116 |
|
117 |
The ids of the datasets to be deleted.
|
118 |
|
119 |
-
#### names: `List[str]`
|
120 |
|
121 |
-
The names of the datasets to be deleted.
|
122 |
-
|
123 |
-
Either `ids` or `names` must be provided, but not both.
|
124 |
### Returns
|
125 |
|
126 |
```python
|
@@ -133,8 +129,7 @@ no return
|
|
133 |
from ragflow import RAGFlow
|
134 |
|
135 |
rag = RAGFlow(api_key="xxxxxx", base_url="http://xxx.xx.xx.xxx:9380")
|
136 |
-
rag.
|
137 |
-
rag.delete_dataset(ids=["id_1","id_2"])
|
138 |
```
|
139 |
|
140 |
---
|
@@ -711,32 +706,35 @@ for c in rag.retrieval(question="What's ragflow?",
|
|
711 |
---
|
712 |
|
713 |
:::tip API GROUPING
|
714 |
-
Chat
|
715 |
:::
|
716 |
|
717 |
-
## Create
|
718 |
|
719 |
```python
|
720 |
-
RAGFlow.
|
721 |
name: str = "assistant",
|
722 |
avatar: str = "path",
|
723 |
knowledgebases: List[DataSet] = ["kb1"],
|
724 |
-
llm:
|
725 |
-
prompt:
|
726 |
-
) ->
|
|
|
727 |
```
|
728 |
|
729 |
### Returns
|
730 |
|
731 |
-
|
|
|
|
|
732 |
|
733 |
#### name: `str`
|
734 |
|
735 |
-
The name of the created
|
736 |
|
737 |
#### avatar: `str`
|
738 |
|
739 |
-
The icon of the created
|
740 |
|
741 |
#### knowledgebases: `List[DataSet]`
|
742 |
|
@@ -744,11 +742,11 @@ Select knowledgebases associated. Defaults to `["kb1"]`.
|
|
744 |
|
745 |
#### id: `str`
|
746 |
|
747 |
-
The id of the created
|
748 |
|
749 |
#### llm: `LLM`
|
750 |
|
751 |
-
The llm of the created
|
752 |
|
753 |
- **model_name**, `str`
|
754 |
Large language chat model. If it is `None`, it will return the user's default model.
|
@@ -782,22 +780,21 @@ from ragflow import RAGFlow
|
|
782 |
|
783 |
rag = RAGFlow(api_key="xxxxxx", base_url="http://xxx.xx.xx.xxx:9380")
|
784 |
kb = rag.get_dataset(name="kb_1")
|
785 |
-
assi = rag.
|
786 |
```
|
787 |
|
788 |
---
|
789 |
|
790 |
-
##
|
791 |
|
792 |
```python
|
793 |
-
|
794 |
```
|
795 |
|
796 |
### Returns
|
797 |
|
798 |
```python
|
799 |
-
|
800 |
-
description:the case of updating an assistant, True or False.
|
801 |
```
|
802 |
|
803 |
### Examples
|
@@ -807,24 +804,28 @@ from ragflow import RAGFlow
|
|
807 |
|
808 |
rag = RAGFlow(api_key="xxxxxx", base_url="http://xxx.xx.xx.xxx:9380")
|
809 |
kb = rag.get_knowledgebase(name="kb_1")
|
810 |
-
assi = rag.
|
811 |
-
assi.
|
812 |
-
assi.save()
|
813 |
```
|
814 |
|
815 |
---
|
816 |
|
817 |
-
## Delete
|
818 |
|
819 |
```python
|
820 |
-
|
821 |
```
|
|
|
|
|
|
|
|
|
|
|
|
|
822 |
|
823 |
### Returns
|
824 |
|
825 |
```python
|
826 |
-
|
827 |
-
description:the case of deleting an assistant, True or False.
|
828 |
```
|
829 |
|
830 |
### Examples
|
@@ -833,98 +834,58 @@ description:the case of deleting an assistant, True or False.
|
|
833 |
from ragflow import RAGFlow
|
834 |
|
835 |
rag = RAGFlow(api_key="xxxxxx", base_url="http://xxx.xx.xx.xxx:9380")
|
836 |
-
|
837 |
-
assi = rag.create_assistant("Miss R", knowledgebases=[kb])
|
838 |
-
assi.delete()
|
839 |
```
|
840 |
|
841 |
---
|
842 |
|
843 |
-
##
|
844 |
|
845 |
```python
|
846 |
-
RAGFlow.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
847 |
```
|
848 |
|
849 |
### Parameters
|
850 |
|
851 |
-
####
|
852 |
-
|
853 |
-
ID of the assistant to retrieve. If `name` is not provided, `id` is required.
|
854 |
-
|
855 |
-
#### name: `str`
|
856 |
-
|
857 |
-
Name of the assistant to retrieve. If `id` is not provided, `name` is required.
|
858 |
-
|
859 |
-
### Returns
|
860 |
-
|
861 |
-
Assistant object.
|
862 |
-
|
863 |
-
#### name: `str`
|
864 |
-
|
865 |
-
The name of the created assistant. Defaults to `"assistant"`.
|
866 |
-
|
867 |
-
#### avatar: `str`
|
868 |
-
|
869 |
-
The icon of the created assistant. Defaults to `"path"`.
|
870 |
-
|
871 |
-
#### knowledgebases: `List[DataSet]`
|
872 |
-
|
873 |
-
Select knowledgebases associated. Defaults to `["kb1"]`.
|
874 |
-
|
875 |
-
#### id: `str`
|
876 |
-
|
877 |
-
The id of the created assistant. Defaults to `""`.
|
878 |
-
|
879 |
-
#### llm: `LLM`
|
880 |
|
881 |
-
The
|
882 |
-
|
883 |
-
- **model_name**, `str`
|
884 |
-
Large language chat model. If it is `None`, it will return the user's default model.
|
885 |
-
- **temperature**, `float`
|
886 |
-
This parameter controls the randomness of predictions by the model. A lower temperature makes the model more confident in its responses, while a higher temperature makes it more creative and diverse. Defaults to `0.1`.
|
887 |
-
- **top_p**, `float`
|
888 |
-
Also known as “nucleus sampling,” this parameter sets a threshold to select a smaller set of words to sample from. It focuses on the most likely words, cutting off the less probable ones. Defaults to `0.3`
|
889 |
-
- **presence_penalty**, `float`
|
890 |
-
This discourages the model from repeating the same information by penalizing words that have already appeared in the conversation. Defaults to `0.2`.
|
891 |
-
- **frequency penalty**, `float`
|
892 |
-
Similar to the presence penalty, this reduces the model’s tendency to repeat the same words frequently. Defaults to `0.7`.
|
893 |
-
- **max_token**, `int`
|
894 |
-
This sets the maximum length of the model’s output, measured in the number of tokens (words or pieces of words). Defaults to `512`.
|
895 |
|
896 |
-
####
|
897 |
|
898 |
-
|
|
|
899 |
|
900 |
-
|
901 |
-
```
|
902 |
-
You are an intelligent assistant. Please summarize the content of the knowledge base to answer the question. Please list the data in the knowledge base and answer in detail. When all knowledge base content is irrelevant to the question, your answer must include the sentence "The answer you are looking for is not found in the knowledge base!" Answers need to consider chat history.
|
903 |
-
Here is the knowledge base:
|
904 |
-
{knowledge}
|
905 |
-
The above is the knowledge base.
|
906 |
-
```
|
907 |
|
908 |
-
|
|
|
909 |
|
910 |
-
|
911 |
-
from ragflow import RAGFlow
|
912 |
|
913 |
-
|
914 |
-
|
915 |
-
```
|
916 |
|
917 |
-
|
918 |
|
919 |
-
|
|
|
920 |
|
921 |
-
|
922 |
-
RAGFlow.list_assistants() -> List[Assistant]
|
923 |
-
```
|
924 |
|
|
|
|
|
925 |
### Returns
|
926 |
|
927 |
-
A list of
|
928 |
|
929 |
### Examples
|
930 |
|
@@ -932,7 +893,7 @@ A list of assistant objects.
|
|
932 |
from ragflow import RAGFlow
|
933 |
|
934 |
rag = RAGFlow(api_key="xxxxxx", base_url="http://xxx.xx.xx.xxx:9380")
|
935 |
-
for assi in rag.
|
936 |
print(assi)
|
937 |
```
|
938 |
|
|
|
107 |
## Delete knowledge bases
|
108 |
|
109 |
```python
|
110 |
+
RAGFlow.delete_datasets(ids: List[str] = None)
|
111 |
```
|
112 |
Deletes knowledge bases.
|
113 |
### Parameters
|
|
|
116 |
|
117 |
The ids of the datasets to be deleted.
|
118 |
|
|
|
119 |
|
|
|
|
|
|
|
120 |
### Returns
|
121 |
|
122 |
```python
|
|
|
129 |
from ragflow import RAGFlow
|
130 |
|
131 |
rag = RAGFlow(api_key="xxxxxx", base_url="http://xxx.xx.xx.xxx:9380")
|
132 |
+
rag.delete_datasets(ids=["id_1","id_2"])
|
|
|
133 |
```
|
134 |
|
135 |
---
|
|
|
706 |
---
|
707 |
|
708 |
:::tip API GROUPING
|
709 |
+
Chat APIs
|
710 |
:::
|
711 |
|
712 |
+
## Create chat
|
713 |
|
714 |
```python
|
715 |
+
RAGFlow.create_chat(
|
716 |
name: str = "assistant",
|
717 |
avatar: str = "path",
|
718 |
knowledgebases: List[DataSet] = ["kb1"],
|
719 |
+
llm: Chat.LLM = None,
|
720 |
+
prompt: Chat.Prompt = None
|
721 |
+
) -> Chat
|
722 |
+
|
723 |
```
|
724 |
|
725 |
### Returns
|
726 |
|
727 |
+
Chat
|
728 |
+
|
729 |
+
description: assitant object.
|
730 |
|
731 |
#### name: `str`
|
732 |
|
733 |
+
The name of the created chat. Defaults to `"assistant"`.
|
734 |
|
735 |
#### avatar: `str`
|
736 |
|
737 |
+
The icon of the created chat. Defaults to `"path"`.
|
738 |
|
739 |
#### knowledgebases: `List[DataSet]`
|
740 |
|
|
|
742 |
|
743 |
#### id: `str`
|
744 |
|
745 |
+
The id of the created chat. Defaults to `""`.
|
746 |
|
747 |
#### llm: `LLM`
|
748 |
|
749 |
+
The llm of the created chat. Defaults to `None`. When the value is `None`, a dictionary with the following values will be generated as the default.
|
750 |
|
751 |
- **model_name**, `str`
|
752 |
Large language chat model. If it is `None`, it will return the user's default model.
|
|
|
780 |
|
781 |
rag = RAGFlow(api_key="xxxxxx", base_url="http://xxx.xx.xx.xxx:9380")
|
782 |
kb = rag.get_dataset(name="kb_1")
|
783 |
+
assi = rag.create_chat("Miss R", knowledgebases=[kb])
|
784 |
```
|
785 |
|
786 |
---
|
787 |
|
788 |
+
## Update chat
|
789 |
|
790 |
```python
|
791 |
+
Chat.update(update_message: dict)
|
792 |
```
|
793 |
|
794 |
### Returns
|
795 |
|
796 |
```python
|
797 |
+
no return
|
|
|
798 |
```
|
799 |
|
800 |
### Examples
|
|
|
804 |
|
805 |
rag = RAGFlow(api_key="xxxxxx", base_url="http://xxx.xx.xx.xxx:9380")
|
806 |
kb = rag.get_knowledgebase(name="kb_1")
|
807 |
+
assi = rag.create_chat("Miss R", knowledgebases=[kb])
|
808 |
+
assi.update({"temperature":0.8})
|
|
|
809 |
```
|
810 |
|
811 |
---
|
812 |
|
813 |
+
## Delete chats
|
814 |
|
815 |
```python
|
816 |
+
RAGFlow.delete_chats(ids: List[str] = None)
|
817 |
```
|
818 |
+
### Parameters
|
819 |
+
|
820 |
+
#### ids: `str`
|
821 |
+
|
822 |
+
IDs of the chats to be deleted.
|
823 |
+
|
824 |
|
825 |
### Returns
|
826 |
|
827 |
```python
|
828 |
+
no return
|
|
|
829 |
```
|
830 |
|
831 |
### Examples
|
|
|
834 |
from ragflow import RAGFlow
|
835 |
|
836 |
rag = RAGFlow(api_key="xxxxxx", base_url="http://xxx.xx.xx.xxx:9380")
|
837 |
+
rag.delete_chats(ids=["id_1","id_2"])
|
|
|
|
|
838 |
```
|
839 |
|
840 |
---
|
841 |
|
842 |
+
## List chats
|
843 |
|
844 |
```python
|
845 |
+
RAGFlow.list_chats(
|
846 |
+
page: int = 1,
|
847 |
+
page_size: int = 1024,
|
848 |
+
orderby: str = "create_time",
|
849 |
+
desc: bool = True,
|
850 |
+
id: str = None,
|
851 |
+
name: str = None
|
852 |
+
) -> List[Chat]
|
853 |
```
|
854 |
|
855 |
### Parameters
|
856 |
|
857 |
+
#### page: `int`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
858 |
|
859 |
+
The current page number to retrieve from the paginated data. This parameter determines which set of records will be fetched.
|
860 |
+
- `1`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
861 |
|
862 |
+
#### page_size: `int`
|
863 |
|
864 |
+
The number of records to retrieve per page. This controls how many records will be included in each page.
|
865 |
+
- `1024`
|
866 |
|
867 |
+
#### orderby: `string`
|
|
|
|
|
|
|
|
|
|
|
|
|
868 |
|
869 |
+
The field by which the records should be sorted. This specifies the attribute or column used to order the results.
|
870 |
+
- `"create_time"`
|
871 |
|
872 |
+
#### desc: `bool`
|
|
|
873 |
|
874 |
+
A boolean flag indicating whether the sorting should be in descending order.
|
875 |
+
- `True`
|
|
|
876 |
|
877 |
+
#### id: `string`
|
878 |
|
879 |
+
The ID of the chat to be retrieved.
|
880 |
+
- `None`
|
881 |
|
882 |
+
#### name: `string`
|
|
|
|
|
883 |
|
884 |
+
The name of the chat to be retrieved.
|
885 |
+
- `None`
|
886 |
### Returns
|
887 |
|
888 |
+
A list of chat objects.
|
889 |
|
890 |
### Examples
|
891 |
|
|
|
893 |
from ragflow import RAGFlow
|
894 |
|
895 |
rag = RAGFlow(api_key="xxxxxx", base_url="http://xxx.xx.xx.xxx:9380")
|
896 |
+
for assi in rag.list_chats():
|
897 |
print(assi)
|
898 |
```
|
899 |
|
api/utils/api_utils.py
CHANGED
@@ -279,8 +279,8 @@ def get_result(retcode=RetCode.SUCCESS, retmsg='error', data=None):
|
|
279 |
response = {"code": retcode, "message": retmsg}
|
280 |
return jsonify(response)
|
281 |
|
282 |
-
def get_error_data_result(retcode=RetCode.DATA_ERROR,
|
283 |
-
|
284 |
import re
|
285 |
result_dict = {
|
286 |
"code": retcode,
|
@@ -295,5 +295,4 @@ def get_error_data_result(retcode=RetCode.DATA_ERROR,
|
|
295 |
continue
|
296 |
else:
|
297 |
response[key] = value
|
298 |
-
return jsonify(response)
|
299 |
-
|
|
|
279 |
response = {"code": retcode, "message": retmsg}
|
280 |
return jsonify(response)
|
281 |
|
282 |
+
def get_error_data_result(retmsg='Sorry! Data missing!',retcode=RetCode.DATA_ERROR,
|
283 |
+
):
|
284 |
import re
|
285 |
result_dict = {
|
286 |
"code": retcode,
|
|
|
295 |
continue
|
296 |
else:
|
297 |
response[key] = value
|
298 |
+
return jsonify(response)
|
|
sdk/python/ragflow/__init__.py
CHANGED
@@ -4,7 +4,7 @@ __version__ = importlib.metadata.version("ragflow")
|
|
4 |
|
5 |
from .ragflow import RAGFlow
|
6 |
from .modules.dataset import DataSet
|
7 |
-
from .modules.
|
8 |
from .modules.session import Session
|
9 |
from .modules.document import Document
|
10 |
from .modules.chunk import Chunk
|
|
|
4 |
|
5 |
from .ragflow import RAGFlow
|
6 |
from .modules.dataset import DataSet
|
7 |
+
from .modules.chat import Chat
|
8 |
from .modules.session import Session
|
9 |
from .modules.document import Document
|
10 |
from .modules.chunk import Chunk
|
sdk/python/ragflow/modules/base.py
CHANGED
@@ -18,16 +18,16 @@ class Base(object):
|
|
18 |
pr[name] = value
|
19 |
return pr
|
20 |
|
21 |
-
def post(self, path,
|
22 |
-
res = self.rag.post(path,
|
23 |
return res
|
24 |
|
25 |
def get(self, path, params):
|
26 |
res = self.rag.get(path, params)
|
27 |
return res
|
28 |
|
29 |
-
def rm(self, path,
|
30 |
-
res = self.rag.delete(path,
|
31 |
return res
|
32 |
|
33 |
def put(self,path, json):
|
|
|
18 |
pr[name] = value
|
19 |
return pr
|
20 |
|
21 |
+
def post(self, path, json, stream=False):
|
22 |
+
res = self.rag.post(path, json, stream=stream)
|
23 |
return res
|
24 |
|
25 |
def get(self, path, params):
|
26 |
res = self.rag.get(path, params)
|
27 |
return res
|
28 |
|
29 |
+
def rm(self, path, json):
|
30 |
+
res = self.rag.delete(path, json)
|
31 |
return res
|
32 |
|
33 |
def put(self,path, json):
|
sdk/python/ragflow/modules/{assistant.py → chat.py}
RENAMED
@@ -4,14 +4,14 @@ from .base import Base
|
|
4 |
from .session import Session
|
5 |
|
6 |
|
7 |
-
class
|
8 |
def __init__(self, rag, res_dict):
|
9 |
self.id = ""
|
10 |
self.name = "assistant"
|
11 |
self.avatar = "path/to/avatar"
|
12 |
self.knowledgebases = ["kb1"]
|
13 |
-
self.llm =
|
14 |
-
self.prompt =
|
15 |
super().__init__(rag, res_dict)
|
16 |
|
17 |
class LLM(Base):
|
@@ -42,21 +42,13 @@ class Assistant(Base):
|
|
42 |
)
|
43 |
super().__init__(rag, res_dict)
|
44 |
|
45 |
-
def
|
46 |
-
res = self.
|
47 |
-
|
48 |
-
"llm": self.llm.to_json(), "prompt": self.prompt.to_json()
|
49 |
-
})
|
50 |
res = res.json()
|
51 |
-
if res.get("
|
52 |
-
|
53 |
|
54 |
-
def delete(self) -> bool:
|
55 |
-
res = self.rm('/assistant/delete',
|
56 |
-
{"id": self.id})
|
57 |
-
res = res.json()
|
58 |
-
if res.get("retmsg") == "success": return True
|
59 |
-
raise Exception(res["retmsg"])
|
60 |
|
61 |
def create_session(self, name: str = "New session") -> Session:
|
62 |
res = self.post("/session/save", {"name": name, "assistant_id": self.id})
|
|
|
4 |
from .session import Session
|
5 |
|
6 |
|
7 |
+
class Chat(Base):
|
8 |
def __init__(self, rag, res_dict):
|
9 |
self.id = ""
|
10 |
self.name = "assistant"
|
11 |
self.avatar = "path/to/avatar"
|
12 |
self.knowledgebases = ["kb1"]
|
13 |
+
self.llm = Chat.LLM(rag, {})
|
14 |
+
self.prompt = Chat.Prompt(rag, {})
|
15 |
super().__init__(rag, res_dict)
|
16 |
|
17 |
class LLM(Base):
|
|
|
42 |
)
|
43 |
super().__init__(rag, res_dict)
|
44 |
|
45 |
+
def update(self, update_message: dict):
|
46 |
+
res = self.put(f'/chat/{self.id}',
|
47 |
+
update_message)
|
|
|
|
|
48 |
res = res.json()
|
49 |
+
if res.get("code") != 0:
|
50 |
+
raise Exception(res["message"])
|
51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
53 |
def create_session(self, name: str = "New session") -> Session:
|
54 |
res = self.post("/session/save", {"name": name, "assistant_id": self.id})
|
sdk/python/ragflow/ragflow.py
CHANGED
@@ -17,7 +17,7 @@ from typing import List
|
|
17 |
|
18 |
import requests
|
19 |
|
20 |
-
from .modules.
|
21 |
from .modules.chunk import Chunk
|
22 |
from .modules.dataset import DataSet
|
23 |
from .modules.document import Document
|
@@ -32,16 +32,16 @@ class RAGFlow:
|
|
32 |
self.api_url = f"{base_url}/api/{version}"
|
33 |
self.authorization_header = {"Authorization": "{} {}".format("Bearer", self.user_key)}
|
34 |
|
35 |
-
def post(self, path,
|
36 |
-
res = requests.post(url=self.api_url + path, json=
|
37 |
return res
|
38 |
|
39 |
def get(self, path, params=None):
|
40 |
res = requests.get(url=self.api_url + path, params=params, headers=self.authorization_header)
|
41 |
return res
|
42 |
|
43 |
-
def delete(self, path,
|
44 |
-
res = requests.delete(url=self.api_url + path, json=
|
45 |
return res
|
46 |
|
47 |
def put(self, path, json):
|
@@ -68,7 +68,7 @@ class RAGFlow:
|
|
68 |
return DataSet(self, res["data"])
|
69 |
raise Exception(res["message"])
|
70 |
|
71 |
-
def
|
72 |
res = self.delete("/dataset",{"ids": ids, "names": names})
|
73 |
res=res.json()
|
74 |
if res.get("code") != 0:
|
@@ -87,21 +87,21 @@ class RAGFlow:
|
|
87 |
return result_list
|
88 |
raise Exception(res["message"])
|
89 |
|
90 |
-
def
|
91 |
-
llm:
|
92 |
datasets = []
|
93 |
for dataset in knowledgebases:
|
94 |
datasets.append(dataset.to_json())
|
95 |
|
96 |
if llm is None:
|
97 |
-
llm =
|
98 |
"temperature": 0.1,
|
99 |
"top_p": 0.3,
|
100 |
"presence_penalty": 0.4,
|
101 |
"frequency_penalty": 0.7,
|
102 |
"max_tokens": 512, })
|
103 |
if prompt is None:
|
104 |
-
prompt =
|
105 |
"keywords_similarity_weight": 0.7,
|
106 |
"top_n": 8,
|
107 |
"variables": [{
|
@@ -127,28 +127,29 @@ class RAGFlow:
|
|
127 |
"knowledgebases": datasets,
|
128 |
"llm": llm.to_json(),
|
129 |
"prompt": prompt.to_json()}
|
130 |
-
res = self.post("/
|
131 |
res = res.json()
|
132 |
-
if res.get("
|
133 |
-
return
|
134 |
-
raise Exception(res["
|
135 |
|
136 |
-
def
|
137 |
-
res = self.
|
|
|
138 |
res = res.json()
|
139 |
-
if res.get("
|
140 |
-
|
141 |
-
raise Exception(res["retmsg"])
|
142 |
|
143 |
-
def
|
144 |
-
|
|
|
145 |
res = res.json()
|
146 |
result_list = []
|
147 |
-
if res.get("
|
148 |
for data in res['data']:
|
149 |
-
result_list.append(
|
150 |
return result_list
|
151 |
-
raise Exception(res["
|
152 |
|
153 |
def create_document(self, ds: DataSet, name: str, blob: bytes) -> bool:
|
154 |
url = f"/doc/dataset/{ds.id}/documents/upload"
|
|
|
17 |
|
18 |
import requests
|
19 |
|
20 |
+
from .modules.chat import Chat
|
21 |
from .modules.chunk import Chunk
|
22 |
from .modules.dataset import DataSet
|
23 |
from .modules.document import Document
|
|
|
32 |
self.api_url = f"{base_url}/api/{version}"
|
33 |
self.authorization_header = {"Authorization": "{} {}".format("Bearer", self.user_key)}
|
34 |
|
35 |
+
def post(self, path, json, stream=False):
|
36 |
+
res = requests.post(url=self.api_url + path, json=json, headers=self.authorization_header, stream=stream)
|
37 |
return res
|
38 |
|
39 |
def get(self, path, params=None):
|
40 |
res = requests.get(url=self.api_url + path, params=params, headers=self.authorization_header)
|
41 |
return res
|
42 |
|
43 |
+
def delete(self, path, json):
|
44 |
+
res = requests.delete(url=self.api_url + path, json=json, headers=self.authorization_header)
|
45 |
return res
|
46 |
|
47 |
def put(self, path, json):
|
|
|
68 |
return DataSet(self, res["data"])
|
69 |
raise Exception(res["message"])
|
70 |
|
71 |
+
def delete_datasets(self, ids: List[str] = None, names: List[str] = None):
|
72 |
res = self.delete("/dataset",{"ids": ids, "names": names})
|
73 |
res=res.json()
|
74 |
if res.get("code") != 0:
|
|
|
87 |
return result_list
|
88 |
raise Exception(res["message"])
|
89 |
|
90 |
+
def create_chat(self, name: str = "assistant", avatar: str = "path", knowledgebases: List[DataSet] = [],
|
91 |
+
llm: Chat.LLM = None, prompt: Chat.Prompt = None) -> Chat:
|
92 |
datasets = []
|
93 |
for dataset in knowledgebases:
|
94 |
datasets.append(dataset.to_json())
|
95 |
|
96 |
if llm is None:
|
97 |
+
llm = Chat.LLM(self, {"model_name": None,
|
98 |
"temperature": 0.1,
|
99 |
"top_p": 0.3,
|
100 |
"presence_penalty": 0.4,
|
101 |
"frequency_penalty": 0.7,
|
102 |
"max_tokens": 512, })
|
103 |
if prompt is None:
|
104 |
+
prompt = Chat.Prompt(self, {"similarity_threshold": 0.2,
|
105 |
"keywords_similarity_weight": 0.7,
|
106 |
"top_n": 8,
|
107 |
"variables": [{
|
|
|
127 |
"knowledgebases": datasets,
|
128 |
"llm": llm.to_json(),
|
129 |
"prompt": prompt.to_json()}
|
130 |
+
res = self.post("/chat", temp_dict)
|
131 |
res = res.json()
|
132 |
+
if res.get("code") == 0:
|
133 |
+
return Chat(self, res["data"])
|
134 |
+
raise Exception(res["message"])
|
135 |
|
136 |
+
def delete_chats(self,ids: List[str] = None,names: List[str] = None ) -> bool:
|
137 |
+
res = self.delete('/chat',
|
138 |
+
{"ids":ids, "names":names})
|
139 |
res = res.json()
|
140 |
+
if res.get("code") != 0:
|
141 |
+
raise Exception(res["message"])
|
|
|
142 |
|
143 |
+
def list_chats(self, page: int = 1, page_size: int = 1024, orderby: str = "create_time", desc: bool = True,
|
144 |
+
id: str = None, name: str = None) -> List[Chat]:
|
145 |
+
res = self.get("/chat",{"page": page, "page_size": page_size, "orderby": orderby, "desc": desc, "id": id, "name": name})
|
146 |
res = res.json()
|
147 |
result_list = []
|
148 |
+
if res.get("code") == 0:
|
149 |
for data in res['data']:
|
150 |
+
result_list.append(Chat(self, data))
|
151 |
return result_list
|
152 |
+
raise Exception(res["message"])
|
153 |
|
154 |
def create_document(self, ds: DataSet, name: str, blob: bytes) -> bool:
|
155 |
url = f"/doc/dataset/{ds.id}/documents/upload"
|
sdk/python/test/t_assistant.py
DELETED
@@ -1,68 +0,0 @@
|
|
1 |
-
from ragflow import RAGFlow, Assistant
|
2 |
-
|
3 |
-
from common import API_KEY, HOST_ADDRESS
|
4 |
-
from test_sdkbase import TestSdk
|
5 |
-
|
6 |
-
|
7 |
-
class TestAssistant(TestSdk):
|
8 |
-
def test_create_assistant_with_success(self):
|
9 |
-
"""
|
10 |
-
Test creating an assistant with success
|
11 |
-
"""
|
12 |
-
rag = RAGFlow(API_KEY, HOST_ADDRESS)
|
13 |
-
kb = rag.create_dataset(name="test_create_assistant")
|
14 |
-
assistant = rag.create_assistant("test_create", knowledgebases=[kb])
|
15 |
-
if isinstance(assistant, Assistant):
|
16 |
-
assert assistant.name == "test_create", "Name does not match."
|
17 |
-
else:
|
18 |
-
assert False, f"Failed to create assistant, error: {assistant}"
|
19 |
-
|
20 |
-
def test_update_assistant_with_success(self):
|
21 |
-
"""
|
22 |
-
Test updating an assistant with success.
|
23 |
-
"""
|
24 |
-
rag = RAGFlow(API_KEY, HOST_ADDRESS)
|
25 |
-
kb = rag.create_dataset(name="test_update_assistant")
|
26 |
-
assistant = rag.create_assistant("test_update", knowledgebases=[kb])
|
27 |
-
if isinstance(assistant, Assistant):
|
28 |
-
assert assistant.name == "test_update", "Name does not match."
|
29 |
-
assistant.name = 'new_assistant'
|
30 |
-
res = assistant.save()
|
31 |
-
assert res is True, f"Failed to update assistant, error: {res}"
|
32 |
-
else:
|
33 |
-
assert False, f"Failed to create assistant, error: {assistant}"
|
34 |
-
|
35 |
-
def test_delete_assistant_with_success(self):
|
36 |
-
"""
|
37 |
-
Test deleting an assistant with success
|
38 |
-
"""
|
39 |
-
rag = RAGFlow(API_KEY, HOST_ADDRESS)
|
40 |
-
kb = rag.create_dataset(name="test_delete_assistant")
|
41 |
-
assistant = rag.create_assistant("test_delete", knowledgebases=[kb])
|
42 |
-
if isinstance(assistant, Assistant):
|
43 |
-
assert assistant.name == "test_delete", "Name does not match."
|
44 |
-
res = assistant.delete()
|
45 |
-
assert res is True, f"Failed to delete assistant, error: {res}"
|
46 |
-
else:
|
47 |
-
assert False, f"Failed to create assistant, error: {assistant}"
|
48 |
-
|
49 |
-
def test_list_assistants_with_success(self):
|
50 |
-
"""
|
51 |
-
Test listing assistants with success
|
52 |
-
"""
|
53 |
-
rag = RAGFlow(API_KEY, HOST_ADDRESS)
|
54 |
-
list_assistants = rag.list_assistants()
|
55 |
-
assert len(list_assistants) > 0, "Do not exist any assistant"
|
56 |
-
for assistant in list_assistants:
|
57 |
-
assert isinstance(assistant, Assistant), "Existence type is not assistant."
|
58 |
-
|
59 |
-
def test_get_detail_assistant_with_success(self):
|
60 |
-
"""
|
61 |
-
Test getting an assistant's detail with success
|
62 |
-
"""
|
63 |
-
rag = RAGFlow(API_KEY, HOST_ADDRESS)
|
64 |
-
kb = rag.create_dataset(name="test_get_assistant")
|
65 |
-
rag.create_assistant("test_get_assistant", knowledgebases=[kb])
|
66 |
-
assistant = rag.get_assistant(name="test_get_assistant")
|
67 |
-
assert isinstance(assistant, Assistant), f"Failed to get assistant, error: {assistant}."
|
68 |
-
assert assistant.name == "test_get_assistant", "Name does not match"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sdk/python/test/t_chat.py
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from ragflow import RAGFlow, Chat
|
2 |
+
|
3 |
+
from common import API_KEY, HOST_ADDRESS
|
4 |
+
from test_sdkbase import TestSdk
|
5 |
+
|
6 |
+
|
7 |
+
class TestChat(TestSdk):
|
8 |
+
def test_create_chat_with_success(self):
|
9 |
+
"""
|
10 |
+
Test creating an chat with success
|
11 |
+
"""
|
12 |
+
rag = RAGFlow(API_KEY, HOST_ADDRESS)
|
13 |
+
kb = rag.create_dataset(name="test_create_chat")
|
14 |
+
chat = rag.create_chat("test_create", knowledgebases=[kb])
|
15 |
+
if isinstance(chat, Chat):
|
16 |
+
assert chat.name == "test_create", "Name does not match."
|
17 |
+
else:
|
18 |
+
assert False, f"Failed to create chat, error: {chat}"
|
19 |
+
|
20 |
+
def test_update_chat_with_success(self):
|
21 |
+
"""
|
22 |
+
Test updating an chat with success.
|
23 |
+
"""
|
24 |
+
rag = RAGFlow(API_KEY, HOST_ADDRESS)
|
25 |
+
kb = rag.create_dataset(name="test_update_chat")
|
26 |
+
chat = rag.create_chat("test_update", knowledgebases=[kb])
|
27 |
+
if isinstance(chat, Chat):
|
28 |
+
assert chat.name == "test_update", "Name does not match."
|
29 |
+
res=chat.update({"name":"new_chat"})
|
30 |
+
assert res is None, f"Failed to update chat, error: {res}"
|
31 |
+
else:
|
32 |
+
assert False, f"Failed to create chat, error: {chat}"
|
33 |
+
|
34 |
+
def test_delete_chats_with_success(self):
|
35 |
+
"""
|
36 |
+
Test deleting an chat with success
|
37 |
+
"""
|
38 |
+
rag = RAGFlow(API_KEY, HOST_ADDRESS)
|
39 |
+
kb = rag.create_dataset(name="test_delete_chat")
|
40 |
+
chat = rag.create_chat("test_delete", knowledgebases=[kb])
|
41 |
+
if isinstance(chat, Chat):
|
42 |
+
assert chat.name == "test_delete", "Name does not match."
|
43 |
+
res = rag.delete_chats(ids=[chat.id])
|
44 |
+
assert res is None, f"Failed to delete chat, error: {res}"
|
45 |
+
else:
|
46 |
+
assert False, f"Failed to create chat, error: {chat}"
|
47 |
+
|
48 |
+
def test_list_chats_with_success(self):
|
49 |
+
"""
|
50 |
+
Test listing chats with success
|
51 |
+
"""
|
52 |
+
rag = RAGFlow(API_KEY, HOST_ADDRESS)
|
53 |
+
list_chats = rag.list_chats()
|
54 |
+
assert len(list_chats) > 0, "Do not exist any chat"
|
55 |
+
for chat in list_chats:
|
56 |
+
assert isinstance(chat, Chat), "Existence type is not chat."
|
sdk/python/test/t_dataset.py
CHANGED
@@ -29,7 +29,7 @@ class TestDataset(TestSdk):
|
|
29 |
else:
|
30 |
assert False, f"Failed to create dataset, error: {ds}"
|
31 |
|
32 |
-
def
|
33 |
"""
|
34 |
Test deleting a dataset with success
|
35 |
"""
|
@@ -37,7 +37,7 @@ class TestDataset(TestSdk):
|
|
37 |
ds = rag.create_dataset("MA")
|
38 |
if isinstance(ds, DataSet):
|
39 |
assert ds.name == "MA", "Name does not match."
|
40 |
-
res = rag.
|
41 |
assert res is None, f"Failed to delete dataset, error: {res}"
|
42 |
else:
|
43 |
assert False, f"Failed to create dataset, error: {ds}"
|
|
|
29 |
else:
|
30 |
assert False, f"Failed to create dataset, error: {ds}"
|
31 |
|
32 |
+
def test_delete_datasets_with_success(self):
|
33 |
"""
|
34 |
Test deleting a dataset with success
|
35 |
"""
|
|
|
37 |
ds = rag.create_dataset("MA")
|
38 |
if isinstance(ds, DataSet):
|
39 |
assert ds.name == "MA", "Name does not match."
|
40 |
+
res = rag.delete_datasets(ids=[ds.id])
|
41 |
assert res is None, f"Failed to delete dataset, error: {res}"
|
42 |
else:
|
43 |
assert False, f"Failed to create dataset, error: {ds}"
|