Subagent: reuse runtime spine for agent-as-tool delegation #49

Description

@Astro-Han

Goal

Build subagent as a first-class LLM delegation primitive without creating a second runtime or a second ledger.

A subagent is a real child agent run created through the existing AgentRun / RuntimeKernel.startTurn orchestration, exposed by a thin child-run seam such as RuntimeKernel.startChildTurn(...). RuntimeRunner remains the inner invocation pump; it should not become the persistence or lifecycle boundary.

The existing ExploreAgent should stay as a deterministic read-only helper. It is useful, but it is not the LLM subagent implementation.

Design filter

  • Simple enough: Day 1 adds one inline spec, one lineage field, and the minimal display metadata needed after restart.
  • Elegant enough: a subagent is still an AgentRun with parentRunId, not a new run type.
  • Reassuring enough: permissions, events, artifacts, recovery, abort, and inspection keep using the existing runtime machinery, with child runs kept out of the parent transcript unless explicitly summarized.

Existing spine to reuse

  • Events: RuntimeEvent / AgentRunEvent
  • Runs: AgentRunHeader / AgentRunStore
  • Permissions: existing PermissionMode × ToolCategory
  • Artifacts: existing ArtifactRecord
  • Inspection: existing agent-run inspect/read models
  • Runtime loop: existing RuntimeKernel.startTurn wiring, AiSdkFlow, and RuntimeRunner
  • Future handoff seam: RuntimeEvent.actions.transferToAgent

Day 1 shape

Add:

  • Inline AgentSpec passed by the spawn tool, not a stored registry:
    • name
    • systemPrompt
  • parentRunId on stored run headers and invocation/run lineage.
  • agentName display metadata on the child run header, copied from AgentSpec.name; do not store the child system prompt in the run header.
  • A narrow child-run starter, for example RuntimeKernel.startChildTurn(parentRunId, spec, prompt), exposed to the spawn tool as spawnChildAgent(spec, prompt) or an equally narrow capability. Do not expose full SessionManager / RuntimeKernel to tools.

Use existing or derived state instead of new duplicates:

  • Delegation prompt: first child input event, not a header copy.
  • Child identity: runId + parentRunId, not RuntimeEvent.branch for Day 1.
  • Parent linkage: use parentRunId because inspect/output and runtime ledgers are run-keyed; mirror existing turn lineage only where the current turn-state machinery needs it.
  • Permission mode: Day 1 spawn policy always runs the child in explore; do not put a general permission profile in AgentSpec yet.
  • Recursion limit: child backend does not receive the spawn tool; no Day 1 maxDepth field is needed.
  • Consumed state: parent tool result / event, not a mutable header flag.
  • Failures: existing InvocationFailure / AgentRunHeader.failureClass; headless AutonomousResultTaxonomy only when headless eval is involved.

Do not add:

  • SubagentRun
  • SubagentEvent
  • PermissionProfile
  • ArtifactRef
  • a subagent-specific failure taxonomy
  • fake AgentRun rows for deterministic tools
  • a stable custom-agent registry until users can actually define reusable project agents

Important boundaries

Same session is acceptable, but child execution still needs its own backend instance built with the child header and AgentSpec.systemPrompt. The current active-session path is one backend per session; startChildTurn must not accidentally reuse the parent backend through that slot. Either inject a child-built backend into the child AgentRun path or make the child starter own the child backend lifecycle explicitly.

Child backend lifecycle is run-scoped. Parent stop/abort must stop and dispose all active child backends, and child finalization must not incorrectly mark the session active while the parent run is still active.

Default session/chat read models, branch copy, and model-history reconstruction must exclude child runs by default. The parent transcript should contain only the spawn tool call/result or explicit child summary, not the child's raw event stream.

The child receives no implicit prior parent/session context in Day 1. Its first model input is the delegation prompt plus any explicit context the spawn tool chooses to pass.

Day 1 child toolset should contain only non-prompting read-only tools, such as read and shell_safe. Exclude web_read, custom_tool, and subagent until per-backend permission routing exists; otherwise a child permission request has no reassuring route back to the right backend.

Parent abort must propagate into the child run and child backend. Slot release should be tied to child finalization, including cancellation and failure.

Restart recovery must not leave a child permanently running. Day 1 can rely on the existing run recovery sweep if the child run header is created before long awaits; otherwise explicitly mark abandoned children as cancelled/failed.

Artifact lookup for agent_output should use the child run header's turnId, because artifacts are keyed by session/turn rather than only by run id.

First runnable path

Enable only:

  • foreground agent-as-tool execution
  • read-only LLM child agent
  • same session by default, linked by parentRunId
  • fresh child turnId, distinct from the parent turn
  • real child run through existing startTurn/AgentRun wiring
  • separate child backend with explore permissions and the child system prompt
  • allow-only local read toolset for the child, with no prompting categories and no spawn tool
  • existing subagent tool slot cap for concurrent foreground spawn tool calls in the parent turn
  • agent_list / agent_output as thin projections over existing run/event/artifact read models

Keep out of Day 1:

  • write-capable subagents
  • background subagents
  • nested subagents beyond one level
  • child web/custom tools that require permission prompts
  • full handoff
  • parallel workflow templates
  • custom project agent library / stable agent registry

Acceptance criteria

  • Parent can spawn a read-only LLM child agent through a tool call.
  • Child is stored as a real AgentRun through existing startTurn/AgentRun wiring.
  • Child run header records parentRunId and agentName.
  • Child run has a fresh turnId different from the parent turn.
  • Child events use existing RuntimeEvent / AgentRunEvent paths.
  • Default parent/sibling session views and future model context do not automatically absorb child runtime events.
  • Child does not automatically inherit prior parent/session context.
  • Parent receives an explicit child result through the tool result/event path.
  • Child runs with a separate backend using the child system prompt and explore permissions.
  • Child receives no tools that can write files, spawn another subagent, or trigger a permission prompt.
  • Parent abort cancels the child, stops/disposes the child backend, and releases the slot.
  • Restart recovery does not leave child runs permanently running.
  • agent_list is listSessionRuns(sessionId) filtered to runs with parentRunId, plus header display metadata.
  • agent_output uses existing run inspect/events plus child turnId artifact lookup.
  • Permission denial, timeout/budget, tool failure, model failure, cancellation, and incomplete result map to existing failure concepts.
  • UI can show a subagent card with agent name, status, permission mode, elapsed time, result summary, and artifact ids.

Suggested PR sequence

  1. Add parentRunId / agentName run metadata and update default read models plus model-history reconstruction to exclude child runs by default.
  2. Add minimal inline AgentSpec and a narrow startChildTurn / spawnChildAgent seam that reuses startTurn / AgentRun wiring without reusing the parent backend.
  3. Add foreground spawn tool: child backend lifecycle, explore policy, allow-only local read toolset, abort propagation, and slot release.
  4. Add agent_list / agent_output projections over existing run inspect/events/artifacts.
  5. Add UI card / child inspect view.
  6. Add runtime/headless tests for context isolation both directions, backend separation, abort, recovery, permission-prompt exclusion, and artifact lookup.

