"""Regression tests for the delegation.request_overrides config key. PR #90953 (salvage): ``delegation.request_overrides`` is an explicit dict of per-child request settings that must be honored on EVERY resolution branch of ``_resolve_delegation_credentials``: 1. direct base_url (provider=custom) — the branch the original PR fixed, 2. named provider (delegation.provider set, no base_url), 3. parent-inherit (neither provider nor base_url). Precedence contract (post-#98237): explicit config values merge OVER runtime/parent-derived overrides — top-level explicit keys win; the ``extra_body`` sub-dict is deep-merged one level so runtime extra_body keys survive unless the explicit key redefines them. Nested values are deep-copied so transport-side mutation cannot leak back into config. """ from unittest.mock import MagicMock, patch from tools.delegate_tool import ( _merge_request_overrides, _resolve_delegation_credentials, ) def _cfg(**overrides): cfg = { "model": "deepseek/deepseek-v4-flash-0731", "base_url": "https://openrouter.ai/api/v1", "api_key": "test-key-1234567890", } cfg.update(overrides) return cfg def _parent(**attrs): parent = MagicMock() parent._delegate_depth = 0 # MagicMock attributes are MagicMocks (non-dict) by default; set real # values for the ones the resolution path inspects. parent.request_overrides = attrs.pop("request_overrides", None) for k, v in attrs.items(): setattr(parent, k, v) return parent # ── Branch 1: direct base_url ────────────────────────────────────────────── def test_direct_branch_forwards_request_overrides(): """delegation.request_overrides flows through the direct-endpoint branch.""" cfg = _cfg( request_overrides={ "extra_body": {"provider": {"sort": "throughput"}}, } ) creds = _resolve_delegation_credentials(cfg, parent_agent=None) assert creds["request_overrides"] == { "extra_body": {"provider": {"sort": "throughput"}}, } # Shape parity with the named-provider branch: max_output_tokens present. assert "max_output_tokens" in creds def test_direct_branch_absent_request_overrides_stays_none(): """No delegation.request_overrides → None, preserving the old contract.""" creds = _resolve_delegation_credentials(_cfg(), parent_agent=None) assert creds["request_overrides"] is None def test_direct_branch_non_dict_request_overrides_stays_none(): """Garbage in config (string/list) must not crash or forward junk.""" for bad in ("throughput", ["extra_body"], 42): creds = _resolve_delegation_credentials( _cfg(request_overrides=bad), parent_agent=None ) assert creds["request_overrides"] is None def test_direct_branch_deep_copies_nested_extra_body(): """Transport-side mutation of the child's overrides must not leak back into the config dict (copy.deepcopy, not a shallow dict()).""" source = {"extra_body": {"provider": {"sort": "throughput"}}} cfg = _cfg(request_overrides=source) creds = _resolve_delegation_credentials(cfg, parent_agent=None) creds["request_overrides"]["extra_body"]["provider"]["sort"] = "mutated" creds["request_overrides"]["extra_body"]["injected"] = True assert source == {"extra_body": {"provider": {"sort": "throughput"}}} @patch("hermes_cli.runtime_provider.resolve_runtime_provider") def test_explicit_merges_over_runtime_on_provider_alongside_base_url(mock_resolve): """Precedence on the provider-alongside-base_url path (#98237 interplay): explicit delegation.request_overrides merges OVER the named provider's runtime overrides — runtime extra_body keys survive unless redefined, explicit top-level keys win, and max_output_tokens is preserved.""" mock_resolve.return_value = { "provider": "custom", "base_url": "https://provider-default.example/v1", "api_key": "provider-key", "api_mode": "chat_completions", "request_overrides": { "service_tier": "default", "extra_body": {"thinking": {"type": "disabled"}, "provider": {"sort": "price"}}, }, "max_output_tokens": 8192, } cfg = _cfg( provider="mimo", request_overrides={ "service_tier": "flex", "extra_body": {"provider": {"sort": "throughput"}}, }, ) creds = _resolve_delegation_credentials(cfg, parent_agent=None) assert creds["request_overrides"] == { # explicit top-level key wins "service_tier": "flex", "extra_body": { # runtime extra_body key survives (not redefined) "thinking": {"type": "disabled"}, # explicit extra_body key wins over runtime's "provider": {"sort": "throughput"}, }, } assert creds["max_output_tokens"] == 8192 # ── Branch 2: named provider (no base_url) ───────────────────────────────── @patch("hermes_cli.runtime_provider.resolve_runtime_provider") def test_named_provider_branch_honors_explicit_key(mock_resolve): """The named-provider branch merges the explicit key over the provider's runtime overrides — the config key never silently no-ops.""" mock_resolve.return_value = { "provider": "openrouter", "base_url": "https://openrouter.ai/api/v1", "api_key": "runtime-key", "api_mode": "chat_completions", "request_overrides": {"extra_body": {"reasoning": {"enabled": True}}}, "max_output_tokens": 4096, } cfg = { "model": "deepseek/deepseek-v4-flash-0731", "provider": "openrouter", "request_overrides": {"extra_body": {"provider": {"sort": "throughput"}}}, } creds = _resolve_delegation_credentials(cfg, parent_agent=None) assert creds["request_overrides"] == { "extra_body": { "reasoning": {"enabled": True}, "provider": {"sort": "throughput"}, } } @patch("hermes_cli.runtime_provider.resolve_runtime_provider") def test_named_provider_branch_without_explicit_key_unchanged(mock_resolve): """Without the config key the named-provider branch behaves as before.""" mock_resolve.return_value = { "provider": "openrouter", "base_url": "https://openrouter.ai/api/v1", "api_key": "runtime-key", "api_mode": "chat_completions", "request_overrides": {"extra_body": {"reasoning": {"enabled": True}}}, "max_output_tokens": 4096, } cfg = {"model": "m", "provider": "openrouter"} creds = _resolve_delegation_credentials(cfg, parent_agent=None) assert creds["request_overrides"] == {"extra_body": {"reasoning": {"enabled": True}}} # ── Branch 3: parent-inherit (no provider, no base_url) ──────────────────── def test_inherit_branch_honors_explicit_key_over_parent(): """Pure-inherit setups still apply delegation.request_overrides, merged over the parent agent's own request_overrides.""" parent = _parent( request_overrides={ "service_tier": "default", "extra_body": {"thinking": {"type": "disabled"}}, } ) cfg = { "model": "", "provider": "", "request_overrides": {"extra_body": {"provider": {"sort": "throughput"}}}, } creds = _resolve_delegation_credentials(cfg, parent) assert creds["request_overrides"] == { "service_tier": "default", "extra_body": { "thinking": {"type": "disabled"}, "provider": {"sort": "throughput"}, }, } def test_inherit_branch_without_key_stays_none(): """No explicit key and no parent overrides → None (old contract: the child's construction path falls back to the parent's request_overrides).""" parent = _parent(request_overrides=None) creds = _resolve_delegation_credentials({"model": "", "provider": ""}, parent) assert creds["request_overrides"] is None def test_inherit_branch_deep_copies_parent_overrides(): """Parent's nested overrides must be deep-copied on the inherit branch.""" parent_overrides = {"extra_body": {"thinking": {"type": "disabled"}}} parent = _parent(request_overrides=parent_overrides) cfg = { "model": "", "provider": "", "request_overrides": {"extra_body": {"provider": {"sort": "throughput"}}}, } creds = _resolve_delegation_credentials(cfg, parent) creds["request_overrides"]["extra_body"]["thinking"]["type"] = "mutated" assert parent_overrides == {"extra_body": {"thinking": {"type": "disabled"}}} # ── Merge helper unit tests ──────────────────────────────────────────────── def test_merge_helper_both_none(): assert _merge_request_overrides(None, None) is None assert _merge_request_overrides({}, {}) is None assert _merge_request_overrides("junk", 42) is None def test_merge_helper_explicit_only(): assert _merge_request_overrides(None, {"a": 1}) == {"a": 1} def test_merge_helper_runtime_only(): assert _merge_request_overrides({"a": 1}, None) == {"a": 1} def test_merge_helper_explicit_top_level_wins(): assert _merge_request_overrides({"a": 1, "b": 2}, {"a": 9}) == {"a": 9, "b": 2} def test_merge_helper_extra_body_one_level_merge(): merged = _merge_request_overrides( {"extra_body": {"keep": 1, "clash": "runtime"}}, {"extra_body": {"clash": "explicit", "new": 2}}, ) assert merged == {"extra_body": {"keep": 1, "clash": "explicit", "new": 2}} def test_merge_helper_non_dict_runtime_extra_body_replaced(): merged = _merge_request_overrides( {"extra_body": "junk"}, {"extra_body": {"a": 1}} ) assert merged == {"extra_body": {"a": 1}}