You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since #421/#444, (await agent()).lineage answers "who is my parent, what is my root, am I a subagent" for the current request. It does not answer the other half of "where am I in the agent topology": who else is alive under my root (siblings), what did I spawn (children), and which other root conversations are live in this workspace.
A plugin that coordinates agent threads (the examples/worktree-proximity pattern: one root, several subagents in linked worktrees, warn/notify the other actor) therefore still has to hand-roll a topology state definition and feed it from session/start + agent/start + stop itself, even though the warm runtime already keeps exactly that tree in the agent lineage registry. The example does not use request.lineage at all (zero references under examples/worktree-proximity/src), because the axis cannot tell it who its peers are.
Evidence (main @ 284141958)
packages/rsc-runtime/src/agent-request.ts:113-123 — AgentLineage is { conversation, depth, generation?, parent?, resolution, root, subagent? }: the request's own chain only.
packages/rsc-runtime/src/lineage/state.ts:10-32, 49-66 — the registry already journals every node (id, parent, root, depth, startedAt, stoppedAt, type, isParallelWorker) in LineageState.nodes.
packages/rsc-runtime/src/lineage/registry.ts:48-60 — AgentLineageRegistry.snapshot() is documented as "for dumps and the Workbench"; packages/agent-bundle/src/build/entry-shell.ts:1028-1041 hands the registry only to createGeneratedRouteMcpServer. No route surface (agent(), providers, services) can reach it.
examples/worktree-proximity/src/state.ts:93-165 — the hand-rolled topologyStateDefinition (actors with kind: root|child, parentSessionId, status), fed by src/events/session/start.tsx, src/events/agent/start.tsx, src/events/stop.tsx.
examples/worktree-proximity/README.md:47-49: "one workspace-durable topology definition and the framework notice definition share the generated runtime's SQLite driver"; README.md:70-81 documents the per-app actor bookkeeping this forces (native vs derived provenance, worktree:<root> fallback identity).
Extend the axis rather than adding a new one, so unavailability semantics stay identical:
interfaceAgentLineage{// …existing fields…/** Live nodes the registry currently holds under the same root, excluding this conversation. */readonlysiblings?: readonlyAgentLineagePeer[];/** Live nodes whose parent is this conversation. */readonlychildren?: readonlyAgentLineagePeer[];/** Other live depth-0 conversations the registry holds (same workspace digest on Cursor). */readonlyroots?: readonlyAgentLineagePeer[];}interfaceAgentLineagePeer{readonlyconversation: string;readonlydepth: number;readonlyparent?: string;readonlystartedAt: string;readonlytype?: string;}
Fed from LineageState.nodes at resolve time (registry.tsresolve() / resolveToolCall()), pruned to stoppedAt === undefined. Alternative: a separate (await agent()).lineageTree() read so the per-request axis stays small; either is fine, the point is that routes can read the tree the runtime already keeps.
Design question: should roots be exposed at all (it crosses conversations that share nothing but an install), or only siblings/children under the caller's own root?
In examples/worktree-proximity: delete src/state.ts's actor bookkeeping (keep activities/intent), and have src/events/tool/before.tsx find the other actor's conversation through lineage.siblings instead of topology.actors; the existing route-unit journeys 1–6 in tests/route-unit/routes.test.ts and the cross-process suite packages/agent-bundle/tests/worktree-proximity-journeys.test.ts still pass, and a new test proves a child sees its sibling after two agent/start events and stops seeing it after the sibling's agent/stop.
Problem
Since #421/#444,
(await agent()).lineageanswers "who is my parent, what is my root, am I a subagent" for the current request. It does not answer the other half of "where am I in the agent topology": who else is alive under my root (siblings), what did I spawn (children), and which other root conversations are live in this workspace.A plugin that coordinates agent threads (the
examples/worktree-proximitypattern: one root, several subagents in linked worktrees, warn/notify the other actor) therefore still has to hand-roll a topology state definition and feed it fromsession/start+agent/start+stopitself, even though the warm runtime already keeps exactly that tree in the agent lineage registry. The example does not userequest.lineageat all (zero references underexamples/worktree-proximity/src), because the axis cannot tell it who its peers are.Evidence (
main@284141958)packages/rsc-runtime/src/agent-request.ts:113-123—AgentLineageis{ conversation, depth, generation?, parent?, resolution, root, subagent? }: the request's own chain only.packages/rsc-runtime/src/lineage/state.ts:10-32, 49-66— the registry already journals every node (id,parent,root,depth,startedAt,stoppedAt,type,isParallelWorker) inLineageState.nodes.packages/rsc-runtime/src/lineage/registry.ts:48-60—AgentLineageRegistry.snapshot()is documented as "for dumps and the Workbench";packages/agent-bundle/src/build/entry-shell.ts:1028-1041hands the registry only tocreateGeneratedRouteMcpServer. No route surface (agent(), providers, services) can reach it.examples/worktree-proximity/src/state.ts:93-165— the hand-rolledtopologyStateDefinition(actors withkind: root|child,parentSessionId,status), fed bysrc/events/session/start.tsx,src/events/agent/start.tsx,src/events/stop.tsx.examples/worktree-proximity/README.md:47-49: "one workspace-durable topology definition and the framework notice definition share the generated runtime's SQLite driver";README.md:70-81documents the per-app actor bookkeeping this forces (native vs derived provenance,worktree:<root>fallback identity).request.lineage. This issue asks only to read what that registry already holds — no new inference.Proposed shape (small)
Extend the axis rather than adding a new one, so unavailability semantics stay identical:
Fed from
LineageState.nodesat resolve time (registry.tsresolve()/resolveToolCall()), pruned tostoppedAt === undefined. Alternative: a separate(await agent()).lineageTree()read so the per-request axis stays small; either is fine, the point is that routes can read the tree the runtime already keeps.Design question: should
rootsbe exposed at all (it crosses conversations that share nothing but an install), or only siblings/children under the caller's own root?Out of scope / related
Acceptance
In
examples/worktree-proximity: deletesrc/state.ts's actor bookkeeping (keep activities/intent), and havesrc/events/tool/before.tsxfind the other actor's conversation throughlineage.siblingsinstead oftopology.actors; the existing route-unit journeys 1–6 intests/route-unit/routes.test.tsand the cross-process suitepackages/agent-bundle/tests/worktree-proximity-journeys.test.tsstill pass, and a new test proves a child sees its sibling after twoagent/startevents and stops seeing it after the sibling'sagent/stop.