Skip to content

fix(agent): repair malformed tool_call arguments before API send#13005

Merged
teknium1 merged 2 commits into
mainfrom
hermes/hermes-67ae3e6f
Apr 20, 2026
Merged

fix(agent): repair malformed tool_call arguments before API send#13005
teknium1 merged 2 commits into
mainfrom
hermes/hermes-67ae3e6f

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Salvage of PR #12252 by @sirEven. Replaces the silent except Exception: pass in the pre-send tool_call argument normalizer with a multi-stage JSON repair pipeline, preventing HTTP 400 session death spirals from models producing broken JSON (GLM-5.1 via Ollama, etc.).

Changes

  • run_agent.py: New _repair_tool_call_arguments() helper — 6-stage pipeline: empty→{}, Python None→{}, strip trailing commas, auto-close unclosed brackets, remove excess closing delimiters (bounded loop), last resort {} with WARNING log
  • run_agent.py: Call site in pre-send normalizer replaced from 75 inline lines to 4-line call
  • scripts/release.py: Added @sirEven to AUTHOR_MAP
  • tests/run_agent/test_repair_tool_call_arguments.py: 17 tests covering all repair stages

Follow-up cleanup (vs raw cherry-pick)

  • Extracted inline block to testable module-level helper
  • Removed redundant import re as _re (re already at line 33)
  • Bounded the while-True excess-delimiter loop to 50 iterations
  • Added comprehensive test suite

Validation

Before After
Malformed args from GLM-5.1 Silent passthrough → HTTP 400 → session death spiral Repaired to valid JSON, session continues
Tests 0 17/17 passing

Closes #12252

sirEven and others added 2 commits April 20, 2026 05:01
Cherry-picked from PR #12252 by @sirEven.

Models like GLM-5.1 via Ollama can produce malformed tool_call arguments
(truncated JSON, trailing commas, Python None). The existing except
Exception: pass silently passes broken args to the API, which rejects
them with HTTP 400, crashing the session.

Adds a multi-stage repair pipeline at the pre-send normalization point:
1. Empty/whitespace-only → {}
2. Python None literal → {}
3. Strip trailing commas
4. Auto-close unclosed brackets
5. Remove excess closing delimiters
6. Last resort: replace with {} (logged at WARNING)
Follow-up for PR #12252 salvage:
- Extract 75-line inline repair block to _repair_tool_call_arguments()
  module-level helper for testability and readability
- Remove redundant 'import re as _re' (re already imported at line 33)
- Bound the while-True excess-delimiter removal loop to 50 iterations
- Add 17 tests covering all 6 repair stages
- Add sirEven to AUTHOR_MAP in release.py
@teknium1 teknium1 merged commit 9725b45 into main Apr 20, 2026
4 of 6 checks passed
@teknium1 teknium1 deleted the hermes/hermes-67ae3e6f branch April 20, 2026 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants