fix(bot-mode): bot sessions always follow the profile's current config - #90343
fix(bot-mode): bot sessions always follow the profile's current config#90343curator8888 wants to merge 2 commits into
Conversation
…rent config
Room member sessions in Bot Mode are per-member scratch conversations
inside a group chat. session.resume restored their stored model/provider
pin from the row's model_config, so a room bot stayed stuck on whatever
provider was pinned when the row was first written — even after the
profile was switched. Every room message then failed on the stale
provider (e.g. 'out of Nous credits' after switching a profile from
Nous to ollama-cloud) while the same bot worked fine in DMs.
Add an explicit room_plumbing contract:
- session.create accepts room_plumbing: true, persisted in model_config
- _stored_session_runtime_overrides() returns {} for marked rows, so a
room session always rebuilds from the member profile's CURRENT config
- hidden + 'Group:' title shape is kept as a legacy fallback for rows
created by older desktop builds that never sent the marker; hidden
non-room chats keep the stored-runtime restore
- Desktop Bot Mode sends room_plumbing: true when creating the hidden
per-member room sessions
Fixes NousResearch#89497
…config Bot-Mode canonical chats (the ONE forever DM per bot) and room plumbing sessions are plugin-owned scratch conversations. They are now created with an explicit follow_profile_config contract, persisted in the session row's model_config, so session.resume rebuilds from the member profile's CURRENT config instead of restoring the stored model/provider pin from an old row. That stale pin is what left bot DMs stuck on a dead provider (e.g. 'out of Nous credits' after the profile was switched to ollama-cloud) while the same bot worked fine in rooms — the mirror image of the room-plumbing bug (NousResearch#89497 class). Normal 1:1 user chats keep the stored-runtime restore: opening an older chat must show the model it actually used. - tui_gateway/methods_session.py: accept follow_profile_config on session.create - tui_gateway/server.py: persist the marker in the row; skip stored-runtime overrides on resume when present - apps/desktop/src/plugins/hermes-bots/plugin.js: send the contract from createCanonicalChat and ensureGroupChatSession - tests: backend override + row-persist coverage; desktop source-contract coverage for both session kinds
Reviewed by reviewer-e (AI automated review). Right contract design: replacing a presentation heuristic's scope creep with an explicit, persisted Nit (non-blocking): tui_gateway/server.py:4154-4207 — the |
|
Fresh user report validating this exact fix: #94818 (2026-08-25) reports that switching the model for a Bot Chat in settings has no effect — the chat keeps using the model pinned at session creation ("Model used during chat creation is model that is continued to use"). That's precisely the stale model/provider pin your |
…Bot Chats Bot Chats created before the follow_profile_config marker existed carry no contract in model_config, so they would stay pinned to a stale stored provider until deleted — the exact shape of the live reports (#89497, #94818). Mirror the plugin's own identity rule (the profile's session titled exactly 'Bot Chat') as a legacy fallback in _stored_session_runtime_overrides, matching the room-plumbing legacy 'Group:' title fallback. Follow-up to the salvaged #90343 (@curator8888) and #96111 (@lorzl).
|
Merged via PR #97008 (rebase-merge) — both of your commits landed on main with your authorship preserved in git log. We added one follow-up on top: a legacy backfill so canonical Bot Chats created BEFORE the follow_profile_config marker existed (rows titled exactly "Bot Chat") also follow the profile's current config — that covers users already stuck in the field. Thanks for the clean explicit-contract design. |
…Bot Chats Bot Chats created before the follow_profile_config marker existed carry no contract in model_config, so they would stay pinned to a stale stored provider until deleted — the exact shape of the live reports (NousResearch#89497, NousResearch#94818). Mirror the plugin's own identity rule (the profile's session titled exactly 'Bot Chat') as a legacy fallback in _stored_session_runtime_overrides, matching the room-plumbing legacy 'Group:' title fallback. Follow-up to the salvaged NousResearch#90343 (@curator8888) and NousResearch#96111 (@lorzl).
Fixes the #89497 bug class: bot sessions stuck on a stale provider pin after a profile switch.
Summary
Bot-Mode sessions (room plumbing AND the canonical per-bot DM chat) are plugin-owned scratch conversations. They are now created with explicit contracts —
room_plumbingfor group-chat member sessions,follow_profile_configfor the canonical Bot Chat — persisted in the session row'smodel_config, sosession.resumerebuilds from the member profile's CURRENT config instead of restoring the stored model/provider pin from an old row.That stale pin is what left bots stuck on a dead provider (e.g. "out of Nous credits" after the profile was switched to ollama-cloud) while the same bot worked fine elsewhere. Normal 1:1 user chats keep the stored-runtime restore: opening an older chat must show the model it actually used.
How to Test
Verification
_stored_session_runtime_overridesreturns{}for rows carrying either marker (dict and JSONmodel_configshapes); unmarked rows still restore stored runtime;_ensure_session_db_rowpersists each marker only when the contract is set. Legacy hidden + "Group:" title rows keep the room guard.createCanonicalChatsendsfollow_profile_config: true;ensureGroupChatSessionsends bothroom_plumbing: trueandfollow_profile_config: trueonsession.create.test_custom_provider_session_persistence.py+test_session_resume_db_ownership.py, 42/42 desktop group-chat tests.Type of Change
Checklist