Skip to content

fix(agent): sanitize unanswered tool_calls on interrupt to prevent transcript corruption - #11354

Closed
nicoechaniz wants to merge 1 commit into
NousResearch:mainfrom
nicoechaniz:fix/interrupt-history-sanitization
Closed

nicoechaniz wants to merge 1 commit into
NousResearch:mainfrom
nicoechaniz:fix/interrupt-history-sanitization

Conversation

@nicoechaniz

Copy link
Copy Markdown
Contributor

Summary

Fixes a bug where interrupting the agent during pending tool calls leaves the conversation transcript in an invalid state, causing the next API call to fail with a "missing tool response" error.

Closes #11351

Changes

  • Adds _sanitize_unanswered_tool_calls() helper to AIAgent in run_agent.py.
  • Calls the helper from _persist_session() so every exit path guarantees an API-valid transcript.
  • Removes the duplicated inline backfill logic from the outer-loop error handler.

Testing

  • Local pytest passes
  • Rebased on latest origin/main

Backwards compatibility

No behavior change for users — this only prevents a crash condition.

@nicoechaniz
nicoechaniz force-pushed the fix/interrupt-history-sanitization branch 2 times, most recently from 91aea29 to fd704ea Compare April 20, 2026 05:28
@nicoechaniz

Copy link
Copy Markdown
Contributor Author

Hi @teknium1 — this fixes transcript corruption when interrupts leave unanswered tool_calls in flight. Rebased on latest main and ready for review. Thanks!

@nicoechaniz
nicoechaniz force-pushed the fix/interrupt-history-sanitization branch from fd704ea to 114522c Compare April 22, 2026 02:24
@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint labels Apr 22, 2026
…anscript corruption

Adds _sanitize_unanswered_tool_calls() to backfill synthetic role=tool
results for any assistant tool_calls that weren't answered before an
interrupt or error exits the loop. This prevents the next API call from
failing with a missing tool response error.

Also removes the duplicated inline logic from the outer-loop error
handler and calls the helper from _persist_session() so every exit
path guarantees an API-valid transcript.
@nicoechaniz
nicoechaniz force-pushed the fix/interrupt-history-sanitization branch from 114522c to ed382e4 Compare April 22, 2026 07:21
@teknium1

Copy link
Copy Markdown
Collaborator

Thanks for the careful writeup and the rebase work, @nicoechaniz! This hermes-sweeper automated review found that current main already covers the reported failure mode.

The bug is already fixed on main by two existing mechanisms:

  • _sanitize_api_messages() (pre-call sanitizer) — Introduced in commit 85993fbb5 (feat: pre-call sanitization and post-call tool guardrails #1732, merged 2026-03-17). It runs unconditionally before every LLM API call and injects synthetic role=tool stub results for any tool_call_id that was never answered (run_agent.py:4597 — step 2 of the method). Called at run_agent.py:9644.
  • Inline cancel messages on interrupt — Both _execute_tool_calls_sequential (run_agent.py:8515) and the pre-flight check in _execute_tool_calls_concurrent (run_agent.py:8216) already append {role: "tool", content: "[Tool execution cancelled…]", tool_call_id: …} for every skipped call immediately at interrupt time.

The proposed _sanitize_unanswered_tool_calls() helper + _persist_session() hook would duplicate what _sanitize_api_messages() already does. Closing as already implemented. No action needed on your end — the fix you described shipped roughly a month ago!

@teknium1 teknium1 closed this Apr 27, 2026
@nicoechaniz
nicoechaniz deleted the fix/interrupt-history-sanitization branch April 28, 2026 03:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P1 High — major feature broken, no workaround type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Interrupt during tool execution corrupts conversation transcript with missing tool responses

3 participants