Skip to content

Commit f74309e

Browse files
committed
feat: simple application debug chat
1 parent 14ae786 commit f74309e

File tree

15 files changed

+267
-116
lines changed

15 files changed

+267
-116
lines changed

apps/application/serializers/application.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -704,14 +704,14 @@ def one(self, with_valid=True):
704704
self.is_valid()
705705
application_id = self.data.get("application_id")
706706
application = QuerySet(Application).get(id=application_id)
707-
dataset_list = self.list_knowledge(with_valid=False)
707+
knowledge_list = self.list_knowledge(with_valid=False)
708708
mapping_knowledge_id_list = [akm.knowledge_id for akm in
709709
QuerySet(ApplicationKnowledgeMapping).filter(application_id=application_id)]
710710
knowledge_id_list = [d.get('id') for d in
711711
list(filter(lambda row: mapping_knowledge_id_list.__contains__(row.get('id')),
712-
dataset_list))]
712+
knowledge_list))]
713713
return {**ApplicationSerializerModel(application).data,
714-
'dataset_id_list': knowledge_id_list}
714+
'knowledge_id_list': knowledge_id_list}
715715

716716
def list_knowledge(self, with_valid=True):
717717
if with_valid:

apps/application/serializers/application_chat_record.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
from rest_framework import serializers
1616
from rest_framework.utils.formatting import lazy_format
1717

18-
from application.models import ChatRecord
18+
from application.models import ChatRecord, ApplicationAccessToken
19+
from application.serializers.common import ChatInfo
1920
from common.db.search import page_search
2021
from common.exception.app_exception import AppApiException
2122
from common.utils.common import post
@@ -37,6 +38,40 @@ class Meta:
3738
'create_time', 'update_time']
3839

3940

41+
class ChatRecordOperateSerializer(serializers.Serializer):
42+
chat_id = serializers.UUIDField(required=True, label=_("Conversation ID"))
43+
workspace_id = serializers.CharField(required=False, label=_("Workspace ID"))
44+
application_id = serializers.UUIDField(required=True, label=_("Application ID"))
45+
chat_record_id = serializers.UUIDField(required=True, label=_("Conversation record id"))
46+
47+
def is_valid(self, *, debug=False, raise_exception=False):
48+
super().is_valid(raise_exception=True)
49+
application_access_token = QuerySet(ApplicationAccessToken).filter(
50+
application_id=self.data.get('application_id')).first()
51+
if application_access_token is None:
52+
raise AppApiException(500, gettext('Application authentication information does not exist'))
53+
if not application_access_token.show_source and not debug:
54+
raise AppApiException(500, gettext('Displaying knowledge sources is not enabled'))
55+
56+
def get_chat_record(self):
57+
chat_record_id = self.data.get('chat_record_id')
58+
chat_id = self.data.get('chat_id')
59+
chat_info: ChatInfo = ChatInfo.get_cache(chat_id)
60+
if chat_info is not None:
61+
chat_record_list = [chat_record for chat_record in chat_info.chat_record_list if
62+
str(chat_record.id) == str(chat_record_id)]
63+
if chat_record_list is not None and len(chat_record_list):
64+
return chat_record_list[-1]
65+
return QuerySet(ChatRecord).filter(id=chat_record_id, chat_id=chat_id).first()
66+
67+
def one(self, debug):
68+
self.is_valid(debug=debug, raise_exception=True)
69+
chat_record = self.get_chat_record()
70+
if chat_record is None:
71+
raise AppApiException(500, gettext("Conversation does not exist"))
72+
return ApplicationChatRecordQuerySerializers.reset_chat_record(chat_record)
73+
74+
4075
class ApplicationChatRecordQuerySerializers(serializers.Serializer):
4176
application_id = serializers.UUIDField(required=True, label=_("Application ID"))
4277
chat_id = serializers.UUIDField(required=True, label=_("Chat ID"))

apps/application/urls.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
path(
3535
'workspace/<str:workspace_id>/application/<str:application_id>/chat/<str:chat_id>/chat_record',
3636
views.ApplicationChatRecord.as_view()),
37+
path(
38+
'workspace/<str:workspace_id>/application/<str:application_id>/chat/<str:chat_id>/chat_record/<str:chat_record_id>',
39+
views.ApplicationChatRecordOperateAPI.as_view()),
3740
path(
3841
'workspace/<str:workspace_id>/application/<str:application_id>/chat/<str:chat_id>/chat_record/<int:current_page>/<int:page_size>',
3942
views.ApplicationChatRecord.Page.as_view()),

apps/application/views/application_chat_record.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
from application.api.application_chat_record import ApplicationChatRecordQueryAPI, \
1515
ApplicationChatRecordImproveParagraphAPI, ApplicationChatRecordAddKnowledgeAPI
1616
from application.serializers.application_chat_record import ApplicationChatRecordQuerySerializers, \
17-
ApplicationChatRecordImproveSerializer, ChatRecordImproveSerializer, ApplicationChatRecordAddKnowledgeSerializer
17+
ApplicationChatRecordImproveSerializer, ChatRecordImproveSerializer, ApplicationChatRecordAddKnowledgeSerializer, \
18+
ChatRecordOperateSerializer
1819
from common import result
1920
from common.auth import TokenAuth
2021
from common.auth.authentication import has_permissions
@@ -67,6 +68,30 @@ def get(self, request: Request, workspace_id: str, application_id: str, chat_id:
6768
page_size=page_size))
6869

6970

71+
class ApplicationChatRecordOperateAPI(APIView):
72+
authentication_classes = [TokenAuth]
73+
74+
@extend_schema(
75+
methods=['GET'],
76+
description=_("Get conversation record details"),
77+
summary=_("Get conversation record details"),
78+
operation_id=_("Get conversation record details"), # type: ignore
79+
request=ApplicationChatRecordQueryAPI.get_request(),
80+
parameters=ApplicationChatRecordQueryAPI.get_parameters(),
81+
responses=ApplicationChatRecordQueryAPI.get_response(),
82+
tags=[_("Application/Conversation Log")] # type: ignore
83+
)
84+
@has_permissions(PermissionConstants.APPLICATION_CHAT_LOG.get_workspace_application_permission(),
85+
RoleConstants.WORKSPACE_MANAGE.get_workspace_role())
86+
def get(self, request: Request, workspace_id: str, application_id: str, chat_id: str, chat_record_id: str):
87+
return result.success(ChatRecordOperateSerializer(
88+
data={
89+
'workspace_id': workspace_id,
90+
'application_id': application_id,
91+
'chat_id': chat_id,
92+
'chat_record_id': chat_record_id}).one(True))
93+
94+
7095
class ApplicationChatRecordAddKnowledge(APIView):
7196
authentication_classes = [TokenAuth]
7297

apps/chat/serializers/chat.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ def chat(self, instance: dict, base_to_response: BaseToResponse = SystemToRespon
101101
self.is_valid(raise_exception=True)
102102
chat_id = self.data.get('chat_id')
103103
chat_info: ChatInfo = ChatInfo.get_cache(chat_id)
104+
application = QuerySet(Application).filter(id=chat_info.application_id).first()
105+
chat_info.application = application
104106
return ChatSerializers(data={
105107
'chat_id': chat_id, "chat_user_id": chat_info.chat_user_id,
106108
"chat_user_type": chat_info.chat_user_type,

ui/src/api/application/application.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,27 @@ const getStatistics: (
140140
) => Promise<Result<any>> = (application_id, data, loading) => {
141141
return get(`${prefix}/${application_id}/application_stats`, data, loading)
142142
}
143+
/**
144+
* 打开调试对话id
145+
* @param application_id 应用id
146+
* @param loading 加载器
147+
* @returns
148+
*/
149+
const open: (application_id: string, loading?: Ref<boolean>) => Promise<Result<string>> = (
150+
application_id,
151+
loading,
152+
) => {
153+
return get(`${prefix}/${application_id}/open`, {}, loading)
154+
}
155+
/**
156+
* 对话
157+
* @param 参数
158+
* chat_id: string
159+
* data
160+
*/
161+
const chat: (chat_id: string, data: any) => Promise<any> = (chat_id, data) => {
162+
return postStream(`/api/chat_message/${chat_id}`, data)
163+
}
143164

144165
export default {
145166
getAllApplication,
@@ -153,4 +174,6 @@ export default {
153174
exportApplication,
154175
importApplication,
155176
getStatistics,
177+
open,
178+
chat,
156179
}

ui/src/api/application/chat-log.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,18 @@ const postExportChatLog: (
188188
loading,
189189
)
190190
}
191-
191+
const getChatRecordDetails: (
192+
application_id: string,
193+
chat_id: string,
194+
chat_record_id: string,
195+
loading?: Ref<boolean>,
196+
) => Promise<any> = (application_id, chat_id, chat_record_id, loading) => {
197+
return get(
198+
`${prefix}/${application_id}/chat/${chat_id}/chat_record/${chat_record_id}`,
199+
{},
200+
loading,
201+
)
202+
}
192203
export default {
193204
postChatLogAddKnowledge,
194205
getChatLog,
@@ -197,4 +208,5 @@ export default {
197208
putChatRecordLog,
198209
delMarkChatRecord,
199210
postExportChatLog,
211+
getChatRecordDetails,
200212
}

ui/src/api/model/model.ts

Lines changed: 79 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import {Result} from '@/request/Result'
2-
import {get, post, del, put} from '@/request/index'
3-
import {type Ref} from 'vue'
1+
import { Result } from '@/request/Result'
2+
import { get, post, del, put } from '@/request/index'
3+
import { type Ref } from 'vue'
44
import type {
55
ListModelRequest,
66
Model,
77
CreateModelRequest,
88
EditModelRequest,
99
} from '@/api/type/model'
10-
import type {FormField} from '@/components/dynamics-form/type'
10+
import type { FormField } from '@/components/dynamics-form/type'
1111

1212
const prefix = '/workspace/' + localStorage.getItem('workspace_id')
1313

@@ -21,7 +21,61 @@ const getModel: (
2121
) => Promise<Result<Array<Model>>> = (data, loading) => {
2222
return get(`${prefix}/model`, data, loading)
2323
}
24+
/**
25+
* 获取当前用户可使用的模型列表
26+
* @param application_id
27+
* @param loading
28+
* @query { query_text: string, top_number: number, similarity: number }
29+
* @returns
30+
*/
31+
const getApplicationRerankerModel: (
32+
application_id: string,
33+
loading?: Ref<boolean>,
34+
) => Promise<Result<Array<any>>> = (application_id, loading) => {
35+
return get(`${prefix}/model`, { model_type: 'RERANKER' }, loading)
36+
}
2437

38+
/**
39+
* 获取当前用户可使用的模型列表
40+
* @param application_id
41+
* @param loading
42+
* @query { query_text: string, top_number: number, similarity: number }
43+
* @returns
44+
*/
45+
const getApplicationSTTModel: (
46+
application_id: string,
47+
loading?: Ref<boolean>,
48+
) => Promise<Result<Array<any>>> = (application_id, loading) => {
49+
return get(`${prefix}/model`, { model_type: 'STT' }, loading)
50+
}
51+
52+
/**
53+
* 获取当前用户可使用的模型列表
54+
* @param application_id
55+
* @param loading
56+
* @query { query_text: string, top_number: number, similarity: number }
57+
* @returns
58+
*/
59+
const getApplicationTTSModel: (
60+
application_id: string,
61+
loading?: Ref<boolean>,
62+
) => Promise<Result<Array<any>>> = (application_id, loading) => {
63+
return get(`${prefix}/model`, { model_type: 'TTS' }, loading)
64+
}
65+
66+
const getApplicationImageModel: (
67+
application_id: string,
68+
loading?: Ref<boolean>,
69+
) => Promise<Result<Array<any>>> = (application_id, loading) => {
70+
return get(`${prefix}/model`, { model_type: 'IMAGE' }, loading)
71+
}
72+
73+
const getApplicationTTIModel: (
74+
application_id: string,
75+
loading?: Ref<boolean>,
76+
) => Promise<Result<Array<any>>> = (application_id, loading) => {
77+
return get(`${prefix}/model`, { model_type: 'TTI' }, loading)
78+
}
2579
/**
2680
* 获取模型参数表单
2781
* @param model_id 模型id
@@ -82,10 +136,10 @@ const updateModelParamsForm: (
82136
* @param loading 加载器
83137
* @returns
84138
*/
85-
const getModelById: (
86-
model_id: string,
87-
loading?: Ref<boolean>,
88-
) => Promise<Result<Model>> = (model_id, loading) => {
139+
const getModelById: (model_id: string, loading?: Ref<boolean>) => Promise<Result<Model>> = (
140+
model_id,
141+
loading,
142+
) => {
89143
return get(`${prefix}/model/${model_id}`, {}, loading)
90144
}
91145
/**
@@ -94,10 +148,10 @@ const getModelById: (
94148
* @param loading 加载器
95149
* @returns
96150
*/
97-
const getModelMetaById: (
98-
model_id: string,
99-
loading?: Ref<boolean>,
100-
) => Promise<Result<Model>> = (model_id, loading) => {
151+
const getModelMetaById: (model_id: string, loading?: Ref<boolean>) => Promise<Result<Model>> = (
152+
model_id,
153+
loading,
154+
) => {
101155
return get(`${prefix}/model/${model_id}/meta`, {}, loading)
102156
}
103157
/**
@@ -106,16 +160,16 @@ const getModelMetaById: (
106160
* @param loading 加载器
107161
* @returns
108162
*/
109-
const pauseDownload: (
110-
model_id: string,
111-
loading?: Ref<boolean>,
112-
) => Promise<Result<boolean>> = (model_id, loading) => {
163+
const pauseDownload: (model_id: string, loading?: Ref<boolean>) => Promise<Result<boolean>> = (
164+
model_id,
165+
loading,
166+
) => {
113167
return put(`${prefix}/model/${model_id}/pause_download`, undefined, {}, loading)
114168
}
115-
const deleteModel: (
116-
model_id: string,
117-
loading?: Ref<boolean>,
118-
) => Promise<Result<boolean>> = (model_id, loading) => {
169+
const deleteModel: (model_id: string, loading?: Ref<boolean>) => Promise<Result<boolean>> = (
170+
model_id,
171+
loading,
172+
) => {
119173
return del(`${prefix}/model/${model_id}`, undefined, {}, loading)
120174
}
121175
export default {
@@ -128,4 +182,9 @@ export default {
128182
pauseDownload,
129183
getModelParamsForm,
130184
updateModelParamsForm,
185+
getApplicationRerankerModel,
186+
getApplicationSTTModel,
187+
getApplicationTTSModel,
188+
getApplicationImageModel,
189+
getApplicationTTIModel,
131190
}

0 commit comments

Comments
 (0)