Skip to content

fix(chat_completions): strip tool_name from messages for strict providers#28958

Closed
savanne-kham wants to merge 1 commit into
NousResearch:mainfrom
savanne-kham:fix/strip-tool-name-strict-providers
Closed

fix(chat_completions): strip tool_name from messages for strict providers#28958
savanne-kham wants to merge 1 commit into
NousResearch:mainfrom
savanne-kham:fix/strip-tool-name-strict-providers

Conversation

@savanne-kham

@savanne-kham savanne-kham commented May 19, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

The internal tool_name key on role=tool messages — stored in the
messages.tool_name SQLite column for FTS indexing — is not part of the
OpenAI Chat Completions schema. Strict OpenAI-compatible providers, notably
Moonshot AI (Kimi), reject any request containing it with HTTP 400:

Error from provider: Extra inputs are not permitted,
field: 'messages[N].tool_name', value: 'execute_code'

This PR adds tool_name to the sanitize block in
ChatCompletionsTransport.convert_messages, alongside the existing
Codex Responses API fields (codex_reasoning_items, codex_message_items),
so it is popped before the request is sent.

The strip is unconditional (matches the existing Codex-strip pattern):
tool_name is never part of any documented OpenAI Chat Completions payload,
so removing it before send is safe for every provider while fixing the
strict ones. Permissive backends (MiniMax, OpenRouter on most routes) were
ignoring the extra field and masking the bug.

Related Issue

Fixes #

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • agent/transports/chat_completions.py — extend the needs_sanitize
    detection and the per-message pop step in convert_messages to cover
    the tool_name key.
  • tests/agent/transports/test_chat_completions.py — add
    test_convert_messages_strips_tool_name covering both the strip on the
    returned list and the deepcopy-on-demand contract (original input
    untouched).

How to Test

Reproducer:

hermes chat --model kimi-k2.6
> list the top 5 Hacker News stories

Before the fix:

  1. assistant emits tool_call(execute_code)
  2. the tool result message is persisted with tool_name='execute_code'
  3. the next-turn payload includes messages[N].tool_name
  4. Kimi rejects with HTTP 400 (Extra inputs are not permitted, field: 'messages[N].tool_name')

After the fix:

  1. Same flow, but convert_messages strips tool_name before send.
  2. Request succeeds, multi-turn tool-using conversations complete normally
    on kimi-k2.6 (verified end-to-end on macOS 15.x, Hermes Agent v0.14.0).

Automated:

pytest tests/agent/transports/test_chat_completions.py -q

The new test (test_convert_messages_strips_tool_name) asserts:

  • tool_name is removed from the returned message
  • tool_call_id and content are preserved
  • the original input list is unmodified (deepcopy-on-demand contract)

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(chat_completions): …)
  • I searched for existing PRs/issues — none target this specific field
  • My PR contains only changes related to this fix
  • I've run pytest tests/agent/transports/test_chat_completions.py -q and all tests pass
  • I've added a test for the fix
  • I've tested on my platform: macOS 15.x (Apple Silicon)

Documentation & Housekeeping

  • N/A — no public docs reference the internal tool_name field
  • N/A — no config keys added/changed
  • N/A — no architectural or workflow changes
  • Cross-platform: the change is a pure dictionary pop, no platform-specific behavior
  • N/A — no tool descriptions/schemas changed

…ders

The 'tool_name' key on role=tool messages is an internal Hermes field
(stored in the messages.tool_name SQLite column for FTS indexing) that
is not part of the OpenAI Chat Completions schema. Strict OpenAI-compatible
providers — notably Moonshot AI (Kimi) — reject it with HTTP 400:

  Error from provider: Extra inputs are not permitted,
  field: 'messages[N].tool_name', value: 'execute_code'

Add 'tool_name' to the sanitize block in ChatCompletionsTransport.convert_messages
alongside the existing Codex Responses API fields (codex_reasoning_items,
codex_message_items) so it is popped before the request is sent.

Reproducer:
  hermes chat --model kimi-k2.6
  > list the top 5 Hacker News stories
  -> assistant emits tool_call(execute_code)
  -> tool result message gets tool_name='execute_code'
  -> next turn's payload includes messages[N].tool_name -> 400

Permissive backends (MiniMax, OpenRouter on most routes) ignore the extra
field and were masking the bug.
@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/kimi Kimi / Moonshot labels May 19, 2026
teknium1 added a commit that referenced this pull request May 20, 2026
Salvage follow-up to PR #28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
@teknium1

Copy link
Copy Markdown
Contributor

Merged via #29126 on current main — your commit cab9bc5 landed with your authorship preserved via rebase-merge. Thanks for the clean repro and the minimal pattern-match fix.

Merge commit: 42c4288

Lillard01 pushed a commit to Lillard01/hermes-agent that referenced this pull request May 21, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
@savanne-kham
savanne-kham deleted the fix/strip-tool-name-strict-providers branch May 22, 2026 13:24
Gpapas pushed a commit to Gpapas/hermes-agent that referenced this pull request May 23, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
Mucky010 pushed a commit to Mucky010/hermes-agent that referenced this pull request May 24, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
Bryce-huang pushed a commit to wbkunlun/hermes-agent that referenced this pull request May 29, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.

#AI commit#
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
Seven74AI pushed a commit to Seven74AI/hermes-agent that referenced this pull request Jun 13, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
alt-glitch pushed a commit that referenced this pull request Jun 14, 2026
Salvage follow-up to PR #28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
T02200059 pushed a commit to T02200059/hermes-agent that referenced this pull request Jun 18, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
liuchanchen pushed a commit to liuchanchen/hermes-agent that referenced this pull request Jun 23, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
liuchanchen pushed a commit to liuchanchen/hermes-agent that referenced this pull request Jul 3, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
liuchanchen pushed a commit to liuchanchen/hermes-agent that referenced this pull request Jul 3, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
donbowman pushed a commit to donbowman/hermes-agent that referenced this pull request Jul 13, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
kulikman pushed a commit to kulikman/hermes-agent that referenced this pull request Jul 16, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
waym0reom3ga added a commit to waym0reom3ga/autolycus-agent that referenced this pull request Jul 21, 2026
Salvage follow-up to PR NousResearch#28958 (savanne-kham):

- convert_messages() docstring now explicitly documents the tool_name strip
  alongside Codex fields, names which providers reject it (Fireworks,
  Moonshot/Kimi), and why permissive providers (OpenRouter, MiniMax)
  masked the bug.
- AUTHOR_MAP entry for [email protected] -> savanne-kham.
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/kimi Kimi / Moonshot type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants