Repository navigation
Commit a60a427
authored
feat(subagent): single routing resolver with persisted binding provenance (#237)
## Related Issue
No issue. Fifth step of the subagent routing work. Stacked on #236
(merge #234, #235, #236 first; until then this diff includes their
commits).
## Problem
Model selection for a new subagent lived in `planSpawn()` and again in
`resolveSubagentBinding()`, and nothing recorded why a child was bound
the way it was. A resumed child that kept an older model (created under
"main = Luna", resumed under "main = Sol") was indistinguishable from a
routing bug, and the Dynamic Workflow card had to guess.
## What changed
- `resolveSubagentModelRoute()` is the single binding authority (inherit
/ default / pool / force; `primary` override; force rejects any explicit
choice). `resolveSubagentBinding()` and the new
`SessionSubagentRoutingService` both delegate to it. `planSpawn()` is a
facade over the routing service; every plan carries `RoutingProvenance`
(`operation`, `profileSource`, `modelSource`, `policyMode`,
`policySource`, `featureSource`,
`resolvedFromRoutingEnvironmentRevision`, `routeDecisionFingerprint`).
- `SubagentBindingProvenance` is persisted once on the child (durable
agent event `subagent.binding_provenance.recorded` folded into a
replayable state key) when the child is created from a plan; forks
record `fork-inherit`. Resume reads it back: sources become
`resume-existing`, the original revision is kept, and the caller's
current `routingEnvironmentRevision` is reported alongside — never
written into the child.
- Live path: `SubagentTaskInfo`, the `subagent.spawned` event, REST
`/tasks`, the WS roster, and the session snapshot carry `routing` +
`current_routing_env_revision`; `packages/protocol` schemas and the web
client (`AppTask.routing`, `DynamicWorkflowMember`, card rows,
`keepLiveSubagents`) map them. Stable enum ids only; no display labels
on the wire.
- Durable path: the Dynamic Workflow result writes `<subagent … profile
model thinking profile_source model_source policy_mode policy_source
feature_source routing_env_revision route_decision started_at
completed_at>` through the existing attribute escaper;
`parseDynamicWorkflowResult` reads them and older results still parse.
- TUI: SDK types are additive/optional;
`agent-dynamic-workflow-progress` and `subagent-event-handler` compile
and their tests pass unchanged.
- `dist-web` rebuilt; state and wire manifests regenerated.
Tests: route matrix (inherit/default/pool/force × explicit/primary/none,
force rejects `primary`); routing service provenance for
spawn/pool/force/fork; two spawns share the environment revision and
differ in decision fingerprint; the mandatory Luna→Sol resume regression
(child stays on Luna, `resume-existing`, original revision A, current
revision B); provenance recorded exactly once per child for spawn and
fork; state fold + record guard; renderer attributes + escaping; gateway
task mapping and roster tracker; web projector, mappers, parser (new
attributes, old rows), card rows pass-through, task merge.
## 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**
* Subagent tasks and workflow results now display routing details,
selected profile/model sources, policy decisions, environment revisions,
and execution timestamps.
* Routing information is preserved across spawned, forked, background,
and resumed subagent runs.
* Server metadata now exposes effective experimental feature-flag
states.
* **Bug Fixes**
* Prevented routing metadata from being overwritten or lost when task
data is merged.
* Cleared stale suspension reasons when updated suspension events omit
them.
* Ensured secondary-model settings can be explicitly cleared when no
longer available.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->1 parent faeb195 commit a60a427
138 files changed
Lines changed: 2309 additions & 536 deletions
File tree
- .changeset
- apps
- pythinker-code/dist-web
- assets
- pythinker-web
- src
- api
- daemon
- composables
- lib
- test
- packages
- agent-core-v2
- docs
- src
- agent/tools/agent
- features/dynamic_workflow
- session
- tools/agent-dynamic_workflow
- session/subagent
- test
- features/dynamic_workflow
- session/subagent
- state
- tool
- agent-gateway
- src
- protocol
- routes
- transport/ws/v1
- test
- oauth/test
- protocol/src
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
| 2 | + | |
3 | 3 | | |
4 | 4 | | |
Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
0 commit comments