Native Responses schema for code_execution_tool admits calls without code — schema guard missing (follow-up to #69/#68) #194

Open
opened 2026-09-09 15:05:33 +00:00 by nsaspy · 0 comments
Owner

Summary

The KeyError crash itself is tracked in #69 / #68, but live debugging of the deployed image (commit ffa5845b, which added a strict native schema for code_execution_tool) shows the schema guard is incomplete: the advertised schema only requires runtime, so provider-native tool calls that omit code pass validation and still crash the tool.

Evidence (all from 2026-09-04, container UTC times)

  • Chat Ct12wUKJ ("SSH key setup"), entries 77-79 and 89-91: model emits
    {"runtime":"terminal","session":0,"reset":false,"allow_running":false} — no code — schema accepts it, code_execution_tool.py raises KeyError: 'code' at self.args["code"], the framework logs "Critical error occurred, retrying...", and with _error_retry configured at retries: 10 the identical failing turn is re-requested.
  • Chat Fy2aJr64 ("Git origin update"): the same KeyError: 'code' critical-retry cycle appears at entries 5, 15, 18, 26, 32.
  • Reproduced live at 15:15:11Z on the already-patched image (console log: Runtime: terminal / Session: 0 / Reset: False / Allow running: False with no Code: line) → same crash. User-visible symptom is the "model keeps sending the same output" loop.

Root cause

  • plugins/_code_execution/prompts/agent.system.tool.code_exe.md declares
    Input schema for tool_args: {"type":"object","required":["runtime"],...}.
  • helpers/responses_tools._schema_from_prompt() uses that declaration verbatim as the native Responses function-tool parameters, so the provider-side JSON schema permits omitting code for every runtime.
  • The tool then does unguarded self.args["code"] (plugins/_code_execution/tools/code_execution_tool.py:68-76).

Suggested fix

  1. Schema: make code conditionally required for runtime in {terminal,python,nodejs} (e.g. allOf/if-then on the runtime enum), keeping output/reset code-free.
  2. Defense in depth in CodeExecution.execute: read code = self.args.get("code", "") and return a repairable tool response ("code argument is required for runtime X") instead of raising, so the model gets one corrective tool result instead of a critical-error retry loop.

Both layers are needed: the schema prevents the bad call, the tool guard turns an inevitable residual into a cheap repairable error instead of an expensive retry loop.

Cross-ref: lost-rob0t/a0-symbolics#73


Mirrored from lost-rob0t/a0-symbolics#83 via tracker sync.

## Summary The KeyError crash itself is tracked in #69 / #68, but live debugging of the deployed image (commit `ffa5845b`, which added a strict native schema for `code_execution_tool`) shows the schema guard is incomplete: the advertised schema only requires `runtime`, so provider-native tool calls that omit `code` pass validation and still crash the tool. ## Evidence (all from 2026-09-04, container UTC times) - Chat `Ct12wUKJ` ("SSH key setup"), entries 77-79 and 89-91: model emits `{"runtime":"terminal","session":0,"reset":false,"allow_running":false}` — no `code` — schema accepts it, `code_execution_tool.py` raises `KeyError: 'code'` at `self.args["code"]`, the framework logs "Critical error occurred, retrying...", and with `_error_retry` configured at `retries: 10` the identical failing turn is re-requested. - Chat `Fy2aJr64` ("Git origin update"): the same `KeyError: 'code'` critical-retry cycle appears at entries 5, 15, 18, 26, 32. - Reproduced live at `15:15:11Z` on the already-patched image (console log: `Runtime: terminal / Session: 0 / Reset: False / Allow running: False` with no `Code:` line) → same crash. User-visible symptom is the "model keeps sending the same output" loop. ## Root cause - `plugins/_code_execution/prompts/agent.system.tool.code_exe.md` declares `Input schema for tool_args: {"type":"object","required":["runtime"],...}`. - `helpers/responses_tools._schema_from_prompt()` uses that declaration verbatim as the native Responses function-tool `parameters`, so the provider-side JSON schema permits omitting `code` for every runtime. - The tool then does unguarded `self.args["code"]` (`plugins/_code_execution/tools/code_execution_tool.py:68-76`). ## Suggested fix 1. Schema: make `code` conditionally required for `runtime` in {`terminal`,`python`,`nodejs`} (e.g. `allOf`/`if-then` on the runtime enum), keeping `output`/`reset` code-free. 2. Defense in depth in `CodeExecution.execute`: read `code = self.args.get("code", "")` and return a repairable tool response ("`code` argument is required for runtime X") instead of raising, so the model gets one corrective tool result instead of a critical-error retry loop. Both layers are needed: the schema prevents the bad call, the tool guard turns an inevitable residual into a cheap repairable error instead of an expensive retry loop. Cross-ref: lost-rob0t/a0-symbolics#73 --- *Mirrored from [`lost-rob0t/a0-symbolics#83`](https://github.com/lost-rob0t/a0-symbolics/issues/83)* via tracker sync.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nsaspy/a0-symbolics#194
No description provided.