### What problem does this PR solve? Unified API response json schema ### Type of change - [x] Refactoringtags/v0.14.0
| try: | try: | ||||
| tenants = UserTenantService.query(user_id=current_user.id) | tenants = UserTenantService.query(user_id=current_user.id) | ||||
| if not tenants: | if not tenants: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| tenant_id = tenants[0].tenant_id | tenant_id = tenants[0].tenant_id | ||||
| obj = {"tenant_id": tenant_id, "token": generate_confirmation_token(tenant_id), | obj = {"tenant_id": tenant_id, "token": generate_confirmation_token(tenant_id), | ||||
| obj["dialog_id"] = req["dialog_id"] | obj["dialog_id"] = req["dialog_id"] | ||||
| if not APITokenService.save(**obj): | if not APITokenService.save(**obj): | ||||
| return get_data_error_result(retmsg="Fail to new a dialog!") | |||||
| return get_data_error_result(message="Fail to new a dialog!") | |||||
| return get_json_result(data=obj) | return get_json_result(data=obj) | ||||
| except Exception as e: | except Exception as e: | ||||
| try: | try: | ||||
| tenants = UserTenantService.query(user_id=current_user.id) | tenants = UserTenantService.query(user_id=current_user.id) | ||||
| if not tenants: | if not tenants: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| id = request.args["dialog_id"] if "dialog_id" in request.args else request.args["canvas_id"] | id = request.args["dialog_id"] if "dialog_id" in request.args else request.args["canvas_id"] | ||||
| objs = APITokenService.query(tenant_id=tenants[0].tenant_id, dialog_id=id) | objs = APITokenService.query(tenant_id=tenants[0].tenant_id, dialog_id=id) | ||||
| try: | try: | ||||
| tenants = UserTenantService.query(user_id=current_user.id) | tenants = UserTenantService.query(user_id=current_user.id) | ||||
| if not tenants: | if not tenants: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| objs = API4ConversationService.stats( | objs = API4ConversationService.stats( | ||||
| tenants[0].tenant_id, | tenants[0].tenant_id, | ||||
| request.args.get( | request.args.get( | ||||
| objs = APIToken.query(token=token) | objs = APIToken.query(token=token) | ||||
| if not objs: | if not objs: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR) | |||||
| req = request.json | req = request.json | ||||
| try: | try: | ||||
| if objs[0].source == "agent": | if objs[0].source == "agent": | ||||
| else: | else: | ||||
| e, dia = DialogService.get_by_id(objs[0].dialog_id) | e, dia = DialogService.get_by_id(objs[0].dialog_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Dialog not found") | |||||
| return get_data_error_result(message="Dialog not found") | |||||
| conv = { | conv = { | ||||
| "id": get_uuid(), | "id": get_uuid(), | ||||
| "dialog_id": dia.id, | "dialog_id": dia.id, | ||||
| objs = APIToken.query(token=token) | objs = APIToken.query(token=token) | ||||
| if not objs: | if not objs: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR) | |||||
| req = request.json | req = request.json | ||||
| e, conv = API4ConversationService.get_by_id(req["conversation_id"]) | e, conv = API4ConversationService.get_by_id(req["conversation_id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Conversation not found!") | |||||
| return get_data_error_result(message="Conversation not found!") | |||||
| if "quote" not in req: req["quote"] = False | if "quote" not in req: req["quote"] = False | ||||
| msg = [] | msg = [] | ||||
| ans = {"answer": ans["content"], "reference": ans.get("reference", [])} | ans = {"answer": ans["content"], "reference": ans.get("reference", [])} | ||||
| fillin_conv(ans) | fillin_conv(ans) | ||||
| rename_field(ans) | rename_field(ans) | ||||
| yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans}, | |||||
| yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, | |||||
| ensure_ascii=False) + "\n\n" | ensure_ascii=False) + "\n\n" | ||||
| canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) | canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) | ||||
| cvs.dsl = json.loads(str(canvas)) | cvs.dsl = json.loads(str(canvas)) | ||||
| API4ConversationService.append_message(conv.id, conv.to_dict()) | API4ConversationService.append_message(conv.id, conv.to_dict()) | ||||
| except Exception as e: | except Exception as e: | ||||
| yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e), | |||||
| yield "data:" + json.dumps({"code": 500, "message": str(e), | |||||
| "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, | "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, | ||||
| ensure_ascii=False) + "\n\n" | ensure_ascii=False) + "\n\n" | ||||
| yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n" | |||||
| yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n" | |||||
| resp = Response(sse(), mimetype="text/event-stream") | resp = Response(sse(), mimetype="text/event-stream") | ||||
| resp.headers.add_header("Cache-control", "no-cache") | resp.headers.add_header("Cache-control", "no-cache") | ||||
| conv.message.append(msg[-1]) | conv.message.append(msg[-1]) | ||||
| e, dia = DialogService.get_by_id(conv.dialog_id) | e, dia = DialogService.get_by_id(conv.dialog_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Dialog not found!") | |||||
| return get_data_error_result(message="Dialog not found!") | |||||
| del req["conversation_id"] | del req["conversation_id"] | ||||
| del req["messages"] | del req["messages"] | ||||
| for ans in chat(dia, msg, True, **req): | for ans in chat(dia, msg, True, **req): | ||||
| fillin_conv(ans) | fillin_conv(ans) | ||||
| rename_field(ans) | rename_field(ans) | ||||
| yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans}, | |||||
| yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, | |||||
| ensure_ascii=False) + "\n\n" | ensure_ascii=False) + "\n\n" | ||||
| API4ConversationService.append_message(conv.id, conv.to_dict()) | API4ConversationService.append_message(conv.id, conv.to_dict()) | ||||
| except Exception as e: | except Exception as e: | ||||
| yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e), | |||||
| yield "data:" + json.dumps({"code": 500, "message": str(e), | |||||
| "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, | "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, | ||||
| ensure_ascii=False) + "\n\n" | ensure_ascii=False) + "\n\n" | ||||
| yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n" | |||||
| yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n" | |||||
| if req.get("stream", True): | if req.get("stream", True): | ||||
| resp = Response(stream(), mimetype="text/event-stream") | resp = Response(stream(), mimetype="text/event-stream") | ||||
| objs = APIToken.query(token=token) | objs = APIToken.query(token=token) | ||||
| if not objs: | if not objs: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR) | |||||
| try: | try: | ||||
| e, conv = API4ConversationService.get_by_id(conversation_id) | e, conv = API4ConversationService.get_by_id(conversation_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Conversation not found!") | |||||
| return get_data_error_result(message="Conversation not found!") | |||||
| conv = conv.to_dict() | conv = conv.to_dict() | ||||
| if token != APIToken.query(dialog_id=conv['dialog_id'])[0].token: | if token != APIToken.query(dialog_id=conv['dialog_id'])[0].token: | ||||
| return get_json_result(data=False, retmsg='Token is not valid for this conversation_id!"', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| return get_json_result(data=False, message='Token is not valid for this conversation_id!"', | |||||
| code=RetCode.AUTHENTICATION_ERROR) | |||||
| for referenct_i in conv['reference']: | for referenct_i in conv['reference']: | ||||
| if referenct_i is None or len(referenct_i) == 0: | if referenct_i is None or len(referenct_i) == 0: | ||||
| objs = APIToken.query(token=token) | objs = APIToken.query(token=token) | ||||
| if not objs: | if not objs: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR) | |||||
| kb_name = request.form.get("kb_name").strip() | kb_name = request.form.get("kb_name").strip() | ||||
| tenant_id = objs[0].tenant_id | tenant_id = objs[0].tenant_id | ||||
| e, kb = KnowledgebaseService.get_by_name(kb_name, tenant_id) | e, kb = KnowledgebaseService.get_by_name(kb_name, tenant_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Can't find this knowledgebase!") | |||||
| message="Can't find this knowledgebase!") | |||||
| kb_id = kb.id | kb_id = kb.id | ||||
| except Exception as e: | except Exception as e: | ||||
| return server_error_response(e) | return server_error_response(e) | ||||
| if 'file' not in request.files: | if 'file' not in request.files: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='No file part!', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='No file part!', code=RetCode.ARGUMENT_ERROR) | |||||
| file = request.files['file'] | file = request.files['file'] | ||||
| if file.filename == '': | if file.filename == '': | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='No file selected!', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='No file selected!', code=RetCode.ARGUMENT_ERROR) | |||||
| root_folder = FileService.get_root_folder(tenant_id) | root_folder = FileService.get_root_folder(tenant_id) | ||||
| pf_id = root_folder["id"] | pf_id = root_folder["id"] | ||||
| try: | try: | ||||
| if DocumentService.get_doc_count(kb.tenant_id) >= int(os.environ.get('MAX_FILE_NUM_PER_USER', 8192)): | if DocumentService.get_doc_count(kb.tenant_id) >= int(os.environ.get('MAX_FILE_NUM_PER_USER', 8192)): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Exceed the maximum file number of a free user!") | |||||
| message="Exceed the maximum file number of a free user!") | |||||
| filename = duplicate_name( | filename = duplicate_name( | ||||
| DocumentService.query, | DocumentService.query, | ||||
| filetype = filename_type(filename) | filetype = filename_type(filename) | ||||
| if not filetype: | if not filetype: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="This type of file has not been supported yet!") | |||||
| message="This type of file has not been supported yet!") | |||||
| location = filename | location = filename | ||||
| while STORAGE_IMPL.obj_exist(kb_id, location): | while STORAGE_IMPL.obj_exist(kb_id, location): | ||||
| # if str(req["run"]) == TaskStatus.CANCEL.value: | # if str(req["run"]) == TaskStatus.CANCEL.value: | ||||
| tenant_id = DocumentService.get_tenant_id(doc["id"]) | tenant_id = DocumentService.get_tenant_id(doc["id"]) | ||||
| if not tenant_id: | if not tenant_id: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| # e, doc = DocumentService.get_by_id(doc["id"]) | # e, doc = DocumentService.get_by_id(doc["id"]) | ||||
| TaskService.filter_delete([Task.doc_id == doc["id"]]) | TaskService.filter_delete([Task.doc_id == doc["id"]]) | ||||
| objs = APIToken.query(token=token) | objs = APIToken.query(token=token) | ||||
| if not objs: | if not objs: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR) | |||||
| if 'file' not in request.files: | if 'file' not in request.files: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='No file part!', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='No file part!', code=RetCode.ARGUMENT_ERROR) | |||||
| file_objs = request.files.getlist('file') | file_objs = request.files.getlist('file') | ||||
| for file_obj in file_objs: | for file_obj in file_objs: | ||||
| if file_obj.filename == '': | if file_obj.filename == '': | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='No file selected!', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='No file selected!', code=RetCode.ARGUMENT_ERROR) | |||||
| doc_ids = doc_upload_and_parse(request.form.get("conversation_id"), file_objs, objs[0].tenant_id) | doc_ids = doc_upload_and_parse(request.form.get("conversation_id"), file_objs, objs[0].tenant_id) | ||||
| return get_json_result(data=doc_ids) | return get_json_result(data=doc_ids) | ||||
| objs = APIToken.query(token=token) | objs = APIToken.query(token=token) | ||||
| if not objs: | if not objs: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR) | |||||
| req = request.json | req = request.json | ||||
| doc_id = req['doc_id'] | doc_id = req['doc_id'] | ||||
| else: | else: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg="Can't find doc_name or doc_id" | |||||
| data=False, message="Can't find doc_name or doc_id" | |||||
| ) | ) | ||||
| res = retrievaler.chunk_list(doc_id=doc_id, tenant_id=tenant_id) | res = retrievaler.chunk_list(doc_id=doc_id, tenant_id=tenant_id) | ||||
| objs = APIToken.query(token=token) | objs = APIToken.query(token=token) | ||||
| if not objs: | if not objs: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR) | |||||
| req = request.json | req = request.json | ||||
| tenant_id = objs[0].tenant_id | tenant_id = objs[0].tenant_id | ||||
| e, kb = KnowledgebaseService.get_by_name(kb_name, tenant_id) | e, kb = KnowledgebaseService.get_by_name(kb_name, tenant_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Can't find this knowledgebase!") | |||||
| message="Can't find this knowledgebase!") | |||||
| kb_id = kb.id | kb_id = kb.id | ||||
| except Exception as e: | except Exception as e: | ||||
| objs = APIToken.query(token=token) | objs = APIToken.query(token=token) | ||||
| if not objs: | if not objs: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR) | |||||
| req = request.json | req = request.json | ||||
| doc_ids = req["doc_ids"] | doc_ids = req["doc_ids"] | ||||
| docs = DocumentService.get_by_ids(doc_ids) | docs = DocumentService.get_by_ids(doc_ids) | ||||
| objs = APIToken.query(token=token) | objs = APIToken.query(token=token) | ||||
| if not objs: | if not objs: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR) | |||||
| tenant_id = objs[0].tenant_id | tenant_id = objs[0].tenant_id | ||||
| req = request.json | req = request.json | ||||
| if not doc_ids: | if not doc_ids: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg="Can't find doc_names or doc_ids" | |||||
| data=False, message="Can't find doc_names or doc_ids" | |||||
| ) | ) | ||||
| except Exception as e: | except Exception as e: | ||||
| try: | try: | ||||
| e, doc = DocumentService.get_by_id(doc_id) | e, doc = DocumentService.get_by_id(doc_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| tenant_id = DocumentService.get_tenant_id(doc_id) | tenant_id = DocumentService.get_tenant_id(doc_id) | ||||
| if not tenant_id: | if not tenant_id: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| b, n = File2DocumentService.get_storage_address(doc_id=doc_id) | b, n = File2DocumentService.get_storage_address(doc_id=doc_id) | ||||
| if not DocumentService.remove_document(doc, tenant_id): | if not DocumentService.remove_document(doc, tenant_id): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Database error (Document removal)!") | |||||
| message="Database error (Document removal)!") | |||||
| f2d = File2DocumentService.get_by_document_id(doc_id) | f2d = File2DocumentService.get_by_document_id(doc_id) | ||||
| FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id]) | FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id]) | ||||
| errors += str(e) | errors += str(e) | ||||
| if errors: | if errors: | ||||
| return get_json_result(data=False, retmsg=errors, retcode=RetCode.SERVER_ERROR) | |||||
| return get_json_result(data=False, message=errors, code=RetCode.SERVER_ERROR) | |||||
| return get_json_result(data=True) | return get_json_result(data=True) | ||||
| objs = APIToken.query(token=token) | objs = APIToken.query(token=token) | ||||
| if not objs: | if not objs: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR) | |||||
| e, conv = API4ConversationService.get_by_id(req["conversation_id"]) | e, conv = API4ConversationService.get_by_id(req["conversation_id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Conversation not found!") | |||||
| return get_data_error_result(message="Conversation not found!") | |||||
| if "quote" not in req: req["quote"] = True | if "quote" not in req: req["quote"] = True | ||||
| msg = [] | msg = [] | ||||
| conv.message.append(msg[-1]) | conv.message.append(msg[-1]) | ||||
| e, dia = DialogService.get_by_id(conv.dialog_id) | e, dia = DialogService.get_by_id(conv.dialog_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Dialog not found!") | |||||
| return get_data_error_result(message="Dialog not found!") | |||||
| del req["conversation_id"] | del req["conversation_id"] | ||||
| if not conv.reference: | if not conv.reference: | ||||
| objs = APIToken.query(token=token) | objs = APIToken.query(token=token) | ||||
| if not objs: | if not objs: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Token is not valid!"', retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| data=False, message='Token is not valid!"', code=RetCode.AUTHENTICATION_ERROR) | |||||
| req = request.json | req = request.json | ||||
| kb_ids = req.get("kb_id",[]) | kb_ids = req.get("kb_id",[]) | ||||
| embd_nms = list(set([kb.embd_id for kb in kbs])) | embd_nms = list(set([kb.embd_id for kb in kbs])) | ||||
| if len(embd_nms) != 1: | if len(embd_nms) != 1: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Knowledge bases use different embedding models or does not exist."', retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| data=False, message='Knowledge bases use different embedding models or does not exist."', code=RetCode.AUTHENTICATION_ERROR) | |||||
| embd_mdl = TenantLLMService.model_instance( | embd_mdl = TenantLLMService.model_instance( | ||||
| kbs[0].tenant_id, LLMType.EMBEDDING.value, llm_name=kbs[0].embd_id) | kbs[0].tenant_id, LLMType.EMBEDDING.value, llm_name=kbs[0].embd_id) | ||||
| return get_json_result(data=ranks) | return get_json_result(data=ranks) | ||||
| except Exception as e: | except Exception as e: | ||||
| if str(e).find("not_found") > 0: | if str(e).find("not_found") > 0: | ||||
| return get_json_result(data=False, retmsg=f'No chunk found! Check the chunk status please!', | |||||
| retcode=RetCode.DATA_ERROR) | |||||
| return get_json_result(data=False, message='No chunk found! Check the chunk status please!', | |||||
| code=RetCode.DATA_ERROR) | |||||
| return server_error_response(e) | return server_error_response(e) |
| for i in request.json["canvas_ids"]: | for i in request.json["canvas_ids"]: | ||||
| if not UserCanvasService.query(user_id=current_user.id,id=i): | if not UserCanvasService.query(user_id=current_user.id,id=i): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg=f'Only owner of canvas authorized for this operation.', | |||||
| retcode=RetCode.OPERATING_ERROR) | |||||
| data=False, message='Only owner of canvas authorized for this operation.', | |||||
| code=RetCode.OPERATING_ERROR) | |||||
| UserCanvasService.delete_by_id(i) | UserCanvasService.delete_by_id(i) | ||||
| return get_json_result(data=True) | return get_json_result(data=True) | ||||
| return server_error_response(ValueError("Duplicated title.")) | return server_error_response(ValueError("Duplicated title.")) | ||||
| req["id"] = get_uuid() | req["id"] = get_uuid() | ||||
| if not UserCanvasService.save(**req): | if not UserCanvasService.save(**req): | ||||
| return get_data_error_result(retmsg="Fail to save canvas.") | |||||
| return get_data_error_result(message="Fail to save canvas.") | |||||
| else: | else: | ||||
| if not UserCanvasService.query(user_id=current_user.id, id=req["id"]): | if not UserCanvasService.query(user_id=current_user.id, id=req["id"]): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg=f'Only owner of canvas authorized for this operation.', | |||||
| retcode=RetCode.OPERATING_ERROR) | |||||
| data=False, message='Only owner of canvas authorized for this operation.', | |||||
| code=RetCode.OPERATING_ERROR) | |||||
| UserCanvasService.update_by_id(req["id"], req) | UserCanvasService.update_by_id(req["id"], req) | ||||
| return get_json_result(data=req) | return get_json_result(data=req) | ||||
| def get(canvas_id): | def get(canvas_id): | ||||
| e, c = UserCanvasService.get_by_id(canvas_id) | e, c = UserCanvasService.get_by_id(canvas_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="canvas not found.") | |||||
| return get_data_error_result(message="canvas not found.") | |||||
| return get_json_result(data=c.to_dict()) | return get_json_result(data=c.to_dict()) | ||||
| stream = req.get("stream", True) | stream = req.get("stream", True) | ||||
| e, cvs = UserCanvasService.get_by_id(req["id"]) | e, cvs = UserCanvasService.get_by_id(req["id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="canvas not found.") | |||||
| return get_data_error_result(message="canvas not found.") | |||||
| if not UserCanvasService.query(user_id=current_user.id, id=req["id"]): | if not UserCanvasService.query(user_id=current_user.id, id=req["id"]): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg=f'Only owner of canvas authorized for this operation.', | |||||
| retcode=RetCode.OPERATING_ERROR) | |||||
| data=False, message='Only owner of canvas authorized for this operation.', | |||||
| code=RetCode.OPERATING_ERROR) | |||||
| if not isinstance(cvs.dsl, str): | if not isinstance(cvs.dsl, str): | ||||
| cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False) | cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False) | ||||
| for k in ans.keys(): | for k in ans.keys(): | ||||
| final_ans[k] = ans[k] | final_ans[k] = ans[k] | ||||
| ans = {"answer": ans["content"], "reference": ans.get("reference", [])} | ans = {"answer": ans["content"], "reference": ans.get("reference", [])} | ||||
| yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans}, ensure_ascii=False) + "\n\n" | |||||
| yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, ensure_ascii=False) + "\n\n" | |||||
| canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) | canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) | ||||
| canvas.history.append(("assistant", final_ans["content"])) | canvas.history.append(("assistant", final_ans["content"])) | ||||
| cvs.dsl = json.loads(str(canvas)) | cvs.dsl = json.loads(str(canvas)) | ||||
| UserCanvasService.update_by_id(req["id"], cvs.to_dict()) | UserCanvasService.update_by_id(req["id"], cvs.to_dict()) | ||||
| except Exception as e: | except Exception as e: | ||||
| yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e), | |||||
| yield "data:" + json.dumps({"code": 500, "message": str(e), | |||||
| "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, | "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, | ||||
| ensure_ascii=False) + "\n\n" | ensure_ascii=False) + "\n\n" | ||||
| yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n" | |||||
| yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n" | |||||
| resp = Response(sse(), mimetype="text/event-stream") | resp = Response(sse(), mimetype="text/event-stream") | ||||
| resp.headers.add_header("Cache-control", "no-cache") | resp.headers.add_header("Cache-control", "no-cache") | ||||
| try: | try: | ||||
| e, user_canvas = UserCanvasService.get_by_id(req["id"]) | e, user_canvas = UserCanvasService.get_by_id(req["id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="canvas not found.") | |||||
| return get_data_error_result(message="canvas not found.") | |||||
| if not UserCanvasService.query(user_id=current_user.id, id=req["id"]): | if not UserCanvasService.query(user_id=current_user.id, id=req["id"]): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg=f'Only owner of canvas authorized for this operation.', | |||||
| retcode=RetCode.OPERATING_ERROR) | |||||
| data=False, message='Only owner of canvas authorized for this operation.', | |||||
| code=RetCode.OPERATING_ERROR) | |||||
| canvas = Canvas(json.dumps(user_canvas.dsl), current_user.id) | canvas = Canvas(json.dumps(user_canvas.dsl), current_user.id) | ||||
| canvas.reset() | canvas.reset() |
| # | # | ||||
| import datetime | import datetime | ||||
| import json | import json | ||||
| import traceback | |||||
| from flask import request | from flask import request | ||||
| from flask_login import login_required, current_user | from flask_login import login_required, current_user | ||||
| try: | try: | ||||
| tenant_id = DocumentService.get_tenant_id(req["doc_id"]) | tenant_id = DocumentService.get_tenant_id(req["doc_id"]) | ||||
| if not tenant_id: | if not tenant_id: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| e, doc = DocumentService.get_by_id(doc_id) | e, doc = DocumentService.get_by_id(doc_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| query = { | query = { | ||||
| "doc_ids": [doc_id], "page": page, "size": size, "question": question, "sort": True | "doc_ids": [doc_id], "page": page, "size": size, "question": question, "sort": True | ||||
| } | } | ||||
| return get_json_result(data=res) | return get_json_result(data=res) | ||||
| except Exception as e: | except Exception as e: | ||||
| if str(e).find("not_found") > 0: | if str(e).find("not_found") > 0: | ||||
| return get_json_result(data=False, retmsg=f'No chunk found!', | |||||
| retcode=RetCode.DATA_ERROR) | |||||
| return get_json_result(data=False, message='No chunk found!', | |||||
| code=RetCode.DATA_ERROR) | |||||
| return server_error_response(e) | return server_error_response(e) | ||||
| try: | try: | ||||
| tenants = UserTenantService.query(user_id=current_user.id) | tenants = UserTenantService.query(user_id=current_user.id) | ||||
| if not tenants: | if not tenants: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| res = ELASTICSEARCH.get( | res = ELASTICSEARCH.get( | ||||
| chunk_id, search.index_name( | chunk_id, search.index_name( | ||||
| tenants[0].tenant_id)) | tenants[0].tenant_id)) | ||||
| return get_json_result(data=res) | return get_json_result(data=res) | ||||
| except Exception as e: | except Exception as e: | ||||
| if str(e).find("NotFoundError") >= 0: | if str(e).find("NotFoundError") >= 0: | ||||
| return get_json_result(data=False, retmsg=f'Chunk not found!', | |||||
| retcode=RetCode.DATA_ERROR) | |||||
| return get_json_result(data=False, message='Chunk not found!', | |||||
| code=RetCode.DATA_ERROR) | |||||
| return server_error_response(e) | return server_error_response(e) | ||||
| try: | try: | ||||
| tenant_id = DocumentService.get_tenant_id(req["doc_id"]) | tenant_id = DocumentService.get_tenant_id(req["doc_id"]) | ||||
| if not tenant_id: | if not tenant_id: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| embd_id = DocumentService.get_embd_id(req["doc_id"]) | embd_id = DocumentService.get_embd_id(req["doc_id"]) | ||||
| embd_mdl = LLMBundle(tenant_id, LLMType.EMBEDDING, embd_id) | embd_mdl = LLMBundle(tenant_id, LLMType.EMBEDDING, embd_id) | ||||
| e, doc = DocumentService.get_by_id(req["doc_id"]) | e, doc = DocumentService.get_by_id(req["doc_id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| if doc.parser_id == ParserType.QA: | if doc.parser_id == ParserType.QA: | ||||
| arr = [ | arr = [ | ||||
| req["content_with_weight"]) if len(t) > 1] | req["content_with_weight"]) if len(t) > 1] | ||||
| if len(arr) != 2: | if len(arr) != 2: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Q&A must be separated by TAB/ENTER key.") | |||||
| message="Q&A must be separated by TAB/ENTER key.") | |||||
| q, a = rmPrefix(arr[0]), rmPrefix(arr[1]) | q, a = rmPrefix(arr[0]), rmPrefix(arr[1]) | ||||
| d = beAdoc(d, arr[0], arr[1], not any( | d = beAdoc(d, arr[0], arr[1], not any( | ||||
| [rag_tokenizer.is_chinese(t) for t in q + a])) | [rag_tokenizer.is_chinese(t) for t in q + a])) | ||||
| try: | try: | ||||
| tenant_id = DocumentService.get_tenant_id(req["doc_id"]) | tenant_id = DocumentService.get_tenant_id(req["doc_id"]) | ||||
| if not tenant_id: | if not tenant_id: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| if not ELASTICSEARCH.upsert([{"id": i, "available_int": int(req["available_int"])} for i in req["chunk_ids"]], | if not ELASTICSEARCH.upsert([{"id": i, "available_int": int(req["available_int"])} for i in req["chunk_ids"]], | ||||
| search.index_name(tenant_id)): | search.index_name(tenant_id)): | ||||
| return get_data_error_result(retmsg="Index updating failure") | |||||
| return get_data_error_result(message="Index updating failure") | |||||
| return get_json_result(data=True) | return get_json_result(data=True) | ||||
| except Exception as e: | except Exception as e: | ||||
| return server_error_response(e) | return server_error_response(e) | ||||
| try: | try: | ||||
| if not ELASTICSEARCH.deleteByQuery( | if not ELASTICSEARCH.deleteByQuery( | ||||
| Q("ids", values=req["chunk_ids"]), search.index_name(current_user.id)): | Q("ids", values=req["chunk_ids"]), search.index_name(current_user.id)): | ||||
| return get_data_error_result(retmsg="Index updating failure") | |||||
| return get_data_error_result(message="Index updating failure") | |||||
| e, doc = DocumentService.get_by_id(req["doc_id"]) | e, doc = DocumentService.get_by_id(req["doc_id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| deleted_chunk_ids = req["chunk_ids"] | deleted_chunk_ids = req["chunk_ids"] | ||||
| chunk_number = len(deleted_chunk_ids) | chunk_number = len(deleted_chunk_ids) | ||||
| DocumentService.decrement_chunk_num(doc.id, doc.kb_id, 1, chunk_number, 0) | DocumentService.decrement_chunk_num(doc.id, doc.kb_id, 1, chunk_number, 0) | ||||
| try: | try: | ||||
| e, doc = DocumentService.get_by_id(req["doc_id"]) | e, doc = DocumentService.get_by_id(req["doc_id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| d["kb_id"] = [doc.kb_id] | d["kb_id"] = [doc.kb_id] | ||||
| d["docnm_kwd"] = doc.name | d["docnm_kwd"] = doc.name | ||||
| d["doc_id"] = doc.id | d["doc_id"] = doc.id | ||||
| tenant_id = DocumentService.get_tenant_id(req["doc_id"]) | tenant_id = DocumentService.get_tenant_id(req["doc_id"]) | ||||
| if not tenant_id: | if not tenant_id: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| embd_id = DocumentService.get_embd_id(req["doc_id"]) | embd_id = DocumentService.get_embd_id(req["doc_id"]) | ||||
| embd_mdl = LLMBundle(tenant_id, LLMType.EMBEDDING.value, embd_id) | embd_mdl = LLMBundle(tenant_id, LLMType.EMBEDDING.value, embd_id) | ||||
| break | break | ||||
| else: | else: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg=f'Only owner of knowledgebase authorized for this operation.', | |||||
| retcode=RetCode.OPERATING_ERROR) | |||||
| data=False, message='Only owner of knowledgebase authorized for this operation.', | |||||
| code=RetCode.OPERATING_ERROR) | |||||
| e, kb = KnowledgebaseService.get_by_id(kb_id[0]) | e, kb = KnowledgebaseService.get_by_id(kb_id[0]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Knowledgebase not found!") | |||||
| return get_data_error_result(message="Knowledgebase not found!") | |||||
| embd_mdl = LLMBundle(kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id) | embd_mdl = LLMBundle(kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id) | ||||
| return get_json_result(data=ranks) | return get_json_result(data=ranks) | ||||
| except Exception as e: | except Exception as e: | ||||
| if str(e).find("not_found") > 0: | if str(e).find("not_found") > 0: | ||||
| return get_json_result(data=False, retmsg=f'No chunk found! Check the chunk status please!', | |||||
| retcode=RetCode.DATA_ERROR) | |||||
| return get_json_result(data=False, message='No chunk found! Check the chunk status please!', | |||||
| code=RetCode.DATA_ERROR) | |||||
| return server_error_response(e) | return server_error_response(e) | ||||
| ty = sres.field[id]["knowledge_graph_kwd"] | ty = sres.field[id]["knowledge_graph_kwd"] | ||||
| try: | try: | ||||
| content_json = json.loads(sres.field[id]["content_with_weight"]) | content_json = json.loads(sres.field[id]["content_with_weight"]) | ||||
| except Exception as e: | |||||
| except Exception: | |||||
| continue | continue | ||||
| if ty == 'mind_map': | if ty == 'mind_map': |
| del req["conversation_id"] | del req["conversation_id"] | ||||
| try: | try: | ||||
| if not ConversationService.update_by_id(conv_id, req): | if not ConversationService.update_by_id(conv_id, req): | ||||
| return get_data_error_result(retmsg="Conversation not found!") | |||||
| return get_data_error_result(message="Conversation not found!") | |||||
| e, conv = ConversationService.get_by_id(conv_id) | e, conv = ConversationService.get_by_id(conv_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Fail to update a conversation!") | |||||
| message="Fail to update a conversation!") | |||||
| conv = conv.to_dict() | conv = conv.to_dict() | ||||
| return get_json_result(data=conv) | return get_json_result(data=conv) | ||||
| except Exception as e: | except Exception as e: | ||||
| try: | try: | ||||
| e, dia = DialogService.get_by_id(req["dialog_id"]) | e, dia = DialogService.get_by_id(req["dialog_id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Dialog not found") | |||||
| return get_data_error_result(message="Dialog not found") | |||||
| conv = { | conv = { | ||||
| "id": conv_id, | "id": conv_id, | ||||
| "dialog_id": req["dialog_id"], | "dialog_id": req["dialog_id"], | ||||
| ConversationService.save(**conv) | ConversationService.save(**conv) | ||||
| e, conv = ConversationService.get_by_id(conv["id"]) | e, conv = ConversationService.get_by_id(conv["id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Fail to new a conversation!") | |||||
| return get_data_error_result(message="Fail to new a conversation!") | |||||
| conv = conv.to_dict() | conv = conv.to_dict() | ||||
| return get_json_result(data=conv) | return get_json_result(data=conv) | ||||
| except Exception as e: | except Exception as e: | ||||
| try: | try: | ||||
| e, conv = ConversationService.get_by_id(conv_id) | e, conv = ConversationService.get_by_id(conv_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Conversation not found!") | |||||
| return get_data_error_result(message="Conversation not found!") | |||||
| tenants = UserTenantService.query(user_id=current_user.id) | tenants = UserTenantService.query(user_id=current_user.id) | ||||
| for tenant in tenants: | for tenant in tenants: | ||||
| if DialogService.query(tenant_id=tenant.tenant_id, id=conv.dialog_id): | if DialogService.query(tenant_id=tenant.tenant_id, id=conv.dialog_id): | ||||
| break | break | ||||
| else: | else: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg=f'Only owner of conversation authorized for this operation.', | |||||
| retcode=RetCode.OPERATING_ERROR) | |||||
| data=False, message='Only owner of conversation authorized for this operation.', | |||||
| code=RetCode.OPERATING_ERROR) | |||||
| conv = conv.to_dict() | conv = conv.to_dict() | ||||
| return get_json_result(data=conv) | return get_json_result(data=conv) | ||||
| except Exception as e: | except Exception as e: | ||||
| for cid in conv_ids: | for cid in conv_ids: | ||||
| exist, conv = ConversationService.get_by_id(cid) | exist, conv = ConversationService.get_by_id(cid) | ||||
| if not exist: | if not exist: | ||||
| return get_data_error_result(retmsg="Conversation not found!") | |||||
| return get_data_error_result(message="Conversation not found!") | |||||
| tenants = UserTenantService.query(user_id=current_user.id) | tenants = UserTenantService.query(user_id=current_user.id) | ||||
| for tenant in tenants: | for tenant in tenants: | ||||
| if DialogService.query(tenant_id=tenant.tenant_id, id=conv.dialog_id): | if DialogService.query(tenant_id=tenant.tenant_id, id=conv.dialog_id): | ||||
| break | break | ||||
| else: | else: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg=f'Only owner of conversation authorized for this operation.', | |||||
| retcode=RetCode.OPERATING_ERROR) | |||||
| data=False, message='Only owner of conversation authorized for this operation.', | |||||
| code=RetCode.OPERATING_ERROR) | |||||
| ConversationService.delete_by_id(cid) | ConversationService.delete_by_id(cid) | ||||
| return get_json_result(data=True) | return get_json_result(data=True) | ||||
| except Exception as e: | except Exception as e: | ||||
| try: | try: | ||||
| if not DialogService.query(tenant_id=current_user.id, id=dialog_id): | if not DialogService.query(tenant_id=current_user.id, id=dialog_id): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg=f'Only owner of dialog authorized for this operation.', | |||||
| retcode=RetCode.OPERATING_ERROR) | |||||
| data=False, message='Only owner of dialog authorized for this operation.', | |||||
| code=RetCode.OPERATING_ERROR) | |||||
| convs = ConversationService.query( | convs = ConversationService.query( | ||||
| dialog_id=dialog_id, | dialog_id=dialog_id, | ||||
| order_by=ConversationService.model.create_time, | order_by=ConversationService.model.create_time, | ||||
| try: | try: | ||||
| e, conv = ConversationService.get_by_id(req["conversation_id"]) | e, conv = ConversationService.get_by_id(req["conversation_id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Conversation not found!") | |||||
| return get_data_error_result(message="Conversation not found!") | |||||
| conv.message = deepcopy(req["messages"]) | conv.message = deepcopy(req["messages"]) | ||||
| e, dia = DialogService.get_by_id(conv.dialog_id) | e, dia = DialogService.get_by_id(conv.dialog_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Dialog not found!") | |||||
| return get_data_error_result(message="Dialog not found!") | |||||
| del req["conversation_id"] | del req["conversation_id"] | ||||
| del req["messages"] | del req["messages"] | ||||
| try: | try: | ||||
| for ans in chat(dia, msg, True, **req): | for ans in chat(dia, msg, True, **req): | ||||
| fillin_conv(ans) | fillin_conv(ans) | ||||
| yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans}, ensure_ascii=False) + "\n\n" | |||||
| yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, ensure_ascii=False) + "\n\n" | |||||
| ConversationService.update_by_id(conv.id, conv.to_dict()) | ConversationService.update_by_id(conv.id, conv.to_dict()) | ||||
| except Exception as e: | except Exception as e: | ||||
| traceback.print_exc() | traceback.print_exc() | ||||
| yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e), | |||||
| yield "data:" + json.dumps({"code": 500, "message": str(e), | |||||
| "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, | "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, | ||||
| ensure_ascii=False) + "\n\n" | ensure_ascii=False) + "\n\n" | ||||
| yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n" | |||||
| yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n" | |||||
| if req.get("stream", True): | if req.get("stream", True): | ||||
| resp = Response(stream(), mimetype="text/event-stream") | resp = Response(stream(), mimetype="text/event-stream") | ||||
| tenants = TenantService.get_info_by(current_user.id) | tenants = TenantService.get_info_by(current_user.id) | ||||
| if not tenants: | if not tenants: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| tts_id = tenants[0]["tts_id"] | tts_id = tenants[0]["tts_id"] | ||||
| if not tts_id: | if not tts_id: | ||||
| return get_data_error_result(retmsg="No default TTS model is set") | |||||
| return get_data_error_result(message="No default TTS model is set") | |||||
| tts_mdl = LLMBundle(tenants[0]["tenant_id"], LLMType.TTS, tts_id) | tts_mdl = LLMBundle(tenants[0]["tenant_id"], LLMType.TTS, tts_id) | ||||
| for chunk in tts_mdl.tts(txt): | for chunk in tts_mdl.tts(txt): | ||||
| yield chunk | yield chunk | ||||
| except Exception as e: | except Exception as e: | ||||
| yield ("data:" + json.dumps({"retcode": 500, "retmsg": str(e), | |||||
| yield ("data:" + json.dumps({"code": 500, "message": str(e), | |||||
| "data": {"answer": "**ERROR**: " + str(e)}}, | "data": {"answer": "**ERROR**: " + str(e)}}, | ||||
| ensure_ascii=False)).encode('utf-8') | ensure_ascii=False)).encode('utf-8') | ||||
| req = request.json | req = request.json | ||||
| e, conv = ConversationService.get_by_id(req["conversation_id"]) | e, conv = ConversationService.get_by_id(req["conversation_id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Conversation not found!") | |||||
| return get_data_error_result(message="Conversation not found!") | |||||
| conv = conv.to_dict() | conv = conv.to_dict() | ||||
| for i, msg in enumerate(conv["message"]): | for i, msg in enumerate(conv["message"]): | ||||
| req = request.json | req = request.json | ||||
| e, conv = ConversationService.get_by_id(req["conversation_id"]) | e, conv = ConversationService.get_by_id(req["conversation_id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Conversation not found!") | |||||
| return get_data_error_result(message="Conversation not found!") | |||||
| up_down = req.get("set") | up_down = req.get("set") | ||||
| feedback = req.get("feedback", "") | feedback = req.get("feedback", "") | ||||
| conv = conv.to_dict() | conv = conv.to_dict() | ||||
| nonlocal req, uid | nonlocal req, uid | ||||
| try: | try: | ||||
| for ans in ask(req["question"], req["kb_ids"], uid): | for ans in ask(req["question"], req["kb_ids"], uid): | ||||
| yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans}, ensure_ascii=False) + "\n\n" | |||||
| yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, ensure_ascii=False) + "\n\n" | |||||
| except Exception as e: | except Exception as e: | ||||
| yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e), | |||||
| yield "data:" + json.dumps({"code": 500, "message": str(e), | |||||
| "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, | "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, | ||||
| ensure_ascii=False) + "\n\n" | ensure_ascii=False) + "\n\n" | ||||
| yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n" | |||||
| yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n" | |||||
| resp = Response(stream(), mimetype="text/event-stream") | resp = Response(stream(), mimetype="text/event-stream") | ||||
| resp.headers.add_header("Cache-control", "no-cache") | resp.headers.add_header("Cache-control", "no-cache") | ||||
| kb_ids = req["kb_ids"] | kb_ids = req["kb_ids"] | ||||
| e, kb = KnowledgebaseService.get_by_id(kb_ids[0]) | e, kb = KnowledgebaseService.get_by_id(kb_ids[0]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Knowledgebase not found!") | |||||
| return get_data_error_result(message="Knowledgebase not found!") | |||||
| embd_mdl = TenantLLMService.model_instance( | embd_mdl = TenantLLMService.model_instance( | ||||
| kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id) | kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id) |
| continue | continue | ||||
| if prompt_config["system"].find("{%s}" % p["key"]) < 0: | if prompt_config["system"].find("{%s}" % p["key"]) < 0: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Parameter '{}' is not used".format(p["key"])) | |||||
| message="Parameter '{}' is not used".format(p["key"])) | |||||
| try: | try: | ||||
| e, tenant = TenantService.get_by_id(current_user.id) | e, tenant = TenantService.get_by_id(current_user.id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| llm_id = req.get("llm_id", tenant.llm_id) | llm_id = req.get("llm_id", tenant.llm_id) | ||||
| if not dialog_id: | if not dialog_id: | ||||
| if not req.get("kb_ids"): | if not req.get("kb_ids"): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Fail! Please select knowledgebase!") | |||||
| message="Fail! Please select knowledgebase!") | |||||
| dia = { | dia = { | ||||
| "id": get_uuid(), | "id": get_uuid(), | ||||
| "tenant_id": current_user.id, | "tenant_id": current_user.id, | ||||
| "icon": icon | "icon": icon | ||||
| } | } | ||||
| if not DialogService.save(**dia): | if not DialogService.save(**dia): | ||||
| return get_data_error_result(retmsg="Fail to new a dialog!") | |||||
| return get_data_error_result(message="Fail to new a dialog!") | |||||
| e, dia = DialogService.get_by_id(dia["id"]) | e, dia = DialogService.get_by_id(dia["id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Fail to new a dialog!") | |||||
| return get_data_error_result(message="Fail to new a dialog!") | |||||
| return get_json_result(data=dia.to_json()) | return get_json_result(data=dia.to_json()) | ||||
| else: | else: | ||||
| del req["dialog_id"] | del req["dialog_id"] | ||||
| if "kb_names" in req: | if "kb_names" in req: | ||||
| del req["kb_names"] | del req["kb_names"] | ||||
| if not DialogService.update_by_id(dialog_id, req): | if not DialogService.update_by_id(dialog_id, req): | ||||
| return get_data_error_result(retmsg="Dialog not found!") | |||||
| return get_data_error_result(message="Dialog not found!") | |||||
| e, dia = DialogService.get_by_id(dialog_id) | e, dia = DialogService.get_by_id(dialog_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Fail to update a dialog!") | |||||
| return get_data_error_result(message="Fail to update a dialog!") | |||||
| dia = dia.to_dict() | dia = dia.to_dict() | ||||
| dia["kb_ids"], dia["kb_names"] = get_kb_names(dia["kb_ids"]) | dia["kb_ids"], dia["kb_names"] = get_kb_names(dia["kb_ids"]) | ||||
| return get_json_result(data=dia) | return get_json_result(data=dia) | ||||
| try: | try: | ||||
| e, dia = DialogService.get_by_id(dialog_id) | e, dia = DialogService.get_by_id(dialog_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Dialog not found!") | |||||
| return get_data_error_result(message="Dialog not found!") | |||||
| dia = dia.to_dict() | dia = dia.to_dict() | ||||
| dia["kb_ids"], dia["kb_names"] = get_kb_names(dia["kb_ids"]) | dia["kb_ids"], dia["kb_names"] = get_kb_names(dia["kb_ids"]) | ||||
| return get_json_result(data=dia) | return get_json_result(data=dia) | ||||
| break | break | ||||
| else: | else: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg=f'Only owner of dialog authorized for this operation.', | |||||
| retcode=RetCode.OPERATING_ERROR) | |||||
| data=False, message='Only owner of dialog authorized for this operation.', | |||||
| code=RetCode.OPERATING_ERROR) | |||||
| dialog_list.append({"id": id,"status":StatusEnum.INVALID.value}) | dialog_list.append({"id": id,"status":StatusEnum.INVALID.value}) | ||||
| DialogService.update_many_by_id(dialog_list) | DialogService.update_many_by_id(dialog_list) | ||||
| return get_json_result(data=True) | return get_json_result(data=True) |
| kb_id = request.form.get("kb_id") | kb_id = request.form.get("kb_id") | ||||
| if not kb_id: | if not kb_id: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Lack of "KB ID"', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='Lack of "KB ID"', code=RetCode.ARGUMENT_ERROR) | |||||
| if 'file' not in request.files: | if 'file' not in request.files: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='No file part!', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='No file part!', code=RetCode.ARGUMENT_ERROR) | |||||
| file_objs = request.files.getlist('file') | file_objs = request.files.getlist('file') | ||||
| for file_obj in file_objs: | for file_obj in file_objs: | ||||
| if file_obj.filename == '': | if file_obj.filename == '': | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='No file selected!', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='No file selected!', code=RetCode.ARGUMENT_ERROR) | |||||
| e, kb = KnowledgebaseService.get_by_id(kb_id) | e, kb = KnowledgebaseService.get_by_id(kb_id) | ||||
| if not e: | if not e: | ||||
| err, _ = FileService.upload_document(kb, file_objs, current_user.id) | err, _ = FileService.upload_document(kb, file_objs, current_user.id) | ||||
| if err: | if err: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg="\n".join(err), retcode=RetCode.SERVER_ERROR) | |||||
| data=False, message="\n".join(err), code=RetCode.SERVER_ERROR) | |||||
| return get_json_result(data=True) | return get_json_result(data=True) | ||||
| kb_id = request.form.get("kb_id") | kb_id = request.form.get("kb_id") | ||||
| if not kb_id: | if not kb_id: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Lack of "KB ID"', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='Lack of "KB ID"', code=RetCode.ARGUMENT_ERROR) | |||||
| name = request.form.get("name") | name = request.form.get("name") | ||||
| url = request.form.get("url") | url = request.form.get("url") | ||||
| if not is_valid_url(url): | if not is_valid_url(url): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='The URL format is invalid', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='The URL format is invalid', code=RetCode.ARGUMENT_ERROR) | |||||
| e, kb = KnowledgebaseService.get_by_id(kb_id) | e, kb = KnowledgebaseService.get_by_id(kb_id) | ||||
| if not e: | if not e: | ||||
| raise LookupError("Can't find this knowledgebase!") | raise LookupError("Can't find this knowledgebase!") | ||||
| kb_id = req["kb_id"] | kb_id = req["kb_id"] | ||||
| if not kb_id: | if not kb_id: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Lack of "KB ID"', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='Lack of "KB ID"', code=RetCode.ARGUMENT_ERROR) | |||||
| try: | try: | ||||
| e, kb = KnowledgebaseService.get_by_id(kb_id) | e, kb = KnowledgebaseService.get_by_id(kb_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Can't find this knowledgebase!") | |||||
| message="Can't find this knowledgebase!") | |||||
| if DocumentService.query(name=req["name"], kb_id=kb_id): | if DocumentService.query(name=req["name"], kb_id=kb_id): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Duplicated document name in the same knowledgebase.") | |||||
| message="Duplicated document name in the same knowledgebase.") | |||||
| doc = DocumentService.insert({ | doc = DocumentService.insert({ | ||||
| "id": get_uuid(), | "id": get_uuid(), | ||||
| kb_id = request.args.get("kb_id") | kb_id = request.args.get("kb_id") | ||||
| if not kb_id: | if not kb_id: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Lack of "KB ID"', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='Lack of "KB ID"', code=RetCode.ARGUMENT_ERROR) | |||||
| tenants = UserTenantService.query(user_id=current_user.id) | tenants = UserTenantService.query(user_id=current_user.id) | ||||
| for tenant in tenants: | for tenant in tenants: | ||||
| if KnowledgebaseService.query( | if KnowledgebaseService.query( | ||||
| break | break | ||||
| else: | else: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg=f'Only owner of knowledgebase authorized for this operation.', | |||||
| retcode=RetCode.OPERATING_ERROR) | |||||
| data=False, message='Only owner of knowledgebase authorized for this operation.', | |||||
| code=RetCode.OPERATING_ERROR) | |||||
| keywords = request.args.get("keywords", "") | keywords = request.args.get("keywords", "") | ||||
| page_number = int(request.args.get("page", 1)) | page_number = int(request.args.get("page", 1)) | ||||
| if not DocumentService.accessible(doc_id, current_user.id): | if not DocumentService.accessible(doc_id, current_user.id): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR | |||||
| message='No authorization.', | |||||
| code=RetCode.AUTHENTICATION_ERROR | |||||
| ) | ) | ||||
| docs = DocumentService.get_by_ids(doc_ids) | docs = DocumentService.get_by_ids(doc_ids) | ||||
| return get_json_result(data=list(docs.dicts())) | return get_json_result(data=list(docs.dicts())) | ||||
| doc_ids = request.args.get("doc_ids").split(",") | doc_ids = request.args.get("doc_ids").split(",") | ||||
| if not doc_ids: | if not doc_ids: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Lack of "Document ID"', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='Lack of "Document ID"', code=RetCode.ARGUMENT_ERROR) | |||||
| try: | try: | ||||
| docs = DocumentService.get_thumbnails(doc_ids) | docs = DocumentService.get_thumbnails(doc_ids) | ||||
| if str(req["status"]) not in ["0", "1"]: | if str(req["status"]) not in ["0", "1"]: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retmsg='"Status" must be either 0 or 1!', | |||||
| retcode=RetCode.ARGUMENT_ERROR) | |||||
| message='"Status" must be either 0 or 1!', | |||||
| code=RetCode.ARGUMENT_ERROR) | |||||
| if not DocumentService.accessible(req["doc_id"], current_user.id): | if not DocumentService.accessible(req["doc_id"], current_user.id): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| message='No authorization.', | |||||
| code=RetCode.AUTHENTICATION_ERROR) | |||||
| try: | try: | ||||
| e, doc = DocumentService.get_by_id(req["doc_id"]) | e, doc = DocumentService.get_by_id(req["doc_id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| e, kb = KnowledgebaseService.get_by_id(doc.kb_id) | e, kb = KnowledgebaseService.get_by_id(doc.kb_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Can't find this knowledgebase!") | |||||
| message="Can't find this knowledgebase!") | |||||
| if not DocumentService.update_by_id( | if not DocumentService.update_by_id( | ||||
| req["doc_id"], {"status": str(req["status"])}): | req["doc_id"], {"status": str(req["status"])}): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Database error (Document update)!") | |||||
| message="Database error (Document update)!") | |||||
| if str(req["status"]) == "0": | if str(req["status"]) == "0": | ||||
| ELASTICSEARCH.updateScriptByQuery(Q("term", doc_id=req["doc_id"]), | ELASTICSEARCH.updateScriptByQuery(Q("term", doc_id=req["doc_id"]), | ||||
| if not DocumentService.accessible4deletion(doc_id, current_user.id): | if not DocumentService.accessible4deletion(doc_id, current_user.id): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR | |||||
| message='No authorization.', | |||||
| code=RetCode.AUTHENTICATION_ERROR | |||||
| ) | ) | ||||
| root_folder = FileService.get_root_folder(current_user.id) | root_folder = FileService.get_root_folder(current_user.id) | ||||
| try: | try: | ||||
| e, doc = DocumentService.get_by_id(doc_id) | e, doc = DocumentService.get_by_id(doc_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| tenant_id = DocumentService.get_tenant_id(doc_id) | tenant_id = DocumentService.get_tenant_id(doc_id) | ||||
| if not tenant_id: | if not tenant_id: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| b, n = File2DocumentService.get_storage_address(doc_id=doc_id) | b, n = File2DocumentService.get_storage_address(doc_id=doc_id) | ||||
| if not DocumentService.remove_document(doc, tenant_id): | if not DocumentService.remove_document(doc, tenant_id): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Database error (Document removal)!") | |||||
| message="Database error (Document removal)!") | |||||
| f2d = File2DocumentService.get_by_document_id(doc_id) | f2d = File2DocumentService.get_by_document_id(doc_id) | ||||
| FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id]) | FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id]) | ||||
| errors += str(e) | errors += str(e) | ||||
| if errors: | if errors: | ||||
| return get_json_result(data=False, retmsg=errors, retcode=RetCode.SERVER_ERROR) | |||||
| return get_json_result(data=False, message=errors, code=RetCode.SERVER_ERROR) | |||||
| return get_json_result(data=True) | return get_json_result(data=True) | ||||
| if not DocumentService.accessible(doc_id, current_user.id): | if not DocumentService.accessible(doc_id, current_user.id): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR | |||||
| message='No authorization.', | |||||
| code=RetCode.AUTHENTICATION_ERROR | |||||
| ) | ) | ||||
| try: | try: | ||||
| for id in req["doc_ids"]: | for id in req["doc_ids"]: | ||||
| # if str(req["run"]) == TaskStatus.CANCEL.value: | # if str(req["run"]) == TaskStatus.CANCEL.value: | ||||
| tenant_id = DocumentService.get_tenant_id(id) | tenant_id = DocumentService.get_tenant_id(id) | ||||
| if not tenant_id: | if not tenant_id: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| ELASTICSEARCH.deleteByQuery( | ELASTICSEARCH.deleteByQuery( | ||||
| Q("match", doc_id=id), idxnm=search.index_name(tenant_id)) | Q("match", doc_id=id), idxnm=search.index_name(tenant_id)) | ||||
| if not DocumentService.accessible(req["doc_id"], current_user.id): | if not DocumentService.accessible(req["doc_id"], current_user.id): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR | |||||
| message='No authorization.', | |||||
| code=RetCode.AUTHENTICATION_ERROR | |||||
| ) | ) | ||||
| try: | try: | ||||
| e, doc = DocumentService.get_by_id(req["doc_id"]) | e, doc = DocumentService.get_by_id(req["doc_id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| if pathlib.Path(req["name"].lower()).suffix != pathlib.Path( | if pathlib.Path(req["name"].lower()).suffix != pathlib.Path( | ||||
| doc.name.lower()).suffix: | doc.name.lower()).suffix: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retmsg="The extension of file can't be changed", | |||||
| retcode=RetCode.ARGUMENT_ERROR) | |||||
| message="The extension of file can't be changed", | |||||
| code=RetCode.ARGUMENT_ERROR) | |||||
| for d in DocumentService.query(name=req["name"], kb_id=doc.kb_id): | for d in DocumentService.query(name=req["name"], kb_id=doc.kb_id): | ||||
| if d.name == req["name"]: | if d.name == req["name"]: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Duplicated document name in the same knowledgebase.") | |||||
| message="Duplicated document name in the same knowledgebase.") | |||||
| if not DocumentService.update_by_id( | if not DocumentService.update_by_id( | ||||
| req["doc_id"], {"name": req["name"]}): | req["doc_id"], {"name": req["name"]}): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Database error (Document rename)!") | |||||
| message="Database error (Document rename)!") | |||||
| informs = File2DocumentService.get_by_document_id(req["doc_id"]) | informs = File2DocumentService.get_by_document_id(req["doc_id"]) | ||||
| if informs: | if informs: | ||||
| try: | try: | ||||
| e, doc = DocumentService.get_by_id(doc_id) | e, doc = DocumentService.get_by_id(doc_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| b, n = File2DocumentService.get_storage_address(doc_id=doc_id) | b, n = File2DocumentService.get_storage_address(doc_id=doc_id) | ||||
| response = flask.make_response(STORAGE_IMPL.get(b, n)) | response = flask.make_response(STORAGE_IMPL.get(b, n)) | ||||
| if not DocumentService.accessible(req["doc_id"], current_user.id): | if not DocumentService.accessible(req["doc_id"], current_user.id): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR | |||||
| message='No authorization.', | |||||
| code=RetCode.AUTHENTICATION_ERROR | |||||
| ) | ) | ||||
| try: | try: | ||||
| e, doc = DocumentService.get_by_id(req["doc_id"]) | e, doc = DocumentService.get_by_id(req["doc_id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| if doc.parser_id.lower() == req["parser_id"].lower(): | if doc.parser_id.lower() == req["parser_id"].lower(): | ||||
| if "parser_config" in req: | if "parser_config" in req: | ||||
| if req["parser_config"] == doc.parser_config: | if req["parser_config"] == doc.parser_config: | ||||
| if ((doc.type == FileType.VISUAL and req["parser_id"] != "picture") | if ((doc.type == FileType.VISUAL and req["parser_id"] != "picture") | ||||
| or (re.search( | or (re.search( | ||||
| r"\.(ppt|pptx|pages)$", doc.name) and req["parser_id"] != "presentation")): | r"\.(ppt|pptx|pages)$", doc.name) and req["parser_id"] != "presentation")): | ||||
| return get_data_error_result(retmsg="Not supported yet!") | |||||
| return get_data_error_result(message="Not supported yet!") | |||||
| e = DocumentService.update_by_id(doc.id, | e = DocumentService.update_by_id(doc.id, | ||||
| {"parser_id": req["parser_id"], "progress": 0, "progress_msg": "", | {"parser_id": req["parser_id"], "progress": 0, "progress_msg": "", | ||||
| "run": TaskStatus.UNSTART.value}) | "run": TaskStatus.UNSTART.value}) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| if "parser_config" in req: | if "parser_config" in req: | ||||
| DocumentService.update_parser_config(doc.id, req["parser_config"]) | DocumentService.update_parser_config(doc.id, req["parser_config"]) | ||||
| if doc.token_num > 0: | if doc.token_num > 0: | ||||
| e = DocumentService.increment_chunk_num(doc.id, doc.kb_id, doc.token_num * -1, doc.chunk_num * -1, | e = DocumentService.increment_chunk_num(doc.id, doc.kb_id, doc.token_num * -1, doc.chunk_num * -1, | ||||
| doc.process_duation * -1) | doc.process_duation * -1) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| tenant_id = DocumentService.get_tenant_id(req["doc_id"]) | tenant_id = DocumentService.get_tenant_id(req["doc_id"]) | ||||
| if not tenant_id: | if not tenant_id: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| ELASTICSEARCH.deleteByQuery( | ELASTICSEARCH.deleteByQuery( | ||||
| Q("match", doc_id=doc.id), idxnm=search.index_name(tenant_id)) | Q("match", doc_id=doc.id), idxnm=search.index_name(tenant_id)) | ||||
| def upload_and_parse(): | def upload_and_parse(): | ||||
| if 'file' not in request.files: | if 'file' not in request.files: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='No file part!', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='No file part!', code=RetCode.ARGUMENT_ERROR) | |||||
| file_objs = request.files.getlist('file') | file_objs = request.files.getlist('file') | ||||
| for file_obj in file_objs: | for file_obj in file_objs: | ||||
| if file_obj.filename == '': | if file_obj.filename == '': | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='No file selected!', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='No file selected!', code=RetCode.ARGUMENT_ERROR) | |||||
| doc_ids = doc_upload_and_parse(request.form.get("conversation_id"), file_objs, current_user.id) | doc_ids = doc_upload_and_parse(request.form.get("conversation_id"), file_objs, current_user.id) | ||||
| # See the License for the specific language governing permissions and | # See the License for the specific language governing permissions and | ||||
| # limitations under the License | # limitations under the License | ||||
| # | # | ||||
| from elasticsearch_dsl import Q | |||||
| from api.db.db_models import File2Document | |||||
| from api.db.services.file2document_service import File2DocumentService | from api.db.services.file2document_service import File2DocumentService | ||||
| from api.db.services.file_service import FileService | from api.db.services.file_service import FileService | ||||
| from api.db.services.document_service import DocumentService | from api.db.services.document_service import DocumentService | ||||
| from api.settings import RetCode | from api.settings import RetCode | ||||
| from api.utils.api_utils import get_json_result | from api.utils.api_utils import get_json_result | ||||
| from rag.nlp import search | |||||
| from rag.utils.es_conn import ELASTICSEARCH | |||||
| @manager.route('/convert', methods=['POST']) | @manager.route('/convert', methods=['POST']) | ||||
| doc_id = inform.document_id | doc_id = inform.document_id | ||||
| e, doc = DocumentService.get_by_id(doc_id) | e, doc = DocumentService.get_by_id(doc_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| tenant_id = DocumentService.get_tenant_id(doc_id) | tenant_id = DocumentService.get_tenant_id(doc_id) | ||||
| if not tenant_id: | if not tenant_id: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| if not DocumentService.remove_document(doc, tenant_id): | if not DocumentService.remove_document(doc, tenant_id): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Database error (Document removal)!") | |||||
| message="Database error (Document removal)!") | |||||
| File2DocumentService.delete_by_file_id(id) | File2DocumentService.delete_by_file_id(id) | ||||
| # insert | # insert | ||||
| e, kb = KnowledgebaseService.get_by_id(kb_id) | e, kb = KnowledgebaseService.get_by_id(kb_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Can't find this knowledgebase!") | |||||
| message="Can't find this knowledgebase!") | |||||
| e, file = FileService.get_by_id(id) | e, file = FileService.get_by_id(id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Can't find this file!") | |||||
| message="Can't find this file!") | |||||
| doc = DocumentService.insert({ | doc = DocumentService.insert({ | ||||
| "id": get_uuid(), | "id": get_uuid(), | ||||
| file_ids = req["file_ids"] | file_ids = req["file_ids"] | ||||
| if not file_ids: | if not file_ids: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Lack of "Files ID"', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='Lack of "Files ID"', code=RetCode.ARGUMENT_ERROR) | |||||
| try: | try: | ||||
| for file_id in file_ids: | for file_id in file_ids: | ||||
| informs = File2DocumentService.get_by_file_id(file_id) | informs = File2DocumentService.get_by_file_id(file_id) | ||||
| if not informs: | if not informs: | ||||
| return get_data_error_result(retmsg="Inform not found!") | |||||
| return get_data_error_result(message="Inform not found!") | |||||
| for inform in informs: | for inform in informs: | ||||
| if not inform: | if not inform: | ||||
| return get_data_error_result(retmsg="Inform not found!") | |||||
| return get_data_error_result(message="Inform not found!") | |||||
| File2DocumentService.delete_by_file_id(file_id) | File2DocumentService.delete_by_file_id(file_id) | ||||
| doc_id = inform.document_id | doc_id = inform.document_id | ||||
| e, doc = DocumentService.get_by_id(doc_id) | e, doc = DocumentService.get_by_id(doc_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| tenant_id = DocumentService.get_tenant_id(doc_id) | tenant_id = DocumentService.get_tenant_id(doc_id) | ||||
| if not tenant_id: | if not tenant_id: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| if not DocumentService.remove_document(doc, tenant_id): | if not DocumentService.remove_document(doc, tenant_id): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Database error (Document removal)!") | |||||
| message="Database error (Document removal)!") | |||||
| return get_json_result(data=True) | return get_json_result(data=True) | ||||
| except Exception as e: | except Exception as e: | ||||
| return server_error_response(e) | return server_error_response(e) |
| import re | import re | ||||
| import flask | import flask | ||||
| from elasticsearch_dsl import Q | |||||
| from flask import request | from flask import request | ||||
| from flask_login import login_required, current_user | from flask_login import login_required, current_user | ||||
| from api.settings import RetCode | from api.settings import RetCode | ||||
| from api.utils.api_utils import get_json_result | from api.utils.api_utils import get_json_result | ||||
| from api.utils.file_utils import filename_type | from api.utils.file_utils import filename_type | ||||
| from rag.nlp import search | |||||
| from rag.utils.es_conn import ELASTICSEARCH | |||||
| from rag.utils.storage_factory import STORAGE_IMPL | from rag.utils.storage_factory import STORAGE_IMPL | ||||
| if 'file' not in request.files: | if 'file' not in request.files: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='No file part!', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='No file part!', code=RetCode.ARGUMENT_ERROR) | |||||
| file_objs = request.files.getlist('file') | file_objs = request.files.getlist('file') | ||||
| for file_obj in file_objs: | for file_obj in file_objs: | ||||
| if file_obj.filename == '': | if file_obj.filename == '': | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='No file selected!', retcode=RetCode.ARGUMENT_ERROR) | |||||
| data=False, message='No file selected!', code=RetCode.ARGUMENT_ERROR) | |||||
| file_res = [] | file_res = [] | ||||
| try: | try: | ||||
| for file_obj in file_objs: | for file_obj in file_objs: | ||||
| e, file = FileService.get_by_id(pf_id) | e, file = FileService.get_by_id(pf_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Can't find this folder!") | |||||
| message="Can't find this folder!") | |||||
| MAX_FILE_NUM_PER_USER = int(os.environ.get('MAX_FILE_NUM_PER_USER', 0)) | MAX_FILE_NUM_PER_USER = int(os.environ.get('MAX_FILE_NUM_PER_USER', 0)) | ||||
| if MAX_FILE_NUM_PER_USER > 0 and DocumentService.get_doc_count(current_user.id) >= MAX_FILE_NUM_PER_USER: | if MAX_FILE_NUM_PER_USER > 0 and DocumentService.get_doc_count(current_user.id) >= MAX_FILE_NUM_PER_USER: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Exceed the maximum file number of a free user!") | |||||
| message="Exceed the maximum file number of a free user!") | |||||
| # split file name path | # split file name path | ||||
| if not file_obj.filename: | if not file_obj.filename: | ||||
| if file_len != len_id_list: | if file_len != len_id_list: | ||||
| e, file = FileService.get_by_id(file_id_list[len_id_list - 1]) | e, file = FileService.get_by_id(file_id_list[len_id_list - 1]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Folder not found!") | |||||
| return get_data_error_result(message="Folder not found!") | |||||
| last_folder = FileService.create_folder(file, file_id_list[len_id_list - 1], file_obj_names, | last_folder = FileService.create_folder(file, file_id_list[len_id_list - 1], file_obj_names, | ||||
| len_id_list) | len_id_list) | ||||
| else: | else: | ||||
| e, file = FileService.get_by_id(file_id_list[len_id_list - 2]) | e, file = FileService.get_by_id(file_id_list[len_id_list - 2]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Folder not found!") | |||||
| return get_data_error_result(message="Folder not found!") | |||||
| last_folder = FileService.create_folder(file, file_id_list[len_id_list - 2], file_obj_names, | last_folder = FileService.create_folder(file, file_id_list[len_id_list - 2], file_obj_names, | ||||
| len_id_list) | len_id_list) | ||||
| try: | try: | ||||
| if not FileService.is_parent_folder_exist(pf_id): | if not FileService.is_parent_folder_exist(pf_id): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg="Parent Folder Doesn't Exist!", retcode=RetCode.OPERATING_ERROR) | |||||
| data=False, message="Parent Folder Doesn't Exist!", code=RetCode.OPERATING_ERROR) | |||||
| if FileService.query(name=req["name"], parent_id=pf_id): | if FileService.query(name=req["name"], parent_id=pf_id): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Duplicated folder name in the same folder.") | |||||
| message="Duplicated folder name in the same folder.") | |||||
| if input_file_type == FileType.FOLDER.value: | if input_file_type == FileType.FOLDER.value: | ||||
| file_type = FileType.FOLDER.value | file_type = FileType.FOLDER.value | ||||
| try: | try: | ||||
| e, file = FileService.get_by_id(pf_id) | e, file = FileService.get_by_id(pf_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Folder not found!") | |||||
| return get_data_error_result(message="Folder not found!") | |||||
| files, total = FileService.get_by_pf_id( | files, total = FileService.get_by_pf_id( | ||||
| current_user.id, pf_id, page_number, items_per_page, orderby, desc, keywords) | current_user.id, pf_id, page_number, items_per_page, orderby, desc, keywords) | ||||
| parent_folder = FileService.get_parent_folder(pf_id) | parent_folder = FileService.get_parent_folder(pf_id) | ||||
| if not FileService.get_parent_folder(pf_id): | if not FileService.get_parent_folder(pf_id): | ||||
| return get_json_result(retmsg="File not found!") | |||||
| return get_json_result(message="File not found!") | |||||
| return get_json_result(data={"total": total, "files": files, "parent_folder": parent_folder.to_json()}) | return get_json_result(data={"total": total, "files": files, "parent_folder": parent_folder.to_json()}) | ||||
| except Exception as e: | except Exception as e: | ||||
| try: | try: | ||||
| e, file = FileService.get_by_id(file_id) | e, file = FileService.get_by_id(file_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Folder not found!") | |||||
| return get_data_error_result(message="Folder not found!") | |||||
| parent_folder = FileService.get_parent_folder(file_id) | parent_folder = FileService.get_parent_folder(file_id) | ||||
| return get_json_result(data={"parent_folder": parent_folder.to_json()}) | return get_json_result(data={"parent_folder": parent_folder.to_json()}) | ||||
| try: | try: | ||||
| e, file = FileService.get_by_id(file_id) | e, file = FileService.get_by_id(file_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Folder not found!") | |||||
| return get_data_error_result(message="Folder not found!") | |||||
| parent_folders = FileService.get_all_parent_folders(file_id) | parent_folders = FileService.get_all_parent_folders(file_id) | ||||
| parent_folders_res = [] | parent_folders_res = [] | ||||
| for file_id in file_ids: | for file_id in file_ids: | ||||
| e, file = FileService.get_by_id(file_id) | e, file = FileService.get_by_id(file_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="File or Folder not found!") | |||||
| return get_data_error_result(message="File or Folder not found!") | |||||
| if not file.tenant_id: | if not file.tenant_id: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| if file.source_type == FileSource.KNOWLEDGEBASE: | if file.source_type == FileSource.KNOWLEDGEBASE: | ||||
| continue | continue | ||||
| for inner_file_id in file_id_list: | for inner_file_id in file_id_list: | ||||
| e, file = FileService.get_by_id(inner_file_id) | e, file = FileService.get_by_id(inner_file_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="File not found!") | |||||
| return get_data_error_result(message="File not found!") | |||||
| STORAGE_IMPL.rm(file.parent_id, file.location) | STORAGE_IMPL.rm(file.parent_id, file.location) | ||||
| FileService.delete_folder_by_pf_id(current_user.id, file_id) | FileService.delete_folder_by_pf_id(current_user.id, file_id) | ||||
| else: | else: | ||||
| if not FileService.delete(file): | if not FileService.delete(file): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Database error (File removal)!") | |||||
| message="Database error (File removal)!") | |||||
| # delete file2document | # delete file2document | ||||
| informs = File2DocumentService.get_by_file_id(file_id) | informs = File2DocumentService.get_by_file_id(file_id) | ||||
| doc_id = inform.document_id | doc_id = inform.document_id | ||||
| e, doc = DocumentService.get_by_id(doc_id) | e, doc = DocumentService.get_by_id(doc_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| tenant_id = DocumentService.get_tenant_id(doc_id) | tenant_id = DocumentService.get_tenant_id(doc_id) | ||||
| if not tenant_id: | if not tenant_id: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| if not DocumentService.remove_document(doc, tenant_id): | if not DocumentService.remove_document(doc, tenant_id): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Database error (Document removal)!") | |||||
| message="Database error (Document removal)!") | |||||
| File2DocumentService.delete_by_file_id(file_id) | File2DocumentService.delete_by_file_id(file_id) | ||||
| return get_json_result(data=True) | return get_json_result(data=True) | ||||
| try: | try: | ||||
| e, file = FileService.get_by_id(req["file_id"]) | e, file = FileService.get_by_id(req["file_id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="File not found!") | |||||
| return get_data_error_result(message="File not found!") | |||||
| if file.type != FileType.FOLDER.value \ | if file.type != FileType.FOLDER.value \ | ||||
| and pathlib.Path(req["name"].lower()).suffix != pathlib.Path( | and pathlib.Path(req["name"].lower()).suffix != pathlib.Path( | ||||
| file.name.lower()).suffix: | file.name.lower()).suffix: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retmsg="The extension of file can't be changed", | |||||
| retcode=RetCode.ARGUMENT_ERROR) | |||||
| message="The extension of file can't be changed", | |||||
| code=RetCode.ARGUMENT_ERROR) | |||||
| for file in FileService.query(name=req["name"], pf_id=file.parent_id): | for file in FileService.query(name=req["name"], pf_id=file.parent_id): | ||||
| if file.name == req["name"]: | if file.name == req["name"]: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Duplicated file name in the same folder.") | |||||
| message="Duplicated file name in the same folder.") | |||||
| if not FileService.update_by_id( | if not FileService.update_by_id( | ||||
| req["file_id"], {"name": req["name"]}): | req["file_id"], {"name": req["name"]}): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Database error (File rename)!") | |||||
| message="Database error (File rename)!") | |||||
| informs = File2DocumentService.get_by_file_id(req["file_id"]) | informs = File2DocumentService.get_by_file_id(req["file_id"]) | ||||
| if informs: | if informs: | ||||
| if not DocumentService.update_by_id( | if not DocumentService.update_by_id( | ||||
| informs[0].document_id, {"name": req["name"]}): | informs[0].document_id, {"name": req["name"]}): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Database error (Document rename)!") | |||||
| message="Database error (Document rename)!") | |||||
| return get_json_result(data=True) | return get_json_result(data=True) | ||||
| except Exception as e: | except Exception as e: | ||||
| try: | try: | ||||
| e, file = FileService.get_by_id(file_id) | e, file = FileService.get_by_id(file_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Document not found!") | |||||
| return get_data_error_result(message="Document not found!") | |||||
| b, n = File2DocumentService.get_storage_address(file_id=file_id) | b, n = File2DocumentService.get_storage_address(file_id=file_id) | ||||
| response = flask.make_response(STORAGE_IMPL.get(b, n)) | response = flask.make_response(STORAGE_IMPL.get(b, n)) | ||||
| ext = re.search(r"\.([^.]+)$", file.name) | ext = re.search(r"\.([^.]+)$", file.name) | ||||
| for file_id in file_ids: | for file_id in file_ids: | ||||
| e, file = FileService.get_by_id(file_id) | e, file = FileService.get_by_id(file_id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="File or Folder not found!") | |||||
| return get_data_error_result(message="File or Folder not found!") | |||||
| if not file.tenant_id: | if not file.tenant_id: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| fe, _ = FileService.get_by_id(parent_id) | fe, _ = FileService.get_by_id(parent_id) | ||||
| if not fe: | if not fe: | ||||
| return get_data_error_result(retmsg="Parent Folder not found!") | |||||
| return get_data_error_result(message="Parent Folder not found!") | |||||
| FileService.move_file(file_ids, parent_id) | FileService.move_file(file_ids, parent_id) | ||||
| return get_json_result(data=True) | return get_json_result(data=True) | ||||
| except Exception as e: | except Exception as e: |
| req["created_by"] = current_user.id | req["created_by"] = current_user.id | ||||
| e, t = TenantService.get_by_id(current_user.id) | e, t = TenantService.get_by_id(current_user.id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result(retmsg="Tenant not found.") | |||||
| return get_data_error_result(message="Tenant not found.") | |||||
| req["embd_id"] = t.embd_id | req["embd_id"] = t.embd_id | ||||
| if not KnowledgebaseService.save(**req): | if not KnowledgebaseService.save(**req): | ||||
| return get_data_error_result() | return get_data_error_result() | ||||
| if not KnowledgebaseService.accessible4deletion(req["kb_id"], current_user.id): | if not KnowledgebaseService.accessible4deletion(req["kb_id"], current_user.id): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR | |||||
| message='No authorization.', | |||||
| code=RetCode.AUTHENTICATION_ERROR | |||||
| ) | ) | ||||
| try: | try: | ||||
| if not KnowledgebaseService.query( | if not KnowledgebaseService.query( | ||||
| created_by=current_user.id, id=req["kb_id"]): | created_by=current_user.id, id=req["kb_id"]): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg=f'Only owner of knowledgebase authorized for this operation.', retcode=RetCode.OPERATING_ERROR) | |||||
| data=False, message='Only owner of knowledgebase authorized for this operation.', code=RetCode.OPERATING_ERROR) | |||||
| e, kb = KnowledgebaseService.get_by_id(req["kb_id"]) | e, kb = KnowledgebaseService.get_by_id(req["kb_id"]) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Can't find this knowledgebase!") | |||||
| message="Can't find this knowledgebase!") | |||||
| if req["name"].lower() != kb.name.lower() \ | if req["name"].lower() != kb.name.lower() \ | ||||
| and len(KnowledgebaseService.query(name=req["name"], tenant_id=current_user.id, status=StatusEnum.VALID.value)) > 1: | and len(KnowledgebaseService.query(name=req["name"], tenant_id=current_user.id, status=StatusEnum.VALID.value)) > 1: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Duplicated knowledgebase name.") | |||||
| message="Duplicated knowledgebase name.") | |||||
| del req["kb_id"] | del req["kb_id"] | ||||
| if not KnowledgebaseService.update_by_id(kb.id, req): | if not KnowledgebaseService.update_by_id(kb.id, req): | ||||
| e, kb = KnowledgebaseService.get_by_id(kb.id) | e, kb = KnowledgebaseService.get_by_id(kb.id) | ||||
| if not e: | if not e: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Database error (Knowledgebase rename)!") | |||||
| message="Database error (Knowledgebase rename)!") | |||||
| return get_json_result(data=kb.to_json()) | return get_json_result(data=kb.to_json()) | ||||
| except Exception as e: | except Exception as e: | ||||
| break | break | ||||
| else: | else: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg=f'Only owner of knowledgebase authorized for this operation.', | |||||
| retcode=RetCode.OPERATING_ERROR) | |||||
| data=False, message='Only owner of knowledgebase authorized for this operation.', | |||||
| code=RetCode.OPERATING_ERROR) | |||||
| kb = KnowledgebaseService.get_detail(kb_id) | kb = KnowledgebaseService.get_detail(kb_id) | ||||
| if not kb: | if not kb: | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Can't find this knowledgebase!") | |||||
| message="Can't find this knowledgebase!") | |||||
| return get_json_result(data=kb) | return get_json_result(data=kb) | ||||
| except Exception as e: | except Exception as e: | ||||
| return server_error_response(e) | return server_error_response(e) | ||||
| if not KnowledgebaseService.accessible4deletion(req["kb_id"], current_user.id): | if not KnowledgebaseService.accessible4deletion(req["kb_id"], current_user.id): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retmsg='No authorization.', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR | |||||
| message='No authorization.', | |||||
| code=RetCode.AUTHENTICATION_ERROR | |||||
| ) | ) | ||||
| try: | try: | ||||
| kbs = KnowledgebaseService.query( | kbs = KnowledgebaseService.query( | ||||
| created_by=current_user.id, id=req["kb_id"]) | created_by=current_user.id, id=req["kb_id"]) | ||||
| if not kbs: | if not kbs: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg=f'Only owner of knowledgebase authorized for this operation.', retcode=RetCode.OPERATING_ERROR) | |||||
| data=False, message='Only owner of knowledgebase authorized for this operation.', code=RetCode.OPERATING_ERROR) | |||||
| for doc in DocumentService.query(kb_id=req["kb_id"]): | for doc in DocumentService.query(kb_id=req["kb_id"]): | ||||
| if not DocumentService.remove_document(doc, kbs[0].tenant_id): | if not DocumentService.remove_document(doc, kbs[0].tenant_id): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Database error (Document removal)!") | |||||
| message="Database error (Document removal)!") | |||||
| f2d = File2DocumentService.get_by_document_id(doc.id) | f2d = File2DocumentService.get_by_document_id(doc.id) | ||||
| FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id]) | FileService.filter_delete([File.source_type == FileSource.KNOWLEDGEBASE, File.id == f2d[0].file_id]) | ||||
| File2DocumentService.delete_by_document_id(doc.id) | File2DocumentService.delete_by_document_id(doc.id) | ||||
| if not KnowledgebaseService.delete_by_id(req["kb_id"]): | if not KnowledgebaseService.delete_by_id(req["kb_id"]): | ||||
| return get_data_error_result( | return get_data_error_result( | ||||
| retmsg="Database error (Knowledgebase removal)!") | |||||
| message="Database error (Knowledgebase removal)!") | |||||
| return get_json_result(data=True) | return get_json_result(data=True) | ||||
| except Exception as e: | except Exception as e: | ||||
| return server_error_response(e) | return server_error_response(e) |
| break | break | ||||
| if msg: | if msg: | ||||
| return get_data_error_result(retmsg=msg) | |||||
| return get_data_error_result(message=msg) | |||||
| llm_config = { | llm_config = { | ||||
| "api_key": req["api_key"], | "api_key": req["api_key"], | ||||
| pass | pass | ||||
| if msg: | if msg: | ||||
| return get_data_error_result(retmsg=msg) | |||||
| return get_data_error_result(message=msg) | |||||
| if not TenantLLMService.filter_update( | if not TenantLLMService.filter_update( | ||||
| [TenantLLM.tenant_id == current_user.id, TenantLLM.llm_factory == factory, TenantLLM.llm_name == llm["llm_name"]], llm): | [TenantLLM.tenant_id == current_user.id, TenantLLM.llm_factory == factory, TenantLLM.llm_name == llm["llm_name"]], llm): |
| req=request.json | req=request.json | ||||
| ids= req.get("dataset_ids") | ids= req.get("dataset_ids") | ||||
| if not ids: | if not ids: | ||||
| return get_error_data_result(retmsg="`dataset_ids` is required") | |||||
| return get_error_data_result(message="`dataset_ids` is required") | |||||
| for kb_id in ids: | for kb_id in ids: | ||||
| kbs = KnowledgebaseService.query(id=kb_id,tenant_id=tenant_id) | kbs = KnowledgebaseService.query(id=kb_id,tenant_id=tenant_id) | ||||
| if not kbs: | if not kbs: | ||||
| kbs = KnowledgebaseService.get_by_ids(ids) | kbs = KnowledgebaseService.get_by_ids(ids) | ||||
| embd_count = list(set([kb.embd_id for kb in kbs])) | embd_count = list(set([kb.embd_id for kb in kbs])) | ||||
| if len(embd_count) != 1: | if len(embd_count) != 1: | ||||
| return get_result(retmsg='Datasets use different embedding models."',retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| return get_result(message='Datasets use different embedding models."',code=RetCode.AUTHENTICATION_ERROR) | |||||
| req["kb_ids"] = ids | req["kb_ids"] = ids | ||||
| # llm | # llm | ||||
| llm = req.get("llm") | llm = req.get("llm") | ||||
| req["llm_setting"] = req.pop("llm") | req["llm_setting"] = req.pop("llm") | ||||
| e, tenant = TenantService.get_by_id(tenant_id) | e, tenant = TenantService.get_by_id(tenant_id) | ||||
| if not e: | if not e: | ||||
| return get_error_data_result(retmsg="Tenant not found!") | |||||
| return get_error_data_result(message="Tenant not found!") | |||||
| # prompt | # prompt | ||||
| prompt = req.get("prompt") | prompt = req.get("prompt") | ||||
| key_mapping = {"parameters": "variables", | key_mapping = {"parameters": "variables", | ||||
| if not req.get("llm_id"): | if not req.get("llm_id"): | ||||
| req["llm_id"] = tenant.llm_id | req["llm_id"] = tenant.llm_id | ||||
| if not req.get("name"): | if not req.get("name"): | ||||
| return get_error_data_result(retmsg="`name` is required.") | |||||
| return get_error_data_result(message="`name` is required.") | |||||
| if DialogService.query(name=req["name"], tenant_id=tenant_id, status=StatusEnum.VALID.value): | if DialogService.query(name=req["name"], tenant_id=tenant_id, status=StatusEnum.VALID.value): | ||||
| return get_error_data_result(retmsg="Duplicated chat name in creating chat.") | |||||
| return get_error_data_result(message="Duplicated chat name in creating chat.") | |||||
| # tenant_id | # tenant_id | ||||
| if req.get("tenant_id"): | if req.get("tenant_id"): | ||||
| return get_error_data_result(retmsg="`tenant_id` must not be provided.") | |||||
| return get_error_data_result(message="`tenant_id` must not be provided.") | |||||
| req["tenant_id"] = tenant_id | req["tenant_id"] = tenant_id | ||||
| # prompt more parameter | # prompt more parameter | ||||
| default_prompt = { | default_prompt = { | ||||
| continue | continue | ||||
| if req['prompt_config']["system"].find("{%s}" % p["key"]) < 0: | if req['prompt_config']["system"].find("{%s}" % p["key"]) < 0: | ||||
| return get_error_data_result( | return get_error_data_result( | ||||
| retmsg="Parameter '{}' is not used".format(p["key"])) | |||||
| message="Parameter '{}' is not used".format(p["key"])) | |||||
| # save | # save | ||||
| if not DialogService.save(**req): | if not DialogService.save(**req): | ||||
| return get_error_data_result(retmsg="Fail to new a chat!") | |||||
| return get_error_data_result(message="Fail to new a chat!") | |||||
| # response | # response | ||||
| e, res = DialogService.get_by_id(req["id"]) | e, res = DialogService.get_by_id(req["id"]) | ||||
| if not e: | if not e: | ||||
| return get_error_data_result(retmsg="Fail to new a chat!") | |||||
| return get_error_data_result(message="Fail to new a chat!") | |||||
| res = res.to_json() | res = res.to_json() | ||||
| renamed_dict = {} | renamed_dict = {} | ||||
| for key, value in res["prompt_config"].items(): | for key, value in res["prompt_config"].items(): | ||||
| @token_required | @token_required | ||||
| def update(tenant_id,chat_id): | def update(tenant_id,chat_id): | ||||
| if not DialogService.query(tenant_id=tenant_id, id=chat_id, status=StatusEnum.VALID.value): | if not DialogService.query(tenant_id=tenant_id, id=chat_id, status=StatusEnum.VALID.value): | ||||
| return get_error_data_result(retmsg='You do not own the chat') | |||||
| return get_error_data_result(message='You do not own the chat') | |||||
| req =request.json | req =request.json | ||||
| ids = req.get("dataset_ids") | ids = req.get("dataset_ids") | ||||
| if "show_quotation" in req: | if "show_quotation" in req: | ||||
| embd_count=list(set([kb.embd_id for kb in kbs])) | embd_count=list(set([kb.embd_id for kb in kbs])) | ||||
| if len(embd_count) != 1 : | if len(embd_count) != 1 : | ||||
| return get_result( | return get_result( | ||||
| retmsg='Datasets use different embedding models."', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR) | |||||
| message='Datasets use different embedding models."', | |||||
| code=RetCode.AUTHENTICATION_ERROR) | |||||
| req["kb_ids"] = ids | req["kb_ids"] = ids | ||||
| llm = req.get("llm") | llm = req.get("llm") | ||||
| if llm: | if llm: | ||||
| req["llm_setting"] = req.pop("llm") | req["llm_setting"] = req.pop("llm") | ||||
| e, tenant = TenantService.get_by_id(tenant_id) | e, tenant = TenantService.get_by_id(tenant_id) | ||||
| if not e: | if not e: | ||||
| return get_error_data_result(retmsg="Tenant not found!") | |||||
| return get_error_data_result(message="Tenant not found!") | |||||
| if req.get("rerank_model"): | if req.get("rerank_model"): | ||||
| if not TenantLLMService.query(tenant_id=tenant_id,llm_name=req.get("rerank_model"),model_type="rerank"): | if not TenantLLMService.query(tenant_id=tenant_id,llm_name=req.get("rerank_model"),model_type="rerank"): | ||||
| return get_error_data_result(f"`rerank_model` {req.get('rerank_model')} doesn't exist") | return get_error_data_result(f"`rerank_model` {req.get('rerank_model')} doesn't exist") | ||||
| res = res.to_json() | res = res.to_json() | ||||
| if "name" in req: | if "name" in req: | ||||
| if not req.get("name"): | if not req.get("name"): | ||||
| return get_error_data_result(retmsg="`name` is not empty.") | |||||
| return get_error_data_result(message="`name` is not empty.") | |||||
| if req["name"].lower() != res["name"].lower() \ | if req["name"].lower() != res["name"].lower() \ | ||||
| and len( | and len( | ||||
| DialogService.query(name=req["name"], tenant_id=tenant_id, status=StatusEnum.VALID.value)) > 0: | DialogService.query(name=req["name"], tenant_id=tenant_id, status=StatusEnum.VALID.value)) > 0: | ||||
| return get_error_data_result(retmsg="Duplicated chat name in updating dataset.") | |||||
| return get_error_data_result(message="Duplicated chat name in updating dataset.") | |||||
| if "prompt_config" in req: | if "prompt_config" in req: | ||||
| res["prompt_config"].update(req["prompt_config"]) | res["prompt_config"].update(req["prompt_config"]) | ||||
| for p in res["prompt_config"]["parameters"]: | for p in res["prompt_config"]["parameters"]: | ||||
| if p["optional"]: | if p["optional"]: | ||||
| continue | continue | ||||
| if res["prompt_config"]["system"].find("{%s}" % p["key"]) < 0: | if res["prompt_config"]["system"].find("{%s}" % p["key"]) < 0: | ||||
| return get_error_data_result(retmsg="Parameter '{}' is not used".format(p["key"])) | |||||
| return get_error_data_result(message="Parameter '{}' is not used".format(p["key"])) | |||||
| if "llm_setting" in req: | if "llm_setting" in req: | ||||
| res["llm_setting"].update(req["llm_setting"]) | res["llm_setting"].update(req["llm_setting"]) | ||||
| req["prompt_config"] = res["prompt_config"] | req["prompt_config"] = res["prompt_config"] | ||||
| if "dataset_ids" in req: | if "dataset_ids" in req: | ||||
| req.pop("dataset_ids") | req.pop("dataset_ids") | ||||
| if not DialogService.update_by_id(chat_id, req): | if not DialogService.update_by_id(chat_id, req): | ||||
| return get_error_data_result(retmsg="Chat not found!") | |||||
| return get_error_data_result(message="Chat not found!") | |||||
| return get_result() | return get_result() | ||||
| id_list=ids | id_list=ids | ||||
| for id in id_list: | for id in id_list: | ||||
| if not DialogService.query(tenant_id=tenant_id, id=id, status=StatusEnum.VALID.value): | if not DialogService.query(tenant_id=tenant_id, id=id, status=StatusEnum.VALID.value): | ||||
| return get_error_data_result(retmsg=f"You don't own the chat {id}") | |||||
| return get_error_data_result(message=f"You don't own the chat {id}") | |||||
| temp_dict = {"status": StatusEnum.INVALID.value} | temp_dict = {"status": StatusEnum.INVALID.value} | ||||
| DialogService.update_by_id(id, temp_dict) | DialogService.update_by_id(id, temp_dict) | ||||
| return get_result() | return get_result() | ||||
| name = request.args.get("name") | name = request.args.get("name") | ||||
| chat = DialogService.query(id=id,name=name,status=StatusEnum.VALID.value) | chat = DialogService.query(id=id,name=name,status=StatusEnum.VALID.value) | ||||
| if not chat: | if not chat: | ||||
| return get_error_data_result(retmsg="The chat doesn't exist") | |||||
| return get_error_data_result(message="The chat doesn't exist") | |||||
| page_number = int(request.args.get("page", 1)) | page_number = int(request.args.get("page", 1)) | ||||
| items_per_page = int(request.args.get("page_size", 1024)) | items_per_page = int(request.args.get("page_size", 1024)) | ||||
| orderby = request.args.get("orderby", "create_time") | orderby = request.args.get("orderby", "create_time") | ||||
| for kb_id in res["kb_ids"]: | for kb_id in res["kb_ids"]: | ||||
| kb = KnowledgebaseService.query(id=kb_id) | kb = KnowledgebaseService.query(id=kb_id) | ||||
| if not kb : | if not kb : | ||||
| return get_error_data_result(retmsg=f"Don't exist the kb {kb_id}") | |||||
| return get_error_data_result(message=f"Don't exist the kb {kb_id}") | |||||
| kb_list.append(kb[0].to_json()) | kb_list.append(kb[0].to_json()) | ||||
| del res["kb_ids"] | del res["kb_ids"] | ||||
| res["datasets"] = kb_list | res["datasets"] = kb_list |
| e, kb = KnowledgebaseService.get_by_id(kb_id) | e, kb = KnowledgebaseService.get_by_id(kb_id) | ||||
| if not e: | if not e: | ||||
| return build_error_result(error_msg="Knowledgebase not found!", retcode=RetCode.NOT_FOUND) | |||||
| return build_error_result(message="Knowledgebase not found!", code=RetCode.NOT_FOUND) | |||||
| if kb.tenant_id != tenant_id: | if kb.tenant_id != tenant_id: | ||||
| return build_error_result(error_msg="Knowledgebase not found!", retcode=RetCode.NOT_FOUND) | |||||
| return build_error_result(message="Knowledgebase not found!", code=RetCode.NOT_FOUND) | |||||
| embd_mdl = LLMBundle(kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id) | embd_mdl = LLMBundle(kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id) | ||||
| except Exception as e: | except Exception as e: | ||||
| if str(e).find("not_found") > 0: | if str(e).find("not_found") > 0: | ||||
| return build_error_result( | return build_error_result( | ||||
| error_msg=f'No chunk found! Check the chunk status please!', | |||||
| retcode=RetCode.NOT_FOUND | |||||
| message='No chunk found! Check the chunk status please!', | |||||
| code=RetCode.NOT_FOUND | |||||
| ) | ) | ||||
| return build_error_result(error_msg=str(e), retcode=RetCode.SERVER_ERROR) | |||||
| return build_error_result(message=str(e), code=RetCode.SERVER_ERROR) |
| """ | """ | ||||
| if "file" not in request.files: | if "file" not in request.files: | ||||
| return get_error_data_result( | return get_error_data_result( | ||||
| retmsg="No file part!", retcode=RetCode.ARGUMENT_ERROR | |||||
| message="No file part!", code=RetCode.ARGUMENT_ERROR | |||||
| ) | ) | ||||
| file_objs = request.files.getlist("file") | file_objs = request.files.getlist("file") | ||||
| for file_obj in file_objs: | for file_obj in file_objs: | ||||
| if file_obj.filename == "": | if file_obj.filename == "": | ||||
| return get_result( | return get_result( | ||||
| retmsg="No file selected!", retcode=RetCode.ARGUMENT_ERROR | |||||
| message="No file selected!", code=RetCode.ARGUMENT_ERROR | |||||
| ) | ) | ||||
| # total size | # total size | ||||
| total_size = 0 | total_size = 0 | ||||
| MAX_TOTAL_FILE_SIZE = 10 * 1024 * 1024 | MAX_TOTAL_FILE_SIZE = 10 * 1024 * 1024 | ||||
| if total_size > MAX_TOTAL_FILE_SIZE: | if total_size > MAX_TOTAL_FILE_SIZE: | ||||
| return get_result( | return get_result( | ||||
| retmsg=f"Total file size exceeds 10MB limit! ({total_size / (1024 * 1024):.2f} MB)", | |||||
| retcode=RetCode.ARGUMENT_ERROR, | |||||
| message=f"Total file size exceeds 10MB limit! ({total_size / (1024 * 1024):.2f} MB)", | |||||
| code=RetCode.ARGUMENT_ERROR, | |||||
| ) | ) | ||||
| e, kb = KnowledgebaseService.get_by_id(dataset_id) | e, kb = KnowledgebaseService.get_by_id(dataset_id) | ||||
| if not e: | if not e: | ||||
| raise LookupError(f"Can't find the dataset with ID {dataset_id}!") | raise LookupError(f"Can't find the dataset with ID {dataset_id}!") | ||||
| err, files = FileService.upload_document(kb, file_objs, tenant_id) | err, files = FileService.upload_document(kb, file_objs, tenant_id) | ||||
| if err: | if err: | ||||
| return get_result(retmsg="\n".join(err), retcode=RetCode.SERVER_ERROR) | |||||
| return get_result(message="\n".join(err), code=RetCode.SERVER_ERROR) | |||||
| # rename key's name | # rename key's name | ||||
| renamed_doc_list = [] | renamed_doc_list = [] | ||||
| for file in files: | for file in files: | ||||
| """ | """ | ||||
| req = request.json | req = request.json | ||||
| if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | ||||
| return get_error_data_result(retmsg="You don't own the dataset.") | |||||
| return get_error_data_result(message="You don't own the dataset.") | |||||
| doc = DocumentService.query(kb_id=dataset_id, id=document_id) | doc = DocumentService.query(kb_id=dataset_id, id=document_id) | ||||
| if not doc: | if not doc: | ||||
| return get_error_data_result(retmsg="The dataset doesn't own the document.") | |||||
| return get_error_data_result(message="The dataset doesn't own the document.") | |||||
| doc = doc[0] | doc = doc[0] | ||||
| if "chunk_count" in req: | if "chunk_count" in req: | ||||
| if req["chunk_count"] != doc.chunk_num: | if req["chunk_count"] != doc.chunk_num: | ||||
| return get_error_data_result(retmsg="Can't change `chunk_count`.") | |||||
| return get_error_data_result(message="Can't change `chunk_count`.") | |||||
| if "token_count" in req: | if "token_count" in req: | ||||
| if req["token_count"] != doc.token_num: | if req["token_count"] != doc.token_num: | ||||
| return get_error_data_result(retmsg="Can't change `token_count`.") | |||||
| return get_error_data_result(message="Can't change `token_count`.") | |||||
| if "progress" in req: | if "progress" in req: | ||||
| if req["progress"] != doc.progress: | if req["progress"] != doc.progress: | ||||
| return get_error_data_result(retmsg="Can't change `progress`.") | |||||
| return get_error_data_result(message="Can't change `progress`.") | |||||
| if "name" in req and req["name"] != doc.name: | if "name" in req and req["name"] != doc.name: | ||||
| if ( | if ( | ||||
| != pathlib.Path(doc.name.lower()).suffix | != pathlib.Path(doc.name.lower()).suffix | ||||
| ): | ): | ||||
| return get_result( | return get_result( | ||||
| retmsg="The extension of file can't be changed", | |||||
| retcode=RetCode.ARGUMENT_ERROR, | |||||
| message="The extension of file can't be changed", | |||||
| code=RetCode.ARGUMENT_ERROR, | |||||
| ) | ) | ||||
| for d in DocumentService.query(name=req["name"], kb_id=doc.kb_id): | for d in DocumentService.query(name=req["name"], kb_id=doc.kb_id): | ||||
| if d.name == req["name"]: | if d.name == req["name"]: | ||||
| return get_error_data_result( | return get_error_data_result( | ||||
| retmsg="Duplicated document name in the same dataset." | |||||
| message="Duplicated document name in the same dataset." | |||||
| ) | ) | ||||
| if not DocumentService.update_by_id(document_id, {"name": req["name"]}): | if not DocumentService.update_by_id(document_id, {"name": req["name"]}): | ||||
| return get_error_data_result(retmsg="Database error (Document rename)!") | |||||
| return get_error_data_result(message="Database error (Document rename)!") | |||||
| informs = File2DocumentService.get_by_document_id(document_id) | informs = File2DocumentService.get_by_document_id(document_id) | ||||
| if informs: | if informs: | ||||
| return get_result() | return get_result() | ||||
| if doc.type == FileType.VISUAL or re.search(r"\.(ppt|pptx|pages)$", doc.name): | if doc.type == FileType.VISUAL or re.search(r"\.(ppt|pptx|pages)$", doc.name): | ||||
| return get_error_data_result(retmsg="Not supported yet!") | |||||
| return get_error_data_result(message="Not supported yet!") | |||||
| e = DocumentService.update_by_id( | e = DocumentService.update_by_id( | ||||
| doc.id, | doc.id, | ||||
| }, | }, | ||||
| ) | ) | ||||
| if not e: | if not e: | ||||
| return get_error_data_result(retmsg="Document not found!") | |||||
| return get_error_data_result(message="Document not found!") | |||||
| req["parser_config"] = get_parser_config( | req["parser_config"] = get_parser_config( | ||||
| req["chunk_method"], req.get("parser_config") | req["chunk_method"], req.get("parser_config") | ||||
| ) | ) | ||||
| doc.process_duation * -1, | doc.process_duation * -1, | ||||
| ) | ) | ||||
| if not e: | if not e: | ||||
| return get_error_data_result(retmsg="Document not found!") | |||||
| return get_error_data_result(message="Document not found!") | |||||
| ELASTICSEARCH.deleteByQuery( | ELASTICSEARCH.deleteByQuery( | ||||
| Q("match", doc_id=doc.id), idxnm=search.index_name(tenant_id) | Q("match", doc_id=doc.id), idxnm=search.index_name(tenant_id) | ||||
| ) | ) | ||||
| type: object | type: object | ||||
| """ | """ | ||||
| if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | ||||
| return get_error_data_result(retmsg=f"You do not own the dataset {dataset_id}.") | |||||
| return get_error_data_result(message=f"You do not own the dataset {dataset_id}.") | |||||
| doc = DocumentService.query(kb_id=dataset_id, id=document_id) | doc = DocumentService.query(kb_id=dataset_id, id=document_id) | ||||
| if not doc: | if not doc: | ||||
| return get_error_data_result( | return get_error_data_result( | ||||
| retmsg=f"The dataset not own the document {document_id}." | |||||
| message=f"The dataset not own the document {document_id}." | |||||
| ) | ) | ||||
| # The process of downloading | # The process of downloading | ||||
| doc_id, doc_location = File2DocumentService.get_storage_address( | doc_id, doc_location = File2DocumentService.get_storage_address( | ||||
| description: Processing status. | description: Processing status. | ||||
| """ | """ | ||||
| if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | ||||
| return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}. ") | |||||
| return get_error_data_result(message=f"You don't own the dataset {dataset_id}. ") | |||||
| id = request.args.get("id") | id = request.args.get("id") | ||||
| name = request.args.get("name") | name = request.args.get("name") | ||||
| if not DocumentService.query(id=id, kb_id=dataset_id): | if not DocumentService.query(id=id, kb_id=dataset_id): | ||||
| return get_error_data_result(retmsg=f"You don't own the document {id}.") | |||||
| return get_error_data_result(message=f"You don't own the document {id}.") | |||||
| if not DocumentService.query(name=name, kb_id=dataset_id): | if not DocumentService.query(name=name, kb_id=dataset_id): | ||||
| return get_error_data_result(retmsg=f"You don't own the document {name}.") | |||||
| return get_error_data_result(message=f"You don't own the document {name}.") | |||||
| page = int(request.args.get("page", 1)) | page = int(request.args.get("page", 1)) | ||||
| keywords = request.args.get("keywords", "") | keywords = request.args.get("keywords", "") | ||||
| page_size = int(request.args.get("page_size", 1024)) | page_size = int(request.args.get("page_size", 1024)) | ||||
| type: object | type: object | ||||
| """ | """ | ||||
| if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | ||||
| return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}. ") | |||||
| return get_error_data_result(message=f"You don't own the dataset {dataset_id}. ") | |||||
| req = request.json | req = request.json | ||||
| if not req: | if not req: | ||||
| doc_ids = None | doc_ids = None | ||||
| try: | try: | ||||
| e, doc = DocumentService.get_by_id(doc_id) | e, doc = DocumentService.get_by_id(doc_id) | ||||
| if not e: | if not e: | ||||
| return get_error_data_result(retmsg="Document not found!") | |||||
| return get_error_data_result(message="Document not found!") | |||||
| tenant_id = DocumentService.get_tenant_id(doc_id) | tenant_id = DocumentService.get_tenant_id(doc_id) | ||||
| if not tenant_id: | if not tenant_id: | ||||
| return get_error_data_result(retmsg="Tenant not found!") | |||||
| return get_error_data_result(message="Tenant not found!") | |||||
| b, n = File2DocumentService.get_storage_address(doc_id=doc_id) | b, n = File2DocumentService.get_storage_address(doc_id=doc_id) | ||||
| if not DocumentService.remove_document(doc, tenant_id): | if not DocumentService.remove_document(doc, tenant_id): | ||||
| return get_error_data_result( | return get_error_data_result( | ||||
| retmsg="Database error (Document removal)!" | |||||
| message="Database error (Document removal)!" | |||||
| ) | ) | ||||
| f2d = File2DocumentService.get_by_document_id(doc_id) | f2d = File2DocumentService.get_by_document_id(doc_id) | ||||
| errors += str(e) | errors += str(e) | ||||
| if errors: | if errors: | ||||
| return get_result(retmsg=errors, retcode=RetCode.SERVER_ERROR) | |||||
| return get_result(message=errors, code=RetCode.SERVER_ERROR) | |||||
| return get_result() | return get_result() | ||||
| type: object | type: object | ||||
| """ | """ | ||||
| if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | ||||
| return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}.") | |||||
| return get_error_data_result(message=f"You don't own the dataset {dataset_id}.") | |||||
| req = request.json | req = request.json | ||||
| if not req.get("document_ids"): | if not req.get("document_ids"): | ||||
| return get_error_data_result("`document_ids` is required") | return get_error_data_result("`document_ids` is required") | ||||
| for id in req["document_ids"]: | for id in req["document_ids"]: | ||||
| doc = DocumentService.query(id=id, kb_id=dataset_id) | doc = DocumentService.query(id=id, kb_id=dataset_id) | ||||
| if not doc: | if not doc: | ||||
| return get_error_data_result(retmsg=f"You don't own the document {id}.") | |||||
| return get_error_data_result(message=f"You don't own the document {id}.") | |||||
| if doc[0].progress != 0.0: | if doc[0].progress != 0.0: | ||||
| return get_error_data_result( | return get_error_data_result( | ||||
| "Can't stop parsing document with progress at 0 or 100" | "Can't stop parsing document with progress at 0 or 100" | ||||
| type: object | type: object | ||||
| """ | """ | ||||
| if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | ||||
| return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}.") | |||||
| return get_error_data_result(message=f"You don't own the dataset {dataset_id}.") | |||||
| req = request.json | req = request.json | ||||
| if not req.get("document_ids"): | if not req.get("document_ids"): | ||||
| return get_error_data_result("`document_ids` is required") | return get_error_data_result("`document_ids` is required") | ||||
| for id in req["document_ids"]: | for id in req["document_ids"]: | ||||
| doc = DocumentService.query(id=id, kb_id=dataset_id) | doc = DocumentService.query(id=id, kb_id=dataset_id) | ||||
| if not doc: | if not doc: | ||||
| return get_error_data_result(retmsg=f"You don't own the document {id}.") | |||||
| return get_error_data_result(message=f"You don't own the document {id}.") | |||||
| if int(doc[0].progress) == 1 or int(doc[0].progress) == 0: | if int(doc[0].progress) == 1 or int(doc[0].progress) == 0: | ||||
| return get_error_data_result( | return get_error_data_result( | ||||
| "Can't stop parsing document with progress at 0 or 1" | "Can't stop parsing document with progress at 0 or 1" | ||||
| description: Document details. | description: Document details. | ||||
| """ | """ | ||||
| if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | ||||
| return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}.") | |||||
| return get_error_data_result(message=f"You don't own the dataset {dataset_id}.") | |||||
| doc = DocumentService.query(id=document_id, kb_id=dataset_id) | doc = DocumentService.query(id=document_id, kb_id=dataset_id) | ||||
| if not doc: | if not doc: | ||||
| return get_error_data_result( | return get_error_data_result( | ||||
| retmsg=f"You don't own the document {document_id}." | |||||
| message=f"You don't own the document {document_id}." | |||||
| ) | ) | ||||
| doc = doc[0] | doc = doc[0] | ||||
| req = request.args | req = request.args | ||||
| description: Important keywords. | description: Important keywords. | ||||
| """ | """ | ||||
| if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | ||||
| return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}.") | |||||
| return get_error_data_result(message=f"You don't own the dataset {dataset_id}.") | |||||
| doc = DocumentService.query(id=document_id, kb_id=dataset_id) | doc = DocumentService.query(id=document_id, kb_id=dataset_id) | ||||
| if not doc: | if not doc: | ||||
| return get_error_data_result( | return get_error_data_result( | ||||
| retmsg=f"You don't own the document {document_id}." | |||||
| message=f"You don't own the document {document_id}." | |||||
| ) | ) | ||||
| doc = doc[0] | doc = doc[0] | ||||
| req = request.json | req = request.json | ||||
| if not req.get("content"): | if not req.get("content"): | ||||
| return get_error_data_result(retmsg="`content` is required") | |||||
| return get_error_data_result(message="`content` is required") | |||||
| if "important_keywords" in req: | if "important_keywords" in req: | ||||
| if type(req["important_keywords"]) != list: | if type(req["important_keywords"]) != list: | ||||
| return get_error_data_result( | return get_error_data_result( | ||||
| type: object | type: object | ||||
| """ | """ | ||||
| if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | ||||
| return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}.") | |||||
| return get_error_data_result(message=f"You don't own the dataset {dataset_id}.") | |||||
| doc = DocumentService.query(id=document_id, kb_id=dataset_id) | doc = DocumentService.query(id=document_id, kb_id=dataset_id) | ||||
| if not doc: | if not doc: | ||||
| return get_error_data_result( | return get_error_data_result( | ||||
| retmsg=f"You don't own the document {document_id}." | |||||
| message=f"You don't own the document {document_id}." | |||||
| ) | ) | ||||
| doc = doc[0] | doc = doc[0] | ||||
| req = request.json | req = request.json | ||||
| if not ELASTICSEARCH.deleteByQuery( | if not ELASTICSEARCH.deleteByQuery( | ||||
| Q("ids", values=chunk_list), search.index_name(tenant_id) | Q("ids", values=chunk_list), search.index_name(tenant_id) | ||||
| ): | ): | ||||
| return get_error_data_result(retmsg="Index updating failure") | |||||
| return get_error_data_result(message="Index updating failure") | |||||
| deleted_chunk_ids = chunk_list | deleted_chunk_ids = chunk_list | ||||
| chunk_number = len(deleted_chunk_ids) | chunk_number = len(deleted_chunk_ids) | ||||
| DocumentService.decrement_chunk_num(doc.id, doc.kb_id, 1, chunk_number, 0) | DocumentService.decrement_chunk_num(doc.id, doc.kb_id, 1, chunk_number, 0) | ||||
| """ | """ | ||||
| try: | try: | ||||
| res = ELASTICSEARCH.get(chunk_id, search.index_name(tenant_id)) | res = ELASTICSEARCH.get(chunk_id, search.index_name(tenant_id)) | ||||
| except Exception as e: | |||||
| except Exception: | |||||
| return get_error_data_result(f"Can't find this chunk {chunk_id}") | return get_error_data_result(f"Can't find this chunk {chunk_id}") | ||||
| if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | if not KnowledgebaseService.query(id=dataset_id, tenant_id=tenant_id): | ||||
| return get_error_data_result(retmsg=f"You don't own the dataset {dataset_id}.") | |||||
| return get_error_data_result(message=f"You don't own the dataset {dataset_id}.") | |||||
| doc = DocumentService.query(id=document_id, kb_id=dataset_id) | doc = DocumentService.query(id=document_id, kb_id=dataset_id) | ||||
| if not doc: | if not doc: | ||||
| return get_error_data_result( | return get_error_data_result( | ||||
| retmsg=f"You don't own the document {document_id}." | |||||
| message=f"You don't own the document {document_id}." | |||||
| ) | ) | ||||
| doc = doc[0] | doc = doc[0] | ||||
| query = { | query = { | ||||
| arr = [t for t in re.split(r"[\n\t]", d["content_with_weight"]) if len(t) > 1] | arr = [t for t in re.split(r"[\n\t]", d["content_with_weight"]) if len(t) > 1] | ||||
| if len(arr) != 2: | if len(arr) != 2: | ||||
| return get_error_data_result( | return get_error_data_result( | ||||
| retmsg="Q&A must be separated by TAB/ENTER key." | |||||
| message="Q&A must be separated by TAB/ENTER key." | |||||
| ) | ) | ||||
| q, a = rmPrefix(arr[0]), rmPrefix(arr[1]) | q, a = rmPrefix(arr[0]), rmPrefix(arr[1]) | ||||
| d = beAdoc( | d = beAdoc( | ||||
| embd_nms = list(set([kb.embd_id for kb in kbs])) | embd_nms = list(set([kb.embd_id for kb in kbs])) | ||||
| if len(embd_nms) != 1: | if len(embd_nms) != 1: | ||||
| return get_result( | return get_result( | ||||
| retmsg='Datasets use different embedding models."', | |||||
| retcode=RetCode.AUTHENTICATION_ERROR, | |||||
| message='Datasets use different embedding models."', | |||||
| code=RetCode.AUTHENTICATION_ERROR, | |||||
| ) | ) | ||||
| if "question" not in req: | if "question" not in req: | ||||
| return get_error_data_result("`question` is required.") | return get_error_data_result("`question` is required.") | ||||
| try: | try: | ||||
| e, kb = KnowledgebaseService.get_by_id(kb_ids[0]) | e, kb = KnowledgebaseService.get_by_id(kb_ids[0]) | ||||
| if not e: | if not e: | ||||
| return get_error_data_result(retmsg="Dataset not found!") | |||||
| return get_error_data_result(message="Dataset not found!") | |||||
| embd_mdl = TenantLLMService.model_instance( | embd_mdl = TenantLLMService.model_instance( | ||||
| kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id | kb.tenant_id, LLMType.EMBEDDING.value, llm_name=kb.embd_id | ||||
| ) | ) | ||||
| except Exception as e: | except Exception as e: | ||||
| if str(e).find("not_found") > 0: | if str(e).find("not_found") > 0: | ||||
| return get_result( | return get_result( | ||||
| retmsg=f"No chunk found! Check the chunk status please!", | |||||
| retcode=RetCode.DATA_ERROR, | |||||
| message="No chunk found! Check the chunk status please!", | |||||
| code=RetCode.DATA_ERROR, | |||||
| ) | ) | ||||
| return server_error_response(e) | return server_error_response(e) |
| # | |||||
| # Copyright 2024 The InfiniFlow Authors. All Rights Reserved. | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| # | |||||
| import json | |||||
| from functools import partial | |||||
| from uuid import uuid4 | |||||
| from flask import request, Response | |||||
| from agent.canvas import Canvas | |||||
| from api.db import StatusEnum | |||||
| from api.db.db_models import API4Conversation | |||||
| from api.db.services.api_service import API4ConversationService | |||||
| from api.db.services.canvas_service import UserCanvasService | |||||
| from api.db.services.dialog_service import DialogService, ConversationService, chat | |||||
| from api.utils import get_uuid | |||||
| from api.utils.api_utils import get_error_data_result | |||||
| from api.utils.api_utils import get_result, token_required | |||||
| @manager.route('/chats/<chat_id>/sessions', methods=['POST']) | |||||
| @token_required | |||||
| def create(tenant_id,chat_id): | |||||
| req = request.json | |||||
| req["dialog_id"] = chat_id | |||||
| dia = DialogService.query(tenant_id=tenant_id, id=req["dialog_id"], status=StatusEnum.VALID.value) | |||||
| if not dia: | |||||
| return get_error_data_result(retmsg="You do not own the assistant.") | |||||
| conv = { | |||||
| "id": get_uuid(), | |||||
| "dialog_id": req["dialog_id"], | |||||
| "name": req.get("name", "New session"), | |||||
| "message": [{"role": "assistant", "content": "Hi! I am your assistant,can I help you?"}] | |||||
| } | |||||
| if not conv.get("name"): | |||||
| return get_error_data_result(retmsg="`name` can not be empty.") | |||||
| ConversationService.save(**conv) | |||||
| e, conv = ConversationService.get_by_id(conv["id"]) | |||||
| if not e: | |||||
| return get_error_data_result(retmsg="Fail to create a session!") | |||||
| conv = conv.to_dict() | |||||
| conv['messages'] = conv.pop("message") | |||||
| conv["chat_id"] = conv.pop("dialog_id") | |||||
| del conv["reference"] | |||||
| return get_result(data=conv) | |||||
| @manager.route('/agents/<agent_id>/sessions', methods=['POST']) | |||||
| @token_required | |||||
| def create_agent_session(tenant_id, agent_id): | |||||
| req = request.json | |||||
| e, cvs = UserCanvasService.get_by_id(agent_id) | |||||
| if not e: | |||||
| return get_error_data_result("Agent not found.") | |||||
| if cvs.user_id != tenant_id: | |||||
| return get_error_data_result(retmsg="You do not own the agent.") | |||||
| if not isinstance(cvs.dsl, str): | |||||
| cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False) | |||||
| canvas = Canvas(cvs.dsl, tenant_id) | |||||
| conv = { | |||||
| "id": get_uuid(), | |||||
| "dialog_id": cvs.id, | |||||
| "user_id": req.get("user_id", ""), | |||||
| "message": [{"role": "assistant", "content": canvas.get_prologue()}], | |||||
| "source": "agent" | |||||
| } | |||||
| API4ConversationService.save(**conv) | |||||
| return get_result(data=conv) | |||||
| @manager.route('/chats/<chat_id>/sessions/<session_id>', methods=['PUT']) | |||||
| @token_required | |||||
| def update(tenant_id,chat_id,session_id): | |||||
| req = request.json | |||||
| req["dialog_id"] = chat_id | |||||
| conv_id = session_id | |||||
| conv = ConversationService.query(id=conv_id,dialog_id=chat_id) | |||||
| if not conv: | |||||
| return get_error_data_result(retmsg="Session does not exist") | |||||
| if not DialogService.query(id=chat_id, tenant_id=tenant_id, status=StatusEnum.VALID.value): | |||||
| return get_error_data_result(retmsg="You do not own the session") | |||||
| if "message" in req or "messages" in req: | |||||
| return get_error_data_result(retmsg="`message` can not be change") | |||||
| if "reference" in req: | |||||
| return get_error_data_result(retmsg="`reference` can not be change") | |||||
| if "name" in req and not req.get("name"): | |||||
| return get_error_data_result(retmsg="`name` can not be empty.") | |||||
| if not ConversationService.update_by_id(conv_id, req): | |||||
| return get_error_data_result(retmsg="Session updates error") | |||||
| return get_result() | |||||
| @manager.route('/chats/<chat_id>/completions', methods=['POST']) | |||||
| @token_required | |||||
| def completion(tenant_id, chat_id): | |||||
| req = request.json | |||||
| if not req.get("session_id"): | |||||
| conv = { | |||||
| "id": get_uuid(), | |||||
| "dialog_id": chat_id, | |||||
| "name": req.get("name", "New session"), | |||||
| "message": [{"role": "assistant", "content": "Hi! I am your assistant,can I help you?"}] | |||||
| } | |||||
| if not conv.get("name"): | |||||
| return get_error_data_result(retmsg="`name` can not be empty.") | |||||
| ConversationService.save(**conv) | |||||
| e, conv = ConversationService.get_by_id(conv["id"]) | |||||
| session_id=conv.id | |||||
| else: | |||||
| session_id = req.get("session_id") | |||||
| if not req.get("question"): | |||||
| return get_error_data_result(retmsg="Please input your question.") | |||||
| conv = ConversationService.query(id=session_id,dialog_id=chat_id) | |||||
| if not conv: | |||||
| return get_error_data_result(retmsg="Session does not exist") | |||||
| conv = conv[0] | |||||
| if not DialogService.query(id=chat_id, tenant_id=tenant_id, status=StatusEnum.VALID.value): | |||||
| return get_error_data_result(retmsg="You do not own the chat") | |||||
| msg = [] | |||||
| question = { | |||||
| "content": req.get("question"), | |||||
| "role": "user", | |||||
| "id": str(uuid4()) | |||||
| } | |||||
| conv.message.append(question) | |||||
| for m in conv.message: | |||||
| if m["role"] == "system": continue | |||||
| if m["role"] == "assistant" and not msg: continue | |||||
| msg.append(m) | |||||
| message_id = msg[-1].get("id") | |||||
| e, dia = DialogService.get_by_id(conv.dialog_id) | |||||
| if not conv.reference: | |||||
| conv.reference = [] | |||||
| conv.message.append({"role": "assistant", "content": "", "id": message_id}) | |||||
| conv.reference.append({"chunks": [], "doc_aggs": []}) | |||||
| def fillin_conv(ans): | |||||
| nonlocal conv, message_id | |||||
| if not conv.reference: | |||||
| conv.reference.append(ans["reference"]) | |||||
| else: | |||||
| conv.reference[-1] = ans["reference"] | |||||
| conv.message[-1] = {"role": "assistant", "content": ans["answer"], | |||||
| "id": message_id, "prompt": ans.get("prompt", "")} | |||||
| ans["id"] = message_id | |||||
| ans["session_id"]=session_id | |||||
| def stream(): | |||||
| nonlocal dia, msg, req, conv | |||||
| try: | |||||
| for ans in chat(dia, msg, **req): | |||||
| fillin_conv(ans) | |||||
| yield "data:" + json.dumps({"code": 0, "data": ans}, ensure_ascii=False) + "\n\n" | |||||
| ConversationService.update_by_id(conv.id, conv.to_dict()) | |||||
| except Exception as e: | |||||
| yield "data:" + json.dumps({"code": 500, "message": str(e), | |||||
| "data": {"answer": "**ERROR**: " + str(e),"reference": []}}, | |||||
| ensure_ascii=False) + "\n\n" | |||||
| yield "data:" + json.dumps({"code": 0, "data": True}, ensure_ascii=False) + "\n\n" | |||||
| if req.get("stream", True): | |||||
| resp = Response(stream(), mimetype="text/event-stream") | |||||
| resp.headers.add_header("Cache-control", "no-cache") | |||||
| resp.headers.add_header("Connection", "keep-alive") | |||||
| resp.headers.add_header("X-Accel-Buffering", "no") | |||||
| resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8") | |||||
| return resp | |||||
| else: | |||||
| answer = None | |||||
| for ans in chat(dia, msg, **req): | |||||
| answer = ans | |||||
| fillin_conv(ans) | |||||
| ConversationService.update_by_id(conv.id, conv.to_dict()) | |||||
| break | |||||
| return get_result(data=answer) | |||||
| @manager.route('/agents/<agent_id>/completions', methods=['POST']) | |||||
| @token_required | |||||
| def agent_completion(tenant_id, agent_id): | |||||
| req = request.json | |||||
| e, cvs = UserCanvasService.get_by_id(agent_id) | |||||
| if not e: | |||||
| return get_error_data_result("Agent not found.") | |||||
| if cvs.user_id != tenant_id: | |||||
| return get_error_data_result(retmsg="You do not own the agent.") | |||||
| if not isinstance(cvs.dsl, str): | |||||
| cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False) | |||||
| canvas = Canvas(cvs.dsl, tenant_id) | |||||
| msg = [] | |||||
| for m in req["messages"]: | |||||
| if m["role"] == "system": | |||||
| continue | |||||
| if m["role"] == "assistant" and not msg: | |||||
| continue | |||||
| msg.append(m) | |||||
| if not msg[-1].get("id"): msg[-1]["id"] = get_uuid() | |||||
| message_id = msg[-1]["id"] | |||||
| if not req.get("session_id"): | |||||
| session_id = get_uuid() | |||||
| conv = { | |||||
| "id": session_id, | |||||
| "dialog_id": cvs.id, | |||||
| "user_id": req.get("user_id", ""), | |||||
| "message": [{"role": "assistant", "content": canvas.get_prologue()}], | |||||
| "source": "agent" | |||||
| } | |||||
| API4ConversationService.save(**conv) | |||||
| conv = API4Conversation(**conv) | |||||
| else: | |||||
| session_id = req.get("session_id") | |||||
| e, conv = API4ConversationService.get_by_id(req["session_id"]) | |||||
| if not e: | |||||
| return get_error_data_result(retmsg="Session not found!") | |||||
| if "quote" not in req: req["quote"] = False | |||||
| stream = req.get("stream", True) | |||||
| def fillin_conv(ans): | |||||
| nonlocal conv, message_id | |||||
| if not conv.reference: | |||||
| conv.reference.append(ans["reference"]) | |||||
| else: | |||||
| conv.reference[-1] = ans["reference"] | |||||
| conv.message[-1] = {"role": "assistant", "content": ans["answer"], "id": message_id} | |||||
| ans["id"] = message_id | |||||
| ans["session_id"] = session_id | |||||
| def rename_field(ans): | |||||
| reference = ans['reference'] | |||||
| if not isinstance(reference, dict): | |||||
| return | |||||
| for chunk_i in reference.get('chunks', []): | |||||
| if 'docnm_kwd' in chunk_i: | |||||
| chunk_i['doc_name'] = chunk_i['docnm_kwd'] | |||||
| chunk_i.pop('docnm_kwd') | |||||
| conv.message.append(msg[-1]) | |||||
| if not conv.reference: | |||||
| conv.reference = [] | |||||
| conv.message.append({"role": "assistant", "content": "", "id": message_id}) | |||||
| conv.reference.append({"chunks": [], "doc_aggs": []}) | |||||
| final_ans = {"reference": [], "content": ""} | |||||
| canvas.messages.append(msg[-1]) | |||||
| canvas.add_user_input(msg[-1]["content"]) | |||||
| answer = canvas.run(stream=stream) | |||||
| assert answer is not None, "Nothing. Is it over?" | |||||
| if stream: | |||||
| assert isinstance(answer, partial), "Nothing. Is it over?" | |||||
| def sse(): | |||||
| nonlocal answer, cvs, conv | |||||
| try: | |||||
| for ans in answer(): | |||||
| for k in ans.keys(): | |||||
| final_ans[k] = ans[k] | |||||
| ans = {"answer": ans["content"], "reference": ans.get("reference", [])} | |||||
| fillin_conv(ans) | |||||
| rename_field(ans) | |||||
| yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": ans}, | |||||
| ensure_ascii=False) + "\n\n" | |||||
| canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) | |||||
| if final_ans.get("reference"): | |||||
| canvas.reference.append(final_ans["reference"]) | |||||
| cvs.dsl = json.loads(str(canvas)) | |||||
| API4ConversationService.append_message(conv.id, conv.to_dict()) | |||||
| except Exception as e: | |||||
| yield "data:" + json.dumps({"retcode": 500, "retmsg": str(e), | |||||
| "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, | |||||
| ensure_ascii=False) + "\n\n" | |||||
| yield "data:" + json.dumps({"retcode": 0, "retmsg": "", "data": True}, ensure_ascii=False) + "\n\n" | |||||
| resp = Response(sse(), mimetype="text/event-stream") | |||||
| resp.headers.add_header("Cache-control", "no-cache") | |||||
| resp.headers.add_header("Connection", "keep-alive") | |||||
| resp.headers.add_header("X-Accel-Buffering", "no") | |||||
| resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8") | |||||
| return resp | |||||
| final_ans["content"] = "\n".join(answer["content"]) if "content" in answer else "" | |||||
| canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) | |||||
| if final_ans.get("reference"): | |||||
| canvas.reference.append(final_ans["reference"]) | |||||
| cvs.dsl = json.loads(str(canvas)) | |||||
| result = {"answer": final_ans["content"], "reference": final_ans.get("reference", [])} | |||||
| fillin_conv(result) | |||||
| API4ConversationService.append_message(conv.id, conv.to_dict()) | |||||
| rename_field(result) | |||||
| return get_result(data=result) | |||||
| @manager.route('/chats/<chat_id>/sessions', methods=['GET']) | |||||
| @token_required | |||||
| def list(chat_id,tenant_id): | |||||
| if not DialogService.query(tenant_id=tenant_id, id=chat_id, status=StatusEnum.VALID.value): | |||||
| return get_error_data_result(retmsg=f"You don't own the assistant {chat_id}.") | |||||
| id = request.args.get("id") | |||||
| name = request.args.get("name") | |||||
| page_number = int(request.args.get("page", 1)) | |||||
| items_per_page = int(request.args.get("page_size", 1024)) | |||||
| orderby = request.args.get("orderby", "create_time") | |||||
| if request.args.get("desc") == "False" or request.args.get("desc") == "false": | |||||
| desc = False | |||||
| else: | |||||
| desc = True | |||||
| convs = ConversationService.get_list(chat_id,page_number,items_per_page,orderby,desc,id,name) | |||||
| if not convs: | |||||
| return get_result(data=[]) | |||||
| for conv in convs: | |||||
| conv['messages'] = conv.pop("message") | |||||
| infos = conv["messages"] | |||||
| for info in infos: | |||||
| if "prompt" in info: | |||||
| info.pop("prompt") | |||||
| conv["chat"] = conv.pop("dialog_id") | |||||
| if conv["reference"]: | |||||
| messages = conv["messages"] | |||||
| message_num = 0 | |||||
| chunk_num = 0 | |||||
| while message_num < len(messages): | |||||
| if message_num != 0 and messages[message_num]["role"] != "user": | |||||
| chunk_list = [] | |||||
| if "chunks" in conv["reference"][chunk_num]: | |||||
| chunks = conv["reference"][chunk_num]["chunks"] | |||||
| for chunk in chunks: | |||||
| new_chunk = { | |||||
| "id": chunk["chunk_id"], | |||||
| "content": chunk["content_with_weight"], | |||||
| "document_id": chunk["doc_id"], | |||||
| "document_name": chunk["docnm_kwd"], | |||||
| "dataset_id": chunk["kb_id"], | |||||
| "image_id": chunk["img_id"], | |||||
| "similarity": chunk["similarity"], | |||||
| "vector_similarity": chunk["vector_similarity"], | |||||
| "term_similarity": chunk["term_similarity"], | |||||
| "positions": chunk["positions"], | |||||
| } | |||||
| chunk_list.append(new_chunk) | |||||
| chunk_num += 1 | |||||
| messages[message_num]["reference"] = chunk_list | |||||
| message_num += 1 | |||||
| del conv["reference"] | |||||
| return get_result(data=convs) | |||||
| @manager.route('/chats/<chat_id>/sessions', methods=["DELETE"]) | |||||
| @token_required | |||||
| def delete(tenant_id,chat_id): | |||||
| if not DialogService.query(id=chat_id, tenant_id=tenant_id, status=StatusEnum.VALID.value): | |||||
| return get_error_data_result(retmsg="You don't own the chat") | |||||
| req = request.json | |||||
| convs = ConversationService.query(dialog_id=chat_id) | |||||
| if not req: | |||||
| ids = None | |||||
| else: | |||||
| ids=req.get("ids") | |||||
| if not ids: | |||||
| conv_list = [] | |||||
| for conv in convs: | |||||
| conv_list.append(conv.id) | |||||
| else: | |||||
| conv_list=ids | |||||
| for id in conv_list: | |||||
| conv = ConversationService.query(id=id,dialog_id=chat_id) | |||||
| if not conv: | |||||
| return get_error_data_result(retmsg="The chat doesn't own the session") | |||||
| ConversationService.delete_by_id(id) | |||||
| return get_result() | |||||
| # | |||||
| # Copyright 2024 The InfiniFlow Authors. All Rights Reserved. | |||||
| # | |||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| # you may not use this file except in compliance with the License. | |||||
| # You may obtain a copy of the License at | |||||
| # | |||||
| # http://www.apache.org/licenses/LICENSE-2.0 | |||||
| # | |||||
| # Unless required by applicable law or agreed to in writing, software | |||||
| # distributed under the License is distributed on an "AS IS" BASIS, | |||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| # See the License for the specific language governing permissions and | |||||
| # limitations under the License. | |||||
| # | |||||
| import json | |||||
| from functools import partial | |||||
| from uuid import uuid4 | |||||
| from flask import request, Response | |||||
| from agent.canvas import Canvas | |||||
| from api.db import StatusEnum | |||||
| from api.db.db_models import API4Conversation | |||||
| from api.db.services.api_service import API4ConversationService | |||||
| from api.db.services.canvas_service import UserCanvasService | |||||
| from api.db.services.dialog_service import DialogService, ConversationService, chat | |||||
| from api.utils import get_uuid | |||||
| from api.utils.api_utils import get_error_data_result | |||||
| from api.utils.api_utils import get_result, token_required | |||||
| @manager.route('/chats/<chat_id>/sessions', methods=['POST']) | |||||
| @token_required | |||||
| def create(tenant_id,chat_id): | |||||
| req = request.json | |||||
| req["dialog_id"] = chat_id | |||||
| dia = DialogService.query(tenant_id=tenant_id, id=req["dialog_id"], status=StatusEnum.VALID.value) | |||||
| if not dia: | |||||
| return get_error_data_result(message="You do not own the assistant.") | |||||
| conv = { | |||||
| "id": get_uuid(), | |||||
| "dialog_id": req["dialog_id"], | |||||
| "name": req.get("name", "New session"), | |||||
| "message": [{"role": "assistant", "content": "Hi! I am your assistant,can I help you?"}] | |||||
| } | |||||
| if not conv.get("name"): | |||||
| return get_error_data_result(message="`name` can not be empty.") | |||||
| ConversationService.save(**conv) | |||||
| e, conv = ConversationService.get_by_id(conv["id"]) | |||||
| if not e: | |||||
| return get_error_data_result(message="Fail to create a session!") | |||||
| conv = conv.to_dict() | |||||
| conv['messages'] = conv.pop("message") | |||||
| conv["chat_id"] = conv.pop("dialog_id") | |||||
| del conv["reference"] | |||||
| return get_result(data=conv) | |||||
| @manager.route('/agents/<agent_id>/sessions', methods=['POST']) | |||||
| @token_required | |||||
| def create_agent_session(tenant_id, agent_id): | |||||
| req = request.json | |||||
| e, cvs = UserCanvasService.get_by_id(agent_id) | |||||
| if not e: | |||||
| return get_error_data_result("Agent not found.") | |||||
| if cvs.user_id != tenant_id: | |||||
| return get_error_data_result(message="You do not own the agent.") | |||||
| if not isinstance(cvs.dsl, str): | |||||
| cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False) | |||||
| canvas = Canvas(cvs.dsl, tenant_id) | |||||
| conv = { | |||||
| "id": get_uuid(), | |||||
| "dialog_id": cvs.id, | |||||
| "user_id": req.get("user_id", ""), | |||||
| "message": [{"role": "assistant", "content": canvas.get_prologue()}], | |||||
| "source": "agent" | |||||
| } | |||||
| API4ConversationService.save(**conv) | |||||
| return get_result(data=conv) | |||||
| @manager.route('/chats/<chat_id>/sessions/<session_id>', methods=['PUT']) | |||||
| @token_required | |||||
| def update(tenant_id,chat_id,session_id): | |||||
| req = request.json | |||||
| req["dialog_id"] = chat_id | |||||
| conv_id = session_id | |||||
| conv = ConversationService.query(id=conv_id,dialog_id=chat_id) | |||||
| if not conv: | |||||
| return get_error_data_result(message="Session does not exist") | |||||
| if not DialogService.query(id=chat_id, tenant_id=tenant_id, status=StatusEnum.VALID.value): | |||||
| return get_error_data_result(message="You do not own the session") | |||||
| if "message" in req or "messages" in req: | |||||
| return get_error_data_result(message="`message` can not be change") | |||||
| if "reference" in req: | |||||
| return get_error_data_result(message="`reference` can not be change") | |||||
| if "name" in req and not req.get("name"): | |||||
| return get_error_data_result(message="`name` can not be empty.") | |||||
| if not ConversationService.update_by_id(conv_id, req): | |||||
| return get_error_data_result(message="Session updates error") | |||||
| return get_result() | |||||
| @manager.route('/chats/<chat_id>/completions', methods=['POST']) | |||||
| @token_required | |||||
| def completion(tenant_id, chat_id): | |||||
| req = request.json | |||||
| if not req.get("session_id"): | |||||
| conv = { | |||||
| "id": get_uuid(), | |||||
| "dialog_id": chat_id, | |||||
| "name": req.get("name", "New session"), | |||||
| "message": [{"role": "assistant", "content": "Hi! I am your assistant,can I help you?"}] | |||||
| } | |||||
| if not conv.get("name"): | |||||
| return get_error_data_result(message="`name` can not be empty.") | |||||
| ConversationService.save(**conv) | |||||
| e, conv = ConversationService.get_by_id(conv["id"]) | |||||
| session_id=conv.id | |||||
| else: | |||||
| session_id = req.get("session_id") | |||||
| if not req.get("question"): | |||||
| return get_error_data_result(message="Please input your question.") | |||||
| conv = ConversationService.query(id=session_id,dialog_id=chat_id) | |||||
| if not conv: | |||||
| return get_error_data_result(message="Session does not exist") | |||||
| conv = conv[0] | |||||
| if not DialogService.query(id=chat_id, tenant_id=tenant_id, status=StatusEnum.VALID.value): | |||||
| return get_error_data_result(message="You do not own the chat") | |||||
| msg = [] | |||||
| question = { | |||||
| "content": req.get("question"), | |||||
| "role": "user", | |||||
| "id": str(uuid4()) | |||||
| } | |||||
| conv.message.append(question) | |||||
| for m in conv.message: | |||||
| if m["role"] == "system": continue | |||||
| if m["role"] == "assistant" and not msg: continue | |||||
| msg.append(m) | |||||
| message_id = msg[-1].get("id") | |||||
| e, dia = DialogService.get_by_id(conv.dialog_id) | |||||
| if not conv.reference: | |||||
| conv.reference = [] | |||||
| conv.message.append({"role": "assistant", "content": "", "id": message_id}) | |||||
| conv.reference.append({"chunks": [], "doc_aggs": []}) | |||||
| def fillin_conv(ans): | |||||
| nonlocal conv, message_id | |||||
| if not conv.reference: | |||||
| conv.reference.append(ans["reference"]) | |||||
| else: | |||||
| conv.reference[-1] = ans["reference"] | |||||
| conv.message[-1] = {"role": "assistant", "content": ans["answer"], | |||||
| "id": message_id, "prompt": ans.get("prompt", "")} | |||||
| ans["id"] = message_id | |||||
| ans["session_id"]=session_id | |||||
| def stream(): | |||||
| nonlocal dia, msg, req, conv | |||||
| try: | |||||
| for ans in chat(dia, msg, **req): | |||||
| fillin_conv(ans) | |||||
| yield "data:" + json.dumps({"code": 0, "data": ans}, ensure_ascii=False) + "\n\n" | |||||
| ConversationService.update_by_id(conv.id, conv.to_dict()) | |||||
| except Exception as e: | |||||
| yield "data:" + json.dumps({"code": 500, "message": str(e), | |||||
| "data": {"answer": "**ERROR**: " + str(e),"reference": []}}, | |||||
| ensure_ascii=False) + "\n\n" | |||||
| yield "data:" + json.dumps({"code": 0, "data": True}, ensure_ascii=False) + "\n\n" | |||||
| if req.get("stream", True): | |||||
| resp = Response(stream(), mimetype="text/event-stream") | |||||
| resp.headers.add_header("Cache-control", "no-cache") | |||||
| resp.headers.add_header("Connection", "keep-alive") | |||||
| resp.headers.add_header("X-Accel-Buffering", "no") | |||||
| resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8") | |||||
| return resp | |||||
| else: | |||||
| answer = None | |||||
| for ans in chat(dia, msg, **req): | |||||
| answer = ans | |||||
| fillin_conv(ans) | |||||
| ConversationService.update_by_id(conv.id, conv.to_dict()) | |||||
| break | |||||
| return get_result(data=answer) | |||||
| @manager.route('/agents/<agent_id>/completions', methods=['POST']) | |||||
| @token_required | |||||
| def agent_completion(tenant_id, agent_id): | |||||
| req = request.json | |||||
| e, cvs = UserCanvasService.get_by_id(agent_id) | |||||
| if not e: | |||||
| return get_error_data_result("Agent not found.") | |||||
| if cvs.user_id != tenant_id: | |||||
| return get_error_data_result(message="You do not own the agent.") | |||||
| if not isinstance(cvs.dsl, str): | |||||
| cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False) | |||||
| canvas = Canvas(cvs.dsl, tenant_id) | |||||
| msg = [] | |||||
| for m in req["messages"]: | |||||
| if m["role"] == "system": | |||||
| continue | |||||
| if m["role"] == "assistant" and not msg: | |||||
| continue | |||||
| msg.append(m) | |||||
| if not msg[-1].get("id"): msg[-1]["id"] = get_uuid() | |||||
| message_id = msg[-1]["id"] | |||||
| if not req.get("session_id"): | |||||
| session_id = get_uuid() | |||||
| conv = { | |||||
| "id": session_id, | |||||
| "dialog_id": cvs.id, | |||||
| "user_id": req.get("user_id", ""), | |||||
| "message": [{"role": "assistant", "content": canvas.get_prologue()}], | |||||
| "source": "agent" | |||||
| } | |||||
| API4ConversationService.save(**conv) | |||||
| conv = API4Conversation(**conv) | |||||
| else: | |||||
| session_id = req.get("session_id") | |||||
| e, conv = API4ConversationService.get_by_id(req["session_id"]) | |||||
| if not e: | |||||
| return get_error_data_result(message="Session not found!") | |||||
| if "quote" not in req: req["quote"] = False | |||||
| stream = req.get("stream", True) | |||||
| def fillin_conv(ans): | |||||
| nonlocal conv, message_id | |||||
| if not conv.reference: | |||||
| conv.reference.append(ans["reference"]) | |||||
| else: | |||||
| conv.reference[-1] = ans["reference"] | |||||
| conv.message[-1] = {"role": "assistant", "content": ans["answer"], "id": message_id} | |||||
| ans["id"] = message_id | |||||
| ans["session_id"] = session_id | |||||
| def rename_field(ans): | |||||
| reference = ans['reference'] | |||||
| if not isinstance(reference, dict): | |||||
| return | |||||
| for chunk_i in reference.get('chunks', []): | |||||
| if 'docnm_kwd' in chunk_i: | |||||
| chunk_i['doc_name'] = chunk_i['docnm_kwd'] | |||||
| chunk_i.pop('docnm_kwd') | |||||
| conv.message.append(msg[-1]) | |||||
| if not conv.reference: | |||||
| conv.reference = [] | |||||
| conv.message.append({"role": "assistant", "content": "", "id": message_id}) | |||||
| conv.reference.append({"chunks": [], "doc_aggs": []}) | |||||
| final_ans = {"reference": [], "content": ""} | |||||
| canvas.messages.append(msg[-1]) | |||||
| canvas.add_user_input(msg[-1]["content"]) | |||||
| answer = canvas.run(stream=stream) | |||||
| assert answer is not None, "Nothing. Is it over?" | |||||
| if stream: | |||||
| assert isinstance(answer, partial), "Nothing. Is it over?" | |||||
| def sse(): | |||||
| nonlocal answer, cvs, conv | |||||
| try: | |||||
| for ans in answer(): | |||||
| for k in ans.keys(): | |||||
| final_ans[k] = ans[k] | |||||
| ans = {"answer": ans["content"], "reference": ans.get("reference", [])} | |||||
| fillin_conv(ans) | |||||
| rename_field(ans) | |||||
| yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, | |||||
| ensure_ascii=False) + "\n\n" | |||||
| canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) | |||||
| if final_ans.get("reference"): | |||||
| canvas.reference.append(final_ans["reference"]) | |||||
| cvs.dsl = json.loads(str(canvas)) | |||||
| API4ConversationService.append_message(conv.id, conv.to_dict()) | |||||
| except Exception as e: | |||||
| yield "data:" + json.dumps({"code": 500, "message": str(e), | |||||
| "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, | |||||
| ensure_ascii=False) + "\n\n" | |||||
| yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n" | |||||
| resp = Response(sse(), mimetype="text/event-stream") | |||||
| resp.headers.add_header("Cache-control", "no-cache") | |||||
| resp.headers.add_header("Connection", "keep-alive") | |||||
| resp.headers.add_header("X-Accel-Buffering", "no") | |||||
| resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8") | |||||
| return resp | |||||
| final_ans["content"] = "\n".join(answer["content"]) if "content" in answer else "" | |||||
| canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) | |||||
| if final_ans.get("reference"): | |||||
| canvas.reference.append(final_ans["reference"]) | |||||
| cvs.dsl = json.loads(str(canvas)) | |||||
| result = {"answer": final_ans["content"], "reference": final_ans.get("reference", [])} | |||||
| fillin_conv(result) | |||||
| API4ConversationService.append_message(conv.id, conv.to_dict()) | |||||
| rename_field(result) | |||||
| return get_result(data=result) | |||||
| @manager.route('/chats/<chat_id>/sessions', methods=['GET']) | |||||
| @token_required | |||||
| def list(chat_id,tenant_id): | |||||
| if not DialogService.query(tenant_id=tenant_id, id=chat_id, status=StatusEnum.VALID.value): | |||||
| return get_error_data_result(message=f"You don't own the assistant {chat_id}.") | |||||
| id = request.args.get("id") | |||||
| name = request.args.get("name") | |||||
| page_number = int(request.args.get("page", 1)) | |||||
| items_per_page = int(request.args.get("page_size", 1024)) | |||||
| orderby = request.args.get("orderby", "create_time") | |||||
| if request.args.get("desc") == "False" or request.args.get("desc") == "false": | |||||
| desc = False | |||||
| else: | |||||
| desc = True | |||||
| convs = ConversationService.get_list(chat_id,page_number,items_per_page,orderby,desc,id,name) | |||||
| if not convs: | |||||
| return get_result(data=[]) | |||||
| for conv in convs: | |||||
| conv['messages'] = conv.pop("message") | |||||
| infos = conv["messages"] | |||||
| for info in infos: | |||||
| if "prompt" in info: | |||||
| info.pop("prompt") | |||||
| conv["chat"] = conv.pop("dialog_id") | |||||
| if conv["reference"]: | |||||
| messages = conv["messages"] | |||||
| message_num = 0 | |||||
| chunk_num = 0 | |||||
| while message_num < len(messages): | |||||
| if message_num != 0 and messages[message_num]["role"] != "user": | |||||
| chunk_list = [] | |||||
| if "chunks" in conv["reference"][chunk_num]: | |||||
| chunks = conv["reference"][chunk_num]["chunks"] | |||||
| for chunk in chunks: | |||||
| new_chunk = { | |||||
| "id": chunk["chunk_id"], | |||||
| "content": chunk["content_with_weight"], | |||||
| "document_id": chunk["doc_id"], | |||||
| "document_name": chunk["docnm_kwd"], | |||||
| "dataset_id": chunk["kb_id"], | |||||
| "image_id": chunk["img_id"], | |||||
| "similarity": chunk["similarity"], | |||||
| "vector_similarity": chunk["vector_similarity"], | |||||
| "term_similarity": chunk["term_similarity"], | |||||
| "positions": chunk["positions"], | |||||
| } | |||||
| chunk_list.append(new_chunk) | |||||
| chunk_num += 1 | |||||
| messages[message_num]["reference"] = chunk_list | |||||
| message_num += 1 | |||||
| del conv["reference"] | |||||
| return get_result(data=convs) | |||||
| @manager.route('/chats/<chat_id>/sessions', methods=["DELETE"]) | |||||
| @token_required | |||||
| def delete(tenant_id,chat_id): | |||||
| if not DialogService.query(id=chat_id, tenant_id=tenant_id, status=StatusEnum.VALID.value): | |||||
| return get_error_data_result(message="You don't own the chat") | |||||
| req = request.json | |||||
| convs = ConversationService.query(dialog_id=chat_id) | |||||
| if not req: | |||||
| ids = None | |||||
| else: | |||||
| ids=req.get("ids") | |||||
| if not ids: | |||||
| conv_list = [] | |||||
| for conv in convs: | |||||
| conv_list.append(conv.id) | |||||
| else: | |||||
| conv_list=ids | |||||
| for id in conv_list: | |||||
| conv = ConversationService.query(id=id,dialog_id=chat_id) | |||||
| if not conv: | |||||
| return get_error_data_result(message="The chat doesn't own the session") | |||||
| ConversationService.delete_by_id(id) | |||||
| return get_result() |
| get_data_error_result, | get_data_error_result, | ||||
| server_error_response, | server_error_response, | ||||
| generate_confirmation_token, | generate_confirmation_token, | ||||
| request, | |||||
| validate_request, | |||||
| ) | ) | ||||
| from api.versions import get_rag_version | from api.versions import get_rag_version | ||||
| from rag.utils.es_conn import ELASTICSEARCH | from rag.utils.es_conn import ELASTICSEARCH | ||||
| try: | try: | ||||
| tenants = UserTenantService.query(user_id=current_user.id) | tenants = UserTenantService.query(user_id=current_user.id) | ||||
| if not tenants: | if not tenants: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| tenant_id = tenants[0].tenant_id | tenant_id = tenants[0].tenant_id | ||||
| obj = { | obj = { | ||||
| } | } | ||||
| if not APITokenService.save(**obj): | if not APITokenService.save(**obj): | ||||
| return get_data_error_result(retmsg="Fail to new a dialog!") | |||||
| return get_data_error_result(message="Fail to new a dialog!") | |||||
| return get_json_result(data=obj) | return get_json_result(data=obj) | ||||
| except Exception as e: | except Exception as e: | ||||
| try: | try: | ||||
| tenants = UserTenantService.query(user_id=current_user.id) | tenants = UserTenantService.query(user_id=current_user.id) | ||||
| if not tenants: | if not tenants: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| objs = APITokenService.query(tenant_id=tenants[0].tenant_id) | objs = APITokenService.query(tenant_id=tenants[0].tenant_id) | ||||
| return get_json_result(data=[o.to_dict() for o in objs]) | return get_json_result(data=[o.to_dict() for o in objs]) |
| req = request.json | req = request.json | ||||
| usrs = UserService.query(email=req["email"]) | usrs = UserService.query(email=req["email"]) | ||||
| if not usrs: | if not usrs: | ||||
| return get_data_error_result(retmsg="User not found.") | |||||
| return get_data_error_result(message="User not found.") | |||||
| user_id = usrs[0].id | user_id = usrs[0].id | ||||
| user_tenants = UserTenantService.query(user_id=user_id, tenant_id=tenant_id) | user_tenants = UserTenantService.query(user_id=user_id, tenant_id=tenant_id) | ||||
| if user_tenants: | if user_tenants: | ||||
| if user_tenants[0].status == UserTenantRole.NORMAL.value: | if user_tenants[0].status == UserTenantRole.NORMAL.value: | ||||
| return get_data_error_result(retmsg="This user is in the team already.") | |||||
| return get_data_error_result(retmsg="Invitation notification is sent.") | |||||
| return get_data_error_result(message="This user is in the team already.") | |||||
| return get_data_error_result(message="Invitation notification is sent.") | |||||
| UserTenantService.save( | UserTenantService.save( | ||||
| id=get_uuid(), | id=get_uuid(), |
| current_timestamp, | current_timestamp, | ||||
| datetime_format, | datetime_format, | ||||
| ) | ) | ||||
| from api.db import UserTenantRole, LLMType, FileType | |||||
| from api.db import UserTenantRole, FileType | |||||
| from api.settings import ( | from api.settings import ( | ||||
| RetCode, | RetCode, | ||||
| GITHUB_OAUTH, | GITHUB_OAUTH, | ||||
| """ | """ | ||||
| if not request.json: | if not request.json: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retcode=RetCode.AUTHENTICATION_ERROR, retmsg="Unauthorized!" | |||||
| data=False, code=RetCode.AUTHENTICATION_ERROR, message="Unauthorized!" | |||||
| ) | ) | ||||
| email = request.json.get("email", "") | email = request.json.get("email", "") | ||||
| if not users: | if not users: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retcode=RetCode.AUTHENTICATION_ERROR, | |||||
| retmsg=f"Email: {email} is not registered!", | |||||
| code=RetCode.AUTHENTICATION_ERROR, | |||||
| message=f"Email: {email} is not registered!", | |||||
| ) | ) | ||||
| password = request.json.get("password") | password = request.json.get("password") | ||||
| password = decrypt(password) | password = decrypt(password) | ||||
| except BaseException: | except BaseException: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retcode=RetCode.SERVER_ERROR, retmsg="Fail to crypt password" | |||||
| data=False, code=RetCode.SERVER_ERROR, message="Fail to crypt password" | |||||
| ) | ) | ||||
| user = UserService.query_user(email, password) | user = UserService.query_user(email, password) | ||||
| user.update_date = (datetime_format(datetime.now()),) | user.update_date = (datetime_format(datetime.now()),) | ||||
| user.save() | user.save() | ||||
| msg = "Welcome back!" | msg = "Welcome back!" | ||||
| return construct_response(data=response_data, auth=user.get_id(), retmsg=msg) | |||||
| return construct_response(data=response_data, auth=user.get_id(), message=msg) | |||||
| else: | else: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retcode=RetCode.AUTHENTICATION_ERROR, | |||||
| retmsg="Email and password do not match!", | |||||
| code=RetCode.AUTHENTICATION_ERROR, | |||||
| message="Email and password do not match!", | |||||
| ) | ) | ||||
| "Authorization": f"Bearer {access_token}", | "Authorization": f"Bearer {access_token}", | ||||
| } | } | ||||
| res = requests.get( | res = requests.get( | ||||
| f"https://open.feishu.cn/open-apis/authen/v1/user_info", headers=headers | |||||
| "https://open.feishu.cn/open-apis/authen/v1/user_info", headers=headers | |||||
| ) | ) | ||||
| user_info = res.json()["data"] | user_info = res.json()["data"] | ||||
| user_info["email"] = None if user_info.get("email") == "" else user_info["email"] | user_info["email"] = None if user_info.get("email") == "" else user_info["email"] | ||||
| ): | ): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retcode=RetCode.AUTHENTICATION_ERROR, | |||||
| retmsg="Password error!", | |||||
| code=RetCode.AUTHENTICATION_ERROR, | |||||
| message="Password error!", | |||||
| ) | ) | ||||
| if new_password: | if new_password: | ||||
| except Exception as e: | except Exception as e: | ||||
| stat_logger.exception(e) | stat_logger.exception(e) | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg="Update failure!", retcode=RetCode.EXCEPTION_ERROR | |||||
| data=False, message="Update failure!", code=RetCode.EXCEPTION_ERROR | |||||
| ) | ) | ||||
| def rollback_user_registration(user_id): | def rollback_user_registration(user_id): | ||||
| try: | try: | ||||
| UserService.delete_by_id(user_id) | UserService.delete_by_id(user_id) | ||||
| except Exception as e: | |||||
| except Exception: | |||||
| pass | pass | ||||
| try: | try: | ||||
| TenantService.delete_by_id(user_id) | TenantService.delete_by_id(user_id) | ||||
| except Exception as e: | |||||
| except Exception: | |||||
| pass | pass | ||||
| try: | try: | ||||
| u = UserTenantService.query(tenant_id=user_id) | u = UserTenantService.query(tenant_id=user_id) | ||||
| if u: | if u: | ||||
| UserTenantService.delete_by_id(u[0].id) | UserTenantService.delete_by_id(u[0].id) | ||||
| except Exception as e: | |||||
| except Exception: | |||||
| pass | pass | ||||
| try: | try: | ||||
| TenantLLM.delete().where(TenantLLM.tenant_id == user_id).execute() | TenantLLM.delete().where(TenantLLM.tenant_id == user_id).execute() | ||||
| except Exception as e: | |||||
| except Exception: | |||||
| pass | pass | ||||
| if not re.match(r"^[\w\._-]+@([\w_-]+\.)+[\w-]{2,5}$", email_address): | if not re.match(r"^[\w\._-]+@([\w_-]+\.)+[\w-]{2,5}$", email_address): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retmsg=f"Invalid email address: {email_address}!", | |||||
| retcode=RetCode.OPERATING_ERROR, | |||||
| message=f"Invalid email address: {email_address}!", | |||||
| code=RetCode.OPERATING_ERROR, | |||||
| ) | ) | ||||
| # Check if the email address is already used | # Check if the email address is already used | ||||
| if UserService.query(email=email_address): | if UserService.query(email=email_address): | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retmsg=f"Email: {email_address} has already registered!", | |||||
| retcode=RetCode.OPERATING_ERROR, | |||||
| message=f"Email: {email_address} has already registered!", | |||||
| code=RetCode.OPERATING_ERROR, | |||||
| ) | ) | ||||
| # Construct user info data | # Construct user info data | ||||
| return construct_response( | return construct_response( | ||||
| data=user.to_json(), | data=user.to_json(), | ||||
| auth=user.get_id(), | auth=user.get_id(), | ||||
| retmsg=f"{nickname}, welcome aboard!", | |||||
| message=f"{nickname}, welcome aboard!", | |||||
| ) | ) | ||||
| except Exception as e: | except Exception as e: | ||||
| rollback_user_registration(user_id) | rollback_user_registration(user_id) | ||||
| stat_logger.exception(e) | stat_logger.exception(e) | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, | data=False, | ||||
| retmsg=f"User registration failure, error: {str(e)}", | |||||
| retcode=RetCode.EXCEPTION_ERROR, | |||||
| message=f"User registration failure, error: {str(e)}", | |||||
| code=RetCode.EXCEPTION_ERROR, | |||||
| ) | ) | ||||
| try: | try: | ||||
| tenants = TenantService.get_info_by(current_user.id) | tenants = TenantService.get_info_by(current_user.id) | ||||
| if not tenants: | if not tenants: | ||||
| return get_data_error_result(retmsg="Tenant not found!") | |||||
| return get_data_error_result(message="Tenant not found!") | |||||
| return get_json_result(data=tenants[0]) | return get_json_result(data=tenants[0]) | ||||
| except Exception as e: | except Exception as e: | ||||
| return server_error_response(e) | return server_error_response(e) |
| return max(0, countdown) | return max(0, countdown) | ||||
| def get_data_error_result(retcode=RetCode.DATA_ERROR, | |||||
| retmsg='Sorry! Data missing!'): | |||||
| def get_data_error_result(code=RetCode.DATA_ERROR, | |||||
| message='Sorry! Data missing!'): | |||||
| import re | import re | ||||
| result_dict = { | result_dict = { | ||||
| "retcode": retcode, | |||||
| "retmsg": re.sub( | |||||
| "code": code, | |||||
| "message": re.sub( | |||||
| r"rag", | r"rag", | ||||
| "seceum", | "seceum", | ||||
| retmsg, | |||||
| message, | |||||
| flags=re.IGNORECASE)} | flags=re.IGNORECASE)} | ||||
| response = {} | response = {} | ||||
| for key, value in result_dict.items(): | for key, value in result_dict.items(): | ||||
| if value is None and key != "retcode": | |||||
| if value is None and key != "code": | |||||
| continue | continue | ||||
| else: | else: | ||||
| response[key] = value | response[key] = value | ||||
| stat_logger.exception(e) | stat_logger.exception(e) | ||||
| try: | try: | ||||
| if e.code == 401: | if e.code == 401: | ||||
| return get_json_result(retcode=401, retmsg=repr(e)) | |||||
| return get_json_result(code=401, message=repr(e)) | |||||
| except BaseException: | except BaseException: | ||||
| pass | pass | ||||
| if len(e.args) > 1: | if len(e.args) > 1: | ||||
| return get_json_result( | return get_json_result( | ||||
| retcode=RetCode.EXCEPTION_ERROR, retmsg=repr(e.args[0]), data=e.args[1]) | |||||
| code=RetCode.EXCEPTION_ERROR, message=repr(e.args[0]), data=e.args[1]) | |||||
| if repr(e).find("index_not_found_exception") >= 0: | if repr(e).find("index_not_found_exception") >= 0: | ||||
| return get_json_result(retcode=RetCode.EXCEPTION_ERROR, | |||||
| retmsg="No chunk found, please upload file and parse it.") | |||||
| return get_json_result(code=RetCode.EXCEPTION_ERROR, | |||||
| message="No chunk found, please upload file and parse it.") | |||||
| return get_json_result(retcode=RetCode.EXCEPTION_ERROR, retmsg=repr(e)) | |||||
| return get_json_result(code=RetCode.EXCEPTION_ERROR, message=repr(e)) | |||||
| def error_response(response_code, retmsg=None): | |||||
| if retmsg is None: | |||||
| retmsg = HTTP_STATUS_CODES.get(response_code, 'Unknown Error') | |||||
| def error_response(response_code, message=None): | |||||
| if message is None: | |||||
| message = HTTP_STATUS_CODES.get(response_code, 'Unknown Error') | |||||
| return Response(json.dumps({ | return Response(json.dumps({ | ||||
| 'retmsg': retmsg, | |||||
| 'retcode': response_code, | |||||
| 'message': message, | |||||
| 'code': response_code, | |||||
| }), status=response_code, mimetype='application/json') | }), status=response_code, mimetype='application/json') | ||||
| error_string += "required argument values: {}".format( | error_string += "required argument values: {}".format( | ||||
| ",".join(["{}={}".format(a[0], a[1]) for a in error_arguments])) | ",".join(["{}={}".format(a[0], a[1]) for a in error_arguments])) | ||||
| return get_json_result( | return get_json_result( | ||||
| retcode=RetCode.ARGUMENT_ERROR, retmsg=error_string) | |||||
| code=RetCode.ARGUMENT_ERROR, message=error_string) | |||||
| return func(*_args, **_kwargs) | return func(*_args, **_kwargs) | ||||
| return decorated_function | return decorated_function | ||||
| return send_file(f, as_attachment=True, attachment_filename=filename) | return send_file(f, as_attachment=True, attachment_filename=filename) | ||||
| def get_json_result(retcode=RetCode.SUCCESS, retmsg='success', data=None): | |||||
| response = {"retcode": retcode, "retmsg": retmsg, "data": data} | |||||
| def get_json_result(code=RetCode.SUCCESS, message='success', data=None): | |||||
| response = {"code": code, "message": message, "data": data} | |||||
| return jsonify(response) | return jsonify(response) | ||||
| def apikey_required(func): | def apikey_required(func): | ||||
| objs = APIToken.query(token=token) | objs = APIToken.query(token=token) | ||||
| if not objs: | if not objs: | ||||
| return build_error_result( | return build_error_result( | ||||
| error_msg='API-KEY is invalid!', retcode=RetCode.FORBIDDEN | |||||
| message='API-KEY is invalid!', code=RetCode.FORBIDDEN | |||||
| ) | ) | ||||
| kwargs['tenant_id'] = objs[0].tenant_id | kwargs['tenant_id'] = objs[0].tenant_id | ||||
| return func(*args, **kwargs) | return func(*args, **kwargs) | ||||
| return decorated_function | return decorated_function | ||||
| def build_error_result(retcode=RetCode.FORBIDDEN, error_msg='success'): | |||||
| response = {"error_code": retcode, "error_msg": error_msg} | |||||
| def build_error_result(code=RetCode.FORBIDDEN, message='success'): | |||||
| response = {"code": code, "message": message} | |||||
| response = jsonify(response) | response = jsonify(response) | ||||
| response.status_code = retcode | |||||
| response.status_code = code | |||||
| return response | return response | ||||
| def construct_response(retcode=RetCode.SUCCESS, | |||||
| retmsg='success', data=None, auth=None): | |||||
| result_dict = {"retcode": retcode, "retmsg": retmsg, "data": data} | |||||
| def construct_response(code=RetCode.SUCCESS, | |||||
| message='success', data=None, auth=None): | |||||
| result_dict = {"code": code, "message": message, "data": data} | |||||
| response_dict = {} | response_dict = {} | ||||
| for key, value in result_dict.items(): | for key, value in result_dict.items(): | ||||
| if value is None and key != "retcode": | |||||
| if value is None and key != "code": | |||||
| continue | continue | ||||
| else: | else: | ||||
| response_dict[key] = value | response_dict[key] = value | ||||
| objs = APIToken.query(token=token) | objs = APIToken.query(token=token) | ||||
| if not objs: | if not objs: | ||||
| return get_json_result( | return get_json_result( | ||||
| data=False, retmsg='Token is not valid!', retcode=RetCode.AUTHENTICATION_ERROR | |||||
| data=False, message='Token is not valid!', code=RetCode.AUTHENTICATION_ERROR | |||||
| ) | ) | ||||
| kwargs['tenant_id'] = objs[0].tenant_id | kwargs['tenant_id'] = objs[0].tenant_id | ||||
| return func(*args, **kwargs) | return func(*args, **kwargs) | ||||
| return decorated_function | return decorated_function | ||||
| def get_result(retcode=RetCode.SUCCESS, retmsg='error', data=None): | |||||
| if retcode == 0: | |||||
| def get_result(code=RetCode.SUCCESS, message='error', data=None): | |||||
| if code == 0: | |||||
| if data is not None: | if data is not None: | ||||
| response = {"code": retcode, "data": data} | |||||
| response = {"code": code, "data": data} | |||||
| else: | else: | ||||
| response = {"code": retcode} | |||||
| response = {"code": code} | |||||
| else: | else: | ||||
| response = {"code": retcode, "message": retmsg} | |||||
| response = {"code": code, "message": message} | |||||
| return jsonify(response) | return jsonify(response) | ||||
| def get_error_data_result(retmsg='Sorry! Data missing!', retcode=RetCode.DATA_ERROR, | |||||
| def get_error_data_result(message='Sorry! Data missing!', code=RetCode.DATA_ERROR, | |||||
| ): | ): | ||||
| import re | import re | ||||
| result_dict = { | result_dict = { | ||||
| "code": retcode, | |||||
| "code": code, | |||||
| "message": re.sub( | "message": re.sub( | ||||
| r"rag", | r"rag", | ||||
| "seceum", | "seceum", | ||||
| retmsg, | |||||
| message, | |||||
| flags=re.IGNORECASE)} | flags=re.IGNORECASE)} | ||||
| response = {} | response = {} | ||||
| for key, value in result_dict.items(): | for key, value in result_dict.items(): |
| 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. | 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. | ||||
| #### 4.10 `{"data":null,"retcode":100,"retmsg":"<NotFound '404: Not Found'>"}` | |||||
| #### 4.10 `{"data":null,"code":100,"message":"<NotFound '404: Not Found'>"}` | |||||
| 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. | 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. | ||||
| import requests | import requests | ||||
| import json | |||||
| from bridge.context import Context, ContextType # Import Context, ContextType | |||||
| from bridge.context import ContextType # Import Context, ContextType | |||||
| from bridge.reply import Reply, ReplyType # Import Reply, ReplyType | from bridge.reply import Reply, ReplyType # Import Reply, ReplyType | ||||
| from bridge import * | from bridge import * | ||||
| from common.log import logger | from common.log import logger | ||||
| from config import conf | |||||
| from plugins import Plugin, register # Import Plugin and register | from plugins import Plugin, register # Import Plugin and register | ||||
| from plugins.event import Event, EventContext, EventAction # Import event-related classes | from plugins.event import Event, EventContext, EventAction # Import event-related classes | ||||
| logger.debug(f"[RAGFlowChat] New conversation response: {response.text}") | logger.debug(f"[RAGFlowChat] New conversation response: {response.text}") | ||||
| if response.status_code == 200: | if response.status_code == 200: | ||||
| data = response.json() | data = response.json() | ||||
| if data.get("retcode") == 0: | |||||
| if data.get("code") == 0: | |||||
| conversation_id = data["data"]["id"] | conversation_id = data["data"]["id"] | ||||
| self.conversations[user_id] = conversation_id | self.conversations[user_id] = conversation_id | ||||
| else: | else: | ||||
| logger.error(f"[RAGFlowChat] Failed to create conversation: {data.get('retmsg')}") | |||||
| return f"Sorry, unable to create a conversation: {data.get('retmsg')}" | |||||
| logger.error(f"[RAGFlowChat] Failed to create conversation: {data.get('message')}") | |||||
| return f"Sorry, unable to create a conversation: {data.get('message')}" | |||||
| else: | else: | ||||
| logger.error(f"[RAGFlowChat] HTTP error when creating conversation: {response.status_code}") | logger.error(f"[RAGFlowChat] HTTP error when creating conversation: {response.status_code}") | ||||
| return f"Sorry, unable to connect to RAGFlow API (create conversation). HTTP status code: {response.status_code}" | return f"Sorry, unable to connect to RAGFlow API (create conversation). HTTP status code: {response.status_code}" | ||||
| logger.debug(f"[RAGFlowChat] Completion response: {response.text}") | logger.debug(f"[RAGFlowChat] Completion response: {response.text}") | ||||
| if response.status_code == 200: | if response.status_code == 200: | ||||
| data = response.json() | data = response.json() | ||||
| if data.get("retcode") == 0: | |||||
| if data.get("code") == 0: | |||||
| answer = data["data"]["answer"] | answer = data["data"]["answer"] | ||||
| return answer | return answer | ||||
| else: | else: | ||||
| logger.error(f"[RAGFlowChat] Failed to get answer: {data.get('retmsg')}") | |||||
| return f"Sorry, unable to get a reply: {data.get('retmsg')}" | |||||
| logger.error(f"[RAGFlowChat] Failed to get answer: {data.get('message')}") | |||||
| return f"Sorry, unable to get a reply: {data.get('message')}" | |||||
| else: | else: | ||||
| logger.error(f"[RAGFlowChat] HTTP error when getting answer: {response.status_code}") | logger.error(f"[RAGFlowChat] HTTP error when getting answer: {response.status_code}") | ||||
| return f"Sorry, unable to connect to RAGFlow API (get reply). HTTP status code: {response.status_code}" | return f"Sorry, unable to connect to RAGFlow API (get reply). HTTP status code: {response.status_code}" |
| register_data = {"email":EMAIL,"nickname":name,"password":PASSWORD} | register_data = {"email":EMAIL,"nickname":name,"password":PASSWORD} | ||||
| res = requests.post(url=url,json=register_data) | res = requests.post(url=url,json=register_data) | ||||
| res = res.json() | res = res.json() | ||||
| if res.get("retcode") != 0: | |||||
| raise Exception(res.get("retmsg")) | |||||
| if res.get("code") != 0: | |||||
| raise Exception(res.get("message")) | |||||
| def login(): | def login(): | ||||
| url = HOST_ADDRESS + "/v1/user/login" | url = HOST_ADDRESS + "/v1/user/login" | ||||
| login_data = {"email":EMAIL,"password":PASSWORD} | login_data = {"email":EMAIL,"password":PASSWORD} | ||||
| response=requests.post(url=url,json=login_data) | response=requests.post(url=url,json=login_data) | ||||
| res = response.json() | res = response.json() | ||||
| if res.get("retcode")!=0: | |||||
| raise Exception(res.get("retmsg")) | |||||
| if res.get("code")!=0: | |||||
| raise Exception(res.get("message")) | |||||
| auth = response.headers["Authorization"] | auth = response.headers["Authorization"] | ||||
| return auth | return auth | ||||
| auth = {"Authorization": auth} | auth = {"Authorization": auth} | ||||
| response = requests.post(url=url,headers=auth) | response = requests.post(url=url,headers=auth) | ||||
| res = response.json() | res = response.json() | ||||
| if res.get("retcode") != 0: | |||||
| raise Exception(res.get("retmsg")) | |||||
| if res.get("code") != 0: | |||||
| raise Exception(res.get("message")) | |||||
| return res["data"].get("token") | return res["data"].get("token") | ||||
| {"data":null,"retcode":100,"retmsg":"TypeError(\"download_document() got an unexpected keyword argument 'tenant_id'\")"} | |||||
| {"data":null,"code":100,"message":"TypeError(\"download_document() got an unexpected keyword argument 'tenant_id'\")"} |
| }; | }; | ||||
| const isUploadSuccess = (file: UploadFile) => { | const isUploadSuccess = (file: UploadFile) => { | ||||
| const retcode = get(file, 'response.retcode'); | |||||
| return typeof retcode === 'number' && retcode === 0; | |||||
| const code = get(file, 'response.code'); | |||||
| return typeof code === 'number' && code === 0; | |||||
| }; | }; | ||||
| interface IProps { | interface IProps { | ||||
| const creatingRet = await createConversationBeforeUploadDocument( | const creatingRet = await createConversationBeforeUploadDocument( | ||||
| file.name, | file.name, | ||||
| ); | ); | ||||
| if (creatingRet?.retcode === 0) { | |||||
| if (creatingRet?.code === 0) { | |||||
| nextConversationId = creatingRet.data.id; | nextConversationId = creatingRet.data.id; | ||||
| } | } | ||||
| } | } | ||||
| originFileObj: file as any, | originFileObj: file as any, | ||||
| response: ret, | response: ret, | ||||
| percent: 100, | percent: 100, | ||||
| status: ret?.retcode === 0 ? 'done' : 'error', | |||||
| status: ret?.code === 0 ? 'done' : 'error', | |||||
| }); | }); | ||||
| return nextList; | return nextList; | ||||
| }); | }); |
| const onRemoveMessage = useCallback(async () => { | const onRemoveMessage = useCallback(async () => { | ||||
| const pureId = getMessagePureId(messageId); | const pureId = getMessagePureId(messageId); | ||||
| if (pureId) { | if (pureId) { | ||||
| const retcode = await deleteMessage(pureId); | |||||
| if (retcode === 0) { | |||||
| const code = await deleteMessage(pureId); | |||||
| if (code === 0) { | |||||
| removeMessageById?.(messageId); | removeMessageById?.(messageId); | ||||
| } | } | ||||
| } | } |
| const fetchDocument = useCallback(async () => { | const fetchDocument = useCallback(async () => { | ||||
| const { data } = await axios.get(url); | const { data } = await axios.get(url); | ||||
| if (data.retcode !== 0) { | |||||
| setError(data?.retmsg); | |||||
| if (data.code !== 0) { | |||||
| setError(data?.message); | |||||
| } | } | ||||
| }, [url]); | }, [url]); | ||||
| useEffect(() => { | useEffect(() => { |
| console.log('🚀 ~ queryFn: ~ params:', params); | console.log('🚀 ~ queryFn: ~ params:', params); | ||||
| const { data } = await chatService.listDialog(); | const { data } = await chatService.listDialog(); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| const list: IDialog[] = data.data; | const list: IDialog[] = data.data; | ||||
| if (list.length > 0) { | if (list.length > 0) { | ||||
| if (list.every((x) => x.id !== dialogId)) { | if (list.every((x) => x.id !== dialogId)) { | ||||
| mutationKey: ['setDialog'], | mutationKey: ['setDialog'], | ||||
| mutationFn: async (params: IDialog) => { | mutationFn: async (params: IDialog) => { | ||||
| const { data } = await chatService.setDialog(params); | const { data } = await chatService.setDialog(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| queryClient.invalidateQueries({ | queryClient.invalidateQueries({ | ||||
| exact: false, | exact: false, | ||||
| queryKey: ['fetchDialogList'], | queryKey: ['fetchDialogList'], | ||||
| i18n.t(`message.${params.dialog_id ? 'modified' : 'created'}`), | i18n.t(`message.${params.dialog_id ? 'modified' : 'created'}`), | ||||
| ); | ); | ||||
| } | } | ||||
| return data?.retcode; | |||||
| return data?.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| mutationKey: ['removeDialog'], | mutationKey: ['removeDialog'], | ||||
| mutationFn: async (dialogIds: string[]) => { | mutationFn: async (dialogIds: string[]) => { | ||||
| const { data } = await chatService.removeDialog({ dialogIds }); | const { data } = await chatService.removeDialog({ dialogIds }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| queryClient.invalidateQueries({ queryKey: ['fetchDialogList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchDialogList'] }); | ||||
| message.success(i18n.t('message.deleted')); | message.success(i18n.t('message.deleted')); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| enabled: !!dialogId, | enabled: !!dialogId, | ||||
| queryFn: async () => { | queryFn: async () => { | ||||
| const { data } = await chatService.listConversation({ dialogId }); | const { data } = await chatService.listConversation({ dialogId }); | ||||
| if (data.retcode === 0 && data.data.length > 0) { | |||||
| if (data.code === 0 && data.data.length > 0) { | |||||
| handleClickConversation(data.data[0].id, ''); | handleClickConversation(data.data[0].id, ''); | ||||
| } | } | ||||
| return data?.data; | return data?.data; | ||||
| ? params.conversation_id | ? params.conversation_id | ||||
| : getConversationId(), | : getConversationId(), | ||||
| }); | }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| queryClient.invalidateQueries({ queryKey: ['fetchConversationList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchConversationList'] }); | ||||
| } | } | ||||
| return data; | return data; | ||||
| conversationIds, | conversationIds, | ||||
| dialogId, | dialogId, | ||||
| }); | }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| queryClient.invalidateQueries({ queryKey: ['fetchConversationList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchConversationList'] }); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| conversationId, | conversationId, | ||||
| }); | }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(i18n.t(`message.deleted`)); | message.success(i18n.t(`message.deleted`)); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| ...params, | ...params, | ||||
| conversationId, | conversationId, | ||||
| }); | }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(i18n.t(`message.operated`)); | message.success(i18n.t(`message.operated`)); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| mutationKey: ['createToken'], | mutationKey: ['createToken'], | ||||
| mutationFn: async (params: Record<string, any>) => { | mutationFn: async (params: Record<string, any>) => { | ||||
| const { data } = await chatService.createToken(params); | const { data } = await chatService.createToken(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| queryClient.invalidateQueries({ queryKey: ['fetchTokenList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchTokenList'] }); | ||||
| } | } | ||||
| return data?.data ?? []; | return data?.data ?? []; | ||||
| tokens: string[]; | tokens: string[]; | ||||
| }) => { | }) => { | ||||
| const { data } = await chatService.removeToken(params); | const { data } = await chatService.removeToken(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| queryClient.invalidateQueries({ queryKey: ['fetchTokenList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchTokenList'] }); | ||||
| } | } | ||||
| return data?.data ?? []; | return data?.data ?? []; |
| available_int: available, | available_int: available, | ||||
| keywords: searchString, | keywords: searchString, | ||||
| }); | }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| const res = data.data; | const res = data.data; | ||||
| return { | return { | ||||
| data: res.chunks, | data: res.chunks, | ||||
| mutationKey: ['deleteChunk'], | mutationKey: ['deleteChunk'], | ||||
| mutationFn: async (params: { chunkIds: string[]; doc_id: string }) => { | mutationFn: async (params: { chunkIds: string[]; doc_id: string }) => { | ||||
| const { data } = await kbService.rm_chunk(params); | const { data } = await kbService.rm_chunk(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| setPaginationParams(1); | setPaginationParams(1); | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchChunkList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchChunkList'] }); | ||||
| } | } | ||||
| return data?.retcode; | |||||
| return data?.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| doc_id: string; | doc_id: string; | ||||
| }) => { | }) => { | ||||
| const { data } = await kbService.switch_chunk(params); | const { data } = await kbService.switch_chunk(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(t('message.modified')); | message.success(t('message.modified')); | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchChunkList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchChunkList'] }); | ||||
| } | } | ||||
| return data?.retcode; | |||||
| return data?.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| service = kbService.set_chunk; | service = kbService.set_chunk; | ||||
| } | } | ||||
| const { data } = await service(payload); | const { data } = await service(payload); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(t('message.created')); | message.success(t('message.created')); | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchChunkList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchChunkList'] }); | ||||
| } | } | ||||
| return data?.retcode; | |||||
| return data?.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| page_size: pagination.pageSize, | page_size: pagination.pageSize, | ||||
| page: pagination.current, | page: pagination.current, | ||||
| }); | }); | ||||
| if (ret.data.retcode === 0) { | |||||
| if (ret.data.code === 0) { | |||||
| return ret.data.data; | return ret.data.data; | ||||
| } | } | ||||
| doc_id: documentId, | doc_id: documentId, | ||||
| status: Number(status), | status: Number(status), | ||||
| }); | }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(i18n.t('message.modified')); | message.success(i18n.t('message.modified')); | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] }); | ||||
| } | } | ||||
| doc_id: documentId, | doc_id: documentId, | ||||
| name: name, | name: name, | ||||
| }); | }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(i18n.t('message.renamed')); | message.success(i18n.t('message.renamed')); | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] }); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| name, | name, | ||||
| kb_id: knowledgeId, | kb_id: knowledgeId, | ||||
| }); | }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| if (page === 1) { | if (page === 1) { | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] }); | ||||
| } else { | } else { | ||||
| message.success(i18n.t('message.created')); | message.success(i18n.t('message.created')); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| doc_id: documentId, | doc_id: documentId, | ||||
| parser_config: parserConfig, | parser_config: parserConfig, | ||||
| }); | }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] }); | ||||
| message.success(i18n.t('message.modified')); | message.success(i18n.t('message.modified')); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| try { | try { | ||||
| const ret = await kbService.document_upload(formData); | const ret = await kbService.document_upload(formData); | ||||
| const retcode = get(ret, 'data.retcode'); | |||||
| if (retcode === 0) { | |||||
| const code = get(ret, 'data.code'); | |||||
| if (code === 0) { | |||||
| message.success(i18n.t('message.uploaded')); | message.success(i18n.t('message.uploaded')); | ||||
| } | } | ||||
| if (retcode === 0 || retcode === 500) { | |||||
| if (code === 0 || code === 500) { | |||||
| queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] }); | ||||
| } | } | ||||
| return ret?.data; | return ret?.data; | ||||
| formData.append('kb_id', knowledgeId); | formData.append('kb_id', knowledgeId); | ||||
| const ret = await kbService.web_crawl(formData); | const ret = await kbService.web_crawl(formData); | ||||
| const retcode = get(ret, 'data.retcode'); | |||||
| if (retcode === 0) { | |||||
| const code = get(ret, 'data.code'); | |||||
| if (code === 0) { | |||||
| message.success(i18n.t('message.uploaded')); | message.success(i18n.t('message.uploaded')); | ||||
| } | } | ||||
| return retcode; | |||||
| return code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| doc_ids: documentIds, | doc_ids: documentIds, | ||||
| run, | run, | ||||
| }); | }); | ||||
| const retcode = get(ret, 'data.retcode'); | |||||
| if (retcode === 0) { | |||||
| const code = get(ret, 'data.code'); | |||||
| if (code === 0) { | |||||
| queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] }); | ||||
| message.success(i18n.t('message.operated')); | message.success(i18n.t('message.operated')); | ||||
| } | } | ||||
| return retcode; | |||||
| return code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| initialData: [], | initialData: [], | ||||
| queryFn: async () => { | queryFn: async () => { | ||||
| const { data } = await kbService.document_infos({ doc_ids: ids }); | const { data } = await kbService.document_infos({ doc_ids: ids }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| return data.data; | return data.data; | ||||
| } | } | ||||
| initialData: {}, | initialData: {}, | ||||
| queryFn: async () => { | queryFn: async () => { | ||||
| const { data } = await kbService.document_thumbnails({ doc_ids: ids }); | const { data } = await kbService.document_thumbnails({ doc_ids: ids }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| return data.data; | return data.data; | ||||
| } | } | ||||
| return {}; | return {}; | ||||
| mutationKey: ['removeDocument'], | mutationKey: ['removeDocument'], | ||||
| mutationFn: async (documentIds: string | string[]) => { | mutationFn: async (documentIds: string | string[]) => { | ||||
| const { data } = await kbService.document_rm({ doc_id: documentIds }); | const { data } = await kbService.document_rm({ doc_id: documentIds }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(i18n.t('message.deleted')); | message.success(i18n.t('message.deleted')); | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchDocumentList'] }); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| mutationKey: ['deleteDocument'], | mutationKey: ['deleteDocument'], | ||||
| mutationFn: async (documentIds: string[]) => { | mutationFn: async (documentIds: string[]) => { | ||||
| const data = await kbService.document_delete({ doc_ids: documentIds }); | const data = await kbService.document_delete({ doc_ids: documentIds }); | ||||
| // if (data.retcode === 0) { | |||||
| // if (data.code === 0) { | |||||
| // queryClient.invalidateQueries({ queryKey: ['fetchFlowList'] }); | // queryClient.invalidateQueries({ queryKey: ['fetchFlowList'] }); | ||||
| // } | // } | ||||
| return data; | return data; |
| mutationKey: ['deleteFile'], | mutationKey: ['deleteFile'], | ||||
| mutationFn: async (params: { fileIds: string[]; parentId: string }) => { | mutationFn: async (params: { fileIds: string[]; parentId: string }) => { | ||||
| const { data } = await fileManagerService.removeFile(params); | const { data } = await fileManagerService.removeFile(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| setPaginationParams(1); // TODO: There should be a better way to paginate the request list | setPaginationParams(1); // TODO: There should be a better way to paginate the request list | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchFileList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchFileList'] }); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| mutationKey: ['renameFile'], | mutationKey: ['renameFile'], | ||||
| mutationFn: async (params: { fileId: string; name: string }) => { | mutationFn: async (params: { fileId: string; name: string }) => { | ||||
| const { data } = await fileManagerService.renameFile(params); | const { data } = await fileManagerService.renameFile(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(t('message.renamed')); | message.success(t('message.renamed')); | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchFileList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchFileList'] }); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| ...params, | ...params, | ||||
| type: 'folder', | type: 'folder', | ||||
| }); | }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(t('message.created')); | message.success(t('message.created')); | ||||
| setPaginationParams(1); | setPaginationParams(1); | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchFileList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchFileList'] }); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| }); | }); | ||||
| try { | try { | ||||
| const ret = await fileManagerService.uploadFile(formData); | const ret = await fileManagerService.uploadFile(formData); | ||||
| if (ret?.data.retcode === 0) { | |||||
| if (ret?.data.code === 0) { | |||||
| message.success(t('message.uploaded')); | message.success(t('message.uploaded')); | ||||
| setPaginationParams(1); | setPaginationParams(1); | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchFileList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchFileList'] }); | ||||
| } | } | ||||
| return ret?.data?.retcode; | |||||
| return ret?.data?.code; | |||||
| } catch (error) { | } catch (error) { | ||||
| console.log('🚀 ~ useUploadFile ~ error:', error); | console.log('🚀 ~ useUploadFile ~ error:', error); | ||||
| } | } | ||||
| mutationKey: ['connectFileToKnowledge'], | mutationKey: ['connectFileToKnowledge'], | ||||
| mutationFn: async (params: IConnectRequestBody) => { | mutationFn: async (params: IConnectRequestBody) => { | ||||
| const { data } = await fileManagerService.connectFileToKnowledge(params); | const { data } = await fileManagerService.connectFileToKnowledge(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(t('message.operated')); | message.success(t('message.operated')); | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchFileList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchFileList'] }); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| mutationKey: ['moveFile'], | mutationKey: ['moveFile'], | ||||
| mutationFn: async (params: IMoveFileBody) => { | mutationFn: async (params: IMoveFileBody) => { | ||||
| const { data } = await fileManagerService.moveFile(params); | const { data } = await fileManagerService.moveFile(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(t('message.operated')); | message.success(t('message.operated')); | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchFileList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchFileList'] }); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| avatar?: string; | avatar?: string; | ||||
| }) => { | }) => { | ||||
| const { data = {} } = await flowService.setCanvas(params); | const { data = {} } = await flowService.setCanvas(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success( | message.success( | ||||
| i18n.t(`message.${params?.id ? 'modified' : 'created'}`), | i18n.t(`message.${params?.id ? 'modified' : 'created'}`), | ||||
| ); | ); | ||||
| mutationKey: ['deleteFlow'], | mutationKey: ['deleteFlow'], | ||||
| mutationFn: async (canvasIds: string[]) => { | mutationFn: async (canvasIds: string[]) => { | ||||
| const { data } = await flowService.removeCanvas({ canvasIds }); | const { data } = await flowService.removeCanvas({ canvasIds }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| queryClient.invalidateQueries({ queryKey: ['fetchFlowList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchFlowList'] }); | ||||
| } | } | ||||
| return data?.data ?? []; | return data?.data ?? []; | ||||
| mutationKey: ['runFlow'], | mutationKey: ['runFlow'], | ||||
| mutationFn: async (params: { id: string; dsl: DSL }) => { | mutationFn: async (params: { id: string; dsl: DSL }) => { | ||||
| const { data } = await flowService.runCanvas(params); | const { data } = await flowService.runCanvas(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(i18n.t(`message.modified`)); | message.success(i18n.t(`message.modified`)); | ||||
| } | } | ||||
| return data?.data ?? {}; | return data?.data ?? {}; | ||||
| mutationKey: ['testDbConnect'], | mutationKey: ['testDbConnect'], | ||||
| mutationFn: async (params: any) => { | mutationFn: async (params: any) => { | ||||
| const ret = await flowService.testDbConnect(params); | const ret = await flowService.testDbConnect(params); | ||||
| if (ret?.data?.retcode === 0) { | |||||
| if (ret?.data?.code === 0) { | |||||
| message.success(ret?.data?.data); | message.success(ret?.data?.data); | ||||
| } else { | } else { | ||||
| message.error(ret?.data?.data); | message.error(ret?.data?.data); |
| mutationKey: ['createKnowledge'], | mutationKey: ['createKnowledge'], | ||||
| mutationFn: async (params: { id?: string; name: string }) => { | mutationFn: async (params: { id?: string; name: string }) => { | ||||
| const { data = {} } = await kbService.createKb(params); | const { data = {} } = await kbService.createKb(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success( | message.success( | ||||
| i18n.t(`message.${params?.id ? 'modified' : 'created'}`), | i18n.t(`message.${params?.id ? 'modified' : 'created'}`), | ||||
| ); | ); | ||||
| mutationKey: ['deleteKnowledge'], | mutationKey: ['deleteKnowledge'], | ||||
| mutationFn: async (id: string) => { | mutationFn: async (id: string) => { | ||||
| const { data } = await kbService.rmKb({ kb_id: id }); | const { data } = await kbService.rmKb({ kb_id: id }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(i18n.t(`message.deleted`)); | message.success(i18n.t(`message.deleted`)); | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchKnowledgeList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchKnowledgeList'] }); | ||||
| } | } | ||||
| kb_id: knowledgeBaseId, | kb_id: knowledgeBaseId, | ||||
| ...params, | ...params, | ||||
| }); | }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(i18n.t(`message.updated`)); | message.success(i18n.t(`message.updated`)); | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchKnowledgeDetail'] }); | queryClient.invalidateQueries({ queryKey: ['fetchKnowledgeDetail'] }); | ||||
| } | } | ||||
| page, | page, | ||||
| size: pageSize, | size: pageSize, | ||||
| }); | }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| const res = data.data; | const res = data.data; | ||||
| return { | return { | ||||
| chunks: res.chunks, | chunks: res.chunks, |
| mutationKey: ['saveApiKey'], | mutationKey: ['saveApiKey'], | ||||
| mutationFn: async (params: IApiKeySavingParams) => { | mutationFn: async (params: IApiKeySavingParams) => { | ||||
| const { data } = await userService.set_api_key(params); | const { data } = await userService.set_api_key(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(t('message.modified')); | message.success(t('message.modified')); | ||||
| queryClient.invalidateQueries({ queryKey: ['myLlmList'] }); | queryClient.invalidateQueries({ queryKey: ['myLlmList'] }); | ||||
| queryClient.invalidateQueries({ queryKey: ['factoryList'] }); | queryClient.invalidateQueries({ queryKey: ['factoryList'] }); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| mutationKey: ['saveTenantInfo'], | mutationKey: ['saveTenantInfo'], | ||||
| mutationFn: async (params: ISystemModelSettingSavingParams) => { | mutationFn: async (params: ISystemModelSettingSavingParams) => { | ||||
| const { data } = await userService.set_tenant_info(params); | const { data } = await userService.set_tenant_info(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(t('message.modified')); | message.success(t('message.modified')); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| mutationKey: ['addLlm'], | mutationKey: ['addLlm'], | ||||
| mutationFn: async (params: IAddLlmRequestBody) => { | mutationFn: async (params: IAddLlmRequestBody) => { | ||||
| const { data } = await userService.add_llm(params); | const { data } = await userService.add_llm(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| queryClient.invalidateQueries({ queryKey: ['myLlmList'] }); | queryClient.invalidateQueries({ queryKey: ['myLlmList'] }); | ||||
| queryClient.invalidateQueries({ queryKey: ['factoryList'] }); | queryClient.invalidateQueries({ queryKey: ['factoryList'] }); | ||||
| message.success(t('message.modified')); | message.success(t('message.modified')); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| mutationKey: ['deleteLlm'], | mutationKey: ['deleteLlm'], | ||||
| mutationFn: async (params: IDeleteLlmRequestBody) => { | mutationFn: async (params: IDeleteLlmRequestBody) => { | ||||
| const { data } = await userService.delete_llm(params); | const { data } = await userService.delete_llm(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| queryClient.invalidateQueries({ queryKey: ['myLlmList'] }); | queryClient.invalidateQueries({ queryKey: ['myLlmList'] }); | ||||
| queryClient.invalidateQueries({ queryKey: ['factoryList'] }); | queryClient.invalidateQueries({ queryKey: ['factoryList'] }); | ||||
| message.success(t('message.deleted')); | message.success(t('message.deleted')); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| mutationKey: ['deleteFactory'], | mutationKey: ['deleteFactory'], | ||||
| mutationFn: async (params: IDeleteLlmRequestBody) => { | mutationFn: async (params: IDeleteLlmRequestBody) => { | ||||
| const { data } = await userService.deleteFactory(params); | const { data } = await userService.deleteFactory(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| queryClient.invalidateQueries({ queryKey: ['myLlmList'] }); | queryClient.invalidateQueries({ queryKey: ['myLlmList'] }); | ||||
| queryClient.invalidateQueries({ queryKey: ['factoryList'] }); | queryClient.invalidateQueries({ queryKey: ['factoryList'] }); | ||||
| message.success(t('message.deleted')); | message.success(t('message.deleted')); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| }); | }); | ||||
| try { | try { | ||||
| const res = await response.clone().json(); | const res = await response.clone().json(); | ||||
| if (res?.retcode !== 0) { | |||||
| message.error(res?.retmsg); | |||||
| if (res?.code !== 0) { | |||||
| message.error(res?.message); | |||||
| } | } | ||||
| } catch (error) { | } catch (error) { | ||||
| console.warn('🚀 ~ error:', error); | console.warn('🚀 ~ error:', error); |
| mutationKey: ['login'], | mutationKey: ['login'], | ||||
| mutationFn: async (params: { email: string; password: string }) => { | mutationFn: async (params: { email: string; password: string }) => { | ||||
| const { data: res = {}, response } = await userService.login(params); | const { data: res = {}, response } = await userService.login(params); | ||||
| if (res.retcode === 0) { | |||||
| if (res.code === 0) { | |||||
| const { data } = res; | const { data } = res; | ||||
| message.success(t('message.logged')); | message.success(t('message.logged')); | ||||
| const authorization = response.headers.get(Authorization); | const authorization = response.headers.get(Authorization); | ||||
| Token: token, | Token: token, | ||||
| }); | }); | ||||
| } | } | ||||
| return res.retcode; | |||||
| return res.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| nickname: string; | nickname: string; | ||||
| }) => { | }) => { | ||||
| const { data = {} } = await userService.register(params); | const { data = {} } = await userService.register(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(t('message.registered')); | message.success(t('message.registered')); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| mutationKey: ['logout'], | mutationKey: ['logout'], | ||||
| mutationFn: async () => { | mutationFn: async () => { | ||||
| const { data = {} } = await userService.logout(); | const { data = {} } = await userService.logout(); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(t('message.logout')); | message.success(t('message.logout')); | ||||
| authorizationUtil.removeAll(); | authorizationUtil.removeAll(); | ||||
| history.push('/login'); | history.push('/login'); | ||||
| } | } | ||||
| return data.retcode; | |||||
| return data.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| gcTime: 0, | gcTime: 0, | ||||
| queryFn: async () => { | queryFn: async () => { | ||||
| const { data } = await userService.user_info(); | const { data } = await userService.user_info(); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| i18n.changeLanguage( | i18n.changeLanguage( | ||||
| LanguageTranslationMap[ | LanguageTranslationMap[ | ||||
| data.data.language as keyof typeof LanguageTranslationMap | data.data.language as keyof typeof LanguageTranslationMap | ||||
| gcTime: 0, | gcTime: 0, | ||||
| queryFn: async () => { | queryFn: async () => { | ||||
| const { data: res } = await userService.get_tenant_info(); | const { data: res } = await userService.get_tenant_info(); | ||||
| if (res.retcode === 0) { | |||||
| if (res.code === 0) { | |||||
| // llm_id is chat_id | // llm_id is chat_id | ||||
| // asr_id is speech2txt | // asr_id is speech2txt | ||||
| const { data } = res; | const { data } = res; | ||||
| userInfo: { new_password: string } | Partial<IUserInfo>, | userInfo: { new_password: string } | Partial<IUserInfo>, | ||||
| ) => { | ) => { | ||||
| const { data } = await userService.setting(userInfo); | const { data } = await userService.setting(userInfo); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(t('message.modified')); | message.success(t('message.modified')); | ||||
| queryClient.invalidateQueries({ queryKey: ['userInfo'] }); | queryClient.invalidateQueries({ queryKey: ['userInfo'] }); | ||||
| } | } | ||||
| return data?.retcode; | |||||
| return data?.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| try { | try { | ||||
| setLoading(true); | setLoading(true); | ||||
| const { data } = await userService.getSystemVersion(); | const { data } = await userService.getSystemVersion(); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| setVersion(data.data); | setVersion(data.data); | ||||
| setLoading(false); | setLoading(false); | ||||
| } | } | ||||
| const fetchSystemStatus = useCallback(async () => { | const fetchSystemStatus = useCallback(async () => { | ||||
| setLoading(true); | setLoading(true); | ||||
| const { data } = await userService.getSystemStatus(); | const { data } = await userService.getSystemStatus(); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| setSystemStatus(data.data); | setSystemStatus(data.data); | ||||
| setLoading(false); | setLoading(false); | ||||
| } | } | ||||
| mutationKey: ['removeSystemToken'], | mutationKey: ['removeSystemToken'], | ||||
| mutationFn: async (token: string) => { | mutationFn: async (token: string) => { | ||||
| const { data } = await userService.removeToken({}, token); | const { data } = await userService.removeToken({}, token); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(t('message.deleted')); | message.success(t('message.deleted')); | ||||
| queryClient.invalidateQueries({ queryKey: ['fetchSystemTokenList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchSystemTokenList'] }); | ||||
| } | } | ||||
| mutationKey: ['createSystemToken'], | mutationKey: ['createSystemToken'], | ||||
| mutationFn: async (params: Record<string, any>) => { | mutationFn: async (params: Record<string, any>) => { | ||||
| const { data } = await userService.createToken(params); | const { data } = await userService.createToken(params); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| queryClient.invalidateQueries({ queryKey: ['fetchSystemTokenList'] }); | queryClient.invalidateQueries({ queryKey: ['fetchSystemTokenList'] }); | ||||
| } | } | ||||
| return data?.data ?? []; | return data?.data ?? []; | ||||
| mutationKey: ['addTenantUser'], | mutationKey: ['addTenantUser'], | ||||
| mutationFn: async (email: string) => { | mutationFn: async (email: string) => { | ||||
| const { data } = await addTenantUser(tenantInfo.tenant_id, email); | const { data } = await addTenantUser(tenantInfo.tenant_id, email); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| queryClient.invalidateQueries({ queryKey: ['listTenantUser'] }); | queryClient.invalidateQueries({ queryKey: ['listTenantUser'] }); | ||||
| } | } | ||||
| return data?.retcode; | |||||
| return data?.code; | |||||
| }, | }, | ||||
| }); | }); | ||||
| tenantId: tenantId ?? tenantInfo.tenant_id, | tenantId: tenantId ?? tenantInfo.tenant_id, | ||||
| userId, | userId, | ||||
| }); | }); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(t('message.deleted')); | message.success(t('message.deleted')); | ||||
| queryClient.invalidateQueries({ queryKey: ['listTenantUser'] }); | queryClient.invalidateQueries({ queryKey: ['listTenantUser'] }); | ||||
| queryClient.invalidateQueries({ queryKey: ['listTenant'] }); | queryClient.invalidateQueries({ queryKey: ['listTenant'] }); | ||||
| mutationKey: ['agreeTenant'], | mutationKey: ['agreeTenant'], | ||||
| mutationFn: async (tenantId: string) => { | mutationFn: async (tenantId: string) => { | ||||
| const { data } = await agreeTenant(tenantId); | const { data } = await agreeTenant(tenantId); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| message.success(t('message.operated')); | message.success(t('message.operated')); | ||||
| queryClient.invalidateQueries({ queryKey: ['listTenant'] }); | queryClient.invalidateQueries({ queryKey: ['listTenant'] }); | ||||
| } | } |
| export interface ResponseType<T = any> { | export interface ResponseType<T = any> { | ||||
| retcode: number; | |||||
| code: number; | |||||
| data: T; | data: T; | ||||
| retmsg: string; | |||||
| message: string; | |||||
| status: number; | status: number; | ||||
| } | } | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (data?.retcode === 0) { | |||||
| if (data?.code === 0) { | |||||
| const { content_with_weight, important_kwd = [] } = data.data; | const { content_with_weight, important_kwd = [] } = data.data; | ||||
| form.setFieldsValue({ content: content_with_weight }); | form.setFieldsValue({ content: content_with_weight }); | ||||
| setKeywords(important_kwd); | setKeywords(important_kwd); |
| const onChunkUpdatingOk = useCallback( | const onChunkUpdatingOk = useCallback( | ||||
| async ({ content, keywords }: { content: string; keywords: string }) => { | async ({ content, keywords }: { content: string; keywords: string }) => { | ||||
| const retcode = await createChunk({ | |||||
| const code = await createChunk({ | |||||
| content_with_weight: content, | content_with_weight: content, | ||||
| doc_id: documentId, | doc_id: documentId, | ||||
| chunk_id: chunkId, | chunk_id: chunkId, | ||||
| important_kwd: keywords, // keywords | important_kwd: keywords, // keywords | ||||
| }); | }); | ||||
| if (retcode === 0) { | |||||
| if (code === 0) { | |||||
| hideChunkUpdatingModal(); | hideChunkUpdatingModal(); | ||||
| } | } | ||||
| }, | }, |
| async (fileList: UploadFile[]): Promise<number | undefined> => { | async (fileList: UploadFile[]): Promise<number | undefined> => { | ||||
| if (fileList.length > 0) { | if (fileList.length > 0) { | ||||
| const ret: any = await uploadDocument(fileList); | const ret: any = await uploadDocument(fileList); | ||||
| if (typeof ret?.retmsg !== 'string') { | |||||
| if (typeof ret?.message !== 'string') { | |||||
| return; | return; | ||||
| } | } | ||||
| const count = getUnSupportedFilesCount(ret?.retmsg); | |||||
| const count = getUnSupportedFilesCount(ret?.message); | |||||
| /// 500 error code indicates that some file types are not supported | /// 500 error code indicates that some file types are not supported | ||||
| let retcode = ret?.retcode; | |||||
| let code = ret?.code; | |||||
| if ( | if ( | ||||
| ret?.retcode === 0 || | |||||
| (ret?.retcode === 500 && count !== fileList.length) // Some files were not uploaded successfully, but some were uploaded successfully. | |||||
| ret?.code === 0 || | |||||
| (ret?.code === 500 && count !== fileList.length) // Some files were not uploaded successfully, but some were uploaded successfully. | |||||
| ) { | ) { | ||||
| retcode = 0; | |||||
| code = 0; | |||||
| hideDocumentUploadModal(); | hideDocumentUploadModal(); | ||||
| } | } | ||||
| return retcode; | |||||
| return code; | |||||
| } | } | ||||
| }, | }, | ||||
| [uploadDocument, hideDocumentUploadModal], | [uploadDocument, hideDocumentUploadModal], |
| async (dialogId?: string) => { | async (dialogId?: string) => { | ||||
| if (dialogId) { | if (dialogId) { | ||||
| const ret = await fetchDialog(dialogId); | const ret = await fetchDialog(dialogId); | ||||
| if (ret.retcode === 0) { | |||||
| if (ret.code === 0) { | |||||
| setDialog(ret.data); | setDialog(ret.data); | ||||
| } | } | ||||
| } | } | ||||
| controller, | controller, | ||||
| ); | ); | ||||
| if (res && (res?.response.status !== 200 || res?.data?.retcode !== 0)) { | |||||
| if (res && (res?.response.status !== 200 || res?.data?.code !== 0)) { | |||||
| // cancel loading | // cancel loading | ||||
| setValue(message.content); | setValue(message.content); | ||||
| console.info('removeLatestMessage111'); | console.info('removeLatestMessage111'); | ||||
| true, | true, | ||||
| conversationId, | conversationId, | ||||
| ); | ); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| setConversationIsNew(''); | setConversationIsNew(''); | ||||
| const id = data.data.id; | const id = data.data.id; | ||||
| // currentConversationIdRef.current = id; | // currentConversationIdRef.current = id; | ||||
| is_new: false, | is_new: false, | ||||
| }); | }); | ||||
| if (ret.retcode === 0) { | |||||
| if (ret.code === 0) { | |||||
| hideConversationRenameModal(); | hideConversationRenameModal(); | ||||
| } | } | ||||
| }, | }, | ||||
| const handleShowConversationRenameModal = useCallback( | const handleShowConversationRenameModal = useCallback( | ||||
| async (conversationId: string) => { | async (conversationId: string) => { | ||||
| const ret = await fetchConversation(conversationId); | const ret = await fetchConversation(conversationId); | ||||
| if (ret.retcode === 0) { | |||||
| if (ret.code === 0) { | |||||
| setConversation(ret.data); | setConversation(ret.data); | ||||
| } | } | ||||
| showConversationRenameModal(); | showConversationRenameModal(); |
| messages: [...(derivedMessages ?? []), message], | messages: [...(derivedMessages ?? []), message], | ||||
| }); | }); | ||||
| if (res && (res?.response.status !== 200 || res?.data?.retcode !== 0)) { | |||||
| if (res && (res?.response.status !== 200 || res?.data?.code !== 0)) { | |||||
| // cancel loading | // cancel loading | ||||
| setValue(message.content); | setValue(message.content); | ||||
| removeLatestMessage(); | removeLatestMessage(); | ||||
| sendMessage(message); | sendMessage(message); | ||||
| } else { | } else { | ||||
| const data = await setConversation('user id'); | const data = await setConversation('user id'); | ||||
| if (data.retcode === 0) { | |||||
| if (data.code === 0) { | |||||
| const id = data.data.id; | const id = data.data.id; | ||||
| sendMessage(message, id); | sendMessage(message, id); | ||||
| } | } |
| const fetchDocument = useCallback(async () => { | const fetchDocument = useCallback(async () => { | ||||
| const ret = await axios.get(api); | const ret = await axios.get(api); | ||||
| const { data } = ret; | const { data } = ret; | ||||
| if (!(data instanceof ArrayBuffer) && data.retcode !== 0) { | |||||
| setError(data.retmsg); | |||||
| if (!(data instanceof ArrayBuffer) && data.code !== 0) { | |||||
| setError(data.message); | |||||
| } | } | ||||
| return ret; | return ret; | ||||
| }, [api]); | }, [api]); |
| const handleRemoveFile = () => { | const handleRemoveFile = () => { | ||||
| showDeleteConfirm({ | showDeleteConfirm({ | ||||
| onOk: async () => { | onOk: async () => { | ||||
| const retcode = await removeDocument({ fileIds, parentId }); | |||||
| if (retcode === 0) { | |||||
| const code = await removeDocument({ fileIds, parentId }); | |||||
| if (code === 0) { | |||||
| setSelectedRowKeys([]); | setSelectedRowKeys([]); | ||||
| } | } | ||||
| return; | return; |
| const onLoadData: TreeSelectProps['loadData'] = useCallback( | const onLoadData: TreeSelectProps['loadData'] = useCallback( | ||||
| async ({ id }) => { | async ({ id }) => { | ||||
| const ret = await fetchList(id); | const ret = await fetchList(id); | ||||
| if (ret.retcode === 0) { | |||||
| if (ret.code === 0) { | |||||
| setTreeData((tree) => { | setTreeData((tree) => { | ||||
| return tree.concat( | return tree.concat( | ||||
| ret.data.files | ret.data.files |
| const res = await send(params); | const res = await send(params); | ||||
| if (receiveMessageError(res)) { | if (receiveMessageError(res)) { | ||||
| antMessage.error(res?.data?.retmsg); | |||||
| antMessage.error(res?.data?.message); | |||||
| // cancel loading | // cancel loading | ||||
| setValue(message.content); | setValue(message.content); | ||||
| const res = await send(params); | const res = await send(params); | ||||
| if (receiveMessageError(res)) { | if (receiveMessageError(res)) { | ||||
| antMessage.error(res?.data?.retmsg); | |||||
| antMessage.error(res?.data?.message); | |||||
| // cancel loading | // cancel loading | ||||
| setValue(message.content); | setValue(message.content); |
| const { send } = useSendMessageWithSse(api.runCanvas); | const { send } = useSendMessageWithSse(api.runCanvas); | ||||
| const handleRun = useCallback(async () => { | const handleRun = useCallback(async () => { | ||||
| const saveRet = await saveGraph(); | const saveRet = await saveGraph(); | ||||
| if (saveRet?.retcode === 0) { | |||||
| if (saveRet?.code === 0) { | |||||
| // Call the reset api before opening the run drawer each time | // Call the reset api before opening the run drawer each time | ||||
| const resetRet = await resetFlow(); | const resetRet = await resetFlow(); | ||||
| // After resetting, all previous messages will be cleared. | // After resetting, all previous messages will be cleared. | ||||
| if (resetRet?.retcode === 0) { | |||||
| if (resetRet?.code === 0) { | |||||
| // fetch prologue | // fetch prologue | ||||
| const sendRet = await send({ id }); | const sendRet = await send({ id }); | ||||
| if (receiveMessageError(sendRet)) { | if (receiveMessageError(sendRet)) { | ||||
| message.error(sendRet?.data?.retmsg); | |||||
| message.error(sendRet?.data?.message); | |||||
| } else { | } else { | ||||
| refetch(); | refetch(); | ||||
| show(); | show(); |
| // }, | // }, | ||||
| }); | }); | ||||
| if (ret?.retcode === 0) { | |||||
| if (ret?.code === 0) { | |||||
| hideFlowSettingModal(); | hideFlowSettingModal(); | ||||
| navigate(`/flow/${ret.data.id}`); | navigate(`/flow/${ret.data.id}`); | ||||
| } | } |
| }; | }; | ||||
| export const receiveMessageError = (res: any) => | export const receiveMessageError = (res: any) => | ||||
| res && (res?.response.status !== 200 || res?.data?.retcode !== 0); | |||||
| res && (res?.response.status !== 200 || res?.data?.code !== 0); | |||||
| // Replace the id in the object with text | // Replace the id in the object with text | ||||
| export const replaceIdWithText = ( | export const replaceIdWithText = ( |
| name, | name, | ||||
| }); | }); | ||||
| if (ret?.retcode === 0) { | |||||
| if (ret?.code === 0) { | |||||
| hideModal(); | hideModal(); | ||||
| navigate( | navigate( | ||||
| `/knowledge/${KnowledgeRouteKey.Configuration}?id=${ret.data.kb_id}`, | `/knowledge/${KnowledgeRouteKey.Configuration}?id=${ret.data.kb_id}`, |
| const rsaPassWord = rsaPsw(params.password) as string; | const rsaPassWord = rsaPsw(params.password) as string; | ||||
| if (title === 'login') { | if (title === 'login') { | ||||
| const retcode = await login({ | |||||
| const code = await login({ | |||||
| email: params.email, | email: params.email, | ||||
| password: rsaPassWord, | password: rsaPassWord, | ||||
| }); | }); | ||||
| if (retcode === 0) { | |||||
| if (code === 0) { | |||||
| navigate('/knowledge'); | navigate('/knowledge'); | ||||
| } | } | ||||
| } else { | } else { | ||||
| const retcode = await register({ | |||||
| const code = await register({ | |||||
| nickname: params.nickname, | nickname: params.nickname, | ||||
| email: params.email, | email: params.email, | ||||
| password: rsaPassWord, | password: rsaPassWord, | ||||
| }); | }); | ||||
| if (retcode === 0) { | |||||
| if (code === 0) { | |||||
| setTitle('login'); | setTitle('login'); | ||||
| } | } | ||||
| } | } |
| const handleAddUserOk = useCallback( | const handleAddUserOk = useCallback( | ||||
| async (email: string) => { | async (email: string) => { | ||||
| const retcode = await addTenantUser(email); | |||||
| if (retcode === 0) { | |||||
| const code = await addTenantUser(email); | |||||
| if (code === 0) { | |||||
| hideAddingTenantModal(); | hideAddingTenantModal(); | ||||
| } | } | ||||
| }, | }, | ||||
| const handleDeleteTenantUser = (userId: string) => () => { | const handleDeleteTenantUser = (userId: string) => () => { | ||||
| showDeleteConfirm({ | showDeleteConfirm({ | ||||
| onOk: async () => { | onOk: async () => { | ||||
| const retcode = await deleteTenantUser({ userId }); | |||||
| if (retcode === 0) { | |||||
| const code = await deleteTenantUser({ userId }); | |||||
| if (code === 0) { | |||||
| } | } | ||||
| return; | return; | ||||
| }, | }, |
| const data: ResponseType = await response.clone().json(); | const data: ResponseType = await response.clone().json(); | ||||
| if (data.retcode === 401 || data.retcode === 401) { | |||||
| if (data.code === 401 || data.code === 401) { | |||||
| notification.error({ | notification.error({ | ||||
| message: data.retmsg, | |||||
| description: data.retmsg, | |||||
| message: data.message, | |||||
| description: data.message, | |||||
| duration: 3, | duration: 3, | ||||
| }); | }); | ||||
| authorizationUtil.removeAll(); | authorizationUtil.removeAll(); | ||||
| history.push('/login'); // Will not jump to the login page | history.push('/login'); // Will not jump to the login page | ||||
| } else if (data.retcode !== 0) { | |||||
| if (data.retcode === 100) { | |||||
| message.error(data.retmsg); | |||||
| } else if (data.code !== 0) { | |||||
| if (data.code === 100) { | |||||
| message.error(data.message); | |||||
| } else { | } else { | ||||
| notification.error({ | notification.error({ | ||||
| message: `${i18n.t('message.hint')} : ${data.retcode}`, | |||||
| description: data.retmsg, | |||||
| message: `${i18n.t('message.hint')} : ${data.code}`, | |||||
| description: data.message, | |||||
| duration: 3, | duration: 3, | ||||
| }); | }); | ||||
| } | } |