feat: 升级至 v0.3.7 — 前后端状态同步与错误处理全量修复
核心引擎修复: - CE-1: 上下文压缩摘要 role 从 system 改为 user,避免被 adapter 过滤 - CE-2: 工具失败时优先使用 error 字段(engine/openai-format/ollama 三处) - P0-1: DeadLoopError 终止时正确传 error 参数,前端可见 ERROR 事件 - MT-1: 新增 waitForAbort 方法,abortSession 等待 run 结束再返回 - MT-2: TERMINATED 状态到达时标记步骤完成,避免 Trace Viewer 转圈 - MT-3: 压缩边界检测孤立 tool 消息,避免 API 400 错误 - isRetryableError 与 catch 分支统一 toLowerCase IPC 与主进程修复: - P0-2: createAdapter 配置缺失返回 null,FALLBACK_ADAPTER 兜底 - P0-3: reloadAdapter 失败返回 success:false 通知前端 - P1-5: 校验失败发 ERROR+DONE 流事件,防止 isStreaming 卡死 - P1-6: configLoaded 标志,配置加载前禁用发送按钮 - P1-7: MCP initialize 移到 agentLoop 后,完成后同步工具 - P2-11: beforeLoad 在 loadURL 前注册 IPC handler - P2-12: provider 切换竞态保护 前端状态同步修复: - clearSessions 后同步清空前端会话与消息状态 - clearMemories 通过 memoryVersion 触发 MemoryViewer 重新加载 - ContextMenu 4 个 session 操作补全 IPC 调用与 try/catch - useConfig 配置保存失败回滚 UI 并提示 - handleToggle 工具切换失败回滚单个工具状态 错误处理全量补全: - 所有 await window.metona 调用补全 try/catch 与 toast 反馈 - MCP addServer/toggleServer/removeServer 检查返回值 - showItemInFolder 检查返回值(handleOpen/handleOpenInFolder) - sse-stream/ollama NDJSON 解析失败改为 log.warn - adapter throwHttpError 带 status 属性供 isRetryableError 判断
This commit is contained in:
@@ -46,6 +46,7 @@ export function ChatInput(): React.JSX.Element {
|
||||
const sendMessage = useAgentStore((s) => s.sendMessage);
|
||||
const abort = useAgentStore((s) => s.abort);
|
||||
const isStreaming = useAgentStore((s) => s.isStreaming);
|
||||
const configLoaded = useAgentStore((s) => s.configLoaded);
|
||||
const tokenUsage = useAgentStore((s) => s.tokenUsage);
|
||||
const currentSessionId = useSessionStore((s) => s.currentSessionId);
|
||||
const provider = useAgentStore((s) => s.provider);
|
||||
@@ -171,6 +172,7 @@ export function ChatInput(): React.JSX.Element {
|
||||
const trimmed = input.trim();
|
||||
if (!trimmed && attachments.length === 0) return;
|
||||
if (isStreaming) return;
|
||||
if (!configLoaded) return; // P1-6: 配置未加载完成时禁止发送
|
||||
|
||||
// 处理 / 命令
|
||||
if (trimmed.startsWith('/')) {
|
||||
@@ -326,8 +328,8 @@ export function ChatInput(): React.JSX.Element {
|
||||
onChange={handleChange}
|
||||
onKeyDown={handleKeyDown}
|
||||
onPaste={handlePaste}
|
||||
placeholder="输入消息... (Cmd/Ctrl+Enter 发送, Cmd/Ctrl+Shift+Enter 换行, / 命令)"
|
||||
disabled={isStreaming}
|
||||
placeholder={configLoaded ? '输入消息... (Cmd/Ctrl+Enter 发送, Cmd/Ctrl+Shift+Enter 换行, / 命令)' : '正在加载配置...'}
|
||||
disabled={isStreaming || !configLoaded}
|
||||
multiline
|
||||
rows={1}
|
||||
sx={{
|
||||
@@ -363,7 +365,7 @@ export function ChatInput(): React.JSX.Element {
|
||||
<Square size={12} style={{ marginRight: 6 }} /> 中断
|
||||
</Button>
|
||||
) : (
|
||||
<Button variant="contained" size="small" onClick={handleSend} disabled={!input.trim() && attachments.length === 0} sx={{ height: 28, fontSize: 12, opacity: (input.trim() || attachments.length > 0) ? 1 : 0.5 }}>
|
||||
<Button variant="contained" size="small" onClick={handleSend} disabled={(!input.trim() && attachments.length === 0) || !configLoaded} sx={{ height: 28, fontSize: 12, opacity: (input.trim() || attachments.length > 0) && configLoaded ? 1 : 0.5 }}>
|
||||
<Send size={12} style={{ marginRight: 6 }} /> 发送
|
||||
</Button>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user