Skip to content

Commit e5e9939

Browse files
authored
feat: application chat debug (#3241)
1 parent 31838f8 commit e5e9939

File tree

7 files changed

+132
-53
lines changed

7 files changed

+132
-53
lines changed

apps/application/chat_pipeline/pipeline_manage.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717

1818
class PipelineManage:
1919
def __init__(self, step_list: List[Type[IBaseChatPipelineStep]],
20-
base_to_response: BaseToResponse = SystemToResponse()):
20+
base_to_response: BaseToResponse = SystemToResponse(),
21+
debug=False):
2122
# 步骤执行器
2223
self.step_list = [step() for step in step_list]
2324
# 上下文
2425
self.context = {'message_tokens': 0, 'answer_tokens': 0}
2526
self.base_to_response = base_to_response
27+
self.debug = debug
2628

2729
def run(self, context: Dict = None):
2830
self.context['start_time'] = time.time()
@@ -44,6 +46,7 @@ class builder:
4446
def __init__(self):
4547
self.step_list: List[Type[IBaseChatPipelineStep]] = []
4648
self.base_to_response = SystemToResponse()
49+
self.debug = False
4750

4851
def append_step(self, step: Type[IBaseChatPipelineStep]):
4952
self.step_list.append(step)
@@ -53,5 +56,9 @@ def add_base_to_response(self, base_to_response: BaseToResponse):
5356
self.base_to_response = base_to_response
5457
return self
5558

59+
def add_debug(self, debug):
60+
self.debug = debug
61+
return self
62+
5663
def build(self):
57-
return PipelineManage(step_list=self.step_list, base_to_response=self.base_to_response)
64+
return PipelineManage(step_list=self.step_list, base_to_response=self.base_to_response, debug=self.debug)

apps/application/flow/i_step_node.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@
1818
from rest_framework.exceptions import ValidationError, ErrorDetail
1919

2020
from application.flow.common import Answer, NodeChunk
21-
from application.models import ChatRecord, ChatUserType
2221
from application.models import ApplicationChatUserStats
23-
from common.constants.authentication_type import AuthenticationType
22+
from application.models import ChatRecord, ChatUserType
2423
from common.field.common import InstanceField
2524

2625
chat_cache = cache
@@ -45,16 +44,14 @@ def is_interrupt(node, step_variable: Dict, global_variable: Dict):
4544

4645

