Skip to content

fix: strip extra_content from tool_calls for strict APIs (Fireworks, Mistral)#18663

Closed
nateGeorge wants to merge 1 commit into
NousResearch:mainfrom
nateGeorge:fix-fireworks-toolcalls
Closed

fix: strip extra_content from tool_calls for strict APIs (Fireworks, Mistral)#18663
nateGeorge wants to merge 1 commit into
NousResearch:mainfrom
nateGeorge:fix-fireworks-toolcalls

Conversation

@nateGeorge

@nateGeorge nateGeorge commented May 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes HTTP 400 errors on strict OpenAI-compatible providers (Fireworks, Mistral) when tool_calls contain extra_content fields.

Problem

Gemini 3 thinking models attach extra_content (thought_signature) to tool_calls for replay on subsequent API calls. When these messages are replayed to strict providers like Fireworks, they reject the request with:

HTTP 400: Extra inputs are not permitted, field: 'messages[N].tool_calls[M].extra_content'

This causes the first message of every new session to fail on Fireworks, forcing fallback to other providers (issue #17986).

Changes

  • agent/transports/chat_completions.py: Strip extra_content from tool_calls in convert_messages() alongside existing call_id/response_item_id stripping
  • run_agent.py: Add extra_content to _sanitize_tool_calls_for_strict_api() _STRIP_KEYS set

Testing

  • Added test in tests/agent/transports/test_chat_completions.py
  • Added test in tests/run_agent/test_provider_parity.py
  • Both tests pass locally

Related Issues

…Mistral)

Strict OpenAI-compatible providers like Fireworks reject tool_calls with
extra_content fields with HTTP 400 'Extra inputs are not permitted'.
This happens when Gemini 3 thinking models attach extra_content
(thought_signature) to tool_calls, which gets replayed on subsequent
API calls.

- agent/transports/chat_completions.py: Strip extra_content from tool_calls
  in convert_messages() along with call_id/response_item_id
- run_agent.py: Add extra_content to _sanitize_tool_calls_for_strict_api()
  _STRIP_KEYS set

Fixes NousResearch#17986 (HTTP 400 on Fireworks custom endpoint — first turn only)
Related: NousResearch#893, NousResearch#5183
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent loop, run_agent.py, prompt builder labels May 2, 2026
Cyrene963 pushed a commit to Cyrene963/hermes-agent that referenced this pull request May 3, 2026
Community PRs applied:
- NousResearch#18596: Enable secret redaction by default (SECURITY)
- NousResearch#18650: Sanitize malformed tool messages + auto-recover on API 400
- NousResearch#18607: Emergency compression before max_iterations exhaustion
- NousResearch#18603: Compression fallback to main model on 413 rate limit
- NousResearch#18638: Pass threshold_percent on model switch
- NousResearch#18663: Strip extra_content from tool_calls for strict APIs
- NousResearch#18618: Forward explicit_api_key to OpenRouter
- NousResearch#18632: Show cache tokens in /insights breakdown
- NousResearch#18614: Add idempotency guard for patch duplicate loops
- NousResearch#18600: Raise ValueError when HERMES_HOME unset in profile mode
- NousResearch#18616: Allow ZWJ emoji in context files
- NousResearch#18582: Reload .env on /restart
- NousResearch#18547: Stabilize system prompt prefix for KV cache reuse
- NousResearch#18692: Strip FTS5 operators from session search truncation terms

Fix: Add order_by_last_active=True to list_sessions_rich call
(pre-existing commit 142b4bf code sync)
@teknium1

teknium1 commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Merged via PR #38543 (commit e8c3ac2) — your fix cherry-picked onto current main with your authorship preserved in git log. I extended the strip to be model-aware (keep extra_content for Gemini-family targets, which need the thought_signature replayed; strip it for strict providers like Fireworks/Mistral) so it doesn't regress Gemini-on-aggregator. Thanks for the fix and the clear root-cause writeup. Closes #17986.

@teknium1 teknium1 closed this Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent loop, run_agent.py, prompt builder P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Title: HTTP 400 on Fireworks custom endpoint — first turn only, fallback succeeds

3 participants