diff --git a/data/goals/_index.json b/data/goals/_index.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/data/goals/_index.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/data/system/agents/master/memory/short-term/session-1774547297290.md b/data/system/agents/master/memory/short-term/session-1774547297290.md new file mode 100644 index 0000000..5ba336f --- /dev/null +++ b/data/system/agents/master/memory/short-term/session-1774547297290.md @@ -0,0 +1,15 @@ +# Session 摘要 + +- **时间**: 2026-03-26 17:48:17 +- **对话ID**: conv-mn7rjae6 +- **状态**: completed +- **工具调用**: 0 次 +- **耗时**: 3分钟 + +## 任务 +我需要创建一个名为 ABC 的 AI 互动剧公司。这家公司的核心业务逻辑和组织架构诉求如下: + +一、 + +## 结果 +API Error: 429 {"type":"error","error":{"type":"rate_limit_error","message":"usage limit exceeded (2056)"},"request_id":"0614a461f8ade83e80e74a117efb3ac7"} diff --git a/packages/acp-core/protocol/ClaudeCliProtocol.js b/packages/acp-core/protocol/ClaudeCliProtocol.js index 6c7fea2..256fa5d 100644 --- a/packages/acp-core/protocol/ClaudeCliProtocol.js +++ b/packages/acp-core/protocol/ClaudeCliProtocol.js @@ -96,12 +96,21 @@ class ClaudeCliProtocol extends EventEmitter { } }); - // stderr 转发 + // stderr 转发 + 致命错误检测 this._child.stderr.on('data', (data) => { const msg = data.toString().trim(); if (msg) { console.log('[ClaudeCliProtocol] stderr:', msg.substring(0, 300)); this.emit('stderr', msg); + + // 检测致命错误:如果 sendPrompt 正在等待,主动 reject 防止 Promise 永远挂起 + if (this._promptReject && /rate.?limit|usage.?limit|429|401|403|authentication|api.?key|quota|billing/i.test(msg)) { + const err = new Error(`Claude CLI 致命错误: ${msg.substring(0, 500)}`); + this._promptReject(err); + this._promptResolve = null; + this._promptReject = null; + console.error('[ClaudeCliProtocol] 致命错误已触发 Promise reject'); + } } }); diff --git a/server/routes/agent-chat.js b/server/routes/agent-chat.js index 03c20a6..6ca8d7d 100644 --- a/server/routes/agent-chat.js +++ b/server/routes/agent-chat.js @@ -1734,12 +1734,31 @@ router.post('/:agentId/chat', async (req, res) => { entry.protocol.on('session_update', onUpdate); entry.protocol.on('acp_event', onAcpEvent); + // 监听 stderr / error / disconnect — 将 Claude CLI 错误实时推送到前端 + const onStderr = (msg) => { + console.warn(`[AgentChat] stderr from ${agentId}:`, msg.substring(0, 300)); + sendSSE('acp_raw', { method: 'claude/stderr', params: { message: msg }, ts: Date.now() }); + // 如果包含严重错误关键词,额外发一条 error 事件 + if (/error|rate.?limit|429|403|timeout|ECONNREFUSED|failed/i.test(msg)) { + sendSSE('error', { message: `⚠️ Claude CLI: ${msg.substring(0, 500)}` }); + } + }; + const onDisconnected = ({ code, signal }) => { + if (code !== 0) { + sendSSE('error', { message: `Claude CLI 异常退出 (code=${code}, signal=${signal})` }); + } + }; + entry.protocol.on('stderr', onStderr); + entry.protocol.on('disconnected', onDisconnected); + // 发送 prompt 并等待完成 await entry.protocol.sendPrompt(prompt); // 清理监听 entry.protocol.off('session_update', onUpdate); entry.protocol.off('acp_event', onAcpEvent); + entry.protocol.off('stderr', onStderr); + entry.protocol.off('disconnected', onDisconnected); // 持久化当前轮次的回复 if (fullOutput) { diff --git a/web/src/views/AgentChat.vue b/web/src/views/AgentChat.vue index 00527b2..32ed749 100644 --- a/web/src/views/AgentChat.vue +++ b/web/src/views/AgentChat.vue @@ -564,7 +564,10 @@ function handleEvent(type, data) { else if (data.event === 'start') subAgents.value[data.callId].status = 'running' scrollToBottom(); break case 'error': - messages.value.push({ role: 'assistant', content: `❌ ${data.message}`, timestamp: new Date().toISOString() }); break + messages.value.push({ role: 'assistant', content: `❌ ${data.message}`, timestamp: new Date().toISOString() }) + acpLog.value.push({ type: 'error', icon: '🚨', text: data.message, ts: Date.now() }) + thinkingText.value = ''; thinkingContent.value = '' + scrollToBottom(); scrollAcpLog(); break } }