Skip to content

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

Closed
HaozheZhang6 wants to merge 1 commit into
NousResearch:mainfrom
HaozheZhang6:fix/tui-resume-bare-billing-provider
Closed

fix(gateway): don't restore a bare billing provider as the resumed session's provider#44062
HaozheZhang6 wants to merge 1 commit into
NousResearch:mainfrom
HaozheZhang6:fix/tui-resume-bare-billing-provider

Conversation

@HaozheZhang6

Copy link
Copy Markdown
Contributor

What does this PR do?

Resuming an older chat in the desktop/TUI gateway failed with resume failed: No LLM provider configured whenever the session had only ever run normal turns (no /model switch) against a custom:<name> endpoint — even though new chats and hermes chat --resume <id> from the CLI work fine for the same sessions.

Root cause: _stored_session_runtime_overrides (tui_gateway/server.py) restored the session provider from billing_provider when model_config had no explicit provider. For a custom endpoint, the only thing persisted on a normal turn is billing_provider, and its value is the bare billing bucket "custom" (not the routable custom:<name> identity). That bare class was then set as the resumed session's provider_override / model_override.provider, and agent_init treats a bare auto/openrouter/custom as non-routable, so provider resolution returned no client and raised No LLM provider configured. The CLI is unaffected because it does not go through the session-scoped runtime-restore path.

Fix: only restore an explicit model_config.provider; skip a bare billing bucket so resume falls back to the configured default provider, matching the working CLI path. A real provider stored in billing_provider (e.g. anthropic) is still restored. Introduced by #43702.

Related Issue

Fixes #44022

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • tui_gateway/server.py_stored_session_runtime_overrides: split provider resolution so a bare billing bucket (auto/openrouter/custom, mirrored from the gate in agent_init) is no longer restored as the session provider; only an explicit model_config.provider (or a non-bare billing_provider) is.
  • tests/test_tui_gateway_server.py — added test_stored_session_runtime_overrides_skips_bare_billing_provider.

How to Test

  1. Configure a custom_providers endpoint as the default (model.provider: custom:<name>, api_mode: anthropic_messages).
  2. In the desktop/TUI app start a chat and send a couple of messages without using /model (so the row persists only billing_provider="custom").
  3. Reopen that chat: on main it fails with No LLM provider configured; with this change it resumes against the configured default.

Regression test: pytest tests/test_tui_gateway_server.py::test_stored_session_runtime_overrides_skips_bare_billing_provider (fails before, passes after). The existing test_session_resume_passes_stored_runtime_to_agent (a non-bare billing_provider) still passes, confirming real providers are still restored.

Checklist

  • Bug fix is non-breaking
  • Added a regression test that fails before and passes after
  • ruff check passes on the changed files

…ssion'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 NousResearch#44022
@liuhao1024

Copy link
Copy Markdown
Contributor

✅ Verified — Bare billing provider exclusion on session resume

Reviewed the diff for _stored_session_runtime_overrides() in tui_gateway/server.py.

  • Root cause: billing_provider="custom" (a billing bucket, not a routable provider) was being restored as the session's provider_override, causing "No LLM provider configured" on resume because agent_init treats bare buckets as non-routable.
  • Fix logic: Explicit model_config.provider takes priority. Bare billing buckets ("auto", "openrouter", "custom") are excluded. Real providers (e.g., "anthropic") still restore correctly.
  • Parity with agent_init: _BARE_BILLING_PROVIDERS matches the provider gate already used during initialization.
  • Tests: Covers bare "custom"/"auto"/"openrouter" → no provider, real provider → restored, explicit provider override → wins over bare bucket.

Targeted fix for a real resume regression. No issues found.

@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 Jun 11, 2026
@liuhao1024

Copy link
Copy Markdown
Contributor

Verification: reviewed diff — clean fix.

The root cause is clear: billing_provider values like "custom", "auto", "openrouter" are billing bucket identifiers, not routable provider identities. Restoring them as the session's provider override on resume causes agent_init to fail with "No LLM provider configured".

The fix correctly separates explicit_provider (from model_config.provider) from billing_provider (from model_config.billing_provider or row.billing_provider), and only restores the billing provider as the session provider when it's not in the _BARE_BILLING_PROVIDERS set.

Priority chain is clean:

  1. model_config.provider (explicit, always restored if present)
  2. billing_provider (only if not a bare billing bucket)
  3. Fallback to configured default (provider left unset)

Test coverage is thorough: bare "custom"/"auto"/"openrouter" all correctly skipped, real provider "anthropic" correctly restored, explicit model_config.provider wins over bare billing bucket.

@alpharou

Copy link
Copy Markdown

Hit this exact bug on Windows desktop with a custom provider. Resume fails with "No LLM provider configured" for every older session, while CLI --resume works fine. The root cause diagnosis and the fix look correct (i've tested it locally on my windows instance). skipping bare billing buckets ("custom", "auto", "openrouter") from being restored as provider identity matches the CLI path and doesn't break real provider restoration.

Currently working around it by backfilling model_config in the sessions DB, but that's obviously not viable long-term. Would be great to get this in. the bug makes the desktop app basically unusable for custom provider users.

@HaozheZhang6

Copy link
Copy Markdown
Contributor Author

Thanks for testing on Windows — good to have the independent confirmation, the older-sessions resume path is exactly it.

@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #45578 with your commit cherry-picked onto current main and authorship preserved.

Thanks for the focused restore-side fix for #44022: bare billing buckets like custom are no longer restored as routable provider identities during Desktop/TUI session resume.

#45578

@teknium1 teknium1 closed this Jun 13, 2026
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 type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Desktop/TUI session.resume fails with "No LLM provider configured" when session only stored a bare billing_provider (e.g. custom)

5 participants