feat: add Hermes tool call parser#1596
Conversation
Add support for Hermes-style tool call format: <|tool_call_start|>[func_name(arg1=val1)]<|tool_call_end|> Supports both bracket format (Python-style keyword args) and JSON format. Adds to the fallback chain in parse_tool_calls() and strips markers when parsing fails to prevent raw markup leaking to API responses.
|
Cross-ref: this PR is the server-side counterpart to NousResearch/hermes-agent#37229 (fix: normalize local tool JSON fallbacks). These two PRs are co-dependent:
Without both, local model tool calling is broken:
Both should merge together for a complete fix. |
|
Thanks for the PR. I checked the Hermes fallback path, streaming marker suppression, and the LFM2 discovery change against the existing parser/model-discovery call paths. The AST-based bracket parser covers the multi-call case without the old comma-splitting risk, and the streaming filter keeps the Hermes markers out of visible deltas when tools are enabled. The focused tool-calling, model discovery, tokenizer/audio discovery, and adapter tests all pass on the PR branch. This looks good to me, and I'm going to merge it. |
Summary
Adds fallback support for the Hermes-style/Liquid tool call wire format:
Some clients/agents emit tool calls using these markers instead of oMLX's currently supported XML/prose bracket formats. Without this fallback, oMLX can surface raw marker text to users instead of returning structured tool calls.
This PR:
<|tool_call_start|>...<|tool_call_end|>[read_file(path='/tmp/a.log')][tool_a(...), tool_b(...)]<|tool_call_end|>cannot leak if it arrives without a visible open markerlfm2as ambiguous and relying on architecture/name checksVerification