From 53e0ed37f67fb0988ce7550ca720bff9721b7d19 Mon Sep 17 00:00:00 2001 From: Wenjie Zhang Date: Mon, 23 Mar 2026 09:43:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=94=9F=E6=88=90?= =?UTF-8?q?=E5=AF=B9=E8=AF=9D=E6=A0=87=E9=A2=98=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=A0=B9=E6=8D=AE=E5=86=85=E5=AE=B9=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E7=94=9F=E6=88=90=E7=AE=80=E7=9F=AD=E6=A0=87=E9=A2=98?= =?UTF-8?q?=EF=BC=8C=E4=BD=BF=E7=94=A8=20fast=5Fmodel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/package/yuxi/config/app.py | 6 +-- web/src/apis/agent_api.js | 14 ++++++ web/src/components/AgentChatComponent.vue | 55 ++++++++++++++++++++--- 3 files changed, 67 insertions(+), 8 deletions(-) diff --git a/backend/package/yuxi/config/app.py b/backend/package/yuxi/config/app.py index 0842803c..dc609897 100644 --- a/backend/package/yuxi/config/app.py +++ b/backend/package/yuxi/config/app.py @@ -47,11 +47,11 @@ class Config(BaseModel): # 模型配置 # ============================================================ default_model: str = Field( - default="siliconflow/Pro/deepseek-ai/DeepSeek-V3.2", + default="siliconflow/Pro/MiniMaxAI/MiniMax-M2.5", description="默认对话模型", ) fast_model: str = Field( - default="siliconflow/Qwen/Qwen3.5-9B", + default="siliconflow/Pro/MiniMaxAI/MiniMax-M2.5", description="快速响应模型", ) embed_model: str = Field( @@ -63,7 +63,7 @@ class Config(BaseModel): description="默认 Re-Ranker 模型", ) content_guard_llm_model: str = Field( - default="siliconflow/Qwen/Qwen3.5-9B", + default="siliconflow/Pro/MiniMaxAI/MiniMax-M2.5", description="内容审查LLM模型", ) diff --git a/web/src/apis/agent_api.js b/web/src/apis/agent_api.js index 6ea0087c..1c16e7f9 100644 --- a/web/src/apis/agent_api.js +++ b/web/src/apis/agent_api.js @@ -52,6 +52,20 @@ export const agentApi = { */ simpleCall: (query) => apiPost('/api/chat/call', { query }), + /** + * 生成对话标题 + * @param {string} query - 查询内容 + * @param {Object} modelSpec - 模型配置 + * @returns {Promise} - 生成的标题 + */ + generateTitle: async (query, modelSpec) => { + const response = await apiPost('/api/chat/call', { + query: `根据以下对话内容生成一个简短的标题(最多30个字符,中英文均可),不要包含 markdown 标记:\n\n${query.slice(0, 2000)}`, + meta: { model_spec: modelSpec } + }) + return response.response + }, + /** * 获取默认智能体 * @returns {Promise} - 默认智能体信息 diff --git a/web/src/components/AgentChatComponent.vue b/web/src/components/AgentChatComponent.vue index d45e706d..eb588e87 100644 --- a/web/src/components/AgentChatComponent.vue +++ b/web/src/components/AgentChatComponent.vue @@ -63,6 +63,12 @@ 新对话 +
+ {{ currentThread.title }} +
@@ -227,6 +233,7 @@ import { useAgentStore } from '@/stores/agent' import { useChatUIStore } from '@/stores/chatUI' import { useInfoStore } from '@/stores/info' import { useUserStore } from '@/stores/user' +import { useConfigStore } from '@/stores/config' import { storeToRefs } from 'pinia' import { MessageProcessor } from '@/utils/messageProcessor' import { agentApi, threadApi } from '@/apis' @@ -250,6 +257,7 @@ const agentStore = useAgentStore() const chatUIStore = useChatUIStore() const infoStore = useInfoStore() const userStore = useUserStore() +const configStore = useConfigStore() const { agents, selectedAgentId, @@ -798,11 +806,24 @@ const sendMessage = async ({ return Promise.reject(error) } - // 如果是新对话,用消息内容作为标题 + // 如果是新对话,用 fast-model 异步生成标题(不阻塞消息发送) if ((threadMessages.value[threadId] || []).length === 0) { - const autoTitle = text.replace(/\s+/g, ' ').trim().slice(0, 255) + const autoTitle = text.replace(/\s+/g, ' ').trim().slice(0, 2000) if (autoTitle) { - void updateThread(threadId, autoTitle).catch(() => {}) + void (async () => { + try { + const generatedTitle = await agentApi.generateTitle(autoTitle, configStore.config?.fast_model) + if (generatedTitle) { + const finalTitle = generatedTitle.slice(0, 30).replace(/\s+/g, ' ').trim() + if (finalTitle) { + void updateThread(threadId, finalTitle).catch(() => {}) + } + } + } catch (e) { + // 失败时使用原始文本作为标题 + void updateThread(threadId, autoTitle.slice(0, 30)).catch(() => {}) + } + })() } } @@ -1017,9 +1038,22 @@ const handleSendMessage = async ({ image } = {}) => { if (useRunsApi) { if ((threadMessages.value[threadId] || []).length === 0) { - const autoTitle = text.replace(/\s+/g, ' ').trim().slice(0, 255) + const autoTitle = text.replace(/\s+/g, ' ').trim().slice(0, 2000) if (autoTitle) { - void updateThread(threadId, autoTitle).catch(() => {}) + void (async () => { + try { + const generatedTitle = await agentApi.generateTitle(autoTitle, configStore.config?.fast_model) + if (generatedTitle) { + const finalTitle = generatedTitle.slice(0, 30).replace(/\s+/g, ' ').trim() + if (finalTitle) { + void updateThread(threadId, finalTitle).catch(() => {}) + } + } + } catch (e) { + // 失败时使用原始文本作为标题 + void updateThread(threadId, autoTitle.slice(0, 30)).catch(() => {}) + } + })() } } @@ -1459,6 +1493,17 @@ watch( .sidebar-logo-toggle:hover .sidebar-expand-overlay { opacity: 1; } + + .conversation-title { + font-size: 14px; + font-weight: 500; + color: var(--text-primary); + max-width: 200px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + margin-left: 8px; + } } }