fix(acp): also mark raised-exception tool results as failed

Extends #26573 to also catch the case the original PR deliberately left
out: when a tool raises an exception, the agent's tool executor wraps it
in a canonical 'Error executing tool '<name>': ...' string prefix (see
agent/tool_executor.py around the try/except). That prefix is unique to
the wrapper and cannot legitimately appear in well-behaved tool output,
so it is a safe signal that the tool blew up.

Without this, the canonical 'tool raised' case still rendered as a green
'completed' row in Zed despite being a runtime failure — exactly the
class of bug #26573 set out to fix.

Adds a positive test (raised-exception prefix -> failed) and a negative
test (bare 'Error:' word in legit tool output stays completed) so a
future contributor doesn't accidentally widen the rule to false-positive
on compiler/linter diagnostics.
This commit is contained in:
teknium1
2026-05-18 11:43:19 -07:00
committed by Teknium
parent 9cf1140caa
commit eda1c97a1e
2 changed files with 34 additions and 0 deletions

View File

@@ -209,6 +209,15 @@ def _tool_result_failed(result: Optional[str], tool_name: str | None = None) ->
"error" because tests failed or a command printed diagnostics; Zed should
only receive ACP failed status for structured tool-level failures.
"""
# Raised exceptions from the agent's tool executor get wrapped in a
# canonical "Error executing tool '<name>': ..." prefix (see
# agent/tool_executor.py around the try/except). That prefix is uniquely
# produced by the wrapper itself — it cannot legitimately appear in
# well-behaved tool output. Catch it so a tool that blew up shows as
# failed in Zed instead of misleadingly green.
if isinstance(result, str) and result.startswith("Error executing tool '"):
return True
data = _json_loads_maybe(result)
if not isinstance(data, dict):
return False