Repository navigation
Adopt upstream's subagent attribution once pingdotgg#5219 lands #20
Description
Activity
Parked: superseded by upstream PR pingdotgg#5219 — adopt, don't invent
The dev flagged that upstream has native subagent support incoming, and it checks out: pingdotgg/t3code#5219 ("native subagent & workflow observability", t3dotgg, WIP, extensively live-tested, active as of 2026-08-02), designed to be field-compatible with the orchestration-v2 series (pingdotgg#4779 et al.).
It contains this ticket's entire deliverable, done upstream: additive tool attribution (
agentId/parentToolUseId) on task and tool payloads, ClaudeAdapter resolvingparent_tool_use_idon tool events, zero migrations, riding the same event-sourced activity path our trace projection reads. It also covers Codex (live-probed collab fleets), which this ticket scoped out, and ports its own Agents right-panel — upstream's answer to the mindwalkAgentsPanelwe skipped.Building this now would have collided twice:
- Our
parentToolCallIdbeside theirparentToolUseIdin the same contracts — a guaranteed merge conflict in exactly the files this fork swears to barely touch. - This ticket's "no suppression — subagent items appear in the work log" is the opposite of feat: native subagent & workflow observability pingdotgg/t3code#5219's quiet timeline, which re-homes agent-attributed rows to the panel and folds lifecycle rows into a spawn CTA. Upstream's merge would have reversed our visible behaviour.
What this ticket becomes when pingdotgg#5219 merges into the fork: a mapping pass, not an ingest change.
TraceProjection.ts's lens gate already reads an optionalparentToolCallIdoff the payload and treats absence as "main" (includedByLens); it points at upstream's field name instead. #21's graph derivation likewise reads upstream's linkage. No fork-owned ingest, no contract edits.Blocked on: pingdotgg#5219 merging upstream, then an upstream merge into this fork.
- Our
- changed the title
[-]Persist the subagent attribution edge[/-][+]Adopt upstream's subagent attribution once pingdotgg#5219 lands[/+]on Aug 2, 2026
Part of #1
Question
Add the subagent attribution edge to T3's model, so subagent work is distinguishable from main-agent work in the event store.
Decided in Close the agent-lenses data gap — see that ticket for the full reasoning. This ticket executes it (the map's Notes carry execution).
Resized by measurement
Measure the fidelity of forwarded subagent tool payloads proved subagent content arrives only as complete
assistant/usermessages — 0 of 32stream_eventmessages carried aparent_tool_use_id. T3 emits tool items only from thestream_eventpath, andhandleAssistantMessagedrops everytool_useblock butExitPlanMode(ClaudeAdapter.ts:2522).So this is not "stop discarding a field." T3 must start emitting tool items for subagent blocks, from the complete-message path, attributed. Payload fidelity is confirmed full (paths, commands, multi-KB results), so the data is all there.
The change:
parentToolCallId?: stringtoItemLifecyclePayload(packages/contracts/src/providerRuntime.ts:404) — the id of the launching tool call, never a thread id, never a T3-invented agent id.tool_use/tool_resultblocks inhandleAssistantMessage, populatingparentToolCallIdfrom the message'sparent_tool_use_id. These blocks are on the wire today and dropped.stream_eventand ignores the complete message. Only blocks with a non-nullparent_tool_use_idmay be emitted from the complete-message path.forwardSubagentTextoff. Mindwalk'sEventis 100% tool-derived; no scene renders subagent prose.projectActivityPayload— it should, untouched, since the projection spreads...payloadand rewrites onlydata(ActivityPayloadProjection.ts:195-201). No widening of the six-key whitelist.Scope boundary — server-side only, and no suppression. Subagent items are allowed to appear in chat. They are ordinary tool-lifecycle items, so they join the per-turn work log group that already collapses by default (
expandedWorkGroupIds,MessagesTimeline.tsx:224; auto-expanded only for the latest turn, line 1289), with run-length collapsing insession-logic.ts. The assistant message body is untouched, so nothing bloats. No ChatView or mobile change is needed — this ticket is entirely server-side.Accepted consequence: a
Task's interior appears as a flat run of entries inside the turn's work log, in arrival order, rather than nested under its launch row. Nesting it properly is a product feature and stays fog.No backfill. Threads already in the event store keep their flattened, unattributed subagent calls. The id was never written down.
Out of scope here: the other four providers. Codex and OpenCode attribution is unmeasured, Cursor/Grok emit no
collab_agent_tool_callat all. When a provider does gain an edge, its adapter resolves whatever it has (e.g. a Codex parent thread id) to the launching call id itself.