4746
class WorkFlowPostHandler:
48-
def __init__(self, chat_info, chat_user_id, chat_user_type):
47+
def __init__(self, chat_info):
4948
self.chat_info = chat_info
50-
self.chat_user_id = chat_user_id
51-
self.chat_user_type = chat_user_type
52-
53-
def handler(self, chat_id,
54-
chat_record_id,
55-
answer,
56-
workflow):
57-
question = workflow.params['question']
49+
50+
def handler(self, workflow):
51+
workflow_body = workflow.get_body()
52+
question = workflow_body.get('question')
53+
chat_record_id = workflow_body.get('chat_record_id')
54+
chat_id = workflow_body.get('chat_id')
5855
details = workflow.get_runtime_details()
5956
message_tokens = sum([row.get('message_tokens') for row in details.values() if
6057
'message_tokens' in row and row.get('message_tokens') is not None])
@@ -83,14 +80,14 @@ def handler(self, chat_id,
8380
answer_text_list=answer_text_list,
8481
run_time=time.time() - workflow.context['start_time'],
8582
index=0)
86-
asker = workflow.context.get('asker', None)
83+
8784
self.chat_info.append_chat_record(chat_record)
8885
self.chat_info.set_cahce()
8986
if [ChatUserType.ANONYMOUS_USER.value, ChatUserType.CHAT_USER.value].__contains__(
90-
self.chat_user_type):
87+
workflow_body.get('chat_user_type')):
9188
application_public_access_client = (QuerySet(ApplicationChatUserStats)
92-
.filter(chat_user_id=self.chat_user_id,
93-
chat_user_type=self.chat_user_type,
89+
.filter(chat_user_id=workflow_body.get('chat_user_id'),
90+
chat_user_type=workflow_body.get('chat_user_type'),
9491
application_id=self.chat_info.application.id).first())
9592
if application_public_access_client is not None:
9693
application_public_access_client.access_num = application_public_access_client.access_num + 1
@@ -141,13 +138,16 @@ class FlowParamsSerializer(serializers.Serializer):
141138

142139
stream = serializers.BooleanField(required=True, label="流式输出")
143140

144-
client_id = serializers.CharField(required=False, label="客户端id")
141+
chat_user_id = serializers.CharField(required=False, label="对话用户id")
142+
143+
chat_user_type = serializers.CharField(required=False, label="对话用户类型")
145144

146-
client_type = serializers.CharField(required=False, label="客户端类型")
145+
workspace_id = serializers.CharField(required=True, label="工作空间id")
147146

148-
user_id = serializers.UUIDField(required=True, label="用户id")
149147
re_chat = serializers.BooleanField(required=True, label="换个答案")
150148

149+
debug = serializers.BooleanField(required=True, label="是否debug")
150+
151151

152152
class INode:
153153
view_type = 'many_view'

apps/application/flow/workflow_manage.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,7 @@ def run_block(self, language='zh'):
367367
'\n\n'.join([a.get('content') for a in answer]) for answer in
368368
answer_text_list)
369369
answer_list = reduce(lambda pre, _n: [*pre, *_n], answer_text_list, [])
370-
self.work_flow_post_handler.handler(self.params['chat_id'], self.params['chat_record_id'],
371-
answer_text,
372-
self)
370+
self.work_flow_post_handler.handler(self)
373371
return self.base_to_response.to_block_response(self.params['chat_id'],
374372
self.params['chat_record_id'], answer_text, True
375373
, message_tokens, answer_tokens,
@@ -384,6 +382,9 @@ def run_stream(self, current_node, node_result_future, language='zh'):
384382
self.run_chain_async(current_node, node_result_future, language)
385383
return tools.to_stream_response_simple(self.await_result())
386384

385+
def get_body(self):
386+
return self.params
387+
387388
def is_run(self, timeout=0.5):
388389
future_list_len = len(self.future_list)
389390
try:
@@ -420,9 +421,7 @@ def await_result(self):
420421
'message_tokens' in row and row.get('message_tokens') is not None])
421422
answer_tokens = sum([row.get('answer_tokens') for row in details.values() if
422423
'answer_tokens' in row and row.get('answer_tokens') is not None])
423-
self.work_flow_post_handler.handler(self.params['chat_id'], self.params['chat_record_id'],
424-
self.answer,
425-
self)
424+
self.work_flow_post_handler.handler(self)
426425
yield self.base_to_response.to_stream_chunk_response(self.params['chat_id'],
427426
self.params['chat_record_id'],
428427
'',

apps/application/serializers/common.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,30 @@ def __init__(self,
2727
chat_user_type: str,
2828
knowledge_id_list: List[str],
2929
exclude_document_id_list: list[str],
30+
application_id: str,
3031
application: Application,
31-
work_flow_version: WorkFlowVersion = None):
32+
work_flow_version: WorkFlowVersion = None,
33+
debug=False):
3234
"""
33-
:param chat_id: 对话id
35+
:param chat_id: 对话id
3436
:param chat_user_id 对话用户id
3537
:param chat_user_type 对话用户类型
3638
:param knowledge_id_list: 知识库列表
3739
:param exclude_document_id_list: 排除的文档
40+
:param application_id 应用id
3841
:param application: 应用信息
42+
:param debug 是否是调试
3943
"""
4044
self.chat_id = chat_id
4145
self.chat_user_id = chat_user_id
4246
self.chat_user_type = chat_user_type
4347
self.application = application
4448
self.knowledge_id_list = knowledge_id_list
4549
self.exclude_document_id_list = exclude_document_id_list
50+
self.application_id = application_id
4651
self.chat_record_list: List[ChatRecord] = []
4752
self.work_flow_version = work_flow_version
53+
self.debug = debug
4854

