From 4fa728b6bed3d0f4e1313ea0c6d183963fc5446d Mon Sep 17 00:00:00 2001 From: kshitij <82637225+kshitijk4poor@users.noreply.github.com> Date: Fri, 14 Aug 2026 00:23:39 +0530 Subject: [PATCH] fix: follow-up polish for salvaged PR #85512 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Log (debug) instead of silently swallowing capability-lookup failures in anthropic_prompt_cache_policy — a swallowed failure would otherwise downgrade an explicit prompt_caching: true to (False, False) with zero trace. Matches the sibling MoA branch's logger.debug style. - Use load_config_readonly() for the None-fallback in get_custom_provider_model_capability: the helper only reads, and the fallback fires on the blank-stub paths (agent init before _custom_providers is assigned, MoA/auxiliary destination planning), so skip the ~135us defensive deepcopy per call. - Add route-isolation regression tests at both levels (config helper + agent policy): a prompt_caching declaration for one provider route must never apply to another route with the same model name. Mutation-checked: both tests fail when the URL match is disabled. --- agent/agent_runtime_helpers.py | 7 +++++-- hermes_cli/config.py | 6 ++++++ .../test_custom_provider_context_length.py | 21 +++++++++++++++++++ .../test_anthropic_prompt_cache_policy.py | 19 +++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/agent/agent_runtime_helpers.py b/agent/agent_runtime_helpers.py index 6a26178354..35d9848496 100644 --- a/agent/agent_runtime_helpers.py +++ b/agent/agent_runtime_helpers.py @@ -2248,8 +2248,11 @@ def anthropic_prompt_cache_policy( capability="prompt_caching", custom_providers=getattr(agent, "_custom_providers", None), ) - except Exception: - pass + except Exception as _cap_exc: + logger.debug( + "custom-provider prompt_caching capability lookup failed: %s", + _cap_exc, + ) if custom_prompt_caching is not None: return custom_prompt_caching, custom_prompt_caching diff --git a/hermes_cli/config.py b/hermes_cli/config.py index 42eef07067..29c7a4551e 100644 --- a/hermes_cli/config.py +++ b/hermes_cli/config.py @@ -1799,6 +1799,12 @@ def get_custom_provider_model_capability( return None if custom_providers is None: try: + if config is None: + # Read-only path: this helper never mutates the entries it + # scans, and get_compatible_custom_providers shallow-copies + # each entry before normalizing, so the no-deepcopy cache is + # safe here (~135us saved per call on the blank-stub paths). + config = load_config_readonly() custom_providers = get_compatible_custom_providers(config) except Exception: return None diff --git a/tests/hermes_cli/test_custom_provider_context_length.py b/tests/hermes_cli/test_custom_provider_context_length.py index 04818f2274..2220262a17 100644 --- a/tests/hermes_cli/test_custom_provider_context_length.py +++ b/tests/hermes_cli/test_custom_provider_context_length.py @@ -98,6 +98,27 @@ class TestGetCustomProviderModelCapability: custom, ) is None + def test_capability_is_route_isolated(self): + """A declaration for one route must not apply to another route. + + Guards normalize_route_base_url matching: if the URL comparison ever + regresses to a model-only (or hostname-only) shortcut, this pins the + failure. + """ + custom = [ + { + "base_url": "https://other.example.invalid/anthropic", + "models": {"fable": {"prompt_caching": True}}, + } + ] + + assert get_custom_provider_model_capability( + "fable", + "https://example.invalid/anthropic", + "prompt_caching", + custom, + ) is None + class TestGetModelContextLengthHonorsOverride: diff --git a/tests/run_agent/test_anthropic_prompt_cache_policy.py b/tests/run_agent/test_anthropic_prompt_cache_policy.py index ea2ed73a4e..9fe66cd4c3 100644 --- a/tests/run_agent/test_anthropic_prompt_cache_policy.py +++ b/tests/run_agent/test_anthropic_prompt_cache_policy.py @@ -212,6 +212,25 @@ class TestThirdPartyAnthropicGateway: assert agent._anthropic_prompt_cache_policy() == (False, False) + def test_capability_on_other_route_does_not_apply(self): + """prompt_caching declared for a DIFFERENT base_url must not enable + caching for this agent's route — route isolation at the policy level.""" + agent = _make_agent( + provider="custom:anthropic-proxy", + base_url="https://gateway.example.com/anthropic", + api_mode="anthropic_messages", + model="fable", + ) + agent._custom_providers = [ + { + "name": "other-proxy", + "base_url": "https://other.example.com/anthropic", + "models": {"fable": {"prompt_caching": True}}, + } + ] + + assert agent._anthropic_prompt_cache_policy() == (False, False) + class TestMiniMaxAnthropicWire: """MiniMax's own model family on its Anthropic-compatible endpoint.