From 6307e09dc3f14815b2f51efcbf2e73d37355a48f Mon Sep 17 00:00:00 2001 From: Emily Date: Fri, 13 Dec 2024 15:07:34 +0100 Subject: [PATCH] fix chat streaming + add "deleted" field to chats --- dashboard/composables/useCustomFetch.ts | 2 +- dashboard/pages/analyst.vue | 20 +++++++++------- dashboard/server/api/ai/[chat_id]/delete.ts | 8 +++---- dashboard/server/api/ai/chats_list.ts | 2 +- dashboard/server/api/ai/send_message.post.ts | 4 ++-- dashboard/server/services/AiService.ts | 24 ++++++++++++-------- shared/schema/ai/AiChatSchema.ts | 2 ++ 7 files changed, 36 insertions(+), 26 deletions(-) diff --git a/dashboard/composables/useCustomFetch.ts b/dashboard/composables/useCustomFetch.ts index b301db1..9c25f7a 100644 --- a/dashboard/composables/useCustomFetch.ts +++ b/dashboard/composables/useCustomFetch.ts @@ -26,7 +26,7 @@ export function useComputedHeaders(customOptions?: CustomOptions) { const useTimeOffset = customOptions?.useTimeOffset || true; const headers = computed>(() => { - console.trace('Computed recalculated'); + // console.trace('Computed recalculated'); const parsedCustom: Record = {} const customKeys = Object.keys(customOptions?.custom || {}); for (const key of customKeys) { diff --git a/dashboard/pages/analyst.vue b/dashboard/pages/analyst.vue index c1b5ef1..8fde690 100644 --- a/dashboard/pages/analyst.vue +++ b/dashboard/pages/analyst.vue @@ -24,8 +24,14 @@ const currentChatId = ref(""); const currentChatMessages = ref<{ role: string, content: string, charts?: any[] }[]>([]); const currentChatMessageDelta = ref(''); -const scroller = ref(null); +const currentChatMessageDeltaHtml = computed(() => { + const lastData = currentChatMessageDelta.value.match(/\[(data:(.*?))\]/g); + const cleanMessage = currentChatMessageDelta.value.replace(/\[(data:(.*?))\]/g, ''); + if (!lastData || lastData.length == 0) return cleanMessage; + return `
LOADER HERE: ${lastData.at(-1)} ${cleanMessage}
`; +}); +const scroller = ref(null); async function pollSendMessageStatus(chat_id: string, times: number, updateStatus: (status: string) => any) { @@ -46,7 +52,7 @@ async function pollSendMessageStatus(chat_id: string, times: number, updateStatu } else { currentChatMessages.value.push({ role: 'assistant', - content: currentChatMessageDelta.value.replace(/\[data:.*?\]/g,''), + content: currentChatMessageDelta.value.replace(/\[data:.*?\]/g, ''), }); currentChatMessageDelta.value = ''; @@ -75,8 +81,6 @@ async function sendMessage() { const res = await $fetch<{ chat_id: string }>(`/api/ai/send_message`, { method: 'POST', body: JSON.stringify(body), headers: useComputedHeaders({ useSnapshotDates: false, custom: { 'Content-Type': 'application/json' } }).value }); currentChatId.value = res.chat_id; - currentChatMessages.value.push({ role: 'assistant', content: '', charts: [] }); - await reloadChatsRemaining(); await reloadChatsList(); @@ -237,16 +241,16 @@ const { visible: pricingDrawerVisible } = usePricingDrawer() - - -
- {{ currentChatMessageDelta.replace(/\[(data:(.*?))\]/g, 'Processing: $2\n') }} +
diff --git a/dashboard/server/api/ai/[chat_id]/delete.ts b/dashboard/server/api/ai/[chat_id]/delete.ts index 87b62cc..f7833c0 100644 --- a/dashboard/server/api/ai/[chat_id]/delete.ts +++ b/dashboard/server/api/ai/[chat_id]/delete.ts @@ -1,4 +1,4 @@ -import { getUserProjectFromId } from "~/server/LIVE_DEMO_DATA"; + import { AiChatModel } from "@schema/ai/AiChatSchema"; export default defineEventHandler(async event => { @@ -7,10 +7,10 @@ export default defineEventHandler(async event => { if (!data) return; const { project_id } = data; - + if (!event.context.params) return; const chat_id = event.context.params['chat_id']; - const result = await AiChatModel.deleteOne({ _id: chat_id, project_id }); - return result.deletedCount > 0; + const result = await AiChatModel.updateOne({ _id: chat_id, project_id }, { deleted: true }); + return result.modifiedCount > 0; }); \ No newline at end of file diff --git a/dashboard/server/api/ai/chats_list.ts b/dashboard/server/api/ai/chats_list.ts index c0c1dcc..c81d4af 100644 --- a/dashboard/server/api/ai/chats_list.ts +++ b/dashboard/server/api/ai/chats_list.ts @@ -9,7 +9,7 @@ export default defineEventHandler(async event => { const { project_id } = data; - const chatList = await AiChatModel.find({ project_id }, { _id: 1, title: 1 }, { sort: { updated_at: 1 } }); + const chatList = await AiChatModel.find({ project_id, deleted: false }, { _id: 1, title: 1 }, { sort: { updated_at: 1 } }); return chatList.map(e => e.toJSON()); diff --git a/dashboard/server/api/ai/send_message.post.ts b/dashboard/server/api/ai/send_message.post.ts index 408d7f4..d89dd04 100644 --- a/dashboard/server/api/ai/send_message.post.ts +++ b/dashboard/server/api/ai/send_message.post.ts @@ -47,8 +47,8 @@ export default defineEventHandler(async event => { await updateChatStatus(targetChatId, currentStatus.join(''), false); }, onFinish: async calls => { - currentStatus.push('[data:FunctionFinish]'); - await updateChatStatus(targetChatId, currentStatus.join(''), false); + // currentStatus.push('[data:FunctionFinish]'); + // await updateChatStatus(targetChatId, currentStatus.join(''), false); } }); diff --git a/dashboard/server/services/AiService.ts b/dashboard/server/services/AiService.ts index f054fe5..65fc4a1 100644 --- a/dashboard/server/services/AiService.ts +++ b/dashboard/server/services/AiService.ts @@ -128,6 +128,15 @@ async function elaborateResponse(messages: OpenAI.Chat.Completions.ChatCompletio functionCall.result = functionResult; await callbacks?.onFunctionResult?.(functionCall.name, functionResult); + + + addMessageToChat({ + tool_call_id: functionCall.tool_call_id, + role: 'tool', + content: JSON.stringify(functionResult) + }, chat_id); + + addMessageToChat({ role: 'assistant', content: delta.content, @@ -141,14 +150,7 @@ async function elaborateResponse(messages: OpenAI.Chat.Completions.ChatCompletio arguments: functionCall.argsRaw.join('') } } - ], - parsed: null - }, chat_id); - - addMessageToChat({ - tool_call_id: functionCall.tool_call_id, - role: 'tool', - content: JSON.stringify(functionResult) + ] }, chat_id); @@ -181,6 +183,7 @@ export async function sendMessageOnChat(text: string, pid: string, initial_chat_ if (chatMessages && chatMessages.length > 0) { messages.push(...chatMessages); + await updateChatStatus(chat_id, '', false); } else { const roleMessage: OpenAI.Chat.Completions.ChatCompletionMessageParam = { role: 'system', @@ -198,8 +201,9 @@ export async function sendMessageOnChat(text: string, pid: string, initial_chat_ try { const streamResponse = await elaborateResponse(messages, pid, chat_id, callbacks); - await addMessageToChat({ role: 'assistant', refusal: null, content: await streamResponse.finalContent() }, chat_id); - return { content: '', charts: [] }; + const finalContent = await streamResponse.finalContent(); + await addMessageToChat({ role: 'assistant', refusal: null, content: finalContent }, chat_id); + return { content: finalContent, charts: [] }; } catch (ex: any) { console.error(ex); return { content: ex.message, charts: [] }; diff --git a/shared/schema/ai/AiChatSchema.ts b/shared/schema/ai/AiChatSchema.ts index a66afe6..934f4b0 100644 --- a/shared/schema/ai/AiChatSchema.ts +++ b/shared/schema/ai/AiChatSchema.ts @@ -7,6 +7,7 @@ export type TAiChatSchema = { status: string, completed: boolean, title: string, + deleted: boolean, created_at: Date, updated_at: Date } @@ -17,6 +18,7 @@ const AiChatSchema = new Schema({ completed: { type: Boolean }, messages: [{ _id: false, type: Schema.Types.Mixed }], title: { type: String, required: true }, + deleted: { type: Boolean, default: false }, created_at: { type: Date, default: () => Date.now() }, updated_at: { type: Date, default: () => Date.now() }, });