From fd2660d21a8afd4998ccdb24f8f1ba167bd2e32a Mon Sep 17 00:00:00 2001 From: Wenjie Zhang Date: Mon, 8 Jun 2026 00:29:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E6=99=BA=E8=83=BD?= =?UTF-8?q?=E4=BD=93=E5=AF=B9=E8=AF=9D=E4=B8=8E=E6=89=A9=E5=B1=95=E7=95=8C?= =?UTF-8?q?=E9=9D=A2=E4=BD=93=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 智能体状态面板改为仅展示有内容的 section,并为空状态保留统一提示 - 将待办名称在提示词、对话状态面板和工具结果中统一限制为 20 个中文汉字以内,同时通过 title 保留完整内容 - v2 模型列表补充供应商展示名,模型选择器展示并支持按供应商名称搜索 - 收紧文件预览编辑浮动操作、附件状态标签、工作区预览分隔线等界面细节 - 更新扩展/管理页命名、官网首页截图与 Demo 链接,并补充 changelog/roadmap --- README.en.md | 2 +- README.md | 2 +- .../yuxi/agents/buildin/chatbot/prompt.py | 1 + .../server/routers/model_provider_router.py | 7 + docs/.vitepress/theme/components/YuxiHome.vue | 6 +- docs/develop-guides/changelog.md | 1 + docs/develop-guides/roadmap.md | 2 + web/src/components/AgentChatComponent.vue | 49 ++++-- web/src/components/AgentFilePreview.vue | 149 +++++++++++------- web/src/components/AgentPanel.vue | 14 ++ .../components/AttachmentTmpUploadModal.vue | 23 ++- web/src/components/ModelSelectorComponent.vue | 19 ++- .../ToolCallingResult/tools/TodoListTool.vue | 18 ++- .../components/extensions/SkillCardList.vue | 11 -- .../components/extensions/SkillDetailView.vue | 4 - .../workspace/WorkspacePreviewPane.vue | 1 - web/src/views/ExtensionsView.vue | 4 +- web/src/views/ModelManageView.vue | 4 +- web/src/views/WorkspaceView.vue | 10 +- 19 files changed, 216 insertions(+), 111 deletions(-) diff --git a/README.en.md b/README.en.md index 409577ae..4b83df9c 100644 --- a/README.en.md +++ b/README.en.md @@ -8,7 +8,7 @@ [![License](https://img.shields.io/github/license/bitcookies/winrar-keygen.svg?logo=github)](https://github.com/xerrors/Yuxi/blob/main/LICENSE) [![DeepWiki](https://img.shields.io/badge/DeepWiki-blue.svg)](https://deepwiki.com/xerrors/Yuxi) [![zread](https://img.shields.io/badge/Ask_Zread-_.svg?style=flat&color=00b0aa&labelColor=000000&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff)](https://zread.ai/xerrors/Yuxi) -[![demo](https://img.shields.io/badge/demo-00A1D6.svg?style=flat&logo=bilibili&logoColor=white)](https://www.bilibili.com/video/BV1DF14BTETq/) +[![demo](https://img.shields.io/badge/demo-00A1D6.svg?style=flat&logo=bilibili&logoColor=white)](https://www.bilibili.com/video/BV1TZEx6NEit/) xerrors%2FYuxi | Trendshift diff --git a/README.md b/README.md index 3b65b0ee..575960c8 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![](https://img.shields.io/github/issues/xerrors/Yuxi?color=F48D73)](https://github.com/xerrors/Yuxi/issues) [![License](https://img.shields.io/github/license/bitcookies/winrar-keygen.svg?logo=github)](https://github.com/xerrors/Yuxi/blob/main/LICENSE) [![DeepWiki](https://img.shields.io/badge/DeepWiki-blue.svg)](https://deepwiki.com/xerrors/Yuxi) -[![demo](https://img.shields.io/badge/demo-00A1D6.svg?style=flat&logo=bilibili&logoColor=white)](https://www.bilibili.com/video/BV1DF14BTETq/) +[![demo](https://img.shields.io/badge/demo-00A1D6.svg?style=flat&logo=bilibili&logoColor=white)](https://www.bilibili.com/video/BV1TZEx6NEit/) xerrors%2FYuxi | Trendshift diff --git a/backend/package/yuxi/agents/buildin/chatbot/prompt.py b/backend/package/yuxi/agents/buildin/chatbot/prompt.py index 24931012..e60dc932 100644 --- a/backend/package/yuxi/agents/buildin/chatbot/prompt.py +++ b/backend/package/yuxi/agents/buildin/chatbot/prompt.py @@ -46,6 +46,7 @@ SOURCE_CITE_PROMPT = """ TODO_MID_PROMPT = """ 你需要根据任务的复杂程度来使用 write_todos 来记录规划和待办事项,确保任务的每个步骤都被记录和跟踪。 +每个待办任务名称必须简短,控制在 20 个中文汉字以内。 """ diff --git a/backend/server/routers/model_provider_router.py b/backend/server/routers/model_provider_router.py index 9ddbddf3..bcf483d9 100644 --- a/backend/server/routers/model_provider_router.py +++ b/backend/server/routers/model_provider_router.py @@ -205,6 +205,7 @@ async def refresh_model_cache( async def get_v2_models( model_type: str = "chat", _current_user: User = Depends(get_required_user), + db: AsyncSession = Depends(get_db), ): """获取 v2 格式的模型列表,按 provider 分组。 @@ -214,10 +215,16 @@ async def get_v2_models( from yuxi.models.providers.cache import model_cache grouped = model_cache.get_specs_grouped_by_provider(model_type) + providers = await get_all_model_providers(db) + provider_name_by_id = { + provider.provider_id: provider.display_name or provider.provider_id for provider in providers + } result = {} for provider_id, models in grouped.items(): result[provider_id] = { + "provider_id": provider_id, + "provider_display_name": provider_name_by_id.get(provider_id, provider_id), "models": [ { "spec": m.spec, diff --git a/docs/.vitepress/theme/components/YuxiHome.vue b/docs/.vitepress/theme/components/YuxiHome.vue index 66221d92..cf9c8c9f 100644 --- a/docs/.vitepress/theme/components/YuxiHome.vue +++ b/docs/.vitepress/theme/components/YuxiHome.vue @@ -3,7 +3,7 @@ import { ref, computed } from 'vue' import { withBase } from 'vitepress' const GITHUB = 'https://github.com/xerrors/Yuxi' -const DEMO = 'https://www.bilibili.com/video/BV1DF14BTETq/' +const DEMO = 'https://www.bilibili.com/video/BV1TZEx6NEit/' // 关键数字(占位,后续替换为真实数据) const stats = [ @@ -126,7 +126,7 @@ const shots = [ { title: '对话工作台', desc: '类 ChatGPT 的智能体对话与产物交付' }, { title: '智能体配置', desc: '挂载 Skills / MCP / 子智能体与中间件' }, { title: '知识图谱可视化', desc: '实体关系抽取与子图检索展示' }, - { title: '拓展管理', desc: '统一管理 Skills 与 MCP 服务' } + { title: '智能体拓展', desc: '统一管理 Skills 与 MCP 服务' } ] // 企业级 @@ -225,7 +225,7 @@ const vReveal = {
语析 Yuxi 产品界面预览 diff --git a/docs/develop-guides/changelog.md b/docs/develop-guides/changelog.md index 06c34b91..547214f2 100644 --- a/docs/develop-guides/changelog.md +++ b/docs/develop-guides/changelog.md @@ -53,6 +53,7 @@ - 工作区知识库分类显示:知识库侧边栏按创建者分组为“我的知识库”和“共享知识库”,自己创建的知识库显示在“我的知识库”下,非自己创建的显示在“共享知识库”下;`knowledge_bases` 表新增 `created_by` 字段记录创建者 uid。 - 工作区文件上传支持多选:`/workspace/upload` 与 Viewer 工作区上传统一使用 `files` 多文件字段,一次最多上传 50 个文件,批量上传失败时清理本次已写入文件。 - 聊天附件新增 MinIO tmp 临时上传、可选 PDF/图片解析、确认后加入线程附件的流程;前端改为弹窗内上传、解析与确认。 +- 优化智能体对话页细节:状态面板隐藏空 section,待办名称限制为 20 个中文汉字以内,模型选择器展示供应商名称,并收紧附件状态标签与文件编辑浮动操作样式。 - 标准化 Agent run/SSE 执行链路:run 创建时持久化输入消息并提交后入队,worker 统一写入 Redis Stream envelope,SSE 输出 `event/data/id`、心跳注释、`Last-Event-ID` 回放和终止 `end` 事件;前端强制使用 run API 并支持 ask_user_question 中断后以 resume run 恢复;事件 envelope 构造收敛到统一 helper,前端优先使用 envelope 一级 `thread_id` 路由。 - Agent run SSE 新增 `verbose=false` 精简模式:默认仍返回完整事件载荷;精简模式仅在 SSE 输出前重建最小 payload,跳过 `metadata` 和空 `yuxi.agent_state`,将同一 data 内的 `request_id` 外提为单个字段,移除 chunk 中重复的 `meta`、`metadata`、`thread_id`、`response`、空 `namespace` 和图片 base64 等调试字段,保留消息增量、工具调用、工具结果、非空 Agent state、终止状态和 SSE 游标,前端订阅默认使用精简模式。 - 收敛后端模块边界:文档解析从 `plugins.parser` 移动到 `knowledge.parser`,内容审查从 `plugins.guard` 移动到 `services.guard`。 diff --git a/docs/develop-guides/roadmap.md b/docs/develop-guides/roadmap.md index 9c4775fc..a4d8f7c8 100644 --- a/docs/develop-guides/roadmap.md +++ b/docs/develop-guides/roadmap.md @@ -13,6 +13,7 @@ - [ ] 调研将当前知识库映射为虚拟文件系统的可行性,先明确文件树映射、权限边界、内容读取与 Agent 工具调用形态,再决定是否实现 - [ ] 增强知识库检索体验:增强 metadata、标签等 - [ ] 优化思维导图构建的接口设计,支持增量构建和更新 +- [ ] 个人工作区增加可检索能力(但是不做向量化) **智能体** @@ -25,6 +26,7 @@ - [ ] 添加 Agent 独立调用接口,方便后续评估使用 **其他** +- [ ] 历史对话新增分组(或者叫做项目) - [ ] 集成 Memory,基于 deepagents 的文件后端实现,需要考虑定位 **仅设想** diff --git a/web/src/components/AgentChatComponent.vue b/web/src/components/AgentChatComponent.vue index da5f7522..789065d5 100644 --- a/web/src/components/AgentChatComponent.vue +++ b/web/src/components/AgentChatComponent.vue @@ -221,6 +221,7 @@
@@ -248,10 +249,10 @@ id="state-section-todos" class="state-section-content" > -
+
@@ -262,15 +263,17 @@
- {{ todo.content }} + + {{ todo.displayContent }} +
-
暂无待办
@@ -296,7 +299,7 @@ id="state-section-files" class="state-section-content" > -
+
-
暂无附件或文件
@@ -339,7 +342,7 @@ id="state-section-artifacts" class="state-section-content" > -
+
-
暂无产物
@@ -389,7 +392,7 @@ id="state-section-subagents" class="state-section-content" > -
+
-
暂无子智能体运行
+ +
暂无状态内容
@@ -600,11 +604,16 @@ const agentPanelActivePreviewPath = ref('') const agentPanelViewMode = ref('tree') const chatContentContainerRef = ref(null) const panelWrapperRef = ref(null) // 直接操作 DOM +const TODO_NAME_MAX_LENGTH = 20 let resizeStartX = 0 let resizeStartWidth = 0 let panelContainerWidth = 0 let streamingStateRefreshTimer = null +const formatTodoName = (content) => { + return Array.from(String(content || '')).slice(0, TODO_NAME_MAX_LENGTH).join('') +} + const getPanelContainerWidth = () => { const container = chatContentContainerRef.value || panelWrapperRef.value?.parentElement return container?.clientWidth || (typeof window !== 'undefined' ? window.innerWidth : 0) @@ -851,7 +860,15 @@ const currentArtifactFiles = computed(() => ) const currentTodos = computed(() => { const todos = currentAgentState.value?.todos - return Array.isArray(todos) ? todos : [] + if (!Array.isArray(todos)) return [] + return todos.map((todo) => { + const fullContent = String(todo?.content || '') + return { + ...todo, + fullContent, + displayContent: formatTodoName(fullContent) + } + }) }) const currentSubagentRuns = computed(() => { const runs = currentAgentState.value?.subagent_runs @@ -939,6 +956,13 @@ const stateSummaryLabel = computed(() => { displaySubagentRuns.value.length return total ? `${total} 项` : '暂无内容' }) +const hasVisibleStateSections = computed( + () => + currentTodos.value.length > 0 || + currentStateFiles.value.length > 0 || + currentArtifactFiles.value.length > 0 || + displaySubagentRuns.value.length > 0 +) const { mentionConfig } = useAgentMentionConfig({ currentAgentState, @@ -3140,12 +3164,13 @@ watch(currentChatId, (threadId, oldThreadId) => { min-width: 0; } -.state-section-empty { +.state-panel-empty { padding: 10px 12px; border-radius: 10px; background: var(--gray-25); color: var(--gray-500); font-size: 13px; + text-align: center; } .todo-panel-list { diff --git a/web/src/components/AgentFilePreview.vue b/web/src/components/AgentFilePreview.vue index aa1b79d3..73691cc3 100644 --- a/web/src/components/AgentFilePreview.vue +++ b/web/src/components/AgentFilePreview.vue @@ -1,7 +1,10 @@