zhichyu commited on
Commit
196c662
·
1 Parent(s): b471fdf

Unified API response json schema (#3170)

Browse files

### What problem does this PR solve?

Unified API response json schema

### Type of change

- [x] Refactoring

This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. api/apps/api_app.py +47 -47
  2. api/apps/canvas_app.py +15 -15
  3. api/apps/chunk_app.py +22 -23
  4. api/apps/conversation_app.py +26 -26
  5. api/apps/dialog_app.py +10 -10
  6. api/apps/document_app.py +48 -48
  7. api/apps/file2document_app.py +11 -15
  8. api/apps/file_app.py +29 -32
  9. api/apps/kb_app.py +15 -15
  10. api/apps/llm_app.py +2 -2
  11. api/apps/sdk/chat.py +20 -20
  12. api/apps/sdk/dataset.py +535 -535
  13. api/apps/sdk/dify_retrieval.py +5 -5
  14. api/apps/sdk/doc.py +48 -48
  15. api/apps/sdk/session.py +394 -394
  16. api/apps/system_app.py +3 -5
  17. api/apps/tenant_app.py +3 -3
  18. api/apps/user_app.py +24 -24
  19. api/utils/api_utils.py +36 -36
  20. docs/references/faq.md +1 -1
  21. intergrations/chatgpt-on-wechat/plugins/ragflow_chat.py +7 -9
  22. sdk/python/test/conftest.py +6 -6
  23. sdk/python/test/ragflow.txt +1 -1
  24. web/src/components/message-input/index.tsx +4 -4
  25. web/src/components/message-item/hooks.ts +2 -2
  26. web/src/components/pdf-previewer/hooks.ts +2 -2
  27. web/src/hooks/chat-hooks.ts +15 -15
  28. web/src/hooks/chunk-hooks.ts +7 -7
  29. web/src/hooks/document-hooks.ts +22 -22
  30. web/src/hooks/file-manager-hooks.ts +12 -12
  31. web/src/hooks/flow-hooks.ts +4 -4
  32. web/src/hooks/knowledge-hooks.ts +4 -4
  33. web/src/hooks/llm-hooks.tsx +10 -10
  34. web/src/hooks/logic-hooks.ts +2 -2
  35. web/src/hooks/login-hooks.ts +6 -6
  36. web/src/hooks/user-setting-hooks.tsx +12 -12
  37. web/src/interfaces/database/base.ts +2 -2
  38. web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-creating-modal/index.tsx +1 -1
  39. web/src/pages/add-knowledge/components/knowledge-chunk/hooks.ts +2 -2
  40. web/src/pages/add-knowledge/components/knowledge-file/hooks.ts +7 -7
  41. web/src/pages/chat/hooks.ts +5 -5
  42. web/src/pages/chat/shared-hooks.ts +2 -2
  43. web/src/pages/document-viewer/hooks.ts +2 -2
  44. web/src/pages/file-manager/hooks.ts +2 -2
  45. web/src/pages/file-manager/move-file-modal/async-tree-select.tsx +1 -1
  46. web/src/pages/flow/chat/hooks.ts +2 -2
  47. web/src/pages/flow/hooks.ts +3 -3
  48. web/src/pages/flow/list/hooks.ts +1 -1
  49. web/src/pages/flow/utils.ts +1 -1
  50. web/src/pages/knowledge/hooks.ts +1 -1
api/apps/api_app.py CHANGED
@@ -52,7 +52,7 @@ def new_token():
52
  try:
53
  tenants = UserTenantService.query(user_id=current_user.id)
54
  if not tenants:
55
- return get_data_error_result(retmsg="Tenant not found!")
56
 
57
  tenant_id = tenants[0].tenant_id
58
  obj = {"tenant_id": tenant_id, "token": generate_confirmation_token(tenant_id),
@@ -68,7 +68,7 @@ def new_token():
68
  obj["dialog_id"] = req["dialog_id"]
69
 
70
  if not APITokenService.save(**obj):
71
- return get_data_error_result(retmsg="Fail to new a dialog!")
72
 
73
  return get_json_result(data=obj)
74
  except Exception as e:
@@ -81,7 +81,7 @@ def token_list():
81
  try:
82
  tenants = UserTenantService.query(user_id=current_user.id)
83
  if not tenants:
84
- return get_data_error_result(retmsg="Tenant not found!")
85
 
86
  id = request.args["dialog_id"] if "dialog_id" in request.args else request.args["canvas_id"]
87
  objs = APITokenService.query(tenant_id=tenants[0].tenant_id, dialog_id=id)
@@ -110,7 +110,7 @@ def stats():
110
  try:
111
  tenants = UserTenantService.query(user_id=current_user.id)
112
  if not tenants:
113
- return get_data_error_result(retmsg="Tenant not found!")
114
  objs = API4ConversationService.stats(
115
  tenants[0].tenant_id,
116
  request.args.get(
@@ -141,7 +141,7 @@ def set_conversation():
141
  objs = APIToken.query(token=token)
142
  if not objs:
143
  return get_json_result(
144
- data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR)
145
  req = request.json
146
  try:
147
  if objs[0].source == "agent":
@@ -163,7 +163,7 @@ def set_conversation():
163
  else:
164
  e, dia = DialogService.get_by_id(objs[0].dialog_id)
165
  if not e:
166
- return get_data_error_result(retmsg="Dialog not found")
167
  conv = {
168
  "id": get_uuid(),
169
  "dialog_id": dia.id,
@@ -183,11 +183,11 @@ def completion():
183
  objs = APIToken.query(token=token)
184
  if not objs:
185
  return get_json_result(
186
- data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR)
187
  req = request.json
188
  e, conv = API4ConversationService.get_by_id(req["conversation_id"])
189
  if not e:
190
- return get_data_error_result(retmsg="Conversation not found!")
191
  if "quote" not in req: req["quote"] = False
192
 
193
  msg = []
@@ -257,7 +257,7 @@ def completion():
257
  ans = {"answer": ans["content"], "reference": ans.get("reference", [])}
258
  fillin_conv(ans)
259
  rename_field(ans)
260
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans},
261
  ensure_ascii=False) + "\n\n"
262
 
263
  canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id})
@@ -267,10 +267,10 @@ def completion():
267
  cvs.dsl = json.loads(str(canvas))
268
  API4ConversationService.append_message(conv.id, conv.to_dict())
269
  except Exception as e:
270
- yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e),
271
  "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
272
  ensure_ascii=False) + "\n\n"
273
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n"
274
 
275
  resp = Response(sse(), mimetype="text/event-stream")
276
  resp.headers.add_header("Cache-control", "no-cache")
@@ -295,7 +295,7 @@ def completion():
295
  conv.message.append(msg[-1])
296
  e, dia = DialogService.get_by_id(conv.dialog_id)
297
  if not e:
298
- return get_data_error_result(retmsg="Dialog not found!")
299
  del req["conversation_id"]
300
  del req["messages"]
301
 
@@ -310,14 +310,14 @@ def completion():
310
  for ans in chat(dia, msg, True, **req):
311
  fillin_conv(ans)
312
  rename_field(ans)
313
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans},
314
  ensure_ascii=False) + "\n\n"
315
  API4ConversationService.append_message(conv.id, conv.to_dict())
316
  except Exception as e:
317
- yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e),
318
  "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
319
  ensure_ascii=False) + "\n\n"
320
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n"
321
 
322
  if req.get("stream", True):
323
  resp = Response(stream(), mimetype="text/event-stream")
@@ -347,17 +347,17 @@ def get(conversation_id):
347
  objs = APIToken.query(token=token)
348
  if not objs:
349
  return get_json_result(
350
- data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR)
351
 
352
  try:
353
  e, conv = API4ConversationService.get_by_id(conversation_id)
354
  if not e:
355
- return get_data_error_result(retmsg="Conversation not found!")
356
 
357
  conv = conv.to_dict()
358
  if token != APIToken.query(dialog_id=conv['dialog_id'])[0].token:
359
- return get_json_result(data=False, retmsg='Token is not valid for this conversation_id!"',
360
- retcode=RetCode.AUTHENTICATION_ERROR)
361
 
362
  for referenct_i in conv['reference']:
363
  if referenct_i is None or len(referenct_i) == 0:
@@ -378,7 +378,7 @@ def upload():
378
  objs = APIToken.query(token=token)
379
  if not objs:
380
  return get_json_result(
381
- data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR)
382
 
383
  kb_name = request.form.get("kb_name").strip()
384
  tenant_id = objs[0].tenant_id
@@ -387,19 +387,19 @@ def upload():
387
  e, kb = KnowledgebaseService.get_by_name(kb_name, tenant_id)
388
  if not e:
389
  return get_data_error_result(
390
- retmsg="Can't find this knowledgebase!")
391
  kb_id = kb.id
392
  except Exception as e:
393
  return server_error_response(e)
394
 
395
  if 'file' not in request.files:
396
  return get_json_result(
397
- data=False, retmsg='No file part!', retcode=RetCode.ARGUMENT_ERROR)
398
 
399
  file = request.files['file']
400
  if file.filename == '':
401
  return get_json_result(
402
- data=False, retmsg='No file selected!', retcode=RetCode.ARGUMENT_ERROR)
403
 
404
  root_folder = FileService.get_root_folder(tenant_id)
405
  pf_id = root_folder["id"]
@@ -410,7 +410,7 @@ def upload():
410
  try:
411
  if DocumentService.get_doc_count(kb.tenant_id) >= int(os.environ.get('MAX_FILE_NUM_PER_USER', 8192)):
412
  return get_data_error_result(
413
- retmsg="Exceed the maximum file number of a free user!")
414
 
415
  filename = duplicate_name(
416
  DocumentService.query,
@@ -419,7 +419,7 @@ def upload():
419
  filetype = filename_type(filename)
420
  if not filetype:
421
  return get_data_error_result(
422
- retmsg="This type of file has not been supported yet!")
423
 
424
  location = filename
425
  while STORAGE_IMPL.obj_exist(kb_id, location):
@@ -468,7 +468,7 @@ def upload():
468
  # if str(req["run"]) == TaskStatus.CANCEL.value:
469
  tenant_id = DocumentService.get_tenant_id(doc["id"])
470
  if not tenant_id:
471
- return get_data_error_result(retmsg="Tenant not found!")
472
 
473
  # e, doc = DocumentService.get_by_id(doc["id"])
474
  TaskService.filter_delete([Task.doc_id == doc["id"]])
@@ -490,17 +490,17 @@ def upload_parse():
490
  objs = APIToken.query(token=token)
491
  if not objs:
492
  return get_json_result(
493
- data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR)
494
 
495
  if 'file' not in request.files:
496
  return get_json_result(
497
- data=False, retmsg='No file part!', retcode=RetCode.ARGUMENT_ERROR)
498
 
499
  file_objs = request.files.getlist('file')
500
  for file_obj in file_objs:
501
  if file_obj.filename == '':
502
  return get_json_result(
503
- data=False, retmsg='No file selected!', retcode=RetCode.ARGUMENT_ERROR)
504
 
505
  doc_ids = doc_upload_and_parse(request.form.get("conversation_id"), file_objs, objs[0].tenant_id)
506
  return get_json_result(data=doc_ids)
@@ -513,7 +513,7 @@ def list_chunks():
513
  objs = APIToken.query(token=token)
514
  if not objs:
515
  return get_json_result(
516
- data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR)
517
 
518
  req = request.json
519
 
@@ -527,7 +527,7 @@ def list_chunks():
527
  doc_id = req['doc_id']
528
  else:
529
  return get_json_result(
530
- data=False, retmsg="Can't find doc_name or doc_id"
531
  )
532
 
533
  res = retrievaler.chunk_list(doc_id=doc_id, tenant_id=tenant_id)
@@ -552,7 +552,7 @@ def list_kb_docs():
552
  objs = APIToken.query(token=token)
553
  if not objs:
554
  return get_json_result(
555
- data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR)
556
 
557
  req = request.json
558
  tenant_id = objs[0].tenant_id
@@ -562,7 +562,7 @@ def list_kb_docs():
562
  e, kb = KnowledgebaseService.get_by_name(kb_name, tenant_id)
563
  if not e:
564
  return get_data_error_result(
565
- retmsg="Can't find this knowledgebase!")
566
  kb_id = kb.id
567
 
568
  except Exception as e:
@@ -591,7 +591,7 @@ def docinfos():
591
  objs = APIToken.query(token=token)
592
  if not objs:
593
  return get_json_result(
594
- data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR)
595
  req = request.json
596
  doc_ids = req["doc_ids"]
597
  docs = DocumentService.get_by_ids(doc_ids)
@@ -605,7 +605,7 @@ def document_rm():
605
  objs = APIToken.query(token=token)
606
  if not objs:
607
  return get_json_result(
608
- data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR)
609
 
610
  tenant_id = objs[0].tenant_id
611
  req = request.json
@@ -617,7 +617,7 @@ def document_rm():
617
 
618
  if not doc_ids:
619
  return get_json_result(
620
- data=False, retmsg="Can't find doc_names or doc_ids"
621
  )
622
 
623
  except Exception as e:
@@ -632,16 +632,16 @@ def document_rm():
632
  try:
633
  e, doc = DocumentService.get_by_id(doc_id)
634
  if not e:
635
- return get_data_error_result(retmsg="Document not found!")
636
  tenant_id = DocumentService.get_tenant_id(doc_id)
637
  if not tenant_id:
638
- return get_data_error_result(retmsg="Tenant not found!")
639
 
640
  b, n = File2DocumentService.get_storage_address(doc_id=doc_id)
641
 
642
  if not DocumentService.remove_document(doc, tenant_id):
643
  return get_data_error_result(
644
- retmsg="Database error (Document removal)!")
645
 
646
  f2d = File2DocumentService.get_by_document_id(doc_id)
647
  FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id])
@@ -652,7 +652,7 @@ def document_rm():
652
  errors += str(e)
653
 
654
  if errors:
655
- return get_json_result(data=False, retmsg=errors, retcode=RetCode.SERVER_ERROR)
656
 
657
  return get_json_result(data=True)
658
 
@@ -667,11 +667,11 @@ def completion_faq():
667
  objs = APIToken.query(token=token)
668
  if not objs:
669
  return get_json_result(
670
- data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR)
671
 
672
  e, conv = API4ConversationService.get_by_id(req["conversation_id"])
673
  if not e:
674
- return get_data_error_result(retmsg="Conversation not found!")
675
  if "quote" not in req: req["quote"] = True
676
 
677
  msg = []
@@ -752,7 +752,7 @@ def completion_faq():
752
  conv.message.append(msg[-1])
753
  e, dia = DialogService.get_by_id(conv.dialog_id)
754
  if not e:
755
- return get_data_error_result(retmsg="Dialog not found!")
756
  del req["conversation_id"]
757
 
758
  if not conv.reference:
@@ -804,7 +804,7 @@ def retrieval():
804
  objs = APIToken.query(token=token)
805
  if not objs:
806
  return get_json_result(
807
- data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR)
808
 
809
  req = request.json
810
  kb_ids = req.get("kb_id",[])
@@ -821,7 +821,7 @@ def retrieval():
821
  embd_nms = list(set([kb.embd_id for kb in kbs]))
822
  if len(embd_nms) != 1:
823
  return get_json_result(
824
- data=False, retmsg='Knowledge bases use different embedding models or does not exist."', retcode=RetCode.AUTHENTICATION_ERROR)
825
 
826
  embd_mdl = TenantLLMService.model_instance(
827
  kbs[0].tenant_id, LLMType.EMBEDDING.value, llm_name=kbs[0].embd_id)
@@ -841,6 +841,6 @@ def retrieval():
841
  return get_json_result(data=ranks)
842
  except Exception as e:
843
  if str(e).find("not_found") > 0:
844
- return get_json_result(data=False, retmsg=f'No chunk found! Check the chunk status please!',
845
- retcode=RetCode.DATA_ERROR)
846
  return server_error_response(e)
 
52
  try:
53
  tenants = UserTenantService.query(user_id=current_user.id)
54
  if not tenants:
55
+ return get_data_error_result(message="Tenant not found!")
56
 
57
  tenant_id = tenants[0].tenant_id
58
  obj = {"tenant_id": tenant_id, "token": generate_confirmation_token(tenant_id),
 
68
  obj["dialog_id"] = req["dialog_id"]
69
 
70
  if not APITokenService.save(**obj):
71
+ return get_data_error_result(message="Fail to new a dialog!")
72
 
73
  return get_json_result(data=obj)
74
  except Exception as e:
 
81
  try:
82
  tenants = UserTenantService.query(user_id=current_user.id)
83
  if not tenants:
84
+ return get_data_error_result(message="Tenant not found!")
85
 
86
  id = request.args["dialog_id"] if "dialog_id" in request.args else request.args["canvas_id"]
87
  objs = APITokenService.query(tenant_id=tenants[0].tenant_id, dialog_id=id)
 
110
  try:
111
  tenants = UserTenantService.query(user_id=current_user.id)
112
  if not tenants:
113
+ return get_data_error_result(message="Tenant not found!")
114
  objs = API4ConversationService.stats(
115
  tenants[0].tenant_id,
116
  request.args.get(
 
141
  objs = APIToken.query(token=token)
142
  if not objs:
143
  return get_json_result(
144
+ data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR)
145
  req = request.json
146
  try:
147
  if objs[0].source == "agent":
 
163
  else:
164
  e, dia = DialogService.get_by_id(objs[0].dialog_id)
165
  if not e:
166
+ return get_data_error_result(message="Dialog not found")
167
  conv = {
168
  "id": get_uuid(),
169
  "dialog_id": dia.id,
 
183
  objs = APIToken.query(token=token)
184
  if not objs:
185
  return get_json_result(
186
+ data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR)
187
  req = request.json
188
  e, conv = API4ConversationService.get_by_id(req["conversation_id"])
189
  if not e:
190
+ return get_data_error_result(message="Conversation not found!")
191
  if "quote" not in req: req["quote"] = False
192
 
193
  msg = []
 
257
  ans = {"answer": ans["content"], "reference": ans.get("reference", [])}
258
  fillin_conv(ans)
259
  rename_field(ans)
260
+ yield "data:" + json.dumps({"code": 0, "message": "", "data": ans},
261
  ensure_ascii=False) + "\n\n"
262
 
263
  canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id})
 
267
  cvs.dsl = json.loads(str(canvas))
268
  API4ConversationService.append_message(conv.id, conv.to_dict())
269
  except Exception as e:
270
+ yield "data:" + json.dumps({"code": 500, "message": str(e),
271
  "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
272
  ensure_ascii=False) + "\n\n"
273
+ yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n"
274
 
275
  resp = Response(sse(), mimetype="text/event-stream")
276
  resp.headers.add_header("Cache-control", "no-cache")
 
295
  conv.message.append(msg[-1])
296
  e, dia = DialogService.get_by_id(conv.dialog_id)
297
  if not e:
298
+ return get_data_error_result(message="Dialog not found!")
299
  del req["conversation_id"]
300
  del req["messages"]
301
 
 
310
  for ans in chat(dia, msg, True, **req):
311
  fillin_conv(ans)
312
  rename_field(ans)
313
+ yield "data:" + json.dumps({"code": 0, "message": "", "data": ans},
314
  ensure_ascii=False) + "\n\n"
315
  API4ConversationService.append_message(conv.id, conv.to_dict())
316
  except Exception as e:
317
+ yield "data:" + json.dumps({"code": 500, "message": str(e),
318
  "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
319
  ensure_ascii=False) + "\n\n"
320
+ yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n"
321
 
322
  if req.get("stream", True):
323
  resp = Response(stream(), mimetype="text/event-stream")
 
347
  objs = APIToken.query(token=token)
348
  if not objs:
349
  return get_json_result(
350
+ data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR)
351
 
352
  try:
353
  e, conv = API4ConversationService.get_by_id(conversation_id)
354
  if not e:
355
+ return get_data_error_result(message="Conversation not found!")
356
 
357
  conv = conv.to_dict()
358
  if token != APIToken.query(dialog_id=conv['dialog_id'])[0].token:
359
+ return get_json_result(data=False, message='Token is not valid for this conversation_id!"',
360
+ code=RetCode.AUTHENTICATION_ERROR)
361
 
362
  for referenct_i in conv['reference']:
363
  if referenct_i is None or len(referenct_i) == 0:
 
378
  objs = APIToken.query(token=token)
379
  if not objs:
380
  return get_json_result(
381
+ data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR)
382
 
383
  kb_name = request.form.get("kb_name").strip()
384
  tenant_id = objs[0].tenant_id
 
387
  e, kb = KnowledgebaseService.get_by_name(kb_name, tenant_id)
388
  if not e:
389
  return get_data_error_result(
390
+ message="Can't find this knowledgebase!")
391
  kb_id = kb.id
392
  except Exception as e:
393
  return server_error_response(e)
394
 
395
  if 'file' not in request.files:
396
  return get_json_result(
397
+ data=False, message='No file part!', code=RetCode.ARGUMENT_ERROR)
398
 
399
  file = request.files['file']
400
  if file.filename == '':
401
  return get_json_result(
402
+ data=False, message='No file selected!', code=RetCode.ARGUMENT_ERROR)
403
 
404
  root_folder = FileService.get_root_folder(tenant_id)
405
  pf_id = root_folder["id"]
 
410
  try:
411
  if DocumentService.get_doc_count(kb.tenant_id) >= int(os.environ.get('MAX_FILE_NUM_PER_USER', 8192)):
412
  return get_data_error_result(
413
+ message="Exceed the maximum file number of a free user!")
414
 
415
  filename = duplicate_name(
416
  DocumentService.query,
 
419
  filetype = filename_type(filename)
420
  if not filetype:
421
  return get_data_error_result(
422
+ message="This type of file has not been supported yet!")
423
 
424
  location = filename
425
  while STORAGE_IMPL.obj_exist(kb_id, location):
 
468
  # if str(req["run"]) == TaskStatus.CANCEL.value:
469
  tenant_id = DocumentService.get_tenant_id(doc["id"])
470
  if not tenant_id:
471
+ return get_data_error_result(message="Tenant not found!")
472
 
473
  # e, doc = DocumentService.get_by_id(doc["id"])
474
  TaskService.filter_delete([Task.doc_id == doc["id"]])
 
490
  objs = APIToken.query(token=token)
491
  if not objs:
492
  return get_json_result(
493
+ data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR)
494
 
495
  if 'file' not in request.files:
496
  return get_json_result(
497
+ data=False, message='No file part!', code=RetCode.ARGUMENT_ERROR)
498
 
499
  file_objs = request.files.getlist('file')
500
  for file_obj in file_objs:
501
  if file_obj.filename == '':
502
  return get_json_result(
503
+ data=False, message='No file selected!', code=RetCode.ARGUMENT_ERROR)
504
 
505
  doc_ids = doc_upload_and_parse(request.form.get("conversation_id"), file_objs, objs[0].tenant_id)
506
  return get_json_result(data=doc_ids)
 
513
  objs = APIToken.query(token=token)
514
  if not objs:
515
  return get_json_result(
516
+ data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR)
517
 
518
  req = request.json
519
 
 
527
  doc_id = req['doc_id']
528
  else:
529
  return get_json_result(
530
+ data=False, message="Can't find doc_name or doc_id"
531
  )
532
 
533
  res = retrievaler.chunk_list(doc_id=doc_id, tenant_id=tenant_id)
 
552
  objs = APIToken.query(token=token)
553
  if not objs:
554
  return get_json_result(
555
+ data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR)
556
 
557
  req = request.json
558
  tenant_id = objs[0].tenant_id
 
562
  e, kb = KnowledgebaseService.get_by_name(kb_name, tenant_id)
563
  if not e:
564
  return get_data_error_result(
565
+ message="Can't find this knowledgebase!")
566
  kb_id = kb.id
567
 
568
  except Exception as e:
 
591
  objs = APIToken.query(token=token)
592
  if not objs:
593
  return get_json_result(
594
+ data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR)
595
  req = request.json
596
  doc_ids = req["doc_ids"]
597
  docs = DocumentService.get_by_ids(doc_ids)
 
605
  objs = APIToken.query(token=token)
606
  if not objs:
607
  return get_json_result(
608
+ data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR)
609
 
610
  tenant_id = objs[0].tenant_id
611
  req = request.json
 
617
 
618
  if not doc_ids:
619
  return get_json_result(
620
+ data=False, message="Can't find doc_names or doc_ids"
621
  )
622
 
623
  except Exception as e:
 
632
  try:
633
  e, doc = DocumentService.get_by_id(doc_id)
634
  if not e:
635
+ return get_data_error_result(message="Document not found!")
636
  tenant_id = DocumentService.get_tenant_id(doc_id)
637
  if not tenant_id:
638
+ return get_data_error_result(message="Tenant not found!")
639
 
640
  b, n = File2DocumentService.get_storage_address(doc_id=doc_id)
641
 
642
  if not DocumentService.remove_document(doc, tenant_id):
643
  return get_data_error_result(
644
+ message="Database error (Document removal)!")
645
 
646
  f2d = File2DocumentService.get_by_document_id(doc_id)
647
  FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id])
 
652
  errors += str(e)
653
 
654
  if errors:
655
+ return get_json_result(data=False, message=errors, code=RetCode.SERVER_ERROR)
656
 
657
  return get_json_result(data=True)
658
 
 
667
  objs = APIToken.query(token=token)
668
  if not objs:
669
  return get_json_result(
670
+ data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR)
671
 
672
  e, conv = API4ConversationService.get_by_id(req["conversation_id"])
673
  if not e:
674
+ return get_data_error_result(message="Conversation not found!")
675
  if "quote" not in req: req["quote"] = True
676
 
677
  msg = []
 
752
  conv.message.append(msg[-1])
753
  e, dia = DialogService.get_by_id(conv.dialog_id)
754
  if not e:
755
+ return get_data_error_result(message="Dialog not found!")
756
  del req["conversation_id"]
757
 
758
  if not conv.reference:
 
804
  objs = APIToken.query(token=token)
805
  if not objs:
806
  return get_json_result(
807
+ data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR)
808
 
809
  req = request.json
810
  kb_ids = req.get("kb_id",[])
 
821
  embd_nms = list(set([kb.embd_id for kb in kbs]))
822
  if len(embd_nms) != 1:
823
  return get_json_result(
824
+ data=False, message='Knowledge bases use different embedding models or does not exist."', code=RetCode.AUTHENTICATION_ERROR)
825
 
826
  embd_mdl = TenantLLMService.model_instance(
827
  kbs[0].tenant_id, LLMType.EMBEDDING.value, llm_name=kbs[0].embd_id)
 
841
  return get_json_result(data=ranks)
842
  except Exception as e:
843
  if str(e).find("not_found") > 0:
844
+ return get_json_result(data=False, message='No chunk found! Check the chunk status please!',
845
+ code=RetCode.DATA_ERROR)
846
  return server_error_response(e)
api/apps/canvas_app.py CHANGED
@@ -46,8 +46,8 @@ def rm():
46
  for i in request.json["canvas_ids"]:
47
  if not UserCanvasService.query(user_id=current_user.id,id=i):
48
  return get_json_result(
49
- data=False, retmsg=f'Only owner of canvas authorized for this operation.',
50
- retcode=RetCode.OPERATING_ERROR)
51
  UserCanvasService.delete_by_id(i)
52
  return get_json_result(data=True)
53
 
@@ -66,12 +66,12 @@ def save():
66
  return server_error_response(ValueError("Duplicated title."))
67
  req["id"] = get_uuid()
68
  if not UserCanvasService.save(**req):
69
- return get_data_error_result(retmsg="Fail to save canvas.")
70
  else:
71
  if not UserCanvasService.query(user_id=current_user.id, id=req["id"]):
72
  return get_json_result(
73
- data=False, retmsg=f'Only owner of canvas authorized for this operation.',
74
- retcode=RetCode.OPERATING_ERROR)
75
  UserCanvasService.update_by_id(req["id"], req)
76
  return get_json_result(data=req)
77
 
@@ -81,7 +81,7 @@ def save():
81
  def get(canvas_id):
82
  e, c = UserCanvasService.get_by_id(canvas_id)
83
  if not e:
84
- return get_data_error_result(retmsg="canvas not found.")
85
  return get_json_result(data=c.to_dict())
86
 
87
 
@@ -93,11 +93,11 @@ def run():
93
  stream = req.get("stream", True)
94
  e, cvs = UserCanvasService.get_by_id(req["id"])
95
  if not e:
96
- return get_data_error_result(retmsg="canvas not found.")
97
  if not UserCanvasService.query(user_id=current_user.id, id=req["id"]):
98
  return get_json_result(
99
- data=False, retmsg=f'Only owner of canvas authorized for this operation.',
100
- retcode=RetCode.OPERATING_ERROR)
101
 
102
  if not isinstance(cvs.dsl, str):
103
  cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False)
@@ -130,7 +130,7 @@ def run():
130
  for k in ans.keys():
131
  final_ans[k] = ans[k]
132
  ans = {"answer": ans["content"], "reference": ans.get("reference", [])}
133
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans}, ensure_ascii=False) + "\n\n"
134
 
135
  canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id})
136
  canvas.history.append(("assistant", final_ans["content"]))
@@ -139,10 +139,10 @@ def run():
139
  cvs.dsl = json.loads(str(canvas))
140
  UserCanvasService.update_by_id(req["id"], cvs.to_dict())
141
  except Exception as e:
142
- yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e),
143
  "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
144
  ensure_ascii=False) + "\n\n"
145
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n"
146
 
147
  resp = Response(sse(), mimetype="text/event-stream")
148
  resp.headers.add_header("Cache-control", "no-cache")
@@ -168,11 +168,11 @@ def reset():
168
  try:
169
  e, user_canvas = UserCanvasService.get_by_id(req["id"])
170
  if not e:
171
- return get_data_error_result(retmsg="canvas not found.")
172
  if not UserCanvasService.query(user_id=current_user.id, id=req["id"]):
173
  return get_json_result(
174
- data=False, retmsg=f'Only owner of canvas authorized for this operation.',
175
- retcode=RetCode.OPERATING_ERROR)
176
 
177
  canvas = Canvas(json.dumps(user_canvas.dsl), current_user.id)
178
  canvas.reset()
 
46
  for i in request.json["canvas_ids"]:
47
  if not UserCanvasService.query(user_id=current_user.id,id=i):
48
  return get_json_result(
49
+ data=False, message='Only owner of canvas authorized for this operation.',
50
+ code=RetCode.OPERATING_ERROR)
51
  UserCanvasService.delete_by_id(i)
52
  return get_json_result(data=True)
53
 
 
66
  return server_error_response(ValueError("Duplicated title."))
67
  req["id"] = get_uuid()
68
  if not UserCanvasService.save(**req):
69
+ return get_data_error_result(message="Fail to save canvas.")
70
  else:
71
  if not UserCanvasService.query(user_id=current_user.id, id=req["id"]):
72
  return get_json_result(
73
+ data=False, message='Only owner of canvas authorized for this operation.',
74
+ code=RetCode.OPERATING_ERROR)
75
  UserCanvasService.update_by_id(req["id"], req)
76
  return get_json_result(data=req)
77
 
 
81
  def get(canvas_id):
82
  e, c = UserCanvasService.get_by_id(canvas_id)
83
  if not e:
84
+ return get_data_error_result(message="canvas not found.")
85
  return get_json_result(data=c.to_dict())
86
 
87
 
 
93
  stream = req.get("stream", True)
94
  e, cvs = UserCanvasService.get_by_id(req["id"])
95
  if not e:
96
+ return get_data_error_result(message="canvas not found.")
97
  if not UserCanvasService.query(user_id=current_user.id, id=req["id"]):
98
  return get_json_result(
99
+ data=False, message='Only owner of canvas authorized for this operation.',
100
+ code=RetCode.OPERATING_ERROR)
101
 
102
  if not isinstance(cvs.dsl, str):
103
  cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False)
 
130
  for k in ans.keys():
131
  final_ans[k] = ans[k]
132
  ans = {"answer": ans["content"], "reference": ans.get("reference", [])}
133
+ yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, ensure_ascii=False) + "\n\n"
134
 
135
  canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id})
136
  canvas.history.append(("assistant", final_ans["content"]))
 
139
  cvs.dsl = json.loads(str(canvas))
140
  UserCanvasService.update_by_id(req["id"], cvs.to_dict())
141
  except Exception as e:
142
+ yield "data:" + json.dumps({"code": 500, "message": str(e),
143
  "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
144
  ensure_ascii=False) + "\n\n"
145
+ yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n"
146
 
147
  resp = Response(sse(), mimetype="text/event-stream")
148
  resp.headers.add_header("Cache-control", "no-cache")
 
168
  try:
169
  e, user_canvas = UserCanvasService.get_by_id(req["id"])
170
  if not e:
171
+ return get_data_error_result(message="canvas not found.")
172
  if not UserCanvasService.query(user_id=current_user.id, id=req["id"]):
173
  return get_json_result(
174
+ data=False, message='Only owner of canvas authorized for this operation.',
175
+ code=RetCode.OPERATING_ERROR)
176
 
177
  canvas = Canvas(json.dumps(user_canvas.dsl), current_user.id)
178
  canvas.reset()
api/apps/chunk_app.py CHANGED
@@ -15,7 +15,6 @@
15
  #
16
  import datetime
17
  import json
18
- import traceback
19
 
20
  from flask import request
21
  from flask_login import login_required, current_user
@@ -50,10 +49,10 @@ def list_chunk():
50
  try:
51
  tenant_id = DocumentService.get_tenant_id(req["doc_id"])
52
  if not tenant_id:
53
- return get_data_error_result(retmsg="Tenant not found!")
54
  e, doc = DocumentService.get_by_id(doc_id)
55
  if not e:
56
- return get_data_error_result(retmsg="Document not found!")
57
  query = {
58
  "doc_ids": [doc_id], "page": page, "size": size, "question": question, "sort": True
59
  }
@@ -84,8 +83,8 @@ def list_chunk():
84
  return get_json_result(data=res)
85
  except Exception as e:
86
  if str(e).find("not_found") > 0:
87
- return get_json_result(data=False, retmsg=f'No chunk found!',
88
- retcode=RetCode.DATA_ERROR)
89
  return server_error_response(e)
90
 
91
 
@@ -96,7 +95,7 @@ def get():
96
  try:
97
  tenants = UserTenantService.query(user_id=current_user.id)
98
  if not tenants:
99
- return get_data_error_result(retmsg="Tenant not found!")
100
  res = ELASTICSEARCH.get(
101
  chunk_id, search.index_name(
102
  tenants[0].tenant_id))
@@ -115,8 +114,8 @@ def get():
115
  return get_json_result(data=res)
116
  except Exception as e:
117
  if str(e).find("NotFoundError") >= 0:
118
- return get_json_result(data=False, retmsg=f'Chunk not found!',
119
- retcode=RetCode.DATA_ERROR)
120
  return server_error_response(e)
121
 
122
 
@@ -139,14 +138,14 @@ def set():
139
  try:
140
  tenant_id = DocumentService.get_tenant_id(req["doc_id"])
141
  if not tenant_id:
142
- return get_data_error_result(retmsg="Tenant not found!")
143
 
144
  embd_id = DocumentService.get_embd_id(req["doc_id"])
145
  embd_mdl = LLMBundle(tenant_id, LLMType.EMBEDDING, embd_id)
146
 
147
  e, doc = DocumentService.get_by_id(req["doc_id"])
148
  if not e:
149
- return get_data_error_result(retmsg="Document not found!")
150
 
151
  if doc.parser_id == ParserType.QA:
152
  arr = [
@@ -155,7 +154,7 @@ def set():
155
  req["content_with_weight"]) if len(t) > 1]
156
  if len(arr) != 2:
157
  return get_data_error_result(
158
- retmsg="Q&A must be separated by TAB/ENTER key.")
159
  q, a = rmPrefix(arr[0]), rmPrefix(arr[1])
160
  d = beAdoc(d, arr[0], arr[1], not any(
161
  [rag_tokenizer.is_chinese(t) for t in q + a]))
@@ -177,10 +176,10 @@ def switch():
177
  try:
178
  tenant_id = DocumentService.get_tenant_id(req["doc_id"])
179
  if not tenant_id:
180
- return get_data_error_result(retmsg="Tenant not found!")
181
  if not ELASTICSEARCH.upsert([{"id": i, "available_int": int(req["available_int"])} for i in req["chunk_ids"]],
182
  search.index_name(tenant_id)):
183
- return get_data_error_result(retmsg="Index updating failure")
184
  return get_json_result(data=True)
185
  except Exception as e:
186
  return server_error_response(e)
@@ -194,10 +193,10 @@ def rm():
194
  try:
195
  if not ELASTICSEARCH.deleteByQuery(
196
  Q("ids", values=req["chunk_ids"]), search.index_name(current_user.id)):
197
- return get_data_error_result(retmsg="Index updating failure")
198
  e, doc = DocumentService.get_by_id(req["doc_id"])
199
  if not e:
200
- return get_data_error_result(retmsg="Document not found!")
201
  deleted_chunk_ids = req["chunk_ids"]
202
  chunk_number = len(deleted_chunk_ids)
203
  DocumentService.decrement_chunk_num(doc.id, doc.kb_id, 1, chunk_number, 0)
@@ -225,14 +224,14 @@ def create():
225
  try:
226
  e, doc = DocumentService.get_by_id(req["doc_id"])
227
  if not e:
228
- return get_data_error_result(retmsg="Document not found!")
229
  d["kb_id"] = [doc.kb_id]
230
  d["docnm_kwd"] = doc.name
231
  d["doc_id"] = doc.id
232
 
233
  tenant_id = DocumentService.get_tenant_id(req["doc_id"])
234
  if not tenant_id:
235
- return get_data_error_result(retmsg="Tenant not found!")
236
 
237
  embd_id = DocumentService.get_embd_id(req["doc_id"])
238
  embd_mdl = LLMBundle(tenant_id, LLMType.EMBEDDING.value, embd_id)
@@ -273,12 +272,12 @@ def retrieval_test():
273
  break
274
  else:
275
  return get_json_result(
276
- data=False, retmsg=f'Only owner of knowledgebase authorized for this operation.',
277
- retcode=RetCode.OPERATING_ERROR)
278
 
279
  e, kb = KnowledgebaseService.get_by_id(kb_id[0])
280
  if not e:
281
- return get_data_error_result(retmsg="Knowledgebase not found!")
282
 
283
  embd_mdl = LLMBundle(kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id)
284
 
@@ -301,8 +300,8 @@ def retrieval_test():
301
  return get_json_result(data=ranks)
302
  except Exception as e:
303
  if str(e).find("not_found") > 0:
304
- return get_json_result(data=False, retmsg=f'No chunk found! Check the chunk status please!',
305
- retcode=RetCode.DATA_ERROR)
306
  return server_error_response(e)
307
 
308
 
@@ -321,7 +320,7 @@ def knowledge_graph():
321
  ty = sres.field[id]["knowledge_graph_kwd"]
322
  try:
323
  content_json = json.loads(sres.field[id]["content_with_weight"])
324
- except Exception as e:
325
  continue
326
 
327
  if ty == 'mind_map':
 
15
  #
16
  import datetime
17
  import json
 
18
 
19
  from flask import request
20
  from flask_login import login_required, current_user
 
49
  try:
50
  tenant_id = DocumentService.get_tenant_id(req["doc_id"])
51
  if not tenant_id:
52
+ return get_data_error_result(message="Tenant not found!")
53
  e, doc = DocumentService.get_by_id(doc_id)
54
  if not e:
55
+ return get_data_error_result(message="Document not found!")
56
  query = {
57
  "doc_ids": [doc_id], "page": page, "size": size, "question": question, "sort": True
58
  }
 
83
  return get_json_result(data=res)
84
  except Exception as e:
85
  if str(e).find("not_found") > 0:
86
+ return get_json_result(data=False, message='No chunk found!',
87
+ code=RetCode.DATA_ERROR)
88
  return server_error_response(e)
89
 
90
 
 
95
  try:
96
  tenants = UserTenantService.query(user_id=current_user.id)
97
  if not tenants:
98
+ return get_data_error_result(message="Tenant not found!")
99
  res = ELASTICSEARCH.get(
100
  chunk_id, search.index_name(
101
  tenants[0].tenant_id))
 
114
  return get_json_result(data=res)
115
  except Exception as e:
116
  if str(e).find("NotFoundError") >= 0:
117
+ return get_json_result(data=False, message='Chunk not found!',
118
+ code=RetCode.DATA_ERROR)
119
  return server_error_response(e)
120
 
121
 
 
138
  try:
139
  tenant_id = DocumentService.get_tenant_id(req["doc_id"])
140
  if not tenant_id:
141
+ return get_data_error_result(message="Tenant not found!")
142
 
143
  embd_id = DocumentService.get_embd_id(req["doc_id"])
144
  embd_mdl = LLMBundle(tenant_id, LLMType.EMBEDDING, embd_id)
145
 
146
  e, doc = DocumentService.get_by_id(req["doc_id"])
147
  if not e:
148
+ return get_data_error_result(message="Document not found!")
149
 
150
  if doc.parser_id == ParserType.QA:
151
  arr = [
 
154
  req["content_with_weight"]) if len(t) > 1]
155
  if len(arr) != 2:
156
  return get_data_error_result(
157
+ message="Q&A must be separated by TAB/ENTER key.")
158
  q, a = rmPrefix(arr[0]), rmPrefix(arr[1])
159
  d = beAdoc(d, arr[0], arr[1], not any(
160
  [rag_tokenizer.is_chinese(t) for t in q + a]))
 
176
  try:
177
  tenant_id = DocumentService.get_tenant_id(req["doc_id"])
178
  if not tenant_id:
179
+ return get_data_error_result(message="Tenant not found!")
180
  if not ELASTICSEARCH.upsert([{"id": i, "available_int": int(req["available_int"])} for i in req["chunk_ids"]],
181
  search.index_name(tenant_id)):
182
+ return get_data_error_result(message="Index updating failure")
183
  return get_json_result(data=True)
184
  except Exception as e:
185
  return server_error_response(e)
 
193
  try:
194
  if not ELASTICSEARCH.deleteByQuery(
195
  Q("ids", values=req["chunk_ids"]), search.index_name(current_user.id)):
196
+ return get_data_error_result(message="Index updating failure")
197
  e, doc = DocumentService.get_by_id(req["doc_id"])
198
  if not e:
199
+ return get_data_error_result(message="Document not found!")
200
  deleted_chunk_ids = req["chunk_ids"]
201
  chunk_number = len(deleted_chunk_ids)
202
  DocumentService.decrement_chunk_num(doc.id, doc.kb_id, 1, chunk_number, 0)
 
224
  try:
225
  e, doc = DocumentService.get_by_id(req["doc_id"])
226
  if not e:
227
+ return get_data_error_result(message="Document not found!")
228
  d["kb_id"] = [doc.kb_id]
229
  d["docnm_kwd"] = doc.name
230
  d["doc_id"] = doc.id
231
 
232
  tenant_id = DocumentService.get_tenant_id(req["doc_id"])
233
  if not tenant_id:
234
+ return get_data_error_result(message="Tenant not found!")
235
 
236
  embd_id = DocumentService.get_embd_id(req["doc_id"])
237
  embd_mdl = LLMBundle(tenant_id, LLMType.EMBEDDING.value, embd_id)
 
272
  break
273
  else:
274
  return get_json_result(
275
+ data=False, message='Only owner of knowledgebase authorized for this operation.',
276
+ code=RetCode.OPERATING_ERROR)
277
 
278
  e, kb = KnowledgebaseService.get_by_id(kb_id[0])
279
  if not e:
280
+ return get_data_error_result(message="Knowledgebase not found!")
281
 
282
  embd_mdl = LLMBundle(kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id)
283
 
 
300
  return get_json_result(data=ranks)
301
  except Exception as e:
302
  if str(e).find("not_found") > 0:
303
+ return get_json_result(data=False, message='No chunk found! Check the chunk status please!',
304
+ code=RetCode.DATA_ERROR)
305
  return server_error_response(e)
306
 
307
 
 
320
  ty = sres.field[id]["knowledge_graph_kwd"]
321
  try:
322
  content_json = json.loads(sres.field[id]["content_with_weight"])
323
+ except Exception:
324
  continue
325
 
326
  if ty == 'mind_map':
api/apps/conversation_app.py CHANGED
@@ -42,11 +42,11 @@ def set_conversation():
42
  del req["conversation_id"]
43
  try:
44
  if not ConversationService.update_by_id(conv_id, req):
45
- return get_data_error_result(retmsg="Conversation not found!")
46
  e, conv = ConversationService.get_by_id(conv_id)
47
  if not e:
48
  return get_data_error_result(
49
- retmsg="Fail to update a conversation!")
50
  conv = conv.to_dict()
51
  return get_json_result(data=conv)
52
  except Exception as e:
@@ -55,7 +55,7 @@ def set_conversation():
55
  try:
56
  e, dia = DialogService.get_by_id(req["dialog_id"])
57
  if not e:
58
- return get_data_error_result(retmsg="Dialog not found")
59
  conv = {
60
  "id": conv_id,
61
  "dialog_id": req["dialog_id"],
@@ -65,7 +65,7 @@ def set_conversation():
65
  ConversationService.save(**conv)
66
  e, conv = ConversationService.get_by_id(conv["id"])
67
  if not e:
68
- return get_data_error_result(retmsg="Fail to new a conversation!")
69
  conv = conv.to_dict()
70
  return get_json_result(data=conv)
71
  except Exception as e:
@@ -79,15 +79,15 @@ def get():
79
  try:
80
  e, conv = ConversationService.get_by_id(conv_id)
81
  if not e:
82
- return get_data_error_result(retmsg="Conversation not found!")
83
  tenants = UserTenantService.query(user_id=current_user.id)
84
  for tenant in tenants:
85
  if DialogService.query(tenant_id=tenant.tenant_id, id=conv.dialog_id):
86
  break
87
  else:
88
  return get_json_result(
89
- data=False, retmsg=f'Only owner of conversation authorized for this operation.',
90
- retcode=RetCode.OPERATING_ERROR)
91
  conv = conv.to_dict()
92
  return get_json_result(data=conv)
93
  except Exception as e:
@@ -102,15 +102,15 @@ def rm():
102
  for cid in conv_ids:
103
  exist, conv = ConversationService.get_by_id(cid)
104
  if not exist:
105
- return get_data_error_result(retmsg="Conversation not found!")
106
  tenants = UserTenantService.query(user_id=current_user.id)
107
  for tenant in tenants:
108
  if DialogService.query(tenant_id=tenant.tenant_id, id=conv.dialog_id):
109
  break
110
  else:
111
  return get_json_result(
112
- data=False, retmsg=f'Only owner of conversation authorized for this operation.',
113
- retcode=RetCode.OPERATING_ERROR)
114
  ConversationService.delete_by_id(cid)
115
  return get_json_result(data=True)
116
  except Exception as e:
@@ -124,8 +124,8 @@ def list_convsersation():
124
  try:
125
  if not DialogService.query(tenant_id=current_user.id, id=dialog_id):
126
  return get_json_result(
127
- data=False, retmsg=f'Only owner of dialog authorized for this operation.',
128
- retcode=RetCode.OPERATING_ERROR)
129
  convs = ConversationService.query(
130
  dialog_id=dialog_id,
131
  order_by=ConversationService.model.create_time,
@@ -152,11 +152,11 @@ def completion():
152
  try:
153
  e, conv = ConversationService.get_by_id(req["conversation_id"])
154
  if not e:
155
- return get_data_error_result(retmsg="Conversation not found!")
156
  conv.message = deepcopy(req["messages"])
157
  e, dia = DialogService.get_by_id(conv.dialog_id)
158
  if not e:
159
- return get_data_error_result(retmsg="Dialog not found!")
160
  del req["conversation_id"]
161
  del req["messages"]
162
 
@@ -180,14 +180,14 @@ def completion():
180
  try:
181
  for ans in chat(dia, msg, True, **req):
182
  fillin_conv(ans)
183
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans}, ensure_ascii=False) + "\n\n"
184
  ConversationService.update_by_id(conv.id, conv.to_dict())
185
  except Exception as e:
186
  traceback.print_exc()
187
- yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e),
188
  "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
189
  ensure_ascii=False) + "\n\n"
190
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n"
191
 
192
  if req.get("stream", True):
193
  resp = Response(stream(), mimetype="text/event-stream")
@@ -217,11 +217,11 @@ def tts():
217
 
218
  tenants = TenantService.get_info_by(current_user.id)
219
  if not tenants:
220
- return get_data_error_result(retmsg="Tenant not found!")
221
 
222
  tts_id = tenants[0]["tts_id"]
223
  if not tts_id:
224
- return get_data_error_result(retmsg="No default TTS model is set")
225
 
226
  tts_mdl = LLMBundle(tenants[0]["tenant_id"], LLMType.TTS, tts_id)
227
 
@@ -231,7 +231,7 @@ def tts():
231
  for chunk in tts_mdl.tts(txt):
232
  yield chunk
233
  except Exception as e:
234
- yield ("data:" + json.dumps({"retcode": 500, "retmsg": str(e),
235
  "data": {"answer": "**ERROR**: " + str(e)}},
236
  ensure_ascii=False)).encode('utf-8')
237
 
@@ -250,7 +250,7 @@ def delete_msg():
250
  req = request.json
251
  e, conv = ConversationService.get_by_id(req["conversation_id"])
252
  if not e:
253
- return get_data_error_result(retmsg="Conversation not found!")
254
 
255
  conv = conv.to_dict()
256
  for i, msg in enumerate(conv["message"]):
@@ -273,7 +273,7 @@ def thumbup():
273
  req = request.json
274
  e, conv = ConversationService.get_by_id(req["conversation_id"])
275
  if not e:
276
- return get_data_error_result(retmsg="Conversation not found!")
277
  up_down = req.get("set")
278
  feedback = req.get("feedback", "")
279
  conv = conv.to_dict()
@@ -301,12 +301,12 @@ def ask_about():
301
  nonlocal req, uid
302
  try:
303
  for ans in ask(req["question"], req["kb_ids"], uid):
304
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans}, ensure_ascii=False) + "\n\n"
305
  except Exception as e:
306
- yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e),
307
  "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
308
  ensure_ascii=False) + "\n\n"
309
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n"
310
 
311
  resp = Response(stream(), mimetype="text/event-stream")
312
  resp.headers.add_header("Cache-control", "no-cache")
@@ -324,7 +324,7 @@ def mindmap():
324
  kb_ids = req["kb_ids"]
325
  e, kb = KnowledgebaseService.get_by_id(kb_ids[0])
326
  if not e:
327
- return get_data_error_result(retmsg="Knowledgebase not found!")
328
 
329
  embd_mdl = TenantLLMService.model_instance(
330
  kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id)
 
42
  del req["conversation_id"]
43
  try:
44
  if not ConversationService.update_by_id(conv_id, req):
45
+ return get_data_error_result(message="Conversation not found!")
46
  e, conv = ConversationService.get_by_id(conv_id)
47
  if not e:
48
  return get_data_error_result(
49
+ message="Fail to update a conversation!")
50
  conv = conv.to_dict()
51
  return get_json_result(data=conv)
52
  except Exception as e:
 
55
  try:
56
  e, dia = DialogService.get_by_id(req["dialog_id"])
57
  if not e:
58
+ return get_data_error_result(message="Dialog not found")
59
  conv = {
60
  "id": conv_id,
61
  "dialog_id": req["dialog_id"],
 
65
  ConversationService.save(**conv)
66
  e, conv = ConversationService.get_by_id(conv["id"])
67
  if not e:
68
+ return get_data_error_result(message="Fail to new a conversation!")
69
  conv = conv.to_dict()
70
  return get_json_result(data=conv)
71
  except Exception as e:
 
79
  try:
80
  e, conv = ConversationService.get_by_id(conv_id)
81
  if not e:
82
+ return get_data_error_result(message="Conversation not found!")
83
  tenants = UserTenantService.query(user_id=current_user.id)
84
  for tenant in tenants:
85
  if DialogService.query(tenant_id=tenant.tenant_id, id=conv.dialog_id):
86
  break
87
  else:
88
  return get_json_result(
89
+ data=False, message='Only owner of conversation authorized for this operation.',
90
+ code=RetCode.OPERATING_ERROR)
91
  conv = conv.to_dict()
92
  return get_json_result(data=conv)
93
  except Exception as e:
 
102
  for cid in conv_ids:
103
  exist, conv = ConversationService.get_by_id(cid)
104
  if not exist:
105
+ return get_data_error_result(message="Conversation not found!")
106
  tenants = UserTenantService.query(user_id=current_user.id)
107
  for tenant in tenants:
108
  if DialogService.query(tenant_id=tenant.tenant_id, id=conv.dialog_id):
109
  break
110
  else:
111
  return get_json_result(
112
+ data=False, message='Only owner of conversation authorized for this operation.',
113
+ code=RetCode.OPERATING_ERROR)
114
  ConversationService.delete_by_id(cid)
115
  return get_json_result(data=True)
116
  except Exception as e:
 
124
  try:
125
  if not DialogService.query(tenant_id=current_user.id, id=dialog_id):
126
  return get_json_result(
127
+ data=False, message='Only owner of dialog authorized for this operation.',
128
+ code=RetCode.OPERATING_ERROR)
129
  convs = ConversationService.query(
130
  dialog_id=dialog_id,
131
  order_by=ConversationService.model.create_time,
 
152
  try:
153
  e, conv = ConversationService.get_by_id(req["conversation_id"])
154
  if not e:
155
+ return get_data_error_result(message="Conversation not found!")
156
  conv.message = deepcopy(req["messages"])
157
  e, dia = DialogService.get_by_id(conv.dialog_id)
158
  if not e:
159
+ return get_data_error_result(message="Dialog not found!")
160
  del req["conversation_id"]
161
  del req["messages"]
162
 
 
180
  try:
181
  for ans in chat(dia, msg, True, **req):
182
  fillin_conv(ans)
183
+ yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, ensure_ascii=False) + "\n\n"
184
  ConversationService.update_by_id(conv.id, conv.to_dict())
185
  except Exception as e:
186
  traceback.print_exc()
187
+ yield "data:" + json.dumps({"code": 500, "message": str(e),
188
  "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
189
  ensure_ascii=False) + "\n\n"
190
+ yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n"
191
 
192
  if req.get("stream", True):
193
  resp = Response(stream(), mimetype="text/event-stream")
 
217
 
218
  tenants = TenantService.get_info_by(current_user.id)
219
  if not tenants:
220
+ return get_data_error_result(message="Tenant not found!")
221
 
222
  tts_id = tenants[0]["tts_id"]
223
  if not tts_id:
224
+ return get_data_error_result(message="No default TTS model is set")
225
 
226
  tts_mdl = LLMBundle(tenants[0]["tenant_id"], LLMType.TTS, tts_id)
227
 
 
231
  for chunk in tts_mdl.tts(txt):
232
  yield chunk
233
  except Exception as e:
234
+ yield ("data:" + json.dumps({"code": 500, "message": str(e),
235
  "data": {"answer": "**ERROR**: " + str(e)}},
236
  ensure_ascii=False)).encode('utf-8')
237
 
 
250
  req = request.json
251
  e, conv = ConversationService.get_by_id(req["conversation_id"])
252
  if not e:
253
+ return get_data_error_result(message="Conversation not found!")
254
 
255
  conv = conv.to_dict()
256
  for i, msg in enumerate(conv["message"]):
 
273
  req = request.json
274
  e, conv = ConversationService.get_by_id(req["conversation_id"])
275
  if not e:
276
+ return get_data_error_result(message="Conversation not found!")
277
  up_down = req.get("set")
278
  feedback = req.get("feedback", "")
279
  conv = conv.to_dict()
 
301
  nonlocal req, uid
302
  try:
303
  for ans in ask(req["question"], req["kb_ids"], uid):
304
+ yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, ensure_ascii=False) + "\n\n"
305
  except Exception as e:
306
+ yield "data:" + json.dumps({"code": 500, "message": str(e),
307
  "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
308
  ensure_ascii=False) + "\n\n"
309
+ yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n"
310
 
311
  resp = Response(stream(), mimetype="text/event-stream")
312
  resp.headers.add_header("Cache-control", "no-cache")
 
324
  kb_ids = req["kb_ids"]
325
  e, kb = KnowledgebaseService.get_by_id(kb_ids[0])
326
  if not e:
327
+ return get_data_error_result(message="Knowledgebase not found!")
328
 
329
  embd_mdl = TenantLLMService.model_instance(
330
  kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id)
api/apps/dialog_app.py CHANGED
@@ -68,17 +68,17 @@ def set_dialog():
68
  continue
69
  if prompt_config["system"].find("{%s}" % p["key"]) < 0:
70
  return get_data_error_result(
71
- retmsg="Parameter '{}' is not used".format(p["key"]))
72
 
73
  try:
74
  e, tenant = TenantService.get_by_id(current_user.id)
75
  if not e:
76
- return get_data_error_result(retmsg="Tenant not found!")
77
  llm_id = req.get("llm_id", tenant.llm_id)
78
  if not dialog_id:
79
  if not req.get("kb_ids"):
80
  return get_data_error_result(
81
- retmsg="Fail! Please select knowledgebase!")
82
  dia = {
83
  "id": get_uuid(),
84
  "tenant_id": current_user.id,
@@ -96,20 +96,20 @@ def set_dialog():
96
  "icon": icon
97
  }
98
  if not DialogService.save(**dia):
99
- return get_data_error_result(retmsg="Fail to new a dialog!")
100
  e, dia = DialogService.get_by_id(dia["id"])
101
  if not e:
102
- return get_data_error_result(retmsg="Fail to new a dialog!")
103
  return get_json_result(data=dia.to_json())
104
  else:
105
  del req["dialog_id"]
106
  if "kb_names" in req:
107
  del req["kb_names"]
108
  if not DialogService.update_by_id(dialog_id, req):
109
- return get_data_error_result(retmsg="Dialog not found!")
110
  e, dia = DialogService.get_by_id(dialog_id)
111
  if not e:
112
- return get_data_error_result(retmsg="Fail to update a dialog!")
113
  dia = dia.to_dict()
114
  dia["kb_ids"], dia["kb_names"] = get_kb_names(dia["kb_ids"])
115
  return get_json_result(data=dia)
@@ -124,7 +124,7 @@ def get():
124
  try:
125
  e, dia = DialogService.get_by_id(dialog_id)
126
  if not e:
127
- return get_data_error_result(retmsg="Dialog not found!")
128
  dia = dia.to_dict()
129
  dia["kb_ids"], dia["kb_names"] = get_kb_names(dia["kb_ids"])
130
  return get_json_result(data=dia)
@@ -174,8 +174,8 @@ def rm():
174
  break
175
  else:
176
  return get_json_result(
177
- data=False, retmsg=f'Only owner of dialog authorized for this operation.',
178
- retcode=RetCode.OPERATING_ERROR)
179
  dialog_list.append({"id": id,"status":StatusEnum.INVALID.value})
180
  DialogService.update_many_by_id(dialog_list)
181
  return get_json_result(data=True)
 
68
  continue
69
  if prompt_config["system"].find("{%s}" % p["key"]) < 0:
70
  return get_data_error_result(
71
+ message="Parameter '{}' is not used".format(p["key"]))
72
 
73
  try:
74
  e, tenant = TenantService.get_by_id(current_user.id)
75
  if not e:
76
+ return get_data_error_result(message="Tenant not found!")
77
  llm_id = req.get("llm_id", tenant.llm_id)
78
  if not dialog_id:
79
  if not req.get("kb_ids"):
80
  return get_data_error_result(
81
+ message="Fail! Please select knowledgebase!")
82
  dia = {
83
  "id": get_uuid(),
84
  "tenant_id": current_user.id,
 
96
  "icon": icon
97
  }
98
  if not DialogService.save(**dia):
99
+ return get_data_error_result(message="Fail to new a dialog!")
100
  e, dia = DialogService.get_by_id(dia["id"])
101
  if not e:
102
+ return get_data_error_result(message="Fail to new a dialog!")
103
  return get_json_result(data=dia.to_json())
104
  else:
105
  del req["dialog_id"]
106
  if "kb_names" in req:
107
  del req["kb_names"]
108
  if not DialogService.update_by_id(dialog_id, req):
109
+ return get_data_error_result(message="Dialog not found!")
110
  e, dia = DialogService.get_by_id(dialog_id)
111
  if not e:
112
+ return get_data_error_result(message="Fail to update a dialog!")
113
  dia = dia.to_dict()
114
  dia["kb_ids"], dia["kb_names"] = get_kb_names(dia["kb_ids"])
115
  return get_json_result(data=dia)
 
124
  try:
125
  e, dia = DialogService.get_by_id(dialog_id)
126
  if not e:
127
+ return get_data_error_result(message="Dialog not found!")
128
  dia = dia.to_dict()
129
  dia["kb_ids"], dia["kb_names"] = get_kb_names(dia["kb_ids"])
130
  return get_json_result(data=dia)
 
174
  break
175
  else:
176
  return get_json_result(
177
+ data=False, message='Only owner of dialog authorized for this operation.',
178
+ code=RetCode.OPERATING_ERROR)
179
  dialog_list.append({"id": id,"status":StatusEnum.INVALID.value})
180
  DialogService.update_many_by_id(dialog_list)
181
  return get_json_result(data=True)
api/apps/document_app.py CHANGED
@@ -49,16 +49,16 @@ def upload():
49
  kb_id = request.form.get("kb_id")
50
  if not kb_id:
51
  return get_json_result(
52
- data=False, retmsg='Lack of "KB ID"', retcode=RetCode.ARGUMENT_ERROR)
53
  if 'file' not in request.files:
54
  return get_json_result(
55
- data=False, retmsg='No file part!', retcode=RetCode.ARGUMENT_ERROR)
56
 
57
  file_objs = request.files.getlist('file')
58
  for file_obj in file_objs:
59
  if file_obj.filename == '':
60
  return get_json_result(
61
- data=False, retmsg='No file selected!', retcode=RetCode.ARGUMENT_ERROR)
62
 
63
  e, kb = KnowledgebaseService.get_by_id(kb_id)
64
  if not e:
@@ -67,7 +67,7 @@ def upload():
67
  err, _ = FileService.upload_document(kb, file_objs, current_user.id)
68
  if err:
69
  return get_json_result(
70
- data=False, retmsg="\n".join(err), retcode=RetCode.SERVER_ERROR)
71
  return get_json_result(data=True)
72
 
73
 
@@ -78,12 +78,12 @@ def web_crawl():
78
  kb_id = request.form.get("kb_id")
79
  if not kb_id:
80
  return get_json_result(
81
- data=False, retmsg='Lack of "KB ID"', retcode=RetCode.ARGUMENT_ERROR)
82
  name = request.form.get("name")
83
  url = request.form.get("url")
84
  if not is_valid_url(url):
85
  return get_json_result(
86
- data=False, retmsg='The URL format is invalid', retcode=RetCode.ARGUMENT_ERROR)
87
  e, kb = KnowledgebaseService.get_by_id(kb_id)
88
  if not e:
89
  raise LookupError("Can't find this knowledgebase!")
@@ -145,17 +145,17 @@ def create():
145
  kb_id = req["kb_id"]
146
  if not kb_id:
147
  return get_json_result(
148
- data=False, retmsg='Lack of "KB ID"', retcode=RetCode.ARGUMENT_ERROR)
149
 
150
  try:
151
  e, kb = KnowledgebaseService.get_by_id(kb_id)
152
  if not e:
153
  return get_data_error_result(
154
- retmsg="Can't find this knowledgebase!")
155
 
156
  if DocumentService.query(name=req["name"], kb_id=kb_id):
157
  return get_data_error_result(
158
- retmsg="Duplicated document name in the same knowledgebase.")
159
 
160
  doc = DocumentService.insert({
161
  "id": get_uuid(),
@@ -179,7 +179,7 @@ def list_docs():
179
  kb_id = request.args.get("kb_id")
180
  if not kb_id:
181
  return get_json_result(
182
- data=False, retmsg='Lack of "KB ID"', retcode=RetCode.ARGUMENT_ERROR)
183
  tenants = UserTenantService.query(user_id=current_user.id)
184
  for tenant in tenants:
185
  if KnowledgebaseService.query(
@@ -187,8 +187,8 @@ def list_docs():
187
  break
188
  else:
189
  return get_json_result(
190
- data=False, retmsg=f'Only owner of knowledgebase authorized for this operation.',
191
- retcode=RetCode.OPERATING_ERROR)
192
  keywords = request.args.get("keywords", "")
193
 
194
  page_number = int(request.args.get("page", 1))
@@ -217,8 +217,8 @@ def docinfos():
217
  if not DocumentService.accessible(doc_id, current_user.id):
218
  return get_json_result(
219
  data=False,
220
- retmsg='No authorization.',
221
- retcode=RetCode.AUTHENTICATION_ERROR
222
  )
223
  docs = DocumentService.get_by_ids(doc_ids)
224
  return get_json_result(data=list(docs.dicts()))
@@ -230,7 +230,7 @@ def thumbnails():
230
  doc_ids = request.args.get("doc_ids").split(",")
231
  if not doc_ids:
232
  return get_json_result(
233
- data=False, retmsg='Lack of "Document ID"', retcode=RetCode.ARGUMENT_ERROR)
234
 
235
  try:
236
  docs = DocumentService.get_thumbnails(doc_ids)
@@ -252,28 +252,28 @@ def change_status():
252
  if str(req["status"]) not in ["0", "1"]:
253
  return get_json_result(
254
  data=False,
255
- retmsg='"Status" must be either 0 or 1!',
256
- retcode=RetCode.ARGUMENT_ERROR)
257
 
258
  if not DocumentService.accessible(req["doc_id"], current_user.id):
259
  return get_json_result(
260
  data=False,
261
- retmsg='No authorization.',
262
- retcode=RetCode.AUTHENTICATION_ERROR)
263
 
264
  try:
265
  e, doc = DocumentService.get_by_id(req["doc_id"])
266
  if not e:
267
- return get_data_error_result(retmsg="Document not found!")
268
  e, kb = KnowledgebaseService.get_by_id(doc.kb_id)
269
  if not e:
270
  return get_data_error_result(
271
- retmsg="Can't find this knowledgebase!")
272
 
273
  if not DocumentService.update_by_id(
274
  req["doc_id"], {"status": str(req["status"])}):
275
  return get_data_error_result(
276
- retmsg="Database error (Document update)!")
277
 
278
  if str(req["status"]) == "0":
279
  ELASTICSEARCH.updateScriptByQuery(Q("term", doc_id=req["doc_id"]),
@@ -304,8 +304,8 @@ def rm():
304
  if not DocumentService.accessible4deletion(doc_id, current_user.id):
305
  return get_json_result(
306
  data=False,
307
- retmsg='No authorization.',
308
- retcode=RetCode.AUTHENTICATION_ERROR
309
  )
310
 
311
  root_folder = FileService.get_root_folder(current_user.id)
@@ -316,16 +316,16 @@ def rm():
316
  try:
317
  e, doc = DocumentService.get_by_id(doc_id)
318
  if not e:
319
- return get_data_error_result(retmsg="Document not found!")
320
  tenant_id = DocumentService.get_tenant_id(doc_id)
321
  if not tenant_id:
322
- return get_data_error_result(retmsg="Tenant not found!")
323
 
324
  b, n = File2DocumentService.get_storage_address(doc_id=doc_id)
325
 
326
  if not DocumentService.remove_document(doc, tenant_id):
327
  return get_data_error_result(
328
- retmsg="Database error (Document removal)!")
329
 
330
  f2d = File2DocumentService.get_by_document_id(doc_id)
331
  FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id])
@@ -336,7 +336,7 @@ def rm():
336
  errors += str(e)
337
 
338
  if errors:
339
- return get_json_result(data=False, retmsg=errors, retcode=RetCode.SERVER_ERROR)
340
 
341
  return get_json_result(data=True)
342
 
@@ -350,8 +350,8 @@ def run():
350
  if not DocumentService.accessible(doc_id, current_user.id):
351
  return get_json_result(
352
  data=False,
353
- retmsg='No authorization.',
354
- retcode=RetCode.AUTHENTICATION_ERROR
355
  )
356
  try:
357
  for id in req["doc_ids"]:
@@ -364,7 +364,7 @@ def run():
364
  # if str(req["run"]) == TaskStatus.CANCEL.value:
365
  tenant_id = DocumentService.get_tenant_id(id)
366
  if not tenant_id:
367
- return get_data_error_result(retmsg="Tenant not found!")
368
  ELASTICSEARCH.deleteByQuery(
369
  Q("match", doc_id=id), idxnm=search.index_name(tenant_id))
370
 
@@ -389,28 +389,28 @@ def rename():
389
  if not DocumentService.accessible(req["doc_id"], current_user.id):
390
  return get_json_result(
391
  data=False,
392
- retmsg='No authorization.',
393
- retcode=RetCode.AUTHENTICATION_ERROR
394
  )
395
  try:
396
  e, doc = DocumentService.get_by_id(req["doc_id"])
397
  if not e:
398
- return get_data_error_result(retmsg="Document not found!")
399
  if pathlib.Path(req["name"].lower()).suffix != pathlib.Path(
400
  doc.name.lower()).suffix:
401
  return get_json_result(
402
  data=False,
403
- retmsg="The extension of file can't be changed",
404
- retcode=RetCode.ARGUMENT_ERROR)
405
  for d in DocumentService.query(name=req["name"], kb_id=doc.kb_id):
406
  if d.name == req["name"]:
407
  return get_data_error_result(
408
- retmsg="Duplicated document name in the same knowledgebase.")
409
 
410
  if not DocumentService.update_by_id(
411
  req["doc_id"], {"name": req["name"]}):
412
  return get_data_error_result(
413
- retmsg="Database error (Document rename)!")
414
 
415
  informs = File2DocumentService.get_by_document_id(req["doc_id"])
416
  if informs:
@@ -428,7 +428,7 @@ def get(doc_id):
428
  try:
429
  e, doc = DocumentService.get_by_id(doc_id)
430
  if not e:
431
- return get_data_error_result(retmsg="Document not found!")
432
 
433
  b, n = File2DocumentService.get_storage_address(doc_id=doc_id)
434
  response = flask.make_response(STORAGE_IMPL.get(b, n))
@@ -456,13 +456,13 @@ def change_parser():
456
  if not DocumentService.accessible(req["doc_id"], current_user.id):
457
  return get_json_result(
458
  data=False,
459
- retmsg='No authorization.',
460
- retcode=RetCode.AUTHENTICATION_ERROR
461
  )
462
  try:
463
  e, doc = DocumentService.get_by_id(req["doc_id"])
464
  if not e:
465
- return get_data_error_result(retmsg="Document not found!")
466
  if doc.parser_id.lower() == req["parser_id"].lower():
467
  if "parser_config" in req:
468
  if req["parser_config"] == doc.parser_config:
@@ -473,23 +473,23 @@ def change_parser():
473
  if ((doc.type == FileType.VISUAL and req["parser_id"] != "picture")
474
  or (re.search(
475
  r"\.(ppt|pptx|pages)$", doc.name) and req["parser_id"] != "presentation")):
476
- return get_data_error_result(retmsg="Not supported yet!")
477
 
478
  e = DocumentService.update_by_id(doc.id,
479
  {"parser_id": req["parser_id"], "progress": 0, "progress_msg": "",
480
  "run": TaskStatus.UNSTART.value})
481
  if not e:
482
- return get_data_error_result(retmsg="Document not found!")
483
  if "parser_config" in req:
484
  DocumentService.update_parser_config(doc.id, req["parser_config"])
485
  if doc.token_num > 0:
486
  e = DocumentService.increment_chunk_num(doc.id, doc.kb_id, doc.token_num * -1, doc.chunk_num * -1,
487
  doc.process_duation * -1)
488
  if not e:
489
- return get_data_error_result(retmsg="Document not found!")
490
  tenant_id = DocumentService.get_tenant_id(req["doc_id"])
491
  if not tenant_id:
492
- return get_data_error_result(retmsg="Tenant not found!")
493
  ELASTICSEARCH.deleteByQuery(
494
  Q("match", doc_id=doc.id), idxnm=search.index_name(tenant_id))
495
 
@@ -516,13 +516,13 @@ def get_image(image_id):
516
  def upload_and_parse():
517
  if 'file' not in request.files:
518
  return get_json_result(
519
- data=False, retmsg='No file part!', retcode=RetCode.ARGUMENT_ERROR)
520
 
521
  file_objs = request.files.getlist('file')
522
  for file_obj in file_objs:
523
  if file_obj.filename == '':
524
  return get_json_result(
525
- data=False, retmsg='No file selected!', retcode=RetCode.ARGUMENT_ERROR)
526
 
527
  doc_ids = doc_upload_and_parse(request.form.get("conversation_id"), file_objs, current_user.id)
528
 
 
49
  kb_id = request.form.get("kb_id")
50
  if not kb_id:
51
  return get_json_result(
52
+ data=False, message='Lack of "KB ID"', code=RetCode.ARGUMENT_ERROR)
53
  if 'file' not in request.files:
54
  return get_json_result(
55
+ data=False, message='No file part!', code=RetCode.ARGUMENT_ERROR)
56
 
57
  file_objs = request.files.getlist('file')
58
  for file_obj in file_objs:
59
  if file_obj.filename == '':
60
  return get_json_result(
61
+ data=False, message='No file selected!', code=RetCode.ARGUMENT_ERROR)
62
 
63
  e, kb = KnowledgebaseService.get_by_id(kb_id)
64
  if not e:
 
67
  err, _ = FileService.upload_document(kb, file_objs, current_user.id)
68
  if err:
69
  return get_json_result(
70
+ data=False, message="\n".join(err), code=RetCode.SERVER_ERROR)
71
  return get_json_result(data=True)
72
 
73
 
 
78
  kb_id = request.form.get("kb_id")
79
  if not kb_id:
80
  return get_json_result(
81
+ data=False, message='Lack of "KB ID"', code=RetCode.ARGUMENT_ERROR)
82
  name = request.form.get("name")
83
  url = request.form.get("url")
84
  if not is_valid_url(url):
85
  return get_json_result(
86
+ data=False, message='The URL format is invalid', code=RetCode.ARGUMENT_ERROR)
87
  e, kb = KnowledgebaseService.get_by_id(kb_id)
88
  if not e:
89
  raise LookupError("Can't find this knowledgebase!")
 
145
  kb_id = req["kb_id"]
146
  if not kb_id:
147
  return get_json_result(
148
+ data=False, message='Lack of "KB ID"', code=RetCode.ARGUMENT_ERROR)
149
 
150
  try:
151
  e, kb = KnowledgebaseService.get_by_id(kb_id)
152
  if not e:
153
  return get_data_error_result(
154
+ message="Can't find this knowledgebase!")
155
 
156
  if DocumentService.query(name=req["name"], kb_id=kb_id):
157
  return get_data_error_result(
158
+ message="Duplicated document name in the same knowledgebase.")
159
 
160
  doc = DocumentService.insert({
161
  "id": get_uuid(),
 
179
  kb_id = request.args.get("kb_id")
180
  if not kb_id:
181
  return get_json_result(
182
+ data=False, message='Lack of "KB ID"', code=RetCode.ARGUMENT_ERROR)
183
  tenants = UserTenantService.query(user_id=current_user.id)
184
  for tenant in tenants:
185
  if KnowledgebaseService.query(
 
187
  break
188
  else:
189
  return get_json_result(
190
+ data=False, message='Only owner of knowledgebase authorized for this operation.',
191
+ code=RetCode.OPERATING_ERROR)
192
  keywords = request.args.get("keywords", "")
193
 
194
  page_number = int(request.args.get("page", 1))
 
217
  if not DocumentService.accessible(doc_id, current_user.id):
218
  return get_json_result(
219
  data=False,
220
+ message='No authorization.',
221
+ code=RetCode.AUTHENTICATION_ERROR
222
  )
223
  docs = DocumentService.get_by_ids(doc_ids)
224
  return get_json_result(data=list(docs.dicts()))
 
230
  doc_ids = request.args.get("doc_ids").split(",")
231
  if not doc_ids:
232
  return get_json_result(
233
+ data=False, message='Lack of "Document ID"', code=RetCode.ARGUMENT_ERROR)
234
 
235
  try:
236
  docs = DocumentService.get_thumbnails(doc_ids)
 
252
  if str(req["status"]) not in ["0", "1"]:
253
  return get_json_result(
254
  data=False,
255
+ message='"Status" must be either 0 or 1!',
256
+ code=RetCode.ARGUMENT_ERROR)
257
 
258
  if not DocumentService.accessible(req["doc_id"], current_user.id):
259
  return get_json_result(
260
  data=False,
261
+ message='No authorization.',
262
+ code=RetCode.AUTHENTICATION_ERROR)
263
 
264
  try:
265
  e, doc = DocumentService.get_by_id(req["doc_id"])
266
  if not e:
267
+ return get_data_error_result(message="Document not found!")
268
  e, kb = KnowledgebaseService.get_by_id(doc.kb_id)
269
  if not e:
270
  return get_data_error_result(
271
+ message="Can't find this knowledgebase!")
272
 
273
  if not DocumentService.update_by_id(
274
  req["doc_id"], {"status": str(req["status"])}):
275
  return get_data_error_result(
276
+ message="Database error (Document update)!")
277
 
278
  if str(req["status"]) == "0":
279
  ELASTICSEARCH.updateScriptByQuery(Q("term", doc_id=req["doc_id"]),
 
304
  if not DocumentService.accessible4deletion(doc_id, current_user.id):
305
  return get_json_result(
306
  data=False,
307
+ message='No authorization.',
308
+ code=RetCode.AUTHENTICATION_ERROR
309
  )
310
 
311
  root_folder = FileService.get_root_folder(current_user.id)
 
316
  try:
317
  e, doc = DocumentService.get_by_id(doc_id)
318
  if not e:
319
+ return get_data_error_result(message="Document not found!")
320
  tenant_id = DocumentService.get_tenant_id(doc_id)
321
  if not tenant_id:
322
+ return get_data_error_result(message="Tenant not found!")
323
 
324
  b, n = File2DocumentService.get_storage_address(doc_id=doc_id)
325
 
326
  if not DocumentService.remove_document(doc, tenant_id):
327
  return get_data_error_result(
328
+ message="Database error (Document removal)!")
329
 
330
  f2d = File2DocumentService.get_by_document_id(doc_id)
331
  FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id])
 
336
  errors += str(e)
337
 
338
  if errors:
339
+ return get_json_result(data=False, message=errors, code=RetCode.SERVER_ERROR)
340
 
341
  return get_json_result(data=True)
342
 
 
350
  if not DocumentService.accessible(doc_id, current_user.id):
351
  return get_json_result(
352
  data=False,
353
+ message='No authorization.',
354
+ code=RetCode.AUTHENTICATION_ERROR
355
  )
356
  try:
357
  for id in req["doc_ids"]:
 
364
  # if str(req["run"]) == TaskStatus.CANCEL.value:
365
  tenant_id = DocumentService.get_tenant_id(id)
366
  if not tenant_id:
367
+ return get_data_error_result(message="Tenant not found!")
368
  ELASTICSEARCH.deleteByQuery(
369
  Q("match", doc_id=id), idxnm=search.index_name(tenant_id))
370
 
 
389
  if not DocumentService.accessible(req["doc_id"], current_user.id):
390
  return get_json_result(
391
  data=False,
392
+ message='No authorization.',
393
+ code=RetCode.AUTHENTICATION_ERROR
394
  )
395
  try:
396
  e, doc = DocumentService.get_by_id(req["doc_id"])
397
  if not e:
398
+ return get_data_error_result(message="Document not found!")
399
  if pathlib.Path(req["name"].lower()).suffix != pathlib.Path(
400
  doc.name.lower()).suffix:
401
  return get_json_result(
402
  data=False,
403
+ message="The extension of file can't be changed",
404
+ code=RetCode.ARGUMENT_ERROR)
405
  for d in DocumentService.query(name=req["name"], kb_id=doc.kb_id):
406
  if d.name == req["name"]:
407
  return get_data_error_result(
408
+ message="Duplicated document name in the same knowledgebase.")
409
 
410
  if not DocumentService.update_by_id(
411
  req["doc_id"], {"name": req["name"]}):
412
  return get_data_error_result(
413
+ message="Database error (Document rename)!")
414
 
415
  informs = File2DocumentService.get_by_document_id(req["doc_id"])
416
  if informs:
 
428
  try:
429
  e, doc = DocumentService.get_by_id(doc_id)
430
  if not e:
431
+ return get_data_error_result(message="Document not found!")
432
 
433
  b, n = File2DocumentService.get_storage_address(doc_id=doc_id)
434
  response = flask.make_response(STORAGE_IMPL.get(b, n))
 
456
  if not DocumentService.accessible(req["doc_id"], current_user.id):
457
  return get_json_result(
458
  data=False,
459
+ message='No authorization.',
460
+ code=RetCode.AUTHENTICATION_ERROR
461
  )
462
  try:
463
  e, doc = DocumentService.get_by_id(req["doc_id"])
464
  if not e:
465
+ return get_data_error_result(message="Document not found!")
466
  if doc.parser_id.lower() == req["parser_id"].lower():
467
  if "parser_config" in req:
468
  if req["parser_config"] == doc.parser_config:
 
473
  if ((doc.type == FileType.VISUAL and req["parser_id"] != "picture")
474
  or (re.search(
475
  r"\.(ppt|pptx|pages)$", doc.name) and req["parser_id"] != "presentation")):
476
+ return get_data_error_result(message="Not supported yet!")
477
 
478
  e = DocumentService.update_by_id(doc.id,
479
  {"parser_id": req["parser_id"], "progress": 0, "progress_msg": "",
480
  "run": TaskStatus.UNSTART.value})
481
  if not e:
482
+ return get_data_error_result(message="Document not found!")
483
  if "parser_config" in req:
484
  DocumentService.update_parser_config(doc.id, req["parser_config"])
485
  if doc.token_num > 0:
486
  e = DocumentService.increment_chunk_num(doc.id, doc.kb_id, doc.token_num * -1, doc.chunk_num * -1,
487
  doc.process_duation * -1)
488
  if not e:
489
+ return get_data_error_result(message="Document not found!")
490
  tenant_id = DocumentService.get_tenant_id(req["doc_id"])
491
  if not tenant_id:
492
+ return get_data_error_result(message="Tenant not found!")
493
  ELASTICSEARCH.deleteByQuery(
494
  Q("match", doc_id=doc.id), idxnm=search.index_name(tenant_id))
495
 
 
516
  def upload_and_parse():
517
  if 'file' not in request.files:
518
  return get_json_result(
519
+ data=False, message='No file part!', code=RetCode.ARGUMENT_ERROR)
520
 
521
  file_objs = request.files.getlist('file')
522
  for file_obj in file_objs:
523
  if file_obj.filename == '':
524
  return get_json_result(
525
+ data=False, message='No file selected!', code=RetCode.ARGUMENT_ERROR)
526
 
527
  doc_ids = doc_upload_and_parse(request.form.get("conversation_id"), file_objs, current_user.id)
528
 
api/apps/file2document_app.py CHANGED
@@ -13,9 +13,7 @@
13
  # See the License for the specific language governing permissions and
14
  # limitations under the License
15
  #
16
- from elasticsearch_dsl import Q
17
 
18
- from api.db.db_models import File2Document
19
  from api.db.services.file2document_service import File2DocumentService
20
  from api.db.services.file_service import FileService
21
 
@@ -28,8 +26,6 @@ from api.db import FileType
28
  from api.db.services.document_service import DocumentService
29
  from api.settings import RetCode
30
  from api.utils.api_utils import get_json_result
31
- from rag.nlp import search
32
- from rag.utils.es_conn import ELASTICSEARCH
33
 
34
 
35
  @manager.route('/convert', methods=['POST'])
@@ -54,13 +50,13 @@ def convert():
54
  doc_id = inform.document_id
55
  e, doc = DocumentService.get_by_id(doc_id)
56
  if not e:
57
- return get_data_error_result(retmsg="Document not found!")
58
  tenant_id = DocumentService.get_tenant_id(doc_id)
59
  if not tenant_id:
60
- return get_data_error_result(retmsg="Tenant not found!")
61
  if not DocumentService.remove_document(doc, tenant_id):
62
  return get_data_error_result(
63
- retmsg="Database error (Document removal)!")
64
  File2DocumentService.delete_by_file_id(id)
65
 
66
  # insert
@@ -68,11 +64,11 @@ def convert():
68
  e, kb = KnowledgebaseService.get_by_id(kb_id)
69
  if not e:
70
  return get_data_error_result(
71
- retmsg="Can't find this knowledgebase!")
72
  e, file = FileService.get_by_id(id)
73
  if not e:
74
  return get_data_error_result(
75
- retmsg="Can't find this file!")
76
 
77
  doc = DocumentService.insert({
78
  "id": get_uuid(),
@@ -104,26 +100,26 @@ def rm():
104
  file_ids = req["file_ids"]
105
  if not file_ids:
106
  return get_json_result(
107
- data=False, retmsg='Lack of "Files ID"', retcode=RetCode.ARGUMENT_ERROR)
108
  try:
109
  for file_id in file_ids:
110
  informs = File2DocumentService.get_by_file_id(file_id)
111
  if not informs:
112
- return get_data_error_result(retmsg="Inform not found!")
113
  for inform in informs:
114
  if not inform:
115
- return get_data_error_result(retmsg="Inform not found!")
116
  File2DocumentService.delete_by_file_id(file_id)
117
  doc_id = inform.document_id
118
  e, doc = DocumentService.get_by_id(doc_id)
119
  if not e:
120
- return get_data_error_result(retmsg="Document not found!")
121
  tenant_id = DocumentService.get_tenant_id(doc_id)
122
  if not tenant_id:
123
- return get_data_error_result(retmsg="Tenant not found!")
124
  if not DocumentService.remove_document(doc, tenant_id):
125
  return get_data_error_result(
126
- retmsg="Database error (Document removal)!")
127
  return get_json_result(data=True)
128
  except Exception as e:
129
  return server_error_response(e)
 
13
  # See the License for the specific language governing permissions and
14
  # limitations under the License
15
  #
 
16
 
 
17
  from api.db.services.file2document_service import File2DocumentService
18
  from api.db.services.file_service import FileService
19
 
 
26
  from api.db.services.document_service import DocumentService
27
  from api.settings import RetCode
28
  from api.utils.api_utils import get_json_result
 
 
29
 
30
 
31
  @manager.route('/convert', methods=['POST'])
 
50
  doc_id = inform.document_id
51
  e, doc = DocumentService.get_by_id(doc_id)
52
  if not e:
53
+ return get_data_error_result(message="Document not found!")
54
  tenant_id = DocumentService.get_tenant_id(doc_id)
55
  if not tenant_id:
56
+ return get_data_error_result(message="Tenant not found!")
57
  if not DocumentService.remove_document(doc, tenant_id):
58
  return get_data_error_result(
59
+ message="Database error (Document removal)!")
60
  File2DocumentService.delete_by_file_id(id)
61
 
62
  # insert
 
64
  e, kb = KnowledgebaseService.get_by_id(kb_id)
65
  if not e:
66
  return get_data_error_result(
67
+ message="Can't find this knowledgebase!")
68
  e, file = FileService.get_by_id(id)
69
  if not e:
70
  return get_data_error_result(
71
+ message="Can't find this file!")
72
 
73
  doc = DocumentService.insert({
74
  "id": get_uuid(),
 
100
  file_ids = req["file_ids"]
101
  if not file_ids:
102
  return get_json_result(
103
+ data=False, message='Lack of "Files ID"', code=RetCode.ARGUMENT_ERROR)
104
  try:
105
  for file_id in file_ids:
106
  informs = File2DocumentService.get_by_file_id(file_id)
107
  if not informs:
108
+ return get_data_error_result(message="Inform not found!")
109
  for inform in informs:
110
  if not inform:
111
+ return get_data_error_result(message="Inform not found!")
112
  File2DocumentService.delete_by_file_id(file_id)
113
  doc_id = inform.document_id
114
  e, doc = DocumentService.get_by_id(doc_id)
115
  if not e:
116
+ return get_data_error_result(message="Document not found!")
117
  tenant_id = DocumentService.get_tenant_id(doc_id)
118
  if not tenant_id:
119
+ return get_data_error_result(message="Tenant not found!")
120
  if not DocumentService.remove_document(doc, tenant_id):
121
  return get_data_error_result(
122
+ message="Database error (Document removal)!")
123
  return get_json_result(data=True)
124
  except Exception as e:
125
  return server_error_response(e)
api/apps/file_app.py CHANGED
@@ -18,7 +18,6 @@ import pathlib
18
  import re
19
 
20
  import flask
21
- from elasticsearch_dsl import Q
22
  from flask import request
23
  from flask_login import login_required, current_user
24
 
@@ -32,8 +31,6 @@ from api.db.services.file_service import FileService
32
  from api.settings import RetCode
33
  from api.utils.api_utils import get_json_result
34
  from api.utils.file_utils import filename_type
35
- from rag.nlp import search
36
- from rag.utils.es_conn import ELASTICSEARCH
37
  from rag.utils.storage_factory import STORAGE_IMPL
38
 
39
 
@@ -49,24 +46,24 @@ def upload():
49
 
50
  if 'file' not in request.files:
51
  return get_json_result(
52
- data=False, retmsg='No file part!', retcode=RetCode.ARGUMENT_ERROR)
53
  file_objs = request.files.getlist('file')
54
 
55
  for file_obj in file_objs:
56
  if file_obj.filename == '':
57
  return get_json_result(
58
- data=False, retmsg='No file selected!', retcode=RetCode.ARGUMENT_ERROR)
59
  file_res = []
60
  try:
61
  for file_obj in file_objs:
62
  e, file = FileService.get_by_id(pf_id)
63
  if not e:
64
  return get_data_error_result(
65
- retmsg="Can't find this folder!")
66
  MAX_FILE_NUM_PER_USER = int(os.environ.get('MAX_FILE_NUM_PER_USER', 0))
67
  if MAX_FILE_NUM_PER_USER > 0 and DocumentService.get_doc_count(current_user.id) >= MAX_FILE_NUM_PER_USER:
68
  return get_data_error_result(
69
- retmsg="Exceed the maximum file number of a free user!")
70
 
71
  # split file name path
72
  if not file_obj.filename:
@@ -85,13 +82,13 @@ def upload():
85
  if file_len != len_id_list:
86
  e, file = FileService.get_by_id(file_id_list[len_id_list - 1])
87
  if not e:
88
- return get_data_error_result(retmsg="Folder not found!")
89
  last_folder = FileService.create_folder(file, file_id_list[len_id_list - 1], file_obj_names,
90
  len_id_list)
91
  else:
92
  e, file = FileService.get_by_id(file_id_list[len_id_list - 2])
93
  if not e:
94
- return get_data_error_result(retmsg="Folder not found!")
95
  last_folder = FileService.create_folder(file, file_id_list[len_id_list - 2], file_obj_names,
96
  len_id_list)
97
 
@@ -137,10 +134,10 @@ def create():
137
  try:
138
  if not FileService.is_parent_folder_exist(pf_id):
139
  return get_json_result(
140
- data=False, retmsg="Parent Folder Doesn't Exist!", retcode=RetCode.OPERATING_ERROR)
141
  if FileService.query(name=req["name"], parent_id=pf_id):
142
  return get_data_error_result(
143
- retmsg="Duplicated folder name in the same folder.")
144
 
145
  if input_file_type == FileType.FOLDER.value:
146
  file_type = FileType.FOLDER.value
@@ -181,14 +178,14 @@ def list_files():
181
  try:
182
  e, file = FileService.get_by_id(pf_id)
183
  if not e:
184
- return get_data_error_result(retmsg="Folder not found!")
185
 
186
  files, total = FileService.get_by_pf_id(
187
  current_user.id, pf_id, page_number, items_per_page, orderby, desc, keywords)
188
 
189
  parent_folder = FileService.get_parent_folder(pf_id)
190
  if not FileService.get_parent_folder(pf_id):
191
- return get_json_result(retmsg="File not found!")
192
 
193
  return get_json_result(data={"total": total, "files": files, "parent_folder": parent_folder.to_json()})
194
  except Exception as e:
@@ -212,7 +209,7 @@ def get_parent_folder():
212
  try:
213
  e, file = FileService.get_by_id(file_id)
214
  if not e:
215
- return get_data_error_result(retmsg="Folder not found!")
216
 
217
  parent_folder = FileService.get_parent_folder(file_id)
218
  return get_json_result(data={"parent_folder": parent_folder.to_json()})
@@ -227,7 +224,7 @@ def get_all_parent_folders():
227
  try:
228
  e, file = FileService.get_by_id(file_id)
229
  if not e:
230
- return get_data_error_result(retmsg="Folder not found!")
231
 
232
  parent_folders = FileService.get_all_parent_folders(file_id)
233
  parent_folders_res = []
@@ -248,9 +245,9 @@ def rm():
248
  for file_id in file_ids:
249
  e, file = FileService.get_by_id(file_id)
250
  if not e:
251
- return get_data_error_result(retmsg="File or Folder not found!")
252
  if not file.tenant_id:
253
- return get_data_error_result(retmsg="Tenant not found!")
254
  if file.source_type == FileSource.KNOWLEDGEBASE:
255
  continue
256
 
@@ -259,13 +256,13 @@ def rm():
259
  for inner_file_id in file_id_list:
260
  e, file = FileService.get_by_id(inner_file_id)
261
  if not e:
262
- return get_data_error_result(retmsg="File not found!")
263
  STORAGE_IMPL.rm(file.parent_id, file.location)
264
  FileService.delete_folder_by_pf_id(current_user.id, file_id)
265
  else:
266
  if not FileService.delete(file):
267
  return get_data_error_result(
268
- retmsg="Database error (File removal)!")
269
 
270
  # delete file2document
271
  informs = File2DocumentService.get_by_file_id(file_id)
@@ -273,13 +270,13 @@ def rm():
273
  doc_id = inform.document_id
274
  e, doc = DocumentService.get_by_id(doc_id)
275
  if not e:
276
- return get_data_error_result(retmsg="Document not found!")
277
  tenant_id = DocumentService.get_tenant_id(doc_id)
278
  if not tenant_id:
279
- return get_data_error_result(retmsg="Tenant not found!")
280
  if not DocumentService.remove_document(doc, tenant_id):
281
  return get_data_error_result(
282
- retmsg="Database error (Document removal)!")
283
  File2DocumentService.delete_by_file_id(file_id)
284
 
285
  return get_json_result(data=True)
@@ -295,30 +292,30 @@ def rename():
295
  try:
296
  e, file = FileService.get_by_id(req["file_id"])
297
  if not e:
298
- return get_data_error_result(retmsg="File not found!")
299
  if file.type != FileType.FOLDER.value \
300
  and pathlib.Path(req["name"].lower()).suffix != pathlib.Path(
301
  file.name.lower()).suffix:
302
  return get_json_result(
303
  data=False,
304
- retmsg="The extension of file can't be changed",
305
- retcode=RetCode.ARGUMENT_ERROR)
306
  for file in FileService.query(name=req["name"], pf_id=file.parent_id):
307
  if file.name == req["name"]:
308
  return get_data_error_result(
309
- retmsg="Duplicated file name in the same folder.")
310
 
311
  if not FileService.update_by_id(
312
  req["file_id"], {"name": req["name"]}):
313
  return get_data_error_result(
314
- retmsg="Database error (File rename)!")
315
 
316
  informs = File2DocumentService.get_by_file_id(req["file_id"])
317
  if informs:
318
  if not DocumentService.update_by_id(
319
  informs[0].document_id, {"name": req["name"]}):
320
  return get_data_error_result(
321
- retmsg="Database error (Document rename)!")
322
 
323
  return get_json_result(data=True)
324
  except Exception as e:
@@ -331,7 +328,7 @@ def get(file_id):
331
  try:
332
  e, file = FileService.get_by_id(file_id)
333
  if not e:
334
- return get_data_error_result(retmsg="Document not found!")
335
  b, n = File2DocumentService.get_storage_address(file_id=file_id)
336
  response = flask.make_response(STORAGE_IMPL.get(b, n))
337
  ext = re.search(r"\.([^.]+)$", file.name)
@@ -359,12 +356,12 @@ def move():
359
  for file_id in file_ids:
360
  e, file = FileService.get_by_id(file_id)
361
  if not e:
362
- return get_data_error_result(retmsg="File or Folder not found!")
363
  if not file.tenant_id:
364
- return get_data_error_result(retmsg="Tenant not found!")
365
  fe, _ = FileService.get_by_id(parent_id)
366
  if not fe:
367
- return get_data_error_result(retmsg="Parent Folder not found!")
368
  FileService.move_file(file_ids, parent_id)
369
  return get_json_result(data=True)
370
  except Exception as e:
 
18
  import re
19
 
20
  import flask
 
21
  from flask import request
22
  from flask_login import login_required, current_user
23
 
 
31
  from api.settings import RetCode
32
  from api.utils.api_utils import get_json_result
33
  from api.utils.file_utils import filename_type
 
 
34
  from rag.utils.storage_factory import STORAGE_IMPL
35
 
36
 
 
46
 
47
  if 'file' not in request.files:
48
  return get_json_result(
49
+ data=False, message='No file part!', code=RetCode.ARGUMENT_ERROR)
50
  file_objs = request.files.getlist('file')
51
 
52
  for file_obj in file_objs:
53
  if file_obj.filename == '':
54
  return get_json_result(
55
+ data=False, message='No file selected!', code=RetCode.ARGUMENT_ERROR)
56
  file_res = []
57
  try:
58
  for file_obj in file_objs:
59
  e, file = FileService.get_by_id(pf_id)
60
  if not e:
61
  return get_data_error_result(
62
+ message="Can't find this folder!")
63
  MAX_FILE_NUM_PER_USER = int(os.environ.get('MAX_FILE_NUM_PER_USER', 0))
64
  if MAX_FILE_NUM_PER_USER > 0 and DocumentService.get_doc_count(current_user.id) >= MAX_FILE_NUM_PER_USER:
65
  return get_data_error_result(
66
+ message="Exceed the maximum file number of a free user!")
67
 
68
  # split file name path
69
  if not file_obj.filename:
 
82
  if file_len != len_id_list:
83
  e, file = FileService.get_by_id(file_id_list[len_id_list - 1])
84
  if not e:
85
+ return get_data_error_result(message="Folder not found!")
86
  last_folder = FileService.create_folder(file, file_id_list[len_id_list - 1], file_obj_names,
87
  len_id_list)
88
  else:
89
  e, file = FileService.get_by_id(file_id_list[len_id_list - 2])
90
  if not e:
91
+ return get_data_error_result(message="Folder not found!")
92
  last_folder = FileService.create_folder(file, file_id_list[len_id_list - 2], file_obj_names,
93
  len_id_list)
94
 
 
134
  try:
135
  if not FileService.is_parent_folder_exist(pf_id):
136
  return get_json_result(
137
+ data=False, message="Parent Folder Doesn't Exist!", code=RetCode.OPERATING_ERROR)
138
  if FileService.query(name=req["name"], parent_id=pf_id):
139
  return get_data_error_result(
140
+ message="Duplicated folder name in the same folder.")
141
 
142
  if input_file_type == FileType.FOLDER.value:
143
  file_type = FileType.FOLDER.value
 
178
  try:
179
  e, file = FileService.get_by_id(pf_id)
180
  if not e:
181
+ return get_data_error_result(message="Folder not found!")
182
 
183
  files, total = FileService.get_by_pf_id(
184
  current_user.id, pf_id, page_number, items_per_page, orderby, desc, keywords)
185
 
186
  parent_folder = FileService.get_parent_folder(pf_id)
187
  if not FileService.get_parent_folder(pf_id):
188
+ return get_json_result(message="File not found!")
189
 
190
  return get_json_result(data={"total": total, "files": files, "parent_folder": parent_folder.to_json()})
191
  except Exception as e:
 
209
  try:
210
  e, file = FileService.get_by_id(file_id)
211
  if not e:
212
+ return get_data_error_result(message="Folder not found!")
213
 
214
  parent_folder = FileService.get_parent_folder(file_id)
215
  return get_json_result(data={"parent_folder": parent_folder.to_json()})
 
224
  try:
225
  e, file = FileService.get_by_id(file_id)
226
  if not e:
227
+ return get_data_error_result(message="Folder not found!")
228
 
229
  parent_folders = FileService.get_all_parent_folders(file_id)
230
  parent_folders_res = []
 
245
  for file_id in file_ids:
246
  e, file = FileService.get_by_id(file_id)
247
  if not e:
248
+ return get_data_error_result(message="File or Folder not found!")
249
  if not file.tenant_id:
250
+ return get_data_error_result(message="Tenant not found!")
251
  if file.source_type == FileSource.KNOWLEDGEBASE:
252
  continue
253
 
 
256
  for inner_file_id in file_id_list:
257
  e, file = FileService.get_by_id(inner_file_id)
258
  if not e:
259
+ return get_data_error_result(message="File not found!")
260
  STORAGE_IMPL.rm(file.parent_id, file.location)
261
  FileService.delete_folder_by_pf_id(current_user.id, file_id)
262
  else:
263
  if not FileService.delete(file):
264
  return get_data_error_result(
265
+ message="Database error (File removal)!")
266
 
267
  # delete file2document
268
  informs = File2DocumentService.get_by_file_id(file_id)
 
270
  doc_id = inform.document_id
271
  e, doc = DocumentService.get_by_id(doc_id)
272
  if not e:
273
+ return get_data_error_result(message="Document not found!")
274
  tenant_id = DocumentService.get_tenant_id(doc_id)
275
  if not tenant_id:
276
+ return get_data_error_result(message="Tenant not found!")
277
  if not DocumentService.remove_document(doc, tenant_id):
278
  return get_data_error_result(
279
+ message="Database error (Document removal)!")
280
  File2DocumentService.delete_by_file_id(file_id)
281
 
282
  return get_json_result(data=True)
 
292
  try:
293
  e, file = FileService.get_by_id(req["file_id"])
294
  if not e:
295
+ return get_data_error_result(message="File not found!")
296
  if file.type != FileType.FOLDER.value \
297
  and pathlib.Path(req["name"].lower()).suffix != pathlib.Path(
298
  file.name.lower()).suffix:
299
  return get_json_result(
300
  data=False,
301
+ message="The extension of file can't be changed",
302
+ code=RetCode.ARGUMENT_ERROR)
303
  for file in FileService.query(name=req["name"], pf_id=file.parent_id):
304
  if file.name == req["name"]:
305
  return get_data_error_result(
306
+ message="Duplicated file name in the same folder.")
307
 
308
  if not FileService.update_by_id(
309
  req["file_id"], {"name": req["name"]}):
310
  return get_data_error_result(
311
+ message="Database error (File rename)!")
312
 
313
  informs = File2DocumentService.get_by_file_id(req["file_id"])
314
  if informs:
315
  if not DocumentService.update_by_id(
316
  informs[0].document_id, {"name": req["name"]}):
317
  return get_data_error_result(
318
+ message="Database error (Document rename)!")
319
 
320
  return get_json_result(data=True)
321
  except Exception as e:
 
328
  try:
329
  e, file = FileService.get_by_id(file_id)
330
  if not e:
331
+ return get_data_error_result(message="Document not found!")
332
  b, n = File2DocumentService.get_storage_address(file_id=file_id)
333
  response = flask.make_response(STORAGE_IMPL.get(b, n))
334
  ext = re.search(r"\.([^.]+)$", file.name)
 
356
  for file_id in file_ids:
357
  e, file = FileService.get_by_id(file_id)
358
  if not e:
359
+ return get_data_error_result(message="File or Folder not found!")
360
  if not file.tenant_id:
361
+ return get_data_error_result(message="Tenant not found!")
362
  fe, _ = FileService.get_by_id(parent_id)
363
  if not fe:
364
+ return get_data_error_result(message="Parent Folder not found!")
365
  FileService.move_file(file_ids, parent_id)
366
  return get_json_result(data=True)
367
  except Exception as e:
api/apps/kb_app.py CHANGED
@@ -47,7 +47,7 @@ def create():
47
  req["created_by"] = current_user.id
48
  e, t = TenantService.get_by_id(current_user.id)
49
  if not e:
50
- return get_data_error_result(retmsg="Tenant not found.")
51
  req["embd_id"] = t.embd_id
52
  if not KnowledgebaseService.save(**req):
53
  return get_data_error_result()
@@ -65,24 +65,24 @@ def update():
65
  if not KnowledgebaseService.accessible4deletion(req["kb_id"], current_user.id):
66
  return get_json_result(
67
  data=False,
68
- retmsg='No authorization.',
69
- retcode=RetCode.AUTHENTICATION_ERROR
70
  )
71
  try:
72
  if not KnowledgebaseService.query(
73
  created_by=current_user.id, id=req["kb_id"]):
74
  return get_json_result(
75
- data=False, retmsg=f'Only owner of knowledgebase authorized for this operation.', retcode=RetCode.OPERATING_ERROR)
76
 
77
  e, kb = KnowledgebaseService.get_by_id(req["kb_id"])
78
  if not e:
79
  return get_data_error_result(
80
- retmsg="Can't find this knowledgebase!")
81
 
82
  if req["name"].lower() != kb.name.lower() \
83
  and len(KnowledgebaseService.query(name=req["name"], tenant_id=current_user.id, status=StatusEnum.VALID.value)) > 1:
84
  return get_data_error_result(
85
- retmsg="Duplicated knowledgebase name.")
86
 
87
  del req["kb_id"]
88
  if not KnowledgebaseService.update_by_id(kb.id, req):
@@ -91,7 +91,7 @@ def update():
91
  e, kb = KnowledgebaseService.get_by_id(kb.id)
92
  if not e:
93
  return get_data_error_result(
94
- retmsg="Database error (Knowledgebase rename)!")
95
 
96
  return get_json_result(data=kb.to_json())
97
  except Exception as e:
@@ -110,12 +110,12 @@ def detail():
110
  break
111
  else:
112
  return get_json_result(
113
- data=False, retmsg=f'Only owner of knowledgebase authorized for this operation.',
114
- retcode=RetCode.OPERATING_ERROR)
115
  kb = KnowledgebaseService.get_detail(kb_id)
116
  if not kb:
117
  return get_data_error_result(
118
- retmsg="Can't find this knowledgebase!")
119
  return get_json_result(data=kb)
120
  except Exception as e:
121
  return server_error_response(e)
@@ -145,27 +145,27 @@ def rm():
145
  if not KnowledgebaseService.accessible4deletion(req["kb_id"], current_user.id):
146
  return get_json_result(
147
  data=False,
148
- retmsg='No authorization.',
149
- retcode=RetCode.AUTHENTICATION_ERROR
150
  )
151
  try:
152
  kbs = KnowledgebaseService.query(
153
  created_by=current_user.id, id=req["kb_id"])
154
  if not kbs:
155
  return get_json_result(
156
- data=False, retmsg=f'Only owner of knowledgebase authorized for this operation.', retcode=RetCode.OPERATING_ERROR)
157
 
158
  for doc in DocumentService.query(kb_id=req["kb_id"]):
159
  if not DocumentService.remove_document(doc, kbs[0].tenant_id):
160
  return get_data_error_result(
161
- retmsg="Database error (Document removal)!")
162
  f2d = File2DocumentService.get_by_document_id(doc.id)
163
  FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id])
164
  File2DocumentService.delete_by_document_id(doc.id)
165
 
166
  if not KnowledgebaseService.delete_by_id(req["kb_id"]):
167
  return get_data_error_result(
168
- retmsg="Database error (Knowledgebase removal)!")
169
  return get_json_result(data=True)
170
  except Exception as e:
171
  return server_error_response(e)
 
47
  req["created_by"] = current_user.id
48
  e, t = TenantService.get_by_id(current_user.id)
49
  if not e:
50
+ return get_data_error_result(message="Tenant not found.")
51
  req["embd_id"] = t.embd_id
52
  if not KnowledgebaseService.save(**req):
53
  return get_data_error_result()
 
65
  if not KnowledgebaseService.accessible4deletion(req["kb_id"], current_user.id):
66
  return get_json_result(
67
  data=False,
68
+ message='No authorization.',
69
+ code=RetCode.AUTHENTICATION_ERROR
70
  )
71
  try:
72
  if not KnowledgebaseService.query(
73
  created_by=current_user.id, id=req["kb_id"]):
74
  return get_json_result(
75
+ data=False, message='Only owner of knowledgebase authorized for this operation.', code=RetCode.OPERATING_ERROR)
76
 
77
  e, kb = KnowledgebaseService.get_by_id(req["kb_id"])
78
  if not e:
79
  return get_data_error_result(
80
+ message="Can't find this knowledgebase!")
81
 
82
  if req["name"].lower() != kb.name.lower() \
83
  and len(KnowledgebaseService.query(name=req["name"], tenant_id=current_user.id, status=StatusEnum.VALID.value)) > 1:
84
  return get_data_error_result(
85
+ message="Duplicated knowledgebase name.")
86
 
87
  del req["kb_id"]
88
  if not KnowledgebaseService.update_by_id(kb.id, req):
 
91
  e, kb = KnowledgebaseService.get_by_id(kb.id)
92
  if not e:
93
  return get_data_error_result(
94
+ message="Database error (Knowledgebase rename)!")
95
 
96
  return get_json_result(data=kb.to_json())
97
  except Exception as e:
 
110
  break
111
  else:
112
  return get_json_result(
113
+ data=False, message='Only owner of knowledgebase authorized for this operation.',
114
+ code=RetCode.OPERATING_ERROR)
115
  kb = KnowledgebaseService.get_detail(kb_id)
116
  if not kb:
117
  return get_data_error_result(
118
+ message="Can't find this knowledgebase!")
119
  return get_json_result(data=kb)
120
  except Exception as e:
121
  return server_error_response(e)
 
145
  if not KnowledgebaseService.accessible4deletion(req["kb_id"], current_user.id):
146
  return get_json_result(
147
  data=False,
148
+ message='No authorization.',
149
+ code=RetCode.AUTHENTICATION_ERROR
150
  )
151
  try:
152
  kbs = KnowledgebaseService.query(
153
  created_by=current_user.id, id=req["kb_id"])
154
  if not kbs:
155
  return get_json_result(
156
+ data=False, message='Only owner of knowledgebase authorized for this operation.', code=RetCode.OPERATING_ERROR)
157
 
158
  for doc in DocumentService.query(kb_id=req["kb_id"]):
159
  if not DocumentService.remove_document(doc, kbs[0].tenant_id):
160
  return get_data_error_result(
161
+ message="Database error (Document removal)!")
162
  f2d = File2DocumentService.get_by_document_id(doc.id)
163
  FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id])
164
  File2DocumentService.delete_by_document_id(doc.id)
165
 
166
  if not KnowledgebaseService.delete_by_id(req["kb_id"]):
167
  return get_data_error_result(
168
+ message="Database error (Knowledgebase removal)!")
169
  return get_json_result(data=True)
170
  except Exception as e:
171
  return server_error_response(e)
api/apps/llm_app.py CHANGED
@@ -98,7 +98,7 @@ def set_api_key():
98
  break
99
 
100
  if msg:
101
- return get_data_error_result(retmsg=msg)
102
 
103
  llm_config = {
104
  "api_key": req["api_key"],
@@ -278,7 +278,7 @@ def add_llm():
278
  pass
279
 
280
  if msg:
281
- return get_data_error_result(retmsg=msg)
282
 
283
  if not TenantLLMService.filter_update(
284
  [TenantLLM.tenant_id == current_user.id, TenantLLM.llm_factory == factory, TenantLLM.llm_name == llm["llm_name"]], llm):
 
98
  break
99
 
100
  if msg:
101
+ return get_data_error_result(message=msg)
102
 
103
  llm_config = {
104
  "api_key": req["api_key"],
 
278
  pass
279
 
280
  if msg:
281
+ return get_data_error_result(message=msg)
282
 
283
  if not TenantLLMService.filter_update(
284
  [TenantLLM.tenant_id == current_user.id, TenantLLM.llm_factory == factory, TenantLLM.llm_name == llm["llm_name"]], llm):
api/apps/sdk/chat.py CHANGED
@@ -32,7 +32,7 @@ def create(tenant_id):
32
  req=request.json
33
  ids= req.get("dataset_ids")
34
  if not ids:
35
- return get_error_data_result(retmsg="`dataset_ids` is required")
36
  for kb_id in ids:
37
  kbs = KnowledgebaseService.query(id=kb_id,tenant_id=tenant_id)
38
  if not kbs:
@@ -43,7 +43,7 @@ def create(tenant_id):
43
  kbs = KnowledgebaseService.get_by_ids(ids)
44
  embd_count = list(set([kb.embd_id for kb in kbs]))
45
  if len(embd_count) != 1:
46
- return get_result(retmsg='Datasets use different embedding models."',retcode=RetCode.AUTHENTICATION_ERROR)
47
  req["kb_ids"] = ids
48
  # llm
49
  llm = req.get("llm")
@@ -55,7 +55,7 @@ def create(tenant_id):
55
  req["llm_setting"] = req.pop("llm")
56
  e, tenant = TenantService.get_by_id(tenant_id)
57
  if not e:
58
- return get_error_data_result(retmsg="Tenant not found!")
59
  # prompt
60
  prompt = req.get("prompt")
61
  key_mapping = {"parameters": "variables",
@@ -86,12 +86,12 @@ def create(tenant_id):
86
  if not req.get("llm_id"):
87
  req["llm_id"] = tenant.llm_id
88
  if not req.get("name"):
89
- return get_error_data_result(retmsg="`name` is required.")
90
  if DialogService.query(name=req["name"], tenant_id=tenant_id, status=StatusEnum.VALID.value):
91
- return get_error_data_result(retmsg="Duplicated chat name in creating chat.")
92
  # tenant_id
93
  if req.get("tenant_id"):
94
- return get_error_data_result(retmsg="`tenant_id` must not be provided.")
95
  req["tenant_id"] = tenant_id
96
  # prompt more parameter
97
  default_prompt = {
@@ -117,14 +117,14 @@ def create(tenant_id):
117
  continue
118
  if req['prompt_config']["system"].find("{%s}" % p["key"]) < 0:
119
  return get_error_data_result(
120
- retmsg="Parameter '{}' is not used".format(p["key"]))
121
  # save
122
  if not DialogService.save(**req):
123
- return get_error_data_result(retmsg="Fail to new a chat!")
124
  # response
125
  e, res = DialogService.get_by_id(req["id"])
126
  if not e:
127
- return get_error_data_result(retmsg="Fail to new a chat!")
128
  res = res.to_json()
129
  renamed_dict = {}
130
  for key, value in res["prompt_config"].items():
@@ -150,7 +150,7 @@ def create(tenant_id):
150
  @token_required
151
  def update(tenant_id,chat_id):
152
  if not DialogService.query(tenant_id=tenant_id, id=chat_id, status=StatusEnum.VALID.value):
153
- return get_error_data_result(retmsg='You do not own the chat')
154
  req =request.json
155
  ids = req.get("dataset_ids")
156
  if "show_quotation" in req:
@@ -170,8 +170,8 @@ def update(tenant_id,chat_id):
170
  embd_count=list(set([kb.embd_id for kb in kbs]))
171
  if len(embd_count) != 1 :
172
  return get_result(
173
- retmsg='Datasets use different embedding models."',
174
- retcode=RetCode.AUTHENTICATION_ERROR)
175
  req["kb_ids"] = ids
176
  llm = req.get("llm")
177
  if llm:
@@ -182,7 +182,7 @@ def update(tenant_id,chat_id):
182
  req["llm_setting"] = req.pop("llm")
183
  e, tenant = TenantService.get_by_id(tenant_id)
184
  if not e:
185
- return get_error_data_result(retmsg="Tenant not found!")
186
  if req.get("rerank_model"):
187
  if not TenantLLMService.query(tenant_id=tenant_id,llm_name=req.get("rerank_model"),model_type="rerank"):
188
  return get_error_data_result(f"`rerank_model` {req.get('rerank_model')} doesn't exist")
@@ -207,18 +207,18 @@ def update(tenant_id,chat_id):
207
  res = res.to_json()
208
  if "name" in req:
209
  if not req.get("name"):
210
- return get_error_data_result(retmsg="`name` is not empty.")
211
  if req["name"].lower() != res["name"].lower() \
212
  and len(
213
  DialogService.query(name=req["name"], tenant_id=tenant_id, status=StatusEnum.VALID.value)) > 0:
214
- return get_error_data_result(retmsg="Duplicated chat name in updating dataset.")
215
  if "prompt_config" in req:
216
  res["prompt_config"].update(req["prompt_config"])
217
  for p in res["prompt_config"]["parameters"]:
218
  if p["optional"]:
219
  continue
220
  if res["prompt_config"]["system"].find("{%s}" % p["key"]) < 0:
221
- return get_error_data_result(retmsg="Parameter '{}' is not used".format(p["key"]))
222
  if "llm_setting" in req:
223
  res["llm_setting"].update(req["llm_setting"])
224
  req["prompt_config"] = res["prompt_config"]
@@ -229,7 +229,7 @@ def update(tenant_id,chat_id):
229
  if "dataset_ids" in req:
230
  req.pop("dataset_ids")
231
  if not DialogService.update_by_id(chat_id, req):
232
- return get_error_data_result(retmsg="Chat not found!")
233
  return get_result()
234
 
235
 
@@ -250,7 +250,7 @@ def delete(tenant_id):
250
  id_list=ids
251
  for id in id_list:
252
  if not DialogService.query(tenant_id=tenant_id, id=id, status=StatusEnum.VALID.value):
253
- return get_error_data_result(retmsg=f"You don't own the chat {id}")
254
  temp_dict = {"status": StatusEnum.INVALID.value}
255
  DialogService.update_by_id(id, temp_dict)
256
  return get_result()
@@ -262,7 +262,7 @@ def list_chat(tenant_id):
262
  name = request.args.get("name")
263
  chat = DialogService.query(id=id,name=name,status=StatusEnum.VALID.value)
264
  if not chat:
265
- return get_error_data_result(retmsg="The chat doesn't exist")
266
  page_number = int(request.args.get("page", 1))
267
  items_per_page = int(request.args.get("page_size", 1024))
268
  orderby = request.args.get("orderby", "create_time")
@@ -302,7 +302,7 @@ def list_chat(tenant_id):
302
  for kb_id in res["kb_ids"]:
303
  kb = KnowledgebaseService.query(id=kb_id)
304
  if not kb :
305
- return get_error_data_result(retmsg=f"Don't exist the kb {kb_id}")
306
  kb_list.append(kb[0].to_json())
307
  del res["kb_ids"]
308
  res["datasets"] = kb_list
 
32
  req=request.json
33
  ids= req.get("dataset_ids")
34
  if not ids:
35
+ return get_error_data_result(message="`dataset_ids` is required")
36
  for kb_id in ids:
37
  kbs = KnowledgebaseService.query(id=kb_id,tenant_id=tenant_id)
38
  if not kbs:
 
43
  kbs = KnowledgebaseService.get_by_ids(ids)
44
  embd_count = list(set([kb.embd_id for kb in kbs]))
45
  if len(embd_count) != 1:
46
+ return get_result(message='Datasets use different embedding models."',code=RetCode.AUTHENTICATION_ERROR)
47
  req["kb_ids"] = ids
48
  # llm
49
  llm = req.get("llm")
 
55
  req["llm_setting"] = req.pop("llm")
56
  e, tenant = TenantService.get_by_id(tenant_id)
57
  if not e:
58
+ return get_error_data_result(message="Tenant not found!")
59
  # prompt
60
  prompt = req.get("prompt")
61
  key_mapping = {"parameters": "variables",
 
86
  if not req.get("llm_id"):
87
  req["llm_id"] = tenant.llm_id
88
  if not req.get("name"):
89
+ return get_error_data_result(message="`name` is required.")
90
  if DialogService.query(name=req["name"], tenant_id=tenant_id, status=StatusEnum.VALID.value):
91
+ return get_error_data_result(message="Duplicated chat name in creating chat.")
92
  # tenant_id
93
  if req.get("tenant_id"):
94
+ return get_error_data_result(message="`tenant_id` must not be provided.")
95
  req["tenant_id"] = tenant_id
96
  # prompt more parameter
97
  default_prompt = {
 
117
  continue
118
  if req['prompt_config']["system"].find("{%s}" % p["key"]) < 0:
119
  return get_error_data_result(
120
+ message="Parameter '{}' is not used".format(p["key"]))
121
  # save
122
  if not DialogService.save(**req):
123
+ return get_error_data_result(message="Fail to new a chat!")
124
  # response
125
  e, res = DialogService.get_by_id(req["id"])
126
  if not e:
127
+ return get_error_data_result(message="Fail to new a chat!")
128
  res = res.to_json()
129
  renamed_dict = {}
130
  for key, value in res["prompt_config"].items():
 
150
  @token_required
151
  def update(tenant_id,chat_id):
152
  if not DialogService.query(tenant_id=tenant_id, id=chat_id, status=StatusEnum.VALID.value):
153
+ return get_error_data_result(message='You do not own the chat')
154
  req =request.json
155
  ids = req.get("dataset_ids")
156
  if "show_quotation" in req:
 
170
  embd_count=list(set([kb.embd_id for kb in kbs]))
171
  if len(embd_count) != 1 :
172
  return get_result(
173
+ message='Datasets use different embedding models."',
174
+ code=RetCode.AUTHENTICATION_ERROR)
175
  req["kb_ids"] = ids
176
  llm = req.get("llm")
177
  if llm:
 
182
  req["llm_setting"] = req.pop("llm")
183
  e, tenant = TenantService.get_by_id(tenant_id)
184
  if not e:
185
+ return get_error_data_result(message="Tenant not found!")
186
  if req.get("rerank_model"):
187
  if not TenantLLMService.query(tenant_id=tenant_id,llm_name=req.get("rerank_model"),model_type="rerank"):
188
  return get_error_data_result(f"`rerank_model` {req.get('rerank_model')} doesn't exist")
 
207
  res = res.to_json()
208
  if "name" in req:
209
  if not req.get("name"):
210
+ return get_error_data_result(message="`name` is not empty.")
211
  if req["name"].lower() != res["name"].lower() \
212
  and len(
213
  DialogService.query(name=req["name"], tenant_id=tenant_id, status=StatusEnum.VALID.value)) > 0:
214
+ return get_error_data_result(message="Duplicated chat name in updating dataset.")
215
  if "prompt_config" in req:
216
  res["prompt_config"].update(req["prompt_config"])
217
  for p in res["prompt_config"]["parameters"]:
218
  if p["optional"]:
219
  continue
220
  if res["prompt_config"]["system"].find("{%s}" % p["key"]) < 0:
221
+ return get_error_data_result(message="Parameter '{}' is not used".format(p["key"]))
222
  if "llm_setting" in req:
223
  res["llm_setting"].update(req["llm_setting"])
224
  req["prompt_config"] = res["prompt_config"]
 
229
  if "dataset_ids" in req:
230
  req.pop("dataset_ids")
231
  if not DialogService.update_by_id(chat_id, req):
232
+ return get_error_data_result(message="Chat not found!")
233
  return get_result()
234
 
235
 
 
250
  id_list=ids
251
  for id in id_list:
252
  if not DialogService.query(tenant_id=tenant_id, id=id, status=StatusEnum.VALID.value):
253
+ return get_error_data_result(message=f"You don't own the chat {id}")
254
  temp_dict = {"status": StatusEnum.INVALID.value}
255
  DialogService.update_by_id(id, temp_dict)
256
  return get_result()
 
262
  name = request.args.get("name")
263
  chat = DialogService.query(id=id,name=name,status=StatusEnum.VALID.value)
264
  if not chat:
265
+ return get_error_data_result(message="The chat doesn't exist")
266
  page_number = int(request.args.get("page", 1))
267
  items_per_page = int(request.args.get("page_size", 1024))
268
  orderby = request.args.get("orderby", "create_time")
 
302
  for kb_id in res["kb_ids"]:
303
  kb = KnowledgebaseService.query(id=kb_id)
304
  if not kb :
305
+ return get_error_data_result(message=f"Don't exist the kb {kb_id}")
306
  kb_list.append(kb[0].to_json())
307
  del res["kb_ids"]
308
  res["datasets"] = kb_list
api/apps/sdk/dataset.py CHANGED
@@ -1,535 +1,535 @@
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
-
17
- from flask import request
18
- from api.db import StatusEnum, FileSource
19
- from api.db.db_models import File
20
- from api.db.services.document_service import DocumentService
21
- from api.db.services.file2document_service import File2DocumentService
22
- from api.db.services.file_service import FileService
23
- from api.db.services.knowledgebase_service import KnowledgebaseService
24
- from api.db.services.llm_service import TenantLLMService, LLMService
25
- from api.db.services.user_service import TenantService
26
- from api.settings import RetCode
27
- from api.utils import get_uuid
28
- from api.utils.api_utils import (
29
- get_result,
30
- token_required,
31
- get_error_data_result,
32
- valid,
33
- get_parser_config,
34
- )
35
-
36
-
37
- @manager.route("/datasets", methods=["POST"])
38
- @token_required
39
- def create(tenant_id):
40
- """
41
- Create a new dataset.
42
- ---
43
- tags:
44
- - Datasets
45
- security:
46
- - ApiKeyAuth: []
47
- parameters:
48
- - in: header
49
- name: Authorization
50
- type: string
51
- required: true
52
- description: Bearer token for authentication.
53
- - in: body
54
- name: body
55
- description: Dataset creation parameters.
56
- required: true
57
- schema:
58
- type: object
59
- required:
60
- - name
61
- properties:
62
- name:
63
- type: string
64
- description: Name of the dataset.
65
- permission:
66
- type: string
67
- enum: ['me', 'team']
68
- description: Dataset permission.
69
- language:
70
- type: string
71
- enum: ['Chinese', 'English']
72
- description: Language of the dataset.
73
- chunk_method:
74
- type: string
75
- enum: ["naive", "manual", "qa", "table", "paper", "book", "laws",
76
- "presentation", "picture", "one", "knowledge_graph", "email"]
77
- description: Chunking method.
78
- parser_config:
79
- type: object
80
- description: Parser configuration.
81
- responses:
82
- 200:
83
- description: Successful operation.
84
- schema:
85
- type: object
86
- properties:
87
- data:
88
- type: object
89
- """
90
- req = request.json
91
- e, t = TenantService.get_by_id(tenant_id)
92
- permission = req.get("permission")
93
- language = req.get("language")
94
- chunk_method = req.get("chunk_method")
95
- parser_config = req.get("parser_config")
96
- valid_permission = ["me", "team"]
97
- valid_language = ["Chinese", "English"]
98
- valid_chunk_method = [
99
- "naive",
100
- "manual",
101
- "qa",
102
- "table",
103
- "paper",
104
- "book",
105
- "laws",
106
- "presentation",
107
- "picture",
108
- "one",
109
- "knowledge_graph",
110
- "email",
111
- ]
112
- check_validation = valid(
113
- permission,
114
- valid_permission,
115
- language,
116
- valid_language,
117
- chunk_method,
118
- valid_chunk_method,
119
- )
120
- if check_validation:
121
- return check_validation
122
- req["parser_config"] = get_parser_config(chunk_method, parser_config)
123
- if "tenant_id" in req:
124
- return get_error_data_result(retmsg="`tenant_id` must not be provided")
125
- if "chunk_count" in req or "document_count" in req:
126
- return get_error_data_result(
127
- retmsg="`chunk_count` or `document_count` must not be provided"
128
- )
129
- if "name" not in req:
130
- return get_error_data_result(retmsg="`name` is not empty!")
131
- req["id"] = get_uuid()
132
- req["name"] = req["name"].strip()
133
- if req["name"] == "":
134
- return get_error_data_result(retmsg="`name` is not empty string!")
135
- if KnowledgebaseService.query(
136
- name=req["name"], tenant_id=tenant_id, status=StatusEnum.VALID.value
137
- ):
138
- return get_error_data_result(
139
- retmsg="Duplicated dataset name in creating dataset."
140
- )
141
- req["tenant_id"] = req["created_by"] = tenant_id
142
- if not req.get("embedding_model"):
143
- req["embedding_model"] = t.embd_id
144
- else:
145
- valid_embedding_models = [
146
- "BAAI/bge-large-zh-v1.5",
147
- "BAAI/bge-base-en-v1.5",
148
- "BAAI/bge-large-en-v1.5",
149
- "BAAI/bge-small-en-v1.5",
150
- "BAAI/bge-small-zh-v1.5",
151
- "jinaai/jina-embeddings-v2-base-en",
152
- "jinaai/jina-embeddings-v2-small-en",
153
- "nomic-ai/nomic-embed-text-v1.5",
154
- "sentence-transformers/all-MiniLM-L6-v2",
155
- "text-embedding-v2",
156
- "text-embedding-v3",
157
- "maidalun1020/bce-embedding-base_v1",
158
- ]
159
- embd_model = LLMService.query(
160
- llm_name=req["embedding_model"], model_type="embedding"
161
- )
162
- if not embd_model:
163
- return get_error_data_result(
164
- f"`embedding_model` {req.get('embedding_model')} doesn't exist"
165
- )
166
- if embd_model:
167
- if req[
168
- "embedding_model"
169
- ] not in valid_embedding_models and not TenantLLMService.query(
170
- tenant_id=tenant_id,
171
- model_type="embedding",
172
- llm_name=req.get("embedding_model"),
173
- ):
174
- return get_error_data_result(
175
- f"`embedding_model` {req.get('embedding_model')} doesn't exist"
176
- )
177
- key_mapping = {
178
- "chunk_num": "chunk_count",
179
- "doc_num": "document_count",
180
- "parser_id": "chunk_method",
181
- "embd_id": "embedding_model",
182
- }
183
- mapped_keys = {
184
- new_key: req[old_key]
185
- for new_key, old_key in key_mapping.items()
186
- if old_key in req
187
- }
188
- req.update(mapped_keys)
189
- if not KnowledgebaseService.save(**req):
190
- return get_error_data_result(retmsg="Create dataset error.(Database error)")
191
- renamed_data = {}
192
- e, k = KnowledgebaseService.get_by_id(req["id"])
193
- for key, value in k.to_dict().items():
194
- new_key = key_mapping.get(key, key)
195
- renamed_data[new_key] = value
196
- return get_result(data=renamed_data)
197
-
198
-
199
- @manager.route("/datasets", methods=["DELETE"])
200
- @token_required
201
- def delete(tenant_id):
202
- """
203
- Delete datasets.
204
- ---
205
- tags:
206
- - Datasets
207
- security:
208
- - ApiKeyAuth: []
209
- parameters:
210
- - in: header
211
- name: Authorization
212
- type: string
213
- required: true
214
- description: Bearer token for authentication.
215
- - in: body
216
- name: body
217
- description: Dataset deletion parameters.
218
- required: true
219
- schema:
220
- type: object
221
- properties:
222
- ids:
223
- type: array
224
- items:
225
- type: string
226
- description: List of dataset IDs to delete.
227
- responses:
228
- 200:
229
- description: Successful operation.
230
- schema:
231
- type: object
232
- """
233
- req = request.json
234
- if not req:
235
- ids = None
236
- else:
237
- ids = req.get("ids")
238
- if not ids:
239
- id_list = []
240
- kbs = KnowledgebaseService.query(tenant_id=tenant_id)
241
- for kb in kbs:
242
- id_list.append(kb.id)
243
- else:
244
- id_list = ids
245
- for id in id_list:
246
- kbs = KnowledgebaseService.query(id=id, tenant_id=tenant_id)
247
- if not kbs:
248
- return get_error_data_result(retmsg=f"You don't own the dataset {id}")
249
- for doc in DocumentService.query(kb_id=id):
250
- if not DocumentService.remove_document(doc, tenant_id):
251
- return get_error_data_result(
252
- retmsg="Remove document error.(Database error)"
253
- )
254
- f2d = File2DocumentService.get_by_document_id(doc.id)
255
- FileService.filter_delete(
256
- [
257
- File.source_type == FileSource.KNOWLEDGEBASE,
258
- File.id == f2d[0].file_id,
259
- ]
260
- )
261
- File2DocumentService.delete_by_document_id(doc.id)
262
- if not KnowledgebaseService.delete_by_id(id):
263
- return get_error_data_result(retmsg="Delete dataset error.(Database error)")
264
- return get_result(retcode=RetCode.SUCCESS)
265
-
266
-
267
- @manager.route("/datasets/<dataset_id>", methods=["PUT"])
268
- @token_required
269
- def update(tenant_id, dataset_id):
270
- """
271
- Update a dataset.
272
- ---
273
- tags:
274
- - Datasets
275
- security:
276
- - ApiKeyAuth: []
277
- parameters:
278
- - in: path
279
- name: dataset_id
280
- type: string
281
- required: true
282
- description: ID of the dataset to update.
283
- - in: header
284
- name: Authorization
285
- type: string
286
- required: true
287
- description: Bearer token for authentication.
288
- - in: body
289
- name: body
290
- description: Dataset update parameters.
291
- required: true
292
- schema:
293
- type: object
294
- properties:
295
- name:
296
- type: string
297
- description: New name of the dataset.
298
- permission:
299
- type: string
300
- enum: ['me', 'team']
301
- description: Updated permission.
302
- language:
303
- type: string
304
- enum: ['Chinese', 'English']
305
- description: Updated language.
306
- chunk_method:
307
- type: string
308
- enum: ["naive", "manual", "qa", "table", "paper", "book", "laws",
309
- "presentation", "picture", "one", "knowledge_graph", "email"]
310
- description: Updated chunking method.
311
- parser_config:
312
- type: object
313
- description: Updated parser configuration.
314
- responses:
315
- 200:
316
- description: Successful operation.
317
- schema:
318
- type: object
319
- """
320
- if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
321
- return get_error_data_result(retmsg="You don't own the dataset")
322
- req = request.json
323
- e, t = TenantService.get_by_id(tenant_id)
324
- invalid_keys = {"id", "embd_id", "chunk_num", "doc_num", "parser_id"}
325
- if any(key in req for key in invalid_keys):
326
- return get_error_data_result(retmsg="The input parameters are invalid.")
327
- permission = req.get("permission")
328
- language = req.get("language")
329
- chunk_method = req.get("chunk_method")
330
- parser_config = req.get("parser_config")
331
- valid_permission = ["me", "team"]
332
- valid_language = ["Chinese", "English"]
333
- valid_chunk_method = [
334
- "naive",
335
- "manual",
336
- "qa",
337
- "table",
338
- "paper",
339
- "book",
340
- "laws",
341
- "presentation",
342
- "picture",
343
- "one",
344
- "knowledge_graph",
345
- "email",
346
- ]
347
- check_validation = valid(
348
- permission,
349
- valid_permission,
350
- language,
351
- valid_language,
352
- chunk_method,
353
- valid_chunk_method,
354
- )
355
- if check_validation:
356
- return check_validation
357
- if "tenant_id" in req:
358
- if req["tenant_id"] != tenant_id:
359
- return get_error_data_result(retmsg="Can't change `tenant_id`.")
360
- e, kb = KnowledgebaseService.get_by_id(dataset_id)
361
- if "parser_config" in req:
362
- temp_dict = kb.parser_config
363
- temp_dict.update(req["parser_config"])
364
- req["parser_config"] = temp_dict
365
- if "chunk_count" in req:
366
- if req["chunk_count"] != kb.chunk_num:
367
- return get_error_data_result(retmsg="Can't change `chunk_count`.")
368
- req.pop("chunk_count")
369
- if "document_count" in req:
370
- if req["document_count"] != kb.doc_num:
371
- return get_error_data_result(retmsg="Can't change `document_count`.")
372
- req.pop("document_count")
373
- if "chunk_method" in req:
374
- if kb.chunk_num != 0 and req["chunk_method"] != kb.parser_id:
375
- return get_error_data_result(
376
- retmsg="If `chunk_count` is not 0, `chunk_method` is not changeable."
377
- )
378
- req["parser_id"] = req.pop("chunk_method")
379
- if req["parser_id"] != kb.parser_id:
380
- if not req.get("parser_config"):
381
- req["parser_config"] = get_parser_config(chunk_method, parser_config)
382
- if "embedding_model" in req:
383
- if kb.chunk_num != 0 and req["embedding_model"] != kb.embd_id:
384
- return get_error_data_result(
385
- retmsg="If `chunk_count` is not 0, `embedding_model` is not changeable."
386
- )
387
- if not req.get("embedding_model"):
388
- return get_error_data_result("`embedding_model` can't be empty")
389
- valid_embedding_models = [
390
- "BAAI/bge-large-zh-v1.5",
391
- "BAAI/bge-base-en-v1.5",
392
- "BAAI/bge-large-en-v1.5",
393
- "BAAI/bge-small-en-v1.5",
394
- "BAAI/bge-small-zh-v1.5",
395
- "jinaai/jina-embeddings-v2-base-en",
396
- "jinaai/jina-embeddings-v2-small-en",
397
- "nomic-ai/nomic-embed-text-v1.5",
398
- "sentence-transformers/all-MiniLM-L6-v2",
399
- "text-embedding-v2",
400
- "text-embedding-v3",
401
- "maidalun1020/bce-embedding-base_v1",
402
- ]
403
- embd_model = LLMService.query(
404
- llm_name=req["embedding_model"], model_type="embedding"
405
- )
406
- if not embd_model:
407
- return get_error_data_result(
408
- f"`embedding_model` {req.get('embedding_model')} doesn't exist"
409
- )
410
- if embd_model:
411
- if req[
412
- "embedding_model"
413
- ] not in valid_embedding_models and not TenantLLMService.query(
414
- tenant_id=tenant_id,
415
- model_type="embedding",
416
- llm_name=req.get("embedding_model"),
417
- ):
418
- return get_error_data_result(
419
- f"`embedding_model` {req.get('embedding_model')} doesn't exist"
420
- )
421
- req["embd_id"] = req.pop("embedding_model")
422
- if "name" in req:
423
- req["name"] = req["name"].strip()
424
- if (
425
- req["name"].lower() != kb.name.lower()
426
- and len(
427
- KnowledgebaseService.query(
428
- name=req["name"], tenant_id=tenant_id, status=StatusEnum.VALID.value
429
- )
430
- )
431
- > 0
432
- ):
433
- return get_error_data_result(
434
- retmsg="Duplicated dataset name in updating dataset."
435
- )
436
- if not KnowledgebaseService.update_by_id(kb.id, req):
437
- return get_error_data_result(retmsg="Update dataset error.(Database error)")
438
- return get_result(retcode=RetCode.SUCCESS)
439
-
440
-
441
- @manager.route("/datasets", methods=["GET"])
442
- @token_required
443
- def list(tenant_id):
444
- """
445
- List datasets.
446
- ---
447
- tags:
448
- - Datasets
449
- security:
450
- - ApiKeyAuth: []
451
- parameters:
452
- - in: query
453
- name: id
454
- type: string
455
- required: false
456
- description: Dataset ID to filter.
457
- - in: query
458
- name: name
459
- type: string
460
- required: false
461
- description: Dataset name to filter.
462
- - in: query
463
- name: page
464
- type: integer
465
- required: false
466
- default: 1
467
- description: Page number.
468
- - in: query
469
- name: page_size
470
- type: integer
471
- required: false
472
- default: 1024
473
- description: Number of items per page.
474
- - in: query
475
- name: orderby
476
- type: string
477
- required: false
478
- default: "create_time"
479
- description: Field to order by.
480
- - in: query
481
- name: desc
482
- type: boolean
483
- required: false
484
- default: true
485
- description: Order in descending.
486
- - in: header
487
- name: Authorization
488
- type: string
489
- required: true
490
- description: Bearer token for authentication.
491
- responses:
492
- 200:
493
- description: Successful operation.
494
- schema:
495
- type: array
496
- items:
497
- type: object
498
- """
499
- id = request.args.get("id")
500
- name = request.args.get("name")
501
- kbs = KnowledgebaseService.query(id=id, name=name, status=1)
502
- if not kbs:
503
- return get_error_data_result(retmsg="The dataset doesn't exist")
504
- page_number = int(request.args.get("page", 1))
505
- items_per_page = int(request.args.get("page_size", 1024))
506
- orderby = request.args.get("orderby", "create_time")
507
- if request.args.get("desc") == "False" or request.args.get("desc") == "false":
508
- desc = False
509
- else:
510
- desc = True
511
- tenants = TenantService.get_joined_tenants_by_user_id(tenant_id)
512
- kbs = KnowledgebaseService.get_list(
513
- [m["tenant_id"] for m in tenants],
514
- tenant_id,
515
- page_number,
516
- items_per_page,
517
- orderby,
518
- desc,
519
- id,
520
- name,
521
- )
522
- renamed_list = []
523
- for kb in kbs:
524
- key_mapping = {
525
- "chunk_num": "chunk_count",
526
- "doc_num": "document_count",
527
- "parser_id": "chunk_method",
528
- "embd_id": "embedding_model",
529
- }
530
- renamed_data = {}
531
- for key, value in kb.items():
532
- new_key = key_mapping.get(key, key)
533
- renamed_data[new_key] = value
534
- renamed_list.append(renamed_data)
535
- return get_result(data=renamed_list)
 
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
+
17
+ from flask import request
18
+ from api.db import StatusEnum, FileSource
19
+ from api.db.db_models import File
20
+ from api.db.services.document_service import DocumentService
21
+ from api.db.services.file2document_service import File2DocumentService
22
+ from api.db.services.file_service import FileService
23
+ from api.db.services.knowledgebase_service import KnowledgebaseService
24
+ from api.db.services.llm_service import TenantLLMService, LLMService
25
+ from api.db.services.user_service import TenantService
26
+ from api.settings import RetCode
27
+ from api.utils import get_uuid
28
+ from api.utils.api_utils import (
29
+ get_result,
30
+ token_required,
31
+ get_error_data_result,
32
+ valid,
33
+ get_parser_config,
34
+ )
35
+
36
+
37
+ @manager.route("/datasets", methods=["POST"])
38
+ @token_required
39
+ def create(tenant_id):
40
+ """
41
+ Create a new dataset.
42
+ ---
43
+ tags:
44
+ - Datasets
45
+ security:
46
+ - ApiKeyAuth: []
47
+ parameters:
48
+ - in: header
49
+ name: Authorization
50
+ type: string
51
+ required: true
52
+ description: Bearer token for authentication.
53
+ - in: body
54
+ name: body
55
+ description: Dataset creation parameters.
56
+ required: true
57
+ schema:
58
+ type: object
59
+ required:
60
+ - name
61
+ properties:
62
+ name:
63
+ type: string
64
+ description: Name of the dataset.
65
+ permission:
66
+ type: string
67
+ enum: ['me', 'team']
68
+ description: Dataset permission.
69
+ language:
70
+ type: string
71
+ enum: ['Chinese', 'English']
72
+ description: Language of the dataset.
73
+ chunk_method:
74
+ type: string
75
+ enum: ["naive", "manual", "qa", "table", "paper", "book", "laws",
76
+ "presentation", "picture", "one", "knowledge_graph", "email"]
77
+ description: Chunking method.
78
+ parser_config:
79
+ type: object
80
+ description: Parser configuration.
81
+ responses:
82
+ 200:
83
+ description: Successful operation.
84
+ schema:
85
+ type: object
86
+ properties:
87
+ data:
88
+ type: object
89
+ """
90
+ req = request.json
91
+ e, t = TenantService.get_by_id(tenant_id)
92
+ permission = req.get("permission")
93
+ language = req.get("language")
94
+ chunk_method = req.get("chunk_method")
95
+ parser_config = req.get("parser_config")
96
+ valid_permission = ["me", "team"]
97
+ valid_language = ["Chinese", "English"]
98
+ valid_chunk_method = [
99
+ "naive",
100
+ "manual",
101
+ "qa",
102
+ "table",
103
+ "paper",
104
+ "book",
105
+ "laws",
106
+ "presentation",
107
+ "picture",
108
+ "one",
109
+ "knowledge_graph",
110
+ "email",
111
+ ]
112
+ check_validation = valid(
113
+ permission,
114
+ valid_permission,
115
+ language,
116
+ valid_language,
117
+ chunk_method,
118
+ valid_chunk_method,
119
+ )
120
+ if check_validation:
121
+ return check_validation
122
+ req["parser_config"] = get_parser_config(chunk_method, parser_config)
123
+ if "tenant_id" in req:
124
+ return get_error_data_result(message="`tenant_id` must not be provided")
125
+ if "chunk_count" in req or "document_count" in req:
126
+ return get_error_data_result(
127
+ message="`chunk_count` or `document_count` must not be provided"
128
+ )
129
+ if "name" not in req:
130
+ return get_error_data_result(message="`name` is not empty!")
131
+ req["id"] = get_uuid()
132
+ req["name"] = req["name"].strip()
133
+ if req["name"] == "":
134
+ return get_error_data_result(message="`name` is not empty string!")
135
+ if KnowledgebaseService.query(
136
+ name=req["name"], tenant_id=tenant_id, status=StatusEnum.VALID.value
137
+ ):
138
+ return get_error_data_result(
139
+ message="Duplicated dataset name in creating dataset."
140
+ )
141
+ req["tenant_id"] = req["created_by"] = tenant_id
142
+ if not req.get("embedding_model"):
143
+ req["embedding_model"] = t.embd_id
144
+ else:
145
+ valid_embedding_models = [
146
+ "BAAI/bge-large-zh-v1.5",
147
+ "BAAI/bge-base-en-v1.5",
148
+ "BAAI/bge-large-en-v1.5",
149
+ "BAAI/bge-small-en-v1.5",
150
+ "BAAI/bge-small-zh-v1.5",
151
+ "jinaai/jina-embeddings-v2-base-en",
152
+ "jinaai/jina-embeddings-v2-small-en",
153
+ "nomic-ai/nomic-embed-text-v1.5",
154
+ "sentence-transformers/all-MiniLM-L6-v2",
155
+ "text-embedding-v2",
156
+ "text-embedding-v3",
157
+ "maidalun1020/bce-embedding-base_v1",
158
+ ]
159
+ embd_model = LLMService.query(
160
+ llm_name=req["embedding_model"], model_type="embedding"
161
+ )
162
+ if not embd_model:
163
+ return get_error_data_result(
164
+ f"`embedding_model` {req.get('embedding_model')} doesn't exist"
165
+ )
166
+ if embd_model:
167
+ if req[
168
+ "embedding_model"
169
+ ] not in valid_embedding_models and not TenantLLMService.query(
170
+ tenant_id=tenant_id,
171
+ model_type="embedding",
172
+ llm_name=req.get("embedding_model"),
173
+ ):
174
+ return get_error_data_result(
175
+ f"`embedding_model` {req.get('embedding_model')} doesn't exist"
176
+ )
177
+ key_mapping = {
178
+ "chunk_num": "chunk_count",
179
+ "doc_num": "document_count",
180
+ "parser_id": "chunk_method",
181
+ "embd_id": "embedding_model",
182
+ }
183
+ mapped_keys = {
184
+ new_key: req[old_key]
185
+ for new_key, old_key in key_mapping.items()
186
+ if old_key in req
187
+ }
188
+ req.update(mapped_keys)
189
+ if not KnowledgebaseService.save(**req):
190
+ return get_error_data_result(message="Create dataset error.(Database error)")
191
+ renamed_data = {}
192
+ e, k = KnowledgebaseService.get_by_id(req["id"])
193
+ for key, value in k.to_dict().items():
194
+ new_key = key_mapping.get(key, key)
195
+ renamed_data[new_key] = value
196
+ return get_result(data=renamed_data)
197
+
198
+
199
+ @manager.route("/datasets", methods=["DELETE"])
200
+ @token_required
201
+ def delete(tenant_id):
202
+ """
203
+ Delete datasets.
204
+ ---
205
+ tags:
206
+ - Datasets
207
+ security:
208
+ - ApiKeyAuth: []
209
+ parameters:
210
+ - in: header
211
+ name: Authorization
212
+ type: string
213
+ required: true
214
+ description: Bearer token for authentication.
215
+ - in: body
216
+ name: body
217
+ description: Dataset deletion parameters.
218
+ required: true
219
+ schema:
220
+ type: object
221
+ properties:
222
+ ids:
223
+ type: array
224
+ items:
225
+ type: string
226
+ description: List of dataset IDs to delete.
227
+ responses:
228
+ 200:
229
+ description: Successful operation.
230
+ schema:
231
+ type: object
232
+ """
233
+ req = request.json
234
+ if not req:
235
+ ids = None
236
+ else:
237
+ ids = req.get("ids")
238
+ if not ids:
239
+ id_list = []
240
+ kbs = KnowledgebaseService.query(tenant_id=tenant_id)
241
+ for kb in kbs:
242
+ id_list.append(kb.id)
243
+ else:
244
+ id_list = ids
245
+ for id in id_list:
246
+ kbs = KnowledgebaseService.query(id=id, tenant_id=tenant_id)
247
+ if not kbs:
248
+ return get_error_data_result(message=f"You don't own the dataset {id}")
249
+ for doc in DocumentService.query(kb_id=id):
250
+ if not DocumentService.remove_document(doc, tenant_id):
251
+ return get_error_data_result(
252
+ message="Remove document error.(Database error)"
253
+ )
254
+ f2d = File2DocumentService.get_by_document_id(doc.id)
255
+ FileService.filter_delete(
256
+ [
257
+ File.source_type == FileSource.KNOWLEDGEBASE,
258
+ File.id == f2d[0].file_id,
259
+ ]
260
+ )
261
+ File2DocumentService.delete_by_document_id(doc.id)
262
+ if not KnowledgebaseService.delete_by_id(id):
263
+ return get_error_data_result(message="Delete dataset error.(Database error)")
264
+ return get_result(code=RetCode.SUCCESS)
265
+
266
+
267
+ @manager.route("/datasets/<dataset_id>", methods=["PUT"])
268
+ @token_required
269
+ def update(tenant_id, dataset_id):
270
+ """
271
+ Update a dataset.
272
+ ---
273
+ tags:
274
+ - Datasets
275
+ security:
276
+ - ApiKeyAuth: []
277
+ parameters:
278
+ - in: path
279
+ name: dataset_id
280
+ type: string
281
+ required: true
282
+ description: ID of the dataset to update.
283
+ - in: header
284
+ name: Authorization
285
+ type: string
286
+ required: true
287
+ description: Bearer token for authentication.
288
+ - in: body
289
+ name: body
290
+ description: Dataset update parameters.
291
+ required: true
292
+ schema:
293
+ type: object
294
+ properties:
295
+ name:
296
+ type: string
297
+ description: New name of the dataset.
298
+ permission:
299
+ type: string
300
+ enum: ['me', 'team']
301
+ description: Updated permission.
302
+ language:
303
+ type: string
304
+ enum: ['Chinese', 'English']
305
+ description: Updated language.
306
+ chunk_method:
307
+ type: string
308
+ enum: ["naive", "manual", "qa", "table", "paper", "book", "laws",
309
+ "presentation", "picture", "one", "knowledge_graph", "email"]
310
+ description: Updated chunking method.
311
+ parser_config:
312
+ type: object
313
+ description: Updated parser configuration.
314
+ responses:
315
+ 200:
316
+ description: Successful operation.
317
+ schema:
318
+ type: object
319
+ """
320
+ if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
321
+ return get_error_data_result(message="You don't own the dataset")
322
+ req = request.json
323
+ e, t = TenantService.get_by_id(tenant_id)
324
+ invalid_keys = {"id", "embd_id", "chunk_num", "doc_num", "parser_id"}
325
+ if any(key in req for key in invalid_keys):
326
+ return get_error_data_result(message="The input parameters are invalid.")
327
+ permission = req.get("permission")
328
+ language = req.get("language")
329
+ chunk_method = req.get("chunk_method")
330
+ parser_config = req.get("parser_config")
331
+ valid_permission = ["me", "team"]
332
+ valid_language = ["Chinese", "English"]
333
+ valid_chunk_method = [
334
+ "naive",
335
+ "manual",
336
+ "qa",
337
+ "table",
338
+ "paper",
339
+ "book",
340
+ "laws",
341
+ "presentation",
342
+ "picture",
343
+ "one",
344
+ "knowledge_graph",
345
+ "email",
346
+ ]
347
+ check_validation = valid(
348
+ permission,
349
+ valid_permission,
350
+ language,
351
+ valid_language,
352
+ chunk_method,
353
+ valid_chunk_method,
354
+ )
355
+ if check_validation:
356
+ return check_validation
357
+ if "tenant_id" in req:
358
+ if req["tenant_id"] != tenant_id:
359
+ return get_error_data_result(message="Can't change `tenant_id`.")
360
+ e, kb = KnowledgebaseService.get_by_id(dataset_id)
361
+ if "parser_config" in req:
362
+ temp_dict = kb.parser_config
363
+ temp_dict.update(req["parser_config"])
364
+ req["parser_config"] = temp_dict
365
+ if "chunk_count" in req:
366
+ if req["chunk_count"] != kb.chunk_num:
367
+ return get_error_data_result(message="Can't change `chunk_count`.")
368
+ req.pop("chunk_count")
369
+ if "document_count" in req:
370
+ if req["document_count"] != kb.doc_num:
371
+ return get_error_data_result(message="Can't change `document_count`.")
372
+ req.pop("document_count")
373
+ if "chunk_method" in req:
374
+ if kb.chunk_num != 0 and req["chunk_method"] != kb.parser_id:
375
+ return get_error_data_result(
376
+ message="If `chunk_count` is not 0, `chunk_method` is not changeable."
377
+ )
378
+ req["parser_id"] = req.pop("chunk_method")
379
+ if req["parser_id"] != kb.parser_id:
380
+ if not req.get("parser_config"):
381
+ req["parser_config"] = get_parser_config(chunk_method, parser_config)
382
+ if "embedding_model" in req:
383
+ if kb.chunk_num != 0 and req["embedding_model"] != kb.embd_id:
384
+ return get_error_data_result(
385
+ message="If `chunk_count` is not 0, `embedding_model` is not changeable."
386
+ )
387
+ if not req.get("embedding_model"):
388
+ return get_error_data_result("`embedding_model` can't be empty")
389
+ valid_embedding_models = [
390
+ "BAAI/bge-large-zh-v1.5",
391
+ "BAAI/bge-base-en-v1.5",
392
+ "BAAI/bge-large-en-v1.5",
393
+ "BAAI/bge-small-en-v1.5",
394
+ "BAAI/bge-small-zh-v1.5",
395
+ "jinaai/jina-embeddings-v2-base-en",
396
+ "jinaai/jina-embeddings-v2-small-en",
397
+ "nomic-ai/nomic-embed-text-v1.5",
398
+ "sentence-transformers/all-MiniLM-L6-v2",
399
+ "text-embedding-v2",
400
+ "text-embedding-v3",
401
+ "maidalun1020/bce-embedding-base_v1",
402
+ ]
403
+ embd_model = LLMService.query(
404
+ llm_name=req["embedding_model"], model_type="embedding"
405
+ )
406
+ if not embd_model:
407
+ return get_error_data_result(
408
+ f"`embedding_model` {req.get('embedding_model')} doesn't exist"
409
+ )
410
+ if embd_model:
411
+ if req[
412
+ "embedding_model"
413
+ ] not in valid_embedding_models and not TenantLLMService.query(
414
+ tenant_id=tenant_id,
415
+ model_type="embedding",
416
+ llm_name=req.get("embedding_model"),
417
+ ):
418
+ return get_error_data_result(
419
+ f"`embedding_model` {req.get('embedding_model')} doesn't exist"
420
+ )
421
+ req["embd_id"] = req.pop("embedding_model")
422
+ if "name" in req:
423
+ req["name"] = req["name"].strip()
424
+ if (
425
+ req["name"].lower() != kb.name.lower()
426
+ and len(
427
+ KnowledgebaseService.query(
428
+ name=req["name"], tenant_id=tenant_id, status=StatusEnum.VALID.value
429
+ )
430
+ )
431
+ > 0
432
+ ):
433
+ return get_error_data_result(
434
+ message="Duplicated dataset name in updating dataset."
435
+ )
436
+ if not KnowledgebaseService.update_by_id(kb.id, req):
437
+ return get_error_data_result(message="Update dataset error.(Database error)")
438
+ return get_result(code=RetCode.SUCCESS)
439
+
440
+
441
+ @manager.route("/datasets", methods=["GET"])
442
+ @token_required
443
+ def list(tenant_id):
444
+ """
445
+ List datasets.
446
+ ---
447
+ tags:
448
+ - Datasets
449
+ security:
450
+ - ApiKeyAuth: []
451
+ parameters:
452
+ - in: query
453
+ name: id
454
+ type: string
455
+ required: false
456
+ description: Dataset ID to filter.
457
+ - in: query
458
+ name: name
459
+ type: string
460
+ required: false
461
+ description: Dataset name to filter.
462
+ - in: query
463
+ name: page
464
+ type: integer
465
+ required: false
466
+ default: 1
467
+ description: Page number.
468
+ - in: query
469
+ name: page_size
470
+ type: integer
471
+ required: false
472
+ default: 1024
473
+ description: Number of items per page.
474
+ - in: query
475
+ name: orderby
476
+ type: string
477
+ required: false
478
+ default: "create_time"
479
+ description: Field to order by.
480
+ - in: query
481
+ name: desc
482
+ type: boolean
483
+ required: false
484
+ default: true
485
+ description: Order in descending.
486
+ - in: header
487
+ name: Authorization
488
+ type: string
489
+ required: true
490
+ description: Bearer token for authentication.
491
+ responses:
492
+ 200:
493
+ description: Successful operation.
494
+ schema:
495
+ type: array
496
+ items:
497
+ type: object
498
+ """
499
+ id = request.args.get("id")
500
+ name = request.args.get("name")
501
+ kbs = KnowledgebaseService.query(id=id, name=name, status=1)
502
+ if not kbs:
503
+ return get_error_data_result(message="The dataset doesn't exist")
504
+ page_number = int(request.args.get("page", 1))
505
+ items_per_page = int(request.args.get("page_size", 1024))
506
+ orderby = request.args.get("orderby", "create_time")
507
+ if request.args.get("desc") == "False" or request.args.get("desc") == "false":
508
+ desc = False
509
+ else:
510
+ desc = True
511
+ tenants = TenantService.get_joined_tenants_by_user_id(tenant_id)
512
+ kbs = KnowledgebaseService.get_list(
513
+ [m["tenant_id"] for m in tenants],
514
+ tenant_id,
515
+ page_number,
516
+ items_per_page,
517
+ orderby,
518
+ desc,
519
+ id,
520
+ name,
521
+ )
522
+ renamed_list = []
523
+ for kb in kbs:
524
+ key_mapping = {
525
+ "chunk_num": "chunk_count",
526
+ "doc_num": "document_count",
527
+ "parser_id": "chunk_method",
528
+ "embd_id": "embedding_model",
529
+ }
530
+ renamed_data = {}
531
+ for key, value in kb.items():
532
+ new_key = key_mapping.get(key, key)
533
+ renamed_data[new_key] = value
534
+ renamed_list.append(renamed_data)
535
+ return get_result(data=renamed_list)
api/apps/sdk/dify_retrieval.py CHANGED
@@ -37,10 +37,10 @@ def retrieval(tenant_id):
37
 
38
  e, kb = KnowledgebaseService.get_by_id(kb_id)
39
  if not e:
40
- return build_error_result(error_msg="Knowledgebase not found!", retcode=RetCode.NOT_FOUND)
41
 
42
  if kb.tenant_id != tenant_id:
43
- return build_error_result(error_msg="Knowledgebase not found!", retcode=RetCode.NOT_FOUND)
44
 
45
  embd_mdl = LLMBundle(kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id)
46
 
@@ -71,7 +71,7 @@ def retrieval(tenant_id):
71
  except Exception as e:
72
  if str(e).find("not_found") > 0:
73
  return build_error_result(
74
- error_msg=f'No chunk found! Check the chunk status please!',
75
- retcode=RetCode.NOT_FOUND
76
  )
77
- return build_error_result(error_msg=str(e), retcode=RetCode.SERVER_ERROR)
 
37
 
38
  e, kb = KnowledgebaseService.get_by_id(kb_id)
39
  if not e:
40
+ return build_error_result(message="Knowledgebase not found!", code=RetCode.NOT_FOUND)
41
 
42
  if kb.tenant_id != tenant_id:
43
+ return build_error_result(message="Knowledgebase not found!", code=RetCode.NOT_FOUND)
44
 
45
  embd_mdl = LLMBundle(kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id)
46
 
 
71
  except Exception as e:
72
  if str(e).find("not_found") > 0:
73
  return build_error_result(
74
+ message='No chunk found! Check the chunk status please!',
75
+ code=RetCode.NOT_FOUND
76
  )
77
+ return build_error_result(message=str(e), code=RetCode.SERVER_ERROR)
api/apps/sdk/doc.py CHANGED
@@ -110,13 +110,13 @@ def upload(dataset_id, tenant_id):
110
  """
111
  if "file" not in request.files:
112
  return get_error_data_result(
113
- retmsg="No file part!", retcode=RetCode.ARGUMENT_ERROR
114
  )
115
  file_objs = request.files.getlist("file")
116
  for file_obj in file_objs:
117
  if file_obj.filename == "":
118
  return get_result(
119
- retmsg="No file selected!", retcode=RetCode.ARGUMENT_ERROR
120
  )
121
  # total size
122
  total_size = 0
@@ -127,15 +127,15 @@ def upload(dataset_id, tenant_id):
127
  MAX_TOTAL_FILE_SIZE = 10 * 1024 * 1024
128
  if total_size > MAX_TOTAL_FILE_SIZE:
129
  return get_result(
130
- retmsg=f"Total file size exceeds 10MB limit! ({total_size / (1024 * 1024):.2f} MB)",
131
- retcode=RetCode.ARGUMENT_ERROR,
132
  )
133
  e, kb = KnowledgebaseService.get_by_id(dataset_id)
134
  if not e:
135
  raise LookupError(f"Can't find the dataset with ID {dataset_id}!")
136
  err, files = FileService.upload_document(kb, file_objs, tenant_id)
137
  if err:
138
- return get_result(retmsg="\n".join(err), retcode=RetCode.SERVER_ERROR)
139
  # rename key's name
140
  renamed_doc_list = []
141
  for file in files:
@@ -205,20 +205,20 @@ def update_doc(tenant_id, dataset_id, document_id):
205
  """
206
  req = request.json
207
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
208
- return get_error_data_result(retmsg="You don't own the dataset.")
209
  doc = DocumentService.query(kb_id=dataset_id, id=document_id)
210
  if not doc:
211
- return get_error_data_result(retmsg="The dataset doesn't own the document.")
212
  doc = doc[0]
213
  if "chunk_count" in req:
214
  if req["chunk_count"] != doc.chunk_num:
215
- return get_error_data_result(retmsg="Can't change `chunk_count`.")
216
  if "token_count" in req:
217
  if req["token_count"] != doc.token_num:
218
- return get_error_data_result(retmsg="Can't change `token_count`.")
219
  if "progress" in req:
220
  if req["progress"] != doc.progress:
221
- return get_error_data_result(retmsg="Can't change `progress`.")
222
 
223
  if "name" in req and req["name"] != doc.name:
224
  if (
@@ -226,16 +226,16 @@ def update_doc(tenant_id, dataset_id, document_id):
226
  != pathlib.Path(doc.name.lower()).suffix
227
  ):
228
  return get_result(
229
- retmsg="The extension of file can't be changed",
230
- retcode=RetCode.ARGUMENT_ERROR,
231
  )
232
  for d in DocumentService.query(name=req["name"], kb_id=doc.kb_id):
233
  if d.name == req["name"]:
234
  return get_error_data_result(
235
- retmsg="Duplicated document name in the same dataset."
236
  )
237
  if not DocumentService.update_by_id(document_id, {"name": req["name"]}):
238
- return get_error_data_result(retmsg="Database error (Document rename)!")
239
 
240
  informs = File2DocumentService.get_by_document_id(document_id)
241
  if informs:
@@ -266,7 +266,7 @@ def update_doc(tenant_id, dataset_id, document_id):
266
  return get_result()
267
 
268
  if doc.type == FileType.VISUAL or re.search(r"\.(ppt|pptx|pages)$", doc.name):
269
- return get_error_data_result(retmsg="Not supported yet!")
270
 
271
  e = DocumentService.update_by_id(
272
  doc.id,
@@ -278,7 +278,7 @@ def update_doc(tenant_id, dataset_id, document_id):
278
  },
279
  )
280
  if not e:
281
- return get_error_data_result(retmsg="Document not found!")
282
  req["parser_config"] = get_parser_config(
283
  req["chunk_method"], req.get("parser_config")
284
  )
@@ -292,7 +292,7 @@ def update_doc(tenant_id, dataset_id, document_id):
292
  doc.process_duation * -1,
293
  )
294
  if not e:
295
- return get_error_data_result(retmsg="Document not found!")
296
  ELASTICSEARCH.deleteByQuery(
297
  Q("match", doc_id=doc.id), idxnm=search.index_name(tenant_id)
298
  )
@@ -339,11 +339,11 @@ def download(tenant_id, dataset_id, document_id):
339
  type: object
340
  """
341
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
342
- return get_error_data_result(retmsg=f"You do not own the dataset {dataset_id}.")
343
  doc = DocumentService.query(kb_id=dataset_id, id=document_id)
344
  if not doc:
345
  return get_error_data_result(
346
- retmsg=f"The dataset not own the document {document_id}."
347
  )
348
  # The process of downloading
349
  doc_id, doc_location = File2DocumentService.get_storage_address(
@@ -451,13 +451,13 @@ def list_docs(dataset_id, tenant_id):
451
  description: Processing status.
452
  """
453
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
454
- return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}. ")
455
  id = request.args.get("id")
456
  name = request.args.get("name")
457
  if not DocumentService.query(id=id, kb_id=dataset_id):
458
- return get_error_data_result(retmsg=f"You don't own the document {id}.")
459
  if not DocumentService.query(name=name, kb_id=dataset_id):
460
- return get_error_data_result(retmsg=f"You don't own the document {name}.")
461
  page = int(request.args.get("page", 1))
462
  keywords = request.args.get("keywords", "")
463
  page_size = int(request.args.get("page_size", 1024))
@@ -538,7 +538,7 @@ def delete(tenant_id, dataset_id):
538
  type: object
539
  """
540
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
541
- return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}. ")
542
  req = request.json
543
  if not req:
544
  doc_ids = None
@@ -559,16 +559,16 @@ def delete(tenant_id, dataset_id):
559
  try:
560
  e, doc = DocumentService.get_by_id(doc_id)
561
  if not e:
562
- return get_error_data_result(retmsg="Document not found!")
563
  tenant_id = DocumentService.get_tenant_id(doc_id)
564
  if not tenant_id:
565
- return get_error_data_result(retmsg="Tenant not found!")
566
 
567
  b, n = File2DocumentService.get_storage_address(doc_id=doc_id)
568
 
569
  if not DocumentService.remove_document(doc, tenant_id):
570
  return get_error_data_result(
571
- retmsg="Database error (Document removal)!"
572
  )
573
 
574
  f2d = File2DocumentService.get_by_document_id(doc_id)
@@ -585,7 +585,7 @@ def delete(tenant_id, dataset_id):
585
  errors += str(e)
586
 
587
  if errors:
588
- return get_result(retmsg=errors, retcode=RetCode.SERVER_ERROR)
589
 
590
  return get_result()
591
 
@@ -630,14 +630,14 @@ def parse(tenant_id, dataset_id):
630
  type: object
631
  """
632
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
633
- return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}.")
634
  req = request.json
635
  if not req.get("document_ids"):
636
  return get_error_data_result("`document_ids` is required")
637
  for id in req["document_ids"]:
638
  doc = DocumentService.query(id=id, kb_id=dataset_id)
639
  if not doc:
640
- return get_error_data_result(retmsg=f"You don't own the document {id}.")
641
  if doc[0].progress != 0.0:
642
  return get_error_data_result(
643
  "Can't stop parsing document with progress at 0 or 100"
@@ -699,14 +699,14 @@ def stop_parsing(tenant_id, dataset_id):
699
  type: object
700
  """
701
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
702
- return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}.")
703
  req = request.json
704
  if not req.get("document_ids"):
705
  return get_error_data_result("`document_ids` is required")
706
  for id in req["document_ids"]:
707
  doc = DocumentService.query(id=id, kb_id=dataset_id)
708
  if not doc:
709
- return get_error_data_result(retmsg=f"You don't own the document {id}.")
710
  if int(doc[0].progress) == 1 or int(doc[0].progress) == 0:
711
  return get_error_data_result(
712
  "Can't stop parsing document with progress at 0 or 1"
@@ -793,11 +793,11 @@ def list_chunks(tenant_id, dataset_id, document_id):
793
  description: Document details.
794
  """
795
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
796
- return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}.")
797
  doc = DocumentService.query(id=document_id, kb_id=dataset_id)
798
  if not doc:
799
  return get_error_data_result(
800
- retmsg=f"You don't own the document {document_id}."
801
  )
802
  doc = doc[0]
803
  req = request.args
@@ -965,16 +965,16 @@ def add_chunk(tenant_id, dataset_id, document_id):
965
  description: Important keywords.
966
  """
967
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
968
- return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}.")
969
  doc = DocumentService.query(id=document_id, kb_id=dataset_id)
970
  if not doc:
971
  return get_error_data_result(
972
- retmsg=f"You don't own the document {document_id}."
973
  )
974
  doc = doc[0]
975
  req = request.json
976
  if not req.get("content"):
977
- return get_error_data_result(retmsg="`content` is required")
978
  if "important_keywords" in req:
979
  if type(req["important_keywords"]) != list:
980
  return get_error_data_result(
@@ -1078,11 +1078,11 @@ def rm_chunk(tenant_id, dataset_id, document_id):
1078
  type: object
1079
  """
1080
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
1081
- return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}.")
1082
  doc = DocumentService.query(id=document_id, kb_id=dataset_id)
1083
  if not doc:
1084
  return get_error_data_result(
1085
- retmsg=f"You don't own the document {document_id}."
1086
  )
1087
  doc = doc[0]
1088
  req = request.json
@@ -1104,7 +1104,7 @@ def rm_chunk(tenant_id, dataset_id, document_id):
1104
  if not ELASTICSEARCH.deleteByQuery(
1105
  Q("ids", values=chunk_list), search.index_name(tenant_id)
1106
  ):
1107
- return get_error_data_result(retmsg="Index updating failure")
1108
  deleted_chunk_ids = chunk_list
1109
  chunk_number = len(deleted_chunk_ids)
1110
  DocumentService.decrement_chunk_num(doc.id, doc.kb_id, 1, chunk_number, 0)
@@ -1170,14 +1170,14 @@ def update_chunk(tenant_id, dataset_id, document_id, chunk_id):
1170
  """
1171
  try:
1172
  res = ELASTICSEARCH.get(chunk_id, search.index_name(tenant_id))
1173
- except Exception as e:
1174
  return get_error_data_result(f"Can't find this chunk {chunk_id}")
1175
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
1176
- return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}.")
1177
  doc = DocumentService.query(id=document_id, kb_id=dataset_id)
1178
  if not doc:
1179
  return get_error_data_result(
1180
- retmsg=f"You don't own the document {document_id}."
1181
  )
1182
  doc = doc[0]
1183
  query = {
@@ -1210,7 +1210,7 @@ def update_chunk(tenant_id, dataset_id, document_id, chunk_id):
1210
  arr = [t for t in re.split(r"[\n\t]", d["content_with_weight"]) if len(t) > 1]
1211
  if len(arr) != 2:
1212
  return get_error_data_result(
1213
- retmsg="Q&A must be separated by TAB/ENTER key."
1214
  )
1215
  q, a = rmPrefix(arr[0]), rmPrefix(arr[1])
1216
  d = beAdoc(
@@ -1317,8 +1317,8 @@ def retrieval_test(tenant_id):
1317
  embd_nms = list(set([kb.embd_id for kb in kbs]))
1318
  if len(embd_nms) != 1:
1319
  return get_result(
1320
- retmsg='Datasets use different embedding models."',
1321
- retcode=RetCode.AUTHENTICATION_ERROR,
1322
  )
1323
  if "question" not in req:
1324
  return get_error_data_result("`question` is required.")
@@ -1344,7 +1344,7 @@ def retrieval_test(tenant_id):
1344
  try:
1345
  e, kb = KnowledgebaseService.get_by_id(kb_ids[0])
1346
  if not e:
1347
- return get_error_data_result(retmsg="Dataset not found!")
1348
  embd_mdl = TenantLLMService.model_instance(
1349
  kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id
1350
  )
@@ -1398,7 +1398,7 @@ def retrieval_test(tenant_id):
1398
  except Exception as e:
1399
  if str(e).find("not_found") > 0:
1400
  return get_result(
1401
- retmsg=f"No chunk found! Check the chunk status please!",
1402
- retcode=RetCode.DATA_ERROR,
1403
  )
1404
  return server_error_response(e)
 
110
  """
111
  if "file" not in request.files:
112
  return get_error_data_result(
113
+ message="No file part!", code=RetCode.ARGUMENT_ERROR
114
  )
115
  file_objs = request.files.getlist("file")
116
  for file_obj in file_objs:
117
  if file_obj.filename == "":
118
  return get_result(
119
+ message="No file selected!", code=RetCode.ARGUMENT_ERROR
120
  )
121
  # total size
122
  total_size = 0
 
127
  MAX_TOTAL_FILE_SIZE = 10 * 1024 * 1024
128
  if total_size > MAX_TOTAL_FILE_SIZE:
129
  return get_result(
130
+ message=f"Total file size exceeds 10MB limit! ({total_size / (1024 * 1024):.2f} MB)",
131
+ code=RetCode.ARGUMENT_ERROR,
132
  )
133
  e, kb = KnowledgebaseService.get_by_id(dataset_id)
134
  if not e:
135
  raise LookupError(f"Can't find the dataset with ID {dataset_id}!")
136
  err, files = FileService.upload_document(kb, file_objs, tenant_id)
137
  if err:
138
+ return get_result(message="\n".join(err), code=RetCode.SERVER_ERROR)
139
  # rename key's name
140
  renamed_doc_list = []
141
  for file in files:
 
205
  """
206
  req = request.json
207
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
208
+ return get_error_data_result(message="You don't own the dataset.")
209
  doc = DocumentService.query(kb_id=dataset_id, id=document_id)
210
  if not doc:
211
+ return get_error_data_result(message="The dataset doesn't own the document.")
212
  doc = doc[0]
213
  if "chunk_count" in req:
214
  if req["chunk_count"] != doc.chunk_num:
215
+ return get_error_data_result(message="Can't change `chunk_count`.")
216
  if "token_count" in req:
217
  if req["token_count"] != doc.token_num:
218
+ return get_error_data_result(message="Can't change `token_count`.")
219
  if "progress" in req:
220
  if req["progress"] != doc.progress:
221
+ return get_error_data_result(message="Can't change `progress`.")
222
 
223
  if "name" in req and req["name"] != doc.name:
224
  if (
 
226
  != pathlib.Path(doc.name.lower()).suffix
227
  ):
228
  return get_result(
229
+ message="The extension of file can't be changed",
230
+ code=RetCode.ARGUMENT_ERROR,
231
  )
232
  for d in DocumentService.query(name=req["name"], kb_id=doc.kb_id):
233
  if d.name == req["name"]:
234
  return get_error_data_result(
235
+ message="Duplicated document name in the same dataset."
236
  )
237
  if not DocumentService.update_by_id(document_id, {"name": req["name"]}):
238
+ return get_error_data_result(message="Database error (Document rename)!")
239
 
240
  informs = File2DocumentService.get_by_document_id(document_id)
241
  if informs:
 
266
  return get_result()
267
 
268
  if doc.type == FileType.VISUAL or re.search(r"\.(ppt|pptx|pages)$", doc.name):
269
+ return get_error_data_result(message="Not supported yet!")
270
 
271
  e = DocumentService.update_by_id(
272
  doc.id,
 
278
  },
279
  )
280
  if not e:
281
+ return get_error_data_result(message="Document not found!")
282
  req["parser_config"] = get_parser_config(
283
  req["chunk_method"], req.get("parser_config")
284
  )
 
292
  doc.process_duation * -1,
293
  )
294
  if not e:
295
+ return get_error_data_result(message="Document not found!")
296
  ELASTICSEARCH.deleteByQuery(
297
  Q("match", doc_id=doc.id), idxnm=search.index_name(tenant_id)
298
  )
 
339
  type: object
340
  """
341
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
342
+ return get_error_data_result(message=f"You do not own the dataset {dataset_id}.")
343
  doc = DocumentService.query(kb_id=dataset_id, id=document_id)
344
  if not doc:
345
  return get_error_data_result(
346
+ message=f"The dataset not own the document {document_id}."
347
  )
348
  # The process of downloading
349
  doc_id, doc_location = File2DocumentService.get_storage_address(
 
451
  description: Processing status.
452
  """
453
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
454
+ return get_error_data_result(message=f"You don't own the dataset {dataset_id}. ")
455
  id = request.args.get("id")
456
  name = request.args.get("name")
457
  if not DocumentService.query(id=id, kb_id=dataset_id):
458
+ return get_error_data_result(message=f"You don't own the document {id}.")
459
  if not DocumentService.query(name=name, kb_id=dataset_id):
460
+ return get_error_data_result(message=f"You don't own the document {name}.")
461
  page = int(request.args.get("page", 1))
462
  keywords = request.args.get("keywords", "")
463
  page_size = int(request.args.get("page_size", 1024))
 
538
  type: object
539
  """
540
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
541
+ return get_error_data_result(message=f"You don't own the dataset {dataset_id}. ")
542
  req = request.json
543
  if not req:
544
  doc_ids = None
 
559
  try:
560
  e, doc = DocumentService.get_by_id(doc_id)
561
  if not e:
562
+ return get_error_data_result(message="Document not found!")
563
  tenant_id = DocumentService.get_tenant_id(doc_id)
564
  if not tenant_id:
565
+ return get_error_data_result(message="Tenant not found!")
566
 
567
  b, n = File2DocumentService.get_storage_address(doc_id=doc_id)
568
 
569
  if not DocumentService.remove_document(doc, tenant_id):
570
  return get_error_data_result(
571
+ message="Database error (Document removal)!"
572
  )
573
 
574
  f2d = File2DocumentService.get_by_document_id(doc_id)
 
585
  errors += str(e)
586
 
587
  if errors:
588
+ return get_result(message=errors, code=RetCode.SERVER_ERROR)
589
 
590
  return get_result()
591
 
 
630
  type: object
631
  """
632
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
633
+ return get_error_data_result(message=f"You don't own the dataset {dataset_id}.")
634
  req = request.json
635
  if not req.get("document_ids"):
636
  return get_error_data_result("`document_ids` is required")
637
  for id in req["document_ids"]:
638
  doc = DocumentService.query(id=id, kb_id=dataset_id)
639
  if not doc:
640
+ return get_error_data_result(message=f"You don't own the document {id}.")
641
  if doc[0].progress != 0.0:
642
  return get_error_data_result(
643
  "Can't stop parsing document with progress at 0 or 100"
 
699
  type: object
700
  """
701
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
702
+ return get_error_data_result(message=f"You don't own the dataset {dataset_id}.")
703
  req = request.json
704
  if not req.get("document_ids"):
705
  return get_error_data_result("`document_ids` is required")
706
  for id in req["document_ids"]:
707
  doc = DocumentService.query(id=id, kb_id=dataset_id)
708
  if not doc:
709
+ return get_error_data_result(message=f"You don't own the document {id}.")
710
  if int(doc[0].progress) == 1 or int(doc[0].progress) == 0:
711
  return get_error_data_result(
712
  "Can't stop parsing document with progress at 0 or 1"
 
793
  description: Document details.
794
  """
795
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
796
+ return get_error_data_result(message=f"You don't own the dataset {dataset_id}.")
797
  doc = DocumentService.query(id=document_id, kb_id=dataset_id)
798
  if not doc:
799
  return get_error_data_result(
800
+ message=f"You don't own the document {document_id}."
801
  )
802
  doc = doc[0]
803
  req = request.args
 
965
  description: Important keywords.
966
  """
967
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
968
+ return get_error_data_result(message=f"You don't own the dataset {dataset_id}.")
969
  doc = DocumentService.query(id=document_id, kb_id=dataset_id)
970
  if not doc:
971
  return get_error_data_result(
972
+ message=f"You don't own the document {document_id}."
973
  )
974
  doc = doc[0]
975
  req = request.json
976
  if not req.get("content"):
977
+ return get_error_data_result(message="`content` is required")
978
  if "important_keywords" in req:
979
  if type(req["important_keywords"]) != list:
980
  return get_error_data_result(
 
1078
  type: object
1079
  """
1080
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
1081
+ return get_error_data_result(message=f"You don't own the dataset {dataset_id}.")
1082
  doc = DocumentService.query(id=document_id, kb_id=dataset_id)
1083
  if not doc:
1084
  return get_error_data_result(
1085
+ message=f"You don't own the document {document_id}."
1086
  )
1087
  doc = doc[0]
1088
  req = request.json
 
1104
  if not ELASTICSEARCH.deleteByQuery(
1105
  Q("ids", values=chunk_list), search.index_name(tenant_id)
1106
  ):
1107
+ return get_error_data_result(message="Index updating failure")
1108
  deleted_chunk_ids = chunk_list
1109
  chunk_number = len(deleted_chunk_ids)
1110
  DocumentService.decrement_chunk_num(doc.id, doc.kb_id, 1, chunk_number, 0)
 
1170
  """
1171
  try:
1172
  res = ELASTICSEARCH.get(chunk_id, search.index_name(tenant_id))
1173
+ except Exception:
1174
  return get_error_data_result(f"Can't find this chunk {chunk_id}")
1175
  if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id):
1176
+ return get_error_data_result(message=f"You don't own the dataset {dataset_id}.")
1177
  doc = DocumentService.query(id=document_id, kb_id=dataset_id)
1178
  if not doc:
1179
  return get_error_data_result(
1180
+ message=f"You don't own the document {document_id}."
1181
  )
1182
  doc = doc[0]
1183
  query = {
 
1210
  arr = [t for t in re.split(r"[\n\t]", d["content_with_weight"]) if len(t) > 1]
1211
  if len(arr) != 2:
1212
  return get_error_data_result(
1213
+ message="Q&A must be separated by TAB/ENTER key."
1214
  )
1215
  q, a = rmPrefix(arr[0]), rmPrefix(arr[1])
1216
  d = beAdoc(
 
1317
  embd_nms = list(set([kb.embd_id for kb in kbs]))
1318
  if len(embd_nms) != 1:
1319
  return get_result(
1320
+ message='Datasets use different embedding models."',
1321
+ code=RetCode.AUTHENTICATION_ERROR,
1322
  )
1323
  if "question" not in req:
1324
  return get_error_data_result("`question` is required.")
 
1344
  try:
1345
  e, kb = KnowledgebaseService.get_by_id(kb_ids[0])
1346
  if not e:
1347
+ return get_error_data_result(message="Dataset not found!")
1348
  embd_mdl = TenantLLMService.model_instance(
1349
  kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id
1350
  )
 
1398
  except Exception as e:
1399
  if str(e).find("not_found") > 0:
1400
  return get_result(
1401
+ message="No chunk found! Check the chunk status please!",
1402
+ code=RetCode.DATA_ERROR,
1403
  )
1404
  return server_error_response(e)
api/apps/sdk/session.py CHANGED
@@ -1,394 +1,394 @@
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
- import json
17
- from functools import partial
18
- from uuid import uuid4
19
-
20
- from flask import request, Response
21
-
22
- from agent.canvas import Canvas
23
- from api.db import StatusEnum
24
- from api.db.db_models import API4Conversation
25
- from api.db.services.api_service import API4ConversationService
26
- from api.db.services.canvas_service import UserCanvasService
27
- from api.db.services.dialog_service import DialogService, ConversationService, chat
28
- from api.utils import get_uuid
29
- from api.utils.api_utils import get_error_data_result
30
- from api.utils.api_utils import get_result, token_required
31
-
32
-
33
- @manager.route('/chats/<chat_id>/sessions', methods=['POST'])
34
- @token_required
35
- def create(tenant_id,chat_id):
36
- req = request.json
37
- req["dialog_id"] = chat_id
38
- dia = DialogService.query(tenant_id=tenant_id, id=req["dialog_id"], status=StatusEnum.VALID.value)
39
- if not dia:
40
- return get_error_data_result(retmsg="You do not own the assistant.")
41
- conv = {
42
- "id": get_uuid(),
43
- "dialog_id": req["dialog_id"],
44
- "name": req.get("name", "New session"),
45
- "message": [{"role": "assistant", "content": "Hi! I am your assistant,can I help you?"}]
46
- }
47
- if not conv.get("name"):
48
- return get_error_data_result(retmsg="`name` can not be empty.")
49
- ConversationService.save(**conv)
50
- e, conv = ConversationService.get_by_id(conv["id"])
51
- if not e:
52
- return get_error_data_result(retmsg="Fail to create a session!")
53
- conv = conv.to_dict()
54
- conv['messages'] = conv.pop("message")
55
- conv["chat_id"] = conv.pop("dialog_id")
56
- del conv["reference"]
57
- return get_result(data=conv)
58
-
59
-
60
- @manager.route('/agents/<agent_id>/sessions', methods=['POST'])
61
- @token_required
62
- def create_agent_session(tenant_id, agent_id):
63
- req = request.json
64
- e, cvs = UserCanvasService.get_by_id(agent_id)
65
- if not e:
66
- return get_error_data_result("Agent not found.")
67
- if cvs.user_id != tenant_id:
68
- return get_error_data_result(retmsg="You do not own the agent.")
69
-
70
- if not isinstance(cvs.dsl, str):
71
- cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False)
72
-
73
- canvas = Canvas(cvs.dsl, tenant_id)
74
- conv = {
75
- "id": get_uuid(),
76
- "dialog_id": cvs.id,
77
- "user_id": req.get("user_id", ""),
78
- "message": [{"role": "assistant", "content": canvas.get_prologue()}],
79
- "source": "agent"
80
- }
81
- API4ConversationService.save(**conv)
82
- return get_result(data=conv)
83
-
84
-
85
- @manager.route('/chats/<chat_id>/sessions/<session_id>', methods=['PUT'])
86
- @token_required
87
- def update(tenant_id,chat_id,session_id):
88
- req = request.json
89
- req["dialog_id"] = chat_id
90
- conv_id = session_id
91
- conv = ConversationService.query(id=conv_id,dialog_id=chat_id)
92
- if not conv:
93
- return get_error_data_result(retmsg="Session does not exist")
94
- if not DialogService.query(id=chat_id, tenant_id=tenant_id, status=StatusEnum.VALID.value):
95
- return get_error_data_result(retmsg="You do not own the session")
96
- if "message" in req or "messages" in req:
97
- return get_error_data_result(retmsg="`message` can not be change")
98
- if "reference" in req:
99
- return get_error_data_result(retmsg="`reference` can not be change")
100
- if "name" in req and not req.get("name"):
101
- return get_error_data_result(retmsg="`name` can not be empty.")
102
- if not ConversationService.update_by_id(conv_id, req):
103
- return get_error_data_result(retmsg="Session updates error")
104
- return get_result()
105
-
106
-
107
- @manager.route('/chats/<chat_id>/completions', methods=['POST'])
108
- @token_required
109
- def completion(tenant_id, chat_id):
110
- req = request.json
111
- if not req.get("session_id"):
112
- conv = {
113
- "id": get_uuid(),
114
- "dialog_id": chat_id,
115
- "name": req.get("name", "New session"),
116
- "message": [{"role": "assistant", "content": "Hi! I am your assistant,can I help you?"}]
117
- }
118
- if not conv.get("name"):
119
- return get_error_data_result(retmsg="`name` can not be empty.")
120
- ConversationService.save(**conv)
121
- e, conv = ConversationService.get_by_id(conv["id"])
122
- session_id=conv.id
123
- else:
124
- session_id = req.get("session_id")
125
- if not req.get("question"):
126
- return get_error_data_result(retmsg="Please input your question.")
127
- conv = ConversationService.query(id=session_id,dialog_id=chat_id)
128
- if not conv:
129
- return get_error_data_result(retmsg="Session does not exist")
130
- conv = conv[0]
131
- if not DialogService.query(id=chat_id, tenant_id=tenant_id, status=StatusEnum.VALID.value):
132
- return get_error_data_result(retmsg="You do not own the chat")
133
- msg = []
134
- question = {
135
- "content": req.get("question"),
136
- "role": "user",
137
- "id": str(uuid4())
138
- }
139
- conv.message.append(question)
140
- for m in conv.message:
141
- if m["role"] == "system": continue
142
- if m["role"] == "assistant" and not msg: continue
143
- msg.append(m)
144
- message_id = msg[-1].get("id")
145
- e, dia = DialogService.get_by_id(conv.dialog_id)
146
-
147
- if not conv.reference:
148
- conv.reference = []
149
- conv.message.append({"role": "assistant", "content": "", "id": message_id})
150
- conv.reference.append({"chunks": [], "doc_aggs": []})
151
-
152
- def fillin_conv(ans):
153
- nonlocal conv, message_id
154
- if not conv.reference:
155
- conv.reference.append(ans["reference"])
156
- else:
157
- conv.reference[-1] = ans["reference"]
158
- conv.message[-1] = {"role": "assistant", "content": ans["answer"],
159
- "id": message_id, "prompt": ans.get("prompt", "")}
160
- ans["id"] = message_id
161
- ans["session_id"]=session_id
162
-
163
- def stream():
164
- nonlocal dia, msg, req, conv
165
- try:
166
- for ans in chat(dia, msg, **req):
167
- fillin_conv(ans)
168
- yield "data:" + json.dumps({"code": 0, "data": ans}, ensure_ascii=False) + "\n\n"
169
- ConversationService.update_by_id(conv.id, conv.to_dict())
170
- except Exception as e:
171
- yield "data:" + json.dumps({"code": 500, "message": str(e),
172
- "data": {"answer": "**ERROR**: " + str(e),"reference": []}},
173
- ensure_ascii=False) + "\n\n"
174
- yield "data:" + json.dumps({"code": 0, "data": True}, ensure_ascii=False) + "\n\n"
175
-
176
- if req.get("stream", True):
177
- resp = Response(stream(), mimetype="text/event-stream")
178
- resp.headers.add_header("Cache-control", "no-cache")
179
- resp.headers.add_header("Connection", "keep-alive")
180
- resp.headers.add_header("X-Accel-Buffering", "no")
181
- resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
182
- return resp
183
-
184
- else:
185
- answer = None
186
- for ans in chat(dia, msg, **req):
187
- answer = ans
188
- fillin_conv(ans)
189
- ConversationService.update_by_id(conv.id, conv.to_dict())
190
- break
191
- return get_result(data=answer)
192
-
193
-
194
- @manager.route('/agents/<agent_id>/completions', methods=['POST'])
195
- @token_required
196
- def agent_completion(tenant_id, agent_id):
197
- req = request.json
198
- e, cvs = UserCanvasService.get_by_id(agent_id)
199
- if not e:
200
- return get_error_data_result("Agent not found.")
201
- if cvs.user_id != tenant_id:
202
- return get_error_data_result(retmsg="You do not own the agent.")
203
- if not isinstance(cvs.dsl, str):
204
- cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False)
205
-
206
- canvas = Canvas(cvs.dsl, tenant_id)
207
-
208
- msg = []
209
- for m in req["messages"]:
210
- if m["role"] == "system":
211
- continue
212
- if m["role"] == "assistant" and not msg:
213
- continue
214
- msg.append(m)
215
- if not msg[-1].get("id"): msg[-1]["id"] = get_uuid()
216
- message_id = msg[-1]["id"]
217
-
218
- if not req.get("session_id"):
219
- session_id = get_uuid()
220
- conv = {
221
- "id": session_id,
222
- "dialog_id": cvs.id,
223
- "user_id": req.get("user_id", ""),
224
- "message": [{"role": "assistant", "content": canvas.get_prologue()}],
225
- "source": "agent"
226
- }
227
- API4ConversationService.save(**conv)
228
- conv = API4Conversation(**conv)
229
- else:
230
- session_id = req.get("session_id")
231
- e, conv = API4ConversationService.get_by_id(req["session_id"])
232
- if not e:
233
- return get_error_data_result(retmsg="Session not found!")
234
-
235
- if "quote" not in req: req["quote"] = False
236
- stream = req.get("stream", True)
237
-
238
- def fillin_conv(ans):
239
- nonlocal conv, message_id
240
- if not conv.reference:
241
- conv.reference.append(ans["reference"])
242
- else:
243
- conv.reference[-1] = ans["reference"]
244
- conv.message[-1] = {"role": "assistant", "content": ans["answer"], "id": message_id}
245
- ans["id"] = message_id
246
- ans["session_id"] = session_id
247
-
248
- def rename_field(ans):
249
- reference = ans['reference']
250
- if not isinstance(reference, dict):
251
- return
252
- for chunk_i in reference.get('chunks', []):
253
- if 'docnm_kwd' in chunk_i:
254
- chunk_i['doc_name'] = chunk_i['docnm_kwd']
255
- chunk_i.pop('docnm_kwd')
256
- conv.message.append(msg[-1])
257
-
258
- if not conv.reference:
259
- conv.reference = []
260
- conv.message.append({"role": "assistant", "content": "", "id": message_id})
261
- conv.reference.append({"chunks": [], "doc_aggs": []})
262
-
263
- final_ans = {"reference": [], "content": ""}
264
-
265
- canvas.messages.append(msg[-1])
266
- canvas.add_user_input(msg[-1]["content"])
267
- answer = canvas.run(stream=stream)
268
-
269
- assert answer is not None, "Nothing. Is it over?"
270
-
271
- if stream:
272
- assert isinstance(answer, partial), "Nothing. Is it over?"
273
-
274
- def sse():
275
- nonlocal answer, cvs, conv
276
- try:
277
- for ans in answer():
278
- for k in ans.keys():
279
- final_ans[k] = ans[k]
280
- ans = {"answer": ans["content"], "reference": ans.get("reference", [])}
281
- fillin_conv(ans)
282
- rename_field(ans)
283
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans},
284
- ensure_ascii=False) + "\n\n"
285
-
286
- canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id})
287
- if final_ans.get("reference"):
288
- canvas.reference.append(final_ans["reference"])
289
- cvs.dsl = json.loads(str(canvas))
290
- API4ConversationService.append_message(conv.id, conv.to_dict())
291
- except Exception as e:
292
- yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e),
293
- "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
294
- ensure_ascii=False) + "\n\n"
295
- yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n"
296
-
297
- resp = Response(sse(), mimetype="text/event-stream")
298
- resp.headers.add_header("Cache-control", "no-cache")
299
- resp.headers.add_header("Connection", "keep-alive")
300
- resp.headers.add_header("X-Accel-Buffering", "no")
301
- resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
302
- return resp
303
-
304
- final_ans["content"] = "\n".join(answer["content"]) if "content" in answer else ""
305
- canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id})
306
- if final_ans.get("reference"):
307
- canvas.reference.append(final_ans["reference"])
308
- cvs.dsl = json.loads(str(canvas))
309
-
310
- result = {"answer": final_ans["content"], "reference": final_ans.get("reference", [])}
311
- fillin_conv(result)
312
- API4ConversationService.append_message(conv.id, conv.to_dict())
313
- rename_field(result)
314
- return get_result(data=result)
315
-
316
-
317
- @manager.route('/chats/<chat_id>/sessions', methods=['GET'])
318
- @token_required
319
- def list(chat_id,tenant_id):
320
- if not DialogService.query(tenant_id=tenant_id, id=chat_id, status=StatusEnum.VALID.value):
321
- return get_error_data_result(retmsg=f"You don't own the assistant {chat_id}.")
322
- id = request.args.get("id")
323
- name = request.args.get("name")
324
- page_number = int(request.args.get("page", 1))
325
- items_per_page = int(request.args.get("page_size", 1024))
326
- orderby = request.args.get("orderby", "create_time")
327
- if request.args.get("desc") == "False" or request.args.get("desc") == "false":
328
- desc = False
329
- else:
330
- desc = True
331
- convs = ConversationService.get_list(chat_id,page_number,items_per_page,orderby,desc,id,name)
332
- if not convs:
333
- return get_result(data=[])
334
- for conv in convs:
335
- conv['messages'] = conv.pop("message")
336
- infos = conv["messages"]
337
- for info in infos:
338
- if "prompt" in info:
339
- info.pop("prompt")
340
- conv["chat"] = conv.pop("dialog_id")
341
- if conv["reference"]:
342
- messages = conv["messages"]
343
- message_num = 0
344
- chunk_num = 0
345
- while message_num < len(messages):
346
- if message_num != 0 and messages[message_num]["role"] != "user":
347
- chunk_list = []
348
- if "chunks" in conv["reference"][chunk_num]:
349
- chunks = conv["reference"][chunk_num]["chunks"]
350
- for chunk in chunks:
351
- new_chunk = {
352
- "id": chunk["chunk_id"],
353
- "content": chunk["content_with_weight"],
354
- "document_id": chunk["doc_id"],
355
- "document_name": chunk["docnm_kwd"],
356
- "dataset_id": chunk["kb_id"],
357
- "image_id": chunk["img_id"],
358
- "similarity": chunk["similarity"],
359
- "vector_similarity": chunk["vector_similarity"],
360
- "term_similarity": chunk["term_similarity"],
361
- "positions": chunk["positions"],
362
- }
363
- chunk_list.append(new_chunk)
364
- chunk_num += 1
365
- messages[message_num]["reference"] = chunk_list
366
- message_num += 1
367
- del conv["reference"]
368
- return get_result(data=convs)
369
-
370
-
371
- @manager.route('/chats/<chat_id>/sessions', methods=["DELETE"])
372
- @token_required
373
- def delete(tenant_id,chat_id):
374
- if not DialogService.query(id=chat_id, tenant_id=tenant_id, status=StatusEnum.VALID.value):
375
- return get_error_data_result(retmsg="You don't own the chat")
376
- req = request.json
377
- convs = ConversationService.query(dialog_id=chat_id)
378
- if not req:
379
- ids = None
380
- else:
381
- ids=req.get("ids")
382
-
383
- if not ids:
384
- conv_list = []
385
- for conv in convs:
386
- conv_list.append(conv.id)
387
- else:
388
- conv_list=ids
389
- for id in conv_list:
390
- conv = ConversationService.query(id=id,dialog_id=chat_id)
391
- if not conv:
392
- return get_error_data_result(retmsg="The chat doesn't own the session")
393
- ConversationService.delete_by_id(id)
394
- return get_result()
 
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
+ import json
17
+ from functools import partial
18
+ from uuid import uuid4
19
+
20
+ from flask import request, Response
21
+
22
+ from agent.canvas import Canvas
23
+ from api.db import StatusEnum
24
+ from api.db.db_models import API4Conversation
25
+ from api.db.services.api_service import API4ConversationService
26
+ from api.db.services.canvas_service import UserCanvasService
27
+ from api.db.services.dialog_service import DialogService, ConversationService, chat
28
+ from api.utils import get_uuid
29
+ from api.utils.api_utils import get_error_data_result
30
+ from api.utils.api_utils import get_result, token_required
31
+
32
+
33
+ @manager.route('/chats/<chat_id>/sessions', methods=['POST'])
34
+ @token_required
35
+ def create(tenant_id,chat_id):
36
+ req = request.json
37
+ req["dialog_id"] = chat_id
38
+ dia = DialogService.query(tenant_id=tenant_id, id=req["dialog_id"], status=StatusEnum.VALID.value)
39
+ if not dia:
40
+ return get_error_data_result(message="You do not own the assistant.")
41
+ conv = {
42
+ "id": get_uuid(),
43
+ "dialog_id": req["dialog_id"],
44
+ "name": req.get("name", "New session"),
45
+ "message": [{"role": "assistant", "content": "Hi! I am your assistant,can I help you?"}]
46
+ }
47
+ if not conv.get("name"):
48
+ return get_error_data_result(message="`name` can not be empty.")
49
+ ConversationService.save(**conv)
50
+ e, conv = ConversationService.get_by_id(conv["id"])
51
+ if not e:
52
+ return get_error_data_result(message="Fail to create a session!")
53
+ conv = conv.to_dict()
54
+ conv['messages'] = conv.pop("message")
55
+ conv["chat_id"] = conv.pop("dialog_id")
56
+ del conv["reference"]
57
+ return get_result(data=conv)
58
+
59
+
60
+ @manager.route('/agents/<agent_id>/sessions', methods=['POST'])
61
+ @token_required
62
+ def create_agent_session(tenant_id, agent_id):
63
+ req = request.json
64
+ e, cvs = UserCanvasService.get_by_id(agent_id)
65
+ if not e:
66
+ return get_error_data_result("Agent not found.")
67
+ if cvs.user_id != tenant_id:
68
+ return get_error_data_result(message="You do not own the agent.")
69
+
70
+ if not isinstance(cvs.dsl, str):
71
+ cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False)
72
+
73
+ canvas = Canvas(cvs.dsl, tenant_id)
74
+ conv = {
75
+ "id": get_uuid(),
76
+ "dialog_id": cvs.id,
77
+ "user_id": req.get("user_id", ""),
78
+ "message": [{"role": "assistant", "content": canvas.get_prologue()}],
79
+ "source": "agent"
80
+ }
81
+ API4ConversationService.save(**conv)
82
+ return get_result(data=conv)
83
+
84
+
85
+ @manager.route('/chats/<chat_id>/sessions/<session_id>', methods=['PUT'])
86
+ @token_required
87
+ def update(tenant_id,chat_id,session_id):
88
+ req = request.json
89
+ req["dialog_id"] = chat_id
90
+ conv_id = session_id
91
+ conv = ConversationService.query(id=conv_id,dialog_id=chat_id)
92
+ if not conv:
93
+ return get_error_data_result(message="Session does not exist")
94
+ if not DialogService.query(id=chat_id, tenant_id=tenant_id, status=StatusEnum.VALID.value):
95
+ return get_error_data_result(message="You do not own the session")
96
+ if "message" in req or "messages" in req:
97
+ return get_error_data_result(message="`message` can not be change")
98
+ if "reference" in req:
99
+ return get_error_data_result(message="`reference` can not be change")
100
+ if "name" in req and not req.get("name"):
101
+ return get_error_data_result(message="`name` can not be empty.")
102
+ if not ConversationService.update_by_id(conv_id, req):
103
+ return get_error_data_result(message="Session updates error")
104
+ return get_result()
105
+
106
+
107
+ @manager.route('/chats/<chat_id>/completions', methods=['POST'])
108
+ @token_required
109
+ def completion(tenant_id, chat_id):
110
+ req = request.json
111
+ if not req.get("session_id"):
112
+ conv = {
113
+ "id": get_uuid(),
114
+ "dialog_id": chat_id,
115
+ "name": req.get("name", "New session"),
116
+ "message": [{"role": "assistant", "content": "Hi! I am your assistant,can I help you?"}]
117
+ }
118
+ if not conv.get("name"):
119
+ return get_error_data_result(message="`name` can not be empty.")
120
+ ConversationService.save(**conv)
121
+ e, conv = ConversationService.get_by_id(conv["id"])
122
+ session_id=conv.id
123
+ else:
124
+ session_id = req.get("session_id")
125
+ if not req.get("question"):
126
+ return get_error_data_result(message="Please input your question.")
127
+ conv = ConversationService.query(id=session_id,dialog_id=chat_id)
128
+ if not conv:
129
+ return get_error_data_result(message="Session does not exist")
130
+ conv = conv[0]
131
+ if not DialogService.query(id=chat_id, tenant_id=tenant_id, status=StatusEnum.VALID.value):
132
+ return get_error_data_result(message="You do not own the chat")
133
+ msg = []
134
+ question = {
135
+ "content": req.get("question"),
136
+ "role": "user",
137
+ "id": str(uuid4())
138
+ }
139
+ conv.message.append(question)
140
+ for m in conv.message:
141
+ if m["role"] == "system": continue
142
+ if m["role"] == "assistant" and not msg: continue
143
+ msg.append(m)
144
+ message_id = msg[-1].get("id")
145
+ e, dia = DialogService.get_by_id(conv.dialog_id)
146
+
147
+ if not conv.reference:
148
+ conv.reference = []
149
+ conv.message.append({"role": "assistant", "content": "", "id": message_id})
150
+ conv.reference.append({"chunks": [], "doc_aggs": []})
151
+
152
+ def fillin_conv(ans):
153
+ nonlocal conv, message_id
154
+ if not conv.reference:
155
+ conv.reference.append(ans["reference"])
156
+ else:
157
+ conv.reference[-1] = ans["reference"]
158
+ conv.message[-1] = {"role": "assistant", "content": ans["answer"],
159
+ "id": message_id, "prompt": ans.get("prompt", "")}
160
+ ans["id"] = message_id
161
+ ans["session_id"]=session_id
162
+
163
+ def stream():
164
+ nonlocal dia, msg, req, conv
165
+ try:
166
+ for ans in chat(dia, msg, **req):
167
+ fillin_conv(ans)
168
+ yield "data:" + json.dumps({"code": 0, "data": ans}, ensure_ascii=False) + "\n\n"
169
+ ConversationService.update_by_id(conv.id, conv.to_dict())
170
+ except Exception as e:
171
+ yield "data:" + json.dumps({"code": 500, "message": str(e),
172
+ "data": {"answer": "**ERROR**: " + str(e),"reference": []}},
173
+ ensure_ascii=False) + "\n\n"
174
+ yield "data:" + json.dumps({"code": 0, "data": True}, ensure_ascii=False) + "\n\n"
175
+
176
+ if req.get("stream", True):
177
+ resp = Response(stream(), mimetype="text/event-stream")
178
+ resp.headers.add_header("Cache-control", "no-cache")
179
+ resp.headers.add_header("Connection", "keep-alive")
180
+ resp.headers.add_header("X-Accel-Buffering", "no")
181
+ resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
182
+ return resp
183
+
184
+ else:
185
+ answer = None
186
+ for ans in chat(dia, msg, **req):
187
+ answer = ans
188
+ fillin_conv(ans)
189
+ ConversationService.update_by_id(conv.id, conv.to_dict())
190
+ break
191
+ return get_result(data=answer)
192
+
193
+
194
+ @manager.route('/agents/<agent_id>/completions', methods=['POST'])
195
+ @token_required
196
+ def agent_completion(tenant_id, agent_id):
197
+ req = request.json
198
+ e, cvs = UserCanvasService.get_by_id(agent_id)
199
+ if not e:
200
+ return get_error_data_result("Agent not found.")
201
+ if cvs.user_id != tenant_id:
202
+ return get_error_data_result(message="You do not own the agent.")
203
+ if not isinstance(cvs.dsl, str):
204
+ cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False)
205
+
206
+ canvas = Canvas(cvs.dsl, tenant_id)
207
+
208
+ msg = []
209
+ for m in req["messages"]:
210
+ if m["role"] == "system":
211
+ continue
212
+ if m["role"] == "assistant" and not msg:
213
+ continue
214
+ msg.append(m)
215
+ if not msg[-1].get("id"): msg[-1]["id"] = get_uuid()
216
+ message_id = msg[-1]["id"]
217
+
218
+ if not req.get("session_id"):
219
+ session_id = get_uuid()
220
+ conv = {
221
+ "id": session_id,
222
+ "dialog_id": cvs.id,
223
+ "user_id": req.get("user_id", ""),
224
+ "message": [{"role": "assistant", "content": canvas.get_prologue()}],
225
+ "source": "agent"
226
+ }
227
+ API4ConversationService.save(**conv)
228
+ conv = API4Conversation(**conv)
229
+ else:
230
+ session_id = req.get("session_id")
231
+ e, conv = API4ConversationService.get_by_id(req["session_id"])
232
+ if not e:
233
+ return get_error_data_result(message="Session not found!")
234
+
235
+ if "quote" not in req: req["quote"] = False
236
+ stream = req.get("stream", True)
237
+
238
+ def fillin_conv(ans):
239
+ nonlocal conv, message_id
240
+ if not conv.reference:
241
+ conv.reference.append(ans["reference"])
242
+ else:
243
+ conv.reference[-1] = ans["reference"]
244
+ conv.message[-1] = {"role": "assistant", "content": ans["answer"], "id": message_id}
245
+ ans["id"] = message_id
246
+ ans["session_id"] = session_id
247
+
248
+ def rename_field(ans):
249
+ reference = ans['reference']
250
+ if not isinstance(reference, dict):
251
+ return
252
+ for chunk_i in reference.get('chunks', []):
253
+ if 'docnm_kwd' in chunk_i:
254
+ chunk_i['doc_name'] = chunk_i['docnm_kwd']
255
+ chunk_i.pop('docnm_kwd')
256
+ conv.message.append(msg[-1])
257
+
258
+ if not conv.reference:
259
+ conv.reference = []
260
+ conv.message.append({"role": "assistant", "content": "", "id": message_id})
261
+ conv.reference.append({"chunks": [], "doc_aggs": []})
262
+
263
+ final_ans = {"reference": [], "content": ""}
264
+
265
+ canvas.messages.append(msg[-1])
266
+ canvas.add_user_input(msg[-1]["content"])
267
+ answer = canvas.run(stream=stream)
268
+
269
+ assert answer is not None, "Nothing. Is it over?"
270
+
271
+ if stream:
272
+ assert isinstance(answer, partial), "Nothing. Is it over?"
273
+
274
+ def sse():
275
+ nonlocal answer, cvs, conv
276
+ try:
277
+ for ans in answer():
278
+ for k in ans.keys():
279
+ final_ans[k] = ans[k]
280
+ ans = {"answer": ans["content"], "reference": ans.get("reference", [])}
281
+ fillin_conv(ans)
282
+ rename_field(ans)
283
+ yield "data:" + json.dumps({"code": 0, "message": "", "data": ans},
284
+ ensure_ascii=False) + "\n\n"
285
+
286
+ canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id})
287
+ if final_ans.get("reference"):
288
+ canvas.reference.append(final_ans["reference"])
289
+ cvs.dsl = json.loads(str(canvas))
290
+ API4ConversationService.append_message(conv.id, conv.to_dict())
291
+ except Exception as e:
292
+ yield "data:" + json.dumps({"code": 500, "message": str(e),
293
+ "data": {"answer": "**ERROR**: " + str(e), "reference": []}},
294
+ ensure_ascii=False) + "\n\n"
295
+ yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n"
296
+
297
+ resp = Response(sse(), mimetype="text/event-stream")
298
+ resp.headers.add_header("Cache-control", "no-cache")
299
+ resp.headers.add_header("Connection", "keep-alive")
300
+ resp.headers.add_header("X-Accel-Buffering", "no")
301
+ resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8")
302
+ return resp
303
+
304
+ final_ans["content"] = "\n".join(answer["content"]) if "content" in answer else ""
305
+ canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id})
306
+ if final_ans.get("reference"):
307
+ canvas.reference.append(final_ans["reference"])
308
+ cvs.dsl = json.loads(str(canvas))
309
+
310
+ result = {"answer": final_ans["content"], "reference": final_ans.get("reference", [])}
311
+ fillin_conv(result)
312
+ API4ConversationService.append_message(conv.id, conv.to_dict())
313
+ rename_field(result)
314
+ return get_result(data=result)
315
+
316
+
317
+ @manager.route('/chats/<chat_id>/sessions', methods=['GET'])
318
+ @token_required
319
+ def list(chat_id,tenant_id):
320
+ if not DialogService.query(tenant_id=tenant_id, id=chat_id, status=StatusEnum.VALID.value):
321
+ return get_error_data_result(message=f"You don't own the assistant {chat_id}.")
322
+ id = request.args.get("id")
323
+ name = request.args.get("name")
324
+ page_number = int(request.args.get("page", 1))
325
+ items_per_page = int(request.args.get("page_size", 1024))
326
+ orderby = request.args.get("orderby", "create_time")
327
+ if request.args.get("desc") == "False" or request.args.get("desc") == "false":
328
+ desc = False
329
+ else:
330
+ desc = True
331
+ convs = ConversationService.get_list(chat_id,page_number,items_per_page,orderby,desc,id,name)
332
+ if not convs:
333
+ return get_result(data=[])
334
+ for conv in convs:
335
+ conv['messages'] = conv.pop("message")
336
+ infos = conv["messages"]
337
+ for info in infos:
338
+ if "prompt" in info:
339
+ info.pop("prompt")
340
+ conv["chat"] = conv.pop("dialog_id")
341
+ if conv["reference"]:
342
+ messages = conv["messages"]
343
+ message_num = 0
344
+ chunk_num = 0
345
+ while message_num < len(messages):
346
+ if message_num != 0 and messages[message_num]["role"] != "user":
347
+ chunk_list = []
348
+ if "chunks" in conv["reference"][chunk_num]:
349
+ chunks = conv["reference"][chunk_num]["chunks"]
350
+ for chunk in chunks:
351
+ new_chunk = {
352
+ "id": chunk["chunk_id"],
353
+ "content": chunk["content_with_weight"],
354
+ "document_id": chunk["doc_id"],
355
+ "document_name": chunk["docnm_kwd"],
356
+ "dataset_id": chunk["kb_id"],
357
+ "image_id": chunk["img_id"],
358
+ "similarity": chunk["similarity"],
359
+ "vector_similarity": chunk["vector_similarity"],
360
+ "term_similarity": chunk["term_similarity"],
361
+ "positions": chunk["positions"],
362
+ }
363
+ chunk_list.append(new_chunk)
364
+ chunk_num += 1
365
+ messages[message_num]["reference"] = chunk_list
366
+ message_num += 1
367
+ del conv["reference"]
368
+ return get_result(data=convs)
369
+
370
+
371
+ @manager.route('/chats/<chat_id>/sessions', methods=["DELETE"])
372
+ @token_required
373
+ def delete(tenant_id,chat_id):
374
+ if not DialogService.query(id=chat_id, tenant_id=tenant_id, status=StatusEnum.VALID.value):
375
+ return get_error_data_result(message="You don't own the chat")
376
+ req = request.json
377
+ convs = ConversationService.query(dialog_id=chat_id)
378
+ if not req:
379
+ ids = None
380
+ else:
381
+ ids=req.get("ids")
382
+
383
+ if not ids:
384
+ conv_list = []
385
+ for conv in convs:
386
+ conv_list.append(conv.id)
387
+ else:
388
+ conv_list=ids
389
+ for id in conv_list:
390
+ conv = ConversationService.query(id=id,dialog_id=chat_id)
391
+ if not conv:
392
+ return get_error_data_result(message="The chat doesn't own the session")
393
+ ConversationService.delete_by_id(id)
394
+ return get_result()
api/apps/system_app.py CHANGED
@@ -29,8 +29,6 @@ from api.utils.api_utils import (
29
  get_data_error_result,
30
  server_error_response,
31
  generate_confirmation_token,
32
- request,
33
- validate_request,
34
  )
