diff --git a/src/api/chatcomplete.ts b/src/api/chatcomplete.ts index 53d6296..704a8d9 100644 --- a/src/api/chatcomplete.ts +++ b/src/api/chatcomplete.ts @@ -85,6 +85,12 @@ export type GetBotPersonaInfoParams = { export type GetBotPersonaInfoResponse = BotPersonaInfo +export type ChatCompleteStreamOutputEvents = { + onToolRun?: (toolName: string) => any, + onToolOutput?: (output: string) => any, + onMessage?: (deltaMessage: string) => any +} + export const chatCompleteApi = { indexPage(params: IndexPageParams, onProgress: IndexPageOnProgress): Promise { return new Promise((resolve, reject) => { @@ -184,7 +190,7 @@ export const chatCompleteApi = { return data.data }, - chatCompleteStreamOutput(taskId: string, onMessage: (deltaMessage: string) => any): Promise { + chatCompleteStreamOutput(taskId: string, eventListeners: ChatCompleteStreamOutputEvents = {}): Promise { return new Promise((resolve, reject) => { let url = getWebSocketApiUrl('/chatcomplete/message/stream', { task_id: taskId @@ -194,11 +200,15 @@ export const chatCompleteApi = { let ws = new WebSocket(url) ws.addEventListener('message', (event) => { if (event.data.startsWith('+')) { // 实时输出的消息是以+开头的纯文本 - onMessage(event.data.substring(1)) + eventListeners.onMessage?.(event.data.substring(1)) + } else if (event.data.startsWith('>')) { + eventListeners.onToolOutput?.(event.data.substring(1)) } else { // 其他消息是JSON格式 let data = JSON.parse(event.data) if (data.event === 'connected') { - onMessage(data.outputed_message) + eventListeners.onMessage?.(data.outputed_message) + } else if (data.event === 'tool_run') { + eventListeners.onToolRun?.(data.tool_name) } else if (data.event === 'finished') { isFinished = true resolve(data.result) diff --git a/src/components.d.ts b/src/components.d.ts index a525e74..66d8b30 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -12,6 +12,8 @@ declare module '@vue/runtime-core' { ChatCompleteSettingsModal: typeof import('./components/ChatCompleteSettingsModal.vue')['default'] ChatMessage: typeof import('./components/ChatMessage.vue')['default'] ConversationList: typeof import('./components/ConversationList.vue')['default'] + IonAccordion: typeof import('@ionic/vue')['IonAccordion'] + IonAccordionGroup: typeof import('@ionic/vue')['IonAccordionGroup'] IonApp: typeof import('@ionic/vue')['IonApp'] IonAvatar: typeof import('@ionic/vue')['IonAvatar'] IonButton: typeof import('@ionic/vue')['IonButton'] diff --git a/src/components/ChatMessage.vue b/src/components/ChatMessage.vue index 394dd98..e4efa6b 100644 --- a/src/components/ChatMessage.vue +++ b/src/components/ChatMessage.vue @@ -1,4 +1,5 @@