fix(gateway): don't restore a bare billing provider as the resumed session's provider

`_stored_session_runtime_overrides` restored the session provider from
`billing_provider` when `model_config` had no explicit provider. For a
`custom:<name>` endpoint that only ran normal turns (no `/model` switch), the
persisted `billing_provider` is the bare billing bucket `"custom"`, which
`agent_init` treats as non-routable, so `session.resume` failed with
"No LLM provider configured" even though new chats and CLI `--resume` work.

Only restore an explicit `model_config.provider`; skip a bare billing bucket
(`auto`/`openrouter`/`custom`) so resume falls back to the configured default,
matching the CLI path.

Fixes #44022
This commit is contained in:
Haozhe Zhang
2026-06-13 05:51:05 -07:00
committed by Teknium
parent cb125c2b3f
commit e256f4aae4
2 changed files with 45 additions and 5 deletions
+29
View File
@@ -971,6 +971,35 @@ def test_session_resume_passes_stored_runtime_to_agent(monkeypatch):
assert server._sessions[runtime_sid]["model_override"] == captured["model_override"]
def test_stored_session_runtime_overrides_skips_bare_billing_provider():
"""A bare billing bucket ("custom"/"auto"/"openrouter") must not be restored as the
provider identity on resume. A custom endpoint that never used `/model` persists only
`billing_provider="custom"`; restoring that broke `session.resume` with "No LLM provider
configured" (agent_init treats it as non-routable). A real provider, or an explicit
`model_config.provider`, is still restored.
"""
# Bare "custom" bucket, no explicit model_config.provider: no provider override restored.
ov = server._stored_session_runtime_overrides({"model": "my-model", "billing_provider": "custom"})
assert "provider_override" not in ov
assert ov["model_override"]["provider"] is None
for bare in ("auto", "openrouter", "custom"):
ov = server._stored_session_runtime_overrides({"model": "m", "billing_provider": bare})
assert "provider_override" not in ov
# A real provider in billing_provider is still restored.
ov = server._stored_session_runtime_overrides({"model": "m", "billing_provider": "anthropic"})
assert ov["provider_override"] == "anthropic"
assert ov["model_override"]["provider"] == "anthropic"
# An explicit routable provider in model_config wins over the bare billing bucket.
ov = server._stored_session_runtime_overrides(
{"model": "m", "billing_provider": "custom", "model_config": {"provider": "custom:myendpoint"}}
)
assert ov["provider_override"] == "custom:myendpoint"
assert ov["model_override"]["provider"] == "custom:myendpoint"
def test_persist_live_session_runtime_preserves_resume_metadata(monkeypatch):
updates = {}