diff --git a/packages/acp-core/protocol/ClaudeCliProtocol.js b/packages/acp-core/protocol/ClaudeCliProtocol.js index ac143f5..f55eaa6 100644 --- a/packages/acp-core/protocol/ClaudeCliProtocol.js +++ b/packages/acp-core/protocol/ClaudeCliProtocol.js @@ -81,7 +81,9 @@ class ClaudeCliProtocol extends EventEmitter { // stdout → NDJSON 解析 this._child.stdout.on('data', (data) => { - this._buffer += data.toString(); + const raw = data.toString(); + console.log(`[ClaudeCliProtocol] 📥 stdout (${raw.length} bytes):`, raw.substring(0, 200)); + this._buffer += raw; const lines = this._buffer.split('\n'); this._buffer = lines.pop() || ''; @@ -103,7 +105,7 @@ class ClaudeCliProtocol extends EventEmitter { this._child.stderr.on('data', (data) => { const msg = data.toString().trim(); if (msg) { - console.log('[ClaudeCliProtocol] stderr:', msg.substring(0, 300)); + console.log(`[ClaudeCliProtocol] 🚨 stderr (${msg.length} bytes):`, msg.substring(0, 500)); this.emit('stderr', msg); // 检测致命错误:如果 sendPrompt 正在等待,主动 reject 防止 Promise 永远挂起 @@ -252,6 +254,7 @@ class ClaudeCliProtocol extends EventEmitter { * @private */ _handleStreamEvent(event) { + console.log(`[ClaudeCliProtocol] 🔄 event.type=${event.type}`); switch (event.type) { case 'system': this.sessionId = event.session_id || this.sessionId; @@ -302,6 +305,26 @@ class ClaudeCliProtocol extends EventEmitter { this._promptReject = null; } break; + case 'error': + this.emit('acp_event', { + type: 'notification', + method: 'claude/error', + params: event, + timestamp: Date.now(), + }); + + // API 报错(如 MiniMax 429)会通过 stdout 下发 error 对象,此时不会下发 result + if (this._promptReject) { + const errMsg = event.error?.message || event.message || JSON.stringify(event); + const err = new Error(`API 请求失败: ${errMsg}`); + console.error(`[ClaudeCliProtocol] 拦截到底层 API 错误:`, err.message); + + if (this._idleTimer) { clearTimeout(this._idleTimer); this._idleTimer = null; } + this._promptReject(err); + this._promptResolve = null; + this._promptReject = null; + } + break; default: this.emit('acp_event', { diff --git a/server/routes/agent-chat.js b/server/routes/agent-chat.js index 6ca8d7d..40bfde4 100644 --- a/server/routes/agent-chat.js +++ b/server/routes/agent-chat.js @@ -1664,6 +1664,7 @@ router.post('/:agentId/chat', async (req, res) => { const onUpdate = (payload) => { const update = payload.update; if (update?.sessionUpdate === 'agent_message_chunk' && update.content?.text) { + console.log(`[SSE-DEBUG] 📤 agent_output (${update.content.text.length} chars)`); fullOutput += update.content.text; logMessageChunk(agentId, convId, update.content.text); sendSSE('agent_output', { agent: agentId, message: update.content.text }); @@ -1751,6 +1752,9 @@ router.post('/:agentId/chat', async (req, res) => { entry.protocol.on('stderr', onStderr); entry.protocol.on('disconnected', onDisconnected); + // 发出状态以便前端展示不卡壳 + sendSSE('agent_output', { agent: agentId, message: `_[系统正在通过 \`${fullSystemConfig.model}\` 请求响应...]_\\\n\\\n` }); + // 发送 prompt 并等待完成 await entry.protocol.sendPrompt(prompt); @@ -1895,6 +1899,7 @@ ${resultsText.join('\n\n')} sessions.delete(key); sendSSE('error', { message: err.message }); + console.log(`[SSE-DEBUG] 🚨 sendSSE('error') called:`, err.message.substring(0, 200)); } finally { res.end(); }