问题描述 / Description
当前工具调用实现中存在三个相互关联的缺陷,导致错误被错误地记录为成功、审计数据失真、以及调用方无法可靠区分成功与失败状态。
The current tool call implementation has three interrelated defects that cause errors to be incorrectly recorded as successes, corrupted audit data, and callers unable to reliably distinguish success from failure.
A. 双层异常处理互相冲突 / Double-Layer Exception Handling Conflict
位置 / Location: tool_registry.py:185-209,base_tool.py:228-246
handle_tool_exceptions 装饰器在工具方法内部捕获所有异常并返回错误字符串。注册表 execute 方法中的 try/except 因此永远无法触发,导致 status 始终为硬编码的 "success"。
The handle_tool_exceptions decorator catches all exceptions inside tool methods and returns error strings. Consequently, the try/except block in the registry's execute method never fires, keeping status stuck at the hardcoded "success".
# tool_registry.py:185-209
status = "success" # 初始设为 success,永远不会被改为 error
try:
result = tool.func(*args, **kwargs) # ← 装饰器已捕获异常并返回字符串
except Exception as e: # ← 永远不会执行
status = "error"
result = f'<func_name=...'
self._log_tool_call(func_name, kwargs, duration_ms, status) # status 永远是 "success"
影响 / Impact: 所有调用(包括失败的)在审计日志中均被记录为成功。依赖 status 的错误分类逻辑(如 tool_registry.py:259-270 的 PENDING_AUDIT 判定)完全失效。
All calls (including failures) are logged as successes in audit logs. Error classification logic depending on status (e.g., PENDING_AUDIT determination at tool_registry.py:259-270) is completely broken.
B. 返回类型不一致 / Inconsistent Return Types
位置 / Location: ls 工具,glob 工具,read 工具,stat 工具
| 工具 / Tool |
成功返回类型 / Success Return Type |
错误返回类型 / Error Return Type |
ls |
list[str] |
str |
glob |
list[str] |
str |
read |
str |
str |
stat |
str |
str |
影响 / Impact: 调用方无法通过类型系统可靠区分成功与错误。对 ls 结果调用 isinstance(result, list) 可以部分区分,但这是隐式约定而非显式协议。
Callers cannot reliably distinguish success from error via the type system. Using isinstance(result, list) on ls results works partially, but this is an implicit convention, not an explicit protocol.
C. 封装穿透 / Encapsulation Breach
位置 / Location: base_tool.py:184,edit_tool.py:109,write_tool.py:55
工具类直接访问 self.workspace._current_session_id(私有属性),绕过了 Workspace 的封装边界。
Tool classes directly access self.workspace._current_session_id (a private attribute), bypassing Workspace's encapsulation boundary.
影响 / Impact: 破坏模块化设计。Workspace 为 db 提供了 @property 做延迟加载,但 session_id 没有对等接口,封装策略不一致。
Breaks modular design. Workspace provides a @property for lazy loading db, but session_id has no equivalent interface — encapsulation strategy is inconsistent.
修复建议 / Fix Suggestions
-
移除或重构异常处理装饰器:让装饰器将异常转换为结构化结果(如 ToolResult(error=...))而非吞噬异常,或完全移除装饰器,让注册表层的 try/except 统一处理。
Remove or refactor the exception handling decorator: Let the decorator convert exceptions to structured results (e.g., ToolResult(error=...)) instead of swallowing them, or remove the decorator entirely and let the registry layer handle exceptions uniformly.
-
统一返回类型:所有工具应返回相同类型(如 ToolResult),显式包含 success 标志、数据或错误信息。
Unify return types: All tools should return the same type (e.g., ToolResult), explicitly containing a success flag, data, or error information.
-
修复封装穿透:为 Workspace 添加 session_id 的公开 getter(如 @property def session_id(self)),工具类通过该接口访问。
Fix encapsulation breach: Add a public getter for session_id on Workspace (e.g., @property def session_id(self)), and have tools access it via that interface.
问题描述 / Description
当前工具调用实现中存在三个相互关联的缺陷,导致错误被错误地记录为成功、审计数据失真、以及调用方无法可靠区分成功与失败状态。
The current tool call implementation has three interrelated defects that cause errors to be incorrectly recorded as successes, corrupted audit data, and callers unable to reliably distinguish success from failure.
A. 双层异常处理互相冲突 / Double-Layer Exception Handling Conflict
位置 / Location:
tool_registry.py:185-209,base_tool.py:228-246handle_tool_exceptions装饰器在工具方法内部捕获所有异常并返回错误字符串。注册表execute方法中的try/except因此永远无法触发,导致status始终为硬编码的"success"。The
handle_tool_exceptionsdecorator catches all exceptions inside tool methods and returns error strings. Consequently, thetry/exceptblock in the registry'sexecutemethod never fires, keepingstatusstuck at the hardcoded"success".影响 / Impact: 所有调用(包括失败的)在审计日志中均被记录为成功。依赖
status的错误分类逻辑(如tool_registry.py:259-270的PENDING_AUDIT判定)完全失效。All calls (including failures) are logged as successes in audit logs. Error classification logic depending on
status(e.g.,PENDING_AUDITdetermination attool_registry.py:259-270) is completely broken.B. 返回类型不一致 / Inconsistent Return Types
位置 / Location:
ls工具,glob工具,read工具,stat工具lslist[str]strgloblist[str]strreadstrstrstatstrstr影响 / Impact: 调用方无法通过类型系统可靠区分成功与错误。对
ls结果调用isinstance(result, list)可以部分区分,但这是隐式约定而非显式协议。Callers cannot reliably distinguish success from error via the type system. Using
isinstance(result, list)onlsresults works partially, but this is an implicit convention, not an explicit protocol.C. 封装穿透 / Encapsulation Breach
位置 / Location:
base_tool.py:184,edit_tool.py:109,write_tool.py:55工具类直接访问
self.workspace._current_session_id(私有属性),绕过了Workspace的封装边界。Tool classes directly access
self.workspace._current_session_id(a private attribute), bypassingWorkspace's encapsulation boundary.影响 / Impact: 破坏模块化设计。
Workspace为db提供了@property做延迟加载,但session_id没有对等接口,封装策略不一致。Breaks modular design.
Workspaceprovides a@propertyfor lazy loadingdb, butsession_idhas no equivalent interface — encapsulation strategy is inconsistent.修复建议 / Fix Suggestions
移除或重构异常处理装饰器:让装饰器将异常转换为结构化结果(如
ToolResult(error=...))而非吞噬异常,或完全移除装饰器,让注册表层的try/except统一处理。Remove or refactor the exception handling decorator: Let the decorator convert exceptions to structured results (e.g.,
ToolResult(error=...)) instead of swallowing them, or remove the decorator entirely and let the registry layer handle exceptions uniformly.统一返回类型:所有工具应返回相同类型(如
ToolResult),显式包含success标志、数据或错误信息。Unify return types: All tools should return the same type (e.g.,
ToolResult), explicitly containing asuccessflag, data, or error information.修复封装穿透:为
Workspace添加session_id的公开 getter(如@property def session_id(self)),工具类通过该接口访问。Fix encapsulation breach: Add a public getter for
session_idonWorkspace(e.g.,@property def session_id(self)), and have tools access it via that interface.