fix(gateway): stale model/provider keys no longer survive session model_config writes (salvage #96748) - #97066
Merged
Merged
Conversation
_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.
Contributor
૮ >ﻌ< ა ci reviewran on f559e74 — chore: contributor mapping for ahrazzle
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stale
model/providerkeys in a session row'smodel_configno 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_configmerges the agent's current identity onto the row's existingmodel_configJSON. Formodelandproviderit only set the key when the agent attribute was truthy — whilebase_url/api_mode/reasoning_config/service_tieralready 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_runtimeupdated themodelcolumn separately. On resume,_stored_session_runtime_overridesread the fresh model from the column but the STALE provider frommodel_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 agentmodel/providernow DELETE the corresponding key from the merged config (config.pop(...)), mirroring the or-None semantics the CLI's_persist_model_switch_to_sessionalready uses. Existing desynced rows self-heal on the next live metadata persist.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.com→ahrazzleattribution mapping.Validation
_runtime_model_configonorigin/mainstill only setsmodel/providerwhen truthy (lines 5439–5470), nopopon the falsy pathtest_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)tests/tui_gateway/test_custom_provider_session_persistence.py— 34 passedtest_custom_provider_session_persistence.py+test_stale_provider_resume_live.py— 37 passedorigin/main; diff touches only the 3 files aboveCredit
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