| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624 |
- # coding=utf-8
- """
- @project: MaxKB
- @Author:虎虎
- @file: chat.py
- @date:2025/6/9 11:23
- @desc:
- """
- import json
- import os
- from gettext import gettext
- from typing import List, Dict
- import uuid_utils.compat as uuid
- from django.db.models import QuerySet
- from django.utils.translation import gettext_lazy as _
- from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
- from rest_framework import serializers
- from application.chat_pipeline.pipeline_manage import PipelineManage
- from application.chat_pipeline.step.chat_step.i_chat_step import PostResponseHandler
- from application.chat_pipeline.step.chat_step.impl.base_chat_step import BaseChatStep
- from application.chat_pipeline.step.generate_human_message_step.impl.base_generate_human_message_step import \
- BaseGenerateHumanMessageStep
- from application.chat_pipeline.step.reset_problem_step.impl.base_reset_problem_step import BaseResetProblemStep
- from application.chat_pipeline.step.search_dataset_step.impl.base_search_dataset_step import BaseSearchDatasetStep
- from application.flow.common import Answer, Workflow
- from application.flow.i_step_node import WorkFlowPostHandler
- from application.flow.tools import to_stream_response_simple
- from application.flow.workflow_manage import WorkflowManage
- from application.models import Application, ApplicationTypeChoices, \
- ChatUserType, ApplicationChatUserStats, ApplicationAccessToken, ChatRecord, Chat, ApplicationVersion
- from application.serializers.application import ApplicationOperateSerializer
- from application.serializers.common import ChatInfo
- from common.database_model_manage.database_model_manage import DatabaseModelManage
- from common.exception.app_exception import AppApiException, AppChatNumOutOfBoundsFailed, ChatException
- from common.handle.base_to_response import BaseToResponse
- from common.handle.impl.response.openai_to_response import OpenaiToResponse
- from common.handle.impl.response.system_to_response import SystemToResponse
- from common.utils.common import flat_map, get_file_content, is_valid_uuid
- from knowledge.models import Document, Paragraph
- from maxkb.conf import PROJECT_DIR
- from models_provider.models import Model, Status
- from models_provider.tools import get_model_instance_by_model_workspace_id
- from system_manage.models.resource_mapping import ResourceMapping
- class ChatMessagesSerializers(serializers.Serializer):
- role = serializers.CharField(required=True, label=_("Role"))
- content = serializers.CharField(required=True, label=_("Content"))
- class GeneratePromptSerializers(serializers.Serializer):
- prompt = serializers.CharField(required=True, label=_("Prompt template"))
- messages = serializers.ListSerializer(child=ChatMessagesSerializers(), required=True, label=_("Chat context"))
- def is_valid(self, *, raise_exception=False):
- super().is_valid(raise_exception=True)
- messages = self.data.get("messages")
- if len(messages) > 30:
- raise AppApiException(400, _("Too many messages"))
- for index in range(len(messages)):
- role = messages[index].get('role')
- if role == 'ai' and index % 2 != 1:
- raise AppApiException(400, _("Authentication failed. Please verify that the parameters are correct."))
- if role == 'user' and index % 2 != 0:
- raise AppApiException(400, _("Authentication failed. Please verify that the parameters are correct."))
- if role not in ['user', 'ai']:
- raise AppApiException(400, _("Authentication failed. Please verify that the parameters are correct."))
- class ChatMessageSerializers(serializers.Serializer):
- message = serializers.CharField(required=True, label=_("User Questions"))
- stream = serializers.BooleanField(required=True,
- label=_("Is the answer in streaming mode"))
- re_chat = serializers.BooleanField(required=True, label=_("Do you want to reply again"))
- chat_record_id = serializers.UUIDField(required=False, allow_null=True,
- label=_("Conversation record id"))
- node_id = serializers.CharField(required=False, allow_null=True, allow_blank=True,
- label=_("Node id"))
- runtime_node_id = serializers.CharField(required=False, allow_null=True, allow_blank=True,
- label=_("Runtime node id"))
- node_data = serializers.DictField(required=False, allow_null=True,
- label=_("Node parameters"))
- form_data = serializers.DictField(required=False, label=_("Global variables"))
- image_list = serializers.ListField(required=False, label=_("picture"))
- document_list = serializers.ListField(required=False, label=_("document"))
- audio_list = serializers.ListField(required=False, label=_("Audio"))
- other_list = serializers.ListField(required=False, label=_("Other"))
- child_node = serializers.DictField(required=False, allow_null=True,
- label=_("Child Nodes"))
- def get_post_handler(chat_info: ChatInfo):
- class PostHandler(PostResponseHandler):
- def handler(self,
- chat_id,
- chat_record_id,
- paragraph_list: List[Paragraph],
- problem_text: str,
- answer_text,
- manage: PipelineManage,
- step: BaseChatStep,
- padding_problem_text: str = None,
- **kwargs):
- answer_list = [[Answer(answer_text, 'ai-chat-node', 'ai-chat-node', 'ai-chat-node', {}, 'ai-chat-node',
- kwargs.get('reasoning_content', '')).to_dict()]]
- chat_record = ChatRecord(id=chat_record_id,
- chat_id=chat_id,
- problem_text=problem_text,
- answer_text=answer_text,
- details=manage.get_details(),
- message_tokens=manage.context['message_tokens'],
- answer_tokens=manage.context['answer_tokens'],
- answer_text_list=answer_list,
- run_time=manage.context['run_time'],
- index=len(chat_info.chat_record_list) + 1,
- ip_address=chat_info.ip_address,
- source=chat_info.source
- )
- chat_info.append_chat_record(chat_record)
- # 重新设置缓存
- chat_info.set_cache()
- return PostHandler()
- class DebugChatSerializers(serializers.Serializer):
- chat_id = serializers.UUIDField(required=True, label=_("Conversation ID"))
- def chat(self, instance: dict, base_to_response: BaseToResponse = SystemToResponse()):
- self.is_valid(raise_exception=True)
- chat_id = self.data.get('chat_id')
- chat_info: ChatInfo = ChatInfo.get_cache(chat_id)
- application = QuerySet(Application).filter(id=chat_info.application_id).first()
- chat_info.application = application
- return ChatSerializers(data={
- 'chat_id': chat_id, "chat_user_id": chat_info.chat_user_id,
- "chat_user_type": chat_info.chat_user_type,
- "application_id": chat_info.application.id, "debug": True
- }).chat(instance, base_to_response)
- SYSTEM_ROLE = get_file_content(os.path.join(PROJECT_DIR, "apps", "chat", 'template', 'generate_prompt_system'))
- class PromptGenerateSerializer(serializers.Serializer):
- workspace_id = serializers.CharField(required=False, label=_('Workspace ID'))
- model_id = serializers.CharField(required=False, allow_blank=True, allow_null=True, label=_("Model"))
- application_id = serializers.CharField(required=False, allow_blank=True, allow_null=True, label=_("Application"))
- def is_valid(self, *, raise_exception=False):
- super().is_valid(raise_exception=True)
- workspace_id = self.data.get('workspace_id')
- query_set = QuerySet(Application).filter(id=self.data.get('application_id'))
- if workspace_id:
- query_set = query_set.filter(workspace_id=workspace_id)
- application = query_set.first()
- if application is None:
- raise AppApiException(500, _('Application id does not exist'))
- return application
- def generate_prompt(self, instance: dict):
- application = self.is_valid(raise_exception=True)
- GeneratePromptSerializers(data=instance).is_valid(raise_exception=True)
- workspace_id = self.data.get('workspace_id')
- model_id = self.data.get('model_id')
- prompt = instance.get('prompt')
- messages = instance.get('messages')
- message = messages[-1]['content']
- q = prompt.replace("{userInput}", message)
- messages[-1]['content'] = q
- SUPPORTED_MODEL_TYPES = ["LLM", "IMAGE"]
- model_exist = QuerySet(Model).filter(
- id=model_id,
- model_type__in=SUPPORTED_MODEL_TYPES
- ).exists()
- if not model_exist:
- raise Exception(_("Model does not exists or is not an LLM model"))
- def process():
- model = get_model_instance_by_model_workspace_id(model_id=model_id, workspace_id=workspace_id,
- **application.model_params_setting)
- try:
- for r in model.stream([SystemMessage(content=SYSTEM_ROLE),
- *[HumanMessage(content=m.get('content')) if m.get(
- 'role') == 'user' else AIMessage(
- content=m.get('content')) for m in messages]]):
- yield 'data: ' + json.dumps({'content': r.content}) + '\n\n'
- except Exception as e:
- yield 'data: ' + json.dumps({'error': str(e)}) + '\n\n'
- return to_stream_response_simple(process())
- class OpenAIMessage(serializers.Serializer):
- content = serializers.CharField(required=True, label=_('content'))
- role = serializers.CharField(required=True, label=_('Role'))
- class OpenAIInstanceSerializer(serializers.Serializer):
- messages = serializers.ListField(child=OpenAIMessage())
- chat_id = serializers.UUIDField(required=False, label=_("Conversation ID"))
- re_chat = serializers.BooleanField(required=False, label=_("Regenerate"))
- stream = serializers.BooleanField(required=False, label=_("Streaming Output"))
- class OpenAIChatSerializer(serializers.Serializer):
- application_id = serializers.UUIDField(required=True, label=_("Application ID"))
- chat_user_id = serializers.CharField(required=True, label=_("Client id"))
- chat_user_type = serializers.CharField(required=True, label=_("Client Type"))
- ip_address = serializers.CharField(required=False, label=_("IP Address"))
- source = serializers.JSONField(required=False, label=_("Source"))
- @staticmethod
- def get_message(instance):
- return instance.get('messages')[-1].get('content')
- @staticmethod
- def generate_chat(chat_id, application_id, message, chat_user_id, chat_user_type, ip_address, source):
- if chat_id is None:
- chat_id = str(uuid.uuid1())
- chat_info = ChatInfo(chat_id, chat_user_id, chat_user_type, ip_address, source, [], [],
- application_id)
- chat_info.set_cache()
- else:
- chat_info = ChatInfo.get_cache(chat_id)
- if chat_info is None:
- open_chat = ChatSerializers(data={
- 'chat_id': chat_id,
- 'chat_user_id': chat_user_id,
- 'chat_user_type': chat_user_type,
- 'application_id': application_id,
- 'ip_address': ip_address,
- 'source': source,
- })
- open_chat.is_valid(raise_exception=True)
- chat_info = open_chat.re_open_chat(chat_id)
- chat_info.set_cache()
- return chat_id
- def chat(self, instance: Dict, with_valid=True):
- if with_valid:
- self.is_valid(raise_exception=True)
- OpenAIInstanceSerializer(data=instance).is_valid(raise_exception=True)
- chat_id = instance.get('chat_id')
- message = self.get_message(instance)
- re_chat = instance.get('re_chat', False)
- stream = instance.get('stream', False)
- application_id = self.data.get('application_id')
- chat_user_id = self.data.get('chat_user_id')
- chat_user_type = self.data.get('chat_user_type')
- ip_address = self.data.get('ip_address')
- source = self.data.get('source')
- chat_id = self.generate_chat(chat_id, application_id, message, chat_user_id, chat_user_type, ip_address, source)
- return ChatSerializers(
- data={
- 'chat_id': chat_id,
- 'chat_user_id': chat_user_id,
- 'chat_user_type': chat_user_type,
- 'application_id': application_id,
- 'ip_address': ip_address,
- 'source': source,
- }
- ).chat({'message': message,
- 're_chat': re_chat,
- 'stream': stream,
- 'form_data': instance.get('form_data', {}),
- 'image_list': instance.get('image_list', []),
- 'document_list': instance.get('document_list', []),
- 'audio_list': instance.get('audio_list', []),
- 'other_list': instance.get('other_list', [])},
- base_to_response=OpenaiToResponse())
- class ChatSerializers(serializers.Serializer):
- chat_id = serializers.UUIDField(required=True, label=_("Conversation ID"))
- chat_user_id = serializers.CharField(required=True, label=_("Client id"))
- chat_user_type = serializers.CharField(required=True, label=_("Client Type"))
- application_id = serializers.UUIDField(required=True, allow_null=True,
- label=_("Application ID"))
- debug = serializers.BooleanField(required=False, label=_("Debug"))
- ip_address = serializers.CharField(required=False, label=_("IP Address"), allow_null=True, allow_blank=True)
- source = serializers.JSONField(required=False, label=_("Source"))
- def is_valid_application_workflow(self, *, raise_exception=False):
- self.is_valid_intraday_access_num()
- def is_valid_chat_id(self, chat_info: ChatInfo):
- if self.data.get('application_id') is not None and self.data.get('application_id') != str(
- chat_info.application_id):
- raise ChatException(500, _("Conversation does not exist"))
- def is_valid_intraday_access_num(self):
- if not self.data.get('debug') and [ChatUserType.ANONYMOUS_USER.value,
- ChatUserType.CHAT_USER.value].__contains__(
- self.data.get('chat_user_type')):
- access_client = QuerySet(ApplicationChatUserStats).filter(chat_user_id=self.data.get('chat_user_id'),
- application_id=self.data.get(
- 'application_id')).first()
- if access_client is None:
- access_client = ApplicationChatUserStats(chat_user_id=self.data.get('chat_user_id'),
- chat_user_type=self.data.get('chat_user_type'),
- application_id=self.data.get('application_id'),
- access_num=0,
- intraday_access_num=0)
- access_client.save()
- application_access_token = QuerySet(ApplicationAccessToken).filter(
- application_id=self.data.get('application_id')).first()
- if application_access_token.access_num <= access_client.intraday_access_num:
- raise AppChatNumOutOfBoundsFailed(1002, _("The number of visits exceeds today's visits"))
- def is_valid_application_simple(self, *, chat_info: ChatInfo, raise_exception=False):
- self.is_valid_intraday_access_num()
- model_id = chat_info.application.model_id
- if model_id is None:
- return chat_info
- model = QuerySet(Model).filter(id=model_id).first()
- if model is None:
- return chat_info
- if model.status == Status.ERROR:
- raise ChatException(500, _("The current model is not available"))
- if model.status == Status.DOWNLOAD:
- raise ChatException(500, _("The model is downloading, please try again later"))
- return chat_info
- def chat_simple(self, chat_info: ChatInfo, instance, base_to_response):
- message = instance.get('message')
- re_chat = instance.get('re_chat')
- stream = instance.get('stream')
- chat_user_id = self.data.get('chat_user_id')
- chat_user_type = self.data.get('chat_user_type')
- ip_address = self.data.get('ip_address')
- source = self.data.get('source')
- form_data = instance.get("form_data")
- chat_record_id = instance.get('chat_record_id')
- pipeline_manage_builder = PipelineManage.builder()
- # 如果开启了问题优化,则添加上问题优化步骤
- if chat_info.application.problem_optimization:
- pipeline_manage_builder.append_step(BaseResetProblemStep)
- # 构建流水线管理器
- pipeline_message = (pipeline_manage_builder.append_step(BaseSearchDatasetStep)
- .append_step(BaseGenerateHumanMessageStep)
- .append_step(BaseChatStep)
- .add_base_to_response(base_to_response)
- .add_debug(self.data.get('debug', False))
- .build())
- exclude_paragraph_id_list = []
- # 相同问题是否需要排除已经查询到的段落
- if re_chat:
- paragraph_id_list = flat_map(
- [[paragraph.get('id') for paragraph in chat_record.details['search_step']['paragraph_list']] for
- chat_record in chat_info.chat_record_list if
- chat_record.problem_text == message and 'search_step' in chat_record.details and 'paragraph_list' in
- chat_record.details['search_step']])
- exclude_paragraph_id_list = list(set(paragraph_id_list))
- # 构建运行参数
- params = chat_info.to_pipeline_manage_params(message, get_post_handler(chat_info), exclude_paragraph_id_list,
- chat_user_id, chat_user_type, ip_address, source, stream,
- form_data)
- if chat_record_id:
- params['chat_record_id'] = chat_record_id
- chat_info.set_chat(message)
- # 运行流水线作业
- pipeline_message.run(params)
- return pipeline_message.context['chat_result']
- @staticmethod
- def get_chat_record(chat_info, chat_record_id):
- if chat_info is not None:
- chat_record_list = [chat_record for chat_record in chat_info.chat_record_list if
- str(chat_record.id) == str(chat_record_id)]
- if chat_record_list is not None and len(chat_record_list):
- return chat_record_list[-1]
- chat_record = QuerySet(ChatRecord).filter(id=chat_record_id, chat_id=chat_info.chat_id).first()
- if chat_record is None:
- if not is_valid_uuid(chat_record_id):
- raise ChatException(500, _("Conversation record does not exist"))
- chat_record = QuerySet(ChatRecord).filter(id=chat_record_id).first()
- return chat_record
- def chat_work_flow(self, chat_info: ChatInfo, instance: dict, base_to_response):
- message = instance.get('message')
- re_chat = instance.get('re_chat')
- stream = instance.get('stream')
- chat_user_id = self.data.get("chat_user_id")
- chat_user_type = self.data.get('chat_user_type')
- ip_address = self.data.get('ip_address')
- source = self.data.get('source')
- form_data = instance.get('form_data')
- image_list = instance.get('image_list')
- video_list = instance.get('video_list')
- document_list = instance.get('document_list')
- audio_list = instance.get('audio_list')
- other_list = instance.get('other_list')
- workspace_id = chat_info.application.workspace_id
- chat_record_id = instance.get('chat_record_id')
- debug = self.data.get('debug', False)
- chat_record = None
- history_chat_record = chat_info.chat_record_list
- if chat_record_id is not None:
- chat_record = self.get_chat_record(chat_info, chat_record_id)
- if chat_record:
- history_chat_record = [r for r in chat_info.chat_record_list if str(r.id) != chat_record_id]
- work_flow = chat_info.application.work_flow
- work_flow_manage = WorkflowManage(Workflow.new_instance(work_flow),
- {'history_chat_record': history_chat_record, 'question': message,
- 'chat_id': chat_info.chat_id, 'chat_record_id': str(
- uuid.uuid7()) if chat_record_id is None else str(chat_record_id),
- 'stream': stream,
- 're_chat': re_chat,
- 'chat_user_id': chat_user_id,
- 'chat_user_type': chat_user_type,
- 'ip_address': ip_address,
- 'source': source,
- 'workspace_id': workspace_id,
- 'debug': debug,
- 'chat_user': chat_info.get_chat_user(),
- 'chat_user_group': chat_info.get_chat_user_group(),
- 'application_id': str(chat_info.application_id)},
- WorkFlowPostHandler(chat_info),
- base_to_response, form_data, image_list, document_list, audio_list,
- video_list,
- other_list,
- instance.get('runtime_node_id'),
- instance.get('node_data'), chat_record, instance.get('child_node'))
- chat_info.set_chat(message)
- r = work_flow_manage.run()
- return r
- def is_valid_chat_user(self):
- chat_user_id = self.data.get('chat_user_id')
- application_id = self.data.get('application_id')
- chat_user_type = self.data.get('chat_user_type')
- is_auth_chat_user = DatabaseModelManage.get_model("is_auth_chat_user")
- application_access_token = QuerySet(ApplicationAccessToken).filter(application_id=application_id).first()
- if application_access_token and application_access_token.authentication and application_access_token.authentication_value.get(
- 'type') == 'login':
- if chat_user_type == ChatUserType.ANONYMOUS_USER.value:
- raise ChatException(500, _("The chat user is not authorized."))
- if chat_user_type == ChatUserType.CHAT_USER.value and is_auth_chat_user:
- is_auth = is_auth_chat_user(chat_user_id, application_id)
- if not is_auth:
- raise ChatException(500, _("The chat user is not authorized."))
- def chat(self, instance: dict, base_to_response: BaseToResponse = SystemToResponse()):
- super().is_valid(raise_exception=True)
- ChatMessageSerializers(data=instance).is_valid(raise_exception=True)
- chat_info = self.get_chat_info()
- chat_info.get_application()
- chat_info.get_chat_user(asker=(instance.get('form_data') or {}).get('asker'))
- self.is_valid_chat_id(chat_info)
- if not self.data.get('debug'):
- self.is_valid_chat_user()
- if chat_info.application.type == ApplicationTypeChoices.SIMPLE:
- self.is_valid_application_simple(raise_exception=True, chat_info=chat_info)
- return self.chat_simple(chat_info, instance, base_to_response)
- else:
- self.is_valid_application_workflow(raise_exception=True)
- return self.chat_work_flow(chat_info, instance, base_to_response)
- def get_chat_info(self):
- self.is_valid(raise_exception=True)
- chat_id = self.data.get('chat_id')
- chat_info: ChatInfo = ChatInfo.get_cache(chat_id)
- if chat_info is None:
- chat_info: ChatInfo = self.re_open_chat(chat_id)
- chat_info.set_cache()
- return chat_info
- def re_open_chat(self, chat_id: str):
- chat = QuerySet(Chat).filter(id=chat_id).first()
- if chat is None:
- raise ChatException(500, _("Conversation does not exist"))
- application = QuerySet(Application).filter(id=chat.application_id).first()
- if application is None:
- raise ChatException(500, _("Application does not exist"))
- application_version = QuerySet(ApplicationVersion).filter(application_id=application.id).order_by(
- '-create_time')[0:1].first()
- if application_version is None:
- raise ChatException(500, _("The application has not been published. Please use it after publishing."))
- if application.type == ApplicationTypeChoices.SIMPLE:
- return self.re_open_chat_simple(chat_id, application)
- else:
- return self.re_open_chat_work_flow(chat_id, application)
- def re_open_chat_simple(self, chat_id, application):
- # 数据集id列表
- knowledge_id_list = [str(row.target_id) for row in
- QuerySet(ResourceMapping).filter(source_id=str(application.id),
- source_type='APPLICATION',
- target_type='KNOWLEDGE')]
- # 需要排除的文档
- exclude_document_id_list = [str(document.id) for document in
- QuerySet(Document).filter(
- knowledge_id__in=knowledge_id_list,
- is_active=False)]
- chat_info = ChatInfo(chat_id, self.data.get('chat_user_id'), self.data.get('chat_user_type'),
- self.data.get('ip_address'),
- self.data.get('source'), knowledge_id_list,
- exclude_document_id_list, application.id)
- chat_record_list = list(QuerySet(ChatRecord).filter(chat_id=chat_id).order_by('-create_time')[0:5])
- chat_record_list.sort(key=lambda r: r.create_time)
- for chat_record in chat_record_list:
- chat_info.chat_record_list.append(chat_record)
- return chat_info
- def re_open_chat_work_flow(self, chat_id, application):
- chat_info = ChatInfo(chat_id, self.data.get('chat_user_id'), self.data.get('chat_user_type'),
- self.data.get('ip_address'),
- self.data.get('source'), [], [],
- application.id)
- chat_record_list = list(QuerySet(ChatRecord).filter(chat_id=chat_id).order_by('-create_time')[0:5])
- chat_record_list.sort(key=lambda r: r.create_time)
- for chat_record in chat_record_list:
- chat_info.chat_record_list.append(chat_record)
- return chat_info
- class OpenChatSerializers(serializers.Serializer):
- workspace_id = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_("Workspace ID"))
- application_id = serializers.UUIDField(required=True)
- chat_user_id = serializers.CharField(required=True, label=_("Client id"))
- chat_user_type = serializers.CharField(required=True, label=_("Client Type"))
- debug = serializers.BooleanField(required=True, label=_("Debug"))
- ip_address = serializers.CharField(required=False, label=_("IP Address"))
- source = serializers.JSONField(required=False, label=_("Source"))
- def is_valid(self, *, raise_exception=False):
- super().is_valid(raise_exception=True)
- workspace_id = self.data.get('workspace_id')
- application_id = self.data.get('application_id')
- query_set = QuerySet(Application).filter(id=application_id)
- if workspace_id:
- query_set = query_set.filter(workspace_id=workspace_id)
- if not query_set.exists():
- raise AppApiException(500, gettext('Application does not exist'))
- def open(self):
- self.is_valid(raise_exception=True)
- application_id = self.data.get('application_id')
- application = QuerySet(Application).get(id=application_id)
- debug = self.data.get("debug")
- if not debug:
- application_version = QuerySet(ApplicationVersion).filter(application_id=application_id).order_by(
- '-create_time')[0:1].first()
- if application_version is None:
- raise AppApiException(500,
- _("The application has not been published. Please use it after publishing."))
- if application.type == ApplicationTypeChoices.SIMPLE:
- return self.open_simple(application)
- else:
- return self.open_work_flow(application)
- def open_work_flow(self, application):
- self.is_valid(raise_exception=True)
- application_id = self.data.get('application_id')
- chat_user_id = self.data.get("chat_user_id")
- chat_user_type = self.data.get("chat_user_type")
- ip_address = self.data.get("ip_address")
- source = self.data.get("source")
- debug = self.data.get("debug")
- chat_id = str(uuid.uuid7())
- ChatInfo(chat_id, chat_user_id, chat_user_type, ip_address, source, [],
- [],
- application_id, debug).set_cache()
- return chat_id
- def open_simple(self, application):
- application_id = self.data.get('application_id')
- chat_user_id = self.data.get("chat_user_id")
- chat_user_type = self.data.get("chat_user_type")
- ip_address = self.data.get("ip_address")
- source = self.data.get("source")
- debug = self.data.get("debug")
- knowledge_id_list = [str(row.target_id) for row in
- QuerySet(ResourceMapping).filter(source_id=str(application_id),
- source_type='APPLICATION',
- target_type='KNOWLEDGE')]
- chat_id = str(uuid.uuid7())
- ChatInfo(chat_id, chat_user_id, chat_user_type, ip_address, source, knowledge_id_list,
- [str(document.id) for document in
- QuerySet(Document).filter(
- knowledge_id__in=knowledge_id_list,
- is_active=False)],
- application_id,
- debug=debug).set_cache()
- return chat_id
- class TextToSpeechSerializers(serializers.Serializer):
- application_id = serializers.UUIDField(required=True, label=_("Application ID"))
- def text_to_speech(self, instance):
- self.is_valid(raise_exception=True)
- application_id = self.data.get('application_id')
- application = QuerySet(Application).filter(id=application_id).first()
- return ApplicationOperateSerializer(
- data={'application_id': application_id,
- 'user_id': application.user_id}).text_to_speech(instance, False)
- class SpeechToTextSerializers(serializers.Serializer):
- application_id = serializers.UUIDField(required=True, label=_("Application ID"))
- def speech_to_text(self, instance):
- self.is_valid(raise_exception=True)
- application_id = self.data.get('application_id')
- application = QuerySet(Application).filter(id=application_id).first()
- return ApplicationOperateSerializer(
- data={'application_id': application_id,
- 'user_id': application.user_id}).speech_to_text(instance, False)
|