fix(transports+agent): GLM reasoning_effort ultra + drop empty tool_calls key (#70058, #70126) - #70182
fix(transports+agent): GLM reasoning_effort ultra + drop empty tool_calls key (#70058, #70126)#70182ms-alan wants to merge 2 commits into
Conversation
…upes sanitize_api_messages() Step 3 deduplication creates tool_calls: [] when every tool_call in a turn has a duplicate id. This empty array then passes through to strict OpenAI-compatible providers (Qwen-series) which reject it with HTTP 400. Fix: when kept_tcs is empty after dedup, drop the tool_calls key entirely instead of setting it to []. Closes NousResearch#70126
…odels GLM models (glm-4, glm-4-plus, etc.) use the same reasoning_effort: ultra parameter as GPT-5.6 ultra. The _reasoning_config_for_model function was only checking for gpt-5.6, causing GLM reasoning effort to be sent as raw string 'ultra' instead of the normalized integer. This fixes the mismatch for GLM model families. Closes NousResearch#70058
Related: #69917 covers the focused GLM-5.2 alias policy and #64345 removes the empty |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for combining two real provider-compatibility reports.
Problems
- The
agent/agent_runtime_helpers.py:2875hunk does not remove the key when every call was deduplicated.if kept_tcs:leaves the original duplicate calls unchanged in that case, instead of preserving deduplication and droppingtool_calls. Current main's dedup contract is atagent/agent_runtime_helpers.py:3142-3167. - The GLM change is broader than the existing GLM-5.2 policy in
plugins/model-providers/zai/__init__.py:49-82, and it misses the direct summary path:agent/chat_completion_helpers.py:2199-2206forwardsagent.reasoning_configwithout calling the transport helper. - The PR adds no regression tests; existing transport coverage only checks GPT-5.6 at
tests/agent/transports/test_chat_completions.py:20-35.
Suggested changes
- On a changed dedup list, retain non-empty calls or remove the
tool_callskey when none survive; add the all-duplicate regression case. - Limit GLM normalization to verified GLM-5.2 aliases and apply the same normalizer to summary requests, with tests for both paths.
Automated hermes-sweeper review.
| seen_assistant_call_ids.add(cid) | ||
| kept_tcs.append(tc) | ||
| if len(kept_tcs) != len(msg.get("tool_calls") or []): | ||
| if kept_tcs: |
There was a problem hiding this comment.
When every call is a duplicate, kept_tcs is empty and this leaves msg unchanged, including the original duplicate IDs. Please retain the changed-list check and remove the tool_calls key when no calls survive, so the sanitizer does not trade tool_calls: [] for duplicate-ID validation failures.
| return reasoning_config | ||
| if ( | ||
| "gpt-5.6" in (model or "").lower() | ||
| ("gpt-5.6" in (model or "").lower() or "glm-" in (model or "").lower()) |
There was a problem hiding this comment.
Please scope this to verified GLM-5.2 aliases rather than every glm- model. The existing Z.AI profile only maps native reasoning effort for GLM-5.2 (plugins/model-providers/zai/__init__.py:49-82), and the direct summary path also needs the same normalization.
|
Thanks for the report-and-fix. This added |
Closes #70058
Closes #70126
Two fixes:
reasoning_effort: "ultra" rejected by GLM API (HTTP 400), triggers silent fallback to Claude Sonnet #70058 - GLM reasoning_effort ultra:
only checked for when normalizing
to the wire-compatible . GLM models (glm-4, glm-4-plus,
etc.) use the same parameter but were never normalized, causing the
raw string 'ultra' to be sent instead of the expected integer.
[Bug]: sanitize_api_messages dedup writes tool_calls: [], breaking Qwen-series tool-calling sessions on v0.18.2+ #70126 - drop empty tool_calls key: Step 3
deduplication replaced with even when
was (every tool_call had a duplicate id). Strict
OpenAI-compatible providers (Qwen-series) reject
with HTTP 400. Fix: when is empty, drop the
key entirely instead of setting it to .