feat(core): expose subagent task tracker for delegated runs#35
Merged
Conversation
Adds a materialized view over the existing SubagentStart/Progress/End
event stream so callers can query the lifecycle of delegated child runs
by task id — without scanning run_events() — making automatic parallel
delegation observable like a task dashboard.
- New `subagent_task_tracker` module with `SubagentTaskSnapshot` +
`InMemorySubagentTaskTracker`; populated from runtime events via the
existing `RuntimeEventSink::observe` path.
- `AgentSession` gains `subagent_task(id)`, `subagent_tasks()`, and
`pending_subagent_tasks()` query APIs, scoped to the parent session.
- Fixes two pre-existing bugs in `TaskExecutor`:
1. `SubagentStart` now carries the real parent session id instead of
`String::new()`, so tracker entries are correctly associated with
the originating session.
2. `execute_background` now returns the same task id used in emitted
events (previously it generated a throwaway id and `execute`
internally generated a different one), and pre-emits `SubagentStart`
synchronously so callers can query the tracker immediately after
the background task is scheduled.
Event stream remains the authoritative record; the tracker is a
read-side projection that can be rebuilt by replaying events.
This was referenced May 23, 2026
This was referenced May 23, 2026
ZhiXiao-Lin
pushed a commit
that referenced
this pull request
May 23, 2026
Bumps Rust core, Node SDK, and Python SDK to 3.2.0 and documents the subagent task tracker work that landed across #35–#41 + #38. Changes - Bump all five version files (core/sdk Cargo.toml, sdk/node/package.json, sdk/python/pyproject.toml) plus Node lockfiles and Cargo.lock. - Mark SubagentStatus #[non_exhaustive] so future variants are non- breaking. The Cancelled variant added in this release still counts as a breaking change for exhaustive matchers — flagged in the CHANGELOG. - Add a [3.2.0] section to CHANGELOG.md covering: the tracker query API, SubagentProgress emission, the Cancelled status and cancel_subagent_task entry point, Node + Python SDK exposure of all of the above, the regen-stable Node .d.ts split, and the TaskExecutor / register_task_with_mcp signature additions. - Extend README with a "What's new in 3.2" block and a Delegation table that lays out the observe + cancel API across Rust, Node, and Python. Preflight done locally - cargo fmt --all --check - cargo test -p a3s-code-core --lib (1661 passed) - cargo test -p a3s-code-core --tests (all green) - scripts/check_release_versions.sh (consistent at 3.2.0) - (cd sdk/node && npm run build:debug && npm test && npm run test:types) Not run here: release.sh / git tag. This commit is for review only; tagging + publishing happens after the PR lands.
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.
Summary
Adds a queryable materialized view of delegated subagent task lifecycles so callers can introspect automatically-triggered parallel sub-agent runs like a task dashboard — without parsing
run_events().subagent_task_trackermodule:SubagentTaskSnapshot+InMemorySubagentTaskTracker, populated from the existingSubagentStart/Progress/Endevent stream viaRuntimeEventSink::observe.AgentSession:subagent_task(id),subagent_tasks(),pending_subagent_tasks()— all scoped to the parent session.TaskExecutor:SubagentStartnow carries the realparent_session_id(wasString::new()).execute_backgroundreturns the sametask_idused in emitted events (was returning a throwaway id), and pre-emitsSubagentStartsynchronously so callers querying the tracker right after scheduling don't hit a race.The event stream remains the authoritative record; the tracker is a read-side projection.
API surface
SubagentTaskSnapshotcarriestask_id,parent_session_id,child_session_id,agent,description,status,started_ms,updated_ms,finished_ms,output,success,progress(currently empty — wired in PR #2).Test plan
subagent_task_tracker.rscover lifecycle, failed-end, pending filter, parent-session filter, end-before-start, and non-subagent events.agent_api/tests.rscover end-to-end propagation throughRuntimeEventSinkand parent-session isolation.cargo test --lib -p a3s-code-core: 1651 passed / 0 failed.cargo test --tests -p a3s-code-core: all integration binaries green.cargo clippy --lib --tests -p a3s-code-core: no new warnings (3 pre-existing warnings inextra_agent_tests.rs/test_auto_delegation_real_parallel.rsare untouched).cargo fmtclean (pre-commit hook passed).Out of scope (follow-ups)
SubagentProgressfrom the child loop (event variant exists but is never sent today).index.d.ts).runs/run_eventsfamily).cancel_subagent_task(id)) — requires trackingJoinHandle+CancellationTokenin the tracker.