feat: 升级至 v0.3.8 — Trace Viewer 叠加修复 + LLM 配置校验改造 + toast 反馈统一

- Trace Viewer 叠加渲染修复
  - sendMessage 补 traceSteps/tokenUsage 重置(止血)
  - TraceStep 加 runId 字段,useAgentStream 按 runId 判定同迭代(稳健改造)

- LLM 配置校验中等改造(SettingsModal LLMSettings)
  - 取消 onChange 实时落库,改为本地 state + Save 按钮统一提交
  - 字段级 inline error:Base URL http(s):// 正则、Model 空格校验、contextWindow ≥ 4096
  - Provider 切换清空 Model(之前只清 apiKey)
  - 保存结果改用 metona-toast(不再用 Alert)

- toast 反馈机制全面统一(15 处问题修复)
  - ContextMenu: 原生 confirm/prompt 改 MUI Dialog(新增 useDialogStore + ContextMenuDialogHost)
  - ContextMenu: 抽 copyWithToast helper 替代散落 7 处静默失败
  - OnboardingWizard: 配置保存失败静默改 toast.error
  - useKeyboardShortcuts: Ctrl+N / Ctrl+Shift+C 失败补 toast
  - SettingsModal: inheritFiles 失败 toast.warning、handleApply 失败 toast.error
  - LogsSettings: resultAlert Alert 改 toast(保留 Dialog 确认)
  - MemoryViewer: 删除失败改 toast(加载/搜索保留 Alert)
  - TaskList: create/update/delete/无会话改 toast
  - agent-store: sendMessage/session 失败补 toast(保留 system message)

- 删除当前会话同步清空 ChatPanel/DetailPanel
  - Sidebar confirmDelete + ContextMenu delete 均补 agent-store 重置
  - 修复 useSessionStore.removeSession 不触发 agent-store 同步的遗漏
This commit is contained in:
2026-07-20 21:22:20 +08:00
parent ceb8ee644d
commit dde21f0b3f
13 changed files with 428 additions and 87 deletions
@@ -40,6 +40,8 @@ export function OnboardingWizard(): React.JSX.Element | null {
const failedCount = results.filter((r) => r.status === 'rejected').length;
if (failedCount > 0) {
console.error('[OnboardingWizard]', `${failedCount} config(s) failed to save`);
// 用户主动操作失败必须有反馈,否则按钮看起来无响应
import('metona-toast').then((mod) => mod.default.error(`部分配置保存失败(${failedCount} 项),请重试`)).catch(() => {});
// 不调用 setOnboardingCompleted(true),让用户重试
return;
}
@@ -50,6 +52,8 @@ export function OnboardingWizard(): React.JSX.Element | null {
setOnboardingCompleted(true);
} catch (err) {
console.error('[OnboardingWizard]', 'Failed to save configuration:', err);
// 用户主动操作失败必须有反馈,否则向导不关闭、用户卡死
import('metona-toast').then((mod) => mod.default.error(`保存配置失败:${(err as Error).message}`)).catch(() => {});
}
};