Umbrella: #15

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
       blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
      }
      } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
      })();
      (function(){
      try {
      var __m = "github.com";
      var __re = new RegExp('^' + "github\\.com" + '
      
      Skip to content

      Subagent: reuse runtime spine for agent-as-tool delegation #49

      Description

      @Astro-Han

      Goal

      Build subagent as a first-class LLM delegation primitive without creating a second runtime or a second ledger.

      A subagent is a real child agent run created through the existing AgentRun / RuntimeKernel.startTurn orchestration, exposed by a thin child-run seam such as RuntimeKernel.startChildTurn(...). RuntimeRunner remains the inner invocation pump; it should not become the persistence or lifecycle boundary.

      The existing ExploreAgent should stay as a deterministic read-only helper. It is useful, but it is not the LLM subagent implementation.

      Design filter

      • Simple enough: Day 1 adds one inline spec, one lineage field, and the minimal display metadata needed after restart.
      • Elegant enough: a subagent is still an AgentRun with parentRunId, not a new run type.
      • Reassuring enough: permissions, events, artifacts, recovery, abort, and inspection keep using the existing runtime machinery, with child runs kept out of the parent transcript unless explicitly summarized.

      Existing spine to reuse

      • Events: RuntimeEvent / AgentRunEvent
      • Runs: AgentRunHeader / AgentRunStore
      • Permissions: existing PermissionMode × ToolCategory
      • Artifacts: existing ArtifactRecord
      • Inspection: existing agent-run inspect/read models
      • Runtime loop: existing RuntimeKernel.startTurn wiring, AiSdkFlow, and RuntimeRunner
      • Future handoff seam: RuntimeEvent.actions.transferToAgent

      Day 1 shape

      Add:

      • Inline AgentSpec passed by the spawn tool, not a stored registry:
        • name
        • systemPrompt
      • parentRunId on stored run headers and invocation/run lineage.
      • agentName display metadata on the child run header, copied from AgentSpec.name; do not store the child system prompt in the run header.
      • A narrow child-run starter, for example RuntimeKernel.startChildTurn(parentRunId, spec, prompt), exposed to the spawn tool as spawnChildAgent(spec, prompt) or an equally narrow capability. Do not expose full SessionManager / RuntimeKernel to tools.

      Use existing or derived state instead of new duplicates:

      • Delegation prompt: first child input event, not a header copy.
      • Child identity: runId + parentRunId, not RuntimeEvent.branch for Day 1.
      • Parent linkage: use parentRunId because inspect/output and runtime ledgers are run-keyed; mirror existing turn lineage only where the current turn-state machinery needs it.
      • Permission mode: Day 1 spawn policy always runs the child in explore; do not put a general permission profile in AgentSpec yet.
      • Recursion limit: child backend does not receive the spawn tool; no Day 1 maxDepth field is needed.
      • Consumed state: parent tool result / event, not a mutable header flag.
      • Failures: existing InvocationFailure / AgentRunHeader.failureClass; headless AutonomousResultTaxonomy only when headless eval is involved.

      Do not add:

      • SubagentRun
      • SubagentEvent
      • PermissionProfile
      • ArtifactRef
      • a subagent-specific failure taxonomy
      • fake AgentRun rows for deterministic tools
      • a stable custom-agent registry until users can actually define reusable project agents

      Important boundaries

      Same session is acceptable, but child execution still needs its own backend instance built with the child header and AgentSpec.systemPrompt. The current active-session path is one backend per session; startChildTurn must not accidentally reuse the parent backend through that slot. Either inject a child-built backend into the child AgentRun path or make the child starter own the child backend lifecycle explicitly.

      Child backend lifecycle is run-scoped. Parent stop/abort must stop and dispose all active child backends, and child finalization must not incorrectly mark the session active while the parent run is still active.

      Default session/chat read models, branch copy, and model-history reconstruction must exclude child runs by default. The parent transcript should contain only the spawn tool call/result or explicit child summary, not the child's raw event stream.

      The child receives no implicit prior parent/session context in Day 1. Its first model input is the delegation prompt plus any explicit context the spawn tool chooses to pass.

      Day 1 child toolset should contain only non-prompting read-only tools, such as read and shell_safe. Exclude web_read, custom_tool, and subagent until per-backend permission routing exists; otherwise a child permission request has no reassuring route back to the right backend.

      Parent abort must propagate into the child run and child backend. Slot release should be tied to child finalization, including cancellation and failure.

      Restart recovery must not leave a child permanently running. Day 1 can rely on the existing run recovery sweep if the child run header is created before long awaits; otherwise explicitly mark abandoned children as cancelled/failed.

      Artifact lookup for agent_output should use the child run header's turnId, because artifacts are keyed by session/turn rather than only by run id.

      First runnable path

      Enable only:

      • foreground agent-as-tool execution
      • read-only LLM child agent
      • same session by default, linked by parentRunId
      • fresh child turnId, distinct from the parent turn
      • real child run through existing startTurn/AgentRun wiring
      • separate child backend with explore permissions and the child system prompt
      • allow-only local read toolset for the child, with no prompting categories and no spawn tool
      • existing subagent tool slot cap for concurrent foreground spawn tool calls in the parent turn
      • agent_list / agent_output as thin projections over existing run/event/artifact read models

      Keep out of Day 1:

      • write-capable subagents
      • background subagents
      • nested subagents beyond one level
      • child web/custom tools that require permission prompts
      • full handoff
      • parallel workflow templates
      • custom project agent library / stable agent registry

      Acceptance criteria

      • Parent can spawn a read-only LLM child agent through a tool call.
      • Child is stored as a real AgentRun through existing startTurn/AgentRun wiring.
      • Child run header records parentRunId and agentName.
      • Child run has a fresh turnId different from the parent turn.
      • Child events use existing RuntimeEvent / AgentRunEvent paths.
      • Default parent/sibling session views and future model context do not automatically absorb child runtime events.
      • Child does not automatically inherit prior parent/session context.
      • Parent receives an explicit child result through the tool result/event path.
      • Child runs with a separate backend using the child system prompt and explore permissions.
      • Child receives no tools that can write files, spawn another subagent, or trigger a permission prompt.
      • Parent abort cancels the child, stops/disposes the child backend, and releases the slot.
      • Restart recovery does not leave child runs permanently running.
      • agent_list is listSessionRuns(sessionId) filtered to runs with parentRunId, plus header display metadata.
      • agent_output uses existing run inspect/events plus child turnId artifact lookup.
      • Permission denial, timeout/budget, tool failure, model failure, cancellation, and incomplete result map to existing failure concepts.
      • UI can show a subagent card with agent name, status, permission mode, elapsed time, result summary, and artifact ids.

      Suggested PR sequence

      1. Add parentRunId / agentName run metadata and update default read models plus model-history reconstruction to exclude child runs by default.
      2. Add minimal inline AgentSpec and a narrow startChildTurn / spawnChildAgent seam that reuses startTurn / AgentRun wiring without reusing the parent backend.
      3. Add foreground spawn tool: child backend lifecycle, explore policy, allow-only local read toolset, abort propagation, and slot release.
      4. Add agent_list / agent_output projections over existing run inspect/events/artifacts.
      5. Add UI card / child inspect view.
      6. Add runtime/headless tests for context isolation both directions, backend separation, abort, recovery, permission-prompt exclusion, and artifact lookup.

      Umbrella: #15

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        enhancementNew feature or request

        Type

        No type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
          Skip to content

          Subagent: reuse runtime spine for agent-as-tool delegation #49

          Description

          @Astro-Han

          Goal

          Build subagent as a first-class LLM delegation primitive without creating a second runtime or a second ledger.

          A subagent is a real child agent run created through the existing AgentRun / RuntimeKernel.startTurn orchestration, exposed by a thin child-run seam such as RuntimeKernel.startChildTurn(...). RuntimeRunner remains the inner invocation pump; it should not become the persistence or lifecycle boundary.

          The existing ExploreAgent should stay as a deterministic read-only helper. It is useful, but it is not the LLM subagent implementation.

          Design filter

          • Simple enough: Day 1 adds one inline spec, one lineage field, and the minimal display metadata needed after restart.
          • Elegant enough: a subagent is still an AgentRun with parentRunId, not a new run type.
          • Reassuring enough: permissions, events, artifacts, recovery, abort, and inspection keep using the existing runtime machinery, with child runs kept out of the parent transcript unless explicitly summarized.

          Existing spine to reuse

          • Events: RuntimeEvent / AgentRunEvent
          • Runs: AgentRunHeader / AgentRunStore
          • Permissions: existing PermissionMode × ToolCategory
          • Artifacts: existing ArtifactRecord
          • Inspection: existing agent-run inspect/read models
          • Runtime loop: existing RuntimeKernel.startTurn wiring, AiSdkFlow, and RuntimeRunner
          • Future handoff seam: RuntimeEvent.actions.transferToAgent

          Day 1 shape

          Add:

          • Inline AgentSpec passed by the spawn tool, not a stored registry:
            • name
            • systemPrompt
          • parentRunId on stored run headers and invocation/run lineage.
          • agentName display metadata on the child run header, copied from AgentSpec.name; do not store the child system prompt in the run header.
          • A narrow child-run starter, for example RuntimeKernel.startChildTurn(parentRunId, spec, prompt), exposed to the spawn tool as spawnChildAgent(spec, prompt) or an equally narrow capability. Do not expose full SessionManager / RuntimeKernel to tools.

          Use existing or derived state instead of new duplicates:

          • Delegation prompt: first child input event, not a header copy.
          • Child identity: runId + parentRunId, not RuntimeEvent.branch for Day 1.
          • Parent linkage: use parentRunId because inspect/output and runtime ledgers are run-keyed; mirror existing turn lineage only where the current turn-state machinery needs it.
          • Permission mode: Day 1 spawn policy always runs the child in explore; do not put a general permission profile in AgentSpec yet.
          • Recursion limit: child backend does not receive the spawn tool; no Day 1 maxDepth field is needed.
          • Consumed state: parent tool result / event, not a mutable header flag.
          • Failures: existing InvocationFailure / AgentRunHeader.failureClass; headless AutonomousResultTaxonomy only when headless eval is involved.

          Do not add:

          • SubagentRun
          • SubagentEvent
          • PermissionProfile
          • ArtifactRef
          • a subagent-specific failure taxonomy
          • fake AgentRun rows for deterministic tools
          • a stable custom-agent registry until users can actually define reusable project agents

          Important boundaries

          Same session is acceptable, but child execution still needs its own backend instance built with the child header and AgentSpec.systemPrompt. The current active-session path is one backend per session; startChildTurn must not accidentally reuse the parent backend through that slot. Either inject a child-built backend into the child AgentRun path or make the child starter own the child backend lifecycle explicitly.

          Child backend lifecycle is run-scoped. Parent stop/abort must stop and dispose all active child backends, and child finalization must not incorrectly mark the session active while the parent run is still active.

          Default session/chat read models, branch copy, and model-history reconstruction must exclude child runs by default. The parent transcript should contain only the spawn tool call/result or explicit child summary, not the child's raw event stream.

          The child receives no implicit prior parent/session context in Day 1. Its first model input is the delegation prompt plus any explicit context the spawn tool chooses to pass.

          Day 1 child toolset should contain only non-prompting read-only tools, such as read and shell_safe. Exclude web_read, custom_tool, and subagent until per-backend permission routing exists; otherwise a child permission request has no reassuring route back to the right backend.

          Parent abort must propagate into the child run and child backend. Slot release should be tied to child finalization, including cancellation and failure.

          Restart recovery must not leave a child permanently running. Day 1 can rely on the existing run recovery sweep if the child run header is created before long awaits; otherwise explicitly mark abandoned children as cancelled/failed.

          Artifact lookup for agent_output should use the child run header's turnId, because artifacts are keyed by session/turn rather than only by run id.

          First runnable path

          Enable only:

          • foreground agent-as-tool execution
          • read-only LLM child agent
          • same session by default, linked by parentRunId
          • fresh child turnId, distinct from the parent turn
          • real child run through existing startTurn/AgentRun wiring
          • separate child backend with explore permissions and the child system prompt
          • allow-only local read toolset for the child, with no prompting categories and no spawn tool
          • existing subagent tool slot cap for concurrent foreground spawn tool calls in the parent turn
          • agent_list / agent_output as thin projections over existing run/event/artifact read models

          Keep out of Day 1:

          • write-capable subagents
          • background subagents
          • nested subagents beyond one level
          • child web/custom tools that require permission prompts
          • full handoff
          • parallel workflow templates
          • custom project agent library / stable agent registry

          Acceptance criteria

          • Parent can spawn a read-only LLM child agent through a tool call.
          • Child is stored as a real AgentRun through existing startTurn/AgentRun wiring.
          • Child run header records parentRunId and agentName.
          • Child run has a fresh turnId different from the parent turn.
          • Child events use existing RuntimeEvent / AgentRunEvent paths.
          • Default parent/sibling session views and future model context do not automatically absorb child runtime events.
          • Child does not automatically inherit prior parent/session context.
          • Parent receives an explicit child result through the tool result/event path.
          • Child runs with a separate backend using the child system prompt and explore permissions.
          • Child receives no tools that can write files, spawn another subagent, or trigger a permission prompt.
          • Parent abort cancels the child, stops/disposes the child backend, and releases the slot.
          • Restart recovery does not leave child runs permanently running.
          • agent_list is listSessionRuns(sessionId) filtered to runs with parentRunId, plus header display metadata.
          • agent_output uses existing run inspect/events plus child turnId artifact lookup.
          • Permission denial, timeout/budget, tool failure, model failure, cancellation, and incomplete result map to existing failure concepts.
          • UI can show a subagent card with agent name, status, permission mode, elapsed time, result summary, and artifact ids.

          Suggested PR sequence

          1. Add parentRunId / agentName run metadata and update default read models plus model-history reconstruction to exclude child runs by default.
          2. Add minimal inline AgentSpec and a narrow startChildTurn / spawnChildAgent seam that reuses startTurn / AgentRun wiring without reusing the parent backend.
          3. Add foreground spawn tool: child backend lifecycle, explore policy, allow-only local read toolset, abort propagation, and slot release.
          4. Add agent_list / agent_output projections over existing run inspect/events/artifacts.
          5. Add UI card / child inspect view.
          6. Add runtime/headless tests for context isolation both directions, backend separation, abort, recovery, permission-prompt exclusion, and artifact lookup.

          Umbrella: #15

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            enhancementNew feature or request

            Type

            No type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
              Skip to content

              Subagent: reuse runtime spine for agent-as-tool delegation #49

              Description

              @Astro-Han

              Goal

              Build subagent as a first-class LLM delegation primitive without creating a second runtime or a second ledger.

              A subagent is a real child agent run created through the existing AgentRun / RuntimeKernel.startTurn orchestration, exposed by a thin child-run seam such as RuntimeKernel.startChildTurn(...). RuntimeRunner remains the inner invocation pump; it should not become the persistence or lifecycle boundary.

              The existing ExploreAgent should stay as a deterministic read-only helper. It is useful, but it is not the LLM subagent implementation.

              Design filter

              • Simple enough: Day 1 adds one inline spec, one lineage field, and the minimal display metadata needed after restart.
              • Elegant enough: a subagent is still an AgentRun with parentRunId, not a new run type.
              • Reassuring enough: permissions, events, artifacts, recovery, abort, and inspection keep using the existing runtime machinery, with child runs kept out of the parent transcript unless explicitly summarized.

              Existing spine to reuse

              • Events: RuntimeEvent / AgentRunEvent
              • Runs: AgentRunHeader / AgentRunStore
              • Permissions: existing PermissionMode × ToolCategory
              • Artifacts: existing ArtifactRecord
              • Inspection: existing agent-run inspect/read models
              • Runtime loop: existing RuntimeKernel.startTurn wiring, AiSdkFlow, and RuntimeRunner
              • Future handoff seam: RuntimeEvent.actions.transferToAgent

              Day 1 shape

              Add:

              • Inline AgentSpec passed by the spawn tool, not a stored registry:
                • name
                • systemPrompt
              • parentRunId on stored run headers and invocation/run lineage.
              • agentName display metadata on the child run header, copied from AgentSpec.name; do not store the child system prompt in the run header.
              • A narrow child-run starter, for example RuntimeKernel.startChildTurn(parentRunId, spec, prompt), exposed to the spawn tool as spawnChildAgent(spec, prompt) or an equally narrow capability. Do not expose full SessionManager / RuntimeKernel to tools.

              Use existing or derived state instead of new duplicates:

              • Delegation prompt: first child input event, not a header copy.
              • Child identity: runId + parentRunId, not RuntimeEvent.branch for Day 1.
              • Parent linkage: use parentRunId because inspect/output and runtime ledgers are run-keyed; mirror existing turn lineage only where the current turn-state machinery needs it.
              • Permission mode: Day 1 spawn policy always runs the child in explore; do not put a general permission profile in AgentSpec yet.
              • Recursion limit: child backend does not receive the spawn tool; no Day 1 maxDepth field is needed.
              • Consumed state: parent tool result / event, not a mutable header flag.
              • Failures: existing InvocationFailure / AgentRunHeader.failureClass; headless AutonomousResultTaxonomy only when headless eval is involved.

              Do not add:

              • SubagentRun
              • SubagentEvent
              • PermissionProfile
              • ArtifactRef
              • a subagent-specific failure taxonomy
              • fake AgentRun rows for deterministic tools
              • a stable custom-agent registry until users can actually define reusable project agents

              Important boundaries

              Same session is acceptable, but child execution still needs its own backend instance built with the child header and AgentSpec.systemPrompt. The current active-session path is one backend per session; startChildTurn must not accidentally reuse the parent backend through that slot. Either inject a child-built backend into the child AgentRun path or make the child starter own the child backend lifecycle explicitly.

              Child backend lifecycle is run-scoped. Parent stop/abort must stop and dispose all active child backends, and child finalization must not incorrectly mark the session active while the parent run is still active.

              Default session/chat read models, branch copy, and model-history reconstruction must exclude child runs by default. The parent transcript should contain only the spawn tool call/result or explicit child summary, not the child's raw event stream.

              The child receives no implicit prior parent/session context in Day 1. Its first model input is the delegation prompt plus any explicit context the spawn tool chooses to pass.

              Day 1 child toolset should contain only non-prompting read-only tools, such as read and shell_safe. Exclude web_read, custom_tool, and subagent until per-backend permission routing exists; otherwise a child permission request has no reassuring route back to the right backend.

              Parent abort must propagate into the child run and child backend. Slot release should be tied to child finalization, including cancellation and failure.

              Restart recovery must not leave a child permanently running. Day 1 can rely on the existing run recovery sweep if the child run header is created before long awaits; otherwise explicitly mark abandoned children as cancelled/failed.

              Artifact lookup for agent_output should use the child run header's turnId, because artifacts are keyed by session/turn rather than only by run id.

              First runnable path

              Enable only:

              • foreground agent-as-tool execution
              • read-only LLM child agent
              • same session by default, linked by parentRunId
              • fresh child turnId, distinct from the parent turn
              • real child run through existing startTurn/AgentRun wiring
              • separate child backend with explore permissions and the child system prompt
              • allow-only local read toolset for the child, with no prompting categories and no spawn tool
              • existing subagent tool slot cap for concurrent foreground spawn tool calls in the parent turn
              • agent_list / agent_output as thin projections over existing run/event/artifact read models

              Keep out of Day 1:

              • write-capable subagents
              • background subagents
              • nested subagents beyond one level
              • child web/custom tools that require permission prompts
              • full handoff
              • parallel workflow templates
              • custom project agent library / stable agent registry

              Acceptance criteria

              • Parent can spawn a read-only LLM child agent through a tool call.
              • Child is stored as a real AgentRun through existing startTurn/AgentRun wiring.
              • Child run header records parentRunId and agentName.
              • Child run has a fresh turnId different from the parent turn.
              • Child events use existing RuntimeEvent / AgentRunEvent paths.
              • Default parent/sibling session views and future model context do not automatically absorb child runtime events.
              • Child does not automatically inherit prior parent/session context.
              • Parent receives an explicit child result through the tool result/event path.
              • Child runs with a separate backend using the child system prompt and explore permissions.
              • Child receives no tools that can write files, spawn another subagent, or trigger a permission prompt.
              • Parent abort cancels the child, stops/disposes the child backend, and releases the slot.
              • Restart recovery does not leave child runs permanently running.
              • agent_list is listSessionRuns(sessionId) filtered to runs with parentRunId, plus header display metadata.
              • agent_output uses existing run inspect/events plus child turnId artifact lookup.
              • Permission denial, timeout/budget, tool failure, model failure, cancellation, and incomplete result map to existing failure concepts.
              • UI can show a subagent card with agent name, status, permission mode, elapsed time, result summary, and artifact ids.

              Suggested PR sequence

              1. Add parentRunId / agentName run metadata and update default read models plus model-history reconstruction to exclude child runs by default.
              2. Add minimal inline AgentSpec and a narrow startChildTurn / spawnChildAgent seam that reuses startTurn / AgentRun wiring without reusing the parent backend.
              3. Add foreground spawn tool: child backend lifecycle, explore policy, allow-only local read toolset, abort propagation, and slot release.
              4. Add agent_list / agent_output projections over existing run inspect/events/artifacts.
              5. Add UI card / child inspect view.
              6. Add runtime/headless tests for context isolation both directions, backend separation, abort, recovery, permission-prompt exclusion, and artifact lookup.

              Umbrella: #15

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                enhancementNew feature or request

                Type

                No type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
                  Skip to content

                  Subagent: reuse runtime spine for agent-as-tool delegation #49

                  Description

                  @Astro-Han

                  Goal

                  Build subagent as a first-class LLM delegation primitive without creating a second runtime or a second ledger.

                  A subagent is a real child agent run created through the existing AgentRun / RuntimeKernel.startTurn orchestration, exposed by a thin child-run seam such as RuntimeKernel.startChildTurn(...). RuntimeRunner remains the inner invocation pump; it should not become the persistence or lifecycle boundary.

                  The existing ExploreAgent should stay as a deterministic read-only helper. It is useful, but it is not the LLM subagent implementation.

                  Design filter

                  • Simple enough: Day 1 adds one inline spec, one lineage field, and the minimal display metadata needed after restart.
                  • Elegant enough: a subagent is still an AgentRun with parentRunId, not a new run type.
                  • Reassuring enough: permissions, events, artifacts, recovery, abort, and inspection keep using the existing runtime machinery, with child runs kept out of the parent transcript unless explicitly summarized.

                  Existing spine to reuse

                  • Events: RuntimeEvent / AgentRunEvent
                  • Runs: AgentRunHeader / AgentRunStore
                  • Permissions: existing PermissionMode × ToolCategory
                  • Artifacts: existing ArtifactRecord
                  • Inspection: existing agent-run inspect/read models
                  • Runtime loop: existing RuntimeKernel.startTurn wiring, AiSdkFlow, and RuntimeRunner
                  • Future handoff seam: RuntimeEvent.actions.transferToAgent

                  Day 1 shape

                  Add:

                  • Inline AgentSpec passed by the spawn tool, not a stored registry:
                    • name
                    • systemPrompt
                  • parentRunId on stored run headers and invocation/run lineage.
                  • agentName display metadata on the child run header, copied from AgentSpec.name; do not store the child system prompt in the run header.
                  • A narrow child-run starter, for example RuntimeKernel.startChildTurn(parentRunId, spec, prompt), exposed to the spawn tool as spawnChildAgent(spec, prompt) or an equally narrow capability. Do not expose full SessionManager / RuntimeKernel to tools.

                  Use existing or derived state instead of new duplicates:

                  • Delegation prompt: first child input event, not a header copy.
                  • Child identity: runId + parentRunId, not RuntimeEvent.branch for Day 1.
                  • Parent linkage: use parentRunId because inspect/output and runtime ledgers are run-keyed; mirror existing turn lineage only where the current turn-state machinery needs it.
                  • Permission mode: Day 1 spawn policy always runs the child in explore; do not put a general permission profile in AgentSpec yet.
                  • Recursion limit: child backend does not receive the spawn tool; no Day 1 maxDepth field is needed.
                  • Consumed state: parent tool result / event, not a mutable header flag.
                  • Failures: existing InvocationFailure / AgentRunHeader.failureClass; headless AutonomousResultTaxonomy only when headless eval is involved.

                  Do not add:

                  • SubagentRun
                  • SubagentEvent
                  • PermissionProfile
                  • ArtifactRef
                  • a subagent-specific failure taxonomy
                  • fake AgentRun rows for deterministic tools
                  • a stable custom-agent registry until users can actually define reusable project agents

                  Important boundaries

                  Same session is acceptable, but child execution still needs its own backend instance built with the child header and AgentSpec.systemPrompt. The current active-session path is one backend per session; startChildTurn must not accidentally reuse the parent backend through that slot. Either inject a child-built backend into the child AgentRun path or make the child starter own the child backend lifecycle explicitly.

                  Child backend lifecycle is run-scoped. Parent stop/abort must stop and dispose all active child backends, and child finalization must not incorrectly mark the session active while the parent run is still active.

                  Default session/chat read models, branch copy, and model-history reconstruction must exclude child runs by default. The parent transcript should contain only the spawn tool call/result or explicit child summary, not the child's raw event stream.

                  The child receives no implicit prior parent/session context in Day 1. Its first model input is the delegation prompt plus any explicit context the spawn tool chooses to pass.

                  Day 1 child toolset should contain only non-prompting read-only tools, such as read and shell_safe. Exclude web_read, custom_tool, and subagent until per-backend permission routing exists; otherwise a child permission request has no reassuring route back to the right backend.

                  Parent abort must propagate into the child run and child backend. Slot release should be tied to child finalization, including cancellation and failure.

                  Restart recovery must not leave a child permanently running. Day 1 can rely on the existing run recovery sweep if the child run header is created before long awaits; otherwise explicitly mark abandoned children as cancelled/failed.

                  Artifact lookup for agent_output should use the child run header's turnId, because artifacts are keyed by session/turn rather than only by run id.

                  First runnable path

                  Enable only:

                  • foreground agent-as-tool execution
                  • read-only LLM child agent
                  • same session by default, linked by parentRunId
                  • fresh child turnId, distinct from the parent turn
                  • real child run through existing startTurn/AgentRun wiring
                  • separate child backend with explore permissions and the child system prompt
                  • allow-only local read toolset for the child, with no prompting categories and no spawn tool
                  • existing subagent tool slot cap for concurrent foreground spawn tool calls in the parent turn
                  • agent_list / agent_output as thin projections over existing run/event/artifact read models

                  Keep out of Day 1:

                  • write-capable subagents
                  • background subagents
                  • nested subagents beyond one level
                  • child web/custom tools that require permission prompts
                  • full handoff
                  • parallel workflow templates
                  • custom project agent library / stable agent registry

                  Acceptance criteria

                  • Parent can spawn a read-only LLM child agent through a tool call.
                  • Child is stored as a real AgentRun through existing startTurn/AgentRun wiring.
                  • Child run header records parentRunId and agentName.
                  • Child run has a fresh turnId different from the parent turn.
                  • Child events use existing RuntimeEvent / AgentRunEvent paths.
                  • Default parent/sibling session views and future model context do not automatically absorb child runtime events.
                  • Child does not automatically inherit prior parent/session context.
                  • Parent receives an explicit child result through the tool result/event path.
                  • Child runs with a separate backend using the child system prompt and explore permissions.
                  • Child receives no tools that can write files, spawn another subagent, or trigger a permission prompt.
                  • Parent abort cancels the child, stops/disposes the child backend, and releases the slot.
                  • Restart recovery does not leave child runs permanently running.
                  • agent_list is listSessionRuns(sessionId) filtered to runs with parentRunId, plus header display metadata.
                  • agent_output uses existing run inspect/events plus child turnId artifact lookup.
                  • Permission denial, timeout/budget, tool failure, model failure, cancellation, and incomplete result map to existing failure concepts.
                  • UI can show a subagent card with agent name, status, permission mode, elapsed time, result summary, and artifact ids.

                  Suggested PR sequence

                  1. Add parentRunId / agentName run metadata and update default read models plus model-history reconstruction to exclude child runs by default.
                  2. Add minimal inline AgentSpec and a narrow startChildTurn / spawnChildAgent seam that reuses startTurn / AgentRun wiring without reusing the parent backend.
                  3. Add foreground spawn tool: child backend lifecycle, explore policy, allow-only local read toolset, abort propagation, and slot release.
                  4. Add agent_list / agent_output projections over existing run inspect/events/artifacts.
                  5. Add UI card / child inspect view.
                  6. Add runtime/headless tests for context isolation both directions, backend separation, abort, recovery, permission-prompt exclusion, and artifact lookup.

                  Umbrella: #15

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Labels

                    enhancementNew feature or request

                    Type

                    No type

                    Projects

                    No projects

                      Milestone

                      No milestone

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
                      Skip to content

                      Subagent: reuse runtime spine for agent-as-tool delegation #49

                      Description

                      @Astro-Han

                      Goal

                      Build subagent as a first-class LLM delegation primitive without creating a second runtime or a second ledger.

                      A subagent is a real child agent run created through the existing AgentRun / RuntimeKernel.startTurn orchestration, exposed by a thin child-run seam such as RuntimeKernel.startChildTurn(...). RuntimeRunner remains the inner invocation pump; it should not become the persistence or lifecycle boundary.

                      The existing ExploreAgent should stay as a deterministic read-only helper. It is useful, but it is not the LLM subagent implementation.

                      Design filter

                      • Simple enough: Day 1 adds one inline spec, one lineage field, and the minimal display metadata needed after restart.
                      • Elegant enough: a subagent is still an AgentRun with parentRunId, not a new run type.
                      • Reassuring enough: permissions, events, artifacts, recovery, abort, and inspection keep using the existing runtime machinery, with child runs kept out of the parent transcript unless explicitly summarized.

                      Existing spine to reuse

                      • Events: RuntimeEvent / AgentRunEvent
                      • Runs: AgentRunHeader / AgentRunStore
                      • Permissions: existing PermissionMode × ToolCategory
                      • Artifacts: existing ArtifactRecord
                      • Inspection: existing agent-run inspect/read models
                      • Runtime loop: existing RuntimeKernel.startTurn wiring, AiSdkFlow, and RuntimeRunner
                      • Future handoff seam: RuntimeEvent.actions.transferToAgent

                      Day 1 shape

                      Add:

                      • Inline AgentSpec passed by the spawn tool, not a stored registry:
                        • name
                        • systemPrompt
                      • parentRunId on stored run headers and invocation/run lineage.
                      • agentName display metadata on the child run header, copied from AgentSpec.name; do not store the child system prompt in the run header.
                      • A narrow child-run starter, for example RuntimeKernel.startChildTurn(parentRunId, spec, prompt), exposed to the spawn tool as spawnChildAgent(spec, prompt) or an equally narrow capability. Do not expose full SessionManager / RuntimeKernel to tools.

                      Use existing or derived state instead of new duplicates:

                      • Delegation prompt: first child input event, not a header copy.
                      • Child identity: runId + parentRunId, not RuntimeEvent.branch for Day 1.
                      • Parent linkage: use parentRunId because inspect/output and runtime ledgers are run-keyed; mirror existing turn lineage only where the current turn-state machinery needs it.
                      • Permission mode: Day 1 spawn policy always runs the child in explore; do not put a general permission profile in AgentSpec yet.
                      • Recursion limit: child backend does not receive the spawn tool; no Day 1 maxDepth field is needed.
                      • Consumed state: parent tool result / event, not a mutable header flag.
                      • Failures: existing InvocationFailure / AgentRunHeader.failureClass; headless AutonomousResultTaxonomy only when headless eval is involved.

                      Do not add:

                      • SubagentRun
                      • SubagentEvent
                      • PermissionProfile
                      • ArtifactRef
                      • a subagent-specific failure taxonomy
                      • fake AgentRun rows for deterministic tools
                      • a stable custom-agent registry until users can actually define reusable project agents

                      Important boundaries

                      Same session is acceptable, but child execution still needs its own backend instance built with the child header and AgentSpec.systemPrompt. The current active-session path is one backend per session; startChildTurn must not accidentally reuse the parent backend through that slot. Either inject a child-built backend into the child AgentRun path or make the child starter own the child backend lifecycle explicitly.

                      Child backend lifecycle is run-scoped. Parent stop/abort must stop and dispose all active child backends, and child finalization must not incorrectly mark the session active while the parent run is still active.

                      Default session/chat read models, branch copy, and model-history reconstruction must exclude child runs by default. The parent transcript should contain only the spawn tool call/result or explicit child summary, not the child's raw event stream.

                      The child receives no implicit prior parent/session context in Day 1. Its first model input is the delegation prompt plus any explicit context the spawn tool chooses to pass.

                      Day 1 child toolset should contain only non-prompting read-only tools, such as read and shell_safe. Exclude web_read, custom_tool, and subagent until per-backend permission routing exists; otherwise a child permission request has no reassuring route back to the right backend.

                      Parent abort must propagate into the child run and child backend. Slot release should be tied to child finalization, including cancellation and failure.

                      Restart recovery must not leave a child permanently running. Day 1 can rely on the existing run recovery sweep if the child run header is created before long awaits; otherwise explicitly mark abandoned children as cancelled/failed.

                      Artifact lookup for agent_output should use the child run header's turnId, because artifacts are keyed by session/turn rather than only by run id.

                      First runnable path

                      Enable only:

                      • foreground agent-as-tool execution
                      • read-only LLM child agent
                      • same session by default, linked by parentRunId
                      • fresh child turnId, distinct from the parent turn
                      • real child run through existing startTurn/AgentRun wiring
                      • separate child backend with explore permissions and the child system prompt
                      • allow-only local read toolset for the child, with no prompting categories and no spawn tool
                      • existing subagent tool slot cap for concurrent foreground spawn tool calls in the parent turn
                      • agent_list / agent_output as thin projections over existing run/event/artifact read models

                      Keep out of Day 1:

                      • write-capable subagents
                      • background subagents
                      • nested subagents beyond one level
                      • child web/custom tools that require permission prompts
                      • full handoff
                      • parallel workflow templates
                      • custom project agent library / stable agent registry

                      Acceptance criteria

                      • Parent can spawn a read-only LLM child agent through a tool call.
                      • Child is stored as a real AgentRun through existing startTurn/AgentRun wiring.
                      • Child run header records parentRunId and agentName.
                      • Child run has a fresh turnId different from the parent turn.
                      • Child events use existing RuntimeEvent / AgentRunEvent paths.
                      • Default parent/sibling session views and future model context do not automatically absorb child runtime events.
                      • Child does not automatically inherit prior parent/session context.
                      • Parent receives an explicit child result through the tool result/event path.
                      • Child runs with a separate backend using the child system prompt and explore permissions.
                      • Child receives no tools that can write files, spawn another subagent, or trigger a permission prompt.
                      • Parent abort cancels the child, stops/disposes the child backend, and releases the slot.
                      • Restart recovery does not leave child runs permanently running.
                      • agent_list is listSessionRuns(sessionId) filtered to runs with parentRunId, plus header display metadata.
                      • agent_output uses existing run inspect/events plus child turnId artifact lookup.
                      • Permission denial, timeout/budget, tool failure, model failure, cancellation, and incomplete result map to existing failure concepts.
                      • UI can show a subagent card with agent name, status, permission mode, elapsed time, result summary, and artifact ids.

                      Suggested PR sequence

                      1. Add parentRunId / agentName run metadata and update default read models plus model-history reconstruction to exclude child runs by default.
                      2. Add minimal inline AgentSpec and a narrow startChildTurn / spawnChildAgent seam that reuses startTurn / AgentRun wiring without reusing the parent backend.
                      3. Add foreground spawn tool: child backend lifecycle, explore policy, allow-only local read toolset, abort propagation, and slot release.
                      4. Add agent_list / agent_output projections over existing run inspect/events/artifacts.
                      5. Add UI card / child inspect view.
                      6. Add runtime/headless tests for context isolation both directions, backend separation, abort, recovery, permission-prompt exclusion, and artifact lookup.

                      Umbrella: #15

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Labels

                        enhancementNew feature or request

                        Type

                        No type

                        Projects

                        No projects

                          Milestone

                          No milestone

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
                          Skip to content

                          Subagent: reuse runtime spine for agent-as-tool delegation #49

                          Description

                          @Astro-Han

                          Goal

                          Build subagent as a first-class LLM delegation primitive without creating a second runtime or a second ledger.

                          A subagent is a real child agent run created through the existing AgentRun / RuntimeKernel.startTurn orchestration, exposed by a thin child-run seam such as RuntimeKernel.startChildTurn(...). RuntimeRunner remains the inner invocation pump; it should not become the persistence or lifecycle boundary.

                          The existing ExploreAgent should stay as a deterministic read-only helper. It is useful, but it is not the LLM subagent implementation.

                          Design filter

                          • Simple enough: Day 1 adds one inline spec, one lineage field, and the minimal display metadata needed after restart.
                          • Elegant enough: a subagent is still an AgentRun with parentRunId, not a new run type.
                          • Reassuring enough: permissions, events, artifacts, recovery, abort, and inspection keep using the existing runtime machinery, with child runs kept out of the parent transcript unless explicitly summarized.

                          Existing spine to reuse

                          • Events: RuntimeEvent / AgentRunEvent
                          • Runs: AgentRunHeader / AgentRunStore
                          • Permissions: existing PermissionMode × ToolCategory
                          • Artifacts: existing ArtifactRecord
                          • Inspection: existing agent-run inspect/read models
                          • Runtime loop: existing RuntimeKernel.startTurn wiring, AiSdkFlow, and RuntimeRunner
                          • Future handoff seam: RuntimeEvent.actions.transferToAgent

                          Day 1 shape

                          Add:

                          • Inline AgentSpec passed by the spawn tool, not a stored registry:
                            • name
                            • systemPrompt
                          • parentRunId on stored run headers and invocation/run lineage.
                          • agentName display metadata on the child run header, copied from AgentSpec.name; do not store the child system prompt in the run header.
                          • A narrow child-run starter, for example RuntimeKernel.startChildTurn(parentRunId, spec, prompt), exposed to the spawn tool as spawnChildAgent(spec, prompt) or an equally narrow capability. Do not expose full SessionManager / RuntimeKernel to tools.

                          Use existing or derived state instead of new duplicates:

                          • Delegation prompt: first child input event, not a header copy.
                          • Child identity: runId + parentRunId, not RuntimeEvent.branch for Day 1.
                          • Parent linkage: use parentRunId because inspect/output and runtime ledgers are run-keyed; mirror existing turn lineage only where the current turn-state machinery needs it.
                          • Permission mode: Day 1 spawn policy always runs the child in explore; do not put a general permission profile in AgentSpec yet.
                          • Recursion limit: child backend does not receive the spawn tool; no Day 1 maxDepth field is needed.
                          • Consumed state: parent tool result / event, not a mutable header flag.
                          • Failures: existing InvocationFailure / AgentRunHeader.failureClass; headless AutonomousResultTaxonomy only when headless eval is involved.

                          Do not add:

                          • SubagentRun
                          • SubagentEvent
                          • PermissionProfile
                          • ArtifactRef
                          • a subagent-specific failure taxonomy
                          • fake AgentRun rows for deterministic tools
                          • a stable custom-agent registry until users can actually define reusable project agents

                          Important boundaries

                          Same session is acceptable, but child execution still needs its own backend instance built with the child header and AgentSpec.systemPrompt. The current active-session path is one backend per session; startChildTurn must not accidentally reuse the parent backend through that slot. Either inject a child-built backend into the child AgentRun path or make the child starter own the child backend lifecycle explicitly.

                          Child backend lifecycle is run-scoped. Parent stop/abort must stop and dispose all active child backends, and child finalization must not incorrectly mark the session active while the parent run is still active.

                          Default session/chat read models, branch copy, and model-history reconstruction must exclude child runs by default. The parent transcript should contain only the spawn tool call/result or explicit child summary, not the child's raw event stream.

                          The child receives no implicit prior parent/session context in Day 1. Its first model input is the delegation prompt plus any explicit context the spawn tool chooses to pass.

                          Day 1 child toolset should contain only non-prompting read-only tools, such as read and shell_safe. Exclude web_read, custom_tool, and subagent until per-backend permission routing exists; otherwise a child permission request has no reassuring route back to the right backend.

                          Parent abort must propagate into the child run and child backend. Slot release should be tied to child finalization, including cancellation and failure.

                          Restart recovery must not leave a child permanently running. Day 1 can rely on the existing run recovery sweep if the child run header is created before long awaits; otherwise explicitly mark abandoned children as cancelled/failed.

                          Artifact lookup for agent_output should use the child run header's turnId, because artifacts are keyed by session/turn rather than only by run id.

                          First runnable path

                          Enable only:

                          • foreground agent-as-tool execution
                          • read-only LLM child agent
                          • same session by default, linked by parentRunId
                          • fresh child turnId, distinct from the parent turn
                          • real child run through existing startTurn/AgentRun wiring
                          • separate child backend with explore permissions and the child system prompt
                          • allow-only local read toolset for the child, with no prompting categories and no spawn tool
                          • existing subagent tool slot cap for concurrent foreground spawn tool calls in the parent turn
                          • agent_list / agent_output as thin projections over existing run/event/artifact read models

                          Keep out of Day 1:

                          • write-capable subagents
                          • background subagents
                          • nested subagents beyond one level
                          • child web/custom tools that require permission prompts
                          • full handoff
                          • parallel workflow templates
                          • custom project agent library / stable agent registry

                          Acceptance criteria

                          • Parent can spawn a read-only LLM child agent through a tool call.
                          • Child is stored as a real AgentRun through existing startTurn/AgentRun wiring.
                          • Child run header records parentRunId and agentName.
                          • Child run has a fresh turnId different from the parent turn.
                          • Child events use existing RuntimeEvent / AgentRunEvent paths.
                          • Default parent/sibling session views and future model context do not automatically absorb child runtime events.
                          • Child does not automatically inherit prior parent/session context.
                          • Parent receives an explicit child result through the tool result/event path.
                          • Child runs with a separate backend using the child system prompt and explore permissions.
                          • Child receives no tools that can write files, spawn another subagent, or trigger a permission prompt.
                          • Parent abort cancels the child, stops/disposes the child backend, and releases the slot.
                          • Restart recovery does not leave child runs permanently running.
                          • agent_list is listSessionRuns(sessionId) filtered to runs with parentRunId, plus header display metadata.
                          • agent_output uses existing run inspect/events plus child turnId artifact lookup.
                          • Permission denial, timeout/budget, tool failure, model failure, cancellation, and incomplete result map to existing failure concepts.
                          • UI can show a subagent card with agent name, status, permission mode, elapsed time, result summary, and artifact ids.

                          Suggested PR sequence

                          1. Add parentRunId / agentName run metadata and update default read models plus model-history reconstruction to exclude child runs by default.
                          2. Add minimal inline AgentSpec and a narrow startChildTurn / spawnChildAgent seam that reuses startTurn / AgentRun wiring without reusing the parent backend.
                          3. Add foreground spawn tool: child backend lifecycle, explore policy, allow-only local read toolset, abort propagation, and slot release.
                          4. Add agent_list / agent_output projections over existing run inspect/events/artifacts.
                          5. Add UI card / child inspect view.
                          6. Add runtime/headless tests for context isolation both directions, backend separation, abort, recovery, permission-prompt exclusion, and artifact lookup.

                          Umbrella: #15

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Labels

                            enhancementNew feature or request

                            Type

                            No type

                            Projects

                            No projects

                              Milestone

                              No milestone

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
                              Skip to content

                              Subagent: reuse runtime spine for agent-as-tool delegation #49

                              Description

                              @Astro-Han

                              Goal

                              Build subagent as a first-class LLM delegation primitive without creating a second runtime or a second ledger.

                              A subagent is a real child agent run created through the existing AgentRun / RuntimeKernel.startTurn orchestration, exposed by a thin child-run seam such as RuntimeKernel.startChildTurn(...). RuntimeRunner remains the inner invocation pump; it should not become the persistence or lifecycle boundary.

                              The existing ExploreAgent should stay as a deterministic read-only helper. It is useful, but it is not the LLM subagent implementation.

                              Design filter

                              • Simple enough: Day 1 adds one inline spec, one lineage field, and the minimal display metadata needed after restart.
                              • Elegant enough: a subagent is still an AgentRun with parentRunId, not a new run type.
                              • Reassuring enough: permissions, events, artifacts, recovery, abort, and inspection keep using the existing runtime machinery, with child runs kept out of the parent transcript unless explicitly summarized.

                              Existing spine to reuse

                              • Events: RuntimeEvent / AgentRunEvent
                              • Runs: AgentRunHeader / AgentRunStore
                              • Permissions: existing PermissionMode × ToolCategory
                              • Artifacts: existing ArtifactRecord
                              • Inspection: existing agent-run inspect/read models
                              • Runtime loop: existing RuntimeKernel.startTurn wiring, AiSdkFlow, and RuntimeRunner
                              • Future handoff seam: RuntimeEvent.actions.transferToAgent

                              Day 1 shape

                              Add:

                              • Inline AgentSpec passed by the spawn tool, not a stored registry:
                                • name
                                • systemPrompt
                              • parentRunId on stored run headers and invocation/run lineage.
                              • agentName display metadata on the child run header, copied from AgentSpec.name; do not store the child system prompt in the run header.
                              • A narrow child-run starter, for example RuntimeKernel.startChildTurn(parentRunId, spec, prompt), exposed to the spawn tool as spawnChildAgent(spec, prompt) or an equally narrow capability. Do not expose full SessionManager / RuntimeKernel to tools.

                              Use existing or derived state instead of new duplicates:

                              • Delegation prompt: first child input event, not a header copy.
                              • Child identity: runId + parentRunId, not RuntimeEvent.branch for Day 1.
                              • Parent linkage: use parentRunId because inspect/output and runtime ledgers are run-keyed; mirror existing turn lineage only where the current turn-state machinery needs it.
                              • Permission mode: Day 1 spawn policy always runs the child in explore; do not put a general permission profile in AgentSpec yet.
                              • Recursion limit: child backend does not receive the spawn tool; no Day 1 maxDepth field is needed.
                              • Consumed state: parent tool result / event, not a mutable header flag.
                              • Failures: existing InvocationFailure / AgentRunHeader.failureClass; headless AutonomousResultTaxonomy only when headless eval is involved.

                              Do not add:

                              • SubagentRun
                              • SubagentEvent
                              • PermissionProfile
                              • ArtifactRef
                              • a subagent-specific failure taxonomy
                              • fake AgentRun rows for deterministic tools
                              • a stable custom-agent registry until users can actually define reusable project agents

                              Important boundaries

                              Same session is acceptable, but child execution still needs its own backend instance built with the child header and AgentSpec.systemPrompt. The current active-session path is one backend per session; startChildTurn must not accidentally reuse the parent backend through that slot. Either inject a child-built backend into the child AgentRun path or make the child starter own the child backend lifecycle explicitly.

                              Child backend lifecycle is run-scoped. Parent stop/abort must stop and dispose all active child backends, and child finalization must not incorrectly mark the session active while the parent run is still active.

                              Default session/chat read models, branch copy, and model-history reconstruction must exclude child runs by default. The parent transcript should contain only the spawn tool call/result or explicit child summary, not the child's raw event stream.

                              The child receives no implicit prior parent/session context in Day 1. Its first model input is the delegation prompt plus any explicit context the spawn tool chooses to pass.

                              Day 1 child toolset should contain only non-prompting read-only tools, such as read and shell_safe. Exclude web_read, custom_tool, and subagent until per-backend permission routing exists; otherwise a child permission request has no reassuring route back to the right backend.

                              Parent abort must propagate into the child run and child backend. Slot release should be tied to child finalization, including cancellation and failure.

                              Restart recovery must not leave a child permanently running. Day 1 can rely on the existing run recovery sweep if the child run header is created before long awaits; otherwise explicitly mark abandoned children as cancelled/failed.

                              Artifact lookup for agent_output should use the child run header's turnId, because artifacts are keyed by session/turn rather than only by run id.

                              First runnable path

                              Enable only:

                              • foreground agent-as-tool execution
                              • read-only LLM child agent
                              • same session by default, linked by parentRunId
                              • fresh child turnId, distinct from the parent turn
                              • real child run through existing startTurn/AgentRun wiring
                              • separate child backend with explore permissions and the child system prompt
                              • allow-only local read toolset for the child, with no prompting categories and no spawn tool
                              • existing subagent tool slot cap for concurrent foreground spawn tool calls in the parent turn
                              • agent_list / agent_output as thin projections over existing run/event/artifact read models

                              Keep out of Day 1:

                              • write-capable subagents
                              • background subagents
                              • nested subagents beyond one level
                              • child web/custom tools that require permission prompts
                              • full handoff
                              • parallel workflow templates
                              • custom project agent library / stable agent registry

                              Acceptance criteria

                              • Parent can spawn a read-only LLM child agent through a tool call.
                              • Child is stored as a real AgentRun through existing startTurn/AgentRun wiring.
                              • Child run header records parentRunId and agentName.
                              • Child run has a fresh turnId different from the parent turn.
                              • Child events use existing RuntimeEvent / AgentRunEvent paths.
                              • Default parent/sibling session views and future model context do not automatically absorb child runtime events.
                              • Child does not automatically inherit prior parent/session context.
                              • Parent receives an explicit child result through the tool result/event path.
                              • Child runs with a separate backend using the child system prompt and explore permissions.
                              • Child receives no tools that can write files, spawn another subagent, or trigger a permission prompt.
                              • Parent abort cancels the child, stops/disposes the child backend, and releases the slot.
                              • Restart recovery does not leave child runs permanently running.
                              • agent_list is listSessionRuns(sessionId) filtered to runs with parentRunId, plus header display metadata.
                              • agent_output uses existing run inspect/events plus child turnId artifact lookup.
                              • Permission denial, timeout/budget, tool failure, model failure, cancellation, and incomplete result map to existing failure concepts.
                              • UI can show a subagent card with agent name, status, permission mode, elapsed time, result summary, and artifact ids.

                              Suggested PR sequence

                              1. Add parentRunId / agentName run metadata and update default read models plus model-history reconstruction to exclude child runs by default.
                              2. Add minimal inline AgentSpec and a narrow startChildTurn / spawnChildAgent seam that reuses startTurn / AgentRun wiring without reusing the parent backend.
                              3. Add foreground spawn tool: child backend lifecycle, explore policy, allow-only local read toolset, abort propagation, and slot release.
                              4. Add agent_list / agent_output projections over existing run inspect/events/artifacts.
                              5. Add UI card / child inspect view.
                              6. Add runtime/headless tests for context isolation both directions, backend separation, abort, recovery, permission-prompt exclusion, and artifact lookup.

                              Umbrella: #15

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Labels

                                enhancementNew feature or request

                                Type

                                No type

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions