@astralyn/pi 0.84.14 → 0.84.16
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 +23 -0
- package/dist/cli.js +2435 -18
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +12 -6
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/types.d.ts +4 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/tools/bash.d.ts +1 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +4 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/find.d.ts +2 -0
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +18 -15
- package/dist/core/tools/find.js.map +1 -1
- package/dist/extensions/background/actions.d.ts.map +1 -1
- package/dist/extensions/background/actions.js +3 -2
- package/dist/extensions/background/actions.js.map +1 -1
- package/dist/extensions/background/index.d.ts +5 -4
- package/dist/extensions/background/index.d.ts.map +1 -1
- package/dist/extensions/background/index.js +9 -5
- package/dist/extensions/background/index.js.map +1 -1
- package/dist/extensions/background/manager.d.ts.map +1 -1
- package/dist/extensions/background/manager.js +8 -9
- package/dist/extensions/background/manager.js.map +1 -1
- package/dist/extensions/background/registry.d.ts +4 -1
- package/dist/extensions/background/registry.d.ts.map +1 -1
- package/dist/extensions/background/registry.js +30 -17
- package/dist/extensions/background/registry.js.map +1 -1
- package/dist/extensions/background/task-view.d.ts +6 -0
- package/dist/extensions/background/task-view.d.ts.map +1 -1
- package/dist/extensions/background/task-view.js +11 -6
- package/dist/extensions/background/task-view.js.map +1 -1
- package/dist/extensions/deepwiki/client.d.ts.map +1 -1
- package/dist/extensions/deepwiki/client.js +3 -0
- package/dist/extensions/deepwiki/client.js.map +1 -1
- package/dist/extensions/deepwiki/execute.d.ts +2 -1
- package/dist/extensions/deepwiki/execute.d.ts.map +1 -1
- package/dist/extensions/deepwiki/execute.js +17 -2
- package/dist/extensions/deepwiki/execute.js.map +1 -1
- package/dist/extensions/deepwiki/http.d.ts +1 -0
- package/dist/extensions/deepwiki/http.d.ts.map +1 -1
- package/dist/extensions/deepwiki/http.js +16 -2
- package/dist/extensions/deepwiki/http.js.map +1 -1
- package/dist/extensions/deepwiki/schema.d.ts +1 -1
- package/dist/extensions/deepwiki/schema.d.ts.map +1 -1
- package/dist/extensions/deepwiki/schema.js +8 -2
- package/dist/extensions/deepwiki/schema.js.map +1 -1
- package/dist/extensions/question/dialog.d.ts.map +1 -1
- package/dist/extensions/question/dialog.js +80 -9
- 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 +8 -0
- package/dist/extensions/question/index.js.map +1 -1
- package/dist/extensions/question/schema.d.ts +2 -2
- package/dist/extensions/question/schema.d.ts.map +1 -1
- package/dist/extensions/question/schema.js +41 -11
- package/dist/extensions/question/schema.js.map +1 -1
- package/dist/extensions/question/types.d.ts +1 -1
- package/dist/extensions/question/types.d.ts.map +1 -1
- package/dist/extensions/question/types.js.map +1 -1
- package/dist/extensions/router/probe.d.ts.map +1 -1
- package/dist/extensions/router/probe.js +10 -29
- package/dist/extensions/router/probe.js.map +1 -1
- package/dist/extensions/router/register.d.ts.map +1 -1
- package/dist/extensions/router/register.js +16 -6
- package/dist/extensions/router/register.js.map +1 -1
- package/dist/extensions/router/store.d.ts.map +1 -1
- package/dist/extensions/router/store.js +108 -51
- package/dist/extensions/router/store.js.map +1 -1
- package/dist/extensions/router/ui.d.ts +6 -0
- package/dist/extensions/router/ui.d.ts.map +1 -1
- package/dist/extensions/router/ui.js +14 -6
- package/dist/extensions/router/ui.js.map +1 -1
- package/dist/extensions/statusline/index.d.ts.map +1 -1
- package/dist/extensions/statusline/index.js +40 -43
- package/dist/extensions/statusline/index.js.map +1 -1
- package/dist/extensions/subagent/activity.d.ts +7 -1
- package/dist/extensions/subagent/activity.d.ts.map +1 -1
- package/dist/extensions/subagent/activity.js +69 -6
- package/dist/extensions/subagent/activity.js.map +1 -1
- package/dist/extensions/subagent/agents-command.js +1 -1
- package/dist/extensions/subagent/agents-command.js.map +1 -1
- package/dist/extensions/subagent/agents.d.ts.map +1 -1
- package/dist/extensions/subagent/agents.js +0 -3
- package/dist/extensions/subagent/agents.js.map +1 -1
- package/dist/extensions/subagent/budget.d.ts.map +1 -1
- package/dist/extensions/subagent/budget.js +29 -2
- package/dist/extensions/subagent/budget.js.map +1 -1
- package/dist/extensions/subagent/cancellation.d.ts +4 -4
- package/dist/extensions/subagent/cancellation.d.ts.map +1 -1
- package/dist/extensions/subagent/cancellation.js +31 -13
- package/dist/extensions/subagent/cancellation.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 +1 -0
- package/dist/extensions/subagent/index.js.map +1 -1
- package/dist/extensions/subagent/render.d.ts +8 -1
- package/dist/extensions/subagent/render.d.ts.map +1 -1
- package/dist/extensions/subagent/render.js +155 -178
- package/dist/extensions/subagent/render.js.map +1 -1
- package/dist/extensions/subagent/runner.d.ts +1 -0
- package/dist/extensions/subagent/runner.d.ts.map +1 -1
- package/dist/extensions/subagent/runner.js +53 -44
- package/dist/extensions/subagent/runner.js.map +1 -1
- package/dist/extensions/subagent/sdk-runner.d.ts.map +1 -1
- package/dist/extensions/subagent/sdk-runner.js +0 -3
- package/dist/extensions/subagent/sdk-runner.js.map +1 -1
- package/dist/extensions/subagent/settings.d.ts +1 -1
- package/dist/extensions/subagent/settings.d.ts.map +1 -1
- package/dist/extensions/subagent/settings.js +74 -25
- package/dist/extensions/subagent/settings.js.map +1 -1
- package/dist/extensions/subagent/state.d.ts +1 -0
- package/dist/extensions/subagent/state.d.ts.map +1 -1
- package/dist/extensions/subagent/state.js +46 -16
- package/dist/extensions/subagent/state.js.map +1 -1
- package/dist/extensions/subagent/types.d.ts +0 -7
- package/dist/extensions/subagent/types.d.ts.map +1 -1
- package/dist/extensions/subagent/types.js.map +1 -1
- package/dist/extensions/subagent/ui/agents-dialog.js +1 -1
- package/dist/extensions/subagent/ui/agents-dialog.js.map +1 -1
- package/dist/extensions/subagent/ui/model-list.d.ts.map +1 -1
- package/dist/extensions/subagent/ui/model-list.js +3 -4
- package/dist/extensions/subagent/ui/model-list.js.map +1 -1
- package/dist/extensions/subagent/ui/model-picker.d.ts.map +1 -1
- package/dist/extensions/subagent/ui/model-picker.js +2 -1
- package/dist/extensions/subagent/ui/model-picker.js.map +1 -1
- package/dist/extensions/web-search/format.d.ts.map +1 -1
- package/dist/extensions/web-search/format.js +36 -15
- package/dist/extensions/web-search/format.js.map +1 -1
- package/dist/extensions/web-search/index.d.ts.map +1 -1
- package/dist/extensions/web-search/index.js +11 -8
- package/dist/extensions/web-search/index.js.map +1 -1
- package/dist/extensions/web-search/providers/deepseek.d.ts.map +1 -1
- package/dist/extensions/web-search/providers/deepseek.js +36 -5
- package/dist/extensions/web-search/providers/deepseek.js.map +1 -1
- package/dist/extensions/web-search/providers/http.d.ts +2 -7
- package/dist/extensions/web-search/providers/http.d.ts.map +1 -1
- package/dist/extensions/web-search/providers/http.js +12 -57
- package/dist/extensions/web-search/providers/http.js.map +1 -1
- package/dist/extensions/web-search/providers/minimax.d.ts.map +1 -1
- package/dist/extensions/web-search/providers/minimax.js +18 -6
- package/dist/extensions/web-search/providers/minimax.js.map +1 -1
- package/dist/extensions/web-search/render.d.ts.map +1 -1
- package/dist/extensions/web-search/render.js +16 -5
- package/dist/extensions/web-search/render.js.map +1 -1
- package/dist/extensions/web-search/results.d.ts +10 -3
- package/dist/extensions/web-search/results.d.ts.map +1 -1
- package/dist/extensions/web-search/results.js +25 -7
- package/dist/extensions/web-search/results.js.map +1 -1
- package/dist/image-resize-worker.js +2 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +7 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-group.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-group.js +10 -0
- package/dist/modes/interactive/components/tool-group.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +3 -40
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +0 -4
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +16 -23
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/rpc-entry.js +2435 -10
- package/dist/utils/http-response.d.ts +10 -0
- package/dist/utils/http-response.d.ts.map +1 -0
- package/dist/utils/http-response.js +68 -0
- package/dist/utils/http-response.js.map +1 -0
- package/docs/bundled/extensions/background.md +4 -3
- package/docs/bundled/extensions/deepwiki.md +7 -5
- package/docs/bundled/extensions/question.md +6 -4
- package/docs/bundled/extensions/router.md +1 -1
- package/docs/bundled/extensions/statusline.md +1 -0
- package/docs/bundled/extensions/subagent.md +29 -39
- package/docs/bundled/extensions/web-search.md +3 -3
- package/docs/development.md +8 -3
- package/docs/extensions.md +2 -2
- package/npm-shrinkwrap.json +110 -109
- package/package.json +4 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,kBAAkB,aAAa,CAAC;AAC7C,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAC9C,eAAO,MAAM,qBAAqB,WAAW,CAAC;AAC9C,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AAEpD,eAAO,MAAM,SAAS,IAAI,CAAC;AAC3B,eAAO,MAAM,eAAe,IAAI,CAAC;AAKjC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,wBAAwB,OAAQ,CAAC;AAK9C,eAAO,MAAM,oBAAoB,kCAAmC,CAAC;AACrE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAGtE,eAAO,MAAM,mBAAmB,4CAA6C,CAAC;AAI9E,eAAO,MAAM,cAAc,iDAAkD,CAAC;AAE9E,eAAO,MAAM,eAAe,sEAQiB,CAAC;AAE9C,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,mBAAmB,QAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,kBAAkB,aAAa,CAAC;AAC7C,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAC9C,eAAO,MAAM,qBAAqB,WAAW,CAAC;AAC9C,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AAEpD,eAAO,MAAM,SAAS,IAAI,CAAC;AAC3B,eAAO,MAAM,eAAe,IAAI,CAAC;AAKjC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,wBAAwB,OAAQ,CAAC;AAK9C,eAAO,MAAM,oBAAoB,kCAAmC,CAAC;AACrE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAGtE,eAAO,MAAM,mBAAmB,4CAA6C,CAAC;AAI9E,eAAO,MAAM,cAAc,iDAAkD,CAAC;AAE9E,eAAO,MAAM,eAAe,sEAQiB,CAAC;AAE9C,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,mBAAmB,QAAY,CAAC;AAC7C,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAIxC,eAAO,MAAM,sBAAsB,eAAe,CAAC;AAGnD,eAAO,MAAM,iBAAiB,QAAY,CAAC;AAE3C,eAAO,MAAM,kBAAkB,QAAY,CAAC;AAC5C,eAAO,MAAM,gBAAgB,QAAW,CAAC;AACzC,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAC1C,eAAO,MAAM,oBAAoB,QAAa,CAAC;AAG/C,eAAO,MAAM,sBAAsB,KAAK,CAAC"}
|
|
@@ -31,6 +31,7 @@ export const THINKING_LEVELS = [
|
|
|
31
31
|
];
|
|
32
32
|
export const ACTIVITY_LIMIT = 80;
|
|
33
33
|
export const ACTIVITY_TEXT_LIMIT = 24 * 1024;
|
|
34
|
+
export const DISPLAY_ACTIVITY_LIMIT = 3;
|
|
34
35
|
// Auto-compaction enters the activity log as a synthetic entry so the worker's
|
|
35
36
|
// context maintenance is visible alongside its tool calls. Only one compaction
|
|
36
37
|
// can run at a time, so a single fixed id is enough to pair start with end.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/extensions/subagent/constants.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAC7C,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAC9C,MAAM,CAAC,MAAM,qBAAqB,GAAG,QAAQ,CAAC;AAC9C,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AACzC,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC;AAEpD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC;AAC3B,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC;AAEjC,yEAAyE;AACzE,0EAA0E;AAC1E,uDAAuD;AACvD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAClC,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,CAAC;AAE9C,4EAA4E;AAC5E,yEAAyE;AACzE,iFAAiF;AACjF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,UAAU,EAAE,SAAS,CAAU,CAAC;AAGrE,0EAA0E;AAC1E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAC9E,4EAA4E;AAC5E,sEAAsE;AACtE,mBAAmB;AACnB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAU,CAAC;AAE9E,MAAM,CAAC,MAAM,eAAe,GAAG;IAC9B,KAAK;IACL,SAAS;IACT,KAAK;IACL,QAAQ;IACR,MAAM;IACN,OAAO;IACP,KAAK;CACuC,CAAC;AAE9C,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,GAAG,IAAI,CAAC;AAC7C,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,sBAAsB,GAAG,YAAY,CAAC;AACnD,yEAAyE;AACzE,oEAAoE;AACpE,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,CAAC;AAC3C,mEAAmE;AACnE,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,CAAC;AAC5C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,CAAC;AACzC,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAC1C,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,GAAG,IAAI,CAAC;AAC/C,yEAAyE;AACzE,yEAAyE;AACzE,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\n\nexport const SUBAGENT_TOOL_NAME = \"subagent\";\nexport const SUBAGENT_TOOL_LABEL = \"Subagent\";\nexport const SUBAGENT_COMMAND_NAME = \"agents\";\nexport const SUBAGENT_CONFIG_VERSION = 1;\nexport const SUBAGENT_CONFIG_FILE = \"subagent.json\";\n\nexport const MAX_TASKS = 8;\nexport const MAX_CONCURRENCY = 6;\n\n// Task-level retry for failures that bypass the session's own auto-retry\n// (preflight throws such as auth checks). Only runs that produced nothing\n// are retried, so a retry never discards partial work.\nexport const TASK_RETRY_LIMIT = 2;\nexport const TASK_RETRY_BASE_DELAY_MS = 1_000;\n\n// The only selectable agents: the schema's agent field restricts task items\n// to these names, resolve.ts defaults an omitted/null agent to explorer.\n// SubagentAgentName is co-located with its source value; types.ts re-imports it.\nexport const SUBAGENT_AGENT_NAMES = [\"explorer\", \"general\"] as const;\nexport type SubagentAgentName = (typeof SUBAGENT_AGENT_NAMES)[number];\n\n// Matches the parent session's default toolset; bash covers search needs.\nexport const DEFAULT_AGENT_TOOLS = [\"read\", \"bash\", \"edit\", \"write\"] as const;\n// The read-only explorer profile gets the standalone search tools plus bash\n// for read-only inspection (git history, counting); the system prompt\n// constrains bash.\nexport const EXPLORER_TOOLS = [\"read\", \"grep\", \"find\", \"ls\", \"bash\"] as const;\n\nexport const THINKING_LEVELS = [\n\t\"off\",\n\t\"minimal\",\n\t\"low\",\n\t\"medium\",\n\t\"high\",\n\t\"xhigh\",\n\t\"max\",\n] as const satisfies readonly ThinkingLevel[];\n\nexport const ACTIVITY_LIMIT = 80;\nexport const ACTIVITY_TEXT_LIMIT = 24 * 1024;\n// Auto-compaction enters the activity log as a synthetic entry so the worker's\n// context maintenance is visible alongside its tool calls. Only one compaction\n// can run at a time, so a single fixed id is enough to pair start with end.\nexport const COMPACTION_ACTIVITY_ID = \"compaction\";\n// Per-task ceiling for the model-facing report; the total cap below wins\n// when the batch is large enough that a fair share would exceed it.\nexport const TASK_OUTPUT_LIMIT = 32 * 1024;\n// Total cap for the model-facing report across every task section.\nexport const TOTAL_OUTPUT_LIMIT = 48 * 1024;\nexport const ERROR_TEXT_LIMIT = 8 * 1024;\nexport const RETRY_ERROR_TEXT_LIMIT = 160;\nexport const DETAILS_OUTPUT_LIMIT = 120 * 1024;\n// Bounded per run inside DETAILS_OUTPUT_LIMIT; each activity costs up to\n// ~600 bytes, so 12 keeps an 8-run parallel batch from starving outputs.\nexport const DETAILS_ACTIVITY_LIMIT = 12;\n"]}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/extensions/subagent/constants.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAC7C,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAC9C,MAAM,CAAC,MAAM,qBAAqB,GAAG,QAAQ,CAAC;AAC9C,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AACzC,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC;AAEpD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC;AAC3B,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC;AAEjC,yEAAyE;AACzE,0EAA0E;AAC1E,uDAAuD;AACvD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAClC,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,CAAC;AAE9C,4EAA4E;AAC5E,yEAAyE;AACzE,iFAAiF;AACjF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,UAAU,EAAE,SAAS,CAAU,CAAC;AAGrE,0EAA0E;AAC1E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAC9E,4EAA4E;AAC5E,sEAAsE;AACtE,mBAAmB;AACnB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAU,CAAC;AAE9E,MAAM,CAAC,MAAM,eAAe,GAAG;IAC9B,KAAK;IACL,SAAS;IACT,KAAK;IACL,QAAQ;IACR,MAAM;IACN,OAAO;IACP,KAAK;CACuC,CAAC;AAE9C,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,GAAG,IAAI,CAAC;AAC7C,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AACxC,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,sBAAsB,GAAG,YAAY,CAAC;AACnD,yEAAyE;AACzE,oEAAoE;AACpE,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,CAAC;AAC3C,mEAAmE;AACnE,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,CAAC;AAC5C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,CAAC;AACzC,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAC1C,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,GAAG,IAAI,CAAC;AAC/C,yEAAyE;AACzE,yEAAyE;AACzE,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC","sourcesContent":["import type { ThinkingLevel } from \"@earendil-works/pi-agent-core\";\n\nexport const SUBAGENT_TOOL_NAME = \"subagent\";\nexport const SUBAGENT_TOOL_LABEL = \"Subagent\";\nexport const SUBAGENT_COMMAND_NAME = \"agents\";\nexport const SUBAGENT_CONFIG_VERSION = 1;\nexport const SUBAGENT_CONFIG_FILE = \"subagent.json\";\n\nexport const MAX_TASKS = 8;\nexport const MAX_CONCURRENCY = 6;\n\n// Task-level retry for failures that bypass the session's own auto-retry\n// (preflight throws such as auth checks). Only runs that produced nothing\n// are retried, so a retry never discards partial work.\nexport const TASK_RETRY_LIMIT = 2;\nexport const TASK_RETRY_BASE_DELAY_MS = 1_000;\n\n// The only selectable agents: the schema's agent field restricts task items\n// to these names, resolve.ts defaults an omitted/null agent to explorer.\n// SubagentAgentName is co-located with its source value; types.ts re-imports it.\nexport const SUBAGENT_AGENT_NAMES = [\"explorer\", \"general\"] as const;\nexport type SubagentAgentName = (typeof SUBAGENT_AGENT_NAMES)[number];\n\n// Matches the parent session's default toolset; bash covers search needs.\nexport const DEFAULT_AGENT_TOOLS = [\"read\", \"bash\", \"edit\", \"write\"] as const;\n// The read-only explorer profile gets the standalone search tools plus bash\n// for read-only inspection (git history, counting); the system prompt\n// constrains bash.\nexport const EXPLORER_TOOLS = [\"read\", \"grep\", \"find\", \"ls\", \"bash\"] as const;\n\nexport const THINKING_LEVELS = [\n\t\"off\",\n\t\"minimal\",\n\t\"low\",\n\t\"medium\",\n\t\"high\",\n\t\"xhigh\",\n\t\"max\",\n] as const satisfies readonly ThinkingLevel[];\n\nexport const ACTIVITY_LIMIT = 80;\nexport const ACTIVITY_TEXT_LIMIT = 24 * 1024;\nexport const DISPLAY_ACTIVITY_LIMIT = 3;\n// Auto-compaction enters the activity log as a synthetic entry so the worker's\n// context maintenance is visible alongside its tool calls. Only one compaction\n// can run at a time, so a single fixed id is enough to pair start with end.\nexport const COMPACTION_ACTIVITY_ID = \"compaction\";\n// Per-task ceiling for the model-facing report; the total cap below wins\n// when the batch is large enough that a fair share would exceed it.\nexport const TASK_OUTPUT_LIMIT = 32 * 1024;\n// Total cap for the model-facing report across every task section.\nexport const TOTAL_OUTPUT_LIMIT = 48 * 1024;\nexport const ERROR_TEXT_LIMIT = 8 * 1024;\nexport const RETRY_ERROR_TEXT_LIMIT = 160;\nexport const DETAILS_OUTPUT_LIMIT = 120 * 1024;\n// Bounded per run inside DETAILS_OUTPUT_LIMIT; each activity costs up to\n// ~600 bytes, so 12 keeps an 8-run parallel batch from starving outputs.\nexport const DETAILS_ACTIVITY_LIMIT = 12;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAYpF,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAYpF,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA+EvD"}
|
|
@@ -49,6 +49,7 @@ export default function subagent(pi) {
|
|
|
49
49
|
onUpdate: (details) => {
|
|
50
50
|
onUpdate?.({ content: [{ type: "text", text: statusSummary(details) }], details });
|
|
51
51
|
},
|
|
52
|
+
onConfigWarning: (message) => ctx.ui.notify(message, "warning"),
|
|
52
53
|
registerAbort: (abort) => {
|
|
53
54
|
activeAborters.add(abort);
|
|
54
55
|
return () => activeAborters.delete(abort);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/subagent/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { getAgentDir } from \"../../config.ts\";\nimport type { AgentToolResult, ExtensionAPI } from \"../../core/extensions/types.ts\";\nimport { emptyUsage } from \"./activity.ts\";\nimport { subagentToolDescription } from \"./agents.ts\";\nimport { showAgentsCommand } from \"./agents-command.ts\";\nimport { SUBAGENT_COMMAND_NAME, SUBAGENT_TOOL_LABEL, SUBAGENT_TOOL_NAME } from \"./constants.ts\";\nimport { renderSubagentCall, renderSubagentResult, type SubagentRenderState, scheduleLiveRefresh } from \"./render.ts\";\nimport type { ParentModelContext } from \"./resolve.ts\";\nimport { ConcurrencyGate, isSubagentError, runSubagentInvocation } from \"./runner.ts\";\nimport { SubagentParamsSchema } from \"./schema.ts\";\nimport { statusSummary } from \"./state.ts\";\nimport type { SubagentDetails } from \"./types.ts\";\n\nexport default function subagent(pi: ExtensionAPI): void {\n\tconst gate = new ConcurrencyGate();\n\tconst activeAborters = new Set<() => Promise<void>>();\n\n\tpi.registerTool<typeof SubagentParamsSchema, SubagentDetails, SubagentRenderState>({\n\t\tname: SUBAGENT_TOOL_NAME,\n\t\tlabel: SUBAGENT_TOOL_LABEL,\n\t\tdescription: subagentToolDescription(),\n\t\tpromptSnippet: \"Delegate bounded work to isolated explorer or general workers\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use `subagent` for bounded work that benefits from isolated context or concurrent investigation; do not delegate a task you can finish with one or two direct tool calls.\",\n\t\t],\n\t\tparameters: SubagentParamsSchema,\n\t\tasync execute(toolCallId, params, signal, onUpdate, ctx): Promise<AgentToolResult<SubagentDetails>> {\n\t\t\t// First paint before task preflight so filesystem and model checks\n\t\t\t// cannot leave the transcript card empty.\n\t\t\tonUpdate?.({\n\t\t\t\tcontent: [{ type: \"text\", text: \"Initializing…\" }],\n\t\t\t\tdetails: {\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t\truns: [],\n\t\t\t\t\tstartedAt: Date.now(),\n\t\t\t\t\tusage: emptyUsage(),\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst parent: ParentModelContext = {\n\t\t\t\tmodel: ctx.model,\n\t\t\t\tthinking: pi.getThinkingLevel(),\n\t\t\t\tmodelRegistry: ctx.modelRegistry,\n\t\t\t};\n\t\t\tconst execution = await runSubagentInvocation({\n\t\t\t\tparams,\n\t\t\t\tparentCwd: ctx.cwd,\n\t\t\t\tparent,\n\t\t\t\tmodelRuntime: ctx.modelRuntime,\n\t\t\t\tagentDir: getAgentDir(),\n\t\t\t\tprojectTrusted: ctx.isProjectTrusted(),\n\t\t\t\tsignal,\n\t\t\t\tgate,\n\t\t\t\tbatchId: toolCallId,\n\t\t\t\tonUpdate: (details) => {\n\t\t\t\t\tonUpdate?.({ content: [{ type: \"text\", text: statusSummary(details) }], details });\n\t\t\t\t},\n\t\t\t\tregisterAbort: (abort) => {\n\t\t\t\t\tactiveAborters.add(abort);\n\t\t\t\t\treturn () => activeAborters.delete(abort);\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: execution.content }],\n\t\t\t\tdetails: execution.details,\n\t\t\t\tusage: execution.usage,\n\t\t\t};\n\t\t},\n\t\trenderCall(args, theme) {\n\t\t\treturn renderSubagentCall(args, theme);\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tscheduleLiveRefresh(context, options.isPartial);\n\t\t\treturn renderSubagentResult(result, options, theme, context.args, context.isError);\n\t\t},\n\t});\n\n\tpi.registerCommand(SUBAGENT_COMMAND_NAME, {\n\t\tdescription: \"Configure Subagent profiles, models, and thinking levels\",\n\t\thandler: async (_args, ctx) => showAgentsCommand(ctx, pi.getThinkingLevel()),\n\t});\n\n\tpi.on(\"tool_result\", async (event) => {\n\t\tif (event.toolName !== SUBAGENT_TOOL_NAME) return;\n\t\tconst details = event.details as SubagentDetails | undefined;\n\t\tif (details && isSubagentError(details)) return { isError: true };\n\t});\n\n\tpi.on(\"session_shutdown\", async () => {\n\t\tawait Promise.allSettled([...activeAborters].map((abort) => abort()));\n\t\tactiveAborters.clear();\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/subagent/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { getAgentDir } from \"../../config.ts\";\nimport type { AgentToolResult, ExtensionAPI } from \"../../core/extensions/types.ts\";\nimport { emptyUsage } from \"./activity.ts\";\nimport { subagentToolDescription } from \"./agents.ts\";\nimport { showAgentsCommand } from \"./agents-command.ts\";\nimport { SUBAGENT_COMMAND_NAME, SUBAGENT_TOOL_LABEL, SUBAGENT_TOOL_NAME } from \"./constants.ts\";\nimport { renderSubagentCall, renderSubagentResult, type SubagentRenderState, scheduleLiveRefresh } from \"./render.ts\";\nimport type { ParentModelContext } from \"./resolve.ts\";\nimport { ConcurrencyGate, isSubagentError, runSubagentInvocation } from \"./runner.ts\";\nimport { SubagentParamsSchema } from \"./schema.ts\";\nimport { statusSummary } from \"./state.ts\";\nimport type { SubagentDetails } from \"./types.ts\";\n\nexport default function subagent(pi: ExtensionAPI): void {\n\tconst gate = new ConcurrencyGate();\n\tconst activeAborters = new Set<() => Promise<void>>();\n\n\tpi.registerTool<typeof SubagentParamsSchema, SubagentDetails, SubagentRenderState>({\n\t\tname: SUBAGENT_TOOL_NAME,\n\t\tlabel: SUBAGENT_TOOL_LABEL,\n\t\tdescription: subagentToolDescription(),\n\t\tpromptSnippet: \"Delegate bounded work to isolated explorer or general workers\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use `subagent` for bounded work that benefits from isolated context or concurrent investigation; do not delegate a task you can finish with one or two direct tool calls.\",\n\t\t],\n\t\tparameters: SubagentParamsSchema,\n\t\tasync execute(toolCallId, params, signal, onUpdate, ctx): Promise<AgentToolResult<SubagentDetails>> {\n\t\t\t// First paint before task preflight so filesystem and model checks\n\t\t\t// cannot leave the transcript card empty.\n\t\t\tonUpdate?.({\n\t\t\t\tcontent: [{ type: \"text\", text: \"Initializing…\" }],\n\t\t\t\tdetails: {\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t\truns: [],\n\t\t\t\t\tstartedAt: Date.now(),\n\t\t\t\t\tusage: emptyUsage(),\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst parent: ParentModelContext = {\n\t\t\t\tmodel: ctx.model,\n\t\t\t\tthinking: pi.getThinkingLevel(),\n\t\t\t\tmodelRegistry: ctx.modelRegistry,\n\t\t\t};\n\t\t\tconst execution = await runSubagentInvocation({\n\t\t\t\tparams,\n\t\t\t\tparentCwd: ctx.cwd,\n\t\t\t\tparent,\n\t\t\t\tmodelRuntime: ctx.modelRuntime,\n\t\t\t\tagentDir: getAgentDir(),\n\t\t\t\tprojectTrusted: ctx.isProjectTrusted(),\n\t\t\t\tsignal,\n\t\t\t\tgate,\n\t\t\t\tbatchId: toolCallId,\n\t\t\t\tonUpdate: (details) => {\n\t\t\t\t\tonUpdate?.({ content: [{ type: \"text\", text: statusSummary(details) }], details });\n\t\t\t\t},\n\t\t\t\tonConfigWarning: (message) => ctx.ui.notify(message, \"warning\"),\n\t\t\t\tregisterAbort: (abort) => {\n\t\t\t\t\tactiveAborters.add(abort);\n\t\t\t\t\treturn () => activeAborters.delete(abort);\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: execution.content }],\n\t\t\t\tdetails: execution.details,\n\t\t\t\tusage: execution.usage,\n\t\t\t};\n\t\t},\n\t\trenderCall(args, theme) {\n\t\t\treturn renderSubagentCall(args, theme);\n\t\t},\n\t\trenderResult(result, options, theme, context) {\n\t\t\tscheduleLiveRefresh(context, options.isPartial);\n\t\t\treturn renderSubagentResult(result, options, theme, context.args, context.isError);\n\t\t},\n\t});\n\n\tpi.registerCommand(SUBAGENT_COMMAND_NAME, {\n\t\tdescription: \"Configure Subagent profiles, models, and thinking levels\",\n\t\thandler: async (_args, ctx) => showAgentsCommand(ctx, pi.getThinkingLevel()),\n\t});\n\n\tpi.on(\"tool_result\", async (event) => {\n\t\tif (event.toolName !== SUBAGENT_TOOL_NAME) return;\n\t\tconst details = event.details as SubagentDetails | undefined;\n\t\tif (details && isSubagentError(details)) return { isError: true };\n\t});\n\n\tpi.on(\"session_shutdown\", async () => {\n\t\tawait Promise.allSettled([...activeAborters].map((abort) => abort()));\n\t\tactiveAborters.clear();\n\t});\n}\n"]}
|
|
@@ -2,14 +2,21 @@ import { type Component } from "@earendil-works/pi-tui";
|
|
|
2
2
|
import type { AgentToolResult, ToolRenderContext, ToolRenderResultOptions } from "../../core/extensions/types.ts";
|
|
3
3
|
import { type Theme } from "../../modes/interactive/theme/theme.ts";
|
|
4
4
|
import type { SubagentParams } from "./schema.ts";
|
|
5
|
-
import type { SubagentDetails } from "./types.ts";
|
|
5
|
+
import type { SubagentDetails, SubagentRunDetails } from "./types.ts";
|
|
6
6
|
/** Per-result live-refresh state owned by the shell's render context. */
|
|
7
7
|
export interface SubagentRenderState {
|
|
8
8
|
refreshTimer?: ReturnType<typeof setTimeout>;
|
|
9
9
|
/** Cadence the current timer was created with, used to detect changes. */
|
|
10
10
|
refreshInterval?: number;
|
|
11
|
+
/** Called by the shell when the transcript row is disposed. */
|
|
12
|
+
dispose?: () => void;
|
|
11
13
|
}
|
|
12
14
|
type SubagentToolRenderContext = ToolRenderContext<SubagentRenderState, SubagentParams, SubagentDetails>;
|
|
15
|
+
/** Pure refresh policy: schedule only while the current view contains changing text. */
|
|
16
|
+
export declare function desiredRefreshInterval(runs: readonly SubagentRunDetails[], options: {
|
|
17
|
+
isPartial: boolean;
|
|
18
|
+
expanded: boolean;
|
|
19
|
+
}): number | undefined;
|
|
13
20
|
export declare function scheduleLiveRefresh(context: SubagentToolRenderContext, isPartial: boolean): void;
|
|
14
21
|
export declare function renderSubagentCall(args: SubagentParams, theme: Theme): Component;
|
|
15
22
|
export declare function renderSubagentResult(result: AgentToolResult<SubagentDetails>, options: ToolRenderResultOptions, theme: Theme, args: SubagentParams, isError: boolean): Component;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/render.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,SAAS,EAOd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAClH,OAAO,EAAoB,KAAK,KAAK,
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/extensions/subagent/render.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,SAAS,EAOd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAClH,OAAO,EAAoB,KAAK,KAAK,EAAmB,MAAM,wCAAwC,CAAC;AAIvG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAmC,MAAM,YAAY,CAAC;AAiUvG,yEAAyE;AACzE,MAAM,WAAW,mBAAmB;IACnC,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAC7C,0EAA0E;IAC1E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,KAAK,yBAAyB,GAAG,iBAAiB,CAAC,mBAAmB,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;AAEzG,wFAAwF;AACxF,wBAAgB,sBAAsB,CACrC,IAAI,EAAE,SAAS,kBAAkB,EAAE,EACnC,OAAO,EAAE;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAChD,MAAM,GAAG,SAAS,CAQpB;AAWD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,yBAAyB,EAAE,SAAS,EAAE,OAAO,GAAG,IAAI,CAwBhG;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK,GAAG,SAAS,CAIhF;AAED,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,eAAe,CAAC,eAAe,CAAC,EACxC,OAAO,EAAE,uBAAuB,EAChC,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,OAAO,GACd,SAAS,CAiBX"}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { Container, Markdown, Spacer, Text, truncateToWidth, visibleWidth, } from "@earendil-works/pi-tui";
|
|
2
2
|
import { getMarkdownTheme } from "../../modes/interactive/theme/theme.js";
|
|
3
|
+
import { activityCallText, isDisplayableActivity } from "./activity.js";
|
|
3
4
|
import { AGENT_PROFILE_LABELS } from "./agents.js";
|
|
4
|
-
import { COMPACTION_ACTIVITY_ID } from "./constants.js";
|
|
5
|
+
import { COMPACTION_ACTIVITY_ID, DISPLAY_ACTIVITY_LIMIT } from "./constants.js";
|
|
5
6
|
import { getSubagentRetryView } from "./state.js";
|
|
6
7
|
import { plainLine, truncate } from "./text.js";
|
|
7
|
-
const ACTIVITY_RESULT_LIMIT = 96;
|
|
8
8
|
const RETRY_ERROR_LIMIT = 160;
|
|
9
9
|
const FALLBACK_OUTPUT_LIMIT = 4_000;
|
|
10
|
-
const ACTIVITY_DURATION_MIN_MS = 10_000;
|
|
11
10
|
const OUTPUT_TRUNCATION_NOTICE_PATTERN = /\s*\[Output truncated(?:: \d+ bytes omitted)?\.\]\s*$/u;
|
|
12
11
|
// A breathing dot-to-star bloom: the sequence plays forward to full bloom
|
|
13
12
|
// and back, holding each extreme for two ticks. The mid frame uses ✼ rather
|
|
@@ -75,17 +74,6 @@ function statusMarker(status, theme) {
|
|
|
75
74
|
: "○";
|
|
76
75
|
return theme.fg(statusColor(status), glyph);
|
|
77
76
|
}
|
|
78
|
-
function statusWord(status) {
|
|
79
|
-
if (status === "completed")
|
|
80
|
-
return "Completed";
|
|
81
|
-
if (status === "failed")
|
|
82
|
-
return "Failed";
|
|
83
|
-
if (status === "aborted")
|
|
84
|
-
return "Aborted";
|
|
85
|
-
if (status === "running")
|
|
86
|
-
return "Thinking...";
|
|
87
|
-
return "Queued";
|
|
88
|
-
}
|
|
89
77
|
function displayLine(text) {
|
|
90
78
|
return plainLine(text).replace(OUTPUT_TRUNCATION_NOTICE_PATTERN, "...").trim();
|
|
91
79
|
}
|
|
@@ -99,72 +87,22 @@ function retryText(run) {
|
|
|
99
87
|
const error = truncate(displayLine(retry.error), RETRY_ERROR_LIMIT);
|
|
100
88
|
return error ? `${state} · ${error}` : state;
|
|
101
89
|
}
|
|
102
|
-
function replaceToolPrefix(text, toolName, label, emptyLabel = label) {
|
|
103
|
-
if (text === toolName)
|
|
104
|
-
return emptyLabel;
|
|
105
|
-
if (text.startsWith(`${toolName} `))
|
|
106
|
-
return `${label}${text.slice(toolName.length)}`;
|
|
107
|
-
return text;
|
|
108
|
-
}
|
|
109
|
-
function activitySummary(activity) {
|
|
110
|
-
const summary = displayLine(activity.summary);
|
|
111
|
-
if (activity.toolName === COMPACTION_ACTIVITY_ID) {
|
|
112
|
-
return activity.status === "running" ? "Compacting..." : summary;
|
|
113
|
-
}
|
|
114
|
-
if (activity.toolName === "bash")
|
|
115
|
-
return summary === "bash" ? "Run" : summary;
|
|
116
|
-
if (activity.toolName === "read")
|
|
117
|
-
return replaceToolPrefix(summary, "read", "Read");
|
|
118
|
-
if (activity.toolName === "grep")
|
|
119
|
-
return replaceToolPrefix(summary, "grep", "Search");
|
|
120
|
-
if (activity.toolName === "find")
|
|
121
|
-
return replaceToolPrefix(summary, "find", "Find");
|
|
122
|
-
if (activity.toolName === "ls")
|
|
123
|
-
return replaceToolPrefix(summary, "ls", "List", "List .");
|
|
124
|
-
if (activity.toolName === "edit")
|
|
125
|
-
return replaceToolPrefix(summary, "edit", "Edit");
|
|
126
|
-
if (activity.toolName === "write")
|
|
127
|
-
return replaceToolPrefix(summary, "write", "Write");
|
|
128
|
-
return summary || activity.toolName;
|
|
129
|
-
}
|
|
130
90
|
function latestRunningActivity(run, toolName) {
|
|
131
91
|
for (let index = run.activities.length - 1; index >= 0; index--) {
|
|
132
92
|
const activity = run.activities[index];
|
|
133
|
-
if (activity?.status === "running" &&
|
|
93
|
+
if (activity?.status === "running" && activity.toolName === toolName)
|
|
134
94
|
return activity;
|
|
135
95
|
}
|
|
136
96
|
return undefined;
|
|
137
97
|
}
|
|
138
|
-
function
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
function runStateText(run) {
|
|
147
|
-
if (run.status === "completed" || run.status === "failed" || run.status === "aborted") {
|
|
148
|
-
const duration = elapsed(run.startedAt, run.endedAt);
|
|
149
|
-
return duration ? `${statusWord(run.status)} · ${duration}` : statusWord(run.status);
|
|
150
|
-
}
|
|
151
|
-
const retry = retryText(run);
|
|
152
|
-
if (retry)
|
|
153
|
-
return retry;
|
|
154
|
-
if (run.status === "queued")
|
|
155
|
-
return "Queued";
|
|
156
|
-
const compaction = latestRunningActivity(run, COMPACTION_ACTIVITY_ID);
|
|
157
|
-
if (compaction)
|
|
158
|
-
return "Compacting...";
|
|
159
|
-
const activity = latestRunningActivity(run);
|
|
160
|
-
if (activity)
|
|
161
|
-
return activitySummary(activity);
|
|
162
|
-
const current = fallbackCurrentActivity(run);
|
|
163
|
-
if (current)
|
|
164
|
-
return current;
|
|
165
|
-
if (run.status === "running" && run.usage.turns === 0 && run.usage.toolUses === 0)
|
|
166
|
-
return "Starting...";
|
|
167
|
-
return statusWord(run.status);
|
|
98
|
+
function formatTotalTokens(value) {
|
|
99
|
+
const count = Number.isFinite(value) ? Math.max(0, Math.round(value)) : 0;
|
|
100
|
+
if (count < 1_000)
|
|
101
|
+
return String(count);
|
|
102
|
+
const divisor = count < 999_950 ? 1_000 : 1_000_000;
|
|
103
|
+
const suffix = divisor === 1_000 ? "k" : "M";
|
|
104
|
+
const rounded = Math.round((count / divisor) * 10) / 10;
|
|
105
|
+
return `${Number.isInteger(rounded) ? rounded.toFixed(0) : rounded.toFixed(1)}${suffix}`;
|
|
168
106
|
}
|
|
169
107
|
function spinnerGlyph(now) {
|
|
170
108
|
const frame = Math.floor(now / SPINNER_INTERVAL_MS) % SPINNER_FRAMES.length;
|
|
@@ -200,8 +138,10 @@ class CollapsedFlow {
|
|
|
200
138
|
const usable = Math.max(1, width);
|
|
201
139
|
const joined = this.segments.join(FLOW_SEPARATOR);
|
|
202
140
|
const packed = visibleWidth(joined);
|
|
203
|
-
if (
|
|
204
|
-
return [
|
|
141
|
+
if (packed <= usable)
|
|
142
|
+
return [joined];
|
|
143
|
+
if (this.cellWidth > usable) {
|
|
144
|
+
return this.segments.map((segment) => truncateToWidth(segment, usable, "..."));
|
|
205
145
|
}
|
|
206
146
|
const columnCount = Math.max(1, Math.floor((usable + FLOW_SEPARATOR_WIDTH) / (this.cellWidth + FLOW_SEPARATOR_WIDTH)));
|
|
207
147
|
const lines = [];
|
|
@@ -220,80 +160,123 @@ class CollapsedFlow {
|
|
|
220
160
|
}
|
|
221
161
|
invalidate() { }
|
|
222
162
|
}
|
|
163
|
+
function toolCallLabel(count) {
|
|
164
|
+
return `${count} tool call${count === 1 ? "" : "s"}`;
|
|
165
|
+
}
|
|
223
166
|
function runHeader(run, index, theme) {
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
167
|
+
const separator = theme.fg("dim", " · ");
|
|
168
|
+
const duration = elapsed(run.startedAt, run.endedAt) ?? "0.0s";
|
|
169
|
+
const metrics = [
|
|
170
|
+
run.model,
|
|
171
|
+
run.thinking,
|
|
172
|
+
`${formatTotalTokens(run.usage.totalTokens)} tok`,
|
|
173
|
+
toolCallLabel(run.usage.toolUses),
|
|
174
|
+
duration,
|
|
175
|
+
].map((metric) => theme.fg("muted", metric));
|
|
176
|
+
return [theme.fg("accent", theme.bold(`#${index + 1} ${profileLabel(run.agent)}`)), ...metrics].join(separator);
|
|
177
|
+
}
|
|
178
|
+
function sectionTitle(title, theme, color, suffix) {
|
|
179
|
+
const heading = theme.fg(color, theme.bold(title));
|
|
180
|
+
return suffix ? `${heading}${theme.fg("dim", ` · ${suffix}`)}` : heading;
|
|
181
|
+
}
|
|
182
|
+
function activityTitleSuffix(total, shown) {
|
|
183
|
+
if (total <= DISPLAY_ACTIVITY_LIMIT && shown >= total)
|
|
184
|
+
return toolCallLabel(total);
|
|
185
|
+
if (shown > 0)
|
|
186
|
+
return `last ${shown} of ${total} tool calls`;
|
|
187
|
+
return toolCallLabel(total);
|
|
237
188
|
}
|
|
238
189
|
function activityLine(activity, theme) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
if (activity.status === "
|
|
246
|
-
|
|
247
|
-
}
|
|
248
|
-
if (activity.endedAt !== undefined && activity.endedAt - activity.startedAt >= ACTIVITY_DURATION_MIN_MS) {
|
|
249
|
-
line += theme.fg("dim", ` · ${formatDuration((activity.endedAt - activity.startedAt) / 1_000)}`);
|
|
250
|
-
}
|
|
251
|
-
return line;
|
|
190
|
+
// State color stays on the two-column status marker; the call text itself
|
|
191
|
+
// keeps the quiet toolOutput color so a running row does not flash a whole
|
|
192
|
+
// accent-colored command line on every refresh.
|
|
193
|
+
const text = theme.fg("toolOutput", activityCallText(activity));
|
|
194
|
+
if (activity.status === "failed")
|
|
195
|
+
return `${theme.fg("error", "×")} ${text}`;
|
|
196
|
+
if (activity.status === "running")
|
|
197
|
+
return `${theme.fg("accent", "›")} ${text}`;
|
|
198
|
+
return ` ${text}`;
|
|
252
199
|
}
|
|
253
200
|
function addPrompt(container, run, index, args, theme) {
|
|
254
|
-
container.addChild(new
|
|
255
|
-
container.addChild(new Text(theme.fg("
|
|
256
|
-
container.addChild(new Text(theme.fg("toolOutput", taskPrompt(args, index, run)), 0, 0));
|
|
201
|
+
container.addChild(new Text(sectionTitle("Prompt", theme, "toolTitle"), 0, 0));
|
|
202
|
+
container.addChild(new Text(theme.fg("toolOutput", taskPrompt(args, index, run)), 2, 0));
|
|
257
203
|
}
|
|
258
|
-
function
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
container.addChild(new
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
if (retry) {
|
|
268
|
-
container.addChild(new SingleLineText(`${statusMarker(run.status, theme)} ${theme.fg("toolOutput", retry)}`));
|
|
204
|
+
function addActivity(container, run, theme) {
|
|
205
|
+
const toolCalls = run.activities.filter(isDisplayableActivity);
|
|
206
|
+
const shown = toolCalls.slice(-DISPLAY_ACTIVITY_LIMIT);
|
|
207
|
+
const total = Math.max(run.usage.toolUses, toolCalls.length);
|
|
208
|
+
container.addChild(new Text(sectionTitle("Activity", theme, "toolTitle", activityTitleSuffix(total, shown.length)), 0, 0));
|
|
209
|
+
if (shown.length === 0) {
|
|
210
|
+
const empty = total === 0 ? "No tool calls yet." : "Activity unavailable.";
|
|
211
|
+
container.addChild(new Text(theme.fg("muted", empty), 2, 0));
|
|
212
|
+
return;
|
|
269
213
|
}
|
|
270
|
-
for (const activity of
|
|
214
|
+
for (const activity of shown)
|
|
271
215
|
container.addChild(new SingleLineText(activityLine(activity, theme)));
|
|
272
|
-
|
|
273
|
-
|
|
216
|
+
}
|
|
217
|
+
function outcomeColor(status) {
|
|
218
|
+
if (status === "completed")
|
|
219
|
+
return "success";
|
|
220
|
+
if (status === "failed")
|
|
221
|
+
return "error";
|
|
222
|
+
if (status === "aborted")
|
|
223
|
+
return "warning";
|
|
224
|
+
return "accent";
|
|
225
|
+
}
|
|
226
|
+
function outcomeReport(run) {
|
|
227
|
+
if (typeof run.report === "string")
|
|
228
|
+
return run.report;
|
|
229
|
+
const legacyOutput = run.finalOutput;
|
|
230
|
+
return typeof legacyOutput === "string" ? legacyOutput : "";
|
|
231
|
+
}
|
|
232
|
+
function hasOutcome(report) {
|
|
233
|
+
return report.trim().length > 0;
|
|
234
|
+
}
|
|
235
|
+
function addOutcomeMarkdown(container, report, theme) {
|
|
236
|
+
container.addChild(new Markdown(report, 2, 0, getMarkdownTheme(), {
|
|
237
|
+
color: (text) => theme.fg("toolOutput", text),
|
|
238
|
+
}));
|
|
239
|
+
}
|
|
240
|
+
function addOutcome(container, run, theme) {
|
|
241
|
+
const color = outcomeColor(run.status);
|
|
242
|
+
const report = outcomeReport(run);
|
|
243
|
+
container.addChild(new Text(sectionTitle("Outcome", theme, color), 0, 0));
|
|
244
|
+
if (run.status === "queued" || run.status === "running") {
|
|
245
|
+
container.addChild(new Text(theme.fg("muted", "Still running..."), 2, 0));
|
|
246
|
+
const retry = retryText(run);
|
|
247
|
+
if (retry) {
|
|
248
|
+
container.addChild(new Text(theme.fg("warning", retry), 2, 0));
|
|
249
|
+
}
|
|
250
|
+
else if (latestRunningActivity(run, COMPACTION_ACTIVITY_ID)) {
|
|
251
|
+
container.addChild(new Text(theme.fg("accent", "Compacting context..."), 2, 0));
|
|
252
|
+
}
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (run.status === "completed") {
|
|
256
|
+
if (hasOutcome(report))
|
|
257
|
+
addOutcomeMarkdown(container, report, theme);
|
|
258
|
+
else
|
|
259
|
+
container.addChild(new Text(theme.fg("muted", "No outcome returned."), 2, 0));
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const verdict = run.status === "failed" ? "Failed" : "Aborted";
|
|
263
|
+
const reason = run.error ? `${verdict}: ${run.error}` : `${verdict}.`;
|
|
264
|
+
container.addChild(new Text(theme.fg(color, reason), 2, 0));
|
|
265
|
+
if (hasOutcome(report)) {
|
|
266
|
+
container.addChild(new Spacer(1));
|
|
267
|
+
container.addChild(new Text(theme.fg("muted", "Partial outcome:"), 2, 0));
|
|
268
|
+
addOutcomeMarkdown(container, report, theme);
|
|
274
269
|
}
|
|
275
|
-
return container;
|
|
276
270
|
}
|
|
277
|
-
function
|
|
271
|
+
function renderRun(run, index, args, theme) {
|
|
278
272
|
const container = new Container();
|
|
279
273
|
container.addChild(new SingleLineText(runHeader(run, index, theme)));
|
|
274
|
+
container.addChild(new Spacer(1));
|
|
280
275
|
addPrompt(container, run, index, args, theme);
|
|
281
|
-
if (run.error) {
|
|
282
|
-
container.addChild(new Spacer(1));
|
|
283
|
-
container.addChild(new Text(theme.fg("muted", "Error"), 0, 0));
|
|
284
|
-
container.addChild(new Text(theme.fg("error", run.error), 0, 0));
|
|
285
|
-
}
|
|
286
276
|
container.addChild(new Spacer(1));
|
|
287
|
-
|
|
288
|
-
container.addChild(new
|
|
289
|
-
|
|
290
|
-
container.addChild(new Markdown(run.report, 0, 0, getMarkdownTheme(), {
|
|
291
|
-
color: (text) => theme.fg("toolOutput", text),
|
|
292
|
-
}));
|
|
293
|
-
}
|
|
294
|
-
else {
|
|
295
|
-
container.addChild(new Text(theme.fg("muted", "(No report.)"), 0, 0));
|
|
296
|
-
}
|
|
277
|
+
addActivity(container, run, theme);
|
|
278
|
+
container.addChild(new Spacer(1));
|
|
279
|
+
addOutcome(container, run, theme);
|
|
297
280
|
return container;
|
|
298
281
|
}
|
|
299
282
|
function fallbackResult(result, theme, isError) {
|
|
@@ -301,60 +284,57 @@ function fallbackResult(result, theme, isError) {
|
|
|
301
284
|
const value = text?.type === "text" ? truncate(text.text, FALLBACK_OUTPUT_LIMIT) : "(no output)";
|
|
302
285
|
return new Text(theme.fg(isError ? "error" : "muted", value), 0, 0);
|
|
303
286
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
287
|
+
/** Pure refresh policy: schedule only while the current view contains changing text. */
|
|
288
|
+
export function desiredRefreshInterval(runs, options) {
|
|
289
|
+
if (!options.isPartial)
|
|
290
|
+
return undefined;
|
|
291
|
+
if (!options.expanded) {
|
|
292
|
+
return runs.some((run) => run.status === "running") ? SPINNER_INTERVAL_MS : undefined;
|
|
293
|
+
}
|
|
294
|
+
return runs.some((run) => run.status === "running" || run.retry !== undefined)
|
|
295
|
+
? ELAPSED_REFRESH_INTERVAL_MS
|
|
296
|
+
: undefined;
|
|
308
297
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
298
|
+
function clearLiveRefresh(state) {
|
|
299
|
+
if (state.refreshTimer !== undefined)
|
|
300
|
+
clearTimeout(state.refreshTimer);
|
|
301
|
+
state.refreshTimer = undefined;
|
|
302
|
+
state.refreshInterval = undefined;
|
|
303
|
+
}
|
|
304
|
+
// One one-shot timer per row. A paint with the same cadence keeps the existing
|
|
305
|
+
// deadline; expansion, settlement, or loss of dynamic content clears or
|
|
306
|
+
// reschedules immediately.
|
|
314
307
|
export function scheduleLiveRefresh(context, isPartial) {
|
|
315
308
|
const state = context.state;
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
return;
|
|
324
|
-
clearTimeout(state.refreshTimer);
|
|
325
|
-
}
|
|
326
|
-
state.refreshInterval = interval;
|
|
327
|
-
state.refreshTimer = setTimeout(() => {
|
|
328
|
-
state.refreshTimer = undefined;
|
|
329
|
-
state.refreshInterval = undefined;
|
|
330
|
-
context.invalidate();
|
|
331
|
-
}, interval);
|
|
332
|
-
state.refreshTimer.unref?.();
|
|
309
|
+
state.dispose ??= () => clearLiveRefresh(state);
|
|
310
|
+
const interval = desiredRefreshInterval(context.result?.details?.runs ?? [], {
|
|
311
|
+
isPartial,
|
|
312
|
+
expanded: context.expanded,
|
|
313
|
+
});
|
|
314
|
+
if (interval === undefined) {
|
|
315
|
+
clearLiveRefresh(state);
|
|
333
316
|
return;
|
|
334
317
|
}
|
|
335
318
|
if (state.refreshTimer !== undefined) {
|
|
319
|
+
// Keep a matching timer so unrelated re-renders cannot postpone the
|
|
320
|
+
// next tick; only reschedule when the desired cadence changes.
|
|
321
|
+
if (state.refreshInterval === interval)
|
|
322
|
+
return;
|
|
336
323
|
clearTimeout(state.refreshTimer);
|
|
324
|
+
}
|
|
325
|
+
state.refreshInterval = interval;
|
|
326
|
+
state.refreshTimer = setTimeout(() => {
|
|
337
327
|
state.refreshTimer = undefined;
|
|
338
328
|
state.refreshInterval = undefined;
|
|
339
|
-
|
|
329
|
+
context.invalidate();
|
|
330
|
+
}, interval);
|
|
331
|
+
state.refreshTimer.unref?.();
|
|
340
332
|
}
|
|
341
333
|
export function renderSubagentCall(args, theme) {
|
|
342
334
|
const count = Array.isArray(args.tasks) ? args.tasks.length : 0;
|
|
343
335
|
const title = theme.fg(count > 0 ? "toolTitle" : "error", theme.bold("Subagent"));
|
|
344
336
|
return new Text(title, 0, 0);
|
|
345
337
|
}
|
|
346
|
-
/** Batch-level timing and cost live only in the expanded view. */
|
|
347
|
-
function batchSummaryLine(details, theme, isPartial) {
|
|
348
|
-
const parts = [];
|
|
349
|
-
const duration = elapsed(details.startedAt, details.endedAt);
|
|
350
|
-
if (duration)
|
|
351
|
-
parts.push(duration);
|
|
352
|
-
const cost = details.usage?.cost;
|
|
353
|
-
if (!isPartial && typeof cost === "number" && Number.isFinite(cost) && cost > 0)
|
|
354
|
-
parts.push(`$${cost.toFixed(3)}`);
|
|
355
|
-
const tasks = `${details.runs.length} task${details.runs.length === 1 ? "" : "s"}`;
|
|
356
|
-
return `${theme.fg("dim", `── Batch · ${tasks}`)}${parts.length > 0 ? `${theme.fg("dim", ` · ${parts.join(" · ")}`)}` : ""}`;
|
|
357
|
-
}
|
|
358
338
|
export function renderSubagentResult(result, options, theme, args, isError) {
|
|
359
339
|
const details = result.details;
|
|
360
340
|
if (!details || !Array.isArray(details.runs))
|
|
@@ -367,13 +347,10 @@ export function renderSubagentResult(result, options, theme, args, isError) {
|
|
|
367
347
|
container.addChild(new CollapsedFlow(details.runs.map((run, index) => flowSegment(run, index, theme, now))));
|
|
368
348
|
return container;
|
|
369
349
|
}
|
|
370
|
-
container.addChild(new SingleLineText(batchSummaryLine(details, theme, options.isPartial)));
|
|
371
|
-
container.addChild(new Spacer(1));
|
|
372
350
|
for (const [index, run] of details.runs.entries()) {
|
|
373
351
|
if (index > 0)
|
|
374
352
|
container.addChild(new Spacer(1));
|
|
375
|
-
|
|
376
|
-
container.addChild(settled ? renderSettledRun(run, index, args, theme) : renderRunningRun(run, index, args, theme));
|
|
353
|
+
container.addChild(renderRun(run, index, args, theme));
|
|
377
354
|
}
|
|
378
355
|
return container;
|
|
379
356
|
}
|