Skip to content

fix(gateway): stale model/provider keys no longer survive session model_config writes (salvage #96748) - #97066

Merged
teknium1 merged 2 commits into
mainfrom
salvage/96748-stale-model-config
Aug 28, 2026
Merged

teknium1 merged 2 commits into
mainfrom
salvage/96748-stale-model-config

Conversation

@teknium1

Copy link
Copy Markdown
Collaborator

Stale model/provider keys in a session row's model_config no longer survive gateway persist writes — a resumed chat can no longer be silently routed to the wrong (but still-routable) provider.

Salvage of #96748 onto current main (rebased over the #97008 resume-side changes).

Problem

tui_gateway/server.py::_runtime_model_config merges the agent's current identity onto the row's existing model_config JSON. For model and provider it only set the key when the agent attribute was truthy — while base_url/api_mode/reasoning_config/service_tier already deleted stale values when falsy. So an agent rebuilt with an empty provider (inheriting the profile default) left the PREVIOUS provider/endpoint in the JSON while _persist_live_session_runtime updated the model column separately. On resume, _stored_session_runtime_overrides read the fresh model from the column but the STALE provider from model_config — silently routing the chat to the wrong endpoint (e.g. a VeniceAI route under a model that should run on the profile default).

Note this is complementary to #97008 (merged as 547f4c9): that fixed the resume/read side for non-routable providers. This PR fixes the write side, where the stale key can name a still-routable but WRONG provider — a case #97008's routability check does not (and cannot) drop.

Changes

  • _runtime_model_config: falsy agent model/provider now DELETE the corresponding key from the merged config (config.pop(...)), mirroring the or-None semantics the CLI's _persist_model_switch_to_session already uses. Existing desynced rows self-heal on the next live metadata persist.
  • Docstring documenting the merge contract (falsy attributes delete, never merely omit).
  • 6 regression tests in tests/tui_gateway/test_custom_provider_session_persistence.py (TestRuntimeModelConfigDropsStaleKeys): falsy provider drops stale provider, falsy model drops stale model, truthy provider overwrites, end-to-end resume override falls back to billing provider, real-SQLite desynced-row heal, and first-write (existing=None) shape.
  • contributors/emails/ahraz.arifuddin@gmail.comahrazzle attribution mapping.

Validation

Check Result
Premise on current main Confirmed live — _runtime_model_config on origin/main still only sets model/provider when truthy (lines 5439–5470), no pop on the falsy path
Sabotage A/B — fix reverted, tests kept 4 new tests FAIL (test_falsy_provider_drops_stale_existing_provider, test_falsy_model_drops_stale_existing_model, test_resume_overrides_get_no_stale_provider, test_real_db_persist_heals_desynced_row)
Fix restored tests/tui_gateway/test_custom_provider_session_persistence.py34 passed
Full targeted run (incl. #97008's live suite) test_custom_provider_session_persistence.py + test_stale_provider_resume_live.py37 passed
Stale-base gate 0 commits behind origin/main; diff touches only the 3 files above

Credit

Fix and regression tests by @ahrazzle (#96748) — cherry-picked with authorship preserved; test-file conflict with the post-#97008 classes on main resolved keeping both sides.

Infographic

Stale provider keys dropped — gateway session model_config fix

ahrazzle and others added 2 commits August 28, 2026 03:50
_runtime_model_config merges the agent's current identity onto the row's
existing model_config JSON. For model and provider it only SET the key
when the agent attribute was truthy, while base_url/api_mode/
reasoning_config/service_tier already deleted stale values when falsy.
When an agent rebuilt with an empty provider (inheriting the profile
default) was persisted, the previous provider/endpoint survived in
model_config while _persist_live_session_runtime updated the model
column separately. Resume then read the fresh model from the column but
the STALE provider from model_config, silently routing the resumed chat
to the wrong endpoint (e.g. a VeniceAI/empero route under a model that
should run on the profile default).

Apply the same delete-on-falsy rule to model and provider, mirroring the
or-None deletion the CLI path (_persist_model_switch_to_session) already
uses, so a stale session state can never survive into a resume override.
Existing desynced rows self-heal on the next live metadata persist.

Adds regression tests: merge drops stale provider/model when the agent
attribute is falsy, a truthy provider overwrites the stale value, resume
overrides fall back to the billing provider instead of the stale
endpoint, a real-DB round trip heals an already-desynced row, and a
first write (existing=None) reflects only the agent's current identity.
@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on f559e74 — chore: contributor mapping for ahrazzle

⚠️ Warnings

OSV vulnerability scan · View job

6 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.


debug info

CI timings

CI timings · View report · View job

Wall time 4m7s vs 4m9s (-0.8%). 6 job(s) slower, 4 faster, 2 unchanged.

  • OS-specific tests / macOS-only tests: -12.0s
  • Python lints / Windows footguns (blocking): +7.0s
  • Python tests / e2e: -4.0s
  • Python lints / ruff enforcement (blocking): +4.0s
  • Check no committed infographics / check-no-committed-infographics: +3.0s

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/tui Terminal UI (ui-tui/ + tui_gateway/) area/config Config system, migrations, profiles sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Aug 28, 2026
@teknium1
teknium1 merged commit b0f40ad into main Aug 28, 2026
39 checks passed
@teknium1
teknium1 deleted the salvage/96748-stale-model-config branch August 28, 2026 11:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/tui Terminal UI (ui-tui/ + tui_gateway/) P2 Medium — degraded but workaround exists sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades 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.

3 participants