35
  from api.versions import get_rag_version
36
  from rag.utils.es_conn import ELASTICSEARCH
@@ -209,7 +207,7 @@ def new_token():
209
  try:
210
  tenants = UserTenantService.query(user_id=current_user.id)
211
  if not tenants:
212
- return get_data_error_result(retmsg="Tenant not found!")
213
 
214
  tenant_id = tenants[0].tenant_id
215
  obj = {
@@ -222,7 +220,7 @@ def new_token():
222
  }
223
 
224
  if not APITokenService.save(**obj):
225
- return get_data_error_result(retmsg="Fail to new a dialog!")
226
 
227
  return get_json_result(data=obj)
228
  except Exception as e:
@@ -263,7 +261,7 @@ def token_list():
263
  try:
264
  tenants = UserTenantService.query(user_id=current_user.id)
265
  if not tenants:
266
- return get_data_error_result(retmsg="Tenant not found!")
267
 
268
  objs = APITokenService.query(tenant_id=tenants[0].tenant_id)
269
  return get_json_result(data=[o.to_dict() for o in objs])
 
29
  get_data_error_result,
30
  server_error_response,
31
  generate_confirmation_token,
 
 
32
  )
33
  from api.versions import get_rag_version
34
  from rag.utils.es_conn import ELASTICSEARCH
 
