Skip to content

fix(agent,transport): drop empty tool_calls array for strict API compatibility - #68942

Closed
lapapatech wants to merge 2 commits into
NousResearch:mainfrom
lapapatech:fix/empty-tool-calls-strict-apis
Closed

fix(agent,transport): drop empty tool_calls array for strict API compatibility#68942
lapapatech wants to merge 2 commits into
NousResearch:mainfrom
lapapatech:fix/empty-tool-calls-strict-apis

Conversation

@lapapatech

Copy link
Copy Markdown

Problem

DeepSeek and Fireworks (among other strict API providers) reject assistant messages containing tool_calls: [] with HTTP 400:

Expected an array with minimum length 1

Empty tool_calls arrays appear in histories written by older versions of Hermes Agent. These histories are stored on disk and replayed, causing every subsequent request in the session to fail once an empty tool_calls message enters the context.

Fix

Two changes across the message pipeline:

  1. run_agent.py_sanitize_tool_calls_for_strict_api() now strips empty tool_calls arrays from the message copy before sending to the provider. This covers the summary/retry path (handle_max_iterations).

  2. agent/transports/chat_completions.pyconvert_messages() (the main-loop message sanitizer) now detects empty tool_calls arrays in the detection phase and removes them from the outgoing copy in the sanitization phase. This covers the primary request path used by ~16 OpenAI-compatible providers.

Both fixes operate on copies — no stored history is mutated.

plasencio added 2 commits July 21, 2026 23:38
DeepSeek rechaza assistant messages con tool_calls=[] (HTTP 400
'Expected an array with minimum length 1'). Historiales escritos por
versiones anteriores pueden contener el array vacío; se elimina la
clave en la copia saliente dentro de _sanitize_tool_calls_for_strict_api.
El parche anterior solo cubría el camino de resumen (handle_max_iterations);
el bucle principal pasa por ChatCompletionsTransport.convert_messages, que
ahora también elimina 'tool_calls: []' de la copia saliente.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint provider/deepseek DeepSeek API sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 21, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related to #64843 and #64335: those cover a dedup pass that creates an empty array; this PR removes already-persisted empty arrays at conversion and retry/summary boundaries. The fixes are complementary rather than duplicates.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused strict-provider compatibility fix. This is already implemented on current main, so this PR is redundant.

  • Automated hermes-sweeper review verified that agent/agent_runtime_helpers.py:2974 removes empty and malformed assistant tool_calls from the per-call copy, preserving persisted history and prompt-cache stability.
  • The same shared sanitizer is invoked by both the main loop (agent/conversation_loop.py:1624) and the iteration-summary path (agent/chat_completion_helpers.py:2167).
  • Commit a7932d86c5cb835309eca289006e95eafeaedfb0 (fix(agent): drop empty tool_calls arrays in pre-API sanitizer (#58755)) is on current main, with regression coverage in tests/run_agent/test_message_sequence_repair.py:715.
  • The member discussion correctly distinguishes persisted-history handling from the related dedup work; current main now provides that persisted-history boundary handling centrally.

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 P2 Medium — degraded but workaround exists provider/deepseek DeepSeek API sweeper:implemented-on-main Sweeper: behavior already present on current main sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants