Skip to content

fix(gateway): reload provider routing and bust cached agents on routing changes - #32088

Open
soynchux wants to merge 1 commit into
NousResearch:mainfrom
soynchux:fix/gateway-hot-reload-provider-routing
Open

soynchux wants to merge 1 commit into
NousResearch:mainfrom
soynchux:fix/gateway-hot-reload-provider-routing

Conversation

@soynchux

Copy link
Copy Markdown

Summary

Reload provider_routing at agent construction time so live config edits take effect on the next turn, and include routing fields in the gateway agent cache signature so stale agents are not reused after routing changes.

Why

The gateway was holding on to the startup routing snapshot, which meant config edits could leave subsequent turns using an outdated OpenRouter routing policy.

Testing

  • 62 passed
  • test_provider_routing_change_busts_cache
  • test_reads_provider_routing_subkeys
  • test_run_agent_reloads_provider_routing_and_busts_cached_agent
  • full test_agent_cache.py
  • full test_session_model_override_routing.py

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery labels May 25, 2026
@hclsys

hclsys commented May 25, 2026

Copy link
Copy Markdown

This is the right shape and it's complete — verified both halves:

  1. Reload: _refresh_provider_routing() re-reads provider_routing from config and updates self._provider_routing, called at the agent-construction/turn path (run.py:~11596, ~16393) instead of using the startup snapshot. ✓
  2. Cache-bust (the part that's easy to get wrong): you added provider_routing.* to _extract_cache_busting_config, and I confirmed that actually feeds the cache key — _agent_config_signature(..., cache_keys=self._extract_cache_busting_config(user_config)) (run.py:16489-16494), and the cache stores (AIAgent, config_signature_str) (1742). So a routing change changes the signature → the cached agent is invalidated and rebuilt, rather than a stale agent being reused. The test_provider_routing_change_busts_cache (sig_before != sig_after) + the first_cached_agent is not second_cached_agent integration assertion prove both the signature change and the actual rebuild.

Worth flagging for the maintainer: this is exactly the pattern the still-open #32007 (reload agent.system_prompt) needs and is currently missing — #32007 reloads the prompt but does not add it to the cache signature, so it only fixes the cache-miss path and leaves returning sessions stale (I flagged that on #32007). If both land, the system-prompt one should mirror this PR's _extract_cache_busting_config approach. This PR itself is correct and well-tested. LGTM.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing both the constructor snapshot and cached-agent path; current main still has the reported gap: gateway/run.py:13383 and gateway/run.py:18032 read the startup self._provider_routing, while gateway/run.py:18158-18163 builds the cache signature without routing fields.

Problems

  • The new refresh helper would retain a configuration-source mismatch. gateway/run.py:4982-4993 loads raw YAML, but the gateway’s effective config path applies the managed-scope overlay at gateway/run.py:2352-2359. The PR should not construct an agent from raw routing while calculating its cache signature from effective user_config.

Suggested changes

  • Thread effective user_config["provider_routing"] through both construction paths, validate it as a dict, and use that same value for cache invalidation. Add coverage for the effective/managed configuration path.

Automated hermes-sweeper review.

Comment thread gateway/run.py
disabled_toolsets = agent_cfg.get("disabled_toolsets") or None

pr = self._provider_routing
pr = self._refresh_provider_routing()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the effective user_config already loaded above for this refresh. _load_provider_routing() reads raw YAML, while _load_gateway_config() applies managed scope; otherwise the new routing passed to AIAgent can disagree with the routing values used in the cache signature.

@teknium1 teknium1 added sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 13, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants