@astralyn/pi 0.82.5 → 0.82.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +55 -0
- package/README.md +1 -1
- package/dist/cli/project-trust.d.ts.map +1 -1
- package/dist/cli/project-trust.js +4 -1
- package/dist/cli/project-trust.js.map +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js +11 -13
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +4 -22
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/types.d.ts +32 -5
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +2 -2
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/tools/bash.d.ts +1 -5
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +16 -41
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +42 -11
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +6 -7
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +17 -8
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +3 -3
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +3 -13
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +6 -36
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +4 -4
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +7 -0
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +11 -0
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +2 -3
- package/dist/core/tools/write.js.map +1 -1
- package/dist/extensions/deepwiki/render.d.ts.map +1 -1
- package/dist/extensions/deepwiki/render.js +34 -22
- package/dist/extensions/deepwiki/render.js.map +1 -1
- package/dist/extensions/plan/constants.d.ts +43 -6
- package/dist/extensions/plan/constants.d.ts.map +1 -1
- package/dist/extensions/plan/constants.js +51 -8
- package/dist/extensions/plan/constants.js.map +1 -1
- package/dist/extensions/plan/index.d.ts +12 -3
- package/dist/extensions/plan/index.d.ts.map +1 -1
- package/dist/extensions/plan/index.js +173 -35
- package/dist/extensions/plan/index.js.map +1 -1
- package/dist/extensions/plan/schema.d.ts +5 -0
- package/dist/extensions/plan/schema.d.ts.map +1 -1
- package/dist/extensions/plan/schema.js.map +1 -1
- package/dist/extensions/plan/state.d.ts +11 -2
- package/dist/extensions/plan/state.d.ts.map +1 -1
- package/dist/extensions/plan/state.js +31 -9
- package/dist/extensions/plan/state.js.map +1 -1
- package/dist/extensions/plan/storage.d.ts +11 -3
- package/dist/extensions/plan/storage.d.ts.map +1 -1
- package/dist/extensions/plan/storage.js +45 -20
- package/dist/extensions/plan/storage.js.map +1 -1
- package/dist/extensions/plan/view.d.ts +44 -0
- package/dist/extensions/plan/view.d.ts.map +1 -0
- package/dist/extensions/plan/view.js +149 -0
- package/dist/extensions/plan/view.js.map +1 -0
- package/dist/extensions/question/dialog.d.ts.map +1 -1
- package/dist/extensions/question/dialog.js +29 -10
- package/dist/extensions/question/dialog.js.map +1 -1
- package/dist/extensions/question/index.d.ts.map +1 -1
- package/dist/extensions/question/index.js +7 -2
- package/dist/extensions/question/index.js.map +1 -1
- package/dist/extensions/question/render.d.ts +4 -8
- package/dist/extensions/question/render.d.ts.map +1 -1
- package/dist/extensions/question/render.js +202 -29
- package/dist/extensions/question/render.js.map +1 -1
- package/dist/extensions/question/results.d.ts.map +1 -1
- package/dist/extensions/question/results.js +1 -0
- package/dist/extensions/question/results.js.map +1 -1
- package/dist/extensions/question/schema.d.ts.map +1 -1
- package/dist/extensions/question/schema.js +2 -2
- package/dist/extensions/question/schema.js.map +1 -1
- package/dist/extensions/question/types.d.ts +1 -0
- package/dist/extensions/question/types.d.ts.map +1 -1
- package/dist/extensions/question/types.js +1 -1
- package/dist/extensions/question/types.js.map +1 -1
- package/dist/extensions/router/stream.d.ts +1 -0
- package/dist/extensions/router/stream.d.ts.map +1 -1
- package/dist/extensions/router/stream.js +75 -0
- package/dist/extensions/router/stream.js.map +1 -1
- package/dist/extensions/subagent/activity.d.ts.map +1 -1
- package/dist/extensions/subagent/activity.js +25 -4
- package/dist/extensions/subagent/activity.js.map +1 -1
- package/dist/extensions/subagent/constants.d.ts +1 -0
- package/dist/extensions/subagent/constants.d.ts.map +1 -1
- package/dist/extensions/subagent/constants.js +1 -0
- package/dist/extensions/subagent/constants.js.map +1 -1
- package/dist/extensions/subagent/index.d.ts.map +1 -1
- package/dist/extensions/subagent/index.js +16 -0
- package/dist/extensions/subagent/index.js.map +1 -1
- package/dist/extensions/subagent/render.d.ts.map +1 -1
- package/dist/extensions/subagent/render.js +352 -152
- package/dist/extensions/subagent/render.js.map +1 -1
- package/dist/extensions/subagent/resolve.d.ts.map +1 -1
- package/dist/extensions/subagent/resolve.js +13 -9
- package/dist/extensions/subagent/resolve.js.map +1 -1
- package/dist/extensions/subagent/retry.d.ts +17 -0
- package/dist/extensions/subagent/retry.d.ts.map +1 -0
- package/dist/extensions/subagent/retry.js +41 -0
- package/dist/extensions/subagent/retry.js.map +1 -0
- package/dist/extensions/subagent/runner.d.ts.map +1 -1
- package/dist/extensions/subagent/runner.js +37 -7
- package/dist/extensions/subagent/runner.js.map +1 -1
- package/dist/extensions/subagent/schema.d.ts.map +1 -1
- package/dist/extensions/subagent/schema.js +2 -2
- package/dist/extensions/subagent/schema.js.map +1 -1
- package/dist/extensions/subagent/sdk-runner.d.ts +6 -0
- package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
- package/dist/extensions/subagent/sdk-runner.js +46 -24
- package/dist/extensions/subagent/sdk-runner.js.map +1 -1
- package/dist/extensions/subagent/types.d.ts +7 -0
- package/dist/extensions/subagent/types.d.ts.map +1 -1
- package/dist/extensions/subagent/types.js.map +1 -1
- package/dist/extensions/todo/constants.d.ts +17 -6
- package/dist/extensions/todo/constants.d.ts.map +1 -1
- package/dist/extensions/todo/constants.js +22 -9
- package/dist/extensions/todo/constants.js.map +1 -1
- package/dist/extensions/todo/index.d.ts +0 -14
- package/dist/extensions/todo/index.d.ts.map +1 -1
- package/dist/extensions/todo/index.js +13 -1
- package/dist/extensions/todo/index.js.map +1 -1
- package/dist/extensions/todo/schema.d.ts +53 -2
- package/dist/extensions/todo/schema.d.ts.map +1 -1
- package/dist/extensions/todo/schema.js +57 -8
- package/dist/extensions/todo/schema.js.map +1 -1
- package/dist/extensions/todo/state.d.ts +16 -5
- package/dist/extensions/todo/state.d.ts.map +1 -1
- package/dist/extensions/todo/state.js +874 -130
- package/dist/extensions/todo/state.js.map +1 -1
- package/dist/extensions/todo/view.d.ts +16 -1
- package/dist/extensions/todo/view.d.ts.map +1 -1
- package/dist/extensions/todo/view.js +428 -1
- package/dist/extensions/todo/view.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +2 -1
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js +5 -0
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +1 -0
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +4 -2
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.d.ts +13 -6
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
- package/dist/modes/interactive/components/countdown-timer.js +54 -17
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +6 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +23 -11
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts +11 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +56 -0
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts +3 -0
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +52 -2
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +10 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +139 -18
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-group.d.ts +1 -0
- package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-group.js +5 -0
- package/dist/modes/interactive/components/tool-group.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +10 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +55 -2
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +5 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +79 -19
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +3 -2
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +8 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/utils/paths.d.ts +6 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +8 -0
- package/dist/utils/paths.js.map +1 -1
- package/docs/bundled/README.md +1 -0
- package/docs/bundled/extensions/deepwiki.md +1 -1
- package/docs/bundled/extensions/plan.md +13 -10
- package/docs/bundled/extensions/question.md +7 -5
- package/docs/bundled/extensions/router.md +3 -4
- package/docs/bundled/extensions/statusline.md +0 -1
- package/docs/bundled/extensions/subagent.md +5 -4
- package/docs/bundled/extensions/todo.md +9 -7
- package/docs/bundled/tool-presentation.md +17 -16
- package/docs/extensions.md +34 -5
- package/docs/rpc.md +1 -1
- package/docs/usage.md +1 -1
- package/npm-shrinkwrap.json +6 -6
- package/package.json +1 -1
- package/dist/utils/output-decoder.d.ts +0 -52
- package/dist/utils/output-decoder.d.ts.map +0 -1
- package/dist/utils/output-decoder.js +0 -134
- package/dist/utils/output-decoder.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/extensions/subagent/render.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, Container, Markdown, Spacer, Text } from \"@earendil-works/pi-tui\";\nimport type { AgentToolResult, ToolRenderResultOptions } from \"../../core/extensions/types.ts\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport { getMarkdownTheme, type Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { statusSummary } from \"./runner.ts\";\nimport type { SubagentParams } from \"./schema.ts\";\nimport type { SubagentDetails, SubagentRunDetails, SubagentRunStatus } from \"./types.ts\";\n\nconst SINGLE_EXCERPT_LIMIT = 200;\nconst RUN_LINE_EXCERPT_LIMIT = 64;\nconst LIVE_TAIL_LIMIT = 100;\nconst COLLAPSED_RUN_LIMIT = 4;\n\nconst ACTIVITY_GROUPS = [\n\t{ toolName: \"read\", verb: \"read\", singular: \"file\", plural: \"files\" },\n\t{ toolName: \"grep\", verb: \"searched\", singular: \"pattern\", plural: \"patterns\" },\n\t{ toolName: \"find\", verb: \"searched\", singular: \"path pattern\", plural: \"path patterns\" },\n\t{ toolName: \"ls\", verb: \"listed\", singular: \"directory\", plural: \"directories\" },\n\t{ toolName: \"bash\", verb: \"ran\", singular: \"command\", plural: \"commands\" },\n\t{ toolName: \"edit\", verb: \"edited\", singular: \"file\", plural: \"files\" },\n\t{ toolName: \"write\", verb: \"wrote\", singular: \"file\", plural: \"files\" },\n] as const;\n\n// Display-only: profile names stay lowercase everywhere the model sees\n// them; the transcript shows \"general\" as \"General\", \"code-reviewer\" as\n// \"Code Reviewer\".\nfunction displayAgentName(name: string): string {\n\treturn name\n\t\t.split(/[-_]/u)\n\t\t.filter(Boolean)\n\t\t.map((word) => `${word[0]?.toUpperCase() ?? \"\"}${word.slice(1)}`)\n\t\t.join(\" \");\n}\n\nfunction singleAgentName(args: { agent?: string | null }): string {\n\treturn displayAgentName(args.agent ?? \"general\");\n}\n\nfunction truncate(text: string, limit: number): string {\n\treturn text.length <= limit ? text : `${text.slice(0, Math.max(0, limit - 1))}…`;\n}\n\n// Transcript excerpts render inside plain Text components, so markdown\n// punctuation would show up literally; strip the common inline syntax.\nfunction stripInlineMarkdown(text: string): string {\n\treturn text\n\t\t.replace(/```[a-zA-Z0-9-]*/gu, \"\")\n\t\t.replace(/`([^`]*)`/gu, \"$1\")\n\t\t.replace(/\\*\\*([^*]+)\\*\\*/gu, \"$1\")\n\t\t.replace(/__([^_]+)__/gu, \"$1\")\n\t\t.replace(/\\[([^\\]]+)\\]\\([^)]*\\)/gu, \"$1\")\n\t\t.replace(/^#{1,6}\\s+/gmu, \"\");\n}\n\n// Markdown tables and horizontal rules turn into symbol soup when\n// flattened onto one line; drop those lines before inline stripping.\nfunction stripBlockMarkdown(text: string): string {\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.filter((line) => {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (trimmed.startsWith(\"|\")) return false;\n\t\t\treturn !(trimmed.length >= 3 && /^[-—─═=*_|:\\s]+$/u.test(trimmed));\n\t\t})\n\t\t.join(\"\\n\");\n}\n\nfunction excerpt(text: string, limit: number): string {\n\t// finalOutput/liveText carry model-facing truncation notices from\n\t// boundText/tailText; in the transcript an ellipsis is enough.\n\tconst cleaned = text.replace(/\\[(?:Output truncated(?:: \\d+ bytes omitted\\.)?|Earlier output omitted\\.)\\]/gu, \"…\");\n\treturn truncate(stripInlineMarkdown(stripBlockMarkdown(cleaned)).replace(/\\s+/gu, \" \").trim(), limit);\n}\n\nfunction liveTail(run: SubagentRunDetails): string | undefined {\n\tconst lines = run.liveText\n\t\t.split(\"\\n\")\n\t\t.map((line) => line.trim())\n\t\t.filter(Boolean);\n\tconst last = lines.at(-1);\n\treturn last ? excerpt(last, LIVE_TAIL_LIMIT) : undefined;\n}\n\n// Completed-run excerpts read better cut at a sentence boundary than\n// mid-word; fall back to a hard truncate when no boundary lands in the\n// second half of the window.\nfunction leadingSentences(text: string, limit: number): string {\n\tconst cleaned = excerpt(text, Number.MAX_SAFE_INTEGER);\n\tif (cleaned.length <= limit) return cleaned;\n\tconst window = cleaned.slice(0, limit);\n\tlet boundary = -1;\n\tfor (const match of window.matchAll(/[.!?。!?](?=\\s|$)/gu)) {\n\t\tboundary = (match.index ?? 0) + match[0].length;\n\t}\n\tif (boundary >= limit / 2) return window.slice(0, boundary).trimEnd();\n\treturn truncate(window, limit);\n}\n\nconst VERIFY_COMMAND_PATTERN = /\\b(test|lint|typecheck|tsc|vitest|jest|pytest|build|check|fmt|format|compile)\\b/iu;\nconst INSPECT_COMMAND_PATTERN = /\\b(rg|grep|find|git (?:diff|status|log|show)|ls|tree|cat|head|tail)\\b/iu;\nconst RETRY_MARKER_PATTERN = /^Retrying\\b/u;\nconst STREAM_MARKERS = new Set([\"Thinking…\", \"Writing response…\"]);\n\n// Translates raw tool traffic into what the worker is doing right now, so\n// the collapsed card reads as a phase instead of a command line. Modelled\n// on tool-type classification; the raw tool summary stays as evidence on\n// the next line.\nfunction runIntent(run: SubagentRunDetails): string {\n\tconst current = run.currentActivity;\n\tif (current && RETRY_MARKER_PATTERN.test(current)) return current;\n\tconst running = [...run.activities].reverse().find((activity) => activity.status === \"running\");\n\tif (running) {\n\t\tif (running.toolName === \"edit\" || running.toolName === \"write\") return \"Applying changes\";\n\t\tif (running.toolName === \"bash\") {\n\t\t\tif (VERIFY_COMMAND_PATTERN.test(running.summary)) return \"Verifying changes\";\n\t\t\treturn INSPECT_COMMAND_PATTERN.test(running.summary) ? \"Exploring code\" : \"Running commands\";\n\t\t}\n\t\treturn \"Exploring code\";\n\t}\n\tconst recent = run.activities.slice(-5);\n\tif (current && STREAM_MARKERS.has(current)) {\n\t\tif (recent.some((activity) => activity.status === \"failed\")) return \"Investigating a failure\";\n\t\treturn current;\n\t}\n\tif (recent.some((activity) => activity.status === \"failed\")) return \"Investigating a failure\";\n\tif (recent.some((activity) => activity.toolName === \"edit\" || activity.toolName === \"write\"))\n\t\treturn \"Reviewing changes\";\n\tif (recent.length > 0) return \"Exploring code\";\n\treturn current ?? \"Thinking…\";\n}\n\n// The raw tool summary backs up the intent line; suppress it when it would\n// just repeat a stream/retry marker.\nfunction runEvidence(run: SubagentRunDetails): string | undefined {\n\tconst current = run.currentActivity;\n\tif (!current || STREAM_MARKERS.has(current) || RETRY_MARKER_PATTERN.test(current)) return undefined;\n\treturn current;\n}\n\nfunction liveElapsed(run: SubagentRunDetails): string | undefined {\n\tif (run.startedAt === undefined) return undefined;\n\tconst end = run.endedAt ?? Date.now();\n\treturn formatDuration(Math.max(0, (end - run.startedAt) / 1000));\n}\n\n// The tool shell already paints a call-level status dot (● in\n// warning/success/error), so `●` is off-limits here: `›` marks where the\n// work currently is, and the remaining glyphs are terminal states.\nfunction statusMarker(status: SubagentRunStatus, theme: Theme): string {\n\tswitch (status) {\n\t\tcase \"completed\":\n\t\t\treturn theme.fg(\"success\", \"✓\");\n\t\tcase \"failed\":\n\t\t\treturn theme.fg(\"error\", \"×\");\n\t\tcase \"aborted\":\n\t\t\treturn theme.fg(\"warning\", \"■\");\n\t\tcase \"running\":\n\t\t\treturn theme.fg(\"accent\", \"›\");\n\t\tdefault:\n\t\t\treturn theme.fg(\"muted\", \"○\");\n\t}\n}\n\nfunction runTitle(run: SubagentRunDetails, theme: Theme, index?: number): string {\n\tconst number = index === undefined ? \"\" : theme.fg(\"dim\", `${index} · `);\n\treturn `${statusMarker(run.status, theme)} ${number}${theme.fg(\"accent\", displayAgentName(run.agent))}${theme.fg(\"dim\", ` · ${truncate(run.description, 48)}`)}`;\n}\n\nfunction runProgressText(run: SubagentRunDetails): string {\n\tconst items = [`${run.usage.toolUses} tool use${run.usage.toolUses === 1 ? \"\" : \"s\"}`];\n\tif (run.usage.totalTokens) items.push(`${formatTokens(run.usage.totalTokens)} tokens`);\n\treturn items.join(\" · \");\n}\n\nfunction runLine(run: SubagentRunDetails, theme: Theme, index?: number): string {\n\tlet line = runTitle(run, theme, index);\n\tconst detail =\n\t\trun.status === \"running\"\n\t\t\t? runIntent(run)\n\t\t\t: run.status === \"failed\" || run.status === \"aborted\"\n\t\t\t\t? run.error && excerpt(run.error, RUN_LINE_EXCERPT_LIMIT)\n\t\t\t\t: run.finalOutput && excerpt(run.finalOutput, RUN_LINE_EXCERPT_LIMIT);\n\tif (detail) line += theme.fg(run.status === \"failed\" ? \"error\" : \"dim\", ` — ${detail}`);\n\tif (run.status === \"running\") {\n\t\tline += theme.fg(\"dim\", ` · ${runProgressText(run)}`);\n\t\tconst elapsed = liveElapsed(run);\n\t\tif (elapsed) line += theme.fg(\"dim\", ` · ${elapsed}`);\n\t}\n\tconst settled = run.status !== \"running\" && run.status !== \"queued\";\n\tif (settled && run.startedAt !== undefined && run.endedAt !== undefined) {\n\t\tline += theme.fg(\"dim\", ` · ${formatDuration(Math.max(0, (run.endedAt - run.startedAt) / 1000))}`);\n\t}\n\treturn line;\n}\n\n// Keep active work visible while a batch is in flight: completed runs\n// may otherwise crowd a still-running task out of the collapsed window.\nfunction selectCollapsedRuns(runs: SubagentRunDetails[], isPartial: boolean): SubagentRunDetails[] {\n\tif (runs.length <= COLLAPSED_RUN_LIMIT) return runs;\n\tif (!isPartial) return runs.slice(0, COLLAPSED_RUN_LIMIT);\n\tconst active = runs.filter((run) => run.status === \"running\" || run.status === \"queued\");\n\tconst settled = runs.filter((run) => run.status !== \"running\" && run.status !== \"queued\");\n\treturn [...active, ...settled].slice(0, COLLAPSED_RUN_LIMIT);\n}\n\nfunction singleCollapsedLines(details: SubagentDetails, theme: Theme): string[] {\n\tconst run = details.runs[0];\n\tif (!run) return [theme.fg(\"muted\", \"Initializing…\")];\n\tif (run.status === \"running\" || run.status === \"queued\") {\n\t\tconst isInitializing =\n\t\t\trun.status === \"running\" && run.usage.turns === 0 && run.usage.toolUses === 0 && run.liveText.length === 0;\n\t\tconst intent =\n\t\t\trun.status === \"queued\"\n\t\t\t\t? (run.currentActivity ?? \"queued\")\n\t\t\t\t: isInitializing\n\t\t\t\t\t? \"Initializing…\"\n\t\t\t\t\t: runIntent(run);\n\t\t// No status marker here: the shell's call-level dot already covers\n\t\t// the whole card, and a single run has nothing to disambiguate.\n\t\tlet status = theme.fg(\"dim\", intent);\n\t\tif (run.status === \"running\" && !isInitializing) {\n\t\t\tstatus += theme.fg(\"dim\", ` · ${runProgressText(run)}`);\n\t\t\tconst elapsed = liveElapsed(run);\n\t\t\tif (elapsed) status += theme.fg(\"dim\", ` · ${elapsed}`);\n\t\t}\n\t\tconst lines = [status];\n\t\tconst evidence = runEvidence(run);\n\t\tif (evidence && evidence !== intent)\n\t\t\tlines.push(`${theme.fg(\"accent\", \"›\")} ${theme.fg(\"dim\", excerpt(evidence, LIVE_TAIL_LIMIT))}`);\n\t\tconst tail = liveTail(run);\n\t\tif (tail) lines.push(theme.fg(\"dim\", tail));\n\t\treturn lines;\n\t}\n\tif (run.error) return [theme.fg(\"error\", excerpt(run.error, SINGLE_EXCERPT_LIMIT))];\n\tif (run.finalOutput) return [theme.fg(\"toolOutput\", leadingSentences(run.finalOutput, SINGLE_EXCERPT_LIMIT))];\n\treturn [theme.fg(\"muted\", run.status)];\n}\n\nfunction activitySummaryText(details: SubagentDetails): string {\n\tconst toolCounts = new Map<string, number>();\n\tlet activityCount = 0;\n\tfor (const run of details.runs) {\n\t\tfor (const activity of run.activities) {\n\t\t\tactivityCount++;\n\t\t\ttoolCounts.set(activity.toolName, (toolCounts.get(activity.toolName) ?? 0) + 1);\n\t\t}\n\t}\n\tconst items: string[] = [];\n\tlet groupedCount = 0;\n\tfor (const group of ACTIVITY_GROUPS) {\n\t\tconst count = toolCounts.get(group.toolName) ?? 0;\n\t\tif (count === 0) continue;\n\t\tgroupedCount += count;\n\t\titems.push(`${group.verb} ${count} ${count === 1 ? group.singular : group.plural}`);\n\t}\n\tconst otherCount = activityCount - groupedCount;\n\tif (otherCount > 0) items.push(`used ${otherCount} other tool${otherCount === 1 ? \"\" : \"s\"}`);\n\tif (items.length === 0) return \"\";\n\tconst earlierCount = Math.max(0, details.usage.toolUses - activityCount);\n\tif (earlierCount > 0) items.push(`${earlierCount} earlier tool use${earlierCount === 1 ? \"\" : \"s\"}`);\n\treturn `${items[0]![0]!.toUpperCase()}${items[0]!.slice(1)}${items\n\t\t.slice(1)\n\t\t.map((item) => ` · ${item}`)\n\t\t.join(\"\")}`;\n}\n\nfunction usageText(details: SubagentDetails, includeToolUses = true): string {\n\tconst usage = details.usage;\n\tconst items: string[] = [];\n\tif (includeToolUses && usage.toolUses) items.push(`${usage.toolUses} tool use${usage.toolUses === 1 ? \"\" : \"s\"}`);\n\tif (usage.turns) items.push(`${usage.turns} turn${usage.turns === 1 ? \"\" : \"s\"}`);\n\tif (usage.output) items.push(`↓${formatTokens(usage.output)}`);\n\tif (usage.contextTokens) items.push(`ctx:${formatTokens(usage.contextTokens)}`);\n\tif (usage.cost) items.push(`$${usage.cost.toFixed(3)}`);\n\tconst duration = details.endedAt ? Math.max(0, (details.endedAt - details.startedAt) / 1000) : undefined;\n\tif (duration !== undefined) items.push(formatDuration(duration));\n\treturn items.join(\" · \");\n}\n\nfunction formatTokens(value: number): string {\n\tif (value < 1_000) return String(value);\n\tif (value < 1_000_000) return `${(value / 1_000).toFixed(value < 10_000 ? 1 : 0)}k`;\n\treturn `${(value / 1_000_000).toFixed(1)}M`;\n}\n\nfunction formatDuration(seconds: number): string {\n\tif (seconds >= 90) return `${Math.floor(seconds / 60)}m ${Math.round(seconds % 60)}s`;\n\treturn `${seconds.toFixed(seconds < 10 ? 1 : 0)}s`;\n}\n\n// A single run's title and usage would duplicate the call header and\n// the call-level usage line, so `single` drops both and folds the\n// duration into the metadata line instead. Multi-run sections carry a\n// numbered `──` header that matches the table of contents above them.\nfunction renderRunDetails(run: SubagentRunDetails, theme: Theme, single: boolean, index?: number): Component {\n\tconst container = new Container();\n\tconst duration =\n\t\trun.startedAt !== undefined && run.endedAt !== undefined\n\t\t\t? formatDuration(Math.max(0, (run.endedAt - run.startedAt) / 1000))\n\t\t\t: undefined;\n\tif (!single) {\n\t\tconst label = index === undefined ? \"\" : `${index} · `;\n\t\tcontainer.addChild(\n\t\t\tnew Text(\n\t\t\t\t`${theme.fg(\"dim\", `── ${label}`)}${theme.fg(\"accent\", displayAgentName(run.agent))}${theme.fg(\"dim\", ` · ${truncate(run.description, 48)}`)}`,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t}\n\tcontainer.addChild(new Text(theme.fg(\"muted\", \"Task\"), 0, 0));\n\tcontainer.addChild(new Text(theme.fg(\"dim\", run.prompt), 0, 0));\n\tif (run.activities.length > 0) {\n\t\tcontainer.addChild(new Spacer(1));\n\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"Activity\"), 0, 0));\n\t\tfor (const activity of run.activities) {\n\t\t\tconst marker =\n\t\t\t\tactivity.status === \"succeeded\"\n\t\t\t\t\t? theme.fg(\"success\", \"✓\")\n\t\t\t\t\t: activity.status === \"failed\"\n\t\t\t\t\t\t? theme.fg(\"error\", \"×\")\n\t\t\t\t\t\t: theme.fg(\"accent\", \"›\");\n\t\t\tlet text = `${marker} ${theme.fg(\"toolOutput\", excerpt(activity.summary, 96))}`;\n\t\t\tif (activity.resultSummary) {\n\t\t\t\tconst color = activity.status === \"failed\" ? \"error\" : \"dim\";\n\t\t\t\ttext += ` ${theme.fg(color, `· ${excerpt(activity.resultSummary, 64)}`)}`;\n\t\t\t}\n\t\t\tif (activity.endedAt !== undefined && activity.endedAt - activity.startedAt >= 1_000) {\n\t\t\t\ttext += ` ${theme.fg(\"dim\", `· ${formatDuration((activity.endedAt - activity.startedAt) / 1000)}`)}`;\n\t\t\t}\n\t\t\tcontainer.addChild(new Text(text, 0, 0));\n\t\t}\n\t}\n\t// The live tail is the \"now\" end of the timeline, so it sits after the\n\t// activity list; once the run settles, Response takes its place.\n\tif (run.status === \"running\" && run.liveText) {\n\t\tconst tail = run.liveText\n\t\t\t.split(\"\\n\")\n\t\t\t.map((line) => line.trim())\n\t\t\t.filter(Boolean)\n\t\t\t.slice(-4);\n\t\tif (tail.length > 0) {\n\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\tfor (const line of tail) {\n\t\t\t\tcontainer.addChild(new Text(theme.fg(\"dim\", excerpt(line, LIVE_TAIL_LIMIT)), 0, 0));\n\t\t\t}\n\t\t}\n\t}\n\tif (run.error) {\n\t\tcontainer.addChild(new Spacer(1));\n\t\tcontainer.addChild(new Text(theme.fg(\"error\", `Error: ${run.error}`), 0, 0));\n\t}\n\tif (run.finalOutput) {\n\t\tcontainer.addChild(new Spacer(1));\n\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"Response\"), 0, 0));\n\t\tcontainer.addChild(new Markdown(run.finalOutput, 0, 0, getMarkdownTheme()));\n\t}\n\tconst metadata = [\n\t\t`${run.model} · ${run.thinking}`,\n\t\trun.cwd ? `cwd: ${run.cwd}` : undefined,\n\t\trun.usage.toolUses ? `${run.usage.toolUses} tool use${run.usage.toolUses === 1 ? \"\" : \"s\"}` : undefined,\n\t\trun.usage.turns ? `${run.usage.turns} turn${run.usage.turns === 1 ? \"\" : \"s\"}` : undefined,\n\t\trun.usage.output ? `↓${formatTokens(run.usage.output)}` : undefined,\n\t\trun.usage.contextTokens ? `ctx:${formatTokens(run.usage.contextTokens)}` : undefined,\n\t\trun.usage.cost ? `$${run.usage.cost.toFixed(3)}` : undefined,\n\t\tsingle ? duration : undefined,\n\t]\n\t\t.filter((item): item is string => Boolean(item))\n\t\t.join(\" · \");\n\tif (metadata) {\n\t\tcontainer.addChild(new Spacer(1));\n\t\tcontainer.addChild(new Text(theme.fg(\"dim\", metadata), 0, 0));\n\t}\n\treturn container;\n}\n\n// The call header stays a single line: run rows in the result area take\n// over within the first update and carry richer per-task state, so a\n// task list here would render everything twice. The task count alone\n// distinguishes a batch from a single delegation.\nexport function renderSubagentCall(args: SubagentParams, theme: Theme): Component {\n\tconst modes = [args.prompt != null && \"prompt\", args.tasks != null && \"tasks\"].filter((mode): mode is string =>\n\t\tBoolean(mode),\n\t);\n\tif (modes.length > 1) {\n\t\treturn new Text(\n\t\t\t`${theme.fg(\"toolTitle\", theme.bold(\"Subagent \"))}${theme.fg(\"error\", `invalid · ${modes.join(\" + \")}`)}`,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t}\n\tif (args.tasks) {\n\t\treturn new Text(\n\t\t\t`${theme.fg(\"toolTitle\", theme.bold(\"Multi-Agent\"))}${theme.fg(\"dim\", ` · ${args.tasks.length} task${args.tasks.length === 1 ? \"\" : \"s\"}`)}`,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t}\n\tlet text = theme.fg(\"toolTitle\", theme.bold(`${singleAgentName(args)} Agent`));\n\tif (args.description) text += theme.fg(\"dim\", ` · ${truncate(args.description, 72)}`);\n\treturn new Text(text, 0, 0);\n}\n\nexport function renderSubagentResult(\n\tresult: AgentToolResult<SubagentDetails>,\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tisError: boolean,\n): Component {\n\tconst details = result.details;\n\tif (!details) {\n\t\tconst text = result.content.find((part) => part.type === \"text\");\n\t\treturn new Text(text?.type === \"text\" ? text.text : \"(no output)\", 0, 0);\n\t}\n\tif (!options.expanded) {\n\t\tconst lines: string[] = [];\n\t\tif (details.mode === \"single\") {\n\t\t\tlines.push(...singleCollapsedLines(details, theme));\n\t\t} else {\n\t\t\tlet header = statusSummary(details);\n\t\t\tif (options.isPartial) {\n\t\t\t\theader += ` · ${formatDuration(Math.max(0, (Date.now() - details.startedAt) / 1000))}`;\n\t\t\t}\n\t\t\tlines.push(theme.fg(isError ? \"error\" : options.isPartial ? \"accent\" : \"muted\", header));\n\t\t\tconst shown = selectCollapsedRuns(details.runs, Boolean(options.isPartial));\n\t\t\tfor (const run of shown) lines.push(runLine(run, theme));\n\t\t\tconst hidden = details.runs.length - shown.length;\n\t\t\tif (hidden > 0) lines.push(theme.fg(\"muted\", `+${hidden} more`));\n\t\t}\n\t\tconst activitySummary = activitySummaryText(details);\n\t\tif (activitySummary) lines.push(theme.fg(\"dim\", activitySummary));\n\t\tconst usage = usageText(details, !activitySummary);\n\t\tif (usage) lines.push(theme.fg(\"dim\", usage));\n\t\tif (!options.isPartial) lines.push(theme.fg(\"muted\", `(${keyHint(\"app.tools.expand\", \"to expand\")})`));\n\t\treturn new Text(lines.join(\"\\n\"), 0, 0);\n\t}\n\tconst container = new Container();\n\tconst single = details.mode === \"single\" && details.runs.length === 1;\n\tif (!single) {\n\t\tcontainer.addChild(new Text(theme.fg(isError ? \"error\" : \"toolTitle\", statusSummary(details)), 0, 0));\n\t\t// Numbered table of contents: the TUI cannot jump, but matching the\n\t\t// numbers against the `──` section headers below makes an 8-run\n\t\t// batch navigable by eye.\n\t\tdetails.runs.forEach((run, index) => {\n\t\t\tcontainer.addChild(new Text(runLine(run, theme, index + 1), 0, 0));\n\t\t});\n\t}\n\tdetails.runs.forEach((run, index) => {\n\t\tif (!single || index > 0) container.addChild(new Spacer(1));\n\t\tcontainer.addChild(renderRunDetails(run, theme, single, single ? undefined : index + 1));\n\t});\n\tif (!single) {\n\t\tconst usage = usageText(details);\n\t\tif (usage) {\n\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\tcontainer.addChild(new Text(theme.fg(\"dim\", usage), 0, 0));\n\t\t}\n\t}\n\treturn container;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/extensions/subagent/render.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, Container, Markdown, Spacer, Text } from \"@earendil-works/pi-tui\";\nimport type { AgentToolResult, ToolRenderResultOptions } from \"../../core/extensions/types.ts\";\nimport { keyHint } from \"../../modes/interactive/components/keybinding-hints.ts\";\nimport { getMarkdownTheme, type Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { getSubagentRetryView } from \"./retry.ts\";\nimport { statusSummary } from \"./runner.ts\";\nimport type { SubagentParams } from \"./schema.ts\";\nimport type { SubagentDetails, SubagentRunDetails, SubagentRunStatus } from \"./types.ts\";\n\nconst SINGLE_EXCERPT_LIMIT = 200;\nconst RUN_LINE_EXCERPT_LIMIT = 96;\nconst RUN_ERROR_EXCERPT_LIMIT = 200;\nconst RETRY_ERROR_EXCERPT_LIMIT = 160;\nconst LIVE_TAIL_LIMIT = 100;\nconst COLLAPSED_RUN_LIMIT = 4;\nconst PROMPT_PREVIEW_LINES = 2;\nconst PROMPT_PREVIEW_LINE_LIMIT = 120;\nconst ACTIVITY_SUMMARY_LIMIT = 96;\nconst ACTIVITY_RESULT_LIMIT = 64;\n// Sub-10s tool calls are routine; a duration only earns ink when it\n// explains where the time went.\nconst ACTIVITY_DURATION_MIN_MS = 10_000;\nconst EXPANDED_LIVE_TAIL_LINES = 3;\n\nclass IndentedText implements Component {\n\tprivate readonly text: Text;\n\tprivate readonly indent: number;\n\n\tconstructor(text: string, indent: number) {\n\t\tthis.text = new Text(text, 0, 0);\n\t\tthis.indent = indent;\n\t}\n\n\trender(width: number): string[] {\n\t\tconst indent = Math.min(this.indent, Math.max(0, width - 1));\n\t\tconst prefix = \" \".repeat(indent);\n\t\treturn this.text.render(Math.max(1, width - indent)).map((line) => `${prefix}${line}`);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.text.invalidate();\n\t}\n}\n\n// Display-only: profile names stay lowercase everywhere the model sees\n// them; the transcript shows \"general\" as \"General\", \"code-reviewer\" as\n// \"Code Reviewer\".\nfunction displayAgentName(name: string): string {\n\treturn name\n\t\t.split(/[-_]/u)\n\t\t.filter(Boolean)\n\t\t.map((word) => `${word[0]?.toUpperCase() ?? \"\"}${word.slice(1)}`)\n\t\t.join(\" \");\n}\n\nfunction singleAgentName(args: { agent?: string | null }): string {\n\treturn displayAgentName(args.agent ?? \"general\");\n}\n\nfunction truncate(text: string, limit: number): string {\n\treturn text.length <= limit ? text : `${text.slice(0, Math.max(0, limit - 1))}…`;\n}\n\n// Transcript excerpts render inside plain Text components, so markdown\n// punctuation would show up literally; strip the common inline syntax.\nfunction stripInlineMarkdown(text: string): string {\n\treturn text\n\t\t.replace(/```[a-zA-Z0-9-]*/gu, \"\")\n\t\t.replace(/`([^`]*)`/gu, \"$1\")\n\t\t.replace(/\\*\\*([^*]+)\\*\\*/gu, \"$1\")\n\t\t.replace(/__([^_]+)__/gu, \"$1\")\n\t\t.replace(/\\[([^\\]]+)\\]\\([^)]*\\)/gu, \"$1\")\n\t\t.replace(/^#{1,6}\\s+/gmu, \"\");\n}\n\n// Markdown tables and horizontal rules turn into symbol soup when\n// flattened onto one line; drop those lines before inline stripping.\nfunction stripBlockMarkdown(text: string): string {\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.filter((line) => {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (trimmed.startsWith(\"|\")) return false;\n\t\t\treturn !(trimmed.length >= 3 && /^[-—─═=*_|:\\s]+$/u.test(trimmed));\n\t\t})\n\t\t.join(\"\\n\");\n}\n\n// finalOutput/liveText carry model-facing truncation notices from\n// boundText/tailText. Only recognize their exact boundary lines so literal\n// discussion of the marker remains visible in the transcript.\nconst OUTPUT_TRUNCATION_NOTICE_PATTERN = /^\\[Output truncated(?:: \\d+ bytes omitted)?\\.\\]$/u;\nconst EARLIER_OUTPUT_NOTICE = \"[Earlier output omitted.]\";\n\nfunction terminalOutputNotice(text: string): { text: string; truncated: boolean } {\n\tconst lines = text.split(\"\\n\");\n\tlet index = lines.length - 1;\n\twhile (index >= 0 && !lines[index]?.trim()) index--;\n\tif (index < 0 || !OUTPUT_TRUNCATION_NOTICE_PATTERN.test(lines[index]?.trim() ?? \"\")) {\n\t\treturn { text, truncated: false };\n\t}\n\tlines.splice(index, 1);\n\treturn { text: lines.join(\"\\n\").trimEnd(), truncated: true };\n}\n\nfunction replaceBoundaryNotices(text: string): string {\n\tconst lines = text.split(\"\\n\");\n\tconst first = lines.findIndex((line) => Boolean(line.trim()));\n\tif (first >= 0 && lines[first]?.trim() === EARLIER_OUTPUT_NOTICE) lines[first] = \"…\";\n\tlet last = lines.length - 1;\n\twhile (last >= 0 && !lines[last]?.trim()) last--;\n\tif (last >= 0 && OUTPUT_TRUNCATION_NOTICE_PATTERN.test(lines[last]?.trim() ?? \"\")) lines[last] = \"…\";\n\treturn lines.join(\"\\n\");\n}\n\nfunction plainExcerpt(text: string, limit: number): string {\n\treturn truncate(stripInlineMarkdown(stripBlockMarkdown(text)).replace(/\\s+/gu, \" \").trim(), limit);\n}\n\nfunction excerpt(text: string, limit: number): string {\n\treturn plainExcerpt(replaceBoundaryNotices(text), limit);\n}\n\n// Generated notice-only boundary lines must never become the live line the\n// user watches; identical text in the body remains ordinary model output.\nfunction liveTailLines(run: SubagentRunDetails): string[] {\n\tconst { text } = terminalOutputNotice(run.liveText);\n\tconst lines = text\n\t\t.split(\"\\n\")\n\t\t.map((line) => line.trim())\n\t\t.filter(Boolean);\n\tif (lines[0] === EARLIER_OUTPUT_NOTICE) lines.shift();\n\treturn lines;\n}\n\nfunction liveTail(run: SubagentRunDetails): string | undefined {\n\tconst last = liveTailLines(run).at(-1);\n\treturn last ? excerpt(last, LIVE_TAIL_LIMIT) : undefined;\n}\n\n// Completed-run excerpts read better cut at a sentence boundary than\n// mid-word; fall back to a hard truncate when no boundary lands in the\n// second half of the window.\nfunction leadingSentences(text: string, limit: number): string {\n\tconst cleaned = excerpt(text, Number.MAX_SAFE_INTEGER);\n\tif (cleaned.length <= limit) return cleaned;\n\tconst window = cleaned.slice(0, limit);\n\tlet boundary = -1;\n\tfor (const match of window.matchAll(/[.!?。!?](?=\\s|$)/gu)) {\n\t\tboundary = (match.index ?? 0) + match[0].length;\n\t}\n\tif (boundary >= limit / 2) return window.slice(0, boundary).trimEnd();\n\treturn truncate(cleaned, limit);\n}\n\nconst VERIFY_COMMAND_PATTERN = /\\b(test|lint|typecheck|tsc|vitest|jest|pytest|build|check|fmt|format|compile)\\b/iu;\nconst INSPECT_COMMAND_PATTERN = /\\b(rg|grep|find|git (?:diff|status|log|show)|ls|tree|cat|head|tail)\\b/iu;\nconst RETRY_MARKER_PATTERN = /^Retrying\\b/u;\nconst STREAM_MARKERS = new Set([\"Thinking…\", \"Writing response…\"]);\n\nfunction retryText(run: SubagentRunDetails): string | undefined {\n\tconst retry = getSubagentRetryView(run);\n\tif (!retry) return undefined;\n\tconst status =\n\t\tretry.remainingSeconds > 0\n\t\t\t? `Retrying (${retry.attempt}/${retry.maxAttempts}) in ${retry.remainingSeconds}s`\n\t\t\t: `Retrying now… (${retry.attempt}/${retry.maxAttempts})`;\n\tconst error = excerpt(retry.error, RETRY_ERROR_EXCERPT_LIMIT);\n\treturn error ? `${status} — ${error}` : status;\n}\n\n// Translates raw tool traffic into what the worker is doing right now, so\n// the collapsed card reads as a phase instead of a command line. Modelled\n// on tool-type classification; the raw tool summary stays as evidence on\n// the next line.\nfunction runIntent(run: SubagentRunDetails): string {\n\tconst retry = retryText(run);\n\tif (retry) return retry;\n\tconst current = run.currentActivity;\n\tif (current && RETRY_MARKER_PATTERN.test(current)) return current;\n\tconst running = [...run.activities].reverse().find((activity) => activity.status === \"running\");\n\tif (running) {\n\t\tif (running.toolName === \"edit\" || running.toolName === \"write\") return \"Applying changes\";\n\t\tif (running.toolName === \"bash\") {\n\t\t\tif (VERIFY_COMMAND_PATTERN.test(running.summary)) return \"Verifying changes\";\n\t\t\treturn INSPECT_COMMAND_PATTERN.test(running.summary) ? \"Exploring code\" : \"Running commands\";\n\t\t}\n\t\treturn \"Exploring code\";\n\t}\n\tconst recent = run.activities.slice(-5);\n\tif (current && STREAM_MARKERS.has(current)) {\n\t\tif (recent.some((activity) => activity.status === \"failed\")) return \"Investigating a failure\";\n\t\treturn current;\n\t}\n\tif (recent.some((activity) => activity.status === \"failed\")) return \"Investigating a failure\";\n\tif (recent.some((activity) => activity.toolName === \"edit\" || activity.toolName === \"write\"))\n\t\treturn \"Reviewing changes\";\n\tif (recent.length > 0) return \"Exploring code\";\n\treturn current ?? \"Thinking…\";\n}\n\n// The raw tool summary backs up the intent line; suppress it when it would\n// just repeat a stream/retry marker.\nfunction runEvidence(run: SubagentRunDetails): string | undefined {\n\tif (getSubagentRetryView(run)) return undefined;\n\tconst current = run.currentActivity;\n\tif (!current || STREAM_MARKERS.has(current) || RETRY_MARKER_PATTERN.test(current)) return undefined;\n\treturn current;\n}\n\nfunction liveElapsed(run: SubagentRunDetails): string | undefined {\n\tif (run.startedAt === undefined) return undefined;\n\tconst end = run.endedAt ?? Date.now();\n\treturn formatDuration(Math.max(0, (end - run.startedAt) / 1000));\n}\n\nfunction statusColor(status: SubagentRunStatus): \"success\" | \"error\" | \"warning\" | \"accent\" | \"muted\" {\n\tswitch (status) {\n\t\tcase \"completed\":\n\t\t\treturn \"success\";\n\t\tcase \"failed\":\n\t\t\treturn \"error\";\n\t\tcase \"aborted\":\n\t\t\treturn \"warning\";\n\t\tcase \"running\":\n\t\t\treturn \"accent\";\n\t\tdefault:\n\t\t\treturn \"muted\";\n\t}\n}\n\n// The tool shell already paints a call-level status dot (● in\n// warning/success/error), so `●` is off-limits here: `›` marks where the\n// work currently is, and the remaining glyphs are terminal states.\nfunction statusMarker(status: SubagentRunStatus, theme: Theme): string {\n\tconst glyph =\n\t\tstatus === \"completed\"\n\t\t\t? \"✓\"\n\t\t\t: status === \"failed\"\n\t\t\t\t? \"×\"\n\t\t\t\t: status === \"aborted\"\n\t\t\t\t\t? \"■\"\n\t\t\t\t\t: status === \"running\"\n\t\t\t\t\t\t? \"›\"\n\t\t\t\t\t\t: \"○\";\n\treturn theme.fg(statusColor(status), glyph);\n}\n\nfunction statusWord(status: SubagentRunStatus): string {\n\tswitch (status) {\n\t\tcase \"completed\":\n\t\t\treturn \"Completed\";\n\t\tcase \"failed\":\n\t\t\treturn \"Failed\";\n\t\tcase \"aborted\":\n\t\t\treturn \"Aborted\";\n\t\tcase \"running\":\n\t\t\treturn \"Running\";\n\t\tdefault:\n\t\t\treturn \"Queued\";\n\t}\n}\n\nfunction runTitle(run: SubagentRunDetails, theme: Theme, index?: number): string {\n\tconst number = index === undefined ? \"\" : theme.fg(\"dim\", `${index} · `);\n\treturn `${statusMarker(run.status, theme)} ${number}${theme.fg(\"accent\", displayAgentName(run.agent))}${theme.fg(\"dim\", ` · ${truncate(run.description, 48)}`)}`;\n}\n\n// Mid-run token totals are cache-inflated (totalTokens sums cache reads\n// across turns), so live lines quote tool uses and the context watermark\n// instead; settled lines get the real total.\nfunction runProgressText(run: SubagentRunDetails): string {\n\tconst items = [`${run.usage.toolUses} tool use${run.usage.toolUses === 1 ? \"\" : \"s\"}`];\n\tif (run.usage.contextTokens) items.push(`ctx: ${formatTokens(run.usage.contextTokens)}`);\n\treturn items.join(\" · \");\n}\n\nfunction runLine(run: SubagentRunDetails, theme: Theme, index?: number): string {\n\tlet line = runTitle(run, theme, index);\n\tconst retry = retryText(run);\n\tconst detail =\n\t\tretry ??\n\t\t(run.status === \"running\"\n\t\t\t? excerpt(runIntent(run), LIVE_TAIL_LIMIT)\n\t\t\t: run.status === \"failed\" || run.status === \"aborted\"\n\t\t\t\t? undefined\n\t\t\t\t: run.finalOutput && leadingSentences(run.finalOutput, RUN_LINE_EXCERPT_LIMIT));\n\tif (detail) line += theme.fg(\"dim\", ` — ${detail}`);\n\tif (run.status === \"running\") {\n\t\tline += theme.fg(\"dim\", ` · ${runProgressText(run)}`);\n\t\tif (run.usage.cost) line += theme.fg(\"dim\", ` · $${run.usage.cost.toFixed(3)}`);\n\t\tconst elapsed = liveElapsed(run);\n\t\tif (elapsed) line += theme.fg(\"dim\", ` · ${elapsed}`);\n\t}\n\tconst settled = run.status !== \"running\" && run.status !== \"queued\";\n\tif (settled && run.startedAt !== undefined && run.endedAt !== undefined) {\n\t\tline += theme.fg(\"dim\", ` · ${formatDuration(Math.max(0, (run.endedAt - run.startedAt) / 1000))}`);\n\t}\n\treturn line;\n}\n\nfunction runErrorExcerpt(run: SubagentRunDetails): string | undefined {\n\tif ((run.status !== \"failed\" && run.status !== \"aborted\") || !run.error) return undefined;\n\treturn leadingSentences(run.error, RUN_ERROR_EXCERPT_LIMIT);\n}\n\nfunction runErrorIndent(index?: number): number {\n\treturn index === undefined ? 2 : 5 + String(index).length;\n}\n\nfunction addRunSummary(container: Container, run: SubagentRunDetails, theme: Theme, index?: number): void {\n\tcontainer.addChild(new Text(runLine(run, theme, index), 0, 0));\n\tconst error = runErrorExcerpt(run);\n\tif (error) container.addChild(new IndentedText(theme.fg(\"error\", error), runErrorIndent(index)));\n}\n\n// Keep active work visible while a batch is in flight: completed runs\n// may otherwise crowd a still-running task out of the collapsed window.\nfunction selectCollapsedRuns(runs: SubagentRunDetails[], isPartial: boolean): SubagentRunDetails[] {\n\tif (runs.length <= COLLAPSED_RUN_LIMIT) return runs;\n\tif (!isPartial) return runs.slice(0, COLLAPSED_RUN_LIMIT);\n\tconst active = runs.filter((run) => run.status === \"running\" || run.status === \"queued\");\n\tconst retrying = active.filter((run) => getSubagentRetryView(run));\n\tconst retryingSet = new Set(retrying);\n\tconst otherActive = active.filter((run) => !retryingSet.has(run));\n\tconst settled = runs.filter((run) => run.status !== \"running\" && run.status !== \"queued\");\n\treturn [...retrying, ...otherActive, ...settled].slice(0, COLLAPSED_RUN_LIMIT);\n}\n\nfunction singleCollapsedLines(details: SubagentDetails, theme: Theme): string[] {\n\tconst run = details.runs[0];\n\tif (!run) return [theme.fg(\"muted\", \"Initializing…\")];\n\tif (run.status === \"running\" || run.status === \"queued\") {\n\t\tconst retry = retryText(run);\n\t\tconst isInitializing =\n\t\t\trun.status === \"running\" &&\n\t\t\t!retry &&\n\t\t\trun.usage.turns === 0 &&\n\t\t\trun.usage.toolUses === 0 &&\n\t\t\trun.liveText.length === 0;\n\t\tconst rawIntent =\n\t\t\tretry ??\n\t\t\t(run.status === \"queued\"\n\t\t\t\t? (run.currentActivity ?? statusWord(run.status))\n\t\t\t\t: isInitializing\n\t\t\t\t\t? \"Initializing…\"\n\t\t\t\t\t: runIntent(run));\n\t\tconst intent = excerpt(rawIntent, LIVE_TAIL_LIMIT);\n\t\t// No status marker here: the shell's call-level dot already covers\n\t\t// the whole card, and a single run has nothing to disambiguate.\n\t\tlet status = theme.fg(\"dim\", intent);\n\t\tif (run.status === \"running\" && !isInitializing) {\n\t\t\tstatus += theme.fg(\"dim\", ` · ${runProgressText(run)}`);\n\t\t\tif (run.usage.cost) status += theme.fg(\"dim\", ` · $${run.usage.cost.toFixed(3)}`);\n\t\t\tconst elapsed = liveElapsed(run);\n\t\t\tif (elapsed) status += theme.fg(\"dim\", ` · ${elapsed}`);\n\t\t}\n\t\tconst lines = [status];\n\t\tconst evidence = runEvidence(run);\n\t\tif (evidence && evidence !== rawIntent)\n\t\t\tlines.push(`${theme.fg(\"accent\", \"›\")} ${theme.fg(\"dim\", excerpt(evidence, LIVE_TAIL_LIMIT))}`);\n\t\tconst tail = liveTail(run);\n\t\tif (tail) lines.push(theme.fg(\"dim\", tail));\n\t\treturn lines;\n\t}\n\tif (run.error) return [theme.fg(\"error\", excerpt(run.error, SINGLE_EXCERPT_LIMIT))];\n\tif (run.finalOutput) return [theme.fg(\"toolOutput\", leadingSentences(run.finalOutput, SINGLE_EXCERPT_LIMIT))];\n\treturn [theme.fg(\"muted\", statusWord(run.status))];\n}\n\n// Deep-trimmed settled footer: turns and per-run breakdowns belong to the\n// expanded view. Parallel batches keep only whole-call numbers — the run\n// rows above already localize the work.\nfunction collapsedUsageText(details: SubagentDetails, extended: boolean): string {\n\tconst usage = details.usage;\n\tconst items: string[] = [];\n\tif (usage.totalTokens) items.push(`${formatTokens(usage.totalTokens)} tok`);\n\tif (extended && usage.toolUses) items.push(`${usage.toolUses} tool use${usage.toolUses === 1 ? \"\" : \"s\"}`);\n\tif (extended && usage.contextTokens) items.push(`ctx: ${formatTokens(usage.contextTokens)}`);\n\tif (usage.cost) items.push(`$${usage.cost.toFixed(3)}`);\n\tif (details.endedAt !== undefined) {\n\t\titems.push(formatDuration(Math.max(0, (details.endedAt - details.startedAt) / 1000)));\n\t}\n\treturn items.join(\" · \");\n}\n\nfunction batchUsageText(details: SubagentDetails, isPartial: boolean): string {\n\tconst usage = details.usage;\n\tconst items: string[] = [];\n\t// The aggregate mixes settled and running runs while partial, and the\n\t// running share is cache-inflated — quote the total only once settled.\n\tif (!isPartial && usage.totalTokens) items.push(`${formatTokens(usage.totalTokens)} tok`);\n\tif (usage.toolUses) items.push(`${usage.toolUses} tool use${usage.toolUses === 1 ? \"\" : \"s\"}`);\n\tif (usage.turns) items.push(`${usage.turns} turn${usage.turns === 1 ? \"\" : \"s\"}`);\n\tif (usage.contextTokens) items.push(`ctx: ${formatTokens(usage.contextTokens)}`);\n\tif (usage.cost) items.push(`$${usage.cost.toFixed(3)}`);\n\tif (details.endedAt !== undefined) {\n\t\titems.push(formatDuration(Math.max(0, (details.endedAt - details.startedAt) / 1000)));\n\t}\n\treturn items.join(\" · \");\n}\n\nfunction formatTokens(value: number): string {\n\tif (value < 1_000) return String(value);\n\tif (value < 1_000_000) return `${(value / 1_000).toFixed(value < 10_000 ? 1 : 0)}k`;\n\treturn `${(value / 1_000_000).toFixed(1)}M`;\n}\n\nfunction formatDuration(seconds: number): string {\n\tconst roundedSeconds = Math.round(seconds);\n\tif (roundedSeconds >= 60) return `${Math.floor(roundedSeconds / 60)}m ${roundedSeconds % 60}s`;\n\treturn `${seconds.toFixed(seconds < 10 ? 1 : 0)}s`;\n}\n\nfunction runDurationText(run: SubagentRunDetails): string | undefined {\n\tif (run.startedAt === undefined || run.endedAt === undefined) return undefined;\n\treturn formatDuration(Math.max(0, (run.endedAt - run.startedAt) / 1000));\n}\n\n// One dim line per run: what it cost. Settled runs quote the real token\n// total; running runs skip it (cache-inflated mid-run) and tick elapsed\n// time instead. Batch sections fold model/thinking/cwd in here because\n// their `──` header already carries verdict and duration.\nfunction runMetricsText(run: SubagentRunDetails, includeIdentity: boolean): string {\n\tconst usage = run.usage;\n\tconst settled = run.status !== \"running\" && run.status !== \"queued\";\n\tconst items: string[] = [];\n\tif (includeIdentity) {\n\t\titems.push(run.model);\n\t\tif (run.thinking !== \"off\") items.push(run.thinking);\n\t\tif (run.cwd) items.push(`cwd: ${run.cwd}`);\n\t}\n\tif (settled && usage.totalTokens) items.push(`${formatTokens(usage.totalTokens)} tok`);\n\tif (usage.toolUses) items.push(`${usage.toolUses} tool use${usage.toolUses === 1 ? \"\" : \"s\"}`);\n\tif (usage.turns) items.push(`${usage.turns} turn${usage.turns === 1 ? \"\" : \"s\"}`);\n\tif (usage.contextTokens) items.push(`ctx: ${formatTokens(usage.contextTokens)}`);\n\tif (usage.cost) items.push(`$${usage.cost.toFixed(3)}`);\n\tconst duration = settled ? (includeIdentity ? undefined : runDurationText(run)) : liveElapsed(run);\n\tif (duration) items.push(duration);\n\treturn items.join(\" · \");\n}\n\n// The details prompt is a 1KB bounded copy of the briefing; the preview\n// shows the first content lines (blank lines carry nothing at two lines\n// of budget) and never pretends to more fidelity than that.\nfunction promptSection(run: SubagentRunDetails, theme: Theme): string[] {\n\tconst boundedPrompt = terminalOutputNotice(run.prompt);\n\tconst lines = boundedPrompt.text\n\t\t.split(\"\\n\")\n\t\t.map((line) => plainExcerpt(line.trim(), Number.MAX_SAFE_INTEGER))\n\t\t.filter(Boolean);\n\tconst shown = lines.slice(0, PROMPT_PREVIEW_LINES);\n\tconst preview = shown.map((line) => theme.fg(\"dim\", truncate(line, PROMPT_PREVIEW_LINE_LIMIT)));\n\t// A one-line briefing clipped mid-sentence must still say it continues.\n\tconst clipped = shown.some((line) => line.length > PROMPT_PREVIEW_LINE_LIMIT);\n\tconst remaining = lines.length - shown.length;\n\tconst capped = boundedPrompt.truncated;\n\tconst section = [theme.fg(\"muted\", \"Prompt\"), ...preview];\n\tif (remaining > 0 || capped || clipped) {\n\t\tlet note = \"… continues\";\n\t\tif (remaining > 0) note += `, ${remaining} more line${remaining === 1 ? \"\" : \"s\"}`;\n\t\tif (capped) note += \" · capped at 1KB\";\n\t\tsection.push(theme.fg(\"muted\", note));\n\t}\n\treturn section;\n}\n\n// Each run expands into a report cover sheet: verdict and cost up top, a\n// bounded Prompt/Activity digest in the middle, then the full Report —\n// the one unbounded element, placed last so the card ends where reading\n// begins. Single runs skip the `──` header (the call header already names\n// them); batch sections carry a numbered header matching the contents\n// list above.\nfunction renderRunDetails(run: SubagentRunDetails, theme: Theme, single: boolean, index?: number): Component {\n\tconst container = new Container();\n\tconst settled = run.status !== \"running\" && run.status !== \"queued\";\n\tif (single) {\n\t\tconst identity = [run.model];\n\t\tif (run.thinking !== \"off\") identity.push(`${run.thinking} thinking`);\n\t\tif (run.cwd) identity.push(`cwd: ${run.cwd}`);\n\t\tcontainer.addChild(\n\t\t\tnew Text(\n\t\t\t\t`${statusMarker(run.status, theme)} ${theme.fg(statusColor(run.status), statusWord(run.status))}${theme.fg(\"dim\", ` · ${identity.join(\" · \")}`)}`,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t} else {\n\t\tconst label = index === undefined ? \"\" : `${index} · `;\n\t\tconst duration = settled ? runDurationText(run) : undefined;\n\t\tcontainer.addChild(\n\t\t\tnew Text(\n\t\t\t\t`${theme.fg(\"dim\", `── ${label}`)}${statusMarker(run.status, theme)} ${theme.fg(\"accent\", displayAgentName(run.agent))}${theme.fg(\"dim\", ` · ${truncate(run.description, 48)}`)}${duration ? theme.fg(\"dim\", ` · ${duration}`) : \"\"}`,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t),\n\t\t);\n\t}\n\tif (run.status !== \"queued\") {\n\t\tconst metrics = runMetricsText(run, !single);\n\t\tif (metrics) container.addChild(new Text(theme.fg(\"dim\", metrics), 0, 0));\n\t}\n\tconst retry = retryText(run);\n\tif (retry) container.addChild(new Text(theme.fg(\"accent\", retry), 0, 0));\n\tcontainer.addChild(new Spacer(1));\n\tfor (const line of promptSection(run, theme)) container.addChild(new Text(line, 0, 0));\n\tif (run.activities.length > 0) {\n\t\tcontainer.addChild(new Spacer(1));\n\t\tconst total = run.usage.toolUses;\n\t\tconst label = total > run.activities.length ? `Activity · last ${run.activities.length} of ${total}` : \"Activity\";\n\t\tcontainer.addChild(new Text(theme.fg(\"muted\", label), 0, 0));\n\t\tfor (const activity of run.activities) {\n\t\t\t// Deviation earns ink: × and › are marked, success rows are quiet\n\t\t\t// one-liners without result echoes.\n\t\t\tlet text: string;\n\t\t\tif (activity.status === \"failed\") {\n\t\t\t\ttext = `${theme.fg(\"error\", \"×\")} ${theme.fg(\"toolOutput\", excerpt(activity.summary, ACTIVITY_SUMMARY_LIMIT))}`;\n\t\t\t\tif (activity.resultSummary) {\n\t\t\t\t\ttext += ` ${theme.fg(\"error\", `· ${excerpt(activity.resultSummary, ACTIVITY_RESULT_LIMIT)}`)}`;\n\t\t\t\t}\n\t\t\t} else if (activity.status === \"running\") {\n\t\t\t\ttext = `${theme.fg(\"accent\", \"›\")} ${theme.fg(\"toolOutput\", excerpt(activity.summary, ACTIVITY_SUMMARY_LIMIT))}`;\n\t\t\t} else {\n\t\t\t\ttext = ` ${theme.fg(\"toolOutput\", excerpt(activity.summary, ACTIVITY_SUMMARY_LIMIT))}`;\n\t\t\t}\n\t\t\tif (activity.endedAt !== undefined && activity.endedAt - activity.startedAt >= ACTIVITY_DURATION_MIN_MS) {\n\t\t\t\ttext += ` ${theme.fg(\"dim\", `· ${formatDuration((activity.endedAt - activity.startedAt) / 1000)}`)}`;\n\t\t\t}\n\t\t\tcontainer.addChild(new Text(text, 0, 0));\n\t\t}\n\t}\n\t// The live tail is the \"now\" end of the timeline; once the run settles,\n\t// Report takes this slot without moving anything above it.\n\tif (run.status === \"running\" && run.liveText) {\n\t\tconst tail = liveTailLines(run).slice(-EXPANDED_LIVE_TAIL_LINES);\n\t\tif (tail.length > 0) {\n\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"Working\"), 0, 0));\n\t\t\tfor (const line of tail) {\n\t\t\t\tcontainer.addChild(new Text(theme.fg(\"dim\", excerpt(line, LIVE_TAIL_LIMIT)), 0, 0));\n\t\t\t}\n\t\t}\n\t}\n\tif (run.error) {\n\t\tcontainer.addChild(new Spacer(1));\n\t\tcontainer.addChild(new Text(theme.fg(\"muted\", \"Error\"), 0, 0));\n\t\tcontainer.addChild(new Text(theme.fg(\"error\", run.error), 0, 0));\n\t}\n\tif (run.finalOutput) {\n\t\tcontainer.addChild(new Spacer(1));\n\t\tconst label = settled && run.status !== \"completed\" ? \"Report · partial\" : \"Report\";\n\t\tcontainer.addChild(new Text(theme.fg(\"muted\", label), 0, 0));\n\t\tcontainer.addChild(\n\t\t\tnew Markdown(run.finalOutput, 0, 0, getMarkdownTheme(), {\n\t\t\t\tcolor: (text) => theme.fg(\"toolOutput\", text),\n\t\t\t}),\n\t\t);\n\t}\n\treturn container;\n}\n\n// The call header stays a single line: run rows in the result area take\n// over within the first update and carry richer per-task state, so a\n// task list here would render everything twice. The task count alone\n// distinguishes a batch from a single delegation.\nexport function renderSubagentCall(args: SubagentParams, theme: Theme): Component {\n\tconst modes = [args.prompt != null && \"prompt\", args.tasks != null && \"tasks\"].filter((mode): mode is string =>\n\t\tBoolean(mode),\n\t);\n\tif (modes.length > 1) {\n\t\treturn new Text(\n\t\t\t`${theme.fg(\"toolTitle\", theme.bold(\"Subagent \"))}${theme.fg(\"error\", `invalid · ${modes.join(\" + \")}`)}`,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t}\n\tif (args.tasks) {\n\t\treturn new Text(\n\t\t\t`${theme.fg(\"toolTitle\", theme.bold(\"Multi-Agent\"))}${theme.fg(\"dim\", ` · ${args.tasks.length} task${args.tasks.length === 1 ? \"\" : \"s\"}`)}`,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t}\n\tlet text = theme.fg(\"toolTitle\", theme.bold(`${singleAgentName(args)} Agent`));\n\tif (args.description) text += theme.fg(\"dim\", ` · ${truncate(args.description, 72)}`);\n\treturn new Text(text, 0, 0);\n}\n\nexport function renderSubagentResult(\n\tresult: AgentToolResult<SubagentDetails>,\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n\tisError: boolean,\n): Component {\n\tconst details = result.details;\n\tif (!details) {\n\t\tconst text = result.content.find((part) => part.type === \"text\");\n\t\treturn new Text(text?.type === \"text\" ? text.text : \"(no output)\", 0, 0);\n\t}\n\t// The pre-resolution first paint carries no runs yet, in either mode.\n\tif (details.runs.length === 0) {\n\t\treturn new Text(theme.fg(\"muted\", \"Initializing…\"), 0, 0);\n\t}\n\tif (!options.expanded) {\n\t\tif (details.mode === \"single\") {\n\t\t\tconst lines = singleCollapsedLines(details, theme);\n\t\t\tif (!options.isPartial) {\n\t\t\t\tconst usage = collapsedUsageText(details, true);\n\t\t\t\tif (usage) lines.push(theme.fg(\"dim\", usage));\n\t\t\t\tlines.push(theme.fg(\"muted\", `(${keyHint(\"app.tools.expand\", \"to expand\")})`));\n\t\t\t}\n\t\t\treturn new Text(lines.join(\"\\n\"), 0, 0);\n\t\t}\n\n\t\tconst container = new Container();\n\t\tlet header = statusSummary(details);\n\t\tif (options.isPartial) {\n\t\t\theader += ` · ${formatDuration(Math.max(0, (Date.now() - details.startedAt) / 1000))}`;\n\t\t}\n\t\tcontainer.addChild(new Text(theme.fg(isError ? \"error\" : options.isPartial ? \"accent\" : \"muted\", header), 0, 0));\n\t\tconst shown = selectCollapsedRuns(details.runs, Boolean(options.isPartial));\n\t\t// Stable ordinals (the run's task position, not its display slot)\n\t\t// keep identity readable while active-first ordering reshuffles\n\t\t// rows, and match the expanded section numbers.\n\t\tfor (const run of shown) addRunSummary(container, run, theme, details.runs.indexOf(run) + 1);\n\t\tconst hidden = details.runs.length - shown.length;\n\t\tif (hidden > 0) container.addChild(new Text(theme.fg(\"muted\", `+${hidden} more`), 0, 0));\n\t\tif (!options.isPartial) {\n\t\t\tconst usage = collapsedUsageText(details, false);\n\t\t\tif (usage) container.addChild(new Text(theme.fg(\"dim\", usage), 0, 0));\n\t\t\tcontainer.addChild(new Text(theme.fg(\"muted\", `(${keyHint(\"app.tools.expand\", \"to expand\")})`), 0, 0));\n\t\t}\n\t\treturn container;\n\t}\n\tconst container = new Container();\n\tconst single = details.mode === \"single\" && details.runs.length === 1;\n\tif (!single) {\n\t\tcontainer.addChild(new Text(theme.fg(isError ? \"error\" : \"toolTitle\", statusSummary(details)), 0, 0));\n\t\t// Numbered table of contents: the TUI cannot jump, but matching the\n\t\t// numbers against the `──` section headers below makes an 8-run\n\t\t// batch navigable by eye.\n\t\tdetails.runs.forEach((run, index) => {\n\t\t\taddRunSummary(container, run, theme, index + 1);\n\t\t});\n\t}\n\tdetails.runs.forEach((run, index) => {\n\t\tif (!single || index > 0) container.addChild(new Spacer(1));\n\t\tcontainer.addChild(renderRunDetails(run, theme, single, single ? undefined : index + 1));\n\t});\n\tif (!single) {\n\t\tconst usage = batchUsageText(details, Boolean(options.isPartial));\n\t\tif (usage) {\n\t\t\tcontainer.addChild(new Spacer(1));\n\t\t\tcontainer.addChild(new Text(theme.fg(\"dim\", usage), 0, 0));\n\t\t}\n\t}\n\treturn container;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/resolve.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,KAAK,GAAG,EAAsB,KAAK,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAExF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,kBAAkB,EAA2B,MAAM,YAAY,CAAC;AAErH,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,aAAa,CAAC;IACxB,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,GAAG,mBAAmB,CAAC,CAAC;CAClF;AAoBD,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/resolve.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,KAAK,GAAG,EAAsB,KAAK,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAExF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,eAAe,EAAE,oBAAoB,EAAE,kBAAkB,EAA2B,MAAM,YAAY,CAAC;AAErH,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IAC9B,QAAQ,EAAE,aAAa,CAAC;IACxB,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,GAAG,mBAAmB,CAAC,CAAC;CAClF;AAoBD,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAqB1F;AAwCD,wBAAsB,mBAAmB,CACxC,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,MAAM,EAAE,kBAAkB,EAC1B,cAAc,SAAgB,EAC9B,eAAe,CAAC,EAAE,kBAAkB,GAClC,OAAO,CAAC,oBAAoB,CAAC,CAqB/B","sourcesContent":["import { existsSync, realpathSync, statSync } from \"node:fs\";\nimport { isAbsolute, relative, resolve } from \"node:path\";\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport { type Api, clampThinkingLevel, type Model } from \"@earendil-works/pi-ai/compat\";\nimport { getAgentDir } from \"../../config.ts\";\nimport type { ModelRegistry } from \"../../core/model-registry.ts\";\nimport type { SubagentTask } from \"./schema.ts\";\nimport { loadSubagentConfig } from \"./settings.ts\";\nimport type { AgentDefinition, ResolvedSubagentTask, SubagentConfigFile, SubagentProfileOverride } from \"./types.ts\";\n\nexport interface ParentModelContext {\n\tmodel: Model<Api> | undefined;\n\tthinking: ThinkingLevel;\n\tmodelRegistry: Pick<ModelRegistry, \"find\" | \"getAvailable\" | \"hasConfiguredAuth\">;\n}\n\nfunction normalizeCwdInput(value: string | undefined): string | undefined {\n\tif (value === undefined) return undefined;\n\tconst trimmed = value.trim();\n\tif (!trimmed) throw new Error(\"cwd must not be empty.\");\n\treturn trimmed.startsWith(\"@\") ? trimmed.slice(1) : trimmed;\n}\n\nfunction isWithin(parent: string, child: string): boolean {\n\tconst normalizedParent = process.platform === \"win32\" ? parent.toLowerCase() : parent;\n\tconst normalizedChild = process.platform === \"win32\" ? child.toLowerCase() : child;\n\tconst rest = relative(normalizedParent, normalizedChild);\n\treturn rest === \"\" || (rest !== \"..\" && !rest.startsWith(`..${requirePathSeparator()}`) && !isAbsolute(rest));\n}\n\nfunction requirePathSeparator(): string {\n\treturn process.platform === \"win32\" ? \"\\\\\" : \"/\";\n}\n\nexport function resolveTaskCwd(parentCwd: string, requestedCwd: string | undefined): string {\n\tconst value = normalizeCwdInput(requestedCwd);\n\t// Models routinely echo the parent working directory back as an absolute\n\t// path; accept an absolute cwd that stays inside the parent instead of\n\t// failing the whole task over path style.\n\tconst absolute = value !== undefined && isAbsolute(value);\n\tconst candidate = absolute ? resolve(value) : resolve(parentCwd, value ?? \".\");\n\t// Relative inputs get a lexical traversal check before touching the file\n\t// system. Absolute inputs may use the real spelling of a symlinked parent,\n\t// so their containment is decided by the canonical check below.\n\tif (!absolute && !isWithin(resolve(parentCwd), candidate))\n\t\tthrow new Error(`Subagent cwd escapes the parent working directory: ${requestedCwd}`);\n\tif (!existsSync(candidate) || !statSync(candidate).isDirectory())\n\t\tthrow new Error(`Subagent cwd is not a directory: ${candidate}`);\n\tconst realParent = realpathSync(parentCwd);\n\tconst realCandidate = realpathSync(candidate);\n\tif (!isWithin(realParent, realCandidate)) {\n\t\tif (absolute) throw new Error(\"cwd must stay inside the parent working directory.\");\n\t\tthrow new Error(`Subagent cwd escapes the parent working directory: ${requestedCwd}`);\n\t}\n\treturn realCandidate;\n}\n\nfunction findAvailableModel(spec: string, parent: ParentModelContext): Model<Api> {\n\tconst normalized = spec.trim();\n\tlet model: Model<Api> | undefined;\n\tif (normalized.includes(\"/\")) {\n\t\tconst separator = normalized.indexOf(\"/\");\n\t\tmodel = parent.modelRegistry.find(normalized.slice(0, separator), normalized.slice(separator + 1));\n\t} else {\n\t\tconst matches = parent.modelRegistry.getAvailable().filter((candidate) => candidate.id === normalized);\n\t\tif (matches.length === 1) model = matches[0];\n\t\tif (matches.length > 1) throw new Error(`Model id \"${normalized}\" is ambiguous; use provider/model.`);\n\t}\n\tif (!model) throw new Error(`Model \"${normalized}\" is not available.`);\n\tif (!parent.modelRegistry.hasConfiguredAuth(model))\n\t\tthrow new Error(`Model \"${normalized}\" has no configured authentication.`);\n\treturn model;\n}\n\n// Exactly two layers: a /agents override wins, otherwise the subagent\n// inherits the parent session. Callers and agent files cannot pick models.\nfunction resolveModel(\n\toverride: SubagentProfileOverride | undefined,\n\tparent: ParentModelContext,\n): { model: Model<Api>; source: ResolvedSubagentTask[\"modelSource\"] } {\n\tif (override?.model) return { model: findAvailableModel(override.model, parent), source: \"profile\" };\n\tif (!parent.model) throw new Error(\"The parent session has no active model.\");\n\treturn { model: parent.model, source: \"parent\" };\n}\n\nfunction resolveThinking(\n\toverride: SubagentProfileOverride | undefined,\n\tparent: ParentModelContext,\n\tmodel: Model<Api>,\n): { thinking: ThinkingLevel; source: ResolvedSubagentTask[\"thinkingSource\"] } {\n\tconst requested = override?.thinking ?? parent.thinking;\n\tconst source: ResolvedSubagentTask[\"thinkingSource\"] = override?.thinking ? \"profile\" : \"parent\";\n\treturn { thinking: clampThinkingLevel(model, requested) as ThinkingLevel, source };\n}\n\nexport async function resolveSubagentTask(\n\ttask: SubagentTask,\n\tparentCwd: string,\n\tagents: readonly AgentDefinition[],\n\tparent: ParentModelContext,\n\tconfigAgentDir = getAgentDir(),\n\tpreloadedConfig?: SubagentConfigFile,\n): Promise<ResolvedSubagentTask> {\n\tconst agentName = task.agent ?? \"general\";\n\tconst agent = agents.find((candidate) => candidate.name === agentName);\n\tif (!agent) {\n\t\tconst available = agents.map((candidate) => candidate.name).join(\", \") || \"none\";\n\t\tthrow new Error(`Unknown agent \"${agentName}\". Available agents: ${available}.`);\n\t}\n\tconst config = preloadedConfig ?? (await loadSubagentConfig(configAgentDir));\n\tconst override = config.profiles[agent.name];\n\tconst resolvedModel = resolveModel(override, parent);\n\tconst resolvedThinking = resolveThinking(override, parent, resolvedModel.model);\n\treturn {\n\t\tagent,\n\t\tdescription: task.description,\n\t\tprompt: task.prompt,\n\t\tcwd: resolveTaskCwd(parentCwd, task.cwd ?? undefined),\n\t\tmodel: resolvedModel.model,\n\t\tthinking: resolvedThinking.thinking,\n\t\tmodelSource: resolvedModel.source,\n\t\tthinkingSource: resolvedThinking.source,\n\t};\n}\n"]}
|
|
@@ -22,21 +22,25 @@ function requirePathSeparator() {
|
|
|
22
22
|
}
|
|
23
23
|
export function resolveTaskCwd(parentCwd, requestedCwd) {
|
|
24
24
|
const value = normalizeCwdInput(requestedCwd);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
|
|
25
|
+
// Models routinely echo the parent working directory back as an absolute
|
|
26
|
+
// path; accept an absolute cwd that stays inside the parent instead of
|
|
27
|
+
// failing the whole task over path style.
|
|
28
|
+
const absolute = value !== undefined && isAbsolute(value);
|
|
29
|
+
const candidate = absolute ? resolve(value) : resolve(parentCwd, value ?? ".");
|
|
30
|
+
// Relative inputs get a lexical traversal check before touching the file
|
|
31
|
+
// system. Absolute inputs may use the real spelling of a symlinked parent,
|
|
32
|
+
// so their containment is decided by the canonical check below.
|
|
33
|
+
if (!absolute && !isWithin(resolve(parentCwd), candidate))
|
|
33
34
|
throw new Error(`Subagent cwd escapes the parent working directory: ${requestedCwd}`);
|
|
34
35
|
if (!existsSync(candidate) || !statSync(candidate).isDirectory())
|
|
35
36
|
throw new Error(`Subagent cwd is not a directory: ${candidate}`);
|
|
36
37
|
const realParent = realpathSync(parentCwd);
|
|
37
38
|
const realCandidate = realpathSync(candidate);
|
|
38
|
-
if (!isWithin(realParent, realCandidate))
|
|
39
|
+
if (!isWithin(realParent, realCandidate)) {
|
|
40
|
+
if (absolute)
|
|
41
|
+
throw new Error("cwd must stay inside the parent working directory.");
|
|
39
42
|
throw new Error(`Subagent cwd escapes the parent working directory: ${requestedCwd}`);
|
|
43
|
+
}
|
|
40
44
|
return realCandidate;
|
|
41
45
|
}
|
|
42
46
|
function findAvailableModel(spec, parent) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/extensions/subagent/resolve.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, realpathSync, statSync } from \"node:fs\";\nimport { isAbsolute, relative, resolve } from \"node:path\";\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport { type Api, clampThinkingLevel, type Model } from \"@earendil-works/pi-ai/compat\";\nimport { getAgentDir } from \"../../config.ts\";\nimport type { ModelRegistry } from \"../../core/model-registry.ts\";\nimport type { SubagentTask } from \"./schema.ts\";\nimport { loadSubagentConfig } from \"./settings.ts\";\nimport type { AgentDefinition, ResolvedSubagentTask, SubagentConfigFile, SubagentProfileOverride } from \"./types.ts\";\n\nexport interface ParentModelContext {\n\tmodel: Model<Api> | undefined;\n\tthinking: ThinkingLevel;\n\tmodelRegistry: Pick<ModelRegistry, \"find\" | \"getAvailable\" | \"hasConfiguredAuth\">;\n}\n\nfunction normalizeCwdInput(value: string | undefined): string | undefined {\n\tif (value === undefined) return undefined;\n\tconst trimmed = value.trim();\n\tif (!trimmed) throw new Error(\"cwd must not be empty.\");\n\treturn trimmed.startsWith(\"@\") ? trimmed.slice(1) : trimmed;\n}\n\nfunction isWithin(parent: string, child: string): boolean {\n\tconst normalizedParent = process.platform === \"win32\" ? parent.toLowerCase() : parent;\n\tconst normalizedChild = process.platform === \"win32\" ? child.toLowerCase() : child;\n\tconst rest = relative(normalizedParent, normalizedChild);\n\treturn rest === \"\" || (rest !== \"..\" && !rest.startsWith(`..${requirePathSeparator()}`) && !isAbsolute(rest));\n}\n\nfunction requirePathSeparator(): string {\n\treturn process.platform === \"win32\" ? \"\\\\\" : \"/\";\n}\n\nexport function resolveTaskCwd(parentCwd: string, requestedCwd: string | undefined): string {\n\tconst value = normalizeCwdInput(requestedCwd);\n\tif (value !== undefined && isAbsolute(value))\n\t\tthrow new Error(\"cwd must be a relative path inside the parent working directory.\");\n\tconst candidate = resolve(parentCwd, value ?? \".\");\n\t// Lexical check first: candidate and parent are both un-realpathed here,\n\t// so a symlinked parent (macOS /tmp, junctions) compares consistently and\n\t// only genuine \"..\" traversal fails. Symlink escapes are caught below by\n\t// comparing the realpathed candidate against the realpathed parent.\n\tif (!isWithin(resolve(parentCwd), candidate))\n\t\tthrow new Error(`Subagent cwd escapes the parent working directory: ${requestedCwd}`);\n\tif (!existsSync(candidate) || !statSync(candidate).isDirectory())\n\t\tthrow new Error(`Subagent cwd is not a directory: ${candidate}`);\n\tconst realParent = realpathSync(parentCwd);\n\tconst realCandidate = realpathSync(candidate);\n\tif (!isWithin(realParent, realCandidate))\n\t\tthrow new Error(`Subagent cwd escapes the parent working directory: ${requestedCwd}`);\n\treturn realCandidate;\n}\n\nfunction findAvailableModel(spec: string, parent: ParentModelContext): Model<Api> {\n\tconst normalized = spec.trim();\n\tlet model: Model<Api> | undefined;\n\tif (normalized.includes(\"/\")) {\n\t\tconst separator = normalized.indexOf(\"/\");\n\t\tmodel = parent.modelRegistry.find(normalized.slice(0, separator), normalized.slice(separator + 1));\n\t} else {\n\t\tconst matches = parent.modelRegistry.getAvailable().filter((candidate) => candidate.id === normalized);\n\t\tif (matches.length === 1) model = matches[0];\n\t\tif (matches.length > 1) throw new Error(`Model id \"${normalized}\" is ambiguous; use provider/model.`);\n\t}\n\tif (!model) throw new Error(`Model \"${normalized}\" is not available.`);\n\tif (!parent.modelRegistry.hasConfiguredAuth(model))\n\t\tthrow new Error(`Model \"${normalized}\" has no configured authentication.`);\n\treturn model;\n}\n\n// Exactly two layers: a /agents override wins, otherwise the subagent\n// inherits the parent session. Callers and agent files cannot pick models.\nfunction resolveModel(\n\toverride: SubagentProfileOverride | undefined,\n\tparent: ParentModelContext,\n): { model: Model<Api>; source: ResolvedSubagentTask[\"modelSource\"] } {\n\tif (override?.model) return { model: findAvailableModel(override.model, parent), source: \"profile\" };\n\tif (!parent.model) throw new Error(\"The parent session has no active model.\");\n\treturn { model: parent.model, source: \"parent\" };\n}\n\nfunction resolveThinking(\n\toverride: SubagentProfileOverride | undefined,\n\tparent: ParentModelContext,\n\tmodel: Model<Api>,\n): { thinking: ThinkingLevel; source: ResolvedSubagentTask[\"thinkingSource\"] } {\n\tconst requested = override?.thinking ?? parent.thinking;\n\tconst source: ResolvedSubagentTask[\"thinkingSource\"] = override?.thinking ? \"profile\" : \"parent\";\n\treturn { thinking: clampThinkingLevel(model, requested) as ThinkingLevel, source };\n}\n\nexport async function resolveSubagentTask(\n\ttask: SubagentTask,\n\tparentCwd: string,\n\tagents: readonly AgentDefinition[],\n\tparent: ParentModelContext,\n\tconfigAgentDir = getAgentDir(),\n\tpreloadedConfig?: SubagentConfigFile,\n): Promise<ResolvedSubagentTask> {\n\tconst agentName = task.agent ?? \"general\";\n\tconst agent = agents.find((candidate) => candidate.name === agentName);\n\tif (!agent) {\n\t\tconst available = agents.map((candidate) => candidate.name).join(\", \") || \"none\";\n\t\tthrow new Error(`Unknown agent \"${agentName}\". Available agents: ${available}.`);\n\t}\n\tconst config = preloadedConfig ?? (await loadSubagentConfig(configAgentDir));\n\tconst override = config.profiles[agent.name];\n\tconst resolvedModel = resolveModel(override, parent);\n\tconst resolvedThinking = resolveThinking(override, parent, resolvedModel.model);\n\treturn {\n\t\tagent,\n\t\tdescription: task.description,\n\t\tprompt: task.prompt,\n\t\tcwd: resolveTaskCwd(parentCwd, task.cwd ?? undefined),\n\t\tmodel: resolvedModel.model,\n\t\tthinking: resolvedThinking.thinking,\n\t\tmodelSource: resolvedModel.source,\n\t\tthinkingSource: resolvedThinking.source,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/extensions/subagent/resolve.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, realpathSync, statSync } from \"node:fs\";\nimport { isAbsolute, relative, resolve } from \"node:path\";\nimport type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\nimport { type Api, clampThinkingLevel, type Model } from \"@earendil-works/pi-ai/compat\";\nimport { getAgentDir } from \"../../config.ts\";\nimport type { ModelRegistry } from \"../../core/model-registry.ts\";\nimport type { SubagentTask } from \"./schema.ts\";\nimport { loadSubagentConfig } from \"./settings.ts\";\nimport type { AgentDefinition, ResolvedSubagentTask, SubagentConfigFile, SubagentProfileOverride } from \"./types.ts\";\n\nexport interface ParentModelContext {\n\tmodel: Model<Api> | undefined;\n\tthinking: ThinkingLevel;\n\tmodelRegistry: Pick<ModelRegistry, \"find\" | \"getAvailable\" | \"hasConfiguredAuth\">;\n}\n\nfunction normalizeCwdInput(value: string | undefined): string | undefined {\n\tif (value === undefined) return undefined;\n\tconst trimmed = value.trim();\n\tif (!trimmed) throw new Error(\"cwd must not be empty.\");\n\treturn trimmed.startsWith(\"@\") ? trimmed.slice(1) : trimmed;\n}\n\nfunction isWithin(parent: string, child: string): boolean {\n\tconst normalizedParent = process.platform === \"win32\" ? parent.toLowerCase() : parent;\n\tconst normalizedChild = process.platform === \"win32\" ? child.toLowerCase() : child;\n\tconst rest = relative(normalizedParent, normalizedChild);\n\treturn rest === \"\" || (rest !== \"..\" && !rest.startsWith(`..${requirePathSeparator()}`) && !isAbsolute(rest));\n}\n\nfunction requirePathSeparator(): string {\n\treturn process.platform === \"win32\" ? \"\\\\\" : \"/\";\n}\n\nexport function resolveTaskCwd(parentCwd: string, requestedCwd: string | undefined): string {\n\tconst value = normalizeCwdInput(requestedCwd);\n\t// Models routinely echo the parent working directory back as an absolute\n\t// path; accept an absolute cwd that stays inside the parent instead of\n\t// failing the whole task over path style.\n\tconst absolute = value !== undefined && isAbsolute(value);\n\tconst candidate = absolute ? resolve(value) : resolve(parentCwd, value ?? \".\");\n\t// Relative inputs get a lexical traversal check before touching the file\n\t// system. Absolute inputs may use the real spelling of a symlinked parent,\n\t// so their containment is decided by the canonical check below.\n\tif (!absolute && !isWithin(resolve(parentCwd), candidate))\n\t\tthrow new Error(`Subagent cwd escapes the parent working directory: ${requestedCwd}`);\n\tif (!existsSync(candidate) || !statSync(candidate).isDirectory())\n\t\tthrow new Error(`Subagent cwd is not a directory: ${candidate}`);\n\tconst realParent = realpathSync(parentCwd);\n\tconst realCandidate = realpathSync(candidate);\n\tif (!isWithin(realParent, realCandidate)) {\n\t\tif (absolute) throw new Error(\"cwd must stay inside the parent working directory.\");\n\t\tthrow new Error(`Subagent cwd escapes the parent working directory: ${requestedCwd}`);\n\t}\n\treturn realCandidate;\n}\n\nfunction findAvailableModel(spec: string, parent: ParentModelContext): Model<Api> {\n\tconst normalized = spec.trim();\n\tlet model: Model<Api> | undefined;\n\tif (normalized.includes(\"/\")) {\n\t\tconst separator = normalized.indexOf(\"/\");\n\t\tmodel = parent.modelRegistry.find(normalized.slice(0, separator), normalized.slice(separator + 1));\n\t} else {\n\t\tconst matches = parent.modelRegistry.getAvailable().filter((candidate) => candidate.id === normalized);\n\t\tif (matches.length === 1) model = matches[0];\n\t\tif (matches.length > 1) throw new Error(`Model id \"${normalized}\" is ambiguous; use provider/model.`);\n\t}\n\tif (!model) throw new Error(`Model \"${normalized}\" is not available.`);\n\tif (!parent.modelRegistry.hasConfiguredAuth(model))\n\t\tthrow new Error(`Model \"${normalized}\" has no configured authentication.`);\n\treturn model;\n}\n\n// Exactly two layers: a /agents override wins, otherwise the subagent\n// inherits the parent session. Callers and agent files cannot pick models.\nfunction resolveModel(\n\toverride: SubagentProfileOverride | undefined,\n\tparent: ParentModelContext,\n): { model: Model<Api>; source: ResolvedSubagentTask[\"modelSource\"] } {\n\tif (override?.model) return { model: findAvailableModel(override.model, parent), source: \"profile\" };\n\tif (!parent.model) throw new Error(\"The parent session has no active model.\");\n\treturn { model: parent.model, source: \"parent\" };\n}\n\nfunction resolveThinking(\n\toverride: SubagentProfileOverride | undefined,\n\tparent: ParentModelContext,\n\tmodel: Model<Api>,\n): { thinking: ThinkingLevel; source: ResolvedSubagentTask[\"thinkingSource\"] } {\n\tconst requested = override?.thinking ?? parent.thinking;\n\tconst source: ResolvedSubagentTask[\"thinkingSource\"] = override?.thinking ? \"profile\" : \"parent\";\n\treturn { thinking: clampThinkingLevel(model, requested) as ThinkingLevel, source };\n}\n\nexport async function resolveSubagentTask(\n\ttask: SubagentTask,\n\tparentCwd: string,\n\tagents: readonly AgentDefinition[],\n\tparent: ParentModelContext,\n\tconfigAgentDir = getAgentDir(),\n\tpreloadedConfig?: SubagentConfigFile,\n): Promise<ResolvedSubagentTask> {\n\tconst agentName = task.agent ?? \"general\";\n\tconst agent = agents.find((candidate) => candidate.name === agentName);\n\tif (!agent) {\n\t\tconst available = agents.map((candidate) => candidate.name).join(\", \") || \"none\";\n\t\tthrow new Error(`Unknown agent \"${agentName}\". Available agents: ${available}.`);\n\t}\n\tconst config = preloadedConfig ?? (await loadSubagentConfig(configAgentDir));\n\tconst override = config.profiles[agent.name];\n\tconst resolvedModel = resolveModel(override, parent);\n\tconst resolvedThinking = resolveThinking(override, parent, resolvedModel.model);\n\treturn {\n\t\tagent,\n\t\tdescription: task.description,\n\t\tprompt: task.prompt,\n\t\tcwd: resolveTaskCwd(parentCwd, task.cwd ?? undefined),\n\t\tmodel: resolvedModel.model,\n\t\tthinking: resolvedThinking.thinking,\n\t\tmodelSource: resolvedModel.source,\n\t\tthinkingSource: resolvedThinking.source,\n\t};\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SubagentRunDetails } from "./types.ts";
|
|
2
|
+
export interface BeginSubagentRetryOptions {
|
|
3
|
+
attempt: number;
|
|
4
|
+
maxAttempts: number;
|
|
5
|
+
delayMs: number;
|
|
6
|
+
error: string;
|
|
7
|
+
}
|
|
8
|
+
export interface SubagentRetryView {
|
|
9
|
+
attempt: number;
|
|
10
|
+
maxAttempts: number;
|
|
11
|
+
remainingSeconds: number;
|
|
12
|
+
error: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function beginSubagentRetry(run: SubagentRunDetails, options: BeginSubagentRetryOptions): void;
|
|
15
|
+
export declare function clearSubagentRetry(run: SubagentRunDetails): void;
|
|
16
|
+
export declare function getSubagentRetryView(run: SubagentRunDetails, now?: number): SubagentRetryView | undefined;
|
|
17
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/retry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,WAAW,yBAAyB;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACd;AAWD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,EAAE,OAAO,EAAE,yBAAyB,GAAG,IAAI,CAWpG;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI,CAGhE;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,kBAAkB,EAAE,GAAG,SAAa,GAAG,iBAAiB,GAAG,SAAS,CAY7G","sourcesContent":["import { boundText } from \"./activity.ts\";\nimport { RETRY_ERROR_TEXT_LIMIT } from \"./constants.ts\";\nimport type { SubagentRunDetails } from \"./types.ts\";\n\nexport interface BeginSubagentRetryOptions {\n\tattempt: number;\n\tmaxAttempts: number;\n\tdelayMs: number;\n\terror: string;\n}\n\nexport interface SubagentRetryView {\n\tattempt: number;\n\tmaxAttempts: number;\n\tremainingSeconds: number;\n\terror: string;\n}\n\nfunction positiveInteger(value: number, fallback: number): number {\n\treturn Number.isFinite(value) ? Math.max(1, Math.floor(value)) : fallback;\n}\n\nfunction retryError(error: string): string {\n\tconst normalized = error.replace(/\\s+/gu, \" \").trim();\n\treturn boundText(normalized, RETRY_ERROR_TEXT_LIMIT).replace(/\\s+/gu, \" \").trim();\n}\n\nexport function beginSubagentRetry(run: SubagentRunDetails, options: BeginSubagentRetryOptions): void {\n\tconst attempt = positiveInteger(options.attempt, 1);\n\tconst maxAttempts = Math.max(attempt, positiveInteger(options.maxAttempts, attempt));\n\tconst delayMs = Number.isFinite(options.delayMs) ? Math.max(0, options.delayMs) : 0;\n\trun.retry = {\n\t\tattempt,\n\t\tmaxAttempts,\n\t\tdeadline: Date.now() + delayMs,\n\t\terror: retryError(options.error),\n\t};\n\trun.currentActivity = `Retrying (${attempt}/${maxAttempts})…`;\n}\n\nexport function clearSubagentRetry(run: SubagentRunDetails): void {\n\trun.retry = undefined;\n\tif (run.currentActivity?.startsWith(\"Retrying\")) run.currentActivity = undefined;\n}\n\nexport function getSubagentRetryView(run: SubagentRunDetails, now = Date.now()): SubagentRetryView | undefined {\n\tconst retry = run.retry;\n\tif (!retry || !Number.isFinite(retry.deadline)) return undefined;\n\tconst attempt = positiveInteger(retry.attempt, 1);\n\tconst maxAttempts = Math.max(attempt, positiveInteger(retry.maxAttempts, attempt));\n\tconst currentTime = Number.isFinite(now) ? now : retry.deadline;\n\treturn {\n\t\tattempt,\n\t\tmaxAttempts,\n\t\tremainingSeconds: Math.max(0, Math.ceil((retry.deadline - currentTime) / 1000)),\n\t\terror: retryError(typeof retry.error === \"string\" ? retry.error : \"\"),\n\t};\n}\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { boundText } from "./activity.js";
|
|
2
|
+
import { RETRY_ERROR_TEXT_LIMIT } from "./constants.js";
|
|
3
|
+
function positiveInteger(value, fallback) {
|
|
4
|
+
return Number.isFinite(value) ? Math.max(1, Math.floor(value)) : fallback;
|
|
5
|
+
}
|
|
6
|
+
function retryError(error) {
|
|
7
|
+
const normalized = error.replace(/\s+/gu, " ").trim();
|
|
8
|
+
return boundText(normalized, RETRY_ERROR_TEXT_LIMIT).replace(/\s+/gu, " ").trim();
|
|
9
|
+
}
|
|
10
|
+
export function beginSubagentRetry(run, options) {
|
|
11
|
+
const attempt = positiveInteger(options.attempt, 1);
|
|
12
|
+
const maxAttempts = Math.max(attempt, positiveInteger(options.maxAttempts, attempt));
|
|
13
|
+
const delayMs = Number.isFinite(options.delayMs) ? Math.max(0, options.delayMs) : 0;
|
|
14
|
+
run.retry = {
|
|
15
|
+
attempt,
|
|
16
|
+
maxAttempts,
|
|
17
|
+
deadline: Date.now() + delayMs,
|
|
18
|
+
error: retryError(options.error),
|
|
19
|
+
};
|
|
20
|
+
run.currentActivity = `Retrying (${attempt}/${maxAttempts})…`;
|
|
21
|
+
}
|
|
22
|
+
export function clearSubagentRetry(run) {
|
|
23
|
+
run.retry = undefined;
|
|
24
|
+
if (run.currentActivity?.startsWith("Retrying"))
|
|
25
|
+
run.currentActivity = undefined;
|
|
26
|
+
}
|
|
27
|
+
export function getSubagentRetryView(run, now = Date.now()) {
|
|
28
|
+
const retry = run.retry;
|
|
29
|
+
if (!retry || !Number.isFinite(retry.deadline))
|
|
30
|
+
return undefined;
|
|
31
|
+
const attempt = positiveInteger(retry.attempt, 1);
|
|
32
|
+
const maxAttempts = Math.max(attempt, positiveInteger(retry.maxAttempts, attempt));
|
|
33
|
+
const currentTime = Number.isFinite(now) ? now : retry.deadline;
|
|
34
|
+
return {
|
|
35
|
+
attempt,
|
|
36
|
+
maxAttempts,
|
|
37
|
+
remainingSeconds: Math.max(0, Math.ceil((retry.deadline - currentTime) / 1000)),
|
|
38
|
+
error: retryError(typeof retry.error === "string" ? retry.error : ""),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/extensions/subagent/retry.ts"],"names":[],"mappings":"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","sourcesContent":["import { boundText } from \"./activity.ts\";\nimport { RETRY_ERROR_TEXT_LIMIT } from \"./constants.ts\";\nimport type { SubagentRunDetails } from \"./types.ts\";\n\nexport interface BeginSubagentRetryOptions {\n\tattempt: number;\n\tmaxAttempts: number;\n\tdelayMs: number;\n\terror: string;\n}\n\nexport interface SubagentRetryView {\n\tattempt: number;\n\tmaxAttempts: number;\n\tremainingSeconds: number;\n\terror: string;\n}\n\nfunction positiveInteger(value: number, fallback: number): number {\n\treturn Number.isFinite(value) ? Math.max(1, Math.floor(value)) : fallback;\n}\n\nfunction retryError(error: string): string {\n\tconst normalized = error.replace(/\\s+/gu, \" \").trim();\n\treturn boundText(normalized, RETRY_ERROR_TEXT_LIMIT).replace(/\\s+/gu, \" \").trim();\n}\n\nexport function beginSubagentRetry(run: SubagentRunDetails, options: BeginSubagentRetryOptions): void {\n\tconst attempt = positiveInteger(options.attempt, 1);\n\tconst maxAttempts = Math.max(attempt, positiveInteger(options.maxAttempts, attempt));\n\tconst delayMs = Number.isFinite(options.delayMs) ? Math.max(0, options.delayMs) : 0;\n\trun.retry = {\n\t\tattempt,\n\t\tmaxAttempts,\n\t\tdeadline: Date.now() + delayMs,\n\t\terror: retryError(options.error),\n\t};\n\trun.currentActivity = `Retrying (${attempt}/${maxAttempts})…`;\n}\n\nexport function clearSubagentRetry(run: SubagentRunDetails): void {\n\trun.retry = undefined;\n\tif (run.currentActivity?.startsWith(\"Retrying\")) run.currentActivity = undefined;\n}\n\nexport function getSubagentRetryView(run: SubagentRunDetails, now = Date.now()): SubagentRetryView | undefined {\n\tconst retry = run.retry;\n\tif (!retry || !Number.isFinite(retry.deadline)) return undefined;\n\tconst attempt = positiveInteger(retry.attempt, 1);\n\tconst maxAttempts = Math.max(attempt, positiveInteger(retry.maxAttempts, attempt));\n\tconst currentTime = Number.isFinite(now) ? now : retry.deadline;\n\treturn {\n\t\tattempt,\n\t\tmaxAttempts,\n\t\tremainingSeconds: Math.max(0, Math.ceil((retry.deadline - currentTime) / 1000)),\n\t\terror: retryError(typeof retry.error === \"string\" ? retry.error : \"\"),\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAehE,OAAO,EAAE,KAAK,kBAAkB,EAAuB,MAAM,cAAc,CAAC;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,aAAa,CAAC;AAGhE,OAAO,KAAK,EACX,eAAe,EAEf,eAAe,EACf,uBAAuB,EAGvB,MAAM,YAAY,CAAC;AAWpB,qBAAa,eAAe;IAC3B,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,YAAY,KAAK,SAAkB,EAElC;IAED,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAkBjD;IAED,OAAO,CAAC,OAAO;CAef;AAED,MAAM,WAAW,yBAAyB;IACzC,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IACnC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IAC9C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC;IAC3D,8DAA8D;IAC9D,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAyCD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,eAAe,CAyF9E;AA6ND,wBAAgB,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,MAAM,CAAC,GAAG,OAAO,CAK1F;AAED,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA4BhH;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAE9D","sourcesContent":["import { relative } from \"node:path\";\nimport { isRetryableAssistantError } from \"@earendil-works/pi-ai/compat\";\nimport type { ModelRuntime } from \"../../core/model-runtime.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport { boundText, emptyUsage, mergeUsage, toNestedUsage } from \"./activity.ts\";\nimport {\n\tDETAILS_ACTIVITY_LIMIT,\n\tDETAILS_OUTPUT_LIMIT,\n\tERROR_TEXT_LIMIT,\n\tMAX_CONCURRENCY,\n\tMAX_TASKS,\n\tPARALLEL_OUTPUT_LIMIT,\n\tPARALLEL_TASK_OUTPUT_LIMIT,\n\tSINGLE_OUTPUT_LIMIT,\n\tTASK_RETRY_BASE_DELAY_MS,\n\tTASK_RETRY_LIMIT,\n} from \"./constants.ts\";\nimport { type ParentModelContext, resolveSubagentTask } from \"./resolve.ts\";\nimport type { SubagentParams, SubagentTask } from \"./schema.ts\";\nimport { runSdkTask } from \"./sdk-runner.ts\";\nimport { loadSubagentConfig } from \"./settings.ts\";\nimport type {\n\tAgentDefinition,\n\tResolvedSubagentTask,\n\tSubagentDetails,\n\tSubagentExecutionResult,\n\tSubagentRunDetails,\n\tSubagentUsage,\n} from \"./types.ts\";\n\nconst EMPTY_OUTPUT = \"(Subagent completed but returned no output.)\";\n\ninterface Waiter {\n\tresolve: (release: () => void) => void;\n\treject: (error: Error) => void;\n\tsignal?: AbortSignal;\n\tabortListener?: () => void;\n}\n\nexport class ConcurrencyGate {\n\tprivate active = 0;\n\tprivate readonly waiters: Waiter[] = [];\n\tprivate readonly limit: number;\n\n\tconstructor(limit = MAX_CONCURRENCY) {\n\t\tthis.limit = limit;\n\t}\n\n\tacquire(signal?: AbortSignal): Promise<() => void> {\n\t\tif (signal?.aborted) return Promise.reject(new Error(\"Subagent was aborted while queued.\"));\n\t\tif (this.active < this.limit) {\n\t\t\tthis.active++;\n\t\t\treturn Promise.resolve(() => this.release());\n\t\t}\n\t\treturn new Promise<() => void>((resolve, reject) => {\n\t\t\tconst waiter: Waiter = { resolve, reject, signal };\n\t\t\tif (signal) {\n\t\t\t\twaiter.abortListener = () => {\n\t\t\t\t\tconst index = this.waiters.indexOf(waiter);\n\t\t\t\t\tif (index >= 0) this.waiters.splice(index, 1);\n\t\t\t\t\treject(new Error(\"Subagent was aborted while queued.\"));\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", waiter.abortListener, { once: true });\n\t\t\t}\n\t\t\tthis.waiters.push(waiter);\n\t\t});\n\t}\n\n\tprivate release(): void {\n\t\tthis.active = Math.max(0, this.active - 1);\n\t\twhile (this.waiters.length > 0) {\n\t\t\tconst waiter = this.waiters.shift();\n\t\t\tif (!waiter) return;\n\t\t\tif (waiter.signal?.aborted) {\n\t\t\t\twaiter.abortListener?.();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\twaiter.signal?.removeEventListener(\"abort\", waiter.abortListener!);\n\t\t\tthis.active++;\n\t\t\twaiter.resolve(() => this.release());\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nexport interface SubagentInvocationOptions {\n\tparams: SubagentParams;\n\tparentCwd: string;\n\tagents: readonly AgentDefinition[];\n\tparent: ParentModelContext;\n\tmodelRuntime: ModelRuntime;\n\tagentDir: string;\n\tprojectTrusted: boolean;\n\tsignal?: AbortSignal;\n\tgate: ConcurrencyGate;\n\tonUpdate?: (details: SubagentDetails) => void;\n\tregisterAbort?: (abort: () => Promise<void>) => () => void;\n\t/** Test hook: overrides the task-retry backoff base delay. */\n\ttaskRetryBaseDelayMs?: number;\n}\n\nfunction runId(index: number): string {\n\treturn `subagent-${index + 1}`;\n}\n\nfunction createRun(task: ResolvedSubagentTask, index: number, parentCwd: string): SubagentRunDetails {\n\treturn {\n\t\tid: runId(index),\n\t\tagent: task.agent.name,\n\t\tagentSource: task.agent.source,\n\t\tdescription: task.description,\n\t\tprompt: task.prompt,\n\t\t// Display-only relative path; the worker session itself uses the\n\t\t// resolved absolute task.cwd. Empty means \"same as the parent\".\n\t\tcwd: relative(parentCwd, task.cwd),\n\t\tmodel: `${task.model.provider}/${task.model.id}`,\n\t\tthinking: task.thinking,\n\t\tstatus: \"queued\",\n\t\tactivities: [],\n\t\tliveText: \"\",\n\t\tfinalOutput: \"\",\n\t\tusage: emptyUsage(),\n\t};\n}\n\nfunction aggregateUsage(runs: readonly SubagentRunDetails[]): SubagentUsage {\n\tconst usage = emptyUsage();\n\tfor (const run of runs) mergeUsage(usage, run.usage);\n\treturn usage;\n}\n\ninterface TextField {\n\tget: () => string;\n\tset: (value: string) => void;\n}\n\nfunction detailsSize(details: SubagentDetails): number {\n\treturn Buffer.byteLength(JSON.stringify(details), \"utf8\");\n}\n\nexport function boundSubagentDetails(details: SubagentDetails): SubagentDetails {\n\tconst perRunBudget = Math.max(\n\t\t1_024,\n\t\tMath.floor((DETAILS_OUTPUT_LIMIT - 8 * 1024) / Math.max(1, details.runs.length)),\n\t);\n\tconst outputLimit = Math.min(SINGLE_OUTPUT_LIMIT, Math.max(1_024, perRunBudget - 7 * 1024));\n\tconst bounded: SubagentDetails = {\n\t\t...details,\n\t\truns: details.runs.map((run) => ({\n\t\t\t...run,\n\t\t\tprompt: boundText(run.prompt, 1_024),\n\t\t\tcwd: boundText(run.cwd, 1_024),\n\t\t\tcurrentActivity: run.currentActivity ? boundText(run.currentActivity, 512) : undefined,\n\t\t\tactivities: run.activities.slice(-DETAILS_ACTIVITY_LIMIT).map((activity) => ({\n\t\t\t\t...activity,\n\t\t\t\tsummary: boundText(activity.summary, 256),\n\t\t\t\tresultSummary: activity.resultSummary ? boundText(activity.resultSummary, 256) : undefined,\n\t\t\t})),\n\t\t\tliveText: boundText(run.liveText, 1_024),\n\t\t\tfinalOutput: boundText(run.finalOutput, outputLimit),\n\t\t\terror: run.error ? boundText(run.error, 1_024) : undefined,\n\t\t})),\n\t};\n\tconst fields: TextField[] = [];\n\tfor (const run of bounded.runs) {\n\t\tfields.push(\n\t\t\t{\n\t\t\t\tget: () => run.prompt,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.prompt = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.cwd,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.cwd = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.currentActivity ?? \"\",\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.currentActivity = value || undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.liveText,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.liveText = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.finalOutput,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.finalOutput = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.error ?? \"\",\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.error = value || undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\tfor (const activity of run.activities) {\n\t\t\tfields.push(\n\t\t\t\t{\n\t\t\t\t\tget: () => activity.summary,\n\t\t\t\t\tset: (value) => {\n\t\t\t\t\t\tactivity.summary = value;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tget: () => activity.resultSummary ?? \"\",\n\t\t\t\t\tset: (value) => {\n\t\t\t\t\t\tactivity.resultSummary = value || undefined;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\twhile (detailsSize(bounded) > DETAILS_OUTPUT_LIMIT) {\n\t\tconst largest = fields\n\t\t\t.map((field) => ({ field, size: Buffer.byteLength(field.get(), \"utf8\") }))\n\t\t\t.sort((left, right) => right.size - left.size)[0];\n\t\tif (!largest || largest.size === 0) break;\n\t\tconst overflow = detailsSize(bounded) - DETAILS_OUTPUT_LIMIT;\n\t\tlargest.field.set(boundText(largest.field.get(), Math.max(0, largest.size - overflow)));\n\t}\n\treturn bounded;\n}\n\nfunction statusOf(runs: readonly SubagentRunDetails[]): SubagentDetails[\"status\"] {\n\tif (runs.some((run) => run.status === \"aborted\")) return \"aborted\";\n\tif (runs.some((run) => run.status === \"failed\")) return \"failed\";\n\tif (runs.some((run) => run.status === \"queued\" || run.status === \"running\")) return \"running\";\n\treturn \"completed\";\n}\n\nfunction statusText(details: SubagentDetails): string {\n\tconst running = details.runs.filter((run) => run.status === \"running\").length;\n\tconst queued = details.runs.filter((run) => run.status === \"queued\").length;\n\tconst completed = details.runs.filter((run) => run.status === \"completed\").length;\n\tconst failed = details.runs.filter((run) => run.status === \"failed\").length;\n\tconst aborted = details.runs.filter((run) => run.status === \"aborted\").length;\n\tif (details.mode === \"single\") {\n\t\tconst run = details.runs[0];\n\t\tif (run?.currentActivity) return run.currentActivity;\n\t\tif (\n\t\t\t!run ||\n\t\t\t(run.status === \"running\" && run.usage.turns === 0 && run.usage.toolUses === 0 && run.liveText.length === 0)\n\t\t) {\n\t\t\treturn \"Initializing…\";\n\t\t}\n\t\treturn run.status === \"running\" ? \"Thinking…\" : run.status;\n\t}\n\tconst parts = [`${completed}/${details.runs.length} complete`];\n\tif (running) parts.push(`${running} running`);\n\tif (queued) parts.push(`${queued} queued`);\n\tif (failed) parts.push(`${failed} failed`);\n\tif (aborted) parts.push(`${aborted} aborted`);\n\treturn parts.join(\" · \");\n}\n\nfunction emitDetails(\n\tmode: SubagentDetails[\"mode\"],\n\truns: SubagentRunDetails[],\n\tstartedAt: number,\n\tonUpdate: ((details: SubagentDetails) => void) | undefined,\n): SubagentDetails {\n\tconst details: SubagentDetails = {\n\t\tmode,\n\t\tstatus: statusOf(runs),\n\t\truns: [...runs],\n\t\tstartedAt,\n\t\tusage: aggregateUsage(runs),\n\t};\n\tonUpdate?.(boundSubagentDetails(details));\n\treturn details;\n}\n\nfunction validateTaskCount(tasks: readonly SubagentTask[]): void {\n\tif (tasks.length === 0) throw new Error(\"Subagent task list must not be empty.\");\n\tif (tasks.length > MAX_TASKS) throw new Error(`Subagent task list is limited to ${MAX_TASKS} tasks.`);\n}\n\nasync function resolveTasks(\n\ttasks: readonly SubagentTask[],\n\toptions: SubagentInvocationOptions,\n): Promise<ResolvedSubagentTask[]> {\n\tvalidateTaskCount(tasks);\n\tconst config = await loadSubagentConfig(options.agentDir);\n\treturn Promise.all(\n\t\ttasks.map((task) =>\n\t\t\tresolveSubagentTask(task, options.parentCwd, options.agents, options.parent, options.agentDir, config),\n\t\t),\n\t);\n}\n\n// Reuses pi-ai's provider-error classification by wrapping the stored error\n// text in the assistant-message shape it inspects.\nfunction isRetryableRunError(error: string | undefined): boolean {\n\tif (!error) return false;\n\tconst probe = { role: \"assistant\", content: [], stopReason: \"error\", errorMessage: error };\n\treturn isRetryableAssistantError(probe as unknown as Parameters<typeof isRetryableAssistantError>[0]);\n}\n\n// Session-level auto-retry already covers errors that happen inside the agent\n// loop; this catches the paths that bypass it (preflight throws such as auth\n// checks). Only a run that produced nothing is retried, so partial work is\n// never discarded.\nfunction shouldRetryTask(run: SubagentRunDetails): boolean {\n\treturn (\n\t\trun.status === \"failed\" && run.usage.turns === 0 && run.usage.toolUses === 0 && isRetryableRunError(run.error)\n\t);\n}\n\nfunction resetRunForRetry(run: SubagentRunDetails, attempt: number, maxAttempts: number): void {\n\trun.status = \"queued\";\n\trun.error = undefined;\n\trun.startedAt = undefined;\n\trun.endedAt = undefined;\n\trun.finalOutput = \"\";\n\trun.liveText = \"\";\n\trun.currentActivity = `Retrying (attempt ${attempt}/${maxAttempts})…`;\n\trun.activities.length = 0;\n\trun.usage = emptyUsage();\n}\n\nasync function runWithGate(\n\ttask: ResolvedSubagentTask,\n\trun: SubagentRunDetails,\n\toptions: SubagentInvocationOptions,\n\tonProgress: () => void,\n): Promise<SubagentRunDetails> {\n\tonProgress();\n\tlet release: (() => void) | undefined;\n\ttry {\n\t\trelease = await options.gate.acquire(options.signal);\n\t\tif (options.signal?.aborted) {\n\t\t\trun.status = \"aborted\";\n\t\t\trun.error = \"Subagent was aborted while queued.\";\n\t\t\treturn run;\n\t\t}\n\t\tconst baseDelayMs = options.taskRetryBaseDelayMs ?? TASK_RETRY_BASE_DELAY_MS;\n\t\tfor (let attempt = 0; ; attempt++) {\n\t\t\tconst result = await runSdkTask({\n\t\t\t\ttask,\n\t\t\t\trun,\n\t\t\t\tmodelRuntime: options.modelRuntime,\n\t\t\t\tagentDir: options.agentDir,\n\t\t\t\tprojectTrusted: options.projectTrusted,\n\t\t\t\tsignal: options.signal,\n\t\t\t\tonProgress,\n\t\t\t\tregisterAbort: options.registerAbort,\n\t\t\t});\n\t\t\tif (attempt >= TASK_RETRY_LIMIT || options.signal?.aborted || !shouldRetryTask(result)) return result;\n\t\t\tresetRunForRetry(run, attempt + 1, TASK_RETRY_LIMIT);\n\t\t\tonProgress();\n\t\t\ttry {\n\t\t\t\tawait sleep(baseDelayMs * 2 ** attempt, options.signal);\n\t\t\t} catch {\n\t\t\t\trun.status = \"aborted\";\n\t\t\t\trun.error = \"Subagent was aborted while waiting to retry.\";\n\t\t\t\trun.endedAt = Date.now();\n\t\t\t\tonProgress();\n\t\t\t\treturn run;\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\trun.status = options.signal?.aborted ? \"aborted\" : \"failed\";\n\t\trun.error = boundText(error instanceof Error ? error.message : String(error), ERROR_TEXT_LIMIT);\n\t\trun.endedAt = Date.now();\n\t\tonProgress();\n\t\treturn run;\n\t} finally {\n\t\trelease?.();\n\t}\n}\n\nfunction resultContent(details: SubagentDetails): string {\n\tif (details.mode === \"single\") {\n\t\tconst run = details.runs[0];\n\t\tif (!run) return \"Subagent produced no run.\";\n\t\tif (run.status === \"failed\" || run.status === \"aborted\") {\n\t\t\treturn boundText(\n\t\t\t\t`${run.status === \"aborted\" ? \"Subagent aborted\" : \"Subagent failed\"}: ${run.error ?? \"unknown error\"}${run.finalOutput ? `\\n\\nPartial response:\\n${run.finalOutput}` : \"\"}`,\n\t\t\t\tSINGLE_OUTPUT_LIMIT,\n\t\t\t);\n\t\t}\n\t\treturn run.finalOutput || EMPTY_OUTPUT;\n\t}\n\tconst sections = details.runs.map((run) => {\n\t\tconst output = run.finalOutput || run.error || EMPTY_OUTPUT;\n\t\treturn `### ${run.description} (${run.agent}) — ${run.status}\\n\\n${boundText(output, PARALLEL_TASK_OUTPUT_LIMIT)}`;\n\t});\n\treturn boundText(sections.join(\"\\n\\n---\\n\\n\"), PARALLEL_OUTPUT_LIMIT);\n}\n\nfunction invocationMode(params: SubagentParams): { mode: SubagentDetails[\"mode\"]; tasks: SubagentTask[] } {\n\tconst provided: string[] = [];\n\tif (params.prompt != null) provided.push(\"prompt\");\n\tif (params.tasks != null) provided.push(\"tasks\");\n\tif (provided.length !== 1) {\n\t\tthrow new Error(\n\t\t\tprovided.length === 0\n\t\t\t\t? \"Provide exactly one subagent mode: prompt (single task) or tasks (parallel tasks); none was provided.\"\n\t\t\t\t: `Provide exactly one subagent mode: received ${provided.join(\", \")}. Keep one and set the unused mode fields to null or omit them.`,\n\t\t);\n\t}\n\tif (params.tasks != null) {\n\t\treturn { mode: \"parallel\", tasks: params.tasks };\n\t}\n\tif (!params.description) throw new Error(\"description is required for single mode.\");\n\treturn {\n\t\tmode: \"single\",\n\t\ttasks: [\n\t\t\t{\n\t\t\t\tagent: params.agent,\n\t\t\t\tdescription: params.description,\n\t\t\t\tprompt: params.prompt!,\n\t\t\t\tcwd: params.cwd,\n\t\t\t},\n\t\t],\n\t};\n}\n\n// Cheap change detector: consecutive events that alter nothing user-visible\n// skip the bounded-details serialization in emitDetails entirely.\nfunction progressKey(runs: readonly SubagentRunDetails[]): string {\n\treturn runs\n\t\t.map((run) => {\n\t\t\tconst last = run.activities[run.activities.length - 1];\n\t\t\treturn [\n\t\t\t\trun.status,\n\t\t\t\trun.currentActivity ?? \"\",\n\t\t\t\trun.activities.length,\n\t\t\t\tlast?.status ?? \"\",\n\t\t\t\tlast?.resultSummary ?? \"\",\n\t\t\t\trun.liveText.length,\n\t\t\t\trun.liveText.slice(-24),\n\t\t\t\trun.finalOutput.length,\n\t\t\t\trun.usage.turns,\n\t\t\t\trun.usage.toolUses,\n\t\t\t\trun.usage.totalTokens,\n\t\t\t\trun.error ?? \"\",\n\t\t\t].join(\"|\");\n\t\t})\n\t\t.join(\"~\");\n}\n\nexport function isSubagentError(details: Pick<SubagentDetails, \"status\" | \"runs\">): boolean {\n\tif (details.status !== \"failed\" && details.status !== \"aborted\") return false;\n\t// A batch with any successful run is a partial result, not an error:\n\t// per-run status is already reported in the content sections.\n\treturn !details.runs.some((run) => run.status === \"completed\");\n}\n\nexport async function runSubagentInvocation(options: SubagentInvocationOptions): Promise<SubagentExecutionResult> {\n\tconst { mode, tasks } = invocationMode(options.params);\n\tconst resolved = await resolveTasks(tasks, options);\n\tconst runs = resolved.map((task, index) => createRun(task, index, options.parentCwd));\n\tconst startedAt = Date.now();\n\tlet latestDetails = emitDetails(mode, runs, startedAt, options.onUpdate);\n\tlet lastProgressKey = progressKey(runs);\n\tconst progress = () => {\n\t\tconst key = progressKey(runs);\n\t\tif (key === lastProgressKey) return;\n\t\tlastProgressKey = key;\n\t\tlatestDetails = emitDetails(mode, runs, startedAt, options.onUpdate);\n\t};\n\n\tif (mode === \"single\") {\n\t\tawait runWithGate(resolved[0]!, runs[0]!, options, progress);\n\t} else {\n\t\tawait Promise.all(resolved.map((task, index) => runWithGate(task, runs[index]!, options, progress)));\n\t}\n\tlatestDetails = emitDetails(mode, runs, startedAt, undefined);\n\tlatestDetails.endedAt = Date.now();\n\tconst isError = isSubagentError(latestDetails);\n\treturn {\n\t\tcontent: resultContent(latestDetails),\n\t\tdetails: boundSubagentDetails(latestDetails),\n\t\tusage: toNestedUsage(latestDetails.usage),\n\t\tisError,\n\t};\n}\n\nexport function statusSummary(details: SubagentDetails): string {\n\treturn statusText(details);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAgBhE,OAAO,EAAE,KAAK,kBAAkB,EAAuB,MAAM,cAAc,CAAC;AAE5E,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,aAAa,CAAC;AAGhE,OAAO,KAAK,EACX,eAAe,EAEf,eAAe,EACf,uBAAuB,EAGvB,MAAM,YAAY,CAAC;AAWpB,qBAAa,eAAe;IAC3B,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,YAAY,KAAK,SAAkB,EAElC;IAED,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAkBjD;IAED,OAAO,CAAC,OAAO;CAef;AAED,MAAM,WAAW,yBAAyB;IACzC,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IACnC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IAC9C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC;IAC3D,8DAA8D;IAC9D,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAyCD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,eAAe,CA4F9E;AAwPD,wBAAgB,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,MAAM,CAAC,GAAG,OAAO,CAK1F;AAED,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA4BhH;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAE9D","sourcesContent":["import { relative } from \"node:path\";\nimport { isRetryableAssistantError } from \"@earendil-works/pi-ai/compat\";\nimport type { ModelRuntime } from \"../../core/model-runtime.ts\";\nimport { sleep } from \"../../utils/sleep.ts\";\nimport { boundText, emptyUsage, mergeUsage, tailText, toNestedUsage } from \"./activity.ts\";\nimport {\n\tDETAILS_ACTIVITY_LIMIT,\n\tDETAILS_OUTPUT_LIMIT,\n\tERROR_TEXT_LIMIT,\n\tMAX_CONCURRENCY,\n\tMAX_TASKS,\n\tPARALLEL_OUTPUT_LIMIT,\n\tPARALLEL_TASK_OUTPUT_LIMIT,\n\tRETRY_ERROR_TEXT_LIMIT,\n\tSINGLE_OUTPUT_LIMIT,\n\tTASK_RETRY_BASE_DELAY_MS,\n\tTASK_RETRY_LIMIT,\n} from \"./constants.ts\";\nimport { type ParentModelContext, resolveSubagentTask } from \"./resolve.ts\";\nimport { beginSubagentRetry, clearSubagentRetry } from \"./retry.ts\";\nimport type { SubagentParams, SubagentTask } from \"./schema.ts\";\nimport { runSdkTask } from \"./sdk-runner.ts\";\nimport { loadSubagentConfig } from \"./settings.ts\";\nimport type {\n\tAgentDefinition,\n\tResolvedSubagentTask,\n\tSubagentDetails,\n\tSubagentExecutionResult,\n\tSubagentRunDetails,\n\tSubagentUsage,\n} from \"./types.ts\";\n\nconst EMPTY_OUTPUT = \"(Subagent completed but returned no output.)\";\n\ninterface Waiter {\n\tresolve: (release: () => void) => void;\n\treject: (error: Error) => void;\n\tsignal?: AbortSignal;\n\tabortListener?: () => void;\n}\n\nexport class ConcurrencyGate {\n\tprivate active = 0;\n\tprivate readonly waiters: Waiter[] = [];\n\tprivate readonly limit: number;\n\n\tconstructor(limit = MAX_CONCURRENCY) {\n\t\tthis.limit = limit;\n\t}\n\n\tacquire(signal?: AbortSignal): Promise<() => void> {\n\t\tif (signal?.aborted) return Promise.reject(new Error(\"Subagent was aborted while queued.\"));\n\t\tif (this.active < this.limit) {\n\t\t\tthis.active++;\n\t\t\treturn Promise.resolve(() => this.release());\n\t\t}\n\t\treturn new Promise<() => void>((resolve, reject) => {\n\t\t\tconst waiter: Waiter = { resolve, reject, signal };\n\t\t\tif (signal) {\n\t\t\t\twaiter.abortListener = () => {\n\t\t\t\t\tconst index = this.waiters.indexOf(waiter);\n\t\t\t\t\tif (index >= 0) this.waiters.splice(index, 1);\n\t\t\t\t\treject(new Error(\"Subagent was aborted while queued.\"));\n\t\t\t\t};\n\t\t\t\tsignal.addEventListener(\"abort\", waiter.abortListener, { once: true });\n\t\t\t}\n\t\t\tthis.waiters.push(waiter);\n\t\t});\n\t}\n\n\tprivate release(): void {\n\t\tthis.active = Math.max(0, this.active - 1);\n\t\twhile (this.waiters.length > 0) {\n\t\t\tconst waiter = this.waiters.shift();\n\t\t\tif (!waiter) return;\n\t\t\tif (waiter.signal?.aborted) {\n\t\t\t\twaiter.abortListener?.();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\twaiter.signal?.removeEventListener(\"abort\", waiter.abortListener!);\n\t\t\tthis.active++;\n\t\t\twaiter.resolve(() => this.release());\n\t\t\treturn;\n\t\t}\n\t}\n}\n\nexport interface SubagentInvocationOptions {\n\tparams: SubagentParams;\n\tparentCwd: string;\n\tagents: readonly AgentDefinition[];\n\tparent: ParentModelContext;\n\tmodelRuntime: ModelRuntime;\n\tagentDir: string;\n\tprojectTrusted: boolean;\n\tsignal?: AbortSignal;\n\tgate: ConcurrencyGate;\n\tonUpdate?: (details: SubagentDetails) => void;\n\tregisterAbort?: (abort: () => Promise<void>) => () => void;\n\t/** Test hook: overrides the task-retry backoff base delay. */\n\ttaskRetryBaseDelayMs?: number;\n}\n\nfunction runId(index: number): string {\n\treturn `subagent-${index + 1}`;\n}\n\nfunction createRun(task: ResolvedSubagentTask, index: number, parentCwd: string): SubagentRunDetails {\n\treturn {\n\t\tid: runId(index),\n\t\tagent: task.agent.name,\n\t\tagentSource: task.agent.source,\n\t\tdescription: task.description,\n\t\tprompt: task.prompt,\n\t\t// Display-only relative path; the worker session itself uses the\n\t\t// resolved absolute task.cwd. Empty means \"same as the parent\".\n\t\tcwd: relative(parentCwd, task.cwd),\n\t\tmodel: `${task.model.provider}/${task.model.id}`,\n\t\tthinking: task.thinking,\n\t\tstatus: \"queued\",\n\t\tactivities: [],\n\t\tliveText: \"\",\n\t\tfinalOutput: \"\",\n\t\tusage: emptyUsage(),\n\t};\n}\n\nfunction aggregateUsage(runs: readonly SubagentRunDetails[]): SubagentUsage {\n\tconst usage = emptyUsage();\n\tfor (const run of runs) mergeUsage(usage, run.usage);\n\treturn usage;\n}\n\ninterface TextField {\n\tget: () => string;\n\tset: (value: string) => void;\n}\n\nfunction detailsSize(details: SubagentDetails): number {\n\treturn Buffer.byteLength(JSON.stringify(details), \"utf8\");\n}\n\nexport function boundSubagentDetails(details: SubagentDetails): SubagentDetails {\n\tconst perRunBudget = Math.max(\n\t\t1_024,\n\t\tMath.floor((DETAILS_OUTPUT_LIMIT - 8 * 1024) / Math.max(1, details.runs.length)),\n\t);\n\tconst outputLimit = Math.min(SINGLE_OUTPUT_LIMIT, Math.max(1_024, perRunBudget - 7 * 1024));\n\tconst bounded: SubagentDetails = {\n\t\t...details,\n\t\truns: details.runs.map((run) => ({\n\t\t\t...run,\n\t\t\tprompt: boundText(run.prompt, 1_024),\n\t\t\tcwd: boundText(run.cwd, 1_024),\n\t\t\tcurrentActivity: run.currentActivity ? boundText(run.currentActivity, 512) : undefined,\n\t\t\tretry: run.retry ? { ...run.retry, error: boundText(run.retry.error, RETRY_ERROR_TEXT_LIMIT) } : undefined,\n\t\t\tactivities: run.activities.slice(-DETAILS_ACTIVITY_LIMIT).map((activity) => ({\n\t\t\t\t...activity,\n\t\t\t\tsummary: boundText(activity.summary, 256),\n\t\t\t\tresultSummary: activity.resultSummary ? boundText(activity.resultSummary, 256) : undefined,\n\t\t\t})),\n\t\t\t// liveText is a tail by construction: keep the newest lines, not the\n\t\t\t// head, or the transcript's live tail would freeze at the 1KB mark.\n\t\t\tliveText: tailText(run.liveText, 1_024),\n\t\t\tfinalOutput: boundText(run.finalOutput, outputLimit),\n\t\t\terror: run.error ? boundText(run.error, 1_024) : undefined,\n\t\t})),\n\t};\n\tconst fields: TextField[] = [];\n\tfor (const run of bounded.runs) {\n\t\tfields.push(\n\t\t\t{\n\t\t\t\tget: () => run.prompt,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.prompt = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.cwd,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.cwd = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.currentActivity ?? \"\",\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.currentActivity = value || undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.liveText,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.liveText = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.finalOutput,\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.finalOutput = value;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tget: () => run.error ?? \"\",\n\t\t\t\tset: (value) => {\n\t\t\t\t\trun.error = value || undefined;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\tfor (const activity of run.activities) {\n\t\t\tfields.push(\n\t\t\t\t{\n\t\t\t\t\tget: () => activity.summary,\n\t\t\t\t\tset: (value) => {\n\t\t\t\t\t\tactivity.summary = value;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tget: () => activity.resultSummary ?? \"\",\n\t\t\t\t\tset: (value) => {\n\t\t\t\t\t\tactivity.resultSummary = value || undefined;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\twhile (detailsSize(bounded) > DETAILS_OUTPUT_LIMIT) {\n\t\tconst largest = fields\n\t\t\t.map((field) => ({ field, size: Buffer.byteLength(field.get(), \"utf8\") }))\n\t\t\t.sort((left, right) => right.size - left.size)[0];\n\t\tif (!largest || largest.size === 0) break;\n\t\tconst overflow = detailsSize(bounded) - DETAILS_OUTPUT_LIMIT;\n\t\tlargest.field.set(boundText(largest.field.get(), Math.max(0, largest.size - overflow)));\n\t}\n\treturn bounded;\n}\n\nfunction statusOf(runs: readonly SubagentRunDetails[]): SubagentDetails[\"status\"] {\n\tif (runs.some((run) => run.status === \"aborted\")) return \"aborted\";\n\tif (runs.some((run) => run.status === \"failed\")) return \"failed\";\n\tif (runs.some((run) => run.status === \"queued\" || run.status === \"running\")) return \"running\";\n\treturn \"completed\";\n}\n\nfunction statusText(details: SubagentDetails): string {\n\tconst running = details.runs.filter((run) => run.status === \"running\").length;\n\tconst queued = details.runs.filter((run) => run.status === \"queued\").length;\n\tconst completed = details.runs.filter((run) => run.status === \"completed\").length;\n\tconst failed = details.runs.filter((run) => run.status === \"failed\").length;\n\tconst aborted = details.runs.filter((run) => run.status === \"aborted\").length;\n\tif (details.mode === \"single\") {\n\t\tconst run = details.runs[0];\n\t\tif (run?.currentActivity) return run.currentActivity;\n\t\tif (\n\t\t\t!run ||\n\t\t\t(run.status === \"running\" && run.usage.turns === 0 && run.usage.toolUses === 0 && run.liveText.length === 0)\n\t\t) {\n\t\t\treturn \"Initializing…\";\n\t\t}\n\t\treturn run.status === \"running\" ? \"Thinking…\" : run.status;\n\t}\n\tconst parts = [`${completed}/${details.runs.length} complete`];\n\tif (running) parts.push(`${running} running`);\n\tif (queued) parts.push(`${queued} queued`);\n\tif (failed) parts.push(`${failed} failed`);\n\tif (aborted) parts.push(`${aborted} aborted`);\n\treturn parts.join(\" · \");\n}\n\nfunction emitDetails(\n\tmode: SubagentDetails[\"mode\"],\n\truns: SubagentRunDetails[],\n\tstartedAt: number,\n\tonUpdate: ((details: SubagentDetails) => void) | undefined,\n): SubagentDetails {\n\tconst details: SubagentDetails = {\n\t\tmode,\n\t\tstatus: statusOf(runs),\n\t\truns: [...runs],\n\t\tstartedAt,\n\t\tusage: aggregateUsage(runs),\n\t};\n\tonUpdate?.(boundSubagentDetails(details));\n\treturn details;\n}\n\nfunction validateTaskCount(tasks: readonly SubagentTask[]): void {\n\tif (tasks.length === 0) throw new Error(\"Subagent task list must not be empty.\");\n\tif (tasks.length > MAX_TASKS) throw new Error(`Subagent task list is limited to ${MAX_TASKS} tasks.`);\n}\n\nasync function resolveTasks(\n\ttasks: readonly SubagentTask[],\n\toptions: SubagentInvocationOptions,\n): Promise<ResolvedSubagentTask[]> {\n\tvalidateTaskCount(tasks);\n\tconst config = await loadSubagentConfig(options.agentDir);\n\treturn Promise.all(\n\t\ttasks.map((task) =>\n\t\t\tresolveSubagentTask(task, options.parentCwd, options.agents, options.parent, options.agentDir, config),\n\t\t),\n\t);\n}\n\n// Reuses pi-ai's provider-error classification by wrapping the stored error\n// text in the assistant-message shape it inspects.\nfunction isRetryableRunError(error: string | undefined): boolean {\n\tif (!error) return false;\n\tconst probe = { role: \"assistant\", content: [], stopReason: \"error\", errorMessage: error };\n\treturn isRetryableAssistantError(probe as unknown as Parameters<typeof isRetryableAssistantError>[0]);\n}\n\n// Session-level auto-retry already covers errors that happen inside the agent\n// loop; this catches the paths that bypass it (preflight throws such as auth\n// checks). Only a run that produced nothing is retried, so partial work is\n// never discarded.\nfunction shouldRetryTask(run: SubagentRunDetails): boolean {\n\treturn (\n\t\trun.status === \"failed\" && run.usage.turns === 0 && run.usage.toolUses === 0 && isRetryableRunError(run.error)\n\t);\n}\n\nfunction resetRunForRetry(run: SubagentRunDetails, attempt: number, maxAttempts: number, delayMs: number): void {\n\tconst error = run.error ?? \"Subagent failed before retry.\";\n\trun.status = \"queued\";\n\trun.error = undefined;\n\trun.startedAt = undefined;\n\trun.endedAt = undefined;\n\trun.finalOutput = \"\";\n\trun.liveText = \"\";\n\trun.activities.length = 0;\n\trun.usage = emptyUsage();\n\tbeginSubagentRetry(run, { attempt, maxAttempts, delayMs, error });\n}\n\nasync function waitForTaskRetry(\n\tdelayMs: number,\n\toptions: Pick<SubagentInvocationOptions, \"signal\" | \"registerAbort\">,\n): Promise<void> {\n\tconst controller = new AbortController();\n\tconst abort = async (): Promise<void> => controller.abort();\n\tconst unregisterAbort = options.registerAbort?.(abort);\n\tconst abortListener = () => controller.abort();\n\tif (options.signal?.aborted) controller.abort();\n\telse options.signal?.addEventListener(\"abort\", abortListener, { once: true });\n\ttry {\n\t\tawait sleep(delayMs, controller.signal);\n\t} finally {\n\t\toptions.signal?.removeEventListener(\"abort\", abortListener);\n\t\tunregisterAbort?.();\n\t}\n}\n\nasync function runWithGate(\n\ttask: ResolvedSubagentTask,\n\trun: SubagentRunDetails,\n\toptions: SubagentInvocationOptions,\n\tonProgress: () => void,\n): Promise<SubagentRunDetails> {\n\tonProgress();\n\tlet release: (() => void) | undefined;\n\ttry {\n\t\trelease = await options.gate.acquire(options.signal);\n\t\tif (options.signal?.aborted) {\n\t\t\trun.status = \"aborted\";\n\t\t\trun.error = \"Subagent was aborted while queued.\";\n\t\t\treturn run;\n\t\t}\n\t\tconst baseDelayMs = options.taskRetryBaseDelayMs ?? TASK_RETRY_BASE_DELAY_MS;\n\t\tfor (let attempt = 0; ; attempt++) {\n\t\t\tclearSubagentRetry(run);\n\t\t\tconst result = await runSdkTask({\n\t\t\t\ttask,\n\t\t\t\trun,\n\t\t\t\tmodelRuntime: options.modelRuntime,\n\t\t\t\tagentDir: options.agentDir,\n\t\t\t\tprojectTrusted: options.projectTrusted,\n\t\t\t\tsignal: options.signal,\n\t\t\t\tonProgress,\n\t\t\t\tregisterAbort: options.registerAbort,\n\t\t\t});\n\t\t\tif (attempt >= TASK_RETRY_LIMIT || options.signal?.aborted || !shouldRetryTask(result)) return result;\n\t\t\tconst delayMs = baseDelayMs * 2 ** attempt;\n\t\t\tresetRunForRetry(run, attempt + 1, TASK_RETRY_LIMIT, delayMs);\n\t\t\tonProgress();\n\t\t\ttry {\n\t\t\t\tawait waitForTaskRetry(delayMs, options);\n\t\t\t} catch {\n\t\t\t\tclearSubagentRetry(run);\n\t\t\t\trun.status = \"aborted\";\n\t\t\t\trun.error = \"Subagent was aborted while waiting to retry.\";\n\t\t\t\trun.endedAt = Date.now();\n\t\t\t\tonProgress();\n\t\t\t\treturn run;\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tclearSubagentRetry(run);\n\t\trun.status = options.signal?.aborted ? \"aborted\" : \"failed\";\n\t\trun.error = boundText(error instanceof Error ? error.message : String(error), ERROR_TEXT_LIMIT);\n\t\trun.endedAt = Date.now();\n\t\tonProgress();\n\t\treturn run;\n\t} finally {\n\t\trelease?.();\n\t}\n}\n\nfunction resultContent(details: SubagentDetails): string {\n\tif (details.mode === \"single\") {\n\t\tconst run = details.runs[0];\n\t\tif (!run) return \"Subagent produced no run.\";\n\t\tif (run.status === \"failed\" || run.status === \"aborted\") {\n\t\t\treturn boundText(\n\t\t\t\t`${run.status === \"aborted\" ? \"Subagent aborted\" : \"Subagent failed\"}: ${run.error ?? \"unknown error\"}${run.finalOutput ? `\\n\\nPartial response:\\n${run.finalOutput}` : \"\"}`,\n\t\t\t\tSINGLE_OUTPUT_LIMIT,\n\t\t\t);\n\t\t}\n\t\treturn run.finalOutput || EMPTY_OUTPUT;\n\t}\n\tconst sections = details.runs.map((run) => {\n\t\tconst output = run.finalOutput || run.error || EMPTY_OUTPUT;\n\t\treturn `### ${run.description} (${run.agent}) — ${run.status}\\n\\n${boundText(output, PARALLEL_TASK_OUTPUT_LIMIT)}`;\n\t});\n\treturn boundText(sections.join(\"\\n\\n---\\n\\n\"), PARALLEL_OUTPUT_LIMIT);\n}\n\nfunction invocationMode(params: SubagentParams): { mode: SubagentDetails[\"mode\"]; tasks: SubagentTask[] } {\n\tconst provided: string[] = [];\n\tif (params.prompt != null) provided.push(\"prompt\");\n\tif (params.tasks != null) provided.push(\"tasks\");\n\tif (provided.length !== 1) {\n\t\tthrow new Error(\n\t\t\tprovided.length === 0\n\t\t\t\t? \"Provide exactly one subagent mode: prompt (single task) or tasks (parallel tasks); none was provided.\"\n\t\t\t\t: `Provide exactly one subagent mode: received ${provided.join(\", \")}. Keep one and set the unused mode fields to null or omit them.`,\n\t\t);\n\t}\n\tif (params.tasks != null) {\n\t\treturn { mode: \"parallel\", tasks: params.tasks };\n\t}\n\tif (!params.description) throw new Error(\"description is required for single mode.\");\n\treturn {\n\t\tmode: \"single\",\n\t\ttasks: [\n\t\t\t{\n\t\t\t\tagent: params.agent,\n\t\t\t\tdescription: params.description,\n\t\t\t\tprompt: params.prompt!,\n\t\t\t\tcwd: params.cwd,\n\t\t\t},\n\t\t],\n\t};\n}\n\n// Cheap change detector: consecutive events that alter nothing user-visible\n// skip the bounded-details serialization in emitDetails entirely.\nfunction progressKey(runs: readonly SubagentRunDetails[]): string {\n\treturn runs\n\t\t.map((run) => {\n\t\t\tconst last = run.activities[run.activities.length - 1];\n\t\t\treturn [\n\t\t\t\trun.status,\n\t\t\t\trun.currentActivity ?? \"\",\n\t\t\t\trun.activities.length,\n\t\t\t\tlast?.status ?? \"\",\n\t\t\t\tlast?.resultSummary ?? \"\",\n\t\t\t\trun.retry?.attempt ?? \"\",\n\t\t\t\trun.retry?.maxAttempts ?? \"\",\n\t\t\t\trun.retry?.deadline ?? \"\",\n\t\t\t\trun.retry?.error ?? \"\",\n\t\t\t\trun.liveText.length,\n\t\t\t\trun.liveText.slice(-24),\n\t\t\t\trun.finalOutput.length,\n\t\t\t\trun.usage.turns,\n\t\t\t\trun.usage.toolUses,\n\t\t\t\trun.usage.totalTokens,\n\t\t\t\trun.error ?? \"\",\n\t\t\t].join(\"|\");\n\t\t})\n\t\t.join(\"~\");\n}\n\nexport function isSubagentError(details: Pick<SubagentDetails, \"status\" | \"runs\">): boolean {\n\tif (details.status !== \"failed\" && details.status !== \"aborted\") return false;\n\t// A batch with any successful run is a partial result, not an error:\n\t// per-run status is already reported in the content sections.\n\treturn !details.runs.some((run) => run.status === \"completed\");\n}\n\nexport async function runSubagentInvocation(options: SubagentInvocationOptions): Promise<SubagentExecutionResult> {\n\tconst { mode, tasks } = invocationMode(options.params);\n\tconst resolved = await resolveTasks(tasks, options);\n\tconst runs = resolved.map((task, index) => createRun(task, index, options.parentCwd));\n\tconst startedAt = Date.now();\n\tlet latestDetails = emitDetails(mode, runs, startedAt, options.onUpdate);\n\tlet lastProgressKey = progressKey(runs);\n\tconst progress = () => {\n\t\tconst key = progressKey(runs);\n\t\tif (key === lastProgressKey) return;\n\t\tlastProgressKey = key;\n\t\tlatestDetails = emitDetails(mode, runs, startedAt, options.onUpdate);\n\t};\n\n\tif (mode === \"single\") {\n\t\tawait runWithGate(resolved[0]!, runs[0]!, options, progress);\n\t} else {\n\t\tawait Promise.all(resolved.map((task, index) => runWithGate(task, runs[index]!, options, progress)));\n\t}\n\tlatestDetails = emitDetails(mode, runs, startedAt, undefined);\n\tlatestDetails.endedAt = Date.now();\n\tconst isError = isSubagentError(latestDetails);\n\treturn {\n\t\tcontent: resultContent(latestDetails),\n\t\tdetails: boundSubagentDetails(latestDetails),\n\t\tusage: toNestedUsage(latestDetails.usage),\n\t\tisError,\n\t};\n}\n\nexport function statusSummary(details: SubagentDetails): string {\n\treturn statusText(details);\n}\n"]}
|