207
  try:
208
  tenants = UserTenantService.query(user_id=current_user.id)
209
  if not tenants:
210
+ return get_data_error_result(message="Tenant not found!")
211
 
212
  tenant_id = tenants[0].tenant_id
213
  obj = {
 
220
  }
221
 
222
  if not APITokenService.save(**obj):
223
+ return get_data_error_result(message="Fail to new a dialog!")
224
 
225
  return get_json_result(data=obj)
226
  except Exception as e:
 
261
  try:
262
  tenants = UserTenantService.query(user_id=current_user.id)
263
  if not tenants:
264
+ return get_data_error_result(message="Tenant not found!")
265
 
266
  objs = APITokenService.query(tenant_id=tenants[0].tenant_id)
267
  return get_json_result(data=[o.to_dict() for o in objs])
api/apps/tenant_app.py CHANGED
@@ -44,14 +44,14 @@ def create(tenant_id):
44
  req = request.json
45
  usrs = UserService.query(email=req["email"])
46
  if not usrs:
47
- return get_data_error_result(retmsg="User not found.")
48
 
49
  user_id = usrs[0].id
50
  user_tenants = UserTenantService.query(user_id=user_id, tenant_id=tenant_id)
51
  if user_tenants:
52
  if user_tenants[0].status == UserTenantRole.NORMAL.value:
