Bug Description
run_agent.py can misclassify a valid tool result as missing when tool_call_id contains leading or trailing whitespace.
The current pre-call sanitizer normalizes assistant-side tool call IDs via _build_assistant_message(), but _sanitize_api_messages() compares tool results using the raw tool_call_id string from persisted history.
This can cause Hermes to inject:
[Result unavailable — see context summary above]
…even though the real tool result is present in the session.
Steps to Reproduce
- Build a message list where the assistant tool call uses
functions.cronjob:24
- Add a matching
role="tool" message whose tool_call_id is " functions.cronjob:24"
- Call
AIAgent._sanitize_api_messages(messages)
Expected Behavior
The tool result should be preserved because the IDs are semantically the same after trimming whitespace.
Actual Behavior
The sanitizer treats the tool result as missing/orphaned and may inject a synthetic stub:
[Result unavailable — see context summary above]
Root Cause Analysis
_build_assistant_message() already strips whitespace from assistant-side tool call IDs, but _sanitize_api_messages() was still:
- collecting
result_call_ids from raw tool_call_id values
- filtering orphaned tool messages using raw
tool_call_id values
So assistant-side IDs and tool-result IDs could diverge purely because of surrounding whitespace.
Proposed Fix
Normalize tool-call IDs before every comparison in _sanitize_api_messages().
A small helper such as AIAgent._normalize_tool_call_id() is enough.
Regression Test Suggestion
Add coverage for both:
- Preserving a valid tool result when
tool_call_id has leading whitespace
- Still stripping a truly orphaned tool result when its
tool_call_id has surrounding whitespace
Are you willing to submit a PR for this?
Bug Description
run_agent.pycan misclassify a valid tool result as missing whentool_call_idcontains leading or trailing whitespace.The current pre-call sanitizer normalizes assistant-side tool call IDs via
_build_assistant_message(), but_sanitize_api_messages()compares tool results using the rawtool_call_idstring from persisted history.This can cause Hermes to inject:
…even though the real tool result is present in the session.
Steps to Reproduce
functions.cronjob:24role="tool"message whosetool_call_idis" functions.cronjob:24"AIAgent._sanitize_api_messages(messages)Expected Behavior
The tool result should be preserved because the IDs are semantically the same after trimming whitespace.
Actual Behavior
The sanitizer treats the tool result as missing/orphaned and may inject a synthetic stub:
Root Cause Analysis
_build_assistant_message()already strips whitespace from assistant-side tool call IDs, but_sanitize_api_messages()was still:result_call_idsfrom rawtool_call_idvaluestool_call_idvaluesSo assistant-side IDs and tool-result IDs could diverge purely because of surrounding whitespace.
Proposed Fix
Normalize tool-call IDs before every comparison in
_sanitize_api_messages().A small helper such as
AIAgent._normalize_tool_call_id()is enough.Regression Test Suggestion
Add coverage for both:
tool_call_idhas leading whitespacetool_call_idhas surrounding whitespaceAre you willing to submit a PR for this?