• v0.3.8 76bd72b702

    thzxx released this 2026-07-20 22:17:39 +08:00 | 7 commits to master since this release

    v0.3.8 — Trace Viewer 重构 + LLM 配置校验改造 + toast 反馈统一

    本次版本聚焦用户反馈的三大体验痛点:Trace Viewer 渲染问题、LLM 配置项修改体验糟糕、全站反馈机制不统一。共 3 次提交,修改 14 个文件,+467 / -103。


    一、Trace Viewer 重构(方案 A+)

    问题现象

    • 发送第二条用户消息时,Trace Viewer 会在第一条上面继续叠加渲染,导致追踪步骤混乱、迭代序号错乱
    • 初版修复(清空 traceSteps)引入了新问题:第一条消息的 trace 被永久覆盖丢失

    最终方案:按 runId 分组渲染

    TraceViewer 改为按 run 分组展示,每轮 AI 回复一个独立 section,所有历史轮次都可见。

    实现细节

    1. TraceStep 加 runId 字段

    src/stores/agent-store.ts TraceStep 接口新增 runId?: string 字段,用于跨 run 隔离。

    2. useAgentStream 按 runId 判定同迭代

    src/hooks/useAgentStream.ts

    • isSameIteration 判定从"只看 iteration"升级为"iteration + runId"
    • 创建新 step 时传入 runId: data.runId
    • TERMINATED 分支加 runId 一致性检查,跨 run 的孤立 TERMINATED 跳过不创建

    3. sendMessage 不清空 traceSteps

    src/stores/agent-store.ts sendMessage 保留历史 traceSteps,仅重置 tokenUsage(当前 run 统计应该重置)。

    4. TraceViewer 按分组渲染

    src/components/trace/TraceViewer.tsx 重写渲染逻辑:

    • 新增 groupByRun 工具函数,按 runId 分组 + 计算轮次序号
    • 每个 run 独立 section,带"第 N 轮"标题 + 状态徽标(进行中/已完成)+ 步数统计
    • 当前 run 高亮primary.main 边框 + 浅色背景 + MessageSquare 图标高亮
    • 历史 run 弱化divider 边框 + 透明背景 + 0.85 透明度
    • 顶部显示"共 N 轮"统计
    • 空态显示"等待 Agent 活动..."

    5. 自动滚动到底部

    src/components/trace/TraceViewer.tsx 新增 scrollContainerRef + useEffect,监听 traceSteps / agentStatus / groups.length 变化时自动滚到底部。与 MessageList.tsx 同款 throttle 80ms 模式,避免流式事件高频触发导致滚动卡顿。

    渲染效果

    [Activity] TRACE VIEWER                    共 3 轮
    ┌─ 第 1 轮  已完成                    2 步 ─┐
    │   [step 1] THINKING → EXECUTING → ...    │
    │   [step 2] THINKING → OBSERVING → ...    │
    └──────────────────────────────────────────┘
    ┌─ 第 2 轮  已完成                    3 步 ─┐
    │   [step 1] ...                            │
    │   [step 2] ...                            │
    │   [step 3] ...                            │
    └──────────────────────────────────────────┘
    ┌─ 第 3 轮  进行中                    1 步 ─┐  ← 高亮(primary 边框+背景)
    │   [step 1] THINKING → EXECUTING → ...    │  ← isCurrent(转圈动画)
    └──────────────────────────────────────────┘
    

    二、LLM 配置项修改体验改造(中等改造)

    问题现象

    • 修改 Base URL 后鼠标失焦,输入被回滚卡死
    • Provider 切换后 Model 字段残留旧值,导致 API 调用 404
    • API Key 未填时 401,但 UI 无任何提示
    • 保存结果无反馈,用户不知道是否成功

    修复方案

    src/components/settings/SettingsModal.tsx LLMSettings 函数中等改造:

    1. 取消 onChange 实时落库

      • 改为本地 useState + 一次性 useEffect 加载配置
      • 新增 Save 按钮(handleSave 串行批量 IPC,hasBlockingError 阻断保存)
    2. 字段级 inline error 校验

      • Base URL: ^https?://.+ 正则校验
      • Model: 空格校验(API 会 404)
      • numCtx: ≥ 512(Ollama)
      • contextWindow: ≥ 4096(DeepSeek/Agnes AI/MiMo 最小值约束)
    3. Provider 切换清理

      • handleProviderChange 新增清空 Model 逻辑(之前只清 apiKey,导致切换后 Model 残留旧 provider 的模型名)
    4. 反馈机制

      • 保存成功/失败改用 metona-toast(不再用 Alert)
      • 保留 inline error(指向具体字段,让用户看到哪个字段有问题)

    三、toast 反馈机制全面统一(15 处问题修复)

    设计原则统一

    场景 反馈方式 理由
    加载失败 Alert / 红字 持续性错误,需用户感知
    表单校验 inline error 指向具体字段
    用户主动操作结果 metona-toast 保存/删除/复制/创建等
    用户确认 MUI Dialog 删除会话、清理数据等

    修复清单

    1. ContextMenu(src/components/ContextMenu.tsx

    • 新增模块级 useDialogStore(zustand)— 暴露 confirm() / prompt() 返回 Promise
    • 新增导出 ContextMenuDialogHost 组件 — 渲染通用 MUI Dialog
    • 新增 copyWithToast(text) helper — 替代散落 7 处的 navigator.clipboard.writeText(...).catch(err => console.error(...)) 静默失败
    • session 的 rename 改用 useDialogStore.getState().prompt(),预填当前标题
    • session 的 delete 改用 useDialogStore.getState().confirm(),行为对齐 Sidebar 的 Dialog 二次确认

    2. App.tsx(src/App.tsx

    • 引入并挂载 <ContextMenuDialogHost />

    3. OnboardingWizard(src/components/onboarding/OnboardingWizard.tsx

    • 部分配置保存失败时 toast.error 提示失败数量
    • handleNext 整体 catch 时 toast.error 提示具体错误

    4. useKeyboardShortcuts(src/hooks/useKeyboardShortcuts.ts

    • Ctrl+N 创建会话失败补 toast
    • Ctrl+Shift+C 复制失败补 toast

    5. SettingsModal(src/components/settings/SettingsModal.tsx

    • handleApply inheritFiles 失败补 toast.warning
    • handleApply 整体 catch 补 toast.error
    • LogsSettings 移除 resultAlert state 和最后 Alert 渲染,所有操作结果改用 toast(保留 Dialog 确认)

    6. MemoryViewer(src/components/memory/MemoryViewer.tsx

    • handleDelete 失败改用 toast.error
    • 加载/搜索保留 Alert(持续性错误)

    7. TaskList(src/components/tasks/TaskList.tsx

    • handleCreate / handleToggleComplete / handleDelete 失败全部改用 toast
    • "请先选择或创建会话" 改用 toast
    • 表单校验"任务标题不能为空"保留 inline error

    8. agent-store(src/stores/agent-store.ts

    • sendMessage 失败和 session 创建失败:保留 system message(聊天流上下文)+ 额外补 toast 作为通知

    四、删除当前会话同步清空 ChatPanel/DetailPanel

    问题现象

    侧边栏删除当前会话时,中间消息区域和右侧详情栏的内容仍然残留,需要切换到其他会话才能清空。

    根因

    Sidebar 的 confirmDelete 只调了 useSessionStore.removeSession(id) 清会话列表,但 agent-store 的 currentSessionId / messages / traceSteps 完全没同步。ChatPanel 和 DetailPanel 读的是 agent-store,所以内容残留。

    修复方案

    • src/components/layout/Sidebar.tsx confirmDelete 删除会话后判断 useAgentStore.getState().currentSessionId === sid,是当前会话就显式 setState 清空:
      • currentSessionId: null
      • messages: []
      • traceSteps: []
      • tokenUsage: { 0, 0, 0 }
      • currentRunId: null, currentIteration: 0
    • src/components/ContextMenu.tsx 右键菜单的 delete 动作同样补 agent-store 重置

    五、版本号升级


    提交记录

    Commit 说明
    dde21f0 feat: 升级至 v0.3.8 — Trace Viewer 叠加修复 + LLM 配置校验改造 + toast 反馈统一
    5ec32f3 fix(trace): Trace Viewer 改为按 runId 分组渲染,显示所有轮次
    76bd72b fix(trace): TraceViewer 出现滚动条时自动滚到底部

    修改文件统计

     README.md                                      |   2 +-
     package-lock.json                              |   4 +-
     package.json                                   |   2 +-
     src/App.tsx                                    |   2 +
     src/components/ContextMenu.tsx                 | 165 ++++++++++++++--
     src/components/layout/Sidebar.tsx              |  12 ++
     src/components/memory/MemoryViewer.tsx         |   6 +-
     src/components/onboarding/OnboardingWizard.tsx |   4 +
     src/components/settings/SettingsModal.tsx      | 259 ++++++++++++++++++++-----
     src/components/tasks/TaskList.tsx              |  18 +-
     src/components/trace/TraceViewer.tsx           | 147 +++++++++++++++--
     src/hooks/useAgentStream.ts                    |  16 +-
     src/hooks/useKeyboardShortcuts.ts              |  12 +-
     src/stores/agent-store.ts                      |  13 ++
     14 files changed, 467 insertions(+), 103 deletions(-)
    

    建议冒烟测试

    Trace Viewer

    • 发第一条消息 → 显示"第 1 轮"
    • 发第二条消息 → 显示"第 1 轮(已完成)+ 第 2 轮(进行中)"
    • 等第二条完成 → "第 2 轮" 状态从"进行中"变为"已完成"
    • 切换到其他会话再切回来 → 所有轮次都还在
    • abort 后重发 → 新 run 的 trace 独立显示,不污染旧 run
    • trace 超出容器高度 → 自动滚动到底部,最新步骤始终可见

    LLM 配置

    • 改 Base URL 不再被回滚卡死
    • 切换 Provider(DeepSeek → Ollama)→ Model 自动清空
    • 故意删掉 Base URL 的 https:// → 出现 inline error,Save 按钮禁用
    • 未填 API Key → 字段下方提示"未填会 401"(warning,不阻断保存)
    • 点 Save → toast 提示"配置已保存"

    会话删除

    • 右键当前会话 → 删除 → ChatPanel 立即清空、DetailPanel 的 Trace Viewer 也清空
    • 右键非当前会话 → 删除 → 当前会话不受影响

    toast 反馈

    • 右键会话 → 重命名 → Dialog 弹出,预填当前标题,回车确认
    • 设置 → 清理会话 → Dialog 确认 → toast 提示已清理
    • 任务面板无会话时点"创建" → toast 提示"请先选择或创建会话"
    • 记忆面板删除某条 → 失败时 toast 弹错
    • 引导向导最后一步 → 故意让某个 IPC 失败 → toast 提示失败数量

    最新 Commit: 76bd72b — fix(trace): TraceViewer 出现滚动条时自动滚到底部

    Downloads