Skip to content

fix(session): include delegated agent usage in totals - #302

Open
li-xiu-qi wants to merge 1 commit into
stepfun-ai:mainfrom
li-xiu-qi:fix/subagent-session-usage
Open

li-xiu-qi wants to merge 1 commit into
stepfun-ai:mainfrom
li-xiu-qi:fix/subagent-session-usage

Conversation

@li-xiu-qi

@li-xiu-qi li-xiu-qi commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #180

Problem

After a subagent or workflow finishes, its own result can display token usage and cost, but /session omits that spending from the parent session's totals. Users therefore cannot reconcile a task's actual cost without manually adding every delegated result. Issue #180 reports the same gap for workflows.

The usage was already collected, but the handoff into the parent session ledger was incomplete: foreground results did not populate ToolResultMessage.usage, workflow terminal errors discarded it, and background lanes had no notification-independent accounting path. Adding parent-side records also required an Overview deduplication rule so parent and child transcripts would not be counted twice.

Changes

  • Convert aggregated subagent and workflow usage into the existing provider Usage shape and persist it on foreground tool results, including cache and total cost.
  • Preserve usage and childSessionIds through workflow terminal errors and the generic agent-loop error-result path. Keep the original error type and message whenever the error object is extensible.
  • Add one idempotent step-subagent-usage entry per background lane turn. Queued replies, interrupts, stops, and shutdowns now settle usage without depending on a terminal notification. Runner and worktree-cleanup failures retain previously observed usage.
  • Deduplicate Overview by the specific child sessions named in parent records. Existing child transcripts remain the fallback when no parent record covers them, while reasoning metadata continues to be counted independently of token suppression.
  • Update the usage projection and public lifecycle/session documentation to match the persisted data and accounting semantics.

Behavior and compatibility

  • /session, the footer, and RPC session totals now include subagent and workflow token usage and cost. Commands, tool arguments, provider requests, model prompts, and notification timing are unchanged.
  • WorkflowRunResult gains optional usage and childSessionIds; WorkflowAgentRunResult gains optional sessionId. These are additive fields. Existing results and transcripts without them remain valid and need no migration.
  • Background launch results intentionally carry no usage. Each turn writes its own ledger entry once, preventing launch/progress duplication and cross-turn reuse of earlier results.
  • Workflow cache replays do not consume the cached usage again. When only aggregate cost is available, cost.total is authoritative and zero component fields mean that no component split was provided.

Validation

  • New and updated regressions were checked against the defective behavior first, then against the fixed implementation. They cover foreground and background subagents, workflow success and terminal errors, Overview first reads and cache hits, and reasoning preservation.
  • npm run check from the repository root: passed on Windows with Node v24.21.0.
  • cd packages/agent-core && pnpm exec vitest --run test/agent-loop.test.ts: 38/38 passed.
  • cd packages/coding-agent && pnpm exec vitest --run test/step-usage.test.ts test/suite/agent-session-delegated-usage.test.ts: 30/30 passed. This covers the real AgentSession consumer path, including workflow failure, budget exhaustion, top-level script failure, and synchronous background progress.
  • cd packages/coding-agent && pnpm exec vitest --run test/step-subagent-events.test.ts -t "later preflight|rejected later turn": 2/2 passed, proving that a later turn cannot reuse the previous turn's usage.
  • cd packages/coding-agent && pnpm exec vitest --run test/subagent-chain-result.test.ts test/step-subagent-events.test.ts -t "usage|worktree cleanup": 3/3 passed, including runner-failure and cleanup-failure usage preservation.
  • cd packages/coding-agent && pnpm exec vitest --run test/subagent-child-env.test.ts: 8/8 passed.
  • A broader related 15-file run covered 225 tests: 222 passed. The same three failures occur on unmodified upstream/main (baseline: 207/210 passed). This run also reported one Windows temporary-directory cleanup error, while the baseline reported two. The 15 additional tests in this branch passed.
  • Fork CI on commit d52521b: run 40116834458 completed with conclusion: success, covering build, check, and test on Ubuntu.
  • Upstream PR CI on the same commit: run 40117569158, attempt 2, completed with conclusion: success; the Build, Check, and Test steps all completed successfully. Attempt 1 failed during coding-agent tests without a failure summary and was rerun without code changes.
  • git diff --check: passed. Public-content review found no private paths, credentials, AI attribution, debug residue, or unrelated files.

Limitations

  • The existing subagent-child-env.test.ts timing tests can still be flaky under heavily parallel Windows runs: the 400 ms idle timeout may fire before queued child output is processed or race the 700 ms wall-clock assertion. This PR leaves those tests and the underlying timeout behavior unchanged because stabilizing them is outside the scope of subagent 的 token 花费不计入 /session,两个视图数字不一致 #180.
  • The three local Windows failures in step-subagent-events.test.ts (oversized-output notification), subagent-exit-drain.test.ts (quiet-descendant exit), and workflow-runtime.test.ts (transient progress-write failure) are pre-existing. They fail identically on unmodified upstream/main, so they are not introduced by this change and are not fixed by this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

subagent 的 token 花费不计入 /session,两个视图数字不一致

1 participant