diff --git a/plugins/model-providers/nous/__init__.py b/plugins/model-providers/nous/__init__.py index b5cd886854e0..c63c05343e79 100644 --- a/plugins/model-providers/nous/__init__.py +++ b/plugins/model-providers/nous/__init__.py @@ -14,6 +14,15 @@ class NousProfile(ProviderProfile): self, *, session_id: str | None = None, **context ) -> dict[str, Any]: body: dict[str, Any] = {"tags": nous_portal_tags(session_id=session_id)} + if session_id: + # Top-level session_id → provider sticky routing key. Pins every + # turn of a session to the same upstream endpoint so explicit + # Anthropic cache_control breakpoints stay warm instead of + # cold-writing a fresh cache on each reroute (Anthropic/Vertex/ + # Bedrock caches are instance-local). Mirrors the OpenRouter + # profile; without it the portal falls back to hashing the opening + # messages, which breaks pinning whenever those shift. + body["session_id"] = session_id provider_preferences = context.get("provider_preferences") if provider_preferences: body["provider"] = provider_preferences diff --git a/tests/providers/test_provider_profiles.py b/tests/providers/test_provider_profiles.py index 73ca4e279083..0e95623a37e2 100644 --- a/tests/providers/test_provider_profiles.py +++ b/tests/providers/test_provider_profiles.py @@ -431,6 +431,18 @@ class TestNousProfile: body = p.build_extra_body(session_id="sess-99") assert conversation_tag("sess-99") in body["tags"] + def test_extra_body_session_id(self): + """Top-level session_id is the provider sticky-routing key — keeps + Anthropic cache_control breakpoints pinned to one upstream endpoint.""" + p = get_provider_profile("nous") + body = p.build_extra_body(session_id="sess-99") + assert body["session_id"] == "sess-99" + + def test_extra_body_no_session_id(self): + p = get_provider_profile("nous") + body = p.build_extra_body() + assert "session_id" not in body + def test_auth_type(self): p = get_provider_profile("nous") assert p.auth_type == "oauth_device_code" diff --git a/tests/run_agent/test_run_agent.py b/tests/run_agent/test_run_agent.py index 539dbdd20a40..073bdd892c42 100644 --- a/tests/run_agent/test_run_agent.py +++ b/tests/run_agent/test_run_agent.py @@ -4046,9 +4046,11 @@ class TestHandleMaxIterations: kwargs = agent.client.chat.completions.create.call_args.kwargs from agent.portal_tags import nous_portal_tags - assert kwargs["extra_body"] == { - "tags": nous_portal_tags(session_id=agent.session_id) - } + expected = {"tags": nous_portal_tags(session_id=agent.session_id)} + if agent.session_id: + # Top-level sticky-routing key ships whenever a session exists. + expected["session_id"] = agent.session_id + assert kwargs["extra_body"] == expected def test_summary_drops_invalid_provider_sort(self, agent): agent.base_url = "https://openrouter.ai/api/v1"