53
- return get_data_error_result(retmsg="This user is in the team already.")
54
- return get_data_error_result(retmsg="Invitation notification is sent.")
55
 
56
  UserTenantService.save(
57
  id=get_uuid(),
 
44
  req = request.json
45
  usrs = UserService.query(email=req["email"])
46
  if not usrs:
47
+ return get_data_error_result(message="User not found.")
48
 
49
  user_id = usrs[0].id
50
  user_tenants = UserTenantService.query(user_id=user_id, tenant_id=tenant_id)
51
  if user_tenants:
52
  if user_tenants[0].status == UserTenantRole.NORMAL.value:
53
+ return get_data_error_result(message="This user is in the team already.")
54
+ return get_data_error_result(message="Invitation notification is sent.")
55
 
56
  UserTenantService.save(
57
  id=get_uuid(),
api/apps/user_app.py CHANGED
@@ -36,7 +36,7 @@ from api.utils import (
36
  current_timestamp,
37
  datetime_format,
38
  )
39
- from api.db import UserTenantRole, LLMType, FileType
40
  from api.settings import (
41
  RetCode,
42
  GITHUB_OAUTH,
@@ -90,7 +90,7 @@ def login():
90
  """
91
  if not request.json:
92
  return get_json_result(
93
- data=False, retcode=RetCode.AUTHENTICATION_ERROR, retmsg="Unauthorized!"
94
  )
95
 
96
  email = request.json.get("email", "")
@@ -98,8 +98,8 @@ def login():
98
  if not users:
99
  return get_json_result(
100
  data=False,
101
- retcode=RetCode.AUTHENTICATION_ERROR,
102
- retmsg=f"Email: {email} is not registered!",
103
  )
104
 
105
  password = request.json.get("password")
@@ -107,7 +107,7 @@ def login():
107
  password = decrypt(password)
108
  except BaseException:
109
  return get_json_result(
110
- data=False, retcode=RetCode.SERVER_ERROR, retmsg="Fail to crypt password"
111
  )
112
 
113
  user = UserService.query_user(email, password)
@@ -119,12 +119,12 @@ def login():
119
  user.update_date = (datetime_format(datetime.now()),)
120
  user.save()
121
  msg = "Welcome back!"
122
- return construct_response(data=response_data, auth=user.get_id(), retmsg=msg)
123
  else:
124
  return get_json_result(
125
  data=False,
126
- retcode=RetCode.AUTHENTICATION_ERROR,
127
- retmsg="Email and password do not match!",
128
  )
129
 
130
 
@@ -323,7 +323,7 @@ def user_info_from_feishu(access_token):
323
  "Authorization": f"Bearer {access_token}",
324
  }
325
  res = requests.get(
326
- f"https://open.feishu.cn/open-apis/authen/v1/user_info", headers=headers
327
  )
328
  user_info = res.json()["data"]
329
  user_info["email"] = None if user_info.get("email") == "" else user_info["email"]
@@ -409,8 +409,8 @@ def setting_user():
409
  ):
410
  return get_json_result(
411
  data=False,
412
- retcode=RetCode.AUTHENTICATION_ERROR,
413
- retmsg="Password error!",
414
  )
415
 
416
  if new_password:
@@ -438,7 +438,7 @@ def setting_user():
438
  except Exception as e:
439
  stat_logger.exception(e)
440
  return get_json_result(
441
- data=False, retmsg="Update failure!", retcode=RetCode.EXCEPTION_ERROR
442
  )
443
 
444
 
@@ -474,21 +474,21 @@ def user_profile():
474
  def rollback_user_registration(user_id):
475
  try:
476
  UserService.delete_by_id(user_id)
477
- except Exception as e:
478
  pass
479
  try:
480
  TenantService.delete_by_id(user_id)
481
- except Exception as e:
482
  pass
483
  try:
484
  u = UserTenantService.query(tenant_id=user_id)
485
  if u:
486
  UserTenantService.delete_by_id(u[0].id)
487
- except Exception as e:
488
  pass
489
  try:
490
  TenantLLM.delete().where(TenantLLM.tenant_id == user_id).execute()
491
- except Exception as e:
492
  pass
493
 
494
 
@@ -581,16 +581,16 @@ def user_add():
581
  if not re.match(r"^[\w\._-]+@([\w_-]+\.)+[\w-]{2,5}$", email_address):
582
  return get_json_result(
583
  data=False,
584
- retmsg=f"Invalid email address: {email_address}!",
585
- retcode=RetCode.OPERATING_ERROR,
586
  )
587
 
588
  # Check if the email address is already used
589
  if UserService.query(email=email_address):
590
  return get_json_result(
591
  data=False,
592
- retmsg=f"Email: {email_address} has already registered!",
593
- retcode=RetCode.OPERATING_ERROR,
594
  )
595
 
596
  # Construct user info data
@@ -617,15 +617,15 @@ def user_add():
617
  return construct_response(
618
  data=user.to_json(),
619
  auth=user.get_id(),
620
- retmsg=f"{nickname}, welcome aboard!",
621
  )
622
  except Exception as e:
623
  rollback_user_registration(user_id)
624
  stat_logger.exception(e)
625
  return get_json_result(
626
  data=False,
627
- retmsg=f"User registration failure, error: {str(e)}",
628
- retcode=RetCode.EXCEPTION_ERROR,
629
  )
630
 
631
 
@@ -661,7 +661,7 @@ def tenant_info():
661
  try:
662
  tenants = TenantService.get_info_by(current_user.id)
663
  if not tenants:
664
- return get_data_error_result(retmsg="Tenant not found!")
665
  return get_json_result(data=tenants[0])
666
  except Exception as e:
667
  return server_error_response(e)
 
36
  current_timestamp,
37
  datetime_format,
38
  )
39
+ from api.db import UserTenantRole, FileType
40
  from api.settings import (
41
  RetCode,
42
  GITHUB_OAUTH,
 
90
  """
91
  if not request.json:
92
  return get_json_result(
93
+ data=False, code=RetCode.AUTHENTICATION_ERROR, message="Unauthorized!"
94
  )
95
 
96
  email = request.json.get("email", "")
 
98
  if not users:
99
  return get_json_result(
100
  data=False,
101
+ code=RetCode.AUTHENTICATION_ERROR,
102
+ message=f"Email: {email} is not registered!",
103
  )
104
 
105
  password = request.json.get("password")
 
107
  password = decrypt(password)
108
  except BaseException:
109
  return get_json_result(
110
+ data=False, code=RetCode.SERVER_ERROR, message="Fail to crypt password"
111
  )
112
 
113
  user = UserService.query_user(email, password)
 
119
  user.update_date = (datetime_format(datetime.now()),)
120
  user.save()
121
  msg = "Welcome back!"
122
+ return construct_response(data=response_data, auth=user.get_id(), message=msg)
123
  else:
124
  return get_json_result(
125
  data=False,
126
+ code=RetCode.AUTHENTICATION_ERROR,
127
+ message="Email and password do not match!",
128
  )
129
 
130
 
 
323
  "Authorization": f"Bearer {access_token}",
324
  }
325
  res = requests.get(
326
+ "https://open.feishu.cn/open-apis/authen/v1/user_info", headers=headers
327
  )
328
  user_info = res.json()["data"]
329
  user_info["email"] = None if user_info.get("email") == "" else user_info["email"]
 
409
  ):
410
  return get_json_result(
411
  data=False,
412
+ code=RetCode.AUTHENTICATION_ERROR,
413
+ message="Password error!",
414
  )
415
 
416
  if new_password:
 
438
  except Exception as e:
439
  stat_logger.exception(e)
440
  return get_json_result(
441
+ data=False, message="Update failure!", code=RetCode.EXCEPTION_ERROR
442
  )
443
 
444
 
 
474
  def rollback_user_registration(user_id):
475
  try:
476
  UserService.delete_by_id(user_id)
477
+ except Exception:
478
  pass
479
  try:
480
  TenantService.delete_by_id(user_id)
481
+ except Exception:
482
  pass
483
  try:
484
  u = UserTenantService.query(tenant_id=user_id)
485
  if u:
486
  UserTenantService.delete_by_id(u[0].id)
487
+ except Exception:
488
  pass
489
  try:
490
  TenantLLM.delete().where(TenantLLM.tenant_id == user_id).execute()
491
+ except Exception:
492
  pass
493
 
494
 
 
581
  if not re.match(r"^[\w\._-]+@([\w_-]+\.)+[\w-]{2,5}$", email_address):
582
  return get_json_result(
583
  data=False,
584
+ message=f"Invalid email address: {email_address}!",
585
+ code=RetCode.OPERATING_ERROR,
586
  )
587
 
588
  # Check if the email address is already used
589
  if UserService.query(email=email_address):
590
  return get_json_result(
591
  data=False,
592
+ message=f"Email: {email_address} has already registered!",
593
+ code=RetCode.OPERATING_ERROR,
594
  )
595
 
596
  # Construct user info data
 
617
  return construct_response(
618
  data=user.to_json(),
619
  auth=user.get_id(),
620
+ message=f"{nickname}, welcome aboard!",
621
  )
622
  except Exception as e:
623
  rollback_user_registration(user_id)
624
  stat_logger.exception(e)
625
  return get_json_result(
626
  data=False,
627
+ message=f"User registration failure, error: {str(e)}",
628
+ code=RetCode.EXCEPTION_ERROR,
629
  )
630
 
631
 
 
661
  try:
662
  tenants = TenantService.get_info_by(current_user.id)
663
  if not tenants:
664
+ return get_data_error_result(message="Tenant not found!")
665
  return get_json_result(data=tenants[0])
666
  except Exception as e:
667
  return server_error_response(e)
api/utils/api_utils.py CHANGED
@@ -97,19 +97,19 @@ def get_exponential_backoff_interval(retries, full_jitter=False):
97
  return max(0, countdown)
98
 
99
 
100
- def get_data_error_result(retcode=RetCode.DATA_ERROR,
101
- retmsg='Sorry! Data missing!'):
102
  import re
103
  result_dict = {
104
- "retcode": retcode,
105
- "retmsg": re.sub(
106
  r"rag",
107
  "seceum",
108
- retmsg,
109
  flags=re.IGNORECASE)}
110
  response = {}
111
  for key, value in result_dict.items():
112
- if value is None and key != "retcode":
113
  continue
114
  else:
115
  response[key] = value
@@ -120,26 +120,26 @@ def server_error_response(e):
120
  stat_logger.exception(e)
121
  try:
122
  if e.code == 401:
123
- return get_json_result(retcode=401, retmsg=repr(e))
124
  except BaseException:
125
  pass
126
  if len(e.args) > 1:
127
  return get_json_result(
128
- retcode=RetCode.EXCEPTION_ERROR, retmsg=repr(e.args[0]), data=e.args[1])
129
  if repr(e).find("index_not_found_exception") >= 0:
130
- return get_json_result(retcode=RetCode.EXCEPTION_ERROR,
131
- retmsg="No chunk found, please upload file and parse it.")
132
 
133
- return get_json_result(retcode=RetCode.EXCEPTION_ERROR, retmsg=repr(e))
134
 
135
 
136
- def error_response(response_code, retmsg=None):
137
- if retmsg is None:
138
- retmsg = HTTP_STATUS_CODES.get(response_code, 'Unknown Error')
139
 
140
  return Response(json.dumps({
141
- 'retmsg': retmsg,
142
- 'retcode': response_code,
143
  }), status=response_code, mimetype='application/json')
144
 
145
 
@@ -171,7 +171,7 @@ def validate_request(*args, **kwargs):
171
  error_string += "required argument values: {}".format(
172
  ",".join(["{}={}".format(a[0], a[1]) for a in error_arguments]))
173
  return get_json_result(
174
- retcode=RetCode.ARGUMENT_ERROR, retmsg=error_string)
175
  return func(*_args, **_kwargs)
176
 
177
  return decorated_function
@@ -196,8 +196,8 @@ def send_file_in_mem(data, filename):
196
  return send_file(f, as_attachment=True, attachment_filename=filename)
197
 
198
 
199
- def get_json_result(retcode=RetCode.SUCCESS, retmsg='success', data=None):
200
- response = {"retcode": retcode, "retmsg": retmsg, "data": data}
201
  return jsonify(response)
202
 
203
  def apikey_required(func):
@@ -207,7 +207,7 @@ def apikey_required(func):
207
  objs = APIToken.query(token=token)
208
  if not objs:
209
  return build_error_result(
210
- error_msg='API-KEY is invalid!', retcode=RetCode.FORBIDDEN
211
  )
212
  kwargs['tenant_id'] = objs[0].tenant_id
213
  return func(*args, **kwargs)
@@ -215,19 +215,19 @@ def apikey_required(func):
215
  return decorated_function
216
 
217
 
218
- def build_error_result(retcode=RetCode.FORBIDDEN, error_msg='success'):
219
- response = {"error_code": retcode, "error_msg": error_msg}
220
  response = jsonify(response)
221
- response.status_code = retcode
222
  return response
223
 
224
 
225
- def construct_response(retcode=RetCode.SUCCESS,
226
- retmsg='success', data=None, auth=None):
227
- result_dict = {"retcode": retcode, "retmsg": retmsg, "data": data}
228
  response_dict = {}
229
  for key, value in result_dict.items():
230
- if value is None and key != "retcode":
231
  continue
232
  else:
233
  response_dict[key] = value
@@ -284,7 +284,7 @@ def token_required(func):
284
  objs = APIToken.query(token=token)
285
  if not objs:
286
  return get_json_result(
287
- data=False, retmsg='Token is not valid!', retcode=RetCode.AUTHENTICATION_ERROR
288
  )
289
  kwargs['tenant_id'] = objs[0].tenant_id
290
  return func(*args, **kwargs)
@@ -292,26 +292,26 @@ def token_required(func):
292
  return decorated_function
293
 
294
 
295
- def get_result(retcode=RetCode.SUCCESS, retmsg='error', data=None):
296
- if retcode == 0:
297
  if data is not None:
298
- response = {"code": retcode, "data": data}
299
  else:
300
- response = {"code": retcode}
301
  else:
302
- response = {"code": retcode, "message": retmsg}
303
  return jsonify(response)
304
 
305
 
306
- def get_error_data_result(retmsg='Sorry! Data missing!', retcode=RetCode.DATA_ERROR,
307
  ):
308
  import re
309
  result_dict = {
310
- "code": retcode,
311
  "message": re.sub(
312
  r"rag",
313
  "seceum",
314
- retmsg,
315
  flags=re.IGNORECASE)}
316
  response = {}
317
  for key, value in result_dict.items():
 
97
  return max(0, countdown)
98
 
99
 
100
+ def get_data_error_result(code=RetCode.DATA_ERROR,
101
+ message='Sorry! Data missing!'):
102
  import re
103
  result_dict = {
104
+ "code": code,
105
+ "message": re.sub(
106
  r"rag",
107
  "seceum",
108
+ message,
109
  flags=re.IGNORECASE)}
110
  response = {}
111
  for key, value in result_dict.items():
112
+ if value is None and key != "code":
113
  continue
114
  else:
115
  response[key] = value
 
120
  stat_logger.exception(e)
121
  try:
122
  if e.code == 401:
123
+ return get_json_result(code=401, message=repr(e))
124
  except BaseException:
125
  pass
126
  if len(e.args) > 1:
127
  return get_json_result(
128
+ code=RetCode.EXCEPTION_ERROR, message=repr(e.args[0]), data=e.args[1])
129
  if repr(e).find("index_not_found_exception") >= 0:
130
+ return get_json_result(code=RetCode.EXCEPTION_ERROR,
131
+ message="No chunk found, please upload file and parse it.")
132
 
133
+ return get_json_result(code=RetCode.EXCEPTION_ERROR, message=repr(e))
134
 
135
 
136
+ def error_response(response_code, message=None):
137
+ if message is None:
138
+ message = HTTP_STATUS_CODES.get(response_code, 'Unknown Error')
139
 
140
  return Response(json.dumps({
141
+ 'message': message,
142
+ 'code': response_code,
143
  }), status=response_code, mimetype='application/json')
144
 
145
 
 
171
  error_string += "required argument values: {}".format(
172
  ",".join(["{}={}".format(a[0], a[1]) for a in error_arguments]))
173
  return get_json_result(
174
+ code=RetCode.ARGUMENT_ERROR, message=error_string)
175
  return func(*_args, **_kwargs)
176
 
177
  return decorated_function
 
196
  return send_file(f, as_attachment=True, attachment_filename=filename)
197
 
198
 
199
+ def get_json_result(code=RetCode.SUCCESS, message='success', data=None):
200
+ response = {"code": code, "message": message, "data": data}
201
  return jsonify(response)
202
 
203
  def apikey_required(func):
 
207
  objs = APIToken.query(token=token)
208
  if not objs:
209
  return build_error_result(
210
+ message='API-KEY is invalid!', code=RetCode.FORBIDDEN
211
  )
212
  kwargs['tenant_id'] = objs[0].tenant_id
213
  return func(*args, **kwargs)
 
215
  return decorated_function
216
 
217
 
218
+ def build_error_result(code=RetCode.FORBIDDEN, message='success'):
219
+ response = {"code": code, "message": message}
220
  response = jsonify(response)
221
+ response.status_code = code
222
  return response
223
 
224
 
225
+ def construct_response(code=RetCode.SUCCESS,
226
+ message='success', data=None, auth=None):
227
+ result_dict = {"code": code, "message": message, "data": data}
228
  response_dict = {}
229
  for key, value in result_dict.items():
230
+ if value is None and key != "code":
231
  continue
232
  else:
233
  response_dict[key] = value
 
284
  objs = APIToken.query(token=token)
285
  if not objs:
286
  return get_json_result(
287
+ data=False, message='Token is not valid!', code=RetCode.AUTHENTICATION_ERROR
288
  )
289
  kwargs['tenant_id'] = objs[0].tenant_id
290
  return func(*args, **kwargs)
 
292
  return decorated_function
293
 
294
 
295
+ def get_result(code=RetCode.SUCCESS, message='error', data=None):
296
+ if code == 0:
297
  if data is not None:
298
+ response = {"code": code, "data": data}
299
  else:
300
+ response = {"code": code}
301
  else:
302
+ response = {"code": code, "message": message}
303
  return jsonify(response)
304
 
305
 
306
+ def get_error_data_result(message='Sorry! Data missing!', code=RetCode.DATA_ERROR,
307
  ):
308
  import re
309
  result_dict = {
310
+ "code": code,
311
  "message": re.sub(
312
  r"rag",
313
  "seceum",
314
+ message,
315
  flags=re.IGNORECASE)}
316
  response = {}
317
  for key, value in result_dict.items():
docs/references/faq.md CHANGED
@@ -276,7 +276,7 @@ $ docker ps
276
 
277
  This is because you forgot to update the `vm.max_map_count` value in **/etc/sysctl.conf** and your change to this value was reset after a system reboot.
278
 
279
- #### 4.10 `{"data":null,"retcode":100,"retmsg":"<NotFound '404: Not Found'>"}`
280
 
281
  Your IP address or port number may be incorrect. If you are using the default configurations, enter `http://<IP_OF_YOUR_MACHINE>` (**NOT 9380, AND NO PORT NUMBER REQUIRED!**) in your browser. This should work.
282
 
 
276
 
277
  This is because you forgot to update the `vm.max_map_count` value in **/etc/sysctl.conf** and your change to this value was reset after a system reboot.
278
 
279
+ #### 4.10 `{"data":null,"code":100,"message":"<NotFound '404: Not Found'>"}`
280
 
281
  Your IP address or port number may be incorrect. If you are using the default configurations, enter `http://<IP_OF_YOUR_MACHINE>` (**NOT 9380, AND NO PORT NUMBER REQUIRED!**) in your browser. This should work.
282
 
intergrations/chatgpt-on-wechat/plugins/ragflow_chat.py CHANGED
@@ -1,10 +1,8 @@
1
  import requests
2
- import json
3
- from bridge.context import Context, ContextType # Import Context, ContextType
4
  from bridge.reply import Reply, ReplyType # Import Reply, ReplyType
5
  from bridge import *
6
  from common.log import logger
7
- from config import conf
8
  from plugins import Plugin, register # Import Plugin and register
9
  from plugins.event import Event, EventContext, EventAction # Import event-related classes
10
 
@@ -68,12 +66,12 @@ class RAGFlowChat(Plugin):
68
  logger.debug(f"[RAGFlowChat] New conversation response: {response.text}")
69
  if response.status_code == 200:
70
  data = response.json()
71
- if data.get("retcode") == 0:
72
  conversation_id = data["data"]["id"]
73
  self.conversations[user_id] = conversation_id
74
  else:
75
- logger.error(f"[RAGFlowChat] Failed to create conversation: {data.get('retmsg')}")
76
- return f"Sorry, unable to create a conversation: {data.get('retmsg')}"
77
  else:
78
  logger.error(f"[RAGFlowChat] HTTP error when creating conversation: {response.status_code}")
79
  return f"Sorry, unable to connect to RAGFlow API (create conversation). HTTP status code: {response.status_code}"
@@ -100,12 +98,12 @@ class RAGFlowChat(Plugin):
100
  logger.debug(f"[RAGFlowChat] Completion response: {response.text}")
101
  if response.status_code == 200:
102
  data = response.json()
103
- if data.get("retcode") == 0:
104
  answer = data["data"]["answer"]
105
  return answer
106
  else:
107
- logger.error(f"[RAGFlowChat] Failed to get answer: {data.get('retmsg')}")
108
- return f"Sorry, unable to get a reply: {data.get('retmsg')}"
109
  else:
110
  logger.error(f"[RAGFlowChat] HTTP error when getting answer: {response.status_code}")
111
  return f"Sorry, unable to connect to RAGFlow API (get reply). HTTP status code: {response.status_code}"
 
1
  import requests
2
+ from bridge.context import ContextType # Import Context, ContextType
 
3
  from bridge.reply import Reply, ReplyType # Import Reply, ReplyType
4
  from bridge import *
5
  from common.log import logger
 
6
  from plugins import Plugin, register # Import Plugin and register
7
  from plugins.event import Event, EventContext, EventAction # Import event-related classes
8
 
 
66
  logger.debug(f"[RAGFlowChat] New conversation response: {response.text}")
67
  if response.status_code == 200:
68
  data = response.json()
69
+ if data.get("code") == 0:
70
  conversation_id = data["data"]["id"]
71
  self.conversations[user_id] = conversation_id
72
  else:
73
+ logger.error(f"[RAGFlowChat] Failed to create conversation: {data.get('message')}")
74
+ return f"Sorry, unable to create a conversation: {data.get('message')}"
75
  else:
76
  logger.error(f"[RAGFlowChat] HTTP error when creating conversation: {response.status_code}")
77
  return f"Sorry, unable to connect to RAGFlow API (create conversation). HTTP status code: {response.status_code}"
 
98
  logger.debug(f"[RAGFlowChat] Completion response: {response.text}")
99
  if response.status_code == 200:
100
  data = response.json()
101
+ if data.get("code") == 0:
102
  answer = data["data"]["answer"]
103
  return answer
104
  else:
105
+ logger.error(f"[RAGFlowChat] Failed to get answer: {data.get('message')}")
106
+ return f"Sorry, unable to get a reply: {data.get('message')}"
107
  else:
108
  logger.error(f"[RAGFlowChat] HTTP error when getting answer: {response.status_code}")
109
  return f"Sorry, unable to connect to RAGFlow API (get reply). HTTP status code: {response.status_code}"
sdk/python/test/conftest.py CHANGED
@@ -25,16 +25,16 @@ def register():
25
  register_data = {"email":EMAIL,"nickname":name,"password":PASSWORD}
26
  res = requests.post(url=url,json=register_data)
27
  res = res.json()
28
- if res.get("retcode") != 0:
29
- raise Exception(res.get("retmsg"))
30
 
31
  def login():
32
  url = HOST_ADDRESS + "/v1/user/login"
33
  login_data = {"email":EMAIL,"password":PASSWORD}
34
  response=requests.post(url=url,json=login_data)
35
  res = response.json()
36
- if res.get("retcode")!=0:
37
- raise Exception(res.get("retmsg"))
38
  auth = response.headers["Authorization"]
39
  return auth
40
 
@@ -46,7 +46,7 @@ def get_api_key_fixture():
46
  auth = {"Authorization": auth}
47
  response = requests.post(url=url,headers=auth)
48
  res = response.json()
49
- if res.get("retcode") != 0:
50
- raise Exception(res.get("retmsg"))
51
  return res["data"].get("token")
52
 
 
25
  register_data = {"email":EMAIL,"nickname":name,"password":PASSWORD}
26
  res = requests.post(url=url,json=register_data)
27
  res = res.json()
28
+ if res.get("code") != 0:
29
+ raise Exception(res.get("message"))
30
 
31
  def login():
32
  url = HOST_ADDRESS + "/v1/user/login"
33
  login_data = {"email":EMAIL,"password":PASSWORD}
34
  response=requests.post(url=url,json=login_data)
35
  res = response.json()
36
+ if res.get("code")!=0:
37
+ raise Exception(res.get("message"))
38
  auth = response.headers["Authorization"]
39
  return auth
40
 
 
46
  auth = {"Authorization": auth}
47
  response = requests.post(url=url,headers=auth)
48
  res = response.json()
49
+ if res.get("code") != 0:
50
+ raise Exception(res.get("message"))
51
  return res["data"].get("token")
52
 
sdk/python/test/ragflow.txt CHANGED
@@ -1 +1 @@
1
- {"data":null,"retcode":100,"retmsg":"TypeError(\"download_document() got an unexpected keyword argument 'tenant_id'\")"}
 
1
+ {"data":null,"code":100,"message":"TypeError(\"download_document() got an unexpected keyword argument 'tenant_id'\")"}
web/src/components/message-input/index.tsx CHANGED
@@ -53,8 +53,8 @@ const getFileIds = (fileList: UploadFile[]) => {
53
  };
54
 
55
  const isUploadSuccess = (file: UploadFile) => {
56
- const retcode = get(file, 'response.retcode');
57
- return typeof retcode === 'number' && retcode === 0;
58
  };
59
 
60
  interface IProps {
@@ -116,7 +116,7 @@ const MessageInput = ({
116
  const creatingRet = await createConversationBeforeUploadDocument(
117
  file.name,
118
  );
119
- if (creatingRet?.retcode === 0) {
120
  nextConversationId = creatingRet.data.id;
121
  }
122
  }
@@ -140,7 +140,7 @@ const MessageInput = ({
140
  originFileObj: file as any,
141
  response: ret,
142
  percent: 100,
143
- status: ret?.retcode === 0 ? 'done' : 'error',
144
  });
145
  return nextList;
146
  });
 
53
  };
54
 
55
  const isUploadSuccess = (file: UploadFile) => {
56
+ const code = get(file, 'response.code');
57
+ return typeof code === 'number' && code === 0;
58
  };
59
 
60
  interface IProps {
 
116
  const creatingRet = await createConversationBeforeUploadDocument(
117
  file.name,
118
  );
119
+ if (creatingRet?.code === 0) {
120
  nextConversationId = creatingRet.data.id;
121
  }
122
  }
 
140
  originFileObj: file as any,
141
  response: ret,
142
  percent: 100,
143
+ status: ret?.code === 0 ? 'done' : 'error',
144
  });
145
  return nextList;
146
  });
web/src/components/message-item/hooks.ts CHANGED
@@ -43,8 +43,8 @@ export const useRemoveMessage = (
43
  const onRemoveMessage = useCallback(async () => {
44
  const pureId = getMessagePureId(messageId);
45
  if (pureId) {
46
- const retcode = await deleteMessage(pureId);
47
- if (retcode === 0) {
48
  removeMessageById?.(messageId);
49
  }
50
  }
 
43
  const onRemoveMessage = useCallback(async () => {
44
  const pureId = getMessagePureId(messageId);
45
  if (pureId) {
46
+ const code = await deleteMessage(pureId);
47
+ if (code === 0) {
48
  removeMessageById?.(messageId);
49
  }
50
  }
web/src/components/pdf-previewer/hooks.ts CHANGED
@@ -6,8 +6,8 @@ export const useCatchDocumentError = (url: string) => {
6
 
7
  const fetchDocument = useCallback(async () => {
8
  const { data } = await axios.get(url);
9
- if (data.retcode !== 0) {
10
- setError(data?.retmsg);
11
  }
12
  }, [url]);
13
  useEffect(() => {
 
6
 
7
  const fetchDocument = useCallback(async () => {
8
  const { data } = await axios.get(url);
9
+ if (data.code !== 0) {
10
+ setError(data?.message);
11
  }
12
  }, [url]);
13
  useEffect(() => {
web/src/hooks/chat-hooks.ts CHANGED
@@ -99,7 +99,7 @@ export const useFetchNextDialogList = () => {
99
  console.log('🚀 ~ queryFn: ~ params:', params);
100
  const { data } = await chatService.listDialog();
101
 
102
- if (data.retcode === 0) {
103
  const list: IDialog[] = data.data;
104
  if (list.length > 0) {
105
  if (list.every((x) => x.id !== dialogId)) {
@@ -128,7 +128,7 @@ export const useSetNextDialog = () => {
128
  mutationKey: ['setDialog'],
129
  mutationFn: async (params: IDialog) => {
130
  const { data } = await chatService.setDialog(params);
131
- if (data.retcode === 0) {
132
  queryClient.invalidateQueries({
133
  exact: false,
134
  queryKey: ['fetchDialogList'],
@@ -141,7 +141,7 @@ export const useSetNextDialog = () => {
141
  i18n.t(`message.${params.dialog_id ? 'modified' : 'created'}`),
142
  );
143
  }
144
- return data?.retcode;
145
  },
146
  });
147
 
@@ -200,12 +200,12 @@ export const useRemoveNextDialog = () => {
200
  mutationKey: ['removeDialog'],
201
  mutationFn: async (dialogIds: string[]) => {
202
  const { data } = await chatService.removeDialog({ dialogIds });
203
- if (data.retcode === 0) {
204
  queryClient.invalidateQueries({ queryKey: ['fetchDialogList'] });
205
 
206
  message.success(i18n.t('message.deleted'));
207
  }
208
- return data.retcode;
209
  },
210
  });
211
 
@@ -231,7 +231,7 @@ export const useFetchNextConversationList = () => {
231
  enabled: !!dialogId,
232
  queryFn: async () => {
233
  const { data } = await chatService.listConversation({ dialogId });
234
- if (data.retcode === 0 && data.data.length > 0) {
235
  handleClickConversation(data.data[0].id, '');
236
  }
237
  return data?.data;
@@ -303,7 +303,7 @@ export const useUpdateNextConversation = () => {
303
  ? params.conversation_id
304
  : getConversationId(),
305
  });
306
- if (data.retcode === 0) {
307
  queryClient.invalidateQueries({ queryKey: ['fetchConversationList'] });
308
  }
309
  return data;
@@ -328,10 +328,10 @@ export const useRemoveNextConversation = () => {
328
  conversationIds,
329
  dialogId,
330
  });
331
- if (data.retcode === 0) {
332
  queryClient.invalidateQueries({ queryKey: ['fetchConversationList'] });
333
  }
334
- return data.retcode;
335
  },
336
  });
337
 
@@ -353,11 +353,11 @@ export const useDeleteMessage = () => {
353
  conversationId,
354
  });
355
 
356
- if (data.retcode === 0) {
357
  message.success(i18n.t(`message.deleted`));
358
  }
359
 
360
- return data.retcode;
361
  },
362
  });
363
 
@@ -378,10 +378,10 @@ export const useFeedback = () => {
378
  ...params,
379
  conversationId,
380
  });
381
- if (data.retcode === 0) {
382
  message.success(i18n.t(`message.operated`));
383
  }
384
- return data.retcode;
385
  },
386
  });
387
 
@@ -402,7 +402,7 @@ export const useCreateNextToken = () => {
402
  mutationKey: ['createToken'],
403
  mutationFn: async (params: Record<string, any>) => {
404
  const { data } = await chatService.createToken(params);
405
- if (data.retcode === 0) {
406
  queryClient.invalidateQueries({ queryKey: ['fetchTokenList'] });
407
  }
408
  return data?.data ?? [];
@@ -445,7 +445,7 @@ export const useRemoveNextToken = () => {
445
  tokens: string[];
446
  }) => {
447
  const { data } = await chatService.removeToken(params);
448
- if (data.retcode === 0) {
449
  queryClient.invalidateQueries({ queryKey: ['fetchTokenList'] });
450
  }
451
  return data?.data ?? [];
 
99
  console.log('🚀 ~ queryFn: ~ params:', params);
100
  const { data } = await chatService.listDialog();
101
 
102
+ if (data.code === 0) {
103
  const list: IDialog[] = data.data;
104
  if (list.length > 0) {
105
  if (list.every((x) => x.id !== dialogId)) {
 
128
  mutationKey: ['setDialog'],
129
  mutationFn: async (params: IDialog) => {
130
  const { data } = await chatService.setDialog(params);
131
+ if (data.code === 0) {
132
  queryClient.invalidateQueries({
133
  exact: false,
134
  queryKey: ['fetchDialogList'],
 
141
  i18n.t(`message.${params.dialog_id ? 'modified' : 'created'}`),
142
  );
143
  }
144
+ return data?.code;
145
  },
146
  });
147
 
 
200
  mutationKey: ['removeDialog'],
201
  mutationFn: async (dialogIds: string[]) => {
202
  const { data } = await chatService.removeDialog({ dialogIds });
203
+ if (data.code === 0) {
204
  queryClient.invalidateQueries({ queryKey: ['fetchDialogList'] });
205
 
206
  message.success(i18n.t('message.deleted'));
207
  }
208
+ return data.code;
209
  },
210
  });
211
 
 
231
  enabled: !!dialogId,
232
  queryFn: async () => {
233
  const { data } = await chatService.listConversation({ dialogId });
234
+ if (data.code === 0 && data.data.length > 0) {
235
  handleClickConversation(data.data[0].id, '');
236
  }
237
  return data?.data;
 
303
  ? params.conversation_id
304
  : getConversationId(),
305
  });
306
+ if (data.code === 0) {
307
  queryClient.invalidateQueries({ queryKey: ['fetchConversationList'] });
308
  }
309
  return data;
 
328
  conversationIds,
329
  dialogId,
330
  });
331
+ if (data.code === 0) {
332
  queryClient.invalidateQueries({ queryKey: ['fetchConversationList'] });
333
  }
334
+ return data.code;
335
  },
336
  });
337
 
 
353
  conversationId,
354
  });
355
 
356
+ if (data.code === 0) {
357
  message.success(i18n.t(`message.deleted`));
358
  }
359
 
360
+ return data.code;
361
  },
362
  });
363
 
 
378
  ...params,
379
  conversationId,
380
  });
381
+ if (data.code === 0) {
382
  message.success(i18n.t(`message.operated`));
383
  }
384
+ return data.code;
385
  },
386
  });
387
 
 
402
  mutationKey: ['createToken'],
403
  mutationFn: async (params: Record<string, any>) => {
404
  const { data } = await chatService.createToken(params);
405
+ if (data.code === 0) {
406
  queryClient.invalidateQueries({ queryKey: ['fetchTokenList'] });
407
  }
408
  return data?.data ?? [];
 
445
  tokens: string[];
446
  }) => {
447
  const { data } = await chatService.removeToken(params);
448
+ if (data.code === 0) {
449
  queryClient.invalidateQueries({ queryKey: ['fetchTokenList'] });
450
  }
451
  return data?.data ?? [];
web/src/hooks/chunk-hooks.ts CHANGED
@@ -57,7 +57,7 @@ export const useFetchNextChunkList = (): ResponseGetType<{
57
  available_int: available,
58
  keywords: searchString,
59
  });
60
- if (data.retcode === 0) {
61
  const res = data.data;
62
  return {
63
  data: res.chunks,
@@ -126,11 +126,11 @@ export const useDeleteChunk = () => {
126
  mutationKey: ['deleteChunk'],
127
  mutationFn: async (params: { chunkIds: string[]; doc_id: string }) => {
128
  const { data } = await kbService.rm_chunk(params);
129
- if (data.retcode === 0) {
130
  setPaginationParams(1);
131
  queryClient.invalidateQueries({ queryKey: ['fetchChunkList'] });
132
  }
133
- return data?.retcode;
134
  },
135
  });
136
 
@@ -152,11 +152,11 @@ export const useSwitchChunk = () => {
152
  doc_id: string;
153
  }) => {
154
  const { data } = await kbService.switch_chunk(params);
155
- if (data.retcode === 0) {
156
  message.success(t('message.modified'));
157
  queryClient.invalidateQueries({ queryKey: ['fetchChunkList'] });
158
  }
159
- return data?.retcode;
160
  },
161
  });
162
 
@@ -179,11 +179,11 @@ export const useCreateChunk = () => {
179
  service = kbService.set_chunk;
180
  }
181
  const { data } = await service(payload);
182
- if (data.retcode === 0) {
183
  message.success(t('message.created'));
184
  queryClient.invalidateQueries({ queryKey: ['fetchChunkList'] });
185
  }
186
- return data?.retcode;
187
  },
188
  });
189
 
 
57
  available_int: available,
58
  keywords: searchString,
59
  });
60
+ if (data.code === 0) {
61
  const res = data.data;
62
  return {
63
  data: res.chunks,
 
126
  mutationKey: ['deleteChunk'],
127
  mutationFn: async (params: { chunkIds: string[]; doc_id: string }) => {
128
  const { data } = await kbService.rm_chunk(params);
129
+ if (data.code === 0) {
130
  setPaginationParams(1);
131
  queryClient.invalidateQueries({ queryKey: ['fetchChunkList'] });
132
  }
133
+ return data?.code;
134
  },
135
  });
136
 
 
152
  doc_id: string;
153
  }) => {
154
  const { data } = await kbService.switch_chunk(params);
155
+ if (data.code === 0) {
156
  message.success(t('message.modified'));
157
  queryClient.invalidateQueries({ queryKey: ['fetchChunkList'] });
158
  }
159
+ return data?.code;
160
  },
161
  });
162
 
 
179
  service = kbService.set_chunk;
180
  }
181
  const { data } = await service(payload);
182
+ if (data.code === 0) {
183
  message.success(t('message.created'));
184
  queryClient.invalidateQueries({ queryKey: ['fetchChunkList'] });
185
  }
186
+ return data?.code;
187
  },
188
  });
189
 
web/src/hooks/document-hooks.ts CHANGED
@@ -69,7 +69,7 @@ export const useFetchNextDocumentList = () => {
69
  page_size: pagination.pageSize,
70
  page: pagination.current,
71
  });
72
- if (ret.data.retcode === 0) {
73
  return ret.data.data;
74
  }
75
 
@@ -118,7 +118,7 @@ export const useSetNextDocumentStatus = () => {
118
  doc_id: documentId,
119
  status: Number(status),
120
  });
121
- if (data.retcode === 0) {
122
  message.success(i18n.t('message.modified'));
123
  queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
124
  }
@@ -149,11 +149,11 @@ export const useSaveNextDocumentName = () => {
149
  doc_id: documentId,
150
  name: name,
151
  });
152
- if (data.retcode === 0) {
153
  message.success(i18n.t('message.renamed'));
154
  queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
155
  }
156
- return data.retcode;
157
  },
158
  });
159
 
@@ -176,7 +176,7 @@ export const useCreateNextDocument = () => {
176
  name,
177
  kb_id: knowledgeId,
178
  });
179
- if (data.retcode === 0) {
180
  if (page === 1) {
181
  queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
182
  } else {
@@ -185,7 +185,7 @@ export const useCreateNextDocument = () => {
185
 
186
  message.success(i18n.t('message.created'));
187
  }
188
- return data.retcode;
189
  },
190
  });
191
 
@@ -215,12 +215,12 @@ export const useSetNextDocumentParser = () => {
215
  doc_id: documentId,
216
  parser_config: parserConfig,
217
  });
218
- if (data.retcode === 0) {
219
  queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
220
 
221
  message.success(i18n.t('message.modified'));
222
  }
223
- return data.retcode;
224
  },
225
  });
226
 
@@ -246,12 +246,12 @@ export const useUploadNextDocument = () => {
246
 
247
  try {
248
  const ret = await kbService.document_upload(formData);
249
- const retcode = get(ret, 'data.retcode');
250
- if (retcode === 0) {
251
  message.success(i18n.t('message.uploaded'));
252
  }
253
 
254
- if (retcode === 0 || retcode === 500) {
255
  queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
256
  }
257
  return ret?.data;
@@ -281,12 +281,12 @@ export const useNextWebCrawl = () => {
281
  formData.append('kb_id', knowledgeId);
282
 
283
  const ret = await kbService.web_crawl(formData);
284
- const retcode = get(ret, 'data.retcode');
285
- if (retcode === 0) {
286
  message.success(i18n.t('message.uploaded'));
287
  }
288
 
289
- return retcode;
290
  },
291
  });
292
 
@@ -317,13 +317,13 @@ export const useRunNextDocument = () => {
317
  doc_ids: documentIds,
318
  run,
319
  });
320
- const retcode = get(ret, 'data.retcode');
321
- if (retcode === 0) {
322
  queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
323
  message.success(i18n.t('message.operated'));
324
  }
325
 
326
- return retcode;
327
  },
328
  });
329
 
@@ -338,7 +338,7 @@ export const useFetchDocumentInfosByIds = () => {
338
  initialData: [],
339
  queryFn: async () => {
340
  const { data } = await kbService.document_infos({ doc_ids: ids });
341
- if (data.retcode === 0) {
342
  return data.data;
343
  }
344
 
@@ -357,7 +357,7 @@ export const useFetchDocumentThumbnailsByIds = () => {
357
  initialData: {},
358
  queryFn: async () => {
359
  const { data } = await kbService.document_thumbnails({ doc_ids: ids });
360
- if (data.retcode === 0) {
361
  return data.data;
362
  }
363
  return {};
@@ -377,11 +377,11 @@ export const useRemoveNextDocument = () => {
377
  mutationKey: ['removeDocument'],
378
  mutationFn: async (documentIds: string | string[]) => {
379
  const { data } = await kbService.document_rm({ doc_id: documentIds });
380
- if (data.retcode === 0) {
381
  message.success(i18n.t('message.deleted'));
382
  queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
383
  }
384
- return data.retcode;
385
  },
386
  });
387
 
@@ -398,7 +398,7 @@ export const useDeleteDocument = () => {
398
  mutationKey: ['deleteDocument'],
399
  mutationFn: async (documentIds: string[]) => {
400
  const data = await kbService.document_delete({ doc_ids: documentIds });
401
- // if (data.retcode === 0) {
402
  // queryClient.invalidateQueries({ queryKey: ['fetchFlowList'] });
403
  // }
404
  return data;
 
69
  page_size: pagination.pageSize,
70
  page: pagination.current,
71
  });
72
+ if (ret.data.code === 0) {
73
  return ret.data.data;
74
  }
75
 
 
118
  doc_id: documentId,
119
  status: Number(status),
120
  });
121
+ if (data.code === 0) {
122
  message.success(i18n.t('message.modified'));
123
  queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
124
  }
 
149
  doc_id: documentId,
150
  name: name,
151
  });
152
+ if (data.code === 0) {
153
  message.success(i18n.t('message.renamed'));
154
  queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
155
  }
156
+ return data.code;
157
  },
158
  });
159
 
 
176
  name,
177
  kb_id: knowledgeId,
178
  });
179
+ if (data.code === 0) {
180
  if (page === 1) {
181
  queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
182
  } else {
 
185
 
186
  message.success(i18n.t('message.created'));
187
  }
188
+ return data.code;
189
  },
190
  });
191
 
 
215
  doc_id: documentId,
216
  parser_config: parserConfig,
217
  });
218
+ if (data.code === 0) {
219
  queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
220
 
221
  message.success(i18n.t('message.modified'));
222
  }
223
+ return data.code;
224
  },
225
  });
226
 
 
246
 
247
  try {
248
  const ret = await kbService.document_upload(formData);
249
+ const code = get(ret, 'data.code');
250
+ if (code === 0) {
251
  message.success(i18n.t('message.uploaded'));
252
  }
253
 
254
+ if (code === 0 || code === 500) {
255
  queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
256
  }
257
  return ret?.data;
 
281
  formData.append('kb_id', knowledgeId);
282
 
283
  const ret = await kbService.web_crawl(formData);
284
+ const code = get(ret, 'data.code');
285
+ if (code === 0) {
286
  message.success(i18n.t('message.uploaded'));
287
  }
288
 
289
+ return code;
290
  },
291
  });
292
 
 
317
  doc_ids: documentIds,
318
  run,
319
  });
320
+ const code = get(ret, 'data.code');
321
+ if (code === 0) {
322
  queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
323
  message.success(i18n.t('message.operated'));
324
  }
325
 
326
+ return code;
327
  },
328
  });
329
 
 
338
  initialData: [],
339
  queryFn: async () => {
340
  const { data } = await kbService.document_infos({ doc_ids: ids });
341
+ if (data.code === 0) {
342
  return data.data;
343
  }
344
 
 
357
  initialData: {},
358
  queryFn: async () => {
359
  const { data } = await kbService.document_thumbnails({ doc_ids: ids });
360
+ if (data.code === 0) {
361
  return data.data;
362
  }
363
  return {};
 
377
  mutationKey: ['removeDocument'],
378
  mutationFn: async (documentIds: string | string[]) => {
379
  const { data } = await kbService.document_rm({ doc_id: documentIds });
380
+ if (data.code === 0) {
381
  message.success(i18n.t('message.deleted'));
382
  queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] });
383
  }
384
+ return data.code;
385
  },
386
  });
387
 
 
398
  mutationKey: ['deleteDocument'],
399
  mutationFn: async (documentIds: string[]) => {
400
  const data = await kbService.document_delete({ doc_ids: documentIds });
401
+ // if (data.code === 0) {
402
  // queryClient.invalidateQueries({ queryKey: ['fetchFlowList'] });
403
  // }
404
  return data;
web/src/hooks/file-manager-hooks.ts CHANGED
@@ -103,11 +103,11 @@ export const useDeleteFile = () => {
103
  mutationKey: ['deleteFile'],
104
  mutationFn: async (params: { fileIds: string[]; parentId: string }) => {
105
  const { data } = await fileManagerService.removeFile(params);
106
- if (data.retcode === 0) {
107
  setPaginationParams(1); // TODO: There should be a better way to paginate the request list
108
  queryClient.invalidateQueries({ queryKey: ['fetchFileList'] });
109
  }
110
- return data.retcode;
111
  },
112
  });
113
 
@@ -125,11 +125,11 @@ export const useRenameFile = () => {
125
  mutationKey: ['renameFile'],
126
  mutationFn: async (params: { fileId: string; name: string }) => {
127
  const { data } = await fileManagerService.renameFile(params);
128
- if (data.retcode === 0) {
129
  message.success(t('message.renamed'));
130
  queryClient.invalidateQueries({ queryKey: ['fetchFileList'] });
131
  }
132
- return data.retcode;
133
  },
134
  });
135
 
@@ -170,12 +170,12 @@ export const useCreateFolder = () => {
170
  ...params,
171
  type: 'folder',
172
  });
173
- if (data.retcode === 0) {
174
  message.success(t('message.created'));
175
  setPaginationParams(1);
176
  queryClient.invalidateQueries({ queryKey: ['fetchFileList'] });
177
  }
178
- return data.retcode;
179
  },
180
  });
181
 
@@ -208,12 +208,12 @@ export const useUploadFile = () => {
208
  });
