feat(agent): per-platform request_overrides via platform_request_overrides - #34007
Closed
juk80x wants to merge 1 commit into
Closed
feat(agent): per-platform request_overrides via platform_request_overrides#34007juk80x wants to merge 1 commit into
juk80x wants to merge 1 commit into
Conversation
…rides
Adds a top-level config key that lets users layer OpenAI-compatible
chat-completion request fields per platform. Concrete cases that
motivated this: tuning reasoning_effort lower on a latency-sensitive
api_server integration while keeping CLI at the default, sending a
chat_template_kwargs.enable_thinking flag to a hybrid-thinking model
(Qwen3 / GLM-4.6 / Hunyuan family on llama.cpp / vLLM) for one
endpoint but not others, or switching service_tier per surface.
Resolution order (high -> low):
1. caller-supplied request_overrides (highest)
2. platform_request_overrides[<platform>] (this layer)
3. custom_providers[].extra_body (existing global, resolved earlier)
extra_body is shallow-merged at the second level so a platform can set
one nested key (e.g. chat_template_kwargs) without erasing siblings
(e.g. reasoning_effort) that a custom-provider entry already supplied.
Top-level keys (service_tier, reasoning_effort) replace wholesale.
Caller-supplied keys always win - the platform layer fills only keys
the caller did not pass explicitly. This preserves the existing
contract for auxiliary clients, kanban workers, and delegated subagents
that already thread request_overrides through.
No-op when platform_request_overrides is absent or the current platform
key has no entry, so untouched configs behave exactly as before.
Changes:
* agent/agent_init.py - _platform_request_overrides_for_agent
resolver + _merge_platform_request_overrides applier, hooked in
immediately after _merge_custom_provider_extra_body
* tests/agent/test_platform_request_overrides.py - 18 tests mirroring
test_custom_provider_extra_body.py (resolver edge cases, top-level
+ extra_body merge semantics, caller-precedence, malformed config
tolerance)
* cli-config.yaml.example - new commented section with three usage
examples and a Scope note clarifying that the override covers the
agent's main conversational LLM call only, not auxiliary models or
non-conversational tools
Measured locally with Qwen3.6-35B-A3B on llama.cpp via the api_server
platform: a "what time is it?" turn that requires one tool call drops
from ~10.1s / 244 completion tokens to ~1.5s / 25 completion tokens
with chat_template_kwargs.enable_thinking: false set only for
api_server. CLI and Telegram surfaces are unaffected.
|
I’m using Hermes with a local Qwen model served by llama.cpp. Setup:
This still returns curl -s http://192.168.1.2:8080/v1/chat/completions -H "Content-Type: application/json" -d '{
"model": "qwen36-27b-unsloth",
"messages": [{"role": "user", "content": "hello /no_think"}],
"max_tokens": 120
}' | jq '.choices[0].message'But this works: curl -s http://192.168.1.2:8080/v1/chat/completions -H "Content-Type: application/json" -d '{
"model": "qwen36-27b-unsloth",
"messages": [{"role": "user", "content": "hello"}],
"chat_template_kwargs": {"enable_thinking": false},
"max_tokens": 120
}' | jq '.choices[0].message'Request: allow Hermes to apply |
Open
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Adds a top-level
platform_request_overridesconfig key that lets users layer OpenAI-compatible chat-completion request fields per platform. When the sameAIAgentconfiguration drives multiple surfaces (cli,telegram,api_server, etc.), each platform can now carry its ownextra_body,reasoning_effort, andservice_tieroverrides — without forking the global config or running a separate process per surface.Resolution order (high → low):
request_overrides(highest — preserves the existing contract for auxiliary clients, kanban workers, delegated subagents).platform_request_overrides[<platform>](new layer).custom_providers[].extra_body(existing global, resolved earlier by_merge_custom_provider_extra_body).extra_bodyis shallow-merged at the second level so a platform setting one nested key (e.g.chat_template_kwargs) doesn't erase siblings (e.g.reasoning_effort) a custom-provider entry already supplied. Top-level keys (service_tier,reasoning_effort) replace wholesale.No-op when
platform_request_overridesis absent or the current platform key has no entry — untouched configs behave exactly as before.Scope of the override: applies to the main conversational LLM call (OpenAI chat completions / Anthropic messages / Codex responses) for every platform that has a matching entry. Does NOT cover auxiliary model calls (those have their own
auxiliary.<task>.extra_bodyknob) or non-conversational tool requests (embeddings, image generation, TTS / STT). Documented inline incli-config.yaml.example.Related Issue
Fixes #34006
Adjacent (open) PRs reviewed before designing this, in case reviewers want context:
chat_template_kwargs.enable_thinking=falsefor llama.cpp / vLLM (this PR enables the same knob per-platform)agent.reasoning_effortoverrides (same shape, different axis)reasoning_effortconfiguration (same shape on the auxiliary axis)extra_bodypass-through (merged baseline this PR extends)Type of Change
Changes Made
agent/agent_init.py— new_platform_request_overrides_for_agentresolver (keyword-only args, defensiveisinstanceguards, returns a copy so callers can't corrupt parsed config) +_merge_platform_request_overridesapplier; hooked in at agent init immediately after_merge_custom_provider_extra_body. Naming + signature shape mirror the existing_custom_provider_extra_body_for_agent/_merge_custom_provider_extra_bodypair.tests/agent/test_platform_request_overrides.py— 18 new tests mirroringtests/agent/test_custom_provider_extra_body.pystyle: resolver edge cases (missing block, unknown platform, empty/non-string key, case-insensitive matching, non-dict config tolerance, copy semantics),_merge_*correctness (no-op paths,extra_bodyshallow-merge, top-level passthrough, layering on top of a custom-provider entry, caller-precedence for both nested and top-level keys, malformedextra_bodytolerance, no-empty-dict policy).cli-config.yaml.example— new "Platform Request Overrides" section betweenPlatform ToolsetsandGateway Platform Settings. Includes resolution-order doc, scope clarification (what's covered vs what isn't), and three concrete examples (per-platformreasoning_effort, per-platformservice_tier, per-platformchat_template_kwargs.enable_thinking).Diffstat:
3 files changed, 396 insertions(+)—+94prod (agent_init.py),+251tests,+59docs.How to Test
Automated:
Manual (config + behavior):
Add to
~/.hermes/config.yaml:Start the gateway with an
api_serverplatform pointed at a local llama.cpp running a hybrid-thinking model (e.g. Qwen3-derived).POST a chat completion to the
api_serverendpoint and observeusage.completion_tokensand round-trip time. With the override, both drop substantially because the model skips its hidden thinking block. CLI and Telegram surfaces (no entry for them) keep the default behaviour.Verify CLI is unaffected:
hermes chat -q "what is the capital of France?"— same thinking-mode behaviour as before the change.Tested on: macOS 15.5 (Darwin 25.5), Python 3.11.15.
Concrete measurement (Qwen3.6-35B-A3B + llama.cpp + the
api_serverplatform via an OpenAI-compatible client): a "what time is it?" turn that requires one tool call (GetDateTimevia Home Assistant MCP) drops from ~10.1s / 244 completion tokens to ~1.5s / 25 completion tokens withchat_template_kwargs.enable_thinking: falseset only forapi_server. CLI and Telegram (no entry) unaffected.Checklist
Code
feat(agent):)scripts/run_tests.shon the new file and 3 adjacent files: 321 passed, 0 failedDocumentation & Housekeeping
cli-config.yaml.examplewith usage examples and a scope notecli-config.yaml.examplebecause this adds a new config keyCONTRIBUTING.md/AGENTS.mdupdatesscripts/check-windows-footguns.pyreports clean on the diff.