diff --git a/AGENTS.md b/AGENTS.md index 9160f34..4755846 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -11,6 +11,7 @@ ## 必须遵循 +- 注意代码的解耦,做到高内聚,低耦合 - 安装依赖时,必须写死依赖的版本,禁止任何升级的可能,如存在需要升级的场景,必须手动执行安装新版本命令 - 新建的mono包必须在根目录安装 - 使用nuxt时遇到不清楚的,必须先加载nuxt-remote查询文档再进行分析 diff --git a/app/composables/useLlmChat.ts b/app/composables/useLlmChat.ts index 5960ffa..4e369da 100644 --- a/app/composables/useLlmChat.ts +++ b/app/composables/useLlmChat.ts @@ -5,6 +5,8 @@ export interface LlmChatMessage { role: 'user' | 'assistant' content: string reasoning?: string + reasoningLoading?: boolean + reasoningDuration?: number } export interface UseLlmChatOptions { @@ -42,13 +44,22 @@ export function useLlmChat(options: UseLlmChatOptions) { const userMsg: LlmChatMessage = { id: generateId(), role: 'user', content: trimmed } messages.value.push(userMsg) - const assistantMsg: LlmChatMessage = { id: generateId(), role: 'assistant', content: '' } + const assistantMsg: LlmChatMessage = { + id: generateId(), + role: 'assistant', + content: '', + reasoning: '', + reasoningLoading: false, + reasoningDuration: 0, + } messages.value.push(assistantMsg) const assistantIdx = messages.value.length - 1 isLoading.value = true abortController = new AbortController() + let reasoningStartTime: number | null = null + try { const res = await fetch(apiEndpoint, { method: 'POST', @@ -79,16 +90,32 @@ export function useLlmChat(options: UseLlmChatOptions) { stream: res.body, onReasoningPart: (text) => { const msg = messages.value[assistantIdx] - if (msg) msg.reasoning = (msg.reasoning ?? '') + text + if (!msg) return + if (reasoningStartTime === null) { + reasoningStartTime = Date.now() + msg.reasoningLoading = true + } + msg.reasoning = (msg.reasoning ?? '') + text }, onTextPart: (text) => { const msg = messages.value[assistantIdx] - if (msg) msg.content += text + if (!msg) return + if (reasoningStartTime !== null && msg.reasoningLoading) { + msg.reasoningDuration = Date.now() - reasoningStartTime + msg.reasoningLoading = false + } + msg.content += text }, onErrorPart: (error) => { errorMessage.value = error || '流式响应出错' }, }) + + const msg = messages.value[assistantIdx] + if (msg && reasoningStartTime !== null && msg.reasoningLoading) { + msg.reasoningDuration = Date.now() - reasoningStartTime + msg.reasoningLoading = false + } } catch (err: any) { if (err.name === 'AbortError') { // user stopped diff --git a/app/pages/settings/llm-test/index.vue b/app/pages/settings/llm-test/index.vue index d80d928..03af481 100644 --- a/app/pages/settings/llm-test/index.vue +++ b/app/pages/settings/llm-test/index.vue @@ -138,7 +138,7 @@ function modelTypeClass(type: string) { -
启用后,支持推理的模型会展示思考过程
+启用后,支持推理的模型会展示思考过程(仅对支持推理的模型有效,如 DeepSeek-R1、o1 等)