209
  try {
210
  const ret = await fileManagerService.uploadFile(formData);
211
- if (ret?.data.retcode === 0) {
212
  message.success(t('message.uploaded'));
213
  setPaginationParams(1);
214
  queryClient.invalidateQueries({ queryKey: ['fetchFileList'] });
215
  }
216
- return ret?.data?.retcode;
217
  } catch (error) {
218
  console.log('🚀 ~ useUploadFile ~ error:', error);
219
  }
@@ -235,11 +235,11 @@ export const useConnectToKnowledge = () => {
235
  mutationKey: ['connectFileToKnowledge'],
236
  mutationFn: async (params: IConnectRequestBody) => {
237
  const { data } = await fileManagerService.connectFileToKnowledge(params);
238
- if (data.retcode === 0) {
239
  message.success(t('message.operated'));
240
  queryClient.invalidateQueries({ queryKey: ['fetchFileList'] });
241
  }
242
- return data.retcode;
243
  },
244
  });
245
 
@@ -263,11 +263,11 @@ export const useMoveFile = () => {
263
  mutationKey: ['moveFile'],
264
  mutationFn: async (params: IMoveFileBody) => {
265
  const { data } = await fileManagerService.moveFile(params);
266
- if (data.retcode === 0) {
267
  message.success(t('message.operated'));
268
  queryClient.invalidateQueries({ queryKey: ['fetchFileList'] });
269
  }
270
- return data.retcode;
271
  },
272
  });
273
 
 
103
  mutationKey: ['deleteFile'],
104
  mutationFn: async (params: { fileIds: string[]; parentId: string }) => {
105
  const { data } = await fileManagerService.removeFile(params);
106
+ if (data.code === 0) {
107
  setPaginationParams(1); // TODO: There should be a better way to paginate the request list
108
  queryClient.invalidateQueries({ queryKey: ['fetchFileList'] });
109
  }
110
+ return data.code;
111
  },
112
  });
113
 
 
125
  mutationKey: ['renameFile'],
126
  mutationFn: async (params: { fileId: string; name: string }) => {
127
  const { data } = await fileManagerService.renameFile(params);
128
+ if (data.code === 0) {
129
  message.success(t('message.renamed'));
130
  queryClient.invalidateQueries({ queryKey: ['fetchFileList'] });
131
  }
132
+ return data.code;
133
  },
134
  });
135
 
 
170
  ...params,
171
  type: 'folder',
172
  });
173
+ if (data.code === 0) {
174
  message.success(t('message.created'));
175
  setPaginationParams(1);
176
  queryClient.invalidateQueries({ queryKey: ['fetchFileList'] });
177
  }
178
+ return data.code;
179
  },
180
  });
181
 
 
208
  });
209
  try {
210
  const ret = await fileManagerService.uploadFile(formData);
211
+ if (ret?.data.code === 0) {
212
  message.success(t('message.uploaded'));
213
  setPaginationParams(1);
214
  queryClient.invalidateQueries({ queryKey: ['fetchFileList'] });
215
  }
216
+ return ret?.data?.code;
217
  } catch (error) {
218
  console.log('🚀 ~ useUploadFile ~ error:', error);
219
  }
 
235
  mutationKey: ['connectFileToKnowledge'],
236
  mutationFn: async (params: IConnectRequestBody) => {
237
  const { data } = await fileManagerService.connectFileToKnowledge(params);
238
+ if (data.code === 0) {
239
  message.success(t('message.operated'));
240
  queryClient.invalidateQueries({ queryKey: ['fetchFileList'] });
241
  }
242
+ return data.code;
243
  },
244
  });
245
 
 
263
  mutationKey: ['moveFile'],
264
  mutationFn: async (params: IMoveFileBody) => {
265
  const { data } = await fileManagerService.moveFile(params);
266
+ if (data.code === 0) {
267
  message.success(t('message.operated'));
268
  queryClient.invalidateQueries({ queryKey: ['fetchFileList'] });
269
  }
270
+ return data.code;
271
  },
272
  });
273
 
web/src/hooks/flow-hooks.ts CHANGED
@@ -131,7 +131,7 @@ export const useSetFlow = () => {
131
  avatar?: string;
132
  }) => {
133
  const { data = {} } = await flowService.setCanvas(params);
134
- if (data.retcode === 0) {
135
  message.success(
136
  i18n.t(`message.${params?.id ? 'modified' : 'created'}`),
137
  );
@@ -154,7 +154,7 @@ export const useDeleteFlow = () => {
154
  mutationKey: ['deleteFlow'],
155
  mutationFn: async (canvasIds: string[]) => {
156
  const { data } = await flowService.removeCanvas({ canvasIds });
157
- if (data.retcode === 0) {
158
  queryClient.invalidateQueries({ queryKey: ['fetchFlowList'] });
159
  }
160
  return data?.data ?? [];
@@ -173,7 +173,7 @@ export const useRunFlow = () => {
173
  mutationKey: ['runFlow'],
174
  mutationFn: async (params: { id: string; dsl: DSL }) => {
175
  const { data } = await flowService.runCanvas(params);
176
- if (data.retcode === 0) {
177
  message.success(i18n.t(`message.modified`));
178
  }
179
  return data?.data ?? {};
@@ -209,7 +209,7 @@ export const useTestDbConnect = () => {
209
  mutationKey: ['testDbConnect'],
210
  mutationFn: async (params: any) => {
211
  const ret = await flowService.testDbConnect(params);
212
- if (ret?.data?.retcode === 0) {
213
  message.success(ret?.data?.data);
214
  } else {
215
  message.error(ret?.data?.data);
 
131
  avatar?: string;
132
  }) => {
133
  const { data = {} } = await flowService.setCanvas(params);
134
+ if (data.code === 0) {
135
  message.success(
136
  i18n.t(`message.${params?.id ? 'modified' : 'created'}`),
137
  );
 
154
  mutationKey: ['deleteFlow'],
155
  mutationFn: async (canvasIds: string[]) => {
156
  const { data } = await flowService.removeCanvas({ canvasIds });
157
+ if (data.code === 0) {
158
  queryClient.invalidateQueries({ queryKey: ['fetchFlowList'] });
159
  }
160
  return data?.data ?? [];
 
173
  mutationKey: ['runFlow'],
174
  mutationFn: async (params: { id: string; dsl: DSL }) => {
175
  const { data } = await flowService.runCanvas(params);
176
+ if (data.code === 0) {
177
  message.success(i18n.t(`message.modified`));
178
  }
179
  return data?.data ?? {};
 
209
  mutationKey: ['testDbConnect'],
210
  mutationFn: async (params: any) => {
211
  const ret = await flowService.testDbConnect(params);
212
+ if (ret?.data?.code === 0) {
213
  message.success(ret?.data?.data);
214
  } else {
215
  message.error(ret?.data?.data);
web/src/hooks/knowledge-hooks.ts CHANGED
@@ -70,7 +70,7 @@ export const useCreateKnowledge = () => {
70
  mutationKey: ['createKnowledge'],
71
  mutationFn: async (params: { id?: string; name: string }) => {
72
  const { data = {} } = await kbService.createKb(params);
73
- if (data.retcode === 0) {
74
  message.success(
75
  i18n.t(`message.${params?.id ? 'modified' : 'created'}`),
76
  );
@@ -93,7 +93,7 @@ export const useDeleteKnowledge = () => {
93
  mutationKey: ['deleteKnowledge'],
94
  mutationFn: async (id: string) => {
95
  const { data } = await kbService.rmKb({ kb_id: id });
96
- if (data.retcode === 0) {
97
  message.success(i18n.t(`message.deleted`));
98
  queryClient.invalidateQueries({ queryKey: ['fetchKnowledgeList'] });
99
  }
@@ -120,7 +120,7 @@ export const useUpdateKnowledge = () => {
120
  kb_id: knowledgeBaseId,
121
  ...params,
122
  });
123
- if (data.retcode === 0) {
124
  message.success(i18n.t(`message.updated`));
125
  queryClient.invalidateQueries({ queryKey: ['fetchKnowledgeDetail'] });
126
  }
@@ -155,7 +155,7 @@ export const useTestChunkRetrieval = (): ResponsePostType<ITestingResult> & {
155
  page,
156
  size: pageSize,
157
  });
158
- if (data.retcode === 0) {
159
  const res = data.data;
160
  return {
161
  chunks: res.chunks,
 
70
  mutationKey: ['createKnowledge'],
71
  mutationFn: async (params: { id?: string; name: string }) => {
72
  const { data = {} } = await kbService.createKb(params);
73
+ if (data.code === 0) {
74
  message.success(
75
  i18n.t(`message.${params?.id ? 'modified' : 'created'}`),
76
  );
 
93
  mutationKey: ['deleteKnowledge'],
94
  mutationFn: async (id: string) => {
95
  const { data } = await kbService.rmKb({ kb_id: id });
96
+ if (data.code === 0) {
97
  message.success(i18n.t(`message.deleted`));
98
  queryClient.invalidateQueries({ queryKey: ['fetchKnowledgeList'] });
99
  }
 
120
  kb_id: knowledgeBaseId,
121
  ...params,
122
  });
123
+ if (data.code === 0) {
124
  message.success(i18n.t(`message.updated`));
125
  queryClient.invalidateQueries({ queryKey: ['fetchKnowledgeDetail'] });
126
  }
 
155
  page,
156
  size: pageSize,
157
  });
158
+ if (data.code === 0) {
159
  const res = data.data;
160
  return {
161
  chunks: res.chunks,
web/src/hooks/llm-hooks.tsx CHANGED
@@ -211,12 +211,12 @@ export const useSaveApiKey = () => {
211
  mutationKey: ['saveApiKey'],
212
  mutationFn: async (params: IApiKeySavingParams) => {
213
  const { data } = await userService.set_api_key(params);
214
- if (data.retcode === 0) {
215
  message.success(t('message.modified'));
216
  queryClient.invalidateQueries({ queryKey: ['myLlmList'] });
217
  queryClient.invalidateQueries({ queryKey: ['factoryList'] });
218
  }
219
- return data.retcode;
220
  },
221
  });
222
 
@@ -242,10 +242,10 @@ export const useSaveTenantInfo = () => {
242
  mutationKey: ['saveTenantInfo'],
243
  mutationFn: async (params: ISystemModelSettingSavingParams) => {
244
  const { data } = await userService.set_tenant_info(params);
245
- if (data.retcode === 0) {
246
  message.success(t('message.modified'));
247
  }
248
- return data.retcode;
249
  },
250
  });
251
 
@@ -263,12 +263,12 @@ export const useAddLlm = () => {
263
  mutationKey: ['addLlm'],
264
  mutationFn: async (params: IAddLlmRequestBody) => {
265
  const { data } = await userService.add_llm(params);
266
- if (data.retcode === 0) {
267
  queryClient.invalidateQueries({ queryKey: ['myLlmList'] });
268
  queryClient.invalidateQueries({ queryKey: ['factoryList'] });
269
  message.success(t('message.modified'));
270
  }
271
- return data.retcode;
272
  },
273
  });
274
 
@@ -286,12 +286,12 @@ export const useDeleteLlm = () => {
286
  mutationKey: ['deleteLlm'],
287
  mutationFn: async (params: IDeleteLlmRequestBody) => {
288
  const { data } = await userService.delete_llm(params);
289
- if (data.retcode === 0) {
290
  queryClient.invalidateQueries({ queryKey: ['myLlmList'] });
291
  queryClient.invalidateQueries({ queryKey: ['factoryList'] });
292
  message.success(t('message.deleted'));
293
  }
294
- return data.retcode;
295
  },
296
  });
297
 
@@ -309,12 +309,12 @@ export const useDeleteFactory = () => {
309
  mutationKey: ['deleteFactory'],
310
  mutationFn: async (params: IDeleteLlmRequestBody) => {
311
  const { data } = await userService.deleteFactory(params);
312
- if (data.retcode === 0) {
313
  queryClient.invalidateQueries({ queryKey: ['myLlmList'] });
314
  queryClient.invalidateQueries({ queryKey: ['factoryList'] });
315
  message.success(t('message.deleted'));
316
  }
317
- return data.retcode;
318
  },
319
  });
320
 
 
211
  mutationKey: ['saveApiKey'],
212
  mutationFn: async (params: IApiKeySavingParams) => {
213
  const { data } = await userService.set_api_key(params);
214
+ if (data.code === 0) {
215
  message.success(t('message.modified'));
216
  queryClient.invalidateQueries({ queryKey: ['myLlmList'] });
217
  queryClient.invalidateQueries({ queryKey: ['factoryList'] });
218
  }
219
+ return data.code;
220
  },
221
  });
222
 
 
242
  mutationKey: ['saveTenantInfo'],
243
  mutationFn: async (params: ISystemModelSettingSavingParams) => {
244
  const { data } = await userService.set_tenant_info(params);
245
+ if (data.code === 0) {
246
  message.success(t('message.modified'));
247
  }
248
+ return data.code;
249
  },
250
  });
251
 
 
263
  mutationKey: ['addLlm'],
264
  mutationFn: async (params: IAddLlmRequestBody) => {
265
  const { data } = await userService.add_llm(params);
266
+ if (data.code === 0) {
267
  queryClient.invalidateQueries({ queryKey: ['myLlmList'] });
268
  queryClient.invalidateQueries({ queryKey: ['factoryList'] });
269
  message.success(t('message.modified'));
270
  }
271
+ return data.code;
272
  },
273
  });
274
 
 
286
  mutationKey: ['deleteLlm'],
287
  mutationFn: async (params: IDeleteLlmRequestBody) => {
288
  const { data } = await userService.delete_llm(params);
289
+ if (data.code === 0) {
290
  queryClient.invalidateQueries({ queryKey: ['myLlmList'] });
291
  queryClient.invalidateQueries({ queryKey: ['factoryList'] });
292
  message.success(t('message.deleted'));
293
  }
294
+ return data.code;
295
  },
296
  });
297
 
 
309
  mutationKey: ['deleteFactory'],
310
  mutationFn: async (params: IDeleteLlmRequestBody) => {
311
  const { data } = await userService.deleteFactory(params);
312
+ if (data.code === 0) {
313
  queryClient.invalidateQueries({ queryKey: ['myLlmList'] });
314
  queryClient.invalidateQueries({ queryKey: ['factoryList'] });
315
  message.success(t('message.deleted'));
316
  }
317
+ return data.code;
318
  },
319
  });
320
 
web/src/hooks/logic-hooks.ts CHANGED
@@ -248,8 +248,8 @@ export const useSpeechWithSse = (url: string = api.tts) => {
248
  });
249
  try {
250
  const res = await response.clone().json();
251
- if (res?.retcode !== 0) {
252
- message.error(res?.retmsg);
253
  }
254
  } catch (error) {
255
  console.warn('🚀 ~ error:', error);
 
248
  });
249
  try {
250
  const res = await response.clone().json();
251
+ if (res?.code !== 0) {
252
+ message.error(res?.message);
253
  }
254
  } catch (error) {
255
  console.warn('🚀 ~ error:', error);
web/src/hooks/login-hooks.ts CHANGED
@@ -26,7 +26,7 @@ export const useLogin = () => {
26
  mutationKey: ['login'],
27
  mutationFn: async (params: { email: string; password: string }) => {
28
  const { data: res = {}, response } = await userService.login(params);
29
- if (res.retcode === 0) {
30
  const { data } = res;
31
  message.success(t('message.logged'));
32
  const authorization = response.headers.get(Authorization);
@@ -42,7 +42,7 @@ export const useLogin = () => {
42
  Token: token,
43
  });
44
  }
45
- return res.retcode;
46
  },
47
  });
48
 
@@ -64,10 +64,10 @@ export const useRegister = () => {
64
  nickname: string;
65
  }) => {
66
  const { data = {} } = await userService.register(params);
67
- if (data.retcode === 0) {
68
  message.success(t('message.registered'));
69
  }
70
- return data.retcode;
71
  },
72
  });
73
 
@@ -84,12 +84,12 @@ export const useLogout = () => {
84
  mutationKey: ['logout'],
85
  mutationFn: async () => {
86
  const { data = {} } = await userService.logout();
87
- if (data.retcode === 0) {
88
  message.success(t('message.logout'));
89
  authorizationUtil.removeAll();
90
  history.push('/login');
91
  }
92
- return data.retcode;
93
  },
94
  });
95
 
 
26
  mutationKey: ['login'],
27
  mutationFn: async (params: { email: string; password: string }) => {
28
  const { data: res = {}, response } = await userService.login(params);
29
+ if (res.code === 0) {
30
  const { data } = res;
31
  message.success(t('message.logged'));
32
  const authorization = response.headers.get(Authorization);
 
42
  Token: token,
43
  });
44
  }
45
+ return res.code;
46
  },
47
  });
48
 
 
64
  nickname: string;
65
  }) => {
66
  const { data = {} } = await userService.register(params);
67
+ if (data.code === 0) {
68
  message.success(t('message.registered'));
69
  }
70
+ return data.code;
71
  },
72
  });
73
 
 
84
  mutationKey: ['logout'],
85
  mutationFn: async () => {
86
  const { data = {} } = await userService.logout();
87
+ if (data.code === 0) {
88
  message.success(t('message.logout'));
89
  authorizationUtil.removeAll();
90
  history.push('/login');
91
  }
92
+ return data.code;
93
  },
94
  });
95
 
web/src/hooks/user-setting-hooks.tsx CHANGED
@@ -32,7 +32,7 @@ export const useFetchUserInfo = (): ResponseGetType<IUserInfo> => {
32
  gcTime: 0,
33
  queryFn: async () => {
34
  const { data } = await userService.user_info();
35
- if (data.retcode === 0) {
36
  i18n.changeLanguage(
37
  LanguageTranslationMap[
38
  data.data.language as keyof typeof LanguageTranslationMap
@@ -54,7 +54,7 @@ export const useFetchTenantInfo = (): ResponseGetType<ITenantInfo> => {
54
  gcTime: 0,
55
  queryFn: async () => {
56
  const { data: res } = await userService.get_tenant_info();
57
- if (res.retcode === 0) {
58
  // llm_id is chat_id
59
  // asr_id is speech2txt
60
  const { data } = res;
@@ -116,11 +116,11 @@ export const useSaveSetting = () => {
116
  userInfo: { new_password: string } | Partial<IUserInfo>,
117
  ) => {
118
  const { data } = await userService.setting(userInfo);
119
- if (data.retcode === 0) {
120
  message.success(t('message.modified'));
121
  queryClient.invalidateQueries({ queryKey: ['userInfo'] });
122
  }
123
- return data?.retcode;
124
  },
125
  });
126
 
@@ -135,7 +135,7 @@ export const useFetchSystemVersion = () => {
135
  try {
136
  setLoading(true);
137
  const { data } = await userService.getSystemVersion();
138
- if (data.retcode === 0) {
139
  setVersion(data.data);
140
  setLoading(false);
141
  }
@@ -156,7 +156,7 @@ export const useFetchSystemStatus = () => {
156
  const fetchSystemStatus = useCallback(async () => {
157
  setLoading(true);
158
  const { data } = await userService.getSystemStatus();
159
- if (data.retcode === 0) {
160
  setSystemStatus(data.data);
161
  setLoading(false);
162
  }
@@ -200,7 +200,7 @@ export const useRemoveSystemToken = () => {
200
  mutationKey: ['removeSystemToken'],
201
  mutationFn: async (token: string) => {
202
  const { data } = await userService.removeToken({}, token);
203
- if (data.retcode === 0) {
204
  message.success(t('message.deleted'));
205
  queryClient.invalidateQueries({ queryKey: ['fetchSystemTokenList'] });
206
  }
@@ -221,7 +221,7 @@ export const useCreateSystemToken = () => {
221
  mutationKey: ['createSystemToken'],
222
  mutationFn: async (params: Record<string, any>) => {
223
  const { data } = await userService.createToken(params);
224
- if (data.retcode === 0) {
225
  queryClient.invalidateQueries({ queryKey: ['fetchSystemTokenList'] });
226
  }
227
  return data?.data ?? [];
@@ -264,10 +264,10 @@ export const useAddTenantUser = () => {
264
  mutationKey: ['addTenantUser'],
265
  mutationFn: async (email: string) => {
266
  const { data } = await addTenantUser(tenantInfo.tenant_id, email);
267
- if (data.retcode === 0) {
268
  queryClient.invalidateQueries({ queryKey: ['listTenantUser'] });
269
  }
270
- return data?.retcode;
271
  },
272
  });
273
 
@@ -296,7 +296,7 @@ export const useDeleteTenantUser = () => {
296
  tenantId: tenantId ?? tenantInfo.tenant_id,
297
  userId,
298
  });
299
- if (data.retcode === 0) {
300
  message.success(t('message.deleted'));
301
  queryClient.invalidateQueries({ queryKey: ['listTenantUser'] });
302
  queryClient.invalidateQueries({ queryKey: ['listTenant'] });
@@ -342,7 +342,7 @@ export const useAgreeTenant = () => {
342
  mutationKey: ['agreeTenant'],
343
  mutationFn: async (tenantId: string) => {
344
  const { data } = await agreeTenant(tenantId);
345
- if (data.retcode === 0) {
346
  message.success(t('message.operated'));
347
  queryClient.invalidateQueries({ queryKey: ['listTenant'] });
348
  }
 
32
  gcTime: 0,
33
  queryFn: async () => {
34
  const { data } = await userService.user_info();
35
+ if (data.code === 0) {
36
  i18n.changeLanguage(
37
  LanguageTranslationMap[
38
  data.data.language as keyof typeof LanguageTranslationMap
 
54
  gcTime: 0,
55
  queryFn: async () => {
56
  const { data: res } = await userService.get_tenant_info();
57
+ if (res.code === 0) {
58
  // llm_id is chat_id
59
  // asr_id is speech2txt
60
  const { data } = res;
 
116
  userInfo: { new_password: string } | Partial<IUserInfo>,
117
  ) => {
118
  const { data } = await userService.setting(userInfo);
119
+ if (data.code === 0) {
120
  message.success(t('message.modified'));
121
  queryClient.invalidateQueries({ queryKey: ['userInfo'] });
122
  }
123
+ return data?.code;
124
  },
125
  });
126
 
 
135
  try {
136
  setLoading(true);
137
  const { data } = await userService.getSystemVersion();
138
+ if (data.code === 0) {
139
  setVersion(data.data);
140
  setLoading(false);
141
  }
 
156
  const fetchSystemStatus = useCallback(async () => {
157
  setLoading(true);
158
  const { data } = await userService.getSystemStatus();
159
+ if (data.code === 0) {
160
  setSystemStatus(data.data);
161
  setLoading(false);
162
  }
 
200
  mutationKey: ['removeSystemToken'],
201
  mutationFn: async (token: string) => {
202
  const { data } = await userService.removeToken({}, token);
203
+ if (data.code === 0) {
204
  message.success(t('message.deleted'));
205
  queryClient.invalidateQueries({ queryKey: ['fetchSystemTokenList'] });
206
  }
 
221
  mutationKey: ['createSystemToken'],
222
  mutationFn: async (params: Record<string, any>) => {
223
  const { data } = await userService.createToken(params);
224
+ if (data.code === 0) {
225
  queryClient.invalidateQueries({ queryKey: ['fetchSystemTokenList'] });
226
  }
227
  return data?.data ?? [];
 
264
  mutationKey: ['addTenantUser'],
265
  mutationFn: async (email: string) => {
266
  const { data } = await addTenantUser(tenantInfo.tenant_id, email);
267
+ if (data.code === 0) {
268
  queryClient.invalidateQueries({ queryKey: ['listTenantUser'] });
269
  }
270
+ return data?.code;
271
  },
272
  });
273
 
 
296
  tenantId: tenantId ?? tenantInfo.tenant_id,
297
  userId,
298
  });
299
+ if (data.code === 0) {
300
  message.success(t('message.deleted'));
301
  queryClient.invalidateQueries({ queryKey: ['listTenantUser'] });
302
  queryClient.invalidateQueries({ queryKey: ['listTenant'] });
 
342
  mutationKey: ['agreeTenant'],
343
  mutationFn: async (tenantId: string) => {
344
  const { data } = await agreeTenant(tenantId);
345
+ if (data.code === 0) {
346
  message.success(t('message.operated'));
347
  queryClient.invalidateQueries({ queryKey: ['listTenant'] });
348
  }
web/src/interfaces/database/base.ts CHANGED
@@ -1,7 +1,7 @@
1
  export interface ResponseType<T = any> {
2
- retcode: number;
3
  data: T;
4
- retmsg: string;
5
  status: number;
6
  }
7
 
 
1
  export interface ResponseType<T = any> {
2
+ code: number;
3
  data: T;
4
+ message: string;
5
  status: number;
6
  }
7
 
web/src/pages/add-knowledge/components/knowledge-chunk/components/chunk-creating-modal/index.tsx CHANGED
@@ -30,7 +30,7 @@ const ChunkCreatingModal: React.FC<IModalProps<any> & kFProps> = ({
30
  const { t } = useTranslation();
31
 
32
  useEffect(() => {
33
- if (data?.retcode === 0) {
34
  const { content_with_weight, important_kwd = [] } = data.data;
35
  form.setFieldsValue({ content: content_with_weight });
36
  setKeywords(important_kwd);
 
30
  const { t } = useTranslation();
31
 
32
  useEffect(() => {
33
+ if (data?.code === 0) {
34
  const { content_with_weight, important_kwd = [] } = data.data;
35
  form.setFieldsValue({ content: content_with_weight });
36
  setKeywords(important_kwd);
web/src/pages/add-knowledge/components/knowledge-chunk/hooks.ts CHANGED
@@ -96,14 +96,14 @@ export const useUpdateChunk = () => {
96
 
97
  const onChunkUpdatingOk = useCallback(
98
  async ({ content, keywords }: { content: string; keywords: string }) => {
99
- const retcode = await createChunk({
100
  content_with_weight: content,
101
  doc_id: documentId,
102
  chunk_id: chunkId,
103
  important_kwd: keywords, // keywords
104
  });
105
 
106
- if (retcode === 0) {
107
  hideChunkUpdatingModal();
108
  }
109
  },
 
96
 
97
  const onChunkUpdatingOk = useCallback(
98
  async ({ content, keywords }: { content: string; keywords: string }) => {
99
+ const code = await createChunk({
100
  content_with_weight: content,
101
  doc_id: documentId,
102
  chunk_id: chunkId,
103
  important_kwd: keywords, // keywords
104
  });
105
 
106
+ if (code === 0) {
107
  hideChunkUpdatingModal();
108
  }
109
  },
web/src/pages/add-knowledge/components/knowledge-file/hooks.ts CHANGED
@@ -148,20 +148,20 @@ export const useHandleUploadDocument = () => {
148
  async (fileList: UploadFile[]): Promise<number | undefined> => {
149
  if (fileList.length > 0) {
150
  const ret: any = await uploadDocument(fileList);
151
- if (typeof ret?.retmsg !== 'string') {
152
  return;
153
  }
154
- const count = getUnSupportedFilesCount(ret?.retmsg);
155
  /// 500 error code indicates that some file types are not supported
156
- let retcode = ret?.retcode;
157
  if (
158
- ret?.retcode === 0 ||
159
- (ret?.retcode === 500 && count !== fileList.length) // Some files were not uploaded successfully, but some were uploaded successfully.
160
  ) {
161
- retcode = 0;
162
  hideDocumentUploadModal();
163
  }
164
- return retcode;
165
  }
166
  },
167
  [uploadDocument, hideDocumentUploadModal],
 
148
  async (fileList: UploadFile[]): Promise<number | undefined> => {
149
  if (fileList.length > 0) {
150
  const ret: any = await uploadDocument(fileList);
151
+ if (typeof ret?.message !== 'string') {
152
  return;
153
  }
154
+ const count = getUnSupportedFilesCount(ret?.message);
155
  /// 500 error code indicates that some file types are not supported
156
+ let code = ret?.code;
157
  if (
158
+ ret?.code === 0 ||
159
+ (ret?.code === 500 && count !== fileList.length) // Some files were not uploaded successfully, but some were uploaded successfully.
160
  ) {
161
+ code = 0;
162
  hideDocumentUploadModal();
163
  }
164
+ return code;
165
  }
166
  },
167
  [uploadDocument, hideDocumentUploadModal],
web/src/pages/chat/hooks.ts CHANGED
@@ -176,7 +176,7 @@ export const useEditDialog = () => {
176
  async (dialogId?: string) => {
177
  if (dialogId) {
178
  const ret = await fetchDialog(dialogId);
179
- if (ret.retcode === 0) {
180
  setDialog(ret.data);
181
  }
182
  }
@@ -393,7 +393,7 @@ export const useSendNextMessage = (controller: AbortController) => {
393
  controller,
394
  );
395
 
396
- if (res && (res?.response.status !== 200 || res?.data?.retcode !== 0)) {
397
  // cancel loading
398
  setValue(message.content);
399
  console.info('removeLatestMessage111');
@@ -421,7 +421,7 @@ export const useSendNextMessage = (controller: AbortController) => {
421
  true,
422
  conversationId,
423
  );
424
- if (data.retcode === 0) {
425
  setConversationIsNew('');
426
  const id = data.data.id;
427
  // currentConversationIdRef.current = id;
@@ -541,7 +541,7 @@ export const useRenameConversation = () => {
541
  is_new: false,
542
  });
543
 
544
- if (ret.retcode === 0) {
545
  hideConversationRenameModal();
546
  }
547
  },
@@ -551,7 +551,7 @@ export const useRenameConversation = () => {
551
  const handleShowConversationRenameModal = useCallback(
552
  async (conversationId: string) => {
553
  const ret = await fetchConversation(conversationId);
554
- if (ret.retcode === 0) {
555
  setConversation(ret.data);
556
  }
557
  showConversationRenameModal();
 
176
  async (dialogId?: string) => {
177
  if (dialogId) {
178
  const ret = await fetchDialog(dialogId);
179
+ if (ret.code === 0) {
180
  setDialog(ret.data);
181
  }
182
  }
 
393
  controller,
394
  );
395
 
396
+ if (res && (res?.response.status !== 200 || res?.data?.code !== 0)) {
397
  // cancel loading
398
  setValue(message.content);
399
  console.info('removeLatestMessage111');
 
421
  true,
422
  conversationId,
423
  );
424
+ if (data.code === 0) {
425
  setConversationIsNew('');
426
  const id = data.data.id;
427
  // currentConversationIdRef.current = id;
 
541
  is_new: false,
542
  });
543
 
544
+ if (ret.code === 0) {
545
  hideConversationRenameModal();
546
  }
547
  },
 
551
  const handleShowConversationRenameModal = useCallback(
552
  async (conversationId: string) => {
553
  const ret = await fetchConversation(conversationId);
554
+ if (ret.code === 0) {
555
  setConversation(ret.data);
556
  }
557
  showConversationRenameModal();
web/src/pages/chat/shared-hooks.ts CHANGED
@@ -96,7 +96,7 @@ export const useSendSharedMessage = (conversationId: string) => {
96
  messages: [...(derivedMessages ?? []), message],
97
  });
98
 
99
- if (res && (res?.response.status !== 200 || res?.data?.retcode !== 0)) {
100
  // cancel loading
101
  setValue(message.content);
102
  removeLatestMessage();
@@ -111,7 +111,7 @@ export const useSendSharedMessage = (conversationId: string) => {
111
  sendMessage(message);
112
  } else {
113
  const data = await setConversation('user id');
114
- if (data.retcode === 0) {
115
  const id = data.data.id;
116
  sendMessage(message, id);
117
  }
 
96
  messages: [...(derivedMessages ?? []), message],
97
  });
98
 
99
+ if (res && (res?.response.status !== 200 || res?.data?.code !== 0)) {
100
  // cancel loading
101
  setValue(message.content);
102
  removeLatestMessage();
 
111
  sendMessage(message);
112
  } else {
113
  const data = await setConversation('user id');
114
+ if (data.code === 0) {
115
  const id = data.data.id;
116
  sendMessage(message, id);
117
  }
web/src/pages/document-viewer/hooks.ts CHANGED
@@ -8,8 +8,8 @@ export const useCatchError = (api: string) => {
8
  const fetchDocument = useCallback(async () => {
9
  const ret = await axios.get(api);
10
  const { data } = ret;
11
- if (!(data instanceof ArrayBuffer) && data.retcode !== 0) {
12
- setError(data.retmsg);
13
  }
14
  return ret;
15
  }, [api]);
 
8
  const fetchDocument = useCallback(async () => {
9
  const ret = await axios.get(api);
10
  const { data } = ret;
11
+ if (!(data instanceof ArrayBuffer) && data.code !== 0) {
12
+ setError(data.message);
13
  }
14
  return ret;
15
  }, [api]);
web/src/pages/file-manager/hooks.ts CHANGED
@@ -141,8 +141,8 @@ export const useHandleDeleteFile = (
141
  const handleRemoveFile = () => {
142
  showDeleteConfirm({
143
  onOk: async () => {
144
- const retcode = await removeDocument({ fileIds, parentId });
145
- if (retcode === 0) {
146
  setSelectedRowKeys([]);
147
  }
148
  return;
 
141
  const handleRemoveFile = () => {
142
  showDeleteConfirm({
143
  onOk: async () => {
144
+ const code = await removeDocument({ fileIds, parentId });
145
+ if (code === 0) {
146
  setSelectedRowKeys([]);
147
  }
148
  return;
web/src/pages/file-manager/move-file-modal/async-tree-select.tsx CHANGED
@@ -22,7 +22,7 @@ const AsyncTreeSelect = ({ value, onChange }: IProps) => {
22
  const onLoadData: TreeSelectProps['loadData'] = useCallback(
23
  async ({ id }) => {
24
  const ret = await fetchList(id);
25
- if (ret.retcode === 0) {
26
  setTreeData((tree) => {
27
  return tree.concat(
28
  ret.data.files
 
22
  const onLoadData: TreeSelectProps['loadData'] = useCallback(
23
  async ({ id }) => {
24
  const ret = await fetchList(id);
25
+ if (ret.code === 0) {
26
  setTreeData((tree) => {
27
  return tree.concat(
28
  ret.data.files
web/src/pages/flow/chat/hooks.ts CHANGED
@@ -151,7 +151,7 @@ export const useSendMessage = (
151
  const res = await send(params);
152
 
153
  if (receiveMessageError(res)) {
154
- antMessage.error(res?.data?.retmsg);
155
 
156
  // cancel loading
157
  setValue(message.content);
@@ -227,7 +227,7 @@ export const useSendNextMessage = () => {
227
  const res = await send(params);
228
 
229
  if (receiveMessageError(res)) {
230
- antMessage.error(res?.data?.retmsg);
231
 
232
  // cancel loading
233
  setValue(message.content);
 
151
  const res = await send(params);
152
 
153
  if (receiveMessageError(res)) {
154
+ antMessage.error(res?.data?.message);
155
 
156
  // cancel loading
157
  setValue(message.content);
 
227
  const res = await send(params);
228
 
229
  if (receiveMessageError(res)) {
230
+ antMessage.error(res?.data?.message);
231
 
232
  // cancel loading
233
  setValue(message.content);
web/src/pages/flow/hooks.ts CHANGED
@@ -497,15 +497,15 @@ export const useSaveGraphBeforeOpeningDebugDrawer = (show: () => void) => {
497
  const { send } = useSendMessageWithSse(api.runCanvas);
498
  const handleRun = useCallback(async () => {
499
  const saveRet = await saveGraph();
500
- if (saveRet?.retcode === 0) {
501
  // Call the reset api before opening the run drawer each time
502
  const resetRet = await resetFlow();
503
  // After resetting, all previous messages will be cleared.
504
- if (resetRet?.retcode === 0) {
505
  // fetch prologue
506
  const sendRet = await send({ id });
507
  if (receiveMessageError(sendRet)) {
508
- message.error(sendRet?.data?.retmsg);
509
  } else {
510
  refetch();
511
  show();
 
497
  const { send } = useSendMessageWithSse(api.runCanvas);
498
  const handleRun = useCallback(async () => {
499
  const saveRet = await saveGraph();
500
+ if (saveRet?.code === 0) {
501
  // Call the reset api before opening the run drawer each time
502
  const resetRet = await resetFlow();
503
  // After resetting, all previous messages will be cleared.
504
+ if (resetRet?.code === 0) {
505
  // fetch prologue
506
  const sendRet = await send({ id });
507
  if (receiveMessageError(sendRet)) {
508
+ message.error(sendRet?.data?.message);
509
  } else {
510
  refetch();
511
  show();
web/src/pages/flow/list/hooks.ts CHANGED
@@ -53,7 +53,7 @@ export const useSaveFlow = () => {
53
  // },
54
  });
55
 
56
- if (ret?.retcode === 0) {
57
  hideFlowSettingModal();
58
  navigate(`/flow/${ret.data.id}`);
59
  }
 
53
  // },
54
  });
55
 
56
+ if (ret?.code === 0) {
57
  hideFlowSettingModal();
58
  navigate(`/flow/${ret.data.id}`);
59
  }
web/src/pages/flow/utils.ts CHANGED
@@ -144,7 +144,7 @@ export const buildDslComponentsByGraph = (
144
  };
145
 
146
  export const receiveMessageError = (res: any) =>
147
- res && (res?.response.status !== 200 || res?.data?.retcode !== 0);
148
 
149
  // Replace the id in the object with text
150
  export const replaceIdWithText = (
 
144
  };
145
 
146
  export const receiveMessageError = (res: any) =>
147
+ res && (res?.response.status !== 200 || res?.data?.code !== 0);
148
 
149
  // Replace the id in the object with text
150
  export const replaceIdWithText = (
web/src/pages/knowledge/hooks.ts CHANGED
@@ -27,7 +27,7 @@ export const useSaveKnowledge = () => {
27
  name,
28
  });
29
 
30
- if (ret?.retcode === 0) {
31
  hideModal();
32
  navigate(
33
  `/knowledge/${KnowledgeRouteKey.Configuration}?id=${ret.data.kb_id}`,
 
27
  name,
28
  });
29
 
30
+ if (ret?.code === 0) {
31
  hideModal();
32
  navigate(
33
  `/knowledge/${KnowledgeRouteKey.Configuration}?id=${ret.data.kb_id}`,