Skip to content

Make Tool failures actionable to the model - #953

Draft
Y1fe1Zh0u wants to merge 2 commits into
dataelement:002-tool-runtime-contractfrom
Y1fe1Zh0u:fix/tool-failure-feedback
Draft

Make Tool failures actionable to the model#953
Y1fe1Zh0u wants to merge 2 commits into
dataelement:002-tool-runtime-contractfrom
Y1fe1Zh0u:fix/tool-failure-feedback

Conversation

@Y1fe1Zh0u

Copy link
Copy Markdown
Collaborator

What changed

  • carry one provider-neutral is_error bit on model-facing Tool Results
  • render failed and unknown Tool outcomes with an explicit label and sanitized remediation text
  • map failures to Anthropic tool_result.is_error
  • map Gemini Tool responses to response.error for failures and response.output for success
  • keep OpenAI Chat and Responses on their native Tool output shape with the improved error body

Why

Runtime already retained the Tool failure summary and optional safe remediation, but _prompt_messages() only forwarded plain content and the original Call ID. Anthropic and Gemini therefore received no native failure signal, and the remediation never reached the model. This made argument repair depend on guessing from an unlabelled string.

The change intentionally does not serialize internal Runtime control fields such as model_action, side_effect_state, Receipt metadata, or reconciliation state into the model protocol.

Impact

A model now receives a call-linked failure such as:

Tool failed: $.path is required

Suggested correction: Provide a non-empty path.

Provider adapters additionally express the failure using their native representation where available.

Validation

  • 149 scoped model-step, provider-boundary, and Tool-step tests passed
  • scoped Ruff passed
  • git diff --check passed

Stack

This draft targets 002-tool-runtime-contract because the Runtime Tool outcome and StepToolContext implementation is currently in PR #945 and has not yet merged into main.

Set the existing protocol repair, safe-read replay, and model-visible Tool episode limits to ten while preserving their current independent state and execution semantics. Update focused tests and planning artifacts to make the off-by-one behavior explicit.

Constraint: Tool-related retry and repair limits must be ten without restructuring the existing counters

Rejected: Unify protocol, Receipt, and model-visible repair state now | counter redesign is intentionally deferred

Confidence: high

Scope-risk: moderate

Directive: Keep the independent counters until the planned repair-control refactor; do not infer identical attempt semantics from the shared numeric limit

Tested: 911 Runtime and Tool pytest cases; scoped Ruff; fatal-level caller Ruff; py_compile; git diff --check

Not-tested: Live Provider credentials
Runtime Tool results already retain sanitized failure summaries and optional remediation, but the model boundary discarded the failure signal and remediation text. Carry one provider-neutral error bit, render actionable failure text, and map it to native Anthropic and Gemini representations.

Constraint: Keep Runtime control fields such as model_action and side_effect_state out of the model protocol.

Rejected: Serialize the complete internal Tool outcome | couples provider prompts to Runtime control metadata.

Confidence: high

Scope-risk: narrow

Directive: Expected Tool failures should provide sanitized result_summary and safe_remediation at their source.

Tested: 151 scoped model-step, provider-boundary, and Tool-step tests; scoped Ruff; git diff --check.

Not-tested: Live Anthropic, Gemini, and OpenAI provider calls.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant