FIX: Fix per-subagent model configs#1682
Merged
Merged
Conversation
Contributor
|
Thanks for the PR, Louis. I pushed a small follow-up commit that keeps the scoped model config fields reactive, but only refreshes the clean settings snapshot when the loaded config was already considered clean. That preserves the fix for false unsaved-change warnings while keeping reset/default changes visible as unsaved until Save. I also added a tiny regression assertion for that guard. |
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.
When per-subagent model assignments are made, they are not saved and the UI doesn't reflect them. This fix was made with AI assistance and human reviewed.
The problems stemmed from how the frontend's reactivity system (Alpine.js) handled the dynamic loading of settings when a user changed the "Project" and "Agent Profile" dropdowns:
The "Unsaved Changes" Popup: When the user switched the Agent Profile to "Developer", the application fetched the correct settings and created a snapshot to monitor for unsaved changes. However, an initialization script ran a moment later to insert empty default properties (like _kwargs_text) if they were missing. Since this modification happened after the snapshot was taken, the UI falsely believed the user had manually changed something.
Changes Reverting to Default Model: The UI elements where the user typed the new model name were tied to a local variable populated only once when the modal first opened (using the Global configuration). When the user switched the scope to "Developer", the main configuration object was updated under the hood, but the UI fields remained permanently tethered to the old "Global" object.
When the user typed his new model name, they were modifying the orphaned object.
When the user clicked "Save", the system submitted the newly loaded (but completely unmodified) "subagent" object. Because it was empty/unmodified, it saved the fallback default model to disk.
This resulted in the engine ignoring user changes (since the default was saved) and the dialogs showing the default model when reopened.
Fixes:
Modified the Alpine components in _model_config:
Reactive Getters (config.html): Changed model: config[section.key] to a reactive getter get model() { return config[section.key]; }. This ensures the UI fields always point to and mutate the currently active configuration scope, regardless of how many times the user switches the dropdowns.
Lifecycle Syncing (config.html): Migrated the initConfigFields logic from a one-time x-init call into an x-effect that watches for scope changes. When a new scope is loaded, it initializes the fields and immediately updates the settingsSnapshotJson to prevent the false "Unsaved Changes" warning.
Dynamic Store Hooks (model-config-store.js): Updated the installSettingsHooks method to read context.settings dynamically upon save, rather than locking into the stale object from initialization.