Skip to content

fix(tui_gateway): restore openrouter provider on session resume - #57593

Closed
liuhao1024 wants to merge 1 commit into
NousResearch:mainfrom
liuhao1024:liuhao/cron-bugfix-57588-openrouter-resume
Closed

liuhao1024 wants to merge 1 commit into
NousResearch:mainfrom
liuhao1024:liuhao/cron-bugfix-57588-openrouter-resume

Conversation

@liuhao1024

Copy link
Copy Markdown
Contributor

What does this PR do?

When a user switches from OpenRouter to a custom endpoint, resuming any previous OpenRouter session fails with a misleading context-window error. The root cause is _BARE_BILLING_PROVIDERS in tui_gateway/server.py treating "openrouter" as a non-routable billing bucket (alongside "auto" and "custom"), which causes _stored_session_runtime_overrides to drop the provider override on resume. The session then falls back to the current global model (the custom endpoint), which serves a completely different model catalog and returns a tiny context window for the stored model name.

OpenRouter is a fully routable provider with its own API key, base URL, and model catalog. Removing it from _BARE_BILLING_PROVIDERS lets OpenRouter sessions correctly restore their provider identity on resume.

Related Issue

Fixes #57588

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • tui_gateway/server.py — Remove "openrouter" from _BARE_BILLING_PROVIDERS set. "auto" and "custom" remain as non-routable billing classes. Added comment explaining why "openrouter" is excluded ([Bug]: Adding new custom provider breaks all previous sessions. Provider changes, but not the model. #57588).
  • tests/test_tui_gateway_server.py — Updated test_stored_session_runtime_overrides_skips_bare_billing_provider to remove "openrouter" from the bare-bucket loop. Added test_openrouter_session_resume_restores_provider regression test verifying that OpenRouter sessions restore the "openrouter" provider override on resume.

How to Test

  1. Configure Hermes with a custom endpoint (e.g. Featherless) as the default model.
  2. Create a session using OpenRouter (e.g. anthropic/claude-opus-4.8).
  3. Exit and restart Hermes.
  4. Resume the OpenRouter session via /sessions.
    • Before: fails with "context window of 2,048 tokens, which is below the minimum 64,000" because the resume hits the custom endpoint with the OpenRouter model name.
    • After: session resumes correctly using OpenRouter as the provider.
  5. Automated: python -m pytest tests/test_tui_gateway_server.py::test_stored_session_runtime_overrides_skips_bare_billing_provider tests/test_tui_gateway_server.py::test_openrouter_session_resume_restores_provider tests/tui_gateway/test_custom_provider_session_persistence.py -v → should pass.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes
  • I've tested on my platform: macOS

Documentation & Housekeeping

  • I've updated relevant documentation — N/A (no doc/docstring impact)
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — N/A
  • I've considered cross-platform impact (Windows, macOS) — N/A (pure Python logic, no platform-specific code)
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A

BARE_BILLING_PROVIDERS incorrectly included "openrouter" alongside
"auto" and "custom".  OpenRouter is a fully routable provider with
its own API key and base_url — sessions that used OpenRouter store
billing_provider="openrouter", and dropping it forces resume to the
current global model (e.g. a custom endpoint), which is the wrong
provider for the stored model.

Remove "openrouter" from the bare-bucket set so OpenRouter sessions
correctly restore their provider identity on resume.

Fixes NousResearch#57588
@alt-glitch alt-glitch added type/bug Something isn't working comp/tui Terminal UI (ui-tui/ + tui_gateway/) P2 Medium — degraded but workaround exists sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 3, 2026
@teknium1

Copy link
Copy Markdown
Collaborator

Thanks for the focused regression fix. Current main still has "openrouter" in _BARE_BILLING_PROVIDERS at tui_gateway/server.py:2243; _stored_session_runtime_overrides() consequently drops it at tui_gateway/server.py:2282. Both deferred and eager session.resume paths consume that helper at tui_gateway/server.py:5778 and tui_gateway/server.py:5861.

The proposed change restores the provider exactly at the shared helper, while preserving the existing auto and custom filtering. The added regression test is a behavioral contract for the affected stored-session shape. The current tree's OpenRouter profile is registered as a concrete provider at plugins/model-providers/openrouter/__init__.py:170-188.

This is an automated hermes-sweeper review.

@kshitijk4poor

Copy link
Copy Markdown
Contributor

Merged via #85558 — your commit was cherry-picked onto current main with your authorship preserved (1c87772186 on main). The branch here was ~7,900 commits behind, so we salvaged rather than rebased; the only addition was a follow-up comment fix.

Thanks for the focused fix and the regression test — this closes #57588. (@Ahmett101's #57597 implemented the same fix and is credited in the salvage PR as well.)

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

Labels

area/sessions Session lifecycle, resume, persistence, history comp/tui Terminal UI (ui-tui/ + tui_gateway/) P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Adding new custom provider breaks all previous sessions. Provider changes, but not the model.

4 participants