Skip to content

Commit 8959522

Browse files
authored
fix(config): replace subagent model settings atomically instead of merging (#234)
## Related Issue No issue. Follow-up to the subagent model pin Settings work: the pin could not be switched off and pool → default transitions kept the pool table on disk. ## Problem `POST /config` merged every domain one at a time. For `secondary_model` that meant a change never dropped fields: switching the pin off kept `force = true`, moving from a pool to a single default kept `[secondary_model.models]`, and an invalid later domain left the earlier domains already written. The web client also omitted `force` when it was false, which hid the bug behind merge semantics. ## What changed - `routes/config.ts` stages every domain from the persisted user layer (`inspect().userValue`, never the effective value — env and default values must not be written back), merges ordinary domains with the registered section merge, replaces `secondary_model`, and commits through one `replaceSections()` call. An invalid domain rejects the whole request; nothing reaches disk. - `rest-config.ts` types the `secondary_model` body (`default_model`/`defaultModel`, `model`, `default_effort`/`defaultEffort`, `models`, `force`, strict). `force: false` normalizes to absence. - `ConfigService.replace()` / `replaceSections()` now really replace on disk: `applySectionToToml` has a `replace` mode that no longer re-adds keys from the previous section value. Before this, only the in-memory state was replaced and stale keys came back on reload. - `SettingsDialog.vue` serializes `force: false` explicitly. This is a compatibility defense for older gateways only; correctness does not depend on it (test name says so). - `dist-web` rebuilt from source. Tests (all fail on `main`): force true → false drops `force`; pool → default drops `models`; pool → force drops `models`; invalid multi-domain request leaves every domain unchanged; providers patch still merges; an env-bound section patch never writes env/default values to the user layer; malformed and unknown-key `secondary_model` bodies are rejected; core `replace`/`replaceSections` drop keys on disk and survive `reload()`; Settings emits `force: false`. ## Checklist - [x] I have read the [CONTRIBUTING](https://github.com/PyModel/pythinker-code/blob/main/CONTRIBUTING.md) document. - [ ] I have linked a related issue (external PRs: the issue must have a maintainer's `/approve`). - [x] I have added tests that prove my feature works. - [x] Ran `gen-changesets` skill, or this PR needs no changeset. - [x] Ran `gen-docs` skill, or this PR needs no doc update. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed subagent model settings so disabled or changed options no longer retain stale force, pool, or related values. * Improved configuration replacement so removed fields and nested settings stay removed after saving and reloading. * Added stricter validation for legacy secondary-model configuration updates. * Ensured configuration updates are applied atomically, preventing partial changes when invalid data is submitted. * **Chores** * Refreshed bundled web assets and diagram support without changing existing rendering behavior. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 974da73 commit 8959522

103 files changed

Lines changed: 442 additions & 142 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@pymodel/pythinker-code": patch
3+
---
4+
5+
Subagent model settings no longer keep stale force or pool values after a change.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"sourceHash": "d530cf09e14c32e121edc34ab7cc75c8d69ca2d08e002c230d120e5e378742f9",
2+
"sourceHash": "de035986f5cd2b25cb86fe5a4fccb3b7cace86f47da191388a3b2485f2fc0093",
33
"sourceFileCount": 405
44
}

apps/pythinker-code/dist-web/assets/CodeBlockNode-BzjrU699.js renamed to apps/pythinker-code/dist-web/assets/CodeBlockNode-BHxsDepl.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/pythinker-code/dist-web/assets/DesignSystemView-fwrkOU6U.js renamed to apps/pythinker-code/dist-web/assets/DesignSystemView-DYIVh4E3.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/pythinker-code/dist-web/assets/Tooltip-DlHtQ3v9.js renamed to apps/pythinker-code/dist-web/assets/Tooltip-CjDZkfwL.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/pythinker-code/dist-web/assets/abnfDiagram-VCTEODGH-Dr80cbBf.js renamed to apps/pythinker-code/dist-web/assets/abnfDiagram-VCTEODGH-CmvdyVev.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/pythinker-code/dist-web/assets/arc-IjDOt_gL.js renamed to apps/pythinker-code/dist-web/assets/arc-DKF6QHIp.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/pythinker-code/dist-web/assets/architectureDiagram-5GKGNRK7-CfNr9zsT.js renamed to apps/pythinker-code/dist-web/assets/architectureDiagram-5GKGNRK7-piSGt784.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)