[Fix] Improve tool error handling and async operations#622
Conversation
…ions - Add default error handler for tool runtime errors in AgentExecutor - Convert non-string tool observations to JSON instead of throwing - Make MCP tool calls properly await async operations - Improve MCP tool response logging to avoid unnecessary stringification These changes ensure better error resilience and proper async handling in both core agent execution and MCP tool integration.
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters (26)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including You can disable this status message by setting the Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 总体概览本变更对代理执行器的错误处理机制进行了调整,将非字符串工具观测值从抛出异常改为日志警告并强制转换;同时优化了MCP客户端的异步调用流程和日志输出格式。 变更概览
序列图sequenceDiagram
participant Agent as 代理执行器
participant Tool as 工具调用
participant Result as 返回结果
Agent->>Tool: 调用工具
Tool->>Result: 执行工具逻辑
alt 返回字符串观测值
Result-->>Agent: 字符串结果
Agent->>Agent: 直接使用观测值
else 返回非字符串观测值
Result-->>Agent: 非字符串对象
Agent->>Agent: ⚠️ 记录警告日志
Agent->>Agent: JSON.stringify()强制转换
Agent->>Agent: 继续执行(无异常)
end
Note over Agent: handleToolRuntimeErrors<br/>提供降级错误处理
代码审查工作量估计🎯 2 (简单) | ⏱️ ~12 分钟
需要重点关注的区域:
可能相关的PR
诗歌
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @dingyi222666, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the stability and reliability of agent tool execution by improving error handling mechanisms and ensuring correct asynchronous operation management. It addresses several bug fixes related to unhandled exceptions, non-string tool outputs, and proper awaiting of async calls within the MCP tool integration, alongside minor improvements to logging and type safety. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces several valuable improvements to error handling and asynchronous operations. Key changes include adding a default error handler in AgentExecutor to prevent unhandled exceptions, gracefully handling non-string tool observations by converting them to JSON, and fixing an issue with awaiting asynchronous MCP tool calls. These changes enhance the robustness and reliability of the agent. My review includes a suggestion to refine the new default error handler to provide cleaner error messages and avoid exposing internal implementation details.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/extension-mcp/src/utils.ts (1)
391-396: 返回值类型与实现不一致(会导致编译错误/运行时歧义)_here_返回了字符串而函数签名要求第一个元素为内容块数组。应返回内容块数组以保持与签名和调用方约定一致。
建议改为保持数组形态(或移除该特判),例如:
- if (convertedContent.length === 1 && convertedContent[0].type === 'text') { - return [convertedContent[0].text, []] // artifacts] - } + if (convertedContent.length === 1 && convertedContent[0].type === 'text') { + return [convertedContent, []] // 保持内容块数组形态 + }packages/core/src/llm-core/agent/executor.ts (1)
731-759: 流式/分步路径未对工具运行时错误应用同样的兜底(与上方路径不一致)这里仅处理了
ToolInputParsingException,其他运行时错误将导致空观察值,用户体验不一致。建议与上方路径对齐,使用
handleToolRuntimeErrors兜底,并保持字符串化一致性:try { observation = await tool.invoke( agentAction.toolInput, runManager?.getChild() ) if (typeof observation !== 'string') { logger.warn( `Tool ${tool.name} returned non-string observation`, observation ) observation = JSON.stringify(observation) } - } catch (e) { + } catch (e) { if (e instanceof ToolInputParsingException) { ... - } + } else if (this.handleToolRuntimeErrors !== undefined) { + observation = this.handleToolRuntimeErrors(e as Error) + } else { + observation = 'Tool execution failed.' + } }
🧹 Nitpick comments (6)
packages/extension-mcp/src/utils.ts (2)
480-483: 日志记录直接打印对象可能放大日志与泄露大字段直接传入
result可能在某些 logger 中输出巨大 base64/二进制或嵌套对象,影响性能与可读性。建议仅输出关键信息(如isError与content中各项的type),并对内容长度做截断。示例:
-logger.debug( - `MCP tool '${toolName}' on server '${serverName}' returned:`, - result -) +logger.debug( + `MCP tool '${toolName}' on server '${serverName}' returned:`, + { + isError: (result as any)?.isError, + types: Array.isArray((result as any)?.content) + ? (result as any).content.map((c: any) => c?.type).slice(0, 10) + : typeof (result as any)?.content + } +)
503-521: 命名小问题:参数名应为 mimeType(非 mineType)当前
putResourceToStorage使用了mineType,容易误解且与上文调用的不一致。建议更正命名以提升可读性。-async function putResourceToStorage( - ctx: Context, - blob: string | Buffer, - mineType: string -) { +async function putResourceToStorage( + ctx: Context, + blob: string | Buffer, + mimeType: string +) { - const extension = mimeTypes.extension(mineType) + const extension = mimeTypes.extension(mimeType) ... - if (!extension) { - throw new Error(`Unsupported mime type: ${mineType}`) + if (!extension) { + throw new Error(`Unsupported mime type: ${mimeType}`) }packages/extension-mcp/src/service.ts (1)
258-259: 传入的 serverName 实际是工具名,日志含义可能混乱此处
serverName: name中的name来自工具名,而非服务器标识。utils.ts 中的日志/报错会将其当作“服务器名”展示,容易误导排查。建议在构建
toolToClientMap时同时保存一个可识别的服务器标识(如url或command摘要),并在此处传入该标识作为serverName。packages/core/src/llm-core/agent/executor.ts (3)
395-397: 新增默认的工具运行时错误处理器默认处理器可避免空观察值,提升鲁棒性。注意:拼接原始错误信息可能在生产中暴露实现细节。建议在生产构建中可选地隐藏具体错误内容,仅保留友好提示。
579-595: 对非字符串观察值进行告警并 JSON 序列化的策略是合理的此变更与上游返回的“content_and_artifact”响应兼容,避免抛错。若担心循环结构导致
JSON.stringify失败,可考虑降级为util.inspect或使用安全序列化库。
588-589: 无效工具提示建议统一口径两处无效工具提示信息不一致(一个不含可用列表,一个包含)。建议统一并包含可用工具列表,便于模型自纠。
示例(第一处):
-: `${action.tool} is not a valid tool, try another one.` +: `${action.tool} is not a valid tool, try another available tool: ${Object.keys(toolsByName).join(', ')}`Also applies to: 761-766
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/core/src/llm-core/agent/executor.ts(4 hunks)packages/extension-mcp/src/service.ts(1 hunks)packages/extension-mcp/src/utils.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
packages/extension-mcp/src/service.ts (1)
packages/extension-mcp/src/utils.ts (1)
callTool(438-501)
packages/core/src/llm-core/agent/executor.ts (3)
packages/adapter-zhipu/src/client.ts (1)
logger(29-31)packages/extension-mcp/src/index.ts (1)
logger(8-8)packages/extension-long-memory/src/index.ts (1)
logger(9-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: lint
- GitHub Check: build
🔇 Additional comments (1)
packages/extension-mcp/src/service.ts (1)
253-264: 显式 await 是必要的(修正异步顺序问题)
return await callTool(...)保证在工具链继续前已拿到结果,匹配上游执行器的观察值处理逻辑。变更合理。如需确认端到端行为,请用一条会返回非字符串内容块的 MCP 工具做一次实际调用,确保不再出现“Promise 被传递”为观察值的情况。
- Bump core package to 1.3.0-alpha.78 - Bump extension-mcp to 1.3.0-alpha.16 - Update peer dependency references across all adapter and extension packages
This PR improves error handling in agent tool execution and fixes async operation handling in MCP tool integration.
Bug fixes
Other Changes