4955
@staticmethod
5056
def get_no_references_setting(knowledge_setting, model_setting):
@@ -116,17 +122,17 @@ def append_chat_record(self, chat_record: ChatRecord):
116122
if record.id == chat_record.id:
117123
self.chat_record_list[index] = chat_record
118124
is_save = False
125+
break
119126
if is_save:
120127
self.chat_record_list.append(chat_record)
121-
cache.set(Cache_Version.CHAT.get_key(key=self.chat_id), self, version=Cache_Version.CHAT.get_version(),
122-
timeout=60 * 30)
123-
if self.application.id is not None:
124-
Chat(id=self.chat_id, application_id=self.application.id, abstract=chat_record.problem_text[0:1024],
125-
chat_user_id=self.chat_user_id, chat_user_type=self.chat_user_type).save()
126-
else:
127-
QuerySet(Chat).filter(id=self.chat_id).update(update_time=datetime.now())
128+
if not self.debug:
129+
if not QuerySet(Chat).filter(id=self.chat_id).exists():
130+
Chat(id=self.chat_id, application_id=self.application.id, abstract=chat_record.problem_text[0:1024],
131+
chat_user_id=self.chat_user_id, chat_user_type=self.chat_user_type).save()
132+
else:
133+
QuerySet(Chat).filter(id=self.chat_id).update(update_time=datetime.now())
128134
# 插入会话记录
129-
chat_record.save()
135+
chat_record.save()
130136

131137
def set_cache(self):
132138
cache.set(Cache_Version.CHAT.get_key(key=self.chat_id), self, version=Cache_Version.CHAT.get_version(),

apps/application/urls.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,7 @@
5252
path(
5353
'workspace/<str:workspace_id>/application/<str:application_id>/work_flow_version/<str:work_flow_version_id>',
5454
views.ApplicationVersionView.Operate.as_view()),
55+
path('workspace/<str:workspace_id>/application/<str:application_id>/open', views.OpenView.as_view()),
56+
path('chat_message/<str:chat_id>', views.ChatView.as_view()),
57+
5558
]

