Skip to content

Commit 55d12a2

Browse files
authored
feat(web): Subagent Model Routing control backed by the policy endpoint (#240)
## Related Issue No issue. Seventh step of the subagent routing work. Stacked on #239 (merge #234#239 first; until then this diff includes their commits). ## Problem Settings wrote the legacy `secondary_model` section through `POST /config` (merge semantics, no version check) and only showed the saved value — never what actually applied when the secondary-model feature was disabled or an environment override was in play. ## What changed - Agent tab: the model picker + "Always use this model" switch are replaced by **Subagent Model Routing** — Inherit / Default / Pool / Force radios, the existing `SecondaryModelPicker` (model + thinking effort) for Default and Force, a checklist with a chosen default for Pool, and an **Effective routing** card that shows `Saved policy` next to `Effective routing` plus `Secondary-model feature is disabled; subagents inherit the main model` when the feature is off. Model choices come from the model catalog (this screen selects models, not profiles). - Reads/writes go through `GET/PUT/DELETE /config/subagent-model-policy` with `If-Match` on the last read `resourceVersion`. A 412 adopts the server's current state, surfaces the conflict as an operation failure, and never overwrites the other writer. - `DaemonHttpClient.exchange()` adds PUT/DELETE with extra request headers, response headers, and allowed envelope codes. `AppSubagentModelPolicy`/`AppSubagentModelPolicyState` types, wire mappers, workspace-state actions (`loadSubagentModelPolicy`, `saveSubagentModelPolicy`, `clearSubagentModelPolicy`) and client exposure. - The `force: false` compatibility test from #234 is removed with the legacy path (the web and gateway ship in one bundle, so there is no version skew to defend). - `dist-web` rebuilt. Tests: section shows only once the policy state is loaded and sits after the default model; one payload per mode (inherit → clear, default/force → picked model + effort, pool → models map with default); saved vs effective card and the feature-disabled line; workspace state writes with the last read version and adopts the server state on a 412. ## 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 * **New Features** * Added subagent model routing controls with Inherit, Default, Pool, and Force modes. * Settings now show both the saved routing policy and currently applied routing. * Added options to fold completed turns and consecutive tool activity runs. * Tasks can be detached from the foreground and continue running in the background. * Added clearer experimental-feature status indicators. * **Bug Fixes** * Improved recovery when saved routing settings conflict with a newer version. * Improved handling of task and routing updates received during active sessions. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent fdaf83d commit 55d12a2

107 files changed

Lines changed: 950 additions & 483 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": minor
3+
---
4+
5+
Settings gains a Subagent Model Routing control with Inherit, Default, Pool, and Force modes and shows the saved policy next to the routing that currently applies.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"sourceHash": "f7f3ed6157809fd616d25b246300a55af33b2e2893911910ae1a2742c790b499",
2+
"sourceHash": "c294d9482527fbd47119352fcaac10f9870f9ef62d7228be22642ea8bd1a7804",
33
"sourceFileCount": 407
44
}

apps/pythinker-code/dist-web/assets/CodeBlockNode-Bidu8-un.js renamed to apps/pythinker-code/dist-web/assets/CodeBlockNode-33pAwoCL.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-CZk8453S.js renamed to apps/pythinker-code/dist-web/assets/DesignSystemView-4b_cOQ1c.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-BctK2XcE.js renamed to apps/pythinker-code/dist-web/assets/Tooltip-CcCCxqwO.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-BAqRO8Bh.js renamed to apps/pythinker-code/dist-web/assets/abnfDiagram-VCTEODGH-BfFA3n2p.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-H6nfPZnv.js renamed to apps/pythinker-code/dist-web/assets/arc-D4p47luw.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-CXQ7WtjQ.js renamed to apps/pythinker-code/dist-web/assets/architectureDiagram-5GKGNRK7-CijUuhX1.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)