apps/application/views/application_chat.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,20 @@
66
@date:2025/6/10 11:00
77
@desc:
88
"""
9+
import uuid
10+
911
from django.utils.translation import gettext_lazy as _
1012
from drf_spectacular.utils import extend_schema
1113
from rest_framework.request import Request
1214
from rest_framework.views import APIView
1315

1416
from application.api.application_chat import ApplicationChatQueryAPI, ApplicationChatQueryPageAPI, \
1517
ApplicationChatExportAPI
18+
from application.models import ChatUserType
1619
from application.serializers.application_chat import ApplicationChatQuerySerializers
20+
from chat.api.chat_api import ChatAPI
21+
from chat.api.chat_authentication_api import ChatOpenAPI
22+
from chat.serializers.chat import OpenChatSerializers, ChatSerializers, DebugChatSerializers
1723
from common.auth import TokenAuth
1824
from common.auth.authentication import has_permissions
1925
from common.constants.permission_constants import PermissionConstants, RoleConstants
@@ -81,3 +87,39 @@ def post(self, request: Request, workspace_id: str, application_id: str):
8187
return ApplicationChatQuerySerializers(
8288
data={**query_params_to_single_dict(request.query_params), 'application_id': application_id,
8389
}).export(request.data)
90+
91+
92+
class OpenView(APIView):
93+
authentication_classes = [TokenAuth]
94+
95+
@extend_schema(
96+
methods=['GET'],
97+
description=_("Get a temporary session id based on the application id"),
98+
summary=_("Get a temporary session id based on the application id"),
99+
operation_id=_("Get a temporary session id based on the application id"), # type: ignore
100+
parameters=ChatOpenAPI.get_parameters(),
101+
responses=None,
102+
tags=[_('Application')] # type: ignore
103+
)
104+
def get(self, request: Request, workspace_id: str, application_id: str):
105+
return result.success(OpenChatSerializers(
106+
data={'workspace_id': workspace_id, 'application_id': application_id,
107+
'chat_user_id': str(uuid.uuid1()), 'chat_user_type': ChatUserType.ANONYMOUS_USER,
108+
'debug': True}).open())
109+
110+
111+
class ChatView(APIView):
112+
authentication_classes = [TokenAuth]
113+
114+
@extend_schema(
115+
methods=['POST'],
116+
description=_("dialogue"),
117+
summary=_("dialogue"),
118+
operation_id=_("dialogue"), # type: ignore
119+
request=ChatAPI.get_request(),
120+
parameters=ChatAPI.get_parameters(),
121+
responses=None,
122+
tags=[_('Application')] # type: ignore
123+
)
124+
def post(self, request: Request, chat_id: str):
125+
return DebugChatSerializers(data={'chat_id': chat_id}).chat(request.data)

apps/chat/serializers/chat.py

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,27 @@ def handler(self,
9494
return PostHandler()
9595

9696

97+
class DebugChatSerializers(serializers.Serializer):
98+
chat_id = serializers.UUIDField(required=True, label=_("Conversation ID"))
99+
100+
def chat(self, instance: dict, base_to_response: BaseToResponse = SystemToResponse()):
101+
self.is_valid(raise_exception=True)
102+
chat_id = self.data.get('chat_id')
103+
chat_info: ChatInfo = ChatInfo.get_cache(chat_id)
104+
return ChatSerializers(data={
105+
'chat_id': chat_id, "chat_user_id": chat_info.chat_user_id,
106+
"chat_user_type": chat_info.chat_user_type,
107+
"application_id": chat_info.application.id, "debug": True
108+
}).chat(instance, base_to_response)
109+
110+
97111
class ChatSerializers(serializers.Serializer):
98112
chat_id = serializers.UUIDField(required=True, label=_("Conversation ID"))
99113
chat_user_id = serializers.CharField(required=True, label=_("Client id"))
100114
chat_user_type = serializers.CharField(required=True, label=_("Client Type"))
101115
application_id = serializers.UUIDField(required=True, allow_null=True,
102116
label=_("Application ID"))
117+
debug = serializers.BooleanField(required=False, label=_("Debug"))
103118

104119
def is_valid_application_workflow(self, *, raise_exception=False):
105120
self.is_valid_intraday_access_num()
@@ -158,6 +173,7 @@ def chat_simple(self, chat_info: ChatInfo, instance, base_to_response):
158173
.append_step(BaseGenerateHumanMessageStep)
159174
.append_step(BaseChatStep)
160175
.add_base_to_response(base_to_response)
176+
.add_debug(self.data.get('debug', False))
161177
.build())
162178
exclude_paragraph_id_list = []
163179
# 相同问题是否需要排除已经查询到的段落
@@ -189,18 +205,18 @@ def get_chat_record(chat_info, chat_record_id):
189205
return chat_record
190206

191207
def chat_work_flow(self, chat_info: ChatInfo, instance: dict, base_to_response):
192-
message = self.data.get('message')
193-
re_chat = self.data.get('re_chat')
194-
stream = self.data.get('stream')
195-
chat_user_id = instance.get('chat_user_id')
196-
chat_user_type = instance.get('chat_user_type')
197-
form_data = self.data.get('form_data')
198-
image_list = self.data.get('image_list')
199-
document_list = self.data.get('document_list')
200-
audio_list = self.data.get('audio_list')
201-
other_list = self.data.get('other_list')
202-
user_id = chat_info.application.user_id
203-
chat_record_id = self.data.get('chat_record_id')
208+
message = instance.get('message')
209+
re_chat = instance.get('re_chat')
210+
stream = instance.get('stream')
211+
chat_user_id = self.data.get("chat_user_id")
212+
chat_user_type = self.data.get('chat_user_type')
213+
form_data = instance.get('form_data')
214+
image_list = instance.get('image_list')
215+
document_list = instance.get('document_list')
216+
audio_list = instance.get('audio_list')
217+
other_list = instance.get('other_list')
218+
workspace_id = chat_info.application.workspace_id
219+
chat_record_id = instance.get('chat_record_id')
204220
chat_record = None
205221
history_chat_record = chat_info.chat_record_list
206222
if chat_record_id is not None:
@@ -214,8 +230,9 @@ def chat_work_flow(self, chat_info: ChatInfo, instance: dict, base_to_response):
214230
're_chat': re_chat,
215231
'chat_user_id': chat_user_id,
216232
'chat_user_type': chat_user_type,
217-
'user_id': user_id},
218-
WorkFlowPostHandler(chat_info, chat_user_id, chat_user_type),
233+
'workspace_id': workspace_id,
234+
'debug': self.data.get('debug', False)},
235+
WorkFlowPostHandler(chat_info),
219236
base_to_response, form_data, image_list, document_list, audio_list,
220237
other_list,
221238
self.data.get('runtime_node_id'),
@@ -229,7 +246,7 @@ def chat(self, instance: dict, base_to_response: BaseToResponse = SystemToRespon
229246
chat_info = self.get_chat_info()
230247
self.is_valid_chat_id(chat_info)
231248
if chat_info.application.type == ApplicationTypeChoices.SIMPLE:
232-
self.is_valid_application_simple(raise_exception=True, chat_info=chat_info),
249+
self.is_valid_application_simple(raise_exception=True, chat_info=chat_info)
233250
return self.chat_simple(chat_info, instance, base_to_response)
234251
else:
235252
self.is_valid_application_workflow(raise_exception=True)
@@ -295,6 +312,7 @@ class OpenChatSerializers(serializers.Serializer):
295312
application_id = serializers.UUIDField(required=True)
296313
chat_user_id = serializers.CharField(required=True, label=_("Client id"))
297314
chat_user_type = serializers.CharField(required=True, label=_("Client Type"))
315+
debug = serializers.BooleanField(required=True, label=_("Debug"))
298316

299317
def is_valid(self, *, raise_exception=False):
300318
super().is_valid(raise_exception=True)
@@ -317,6 +335,7 @@ def open_work_flow(self, application):
317335
application_id = self.data.get('application_id')
318336
chat_user_id = self.data.get("chat_user_id")
319337
chat_user_type = self.data.get("chat_user_type")
338+
debug = self.data.get("debug")
320339
chat_id = str(uuid.uuid7())
321340
work_flow_version = QuerySet(WorkFlowVersion).filter(application_id=application_id).order_by(
322341
'-create_time')[0:1].first()
@@ -326,13 +345,15 @@ def open_work_flow(self, application):
326345
"The application has not been published. Please use it after publishing."))
327346
ChatInfo(chat_id, chat_user_id, chat_user_type, [],
328347
[],
329-
application, work_flow_version).set_cache()
348+
application_id,
349+
application, work_flow_version, debug).set_cache()
330350
return chat_id
331351

332352
def open_simple(self, application):
333353
application_id = self.data.get('application_id')
334354
chat_user_id = self.data.get("chat_user_id")
335355
chat_user_type = self.data.get("chat_user_type")
356+
debug = self.data.get("debug")
336357
knowledge_id_list = [str(row.dataset_id) for row in
337358
QuerySet(ApplicationKnowledgeMapping).filter(
338359
application_id=application_id)]
@@ -342,5 +363,6 @@ def open_simple(self, application):
342363
QuerySet(Document).filter(
343364
knowledge_id__in=knowledge_id_list,
344365
is_active=False)],
345-
application).set_cache()
366+
application_id,
367+
application, debug=debug).set_cache()
346368
return chat_id

0 commit comments

Comments
 (0)