@kr78/pi-coding-agent 17.2.10
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 +14861 -0
- package/README.md +35 -0
- package/dist/CHANGELOG-chtdxh1z.md +14861 -0
- package/dist/cli.js +20483 -0
- package/dist/template-c2hyaytt.js +1653 -0
- package/dist/template-f8wx9vfn.css +1355 -0
- package/dist/template-qat058wr.html +55 -0
- package/dist/tool-views.generated-jdfmzwmn.js +35 -0
- package/examples/README.md +21 -0
- package/examples/custom-tools/README.md +104 -0
- package/examples/custom-tools/hello/index.ts +20 -0
- package/examples/extensions/README.md +142 -0
- package/examples/extensions/api-demo.ts +78 -0
- package/examples/extensions/chalk-logger.ts +25 -0
- package/examples/extensions/hello.ts +31 -0
- package/examples/extensions/pirate.ts +43 -0
- package/examples/extensions/plan-mode.ts +549 -0
- package/examples/extensions/reload-runtime.ts +38 -0
- package/examples/extensions/thinking-note.ts +13 -0
- package/examples/extensions/tools.ts +145 -0
- package/examples/extensions/with-deps/index.ts +36 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +17 -0
- package/examples/hooks/README.md +56 -0
- package/examples/hooks/auto-commit-on-exit.ts +48 -0
- package/examples/hooks/confirm-destructive.ts +58 -0
- package/examples/hooks/custom-compaction.ts +115 -0
- package/examples/hooks/dirty-repo-guard.ts +51 -0
- package/examples/hooks/file-trigger.ts +40 -0
- package/examples/hooks/git-checkpoint.ts +52 -0
- package/examples/hooks/handoff.ts +149 -0
- package/examples/hooks/permission-gate.ts +33 -0
- package/examples/hooks/protected-paths.ts +29 -0
- package/examples/hooks/qna.ts +118 -0
- package/examples/hooks/status-line.ts +39 -0
- package/examples/sdk/01-minimal.ts +21 -0
- package/examples/sdk/02-custom-model.ts +49 -0
- package/examples/sdk/03-custom-prompt.ts +46 -0
- package/examples/sdk/04-skills.ts +43 -0
- package/examples/sdk/06-extensions.ts +82 -0
- package/examples/sdk/06-hooks.ts +61 -0
- package/examples/sdk/07-context-files.ts +35 -0
- package/examples/sdk/08-prompt-templates.ts +41 -0
- package/examples/sdk/08-slash-commands.ts +46 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +54 -0
- package/examples/sdk/11-sessions.ts +47 -0
- package/examples/sdk/12-redis-sessions.ts +54 -0
- package/examples/sdk/13-sql-sessions.ts +61 -0
- package/examples/sdk/README.md +169 -0
- package/package.json +587 -0
- package/scripts/bench-guard.ts +71 -0
- package/scripts/bench-title-models.ts +332 -0
- package/scripts/build-binary.ts +117 -0
- package/scripts/bundle-dist.ts +123 -0
- package/scripts/compile-binary.ts +69 -0
- package/scripts/embed-mupdf-wasm.ts +67 -0
- package/scripts/format-prompts.ts +68 -0
- package/scripts/generate-aria-snapshot.ts +134 -0
- package/scripts/generate-docs-index.ts +58 -0
- package/scripts/generate-share-viewer.ts +34 -0
- package/scripts/legacy-pi-virtual-module.ts +205 -0
- package/scripts/measure-prompt-tokens.ts +63 -0
- package/scripts/omp +51 -0
- package/scripts/omp.ts +19 -0
- package/scripts/security-compare.ts +40 -0
- package/src/advisor/advise-tool.ts +234 -0
- package/src/advisor/config.ts +341 -0
- package/src/advisor/emission-guard.ts +172 -0
- package/src/advisor/index.ts +6 -0
- package/src/advisor/runtime.ts +1412 -0
- package/src/advisor/transcript-recorder.ts +215 -0
- package/src/advisor/watchdog.ts +135 -0
- package/src/async/index.ts +1 -0
- package/src/async/job-manager.ts +847 -0
- package/src/auto-thinking/classifier.ts +220 -0
- package/src/autolearn/controller.ts +152 -0
- package/src/autolearn/managed-skills.ts +255 -0
- package/src/autoresearch/command-resume.md +14 -0
- package/src/autoresearch/dashboard.ts +436 -0
- package/src/autoresearch/git.ts +331 -0
- package/src/autoresearch/helpers.ts +218 -0
- package/src/autoresearch/index.ts +541 -0
- package/src/autoresearch/prompt-setup.md +43 -0
- package/src/autoresearch/prompt.md +103 -0
- package/src/autoresearch/resume-message.md +10 -0
- package/src/autoresearch/state.ts +273 -0
- package/src/autoresearch/storage.ts +700 -0
- package/src/autoresearch/tools/init-experiment.ts +268 -0
- package/src/autoresearch/tools/log-experiment.ts +520 -0
- package/src/autoresearch/tools/run-experiment.ts +407 -0
- package/src/autoresearch/tools/update-notes.ts +109 -0
- package/src/autoresearch/types.ts +168 -0
- package/src/capability/context-file.ts +44 -0
- package/src/capability/extension-module.ts +34 -0
- package/src/capability/extension.ts +47 -0
- package/src/capability/fs.ts +117 -0
- package/src/capability/hook.ts +40 -0
- package/src/capability/index.ts +467 -0
- package/src/capability/instruction.ts +37 -0
- package/src/capability/mcp.ts +115 -0
- package/src/capability/prompt.ts +35 -0
- package/src/capability/rule-buckets.ts +66 -0
- package/src/capability/rule.ts +298 -0
- package/src/capability/settings.ts +34 -0
- package/src/capability/skill.ts +69 -0
- package/src/capability/slash-command.ts +40 -0
- package/src/capability/ssh.ts +41 -0
- package/src/capability/system-prompt.ts +34 -0
- package/src/capability/tool.ts +38 -0
- package/src/capability/types.ts +187 -0
- package/src/cleanse/agent.ts +226 -0
- package/src/cleanse/balance.ts +79 -0
- package/src/cleanse/checkers.ts +996 -0
- package/src/cleanse/index.ts +190 -0
- package/src/cleanse/loop.ts +51 -0
- package/src/cleanse/parsers.ts +726 -0
- package/src/cleanse/progress.ts +50 -0
- package/src/cleanse/prompts/assignment.md +47 -0
- package/src/cleanse/types.ts +72 -0
- package/src/cli/agents-cli.ts +138 -0
- package/src/cli/args.ts +368 -0
- package/src/cli/auth-broker-cli.ts +940 -0
- package/src/cli/auth-gateway-cli.ts +674 -0
- package/src/cli/bench-cli.ts +990 -0
- package/src/cli/browser-relay-cli.ts +119 -0
- package/src/cli/classify-install-target.ts +76 -0
- package/src/cli/claude-trace-cli.ts +795 -0
- package/src/cli/command-help.ts +107 -0
- package/src/cli/commands/init-xdg.ts +27 -0
- package/src/cli/completion-gen.ts +550 -0
- package/src/cli/config-cli.ts +459 -0
- package/src/cli/dry-balance-cli.ts +864 -0
- package/src/cli/extension-flags.ts +48 -0
- package/src/cli/file-processor.ts +132 -0
- package/src/cli/flag-tables.ts +367 -0
- package/src/cli/gallery-cli.ts +272 -0
- package/src/cli/gallery-fixtures/agentic.ts +420 -0
- package/src/cli/gallery-fixtures/codeintel.ts +187 -0
- package/src/cli/gallery-fixtures/edit.ts +254 -0
- package/src/cli/gallery-fixtures/fs.ts +245 -0
- package/src/cli/gallery-fixtures/index.ts +40 -0
- package/src/cli/gallery-fixtures/interaction.ts +46 -0
- package/src/cli/gallery-fixtures/memory.ts +81 -0
- package/src/cli/gallery-fixtures/misc.ts +177 -0
- package/src/cli/gallery-fixtures/search.ts +135 -0
- package/src/cli/gallery-fixtures/shell.ts +241 -0
- package/src/cli/gallery-fixtures/types.ts +57 -0
- package/src/cli/gallery-fixtures/web.ts +158 -0
- package/src/cli/gallery-screenshot.ts +279 -0
- package/src/cli/gc-cli.ts +1566 -0
- package/src/cli/grep-cli.ts +161 -0
- package/src/cli/grievances-cli.ts +256 -0
- package/src/cli/help-extra.ts +89 -0
- package/src/cli/initial-message.ts +58 -0
- package/src/cli/models-cli.ts +385 -0
- package/src/cli/plugin-cli.ts +996 -0
- package/src/cli/profile-alias.ts +369 -0
- package/src/cli/profile-bootstrap.ts +233 -0
- package/src/cli/read-cli.ts +99 -0
- package/src/cli/session-picker.ts +110 -0
- package/src/cli/setup-cli.ts +312 -0
- package/src/cli/setup-model-picker.ts +43 -0
- package/src/cli/shell-cli.ts +176 -0
- package/src/cli/ssh-cli.ts +179 -0
- package/src/cli/startup-cwd.ts +58 -0
- package/src/cli/stats-cli.ts +229 -0
- package/src/cli/thinking-levels.ts +7 -0
- package/src/cli/tiny-models-cli.ts +153 -0
- package/src/cli/ttsr-cli.ts +1013 -0
- package/src/cli/update-cli.ts +1184 -0
- package/src/cli/usage-cli.ts +1084 -0
- package/src/cli/usage-error.ts +7 -0
- package/src/cli/web-search-cli.ts +144 -0
- package/src/cli/worktree-cli.ts +311 -0
- package/src/cli-commands.ts +308 -0
- package/src/cli.ts +428 -0
- package/src/collab/crypto.ts +63 -0
- package/src/collab/display-name.ts +13 -0
- package/src/collab/guest.ts +764 -0
- package/src/collab/host.ts +692 -0
- package/src/collab/protocol.ts +296 -0
- package/src/collab/relay-client.ts +282 -0
- package/src/collab/replication-shrink.ts +111 -0
- package/src/commands/acp.ts +35 -0
- package/src/commands/agents.ts +58 -0
- package/src/commands/auth-broker.ts +100 -0
- package/src/commands/auth-gateway.ts +70 -0
- package/src/commands/bench.ts +64 -0
- package/src/commands/browser-relay.ts +53 -0
- package/src/commands/cleanse.ts +45 -0
- package/src/commands/commit.ts +47 -0
- package/src/commands/complete.ts +67 -0
- package/src/commands/completions.ts +61 -0
- package/src/commands/config.ts +52 -0
- package/src/commands/dry-balance.ts +43 -0
- package/src/commands/gallery.ts +61 -0
- package/src/commands/gc.ts +47 -0
- package/src/commands/grep.ts +49 -0
- package/src/commands/grievances.ts +52 -0
- package/src/commands/install.ts +107 -0
- package/src/commands/join.ts +40 -0
- package/src/commands/launch-help.ts +116 -0
- package/src/commands/launch.ts +34 -0
- package/src/commands/models.ts +61 -0
- package/src/commands/plugin.ts +79 -0
- package/src/commands/read.ts +39 -0
- package/src/commands/say.ts +146 -0
- package/src/commands/setup.ts +68 -0
- package/src/commands/share.ts +71 -0
- package/src/commands/shell.ts +30 -0
- package/src/commands/ssh.ts +61 -0
- package/src/commands/stats.ts +30 -0
- package/src/commands/tiny-models.ts +36 -0
- package/src/commands/token.ts +164 -0
- package/src/commands/ttsr.ts +125 -0
- package/src/commands/update.ts +34 -0
- package/src/commands/usage.ts +55 -0
- package/src/commands/web-search.ts +43 -0
- package/src/commands/worktree.ts +63 -0
- package/src/commit/agentic/agent.ts +322 -0
- package/src/commit/agentic/fallback.ts +96 -0
- package/src/commit/agentic/index.ts +383 -0
- package/src/commit/agentic/lock-files.ts +107 -0
- package/src/commit/agentic/prompts/analyze-file.md +22 -0
- package/src/commit/agentic/prompts/session-user.md +25 -0
- package/src/commit/agentic/prompts/split-confirm.md +1 -0
- package/src/commit/agentic/prompts/system.md +38 -0
- package/src/commit/agentic/state.ts +60 -0
- package/src/commit/agentic/tools/analyze-file.ts +148 -0
- package/src/commit/agentic/tools/git-file-diff.ts +191 -0
- package/src/commit/agentic/tools/git-hunk.ts +52 -0
- package/src/commit/agentic/tools/git-overview.ts +62 -0
- package/src/commit/agentic/tools/index.ts +54 -0
- package/src/commit/agentic/tools/propose-changelog.ts +147 -0
- package/src/commit/agentic/tools/propose-commit.ts +109 -0
- package/src/commit/agentic/tools/recent-commits.ts +81 -0
- package/src/commit/agentic/tools/schemas.ts +11 -0
- package/src/commit/agentic/tools/split-commit.ts +241 -0
- package/src/commit/agentic/topo-sort.ts +44 -0
- package/src/commit/agentic/trivial.ts +51 -0
- package/src/commit/agentic/validation.ts +183 -0
- package/src/commit/analysis/conventional.ts +64 -0
- package/src/commit/analysis/index.ts +4 -0
- package/src/commit/analysis/scope.ts +242 -0
- package/src/commit/analysis/summary.ts +107 -0
- package/src/commit/analysis/validation.ts +66 -0
- package/src/commit/changelog/detect.ts +40 -0
- package/src/commit/changelog/generate.ts +101 -0
- package/src/commit/changelog/index.ts +234 -0
- package/src/commit/changelog/parse.ts +44 -0
- package/src/commit/cli.ts +85 -0
- package/src/commit/git/diff.ts +148 -0
- package/src/commit/index.ts +5 -0
- package/src/commit/map-reduce/index.ts +69 -0
- package/src/commit/map-reduce/map-phase.ts +193 -0
- package/src/commit/map-reduce/reduce-phase.ts +49 -0
- package/src/commit/map-reduce/utils.ts +9 -0
- package/src/commit/message.ts +11 -0
- package/src/commit/model-selection.ts +95 -0
- package/src/commit/pipeline.ts +244 -0
- package/src/commit/prompts/analysis-system.md +148 -0
- package/src/commit/prompts/analysis-user.md +38 -0
- package/src/commit/prompts/changelog-system.md +50 -0
- package/src/commit/prompts/changelog-user.md +18 -0
- package/src/commit/prompts/file-observer-system.md +24 -0
- package/src/commit/prompts/file-observer-user.md +8 -0
- package/src/commit/prompts/reduce-system.md +50 -0
- package/src/commit/prompts/reduce-user.md +17 -0
- package/src/commit/prompts/summary-retry.md +3 -0
- package/src/commit/prompts/summary-system.md +38 -0
- package/src/commit/prompts/summary-user.md +13 -0
- package/src/commit/prompts/types-description.md +2 -0
- package/src/commit/shared-llm.ts +70 -0
- package/src/commit/types.ts +118 -0
- package/src/commit/utils/exclusions.ts +42 -0
- package/src/commit/utils.ts +58 -0
- package/src/config/api-key-resolver.ts +81 -0
- package/src/config/append-only-context-mode.ts +76 -0
- package/src/config/config-file.ts +347 -0
- package/src/config/inline-tool-descriptors-mode.ts +26 -0
- package/src/config/keybindings.ts +703 -0
- package/src/config/mcp-schema.json +252 -0
- package/src/config/model-discovery.ts +1077 -0
- package/src/config/model-registry.ts +2822 -0
- package/src/config/model-resolver.ts +2115 -0
- package/src/config/model-roles.ts +113 -0
- package/src/config/models-config-schema-bundle.ts +315 -0
- package/src/config/models-config-schema.ts +14 -0
- package/src/config/models-config.ts +130 -0
- package/src/config/prompt-templates.ts +205 -0
- package/src/config/provider-globals.ts +25 -0
- package/src/config/resolve-config-value.ts +95 -0
- package/src/config/service-tier.ts +146 -0
- package/src/config/settings-schema.ts +5887 -0
- package/src/config/settings.ts +2394 -0
- package/src/config.ts +242 -0
- package/src/cursor-bridge-tools.ts +81 -0
- package/src/cursor.ts +960 -0
- package/src/dap/client.ts +1043 -0
- package/src/dap/config.ts +480 -0
- package/src/dap/defaults.json +212 -0
- package/src/dap/index.ts +4 -0
- package/src/dap/session.ts +1841 -0
- package/src/dap/types.ts +611 -0
- package/src/debug/index.ts +584 -0
- package/src/debug/log-formatting.ts +58 -0
- package/src/debug/log-viewer.ts +966 -0
- package/src/debug/profiler.ts +168 -0
- package/src/debug/protocol-probe.ts +267 -0
- package/src/debug/raw-sse-buffer.ts +421 -0
- package/src/debug/raw-sse.ts +312 -0
- package/src/debug/remote-debugger.ts +151 -0
- package/src/debug/report-bundle.ts +411 -0
- package/src/debug/system-info.ts +111 -0
- package/src/debug/terminal-info.ts +124 -0
- package/src/discovery/agent-plugin-format.ts +551 -0
- package/src/discovery/agent-plugins.ts +341 -0
- package/src/discovery/agents-md.ts +67 -0
- package/src/discovery/agents.ts +300 -0
- package/src/discovery/at-imports.ts +273 -0
- package/src/discovery/builtin-defaults.ts +39 -0
- package/src/discovery/builtin-rules/go-add-cleanup.md +33 -0
- package/src/discovery/builtin-rules/go-bench-loop.md +36 -0
- package/src/discovery/builtin-rules/go-exp-promoted.md +40 -0
- package/src/discovery/builtin-rules/go-ioutil.md +37 -0
- package/src/discovery/builtin-rules/go-join-hostport.md +30 -0
- package/src/discovery/builtin-rules/go-new-expr.md +44 -0
- package/src/discovery/builtin-rules/go-rand-v2.md +41 -0
- package/src/discovery/builtin-rules/go-range-int.md +45 -0
- package/src/discovery/builtin-rules/index.ts +74 -0
- package/src/discovery/builtin-rules/rs-box-leak.md +49 -0
- package/src/discovery/builtin-rules/rs-future-prelude.md +24 -0
- package/src/discovery/builtin-rules/rs-lazylock.md +52 -0
- package/src/discovery/builtin-rules/rs-match-ergonomics.md +68 -0
- package/src/discovery/builtin-rules/rs-parking-lot.md +45 -0
- package/src/discovery/builtin-rules/rs-result-type.md +20 -0
- package/src/discovery/builtin-rules/ts-bare-catch.md +39 -0
- package/src/discovery/builtin-rules/ts-import-type.md +43 -0
- package/src/discovery/builtin-rules/ts-no-any.md +66 -0
- package/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md +45 -0
- package/src/discovery/builtin-rules/ts-no-dynamic-import.md +40 -0
- package/src/discovery/builtin-rules/ts-no-inline-cast-access.md +56 -0
- package/src/discovery/builtin-rules/ts-no-local-is-record.md +48 -0
- package/src/discovery/builtin-rules/ts-no-return-type.md +45 -0
- package/src/discovery/builtin-rules/ts-no-test-timers.md +55 -0
- package/src/discovery/builtin-rules/ts-no-tiny-functions.md +51 -0
- package/src/discovery/builtin-rules/ts-promise-with-resolvers.md +66 -0
- package/src/discovery/builtin-rules/ts-redundant-clear-guard.md +75 -0
- package/src/discovery/builtin-rules/ts-set-map.md +28 -0
- package/src/discovery/builtin.ts +945 -0
- package/src/discovery/claude-plugins.ts +640 -0
- package/src/discovery/claude.ts +591 -0
- package/src/discovery/cline.ts +83 -0
- package/src/discovery/codex.ts +553 -0
- package/src/discovery/contained-path.ts +78 -0
- package/src/discovery/cursor.ts +223 -0
- package/src/discovery/gemini.ts +386 -0
- package/src/discovery/github.ts +337 -0
- package/src/discovery/helpers.ts +1183 -0
- package/src/discovery/index.ts +82 -0
- package/src/discovery/mcp-json.ts +182 -0
- package/src/discovery/omp-extension-roots.ts +272 -0
- package/src/discovery/omp-plugins.ts +409 -0
- package/src/discovery/opencode.ts +441 -0
- package/src/discovery/plugin-dir-roots.ts +28 -0
- package/src/discovery/ssh.ts +153 -0
- package/src/discovery/substitute-plugin-root.ts +77 -0
- package/src/discovery/vscode.ts +106 -0
- package/src/discovery/windsurf.ts +149 -0
- package/src/edit/apply-patch/index.ts +87 -0
- package/src/edit/apply-patch/parser.ts +174 -0
- package/src/edit/diff.ts +1008 -0
- package/src/edit/edit-clipboard.ts +23 -0
- package/src/edit/file-snapshot-store.ts +148 -0
- package/src/edit/hashline/block-resolver.ts +33 -0
- package/src/edit/hashline/diff.ts +402 -0
- package/src/edit/hashline/execute.ts +313 -0
- package/src/edit/hashline/filesystem.ts +247 -0
- package/src/edit/hashline/index.ts +5 -0
- package/src/edit/hashline/noop-loop-guard.ts +99 -0
- package/src/edit/hashline/params.ts +12 -0
- package/src/edit/index.ts +699 -0
- package/src/edit/modes/apply-patch.lark +19 -0
- package/src/edit/modes/apply-patch.ts +53 -0
- package/src/edit/modes/patch.ts +1958 -0
- package/src/edit/modes/replace.ts +1191 -0
- package/src/edit/normalize.ts +345 -0
- package/src/edit/notebook.ts +242 -0
- package/src/edit/read-file.ts +25 -0
- package/src/edit/renderer.ts +998 -0
- package/src/edit/snapshot-details.ts +77 -0
- package/src/edit/streaming.ts +710 -0
- package/src/eval/agent-bridge.ts +224 -0
- package/src/eval/backend-helpers.ts +48 -0
- package/src/eval/backend.ts +71 -0
- package/src/eval/bridge-timeout.ts +65 -0
- package/src/eval/budget-bridge.ts +48 -0
- package/src/eval/completion-bridge.ts +212 -0
- package/src/eval/concurrency-bridge.ts +34 -0
- package/src/eval/executor-base.ts +562 -0
- package/src/eval/idle-timeout.ts +91 -0
- package/src/eval/index.ts +6 -0
- package/src/eval/jl/executor.ts +551 -0
- package/src/eval/jl/index.ts +54 -0
- package/src/eval/jl/kernel.ts +236 -0
- package/src/eval/jl/prelude.jl +736 -0
- package/src/eval/jl/prelude.ts +3 -0
- package/src/eval/jl/runner.jl +666 -0
- package/src/eval/jl/runtime.ts +118 -0
- package/src/eval/js/context-manager.ts +872 -0
- package/src/eval/js/executor.ts +178 -0
- package/src/eval/js/index.ts +41 -0
- package/src/eval/js/process-entry.ts +31 -0
- package/src/eval/js/shared/helpers.ts +170 -0
- package/src/eval/js/shared/indirect-eval.ts +30 -0
- package/src/eval/js/shared/local-module-loader.ts +364 -0
- package/src/eval/js/shared/prelude.ts +2 -0
- package/src/eval/js/shared/prelude.txt +294 -0
- package/src/eval/js/shared/rewrite-imports.ts +550 -0
- package/src/eval/js/shared/runtime.ts +590 -0
- package/src/eval/js/shared/types.ts +18 -0
- package/src/eval/js/tool-bridge.ts +163 -0
- package/src/eval/js/worker-core.ts +380 -0
- package/src/eval/js/worker-entry.ts +37 -0
- package/src/eval/js/worker-protocol.ts +47 -0
- package/src/eval/kernel-base.ts +569 -0
- package/src/eval/py/display.ts +71 -0
- package/src/eval/py/executor.ts +643 -0
- package/src/eval/py/index.ts +57 -0
- package/src/eval/py/kernel.ts +235 -0
- package/src/eval/py/prelude.py +673 -0
- package/src/eval/py/prelude.ts +3 -0
- package/src/eval/py/runner.py +1425 -0
- package/src/eval/py/runtime.ts +276 -0
- package/src/eval/py/spawn-options.ts +134 -0
- package/src/eval/py/tool-bridge.ts +201 -0
- package/src/eval/rb/executor.ts +511 -0
- package/src/eval/rb/index.ts +54 -0
- package/src/eval/rb/kernel.ts +231 -0
- package/src/eval/rb/prelude.rb +551 -0
- package/src/eval/rb/prelude.ts +3 -0
- package/src/eval/rb/runner.rb +581 -0
- package/src/eval/rb/runtime.ts +132 -0
- package/src/eval/runtime-env.ts +104 -0
- package/src/eval/session-id.ts +8 -0
- package/src/eval/types.ts +48 -0
- package/src/exa/index.ts +2 -0
- package/src/exa/mcp-client.ts +370 -0
- package/src/exa/types.ts +69 -0
- package/src/exec/bash-executor.ts +627 -0
- package/src/exec/direnv.ts +145 -0
- package/src/exec/exec.ts +53 -0
- package/src/exec/non-interactive-env.ts +118 -0
- package/src/export/custom-share.ts +65 -0
- package/src/export/html/args.ts +20 -0
- package/src/export/html/index.ts +320 -0
- package/src/export/html/share-loader.js +102 -0
- package/src/export/html/template.css +1355 -0
- package/src/export/html/template.html +55 -0
- package/src/export/html/template.js +1653 -0
- package/src/export/html/tool-views.generated.js +35 -0
- package/src/export/html/vendor/highlight.min.js +1213 -0
- package/src/export/html/vendor/marked.min.js +6 -0
- package/src/export/html/web-palette.ts +126 -0
- package/src/export/share.ts +686 -0
- package/src/export/ttsr.ts +590 -0
- package/src/extensibility/custom-commands/bundled/ci-green/index.ts +54 -0
- package/src/extensibility/custom-commands/bundled/review/index.ts +698 -0
- package/src/extensibility/custom-commands/index.ts +2 -0
- package/src/extensibility/custom-commands/loader.ts +242 -0
- package/src/extensibility/custom-commands/types.ts +119 -0
- package/src/extensibility/custom-tools/index.ts +7 -0
- package/src/extensibility/custom-tools/loader.ts +301 -0
- package/src/extensibility/custom-tools/types.ts +287 -0
- package/src/extensibility/custom-tools/wrapper.ts +50 -0
- package/src/extensibility/extensions/compact-handler.ts +40 -0
- package/src/extensibility/extensions/get-commands-handler.ts +78 -0
- package/src/extensibility/extensions/index.ts +16 -0
- package/src/extensibility/extensions/load-errors.ts +13 -0
- package/src/extensibility/extensions/loader.ts +663 -0
- package/src/extensibility/extensions/managed-timers.ts +83 -0
- package/src/extensibility/extensions/model-api.ts +39 -0
- package/src/extensibility/extensions/runner.ts +1396 -0
- package/src/extensibility/extensions/types.ts +1603 -0
- package/src/extensibility/extensions/wrapper.ts +395 -0
- package/src/extensibility/hooks/index.ts +6 -0
- package/src/extensibility/hooks/loader.ts +243 -0
- package/src/extensibility/hooks/runner.ts +425 -0
- package/src/extensibility/hooks/tool-wrapper.ts +124 -0
- package/src/extensibility/hooks/types.ts +612 -0
- package/src/extensibility/legacy-pi-ai-shim.ts +161 -0
- package/src/extensibility/legacy-pi-coding-agent-shim.ts +1460 -0
- package/src/extensibility/legacy-pi-tui-shim.ts +43 -0
- package/src/extensibility/legacy-typebox.ts +101 -0
- package/src/extensibility/plugins/bun-git-cache.ts +91 -0
- package/src/extensibility/plugins/doctor.ts +65 -0
- package/src/extensibility/plugins/git-url.ts +367 -0
- package/src/extensibility/plugins/index.ts +9 -0
- package/src/extensibility/plugins/installer.ts +201 -0
- package/src/extensibility/plugins/legacy-pi-compat.ts +2643 -0
- package/src/extensibility/plugins/legacy-pi-virtual-modules.d.ts +4 -0
- package/src/extensibility/plugins/loader.ts +535 -0
- package/src/extensibility/plugins/manager.ts +1142 -0
- package/src/extensibility/plugins/marketplace/cache.ts +136 -0
- package/src/extensibility/plugins/marketplace/fetcher.ts +316 -0
- package/src/extensibility/plugins/marketplace/index.ts +6 -0
- package/src/extensibility/plugins/marketplace/manager.ts +927 -0
- package/src/extensibility/plugins/marketplace/registry.ts +192 -0
- package/src/extensibility/plugins/marketplace/source-resolver.ts +147 -0
- package/src/extensibility/plugins/marketplace/types.ts +192 -0
- package/src/extensibility/plugins/marketplace-auto-update.ts +49 -0
- package/src/extensibility/plugins/parser.ts +107 -0
- package/src/extensibility/plugins/runtime-config.ts +9 -0
- package/src/extensibility/plugins/types.ts +194 -0
- package/src/extensibility/session-handler-types.ts +21 -0
- package/src/extensibility/shared-events.ts +401 -0
- package/src/extensibility/skills.ts +531 -0
- package/src/extensibility/slash-commands.ts +131 -0
- package/src/extensibility/tool-event-input.ts +80 -0
- package/src/extensibility/tool-proxy.ts +28 -0
- package/src/extensibility/utils.ts +192 -0
- package/src/goals/index.ts +3 -0
- package/src/goals/runtime.ts +521 -0
- package/src/goals/state.ts +37 -0
- package/src/goals/tools/goal-tool.ts +251 -0
- package/src/hindsight/backend.ts +354 -0
- package/src/hindsight/bank.ts +156 -0
- package/src/hindsight/client.ts +680 -0
- package/src/hindsight/config.ts +193 -0
- package/src/hindsight/content.ts +266 -0
- package/src/hindsight/index.ts +8 -0
- package/src/hindsight/mental-models.ts +429 -0
- package/src/hindsight/seeds.json +32 -0
- package/src/hindsight/state.ts +530 -0
- package/src/hindsight/transcript.ts +71 -0
- package/src/index.ts +66 -0
- package/src/internal-urls/agent-protocol.ts +180 -0
- package/src/internal-urls/artifact-protocol.ts +151 -0
- package/src/internal-urls/docs-index.ts +102 -0
- package/src/internal-urls/filesystem-resource.ts +34 -0
- package/src/internal-urls/history-protocol.ts +198 -0
- package/src/internal-urls/index.ts +28 -0
- package/src/internal-urls/issue-pr-protocol.ts +594 -0
- package/src/internal-urls/json-query.ts +126 -0
- package/src/internal-urls/local-protocol.ts +471 -0
- package/src/internal-urls/mcp-protocol.ts +168 -0
- package/src/internal-urls/memory-protocol.ts +380 -0
- package/src/internal-urls/omp-protocol.ts +94 -0
- package/src/internal-urls/parse.ts +103 -0
- package/src/internal-urls/registry-helpers.ts +132 -0
- package/src/internal-urls/router.ts +153 -0
- package/src/internal-urls/rule-protocol.ts +45 -0
- package/src/internal-urls/security-protocol.ts +261 -0
- package/src/internal-urls/skill-protocol.ts +131 -0
- package/src/internal-urls/ssh-protocol.ts +368 -0
- package/src/internal-urls/types.ts +196 -0
- package/src/internal-urls/vault-protocol.ts +940 -0
- package/src/internal-urls/xd-protocol.ts +46 -0
- package/src/irc/bus.ts +380 -0
- package/src/jsonrpc/message-framing.ts +142 -0
- package/src/launch/broker.ts +1368 -0
- package/src/launch/client.ts +521 -0
- package/src/launch/ensure.ts +73 -0
- package/src/launch/paths.ts +14 -0
- package/src/launch/presence.ts +82 -0
- package/src/launch/protocol.ts +448 -0
- package/src/launch/spawn-options.ts +17 -0
- package/src/launch/terminal-output-worker-client.ts +53 -0
- package/src/launch/terminal-output-worker-protocol.ts +11 -0
- package/src/launch/terminal-output-worker.ts +23 -0
- package/src/launch/terminal-output.ts +46 -0
- package/src/lib/xai-http.ts +150 -0
- package/src/live/attestation.ts +91 -0
- package/src/live/controller.ts +517 -0
- package/src/live/prompts/agent-final-message.md +3 -0
- package/src/live/prompts/live-instructions.md +23 -0
- package/src/live/protocol.ts +233 -0
- package/src/live/transport.ts +422 -0
- package/src/live/visualizer.ts +221 -0
- package/src/live/voices.ts +18 -0
- package/src/lsp/client.ts +1465 -0
- package/src/lsp/clients/biome-client.ts +263 -0
- package/src/lsp/clients/index.ts +50 -0
- package/src/lsp/clients/lsp-linter-client.ts +85 -0
- package/src/lsp/clients/swiftlint-client.ts +120 -0
- package/src/lsp/config.ts +549 -0
- package/src/lsp/defaults.json +499 -0
- package/src/lsp/deferred-diagnostics.ts +66 -0
- package/src/lsp/diagnostics-ledger.ts +51 -0
- package/src/lsp/edits.ts +288 -0
- package/src/lsp/format-options.ts +119 -0
- package/src/lsp/index.ts +2821 -0
- package/src/lsp/lspmux.ts +233 -0
- package/src/lsp/mux/daemon.ts +348 -0
- package/src/lsp/mux/protocol.ts +96 -0
- package/src/lsp/mux/server.ts +797 -0
- package/src/lsp/render.ts +668 -0
- package/src/lsp/startup-events.ts +13 -0
- package/src/lsp/types.ts +479 -0
- package/src/lsp/utils.ts +747 -0
- package/src/main.ts +1799 -0
- package/src/markit/NOTICE +32 -0
- package/src/markit/converters/docx.ts +56 -0
- package/src/markit/converters/epub.ts +136 -0
- package/src/markit/converters/pdf/columns.ts +103 -0
- package/src/markit/converters/pdf/extract.ts +598 -0
- package/src/markit/converters/pdf/grid.ts +780 -0
- package/src/markit/converters/pdf/headers.ts +106 -0
- package/src/markit/converters/pdf/index.ts +146 -0
- package/src/markit/converters/pdf/render.ts +501 -0
- package/src/markit/converters/pdf/types.ts +84 -0
- package/src/markit/converters/pptx.ts +325 -0
- package/src/markit/converters/xlsx.ts +173 -0
- package/src/markit/index.ts +2 -0
- package/src/markit/registry.ts +59 -0
- package/src/markit/types.ts +35 -0
- package/src/mcp/client.ts +511 -0
- package/src/mcp/config-writer.ts +377 -0
- package/src/mcp/config.ts +385 -0
- package/src/mcp/index.ts +29 -0
- package/src/mcp/json-rpc.ts +122 -0
- package/src/mcp/loader.ts +125 -0
- package/src/mcp/manager.ts +1524 -0
- package/src/mcp/oauth-credentials.ts +104 -0
- package/src/mcp/oauth-discovery.ts +587 -0
- package/src/mcp/oauth-flow.ts +830 -0
- package/src/mcp/render.ts +214 -0
- package/src/mcp/request-id.ts +24 -0
- package/src/mcp/smithery-auth.ts +108 -0
- package/src/mcp/smithery-connect.ts +154 -0
- package/src/mcp/smithery-registry.ts +500 -0
- package/src/mcp/startup-events.ts +116 -0
- package/src/mcp/timeout.ts +59 -0
- package/src/mcp/tool-bridge.ts +691 -0
- package/src/mcp/tool-cache.ts +117 -0
- package/src/mcp/transports/header-policy.ts +95 -0
- package/src/mcp/transports/http.ts +508 -0
- package/src/mcp/transports/index.ts +7 -0
- package/src/mcp/transports/sse.ts +372 -0
- package/src/mcp/transports/stdio.ts +905 -0
- package/src/mcp/types.ts +467 -0
- package/src/memories/index.ts +1434 -0
- package/src/memories/storage.ts +578 -0
- package/src/memory-backend/index.ts +19 -0
- package/src/memory-backend/local-backend.ts +47 -0
- package/src/memory-backend/messages.ts +19 -0
- package/src/memory-backend/off-backend.ts +25 -0
- package/src/memory-backend/resolve.ts +25 -0
- package/src/memory-backend/runtime.ts +66 -0
- package/src/memory-backend/tool-names.ts +2 -0
- package/src/memory-backend/types.ts +166 -0
- package/src/mnemopi/backend.ts +629 -0
- package/src/mnemopi/config.ts +267 -0
- package/src/mnemopi/embed-client.ts +293 -0
- package/src/mnemopi/embed-protocol.ts +35 -0
- package/src/mnemopi/embed-worker.ts +114 -0
- package/src/mnemopi/index.ts +3 -0
- package/src/mnemopi/state.ts +940 -0
- package/src/modes/acp/acp-agent.ts +2595 -0
- package/src/modes/acp/acp-client-bridge.ts +154 -0
- package/src/modes/acp/acp-event-mapper.ts +1084 -0
- package/src/modes/acp/acp-mode.ts +48 -0
- package/src/modes/acp/index.ts +2 -0
- package/src/modes/acp/terminal-auth.ts +37 -0
- package/src/modes/components/advisor-config.ts +635 -0
- package/src/modes/components/advisor-message.ts +109 -0
- package/src/modes/components/agent-dashboard.ts +1252 -0
- package/src/modes/components/agent-hub-projection.ts +248 -0
- package/src/modes/components/agent-hub-renderer.ts +194 -0
- package/src/modes/components/agent-hub.ts +1126 -0
- package/src/modes/components/agent-transcript-viewer.ts +647 -0
- package/src/modes/components/ask-dialog.ts +1017 -0
- package/src/modes/components/assistant-message.ts +978 -0
- package/src/modes/components/background-tan-message.ts +36 -0
- package/src/modes/components/bash-execution.ts +233 -0
- package/src/modes/components/bordered-loader.ts +41 -0
- package/src/modes/components/btw-panel.ts +161 -0
- package/src/modes/components/cache-invalidation-marker.ts +110 -0
- package/src/modes/components/chat-block.ts +111 -0
- package/src/modes/components/chat-transcript-builder.ts +518 -0
- package/src/modes/components/codex-reset-fireworks.ts +369 -0
- package/src/modes/components/collab-prompt-message.ts +32 -0
- package/src/modes/components/compaction-summary-message.ts +221 -0
- package/src/modes/components/copy-selector.ts +218 -0
- package/src/modes/components/countdown-timer.ts +75 -0
- package/src/modes/components/custom-editor.ts +1036 -0
- package/src/modes/components/custom-message.ts +70 -0
- package/src/modes/components/diff.ts +254 -0
- package/src/modes/components/dynamic-border.ts +37 -0
- package/src/modes/components/error-banner.ts +33 -0
- package/src/modes/components/eval-execution.ts +169 -0
- package/src/modes/components/execution-shared.ts +101 -0
- package/src/modes/components/extensions/extension-dashboard.ts +492 -0
- package/src/modes/components/extensions/extension-list.ts +507 -0
- package/src/modes/components/extensions/index.ts +9 -0
- package/src/modes/components/extensions/inspector-panel.ts +326 -0
- package/src/modes/components/extensions/state-manager.ts +648 -0
- package/src/modes/components/extensions/types.ts +186 -0
- package/src/modes/components/footer.ts +274 -0
- package/src/modes/components/history-search.ts +268 -0
- package/src/modes/components/hook-editor.ts +213 -0
- package/src/modes/components/hook-input.ts +87 -0
- package/src/modes/components/hook-message.ts +67 -0
- package/src/modes/components/hook-selector.ts +691 -0
- package/src/modes/components/index.ts +42 -0
- package/src/modes/components/keybinding-hints.ts +56 -0
- package/src/modes/components/late-diagnostics-message.ts +60 -0
- package/src/modes/components/login-dialog.ts +197 -0
- package/src/modes/components/logout-account-selector.ts +130 -0
- package/src/modes/components/mcp-add-wizard.ts +1413 -0
- package/src/modes/components/message-frame.ts +98 -0
- package/src/modes/components/model-browser.ts +888 -0
- package/src/modes/components/model-hub.ts +2014 -0
- package/src/modes/components/model-picker.ts +237 -0
- package/src/modes/components/move-overlay.ts +293 -0
- package/src/modes/components/oauth-selector.ts +474 -0
- package/src/modes/components/omfg-panel.ts +141 -0
- package/src/modes/components/overlay-box.ts +109 -0
- package/src/modes/components/pause-screen.ts +208 -0
- package/src/modes/components/plan-review-overlay.ts +1226 -0
- package/src/modes/components/plan-toc.ts +138 -0
- package/src/modes/components/plugin-selector.ts +100 -0
- package/src/modes/components/plugin-settings.ts +745 -0
- package/src/modes/components/queue-mode-selector.ts +61 -0
- package/src/modes/components/read-tool-group.ts +856 -0
- package/src/modes/components/reset-usage-selector.ts +161 -0
- package/src/modes/components/segment-track.ts +89 -0
- package/src/modes/components/select-list-mouse-routing.ts +35 -0
- package/src/modes/components/selector-helpers.ts +129 -0
- package/src/modes/components/session-account-selector.ts +62 -0
- package/src/modes/components/session-selector.ts +1035 -0
- package/src/modes/components/settings-defs.ts +267 -0
- package/src/modes/components/settings-selector.ts +1445 -0
- package/src/modes/components/show-images-selector.ts +50 -0
- package/src/modes/components/skill-message.ts +110 -0
- package/src/modes/components/snapcompact-shape-preview-doc.md +14 -0
- package/src/modes/components/snapcompact-shape-preview.ts +192 -0
- package/src/modes/components/status-line/component.ts +1843 -0
- package/src/modes/components/status-line/context-thresholds.ts +86 -0
- package/src/modes/components/status-line/git-utils.ts +42 -0
- package/src/modes/components/status-line/index.ts +5 -0
- package/src/modes/components/status-line/presets.ts +106 -0
- package/src/modes/components/status-line/segments.ts +710 -0
- package/src/modes/components/status-line/separators.ts +55 -0
- package/src/modes/components/status-line/types.ts +159 -0
- package/src/modes/components/stripped-tool-calls-placeholder.ts +35 -0
- package/src/modes/components/theme-selector.ts +68 -0
- package/src/modes/components/thinking-selector.ts +57 -0
- package/src/modes/components/tiny-title-download-progress.ts +90 -0
- package/src/modes/components/tips.txt +26 -0
- package/src/modes/components/todo-reminder.ts +43 -0
- package/src/modes/components/tool-execution.ts +1467 -0
- package/src/modes/components/transcript-container.ts +527 -0
- package/src/modes/components/tree-selector.ts +1006 -0
- package/src/modes/components/ttsr-notification.ts +123 -0
- package/src/modes/components/usage-row.ts +52 -0
- package/src/modes/components/user-message-selector.ts +227 -0
- package/src/modes/components/user-message.ts +167 -0
- package/src/modes/components/visual-truncate.ts +63 -0
- package/src/modes/components/welcome.ts +578 -0
- package/src/modes/controllers/btw-controller.ts +246 -0
- package/src/modes/controllers/command-controller-shared.ts +109 -0
- package/src/modes/controllers/command-controller.ts +2024 -0
- package/src/modes/controllers/event-controller.ts +2173 -0
- package/src/modes/controllers/extension-ui-controller.ts +1243 -0
- package/src/modes/controllers/input-controller.ts +2037 -0
- package/src/modes/controllers/live-command-controller.ts +261 -0
- package/src/modes/controllers/mcp-command-controller.ts +2552 -0
- package/src/modes/controllers/omfg-controller.ts +287 -0
- package/src/modes/controllers/omfg-rule.ts +647 -0
- package/src/modes/controllers/selector-controller.ts +2058 -0
- package/src/modes/controllers/session-focus-controller.ts +117 -0
- package/src/modes/controllers/ssh-command-controller.ts +385 -0
- package/src/modes/controllers/streaming-reveal.ts +399 -0
- package/src/modes/controllers/tan-command-controller.ts +243 -0
- package/src/modes/controllers/todo-command-controller.ts +487 -0
- package/src/modes/controllers/tool-args-reveal.ts +591 -0
- package/src/modes/data/emojis.json +1 -0
- package/src/modes/emoji-autocomplete.ts +285 -0
- package/src/modes/github-ref-autocomplete.ts +75 -0
- package/src/modes/gradient-highlight.ts +99 -0
- package/src/modes/image-references.ts +137 -0
- package/src/modes/index.ts +10 -0
- package/src/modes/interactive-mode.ts +5055 -0
- package/src/modes/internal-url-autocomplete.ts +158 -0
- package/src/modes/loop-limit.ts +192 -0
- package/src/modes/magic-keyword-boundary.ts +23 -0
- package/src/modes/magic-keywords.ts +42 -0
- package/src/modes/markdown-prose.ts +247 -0
- package/src/modes/oauth-manual-input.ts +69 -0
- package/src/modes/orchestrate.ts +43 -0
- package/src/modes/print-mode.ts +282 -0
- package/src/modes/prompt-action-autocomplete.ts +322 -0
- package/src/modes/queue-input.ts +132 -0
- package/src/modes/rpc/host-tools.ts +204 -0
- package/src/modes/rpc/host-uris.ts +241 -0
- package/src/modes/rpc/rpc-client.ts +1213 -0
- package/src/modes/rpc/rpc-frame.ts +316 -0
- package/src/modes/rpc/rpc-input.ts +38 -0
- package/src/modes/rpc/rpc-messages.ts +127 -0
- package/src/modes/rpc/rpc-mode.ts +1519 -0
- package/src/modes/rpc/rpc-subagents.ts +265 -0
- package/src/modes/rpc/rpc-types.ts +544 -0
- package/src/modes/running-subagent-badge.ts +13 -0
- package/src/modes/runtime-init.ts +144 -0
- package/src/modes/session-observer-registry.ts +223 -0
- package/src/modes/session-teardown.ts +82 -0
- package/src/modes/setup-version.ts +11 -0
- package/src/modes/setup-wizard/index.ts +103 -0
- package/src/modes/setup-wizard/lazy.ts +16 -0
- package/src/modes/setup-wizard/scenes/glyph.ts +103 -0
- package/src/modes/setup-wizard/scenes/model.ts +132 -0
- package/src/modes/setup-wizard/scenes/outro.ts +35 -0
- package/src/modes/setup-wizard/scenes/providers.ts +105 -0
- package/src/modes/setup-wizard/scenes/sign-in.ts +312 -0
- package/src/modes/setup-wizard/scenes/splash.ts +201 -0
- package/src/modes/setup-wizard/scenes/theme.ts +330 -0
- package/src/modes/setup-wizard/scenes/types.ts +65 -0
- package/src/modes/setup-wizard/scenes/web-search.ts +153 -0
- package/src/modes/setup-wizard/startup-splash.ts +107 -0
- package/src/modes/setup-wizard/wizard-overlay.ts +335 -0
- package/src/modes/shared.ts +49 -0
- package/src/modes/skill-command.ts +91 -0
- package/src/modes/theme/dark.json +95 -0
- package/src/modes/theme/defaults/alabaster.json +93 -0
- package/src/modes/theme/defaults/amethyst.json +96 -0
- package/src/modes/theme/defaults/anthracite.json +93 -0
- package/src/modes/theme/defaults/basalt.json +91 -0
- package/src/modes/theme/defaults/birch.json +95 -0
- package/src/modes/theme/defaults/dark-abyss.json +91 -0
- package/src/modes/theme/defaults/dark-arctic.json +104 -0
- package/src/modes/theme/defaults/dark-aurora.json +95 -0
- package/src/modes/theme/defaults/dark-catppuccin.json +107 -0
- package/src/modes/theme/defaults/dark-cavern.json +91 -0
- package/src/modes/theme/defaults/dark-copper.json +95 -0
- package/src/modes/theme/defaults/dark-cosmos.json +90 -0
- package/src/modes/theme/defaults/dark-cyberpunk.json +102 -0
- package/src/modes/theme/defaults/dark-dracula.json +98 -0
- package/src/modes/theme/defaults/dark-eclipse.json +91 -0
- package/src/modes/theme/defaults/dark-ember.json +95 -0
- package/src/modes/theme/defaults/dark-equinox.json +90 -0
- package/src/modes/theme/defaults/dark-forest.json +96 -0
- package/src/modes/theme/defaults/dark-github.json +105 -0
- package/src/modes/theme/defaults/dark-gruvbox.json +112 -0
- package/src/modes/theme/defaults/dark-lavender.json +95 -0
- package/src/modes/theme/defaults/dark-lunar.json +89 -0
- package/src/modes/theme/defaults/dark-midnight.json +95 -0
- package/src/modes/theme/defaults/dark-monochrome.json +94 -0
- package/src/modes/theme/defaults/dark-monokai.json +98 -0
- package/src/modes/theme/defaults/dark-nebula.json +90 -0
- package/src/modes/theme/defaults/dark-nord.json +97 -0
- package/src/modes/theme/defaults/dark-ocean.json +101 -0
- package/src/modes/theme/defaults/dark-one.json +100 -0
- package/src/modes/theme/defaults/dark-poimandres.json +143 -0
- package/src/modes/theme/defaults/dark-rainforest.json +91 -0
- package/src/modes/theme/defaults/dark-reef.json +91 -0
- package/src/modes/theme/defaults/dark-retro.json +92 -0
- package/src/modes/theme/defaults/dark-rose-pine.json +96 -0
- package/src/modes/theme/defaults/dark-sakura.json +95 -0
- package/src/modes/theme/defaults/dark-slate.json +95 -0
- package/src/modes/theme/defaults/dark-solarized.json +97 -0
- package/src/modes/theme/defaults/dark-solstice.json +90 -0
- package/src/modes/theme/defaults/dark-starfall.json +91 -0
- package/src/modes/theme/defaults/dark-sunset.json +99 -0
- package/src/modes/theme/defaults/dark-swamp.json +90 -0
- package/src/modes/theme/defaults/dark-synthwave.json +103 -0
- package/src/modes/theme/defaults/dark-taiga.json +91 -0
- package/src/modes/theme/defaults/dark-terminal.json +95 -0
- package/src/modes/theme/defaults/dark-tokyo-night.json +101 -0
- package/src/modes/theme/defaults/dark-tundra.json +91 -0
- package/src/modes/theme/defaults/dark-twilight.json +91 -0
- package/src/modes/theme/defaults/dark-volcanic.json +91 -0
- package/src/modes/theme/defaults/graphite.json +92 -0
- package/src/modes/theme/defaults/index.ts +199 -0
- package/src/modes/theme/defaults/light-arctic.json +107 -0
- package/src/modes/theme/defaults/light-aurora-day.json +91 -0
- package/src/modes/theme/defaults/light-canyon.json +91 -0
- package/src/modes/theme/defaults/light-catppuccin.json +106 -0
- package/src/modes/theme/defaults/light-cirrus.json +90 -0
- package/src/modes/theme/defaults/light-coral.json +95 -0
- package/src/modes/theme/defaults/light-cyberpunk.json +96 -0
- package/src/modes/theme/defaults/light-dawn.json +90 -0
- package/src/modes/theme/defaults/light-dunes.json +91 -0
- package/src/modes/theme/defaults/light-eucalyptus.json +95 -0
- package/src/modes/theme/defaults/light-forest.json +100 -0
- package/src/modes/theme/defaults/light-frost.json +95 -0
- package/src/modes/theme/defaults/light-github.json +115 -0
- package/src/modes/theme/defaults/light-glacier.json +91 -0
- package/src/modes/theme/defaults/light-gruvbox.json +108 -0
- package/src/modes/theme/defaults/light-haze.json +90 -0
- package/src/modes/theme/defaults/light-honeycomb.json +95 -0
- package/src/modes/theme/defaults/light-lagoon.json +91 -0
- package/src/modes/theme/defaults/light-lavender.json +95 -0
- package/src/modes/theme/defaults/light-meadow.json +91 -0
- package/src/modes/theme/defaults/light-mint.json +95 -0
- package/src/modes/theme/defaults/light-monochrome.json +101 -0
- package/src/modes/theme/defaults/light-ocean.json +99 -0
- package/src/modes/theme/defaults/light-one.json +99 -0
- package/src/modes/theme/defaults/light-opal.json +91 -0
- package/src/modes/theme/defaults/light-orchard.json +91 -0
- package/src/modes/theme/defaults/light-paper.json +95 -0
- package/src/modes/theme/defaults/light-poimandres.json +143 -0
- package/src/modes/theme/defaults/light-prism.json +90 -0
- package/src/modes/theme/defaults/light-retro.json +98 -0
- package/src/modes/theme/defaults/light-sand.json +95 -0
- package/src/modes/theme/defaults/light-savanna.json +91 -0
- package/src/modes/theme/defaults/light-solarized.json +102 -0
- package/src/modes/theme/defaults/light-soleil.json +90 -0
- package/src/modes/theme/defaults/light-sunset.json +99 -0
- package/src/modes/theme/defaults/light-synthwave.json +98 -0
- package/src/modes/theme/defaults/light-tokyo-night.json +111 -0
- package/src/modes/theme/defaults/light-wetland.json +91 -0
- package/src/modes/theme/defaults/light-zenith.json +89 -0
- package/src/modes/theme/defaults/limestone.json +94 -0
- package/src/modes/theme/defaults/mahogany.json +97 -0
- package/src/modes/theme/defaults/marble.json +93 -0
- package/src/modes/theme/defaults/obsidian.json +91 -0
- package/src/modes/theme/defaults/onyx.json +91 -0
- package/src/modes/theme/defaults/pearl.json +93 -0
- package/src/modes/theme/defaults/porcelain.json +91 -0
- package/src/modes/theme/defaults/quartz.json +96 -0
- package/src/modes/theme/defaults/sandstone.json +95 -0
- package/src/modes/theme/defaults/titanium.json +90 -0
- package/src/modes/theme/light.json +93 -0
- package/src/modes/theme/mermaid-cache.ts +92 -0
- package/src/modes/theme/shimmer.ts +305 -0
- package/src/modes/theme/theme-schema.json +463 -0
- package/src/modes/theme/theme.ts +3171 -0
- package/src/modes/turn-budget.ts +31 -0
- package/src/modes/types.ts +494 -0
- package/src/modes/ultrathink.ts +42 -0
- package/src/modes/utils/context-usage.ts +518 -0
- package/src/modes/utils/copy-targets.ts +378 -0
- package/src/modes/utils/hotkeys-markdown.ts +65 -0
- package/src/modes/utils/interactive-context-helpers.ts +31 -0
- package/src/modes/utils/keybinding-matchers.ts +86 -0
- package/src/modes/utils/tools-markdown.ts +31 -0
- package/src/modes/utils/transcript-render-helpers.ts +253 -0
- package/src/modes/utils/ui-helpers.ts +976 -0
- package/src/modes/warp-events.ts +232 -0
- package/src/modes/workflow.ts +55 -0
- package/src/plan-mode/approved-plan.ts +194 -0
- package/src/plan-mode/model-transition.ts +51 -0
- package/src/plan-mode/plan-files.ts +40 -0
- package/src/plan-mode/plan-handoff.ts +37 -0
- package/src/plan-mode/plan-protection.ts +31 -0
- package/src/plan-mode/state.ts +6 -0
- package/src/priority.json +60 -0
- package/src/prompts/advisor/active-repo-watchdog.md +6 -0
- package/src/prompts/advisor/advise-tool.md +3 -0
- package/src/prompts/advisor/context-files.md +8 -0
- package/src/prompts/advisor/system.md +98 -0
- package/src/prompts/agents/designer.md +74 -0
- package/src/prompts/agents/frontmatter.md +12 -0
- package/src/prompts/agents/init.md +33 -0
- package/src/prompts/agents/librarian.md +119 -0
- package/src/prompts/agents/reviewer.md +139 -0
- package/src/prompts/agents/scout.md +58 -0
- package/src/prompts/agents/security-reviewer.md +75 -0
- package/src/prompts/agents/task.md +17 -0
- package/src/prompts/bench/cache-prefix-chunk.md +1 -0
- package/src/prompts/bench/cache-prefix.md +3 -0
- package/src/prompts/bench/cache-suffix.md +1 -0
- package/src/prompts/bench.md +6 -0
- package/src/prompts/ci-green-request.md +36 -0
- package/src/prompts/dry-balance-bench.md +8 -0
- package/src/prompts/goals/goal-budget-limit.md +16 -0
- package/src/prompts/goals/goal-continuation.md +28 -0
- package/src/prompts/goals/goal-mode-active.md +23 -0
- package/src/prompts/goals/goal-mode-context.md +4 -0
- package/src/prompts/goals/goal-todo-context.md +12 -0
- package/src/prompts/goals/guided-goal-interview.md +43 -0
- package/src/prompts/memories/consolidation.md +30 -0
- package/src/prompts/memories/consolidation_system.md +4 -0
- package/src/prompts/memories/read-path.md +17 -0
- package/src/prompts/memories/stage_one_input.md +6 -0
- package/src/prompts/memories/stage_one_system.md +21 -0
- package/src/prompts/review-custom-request.md +21 -0
- package/src/prompts/review-headless-request.md +16 -0
- package/src/prompts/review-request.md +68 -0
- package/src/prompts/security/scan-coordinator.md +7 -0
- package/src/prompts/security/scan-request.md +21 -0
- package/src/prompts/security/validate-request.md +8 -0
- package/src/prompts/session/launch-completion.md +1 -0
- package/src/prompts/skills/autoload.md +8 -0
- package/src/prompts/skills/user-invocation.md +11 -0
- package/src/prompts/steering/parent-irc.md +5 -0
- package/src/prompts/steering/user-interjection.md +6 -0
- package/src/prompts/system/active-repo-context.md +4 -0
- package/src/prompts/system/agent-creation-architect.md +50 -0
- package/src/prompts/system/agent-creation-user.md +6 -0
- package/src/prompts/system/auto-continue.md +1 -0
- package/src/prompts/system/auto-thinking-difficulty-local.md +14 -0
- package/src/prompts/system/auto-thinking-difficulty.md +14 -0
- package/src/prompts/system/autolearn-guidance-learn.md +1 -0
- package/src/prompts/system/autolearn-guidance.md +7 -0
- package/src/prompts/system/autolearn-nudge-autocontinue.md +5 -0
- package/src/prompts/system/background-tan-dispatch.md +8 -0
- package/src/prompts/system/btw-user.md +8 -0
- package/src/prompts/system/commit-message-system.md +14 -0
- package/src/prompts/system/computer-safety.md +14 -0
- package/src/prompts/system/custom-system-prompt.md +64 -0
- package/src/prompts/system/eager-task.md +7 -0
- package/src/prompts/system/eager-todo.md +18 -0
- package/src/prompts/system/empty-stop-retry.md +4 -0
- package/src/prompts/system/gemini-tool-call-reminder.md +9 -0
- package/src/prompts/system/interrupted-thinking.md +7 -0
- package/src/prompts/system/irc-autoreply.md +6 -0
- package/src/prompts/system/irc-incoming.md +9 -0
- package/src/prompts/system/manual-continue.md +7 -0
- package/src/prompts/system/mcp-xdev-guidance.md +11 -0
- package/src/prompts/system/memory-consolidation-system.md +8 -0
- package/src/prompts/system/memory-extraction-system.md +26 -0
- package/src/prompts/system/mid-run-todo-nudge.md +3 -0
- package/src/prompts/system/omfg-user.md +50 -0
- package/src/prompts/system/orchestrate-notice.md +40 -0
- package/src/prompts/system/personalities/default.md +18 -0
- package/src/prompts/system/personalities/friendly.md +17 -0
- package/src/prompts/system/personalities/pragmatic.md +15 -0
- package/src/prompts/system/plan-mode-active.md +125 -0
- package/src/prompts/system/plan-mode-approved.md +22 -0
- package/src/prompts/system/plan-mode-compact-instructions.md +17 -0
- package/src/prompts/system/plan-mode-reference.md +10 -0
- package/src/prompts/system/plan-mode-subagent.md +33 -0
- package/src/prompts/system/plan-mode-tool-decision-reminder.md +9 -0
- package/src/prompts/system/plan-yolo-handoff.md +5 -0
- package/src/prompts/system/prewalk-checklist.md +7 -0
- package/src/prompts/system/prewalk-continue.md +1 -0
- package/src/prompts/system/prewalk-plan.md +13 -0
- package/src/prompts/system/project-prompt.md +61 -0
- package/src/prompts/system/recap-user.md +9 -0
- package/src/prompts/system/resolve-device-reminder.md +3 -0
- package/src/prompts/system/rewind-report.md +6 -0
- package/src/prompts/system/side-channel-no-tools.md +3 -0
- package/src/prompts/system/snapcompact-context-frames-note.md +1 -0
- package/src/prompts/system/snapcompact-context-stub.md +1 -0
- package/src/prompts/system/snapcompact-system-frames-note.md +1 -0
- package/src/prompts/system/snapcompact-system-stub.md +1 -0
- package/src/prompts/system/snapcompact-toolresult-note.md +1 -0
- package/src/prompts/system/speech-rewrite.md +15 -0
- package/src/prompts/system/subagent-async-pending.md +6 -0
- package/src/prompts/system/subagent-system-prompt.md +73 -0
- package/src/prompts/system/subagent-user-prompt.md +3 -0
- package/src/prompts/system/subagent-yield-reminder.md +23 -0
- package/src/prompts/system/system-prompt.md +263 -0
- package/src/prompts/system/tan-context-switch.md +17 -0
- package/src/prompts/system/task-label.md +23 -0
- package/src/prompts/system/thinking-loop-redirect.md +10 -0
- package/src/prompts/system/title-marker-instruction.md +1 -0
- package/src/prompts/system/title-system.md +16 -0
- package/src/prompts/system/tool-call-loop-redirect.md +8 -0
- package/src/prompts/system/ttsr-interrupt.md +7 -0
- package/src/prompts/system/ttsr-tool-reminder.md +5 -0
- package/src/prompts/system/ultrathink-notice.md +3 -0
- package/src/prompts/system/unexpected-stop-classifier.md +17 -0
- package/src/prompts/system/unexpected-stop-retry.md +4 -0
- package/src/prompts/system/vibe-mode-active.md +26 -0
- package/src/prompts/system/web-search.md +25 -0
- package/src/prompts/system/workflow-notice.md +112 -0
- package/src/prompts/system/xdev-mount-notice.md +20 -0
- package/src/prompts/tools/apply-patch.md +65 -0
- package/src/prompts/tools/ask.md +22 -0
- package/src/prompts/tools/ast-edit.md +11 -0
- package/src/prompts/tools/ast-grep.md +19 -0
- package/src/prompts/tools/async-result.md +8 -0
- package/src/prompts/tools/bash.md +23 -0
- package/src/prompts/tools/browser.md +29 -0
- package/src/prompts/tools/checkpoint.md +15 -0
- package/src/prompts/tools/computer.md +26 -0
- package/src/prompts/tools/debug.md +3 -0
- package/src/prompts/tools/eval.md +45 -0
- package/src/prompts/tools/github.md +22 -0
- package/src/prompts/tools/glob.md +16 -0
- package/src/prompts/tools/goal.md +11 -0
- package/src/prompts/tools/grep.md +13 -0
- package/src/prompts/tools/hub.md +34 -0
- package/src/prompts/tools/image-attachment-describe-system.md +8 -0
- package/src/prompts/tools/image-attachment-describe.md +10 -0
- package/src/prompts/tools/image-gen.md +7 -0
- package/src/prompts/tools/inspect-image-system.md +20 -0
- package/src/prompts/tools/inspect-image.md +22 -0
- package/src/prompts/tools/learn.md +7 -0
- package/src/prompts/tools/lsp-late-diagnostic.md +8 -0
- package/src/prompts/tools/lsp.md +19 -0
- package/src/prompts/tools/manage-skill.md +9 -0
- package/src/prompts/tools/memory-edit.md +12 -0
- package/src/prompts/tools/patch.md +57 -0
- package/src/prompts/tools/read.md +27 -0
- package/src/prompts/tools/recall.md +7 -0
- package/src/prompts/tools/reflect.md +5 -0
- package/src/prompts/tools/replace.md +30 -0
- package/src/prompts/tools/retain.md +6 -0
- package/src/prompts/tools/rewind.md +14 -0
- package/src/prompts/tools/security-publish.md +1 -0
- package/src/prompts/tools/security-scan.md +1 -0
- package/src/prompts/tools/task-async-contract.md +1 -0
- package/src/prompts/tools/task-summary.md +20 -0
- package/src/prompts/tools/task.md +83 -0
- package/src/prompts/tools/todo.md +42 -0
- package/src/prompts/tools/vibe-kill.md +3 -0
- package/src/prompts/tools/vibe-list.md +3 -0
- package/src/prompts/tools/vibe-send.md +9 -0
- package/src/prompts/tools/vibe-spawn.md +10 -0
- package/src/prompts/tools/vibe-turn-result.md +19 -0
- package/src/prompts/tools/vibe-wait.md +8 -0
- package/src/prompts/tools/web-search.md +8 -0
- package/src/prompts/tools/write.md +14 -0
- package/src/registry/agent-lifecycle.ts +505 -0
- package/src/registry/agent-registry.ts +287 -0
- package/src/registry/persisted-agents.ts +423 -0
- package/src/sdk.ts +3820 -0
- package/src/secrets/index.ts +375 -0
- package/src/secrets/obfuscator.ts +2629 -0
- package/src/secrets/regex.ts +21 -0
- package/src/security/auth.ts +98 -0
- package/src/security/cloud.ts +686 -0
- package/src/security/comparison.ts +255 -0
- package/src/security/contracts/ids.ts +111 -0
- package/src/security/contracts/index.ts +4 -0
- package/src/security/contracts/schemas.ts +219 -0
- package/src/security/contracts/types.ts +254 -0
- package/src/security/contracts/validation.ts +69 -0
- package/src/security/coordinator.ts +708 -0
- package/src/security/importers/codex-security.ts +387 -0
- package/src/security/importers/index.ts +2 -0
- package/src/security/importers/sarif.ts +357 -0
- package/src/security/index.ts +13 -0
- package/src/security/preflight.ts +405 -0
- package/src/security/provenance.ts +106 -0
- package/src/security/publication.ts +326 -0
- package/src/security/remediation.ts +93 -0
- package/src/security/resource-output.ts +50 -0
- package/src/security/sarif.ts +78 -0
- package/src/security/store.ts +430 -0
- package/src/session/acp-permission-gate.ts +165 -0
- package/src/session/agent-session-events.ts +67 -0
- package/src/session/agent-session-types.ts +407 -0
- package/src/session/agent-session.ts +9000 -0
- package/src/session/agent-storage.ts +807 -0
- package/src/session/artifacts.ts +154 -0
- package/src/session/async-job-delivery.ts +82 -0
- package/src/session/auth-broker-config.ts +92 -0
- package/src/session/auth-storage.ts +25 -0
- package/src/session/bash-runner.ts +326 -0
- package/src/session/blob-store.ts +295 -0
- package/src/session/checkpoint-entries.ts +81 -0
- package/src/session/claude-session-store.ts +426 -0
- package/src/session/client-bridge.ts +85 -0
- package/src/session/codex-auto-reset.ts +673 -0
- package/src/session/codex-session-store.ts +673 -0
- package/src/session/compact-modes.ts +105 -0
- package/src/session/credential-pin.ts +93 -0
- package/src/session/eval-runner.ts +219 -0
- package/src/session/exit-diagnostics.ts +310 -0
- package/src/session/foreign-session-import.ts +52 -0
- package/src/session/foreign-session-jsonl.ts +29 -0
- package/src/session/foreign-session-store.ts +26 -0
- package/src/session/history-storage.ts +329 -0
- package/src/session/indexed-session-storage.ts +553 -0
- package/src/session/irc-bridge.ts +203 -0
- package/src/session/launch-completion.ts +37 -0
- package/src/session/messages.ts +1304 -0
- package/src/session/model-controls.ts +757 -0
- package/src/session/prewalk.ts +279 -0
- package/src/session/provider-image-budget.ts +86 -0
- package/src/session/queued-messages.ts +99 -0
- package/src/session/redis-session-storage.ts +257 -0
- package/src/session/retry-fallback-chains.ts +455 -0
- package/src/session/role-models.ts +85 -0
- package/src/session/session-advisors.ts +1896 -0
- package/src/session/session-context.ts +584 -0
- package/src/session/session-dump-format.ts +216 -0
- package/src/session/session-entries.ts +306 -0
- package/src/session/session-handoff.ts +325 -0
- package/src/session/session-history-format.ts +459 -0
- package/src/session/session-listing.ts +715 -0
- package/src/session/session-loader.ts +362 -0
- package/src/session/session-maintenance.ts +3115 -0
- package/src/session/session-manager.ts +2747 -0
- package/src/session/session-memory.ts +222 -0
- package/src/session/session-metadata.ts +53 -0
- package/src/session/session-migrations.ts +78 -0
- package/src/session/session-paths.ts +280 -0
- package/src/session/session-persistence.ts +293 -0
- package/src/session/session-provider-boundary.ts +306 -0
- package/src/session/session-stats.ts +349 -0
- package/src/session/session-storage.ts +774 -0
- package/src/session/session-title-slot.ts +141 -0
- package/src/session/session-tools.ts +1385 -0
- package/src/session/session-workspace.ts +53 -0
- package/src/session/settings-stream-fn.ts +79 -0
- package/src/session/shake-types.ts +43 -0
- package/src/session/snapcompact-inline.ts +545 -0
- package/src/session/snapcompact-savings-journal.ts +113 -0
- package/src/session/sql-session-storage.ts +374 -0
- package/src/session/stream-guards.ts +417 -0
- package/src/session/streaming-output.ts +1459 -0
- package/src/session/todo-tracker.ts +380 -0
- package/src/session/tool-choice-queue.ts +305 -0
- package/src/session/ttsr-coordinator.ts +496 -0
- package/src/session/turn-persistence.ts +142 -0
- package/src/session/turn-recovery.ts +2005 -0
- package/src/session/unexpected-stop-classifier.ts +141 -0
- package/src/session/yield-queue.ts +288 -0
- package/src/slash-commands/acp-builtins.ts +70 -0
- package/src/slash-commands/available-commands.ts +105 -0
- package/src/slash-commands/builtin-registry.ts +3149 -0
- package/src/slash-commands/helpers/active-oauth-account.ts +80 -0
- package/src/slash-commands/helpers/collab-qrcode.ts +28 -0
- package/src/slash-commands/helpers/context-report.ts +66 -0
- package/src/slash-commands/helpers/format.ts +46 -0
- package/src/slash-commands/helpers/logout.ts +108 -0
- package/src/slash-commands/helpers/marketplace-manager.ts +25 -0
- package/src/slash-commands/helpers/mcp.ts +533 -0
- package/src/slash-commands/helpers/parse.ts +85 -0
- package/src/slash-commands/helpers/reset-usage.ts +68 -0
- package/src/slash-commands/helpers/security.ts +451 -0
- package/src/slash-commands/helpers/session-pin.ts +44 -0
- package/src/slash-commands/helpers/ssh.ts +196 -0
- package/src/slash-commands/helpers/stats-dashboard.ts +86 -0
- package/src/slash-commands/helpers/todo.ts +285 -0
- package/src/slash-commands/helpers/usage-report.ts +198 -0
- package/src/slash-commands/marketplace-install-parser.ts +99 -0
- package/src/slash-commands/types.ts +139 -0
- package/src/ssh/config-writer.ts +183 -0
- package/src/ssh/connection-manager.ts +667 -0
- package/src/ssh/file-transfer.ts +214 -0
- package/src/ssh/sshfs-mount.ts +163 -0
- package/src/ssh/utils.ts +51 -0
- package/src/startup-splash.ts +19 -0
- package/src/stt/asr-client.ts +401 -0
- package/src/stt/asr-protocol.ts +65 -0
- package/src/stt/asr-worker.ts +603 -0
- package/src/stt/downloader.ts +142 -0
- package/src/stt/endpointer.ts +259 -0
- package/src/stt/index.ts +6 -0
- package/src/stt/models.ts +150 -0
- package/src/stt/sherpa-runtime.ts +71 -0
- package/src/stt/stt-controller.ts +320 -0
- package/src/stt/submit-trigger.ts +74 -0
- package/src/subprocess/worker-client.ts +463 -0
- package/src/subprocess/worker-runtime.ts +494 -0
- package/src/system-prompt.ts +921 -0
- package/src/task/agents.ts +170 -0
- package/src/task/commands.ts +132 -0
- package/src/task/discovery.ts +145 -0
- package/src/task/executor.ts +3431 -0
- package/src/task/index.ts +1515 -0
- package/src/task/isolation-ownership.ts +106 -0
- package/src/task/isolation-runner.ts +444 -0
- package/src/task/label.ts +40 -0
- package/src/task/name-generator.ts +1577 -0
- package/src/task/omp-command.ts +26 -0
- package/src/task/output-manager.ts +115 -0
- package/src/task/parallel.ts +221 -0
- package/src/task/persisted-revive.ts +173 -0
- package/src/task/prewalk.ts +6 -0
- package/src/task/prompt-policy.ts +8 -0
- package/src/task/provider-concurrency.ts +100 -0
- package/src/task/read-only-policy.ts +27 -0
- package/src/task/render.ts +1830 -0
- package/src/task/renderer.ts +14 -0
- package/src/task/repair-args.ts +118 -0
- package/src/task/spawn-policy.ts +72 -0
- package/src/task/structured-subagent.ts +676 -0
- package/src/task/subprocess-tool-registry.ts +88 -0
- package/src/task/types.ts +555 -0
- package/src/task/worktree.ts +967 -0
- package/src/task/yield-assembly.ts +198 -0
- package/src/telemetry-export.ts +504 -0
- package/src/thinking.ts +377 -0
- package/src/tiny/device.ts +111 -0
- package/src/tiny/dtype.ts +101 -0
- package/src/tiny/message-preproc.ts +155 -0
- package/src/tiny/models.ts +268 -0
- package/src/tiny/text.ts +290 -0
- package/src/tiny/title-client.ts +460 -0
- package/src/tiny/title-protocol.ts +56 -0
- package/src/tiny/worker.ts +354 -0
- package/src/tools/acp-bridge.ts +125 -0
- package/src/tools/approval.ts +245 -0
- package/src/tools/ask.ts +1459 -0
- package/src/tools/ast-edit.ts +718 -0
- package/src/tools/ast-grep.ts +526 -0
- package/src/tools/auto-generated-guard.ts +335 -0
- package/src/tools/bash-interactive.ts +435 -0
- package/src/tools/bash-interceptor.ts +148 -0
- package/src/tools/bash-pty-selection.ts +14 -0
- package/src/tools/bash-skill-urls.ts +350 -0
- package/src/tools/bash.ts +1826 -0
- package/src/tools/browser/aria/aria-snapshot.bundle.txt +7 -0
- package/src/tools/browser/aria/aria-snapshot.ts +131 -0
- package/src/tools/browser/attach.ts +219 -0
- package/src/tools/browser/cmux/cmux-tab.ts +1531 -0
- package/src/tools/browser/cmux/rpc.ts +200 -0
- package/src/tools/browser/cmux/socket-client.ts +445 -0
- package/src/tools/browser/launch.ts +939 -0
- package/src/tools/browser/readable.ts +112 -0
- package/src/tools/browser/registry.ts +447 -0
- package/src/tools/browser/relay/bridge.ts +945 -0
- package/src/tools/browser/relay/daemon.ts +117 -0
- package/src/tools/browser/relay/extension-assets/background.js.txt +242 -0
- package/src/tools/browser/relay/extension-assets/manifest.json.txt +14 -0
- package/src/tools/browser/relay/extension-assets/options.html.txt +53 -0
- package/src/tools/browser/relay/extension-assets/options.js.txt +23 -0
- package/src/tools/browser/relay/kind.ts +41 -0
- package/src/tools/browser/relay/protocol.ts +54 -0
- package/src/tools/browser/relay/server.ts +141 -0
- package/src/tools/browser/render.ts +229 -0
- package/src/tools/browser/run-output.ts +76 -0
- package/src/tools/browser/shared-daemon.ts +139 -0
- package/src/tools/browser/tab-protocol.ts +123 -0
- package/src/tools/browser/tab-supervisor.ts +1077 -0
- package/src/tools/browser/tab-worker-entry.ts +29 -0
- package/src/tools/browser/tab-worker.ts +1982 -0
- package/src/tools/browser.ts +487 -0
- package/src/tools/builtin-names.ts +67 -0
- package/src/tools/checkpoint.ts +137 -0
- package/src/tools/computer/exposure.ts +14 -0
- package/src/tools/computer/protocol.ts +69 -0
- package/src/tools/computer/supervisor.ts +409 -0
- package/src/tools/computer/worker-entry.ts +39 -0
- package/src/tools/computer/worker.ts +745 -0
- package/src/tools/computer-renderer.ts +147 -0
- package/src/tools/computer.ts +222 -0
- package/src/tools/conflict-detect.ts +815 -0
- package/src/tools/context.ts +49 -0
- package/src/tools/debug.ts +1121 -0
- package/src/tools/default-renderer.ts +154 -0
- package/src/tools/essential-tools.ts +46 -0
- package/src/tools/eval-backends.ts +34 -0
- package/src/tools/eval-format/index.ts +24 -0
- package/src/tools/eval-format/javascript.ts +952 -0
- package/src/tools/eval-format/julia.ts +446 -0
- package/src/tools/eval-format/python.ts +544 -0
- package/src/tools/eval-format/ruby.ts +380 -0
- package/src/tools/eval-render.ts +784 -0
- package/src/tools/eval.ts +774 -0
- package/src/tools/fetch.ts +1889 -0
- package/src/tools/file-recorder.ts +35 -0
- package/src/tools/fs-cache-invalidation.ts +28 -0
- package/src/tools/gh-cache-invalidation.ts +175 -0
- package/src/tools/gh-format.ts +12 -0
- package/src/tools/gh-renderer.ts +484 -0
- package/src/tools/gh.ts +3958 -0
- package/src/tools/github-cache.ts +663 -0
- package/src/tools/glob.ts +691 -0
- package/src/tools/grep.ts +1920 -0
- package/src/tools/grouped-file-output.ts +210 -0
- package/src/tools/hub/index.ts +579 -0
- package/src/tools/hub/jobs.ts +714 -0
- package/src/tools/hub/launch.ts +690 -0
- package/src/tools/hub/messaging.ts +735 -0
- package/src/tools/hub/types.ts +117 -0
- package/src/tools/image-gen.ts +1689 -0
- package/src/tools/image-providers.ts +50 -0
- package/src/tools/index.ts +736 -0
- package/src/tools/inspect-image-renderer.ts +133 -0
- package/src/tools/inspect-image.ts +316 -0
- package/src/tools/json-tree.ts +260 -0
- package/src/tools/jtd-to-json-schema.ts +219 -0
- package/src/tools/jtd-to-typescript.ts +136 -0
- package/src/tools/jtd-utils.ts +102 -0
- package/src/tools/learn.ts +141 -0
- package/src/tools/list-limit.ts +40 -0
- package/src/tools/manage-skill.ts +102 -0
- package/src/tools/match-line-format.ts +20 -0
- package/src/tools/memory-edit.ts +61 -0
- package/src/tools/memory-recall.ts +102 -0
- package/src/tools/memory-reflect.ts +88 -0
- package/src/tools/memory-render.ts +211 -0
- package/src/tools/memory-retain.ts +89 -0
- package/src/tools/output-meta.ts +860 -0
- package/src/tools/output-schema-validator.ts +307 -0
- package/src/tools/path-utils.ts +1489 -0
- package/src/tools/plan-mode-guard.ts +155 -0
- package/src/tools/puppeteer/00_stealth_tampering.txt +44 -0
- package/src/tools/puppeteer/01_stealth_activity.txt +80 -0
- package/src/tools/puppeteer/02_stealth_hairline.txt +57 -0
- package/src/tools/puppeteer/03_stealth_botd.txt +380 -0
- package/src/tools/puppeteer/04_stealth_iframe.txt +174 -0
- package/src/tools/puppeteer/05_stealth_webgl.txt +233 -0
- package/src/tools/puppeteer/06_stealth_screen.txt +260 -0
- package/src/tools/puppeteer/07_stealth_fonts.txt +99 -0
- package/src/tools/puppeteer/08_stealth_audio.txt +63 -0
- package/src/tools/puppeteer/09_stealth_locale.txt +51 -0
- package/src/tools/puppeteer/10_stealth_plugins.txt +212 -0
- package/src/tools/puppeteer/11_stealth_hardware.txt +59 -0
- package/src/tools/puppeteer/12_stealth_codecs.txt +42 -0
- package/src/tools/puppeteer/13_stealth_worker.txt +235 -0
- package/src/tools/read.ts +3762 -0
- package/src/tools/render-utils.ts +926 -0
- package/src/tools/renderers.ts +133 -0
- package/src/tools/report-tool-issue.ts +568 -0
- package/src/tools/resolve.ts +423 -0
- package/src/tools/review.ts +103 -0
- package/src/tools/run-scope.ts +417 -0
- package/src/tools/security-scan.ts +287 -0
- package/src/tools/shell-tokenize.ts +213 -0
- package/src/tools/sqlite-reader.ts +884 -0
- package/src/tools/terminal-output.ts +141 -0
- package/src/tools/todo.ts +1226 -0
- package/src/tools/tool-errors.ts +62 -0
- package/src/tools/tool-result.ts +102 -0
- package/src/tools/tool-timeouts.ts +38 -0
- package/src/tools/tts.ts +266 -0
- package/src/tools/vibe.ts +608 -0
- package/src/tools/write.ts +1646 -0
- package/src/tools/xdev.ts +560 -0
- package/src/tools/yield.ts +486 -0
- package/src/tts/downloader.ts +64 -0
- package/src/tts/index.ts +10 -0
- package/src/tts/models.ts +137 -0
- package/src/tts/runtime.ts +21 -0
- package/src/tts/speakable.ts +392 -0
- package/src/tts/speech-enhancer.ts +206 -0
- package/src/tts/streaming-player.ts +120 -0
- package/src/tts/tts-client.ts +475 -0
- package/src/tts/tts-protocol.ts +69 -0
- package/src/tts/tts-worker.ts +434 -0
- package/src/tts/vocalizer.ts +419 -0
- package/src/tts/wav.ts +58 -0
- package/src/tui/code-cell.ts +268 -0
- package/src/tui/file-list.ts +55 -0
- package/src/tui/hyperlink.ts +178 -0
- package/src/tui/index.ts +13 -0
- package/src/tui/output-block.ts +268 -0
- package/src/tui/status-line.ts +54 -0
- package/src/tui/tree-list.ts +172 -0
- package/src/tui/types.ts +15 -0
- package/src/tui/utils.ts +103 -0
- package/src/tui/width-aware-text.ts +58 -0
- package/src/utils/active-repo-context.ts +143 -0
- package/src/utils/block-context.ts +312 -0
- package/src/utils/changelog.ts +373 -0
- package/src/utils/clipboard.ts +361 -0
- package/src/utils/command-args.ts +74 -0
- package/src/utils/commit-message-generator.ts +148 -0
- package/src/utils/cpuprofile.ts +235 -0
- package/src/utils/edit-mode.ts +61 -0
- package/src/utils/enhanced-paste.ts +230 -0
- package/src/utils/event-bus.ts +33 -0
- package/src/utils/external-editor.ts +80 -0
- package/src/utils/fetch-timeout.ts +10 -0
- package/src/utils/file-display-mode.ts +44 -0
- package/src/utils/file-mentions.ts +293 -0
- package/src/utils/git.ts +2472 -0
- package/src/utils/image-loading.ts +236 -0
- package/src/utils/image-resize.ts +420 -0
- package/src/utils/image-vision-fallback.ts +196 -0
- package/src/utils/inspect-image-mode.ts +39 -0
- package/src/utils/ipc.ts +38 -0
- package/src/utils/jj.ts +422 -0
- package/src/utils/lang-from-path.ts +251 -0
- package/src/utils/late-cleanup.ts +17 -0
- package/src/utils/local-date.ts +7 -0
- package/src/utils/mac-file-urls.applescript +37 -0
- package/src/utils/markit-cache.ts +166 -0
- package/src/utils/markit.ts +223 -0
- package/src/utils/mupdf-wasm-embed.ts +12 -0
- package/src/utils/open.ts +126 -0
- package/src/utils/profile-tree.ts +111 -0
- package/src/utils/prompt-path.ts +3 -0
- package/src/utils/qrcode.ts +535 -0
- package/src/utils/sample-profile.ts +437 -0
- package/src/utils/session-color.ts +142 -0
- package/src/utils/shell-snapshot-fn-env.sh +63 -0
- package/src/utils/shell-snapshot.ts +326 -0
- package/src/utils/sixel.ts +69 -0
- package/src/utils/thinking-display.ts +163 -0
- package/src/utils/title-generator.ts +597 -0
- package/src/utils/token-rate.ts +72 -0
- package/src/utils/tool-choice.ts +50 -0
- package/src/utils/tools-manager.ts +411 -0
- package/src/utils/turndown.ts +82 -0
- package/src/utils/zip.ts +1106 -0
- package/src/vibe/runtime.ts +1684 -0
- package/src/vibe/state.ts +4 -0
- package/src/web/kagi.ts +305 -0
- package/src/web/parallel.ts +354 -0
- package/src/web/scrapers/artifacthub.ts +207 -0
- package/src/web/scrapers/arxiv.ts +83 -0
- package/src/web/scrapers/aur.ts +162 -0
- package/src/web/scrapers/biorxiv.ts +133 -0
- package/src/web/scrapers/bluesky.ts +262 -0
- package/src/web/scrapers/brew.ts +172 -0
- package/src/web/scrapers/cheatsh.ts +68 -0
- package/src/web/scrapers/chocolatey.ts +196 -0
- package/src/web/scrapers/choosealicense.ts +95 -0
- package/src/web/scrapers/cisa-kev.ts +87 -0
- package/src/web/scrapers/clojars.ts +154 -0
- package/src/web/scrapers/coingecko.ts +177 -0
- package/src/web/scrapers/crates-io.ts +97 -0
- package/src/web/scrapers/crossref.ts +136 -0
- package/src/web/scrapers/devto.ts +147 -0
- package/src/web/scrapers/discogs.ts +306 -0
- package/src/web/scrapers/discourse.ts +197 -0
- package/src/web/scrapers/dockerhub.ts +138 -0
- package/src/web/scrapers/docs-rs.ts +663 -0
- package/src/web/scrapers/fdroid.ts +134 -0
- package/src/web/scrapers/firefox-addons.ts +191 -0
- package/src/web/scrapers/flathub.ts +223 -0
- package/src/web/scrapers/github-gist.ts +58 -0
- package/src/web/scrapers/github.ts +800 -0
- package/src/web/scrapers/gitlab.ts +401 -0
- package/src/web/scrapers/go-pkg.ts +266 -0
- package/src/web/scrapers/hackage.ts +129 -0
- package/src/web/scrapers/hackernews.ts +189 -0
- package/src/web/scrapers/hex.ts +105 -0
- package/src/web/scrapers/huggingface.ts +321 -0
- package/src/web/scrapers/iacr.ts +89 -0
- package/src/web/scrapers/index.ts +252 -0
- package/src/web/scrapers/jetbrains-marketplace.ts +159 -0
- package/src/web/scrapers/lemmy.ts +203 -0
- package/src/web/scrapers/lobsters.ts +175 -0
- package/src/web/scrapers/mastodon.ts +292 -0
- package/src/web/scrapers/maven.ts +138 -0
- package/src/web/scrapers/mdn.ts +173 -0
- package/src/web/scrapers/metacpan.ts +222 -0
- package/src/web/scrapers/musicbrainz.ts +250 -0
- package/src/web/scrapers/npm.ts +98 -0
- package/src/web/scrapers/nuget.ts +183 -0
- package/src/web/scrapers/nvd.ts +222 -0
- package/src/web/scrapers/ollama.ts +239 -0
- package/src/web/scrapers/open-vsx.ts +106 -0
- package/src/web/scrapers/opencorporates.ts +292 -0
- package/src/web/scrapers/openlibrary.ts +336 -0
- package/src/web/scrapers/orcid.ts +286 -0
- package/src/web/scrapers/osv.ts +176 -0
- package/src/web/scrapers/packagist.ts +160 -0
- package/src/web/scrapers/pub-dev.ts +143 -0
- package/src/web/scrapers/pubmed.ts +211 -0
- package/src/web/scrapers/pypi.ts +112 -0
- package/src/web/scrapers/rawg.ts +110 -0
- package/src/web/scrapers/readthedocs.ts +121 -0
- package/src/web/scrapers/reddit.ts +95 -0
- package/src/web/scrapers/repology.ts +251 -0
- package/src/web/scrapers/rfc.ts +201 -0
- package/src/web/scrapers/rubygems.ts +103 -0
- package/src/web/scrapers/searchcode.ts +189 -0
- package/src/web/scrapers/sec-edgar.ts +261 -0
- package/src/web/scrapers/semantic-scholar.ts +171 -0
- package/src/web/scrapers/snapcraft.ts +187 -0
- package/src/web/scrapers/sourcegraph.ts +336 -0
- package/src/web/scrapers/spdx.ts +108 -0
- package/src/web/scrapers/spotify.ts +198 -0
- package/src/web/scrapers/stackoverflow.ts +120 -0
- package/src/web/scrapers/terraform.ts +277 -0
- package/src/web/scrapers/tldr.ts +47 -0
- package/src/web/scrapers/twitter.ts +94 -0
- package/src/web/scrapers/types.ts +354 -0
- package/src/web/scrapers/utils.ts +109 -0
- package/src/web/scrapers/vimeo.ts +133 -0
- package/src/web/scrapers/vscode-marketplace.ts +187 -0
- package/src/web/scrapers/w3c.ts +156 -0
- package/src/web/scrapers/wikidata.ts +344 -0
- package/src/web/scrapers/wikipedia.ts +84 -0
- package/src/web/scrapers/youtube.ts +325 -0
- package/src/web/search/index.ts +393 -0
- package/src/web/search/provider.ts +272 -0
- package/src/web/search/providers/anthropic.ts +406 -0
- package/src/web/search/providers/base.ts +112 -0
- package/src/web/search/providers/brave.ts +181 -0
- package/src/web/search/providers/browser-headers.ts +82 -0
- package/src/web/search/providers/browser-page.ts +125 -0
- package/src/web/search/providers/codex.ts +788 -0
- package/src/web/search/providers/duckduckgo.ts +382 -0
- package/src/web/search/providers/ecosia.ts +183 -0
- package/src/web/search/providers/exa.ts +513 -0
- package/src/web/search/providers/firecrawl.ts +213 -0
- package/src/web/search/providers/gemini.ts +634 -0
- package/src/web/search/providers/google.ts +195 -0
- package/src/web/search/providers/jina.ts +144 -0
- package/src/web/search/providers/kagi.ts +98 -0
- package/src/web/search/providers/kimi.ts +221 -0
- package/src/web/search/providers/mojeek.ts +220 -0
- package/src/web/search/providers/parallel.ts +186 -0
- package/src/web/search/providers/perplexity-auth.ts +142 -0
- package/src/web/search/providers/perplexity.ts +997 -0
- package/src/web/search/providers/public.ts +199 -0
- package/src/web/search/providers/searxng.ts +467 -0
- package/src/web/search/providers/startpage.ts +225 -0
- package/src/web/search/providers/synthetic.ts +126 -0
- package/src/web/search/providers/tavily.ts +244 -0
- package/src/web/search/providers/tinyfish.ts +166 -0
- package/src/web/search/providers/utils.ts +130 -0
- package/src/web/search/providers/xai.ts +372 -0
- package/src/web/search/providers/zai.ts +452 -0
- package/src/web/search/query.ts +850 -0
- package/src/web/search/render.ts +262 -0
- package/src/web/search/types.ts +518 -0
- package/src/web/search/utils.ts +17 -0
- package/src/workspace-tree.ts +326 -0
|
@@ -0,0 +1,1515 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task tool - Delegate tasks to specialized agents.
|
|
3
|
+
*
|
|
4
|
+
* Discovers agent definitions from:
|
|
5
|
+
* - Bundled agents (shipped with omp-coding-agent)
|
|
6
|
+
* - ~/.omp/agent/agents/*.md (user-level)
|
|
7
|
+
* - .omp/agents/*.md (project-level)
|
|
8
|
+
*
|
|
9
|
+
* Supports:
|
|
10
|
+
* - Single agent spawn per call (parallelism = parallel task calls)
|
|
11
|
+
* - Batch spawning + shared context per call when `task.batch` is enabled
|
|
12
|
+
* - Background execution through AsyncJobManager when `async.enabled` is enabled
|
|
13
|
+
* - Progress tracking via JSON events
|
|
14
|
+
* - Session artifacts for debugging
|
|
15
|
+
*/
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import type { AgentTool, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
18
|
+
import type { Usage } from "@oh-my-pi/pi-ai";
|
|
19
|
+
import { $env, logger, prompt } from "@oh-my-pi/pi-utils";
|
|
20
|
+
import type { ToolSession } from "..";
|
|
21
|
+
import type { Theme } from "../modes/theme/theme";
|
|
22
|
+
import subagentUserPromptTemplate from "../prompts/system/subagent-user-prompt.md" with { type: "text" };
|
|
23
|
+
import taskDescriptionTemplate from "../prompts/tools/task.md" with { type: "text" };
|
|
24
|
+
import taskAsyncContractTemplate from "../prompts/tools/task-async-contract.md" with { type: "text" };
|
|
25
|
+
import taskSummaryTemplate from "../prompts/tools/task-summary.md" with { type: "text" };
|
|
26
|
+
import { TASK_EFFORTS, type TaskEffort } from "../thinking";
|
|
27
|
+
import { truncateForPrompt } from "../tools/approval";
|
|
28
|
+
import { isIrcEnabled } from "../tools/hub";
|
|
29
|
+
import { formatBytes, formatDuration } from "../tools/render-utils";
|
|
30
|
+
import { isReadOnlyAgent } from "./read-only-policy";
|
|
31
|
+
import { isScoutSpawnable, resolveSpawnPolicy } from "./spawn-policy";
|
|
32
|
+
import {
|
|
33
|
+
type AgentDefinition,
|
|
34
|
+
type AgentProgress,
|
|
35
|
+
canSpawnAtDepth,
|
|
36
|
+
getTaskSchema,
|
|
37
|
+
type SingleResult,
|
|
38
|
+
type TaskItem,
|
|
39
|
+
type TaskParams,
|
|
40
|
+
type TaskToolDetails,
|
|
41
|
+
type TaskToolSchemaInstance,
|
|
42
|
+
} from "./types";
|
|
43
|
+
// Import review tools for side effects (registers subagent tool handlers)
|
|
44
|
+
import "../tools/review";
|
|
45
|
+
import type { AsyncJobManager } from "../async";
|
|
46
|
+
import { hasResolvableTranscript } from "../internal-urls/registry-helpers";
|
|
47
|
+
import { AgentRegistry } from "../registry/agent-registry";
|
|
48
|
+
import { type DiscoveryResult, discoverAgents } from "./discovery";
|
|
49
|
+
import { generateTaskName } from "./name-generator";
|
|
50
|
+
import { AgentOutputManager } from "./output-manager";
|
|
51
|
+
import { mapWithConcurrencyLimitAllSettled, Semaphore } from "./parallel";
|
|
52
|
+
import { renderResult, renderCall as renderTaskCall } from "./render";
|
|
53
|
+
import { repairTaskParams } from "./repair-args";
|
|
54
|
+
import { resolveEffectiveSubagentPolicy, runStructuredSubagent, StructuredSubagentError } from "./structured-subagent";
|
|
55
|
+
|
|
56
|
+
function renderSubagentUserPrompt(assignment: string): string {
|
|
57
|
+
return prompt.render(subagentUserPromptTemplate, {
|
|
58
|
+
assignment: assignment.trim(),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function createUsageTotals(): Usage {
|
|
63
|
+
return {
|
|
64
|
+
input: 0,
|
|
65
|
+
output: 0,
|
|
66
|
+
cacheRead: 0,
|
|
67
|
+
cacheWrite: 0,
|
|
68
|
+
totalTokens: 0,
|
|
69
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function addUsageTotals(target: Usage, usage: Partial<Usage>): void {
|
|
74
|
+
const input = usage.input ?? 0;
|
|
75
|
+
const output = usage.output ?? 0;
|
|
76
|
+
const cacheRead = usage.cacheRead ?? 0;
|
|
77
|
+
const cacheWrite = usage.cacheWrite ?? 0;
|
|
78
|
+
const totalTokens = usage.totalTokens ?? input + output + cacheRead + cacheWrite;
|
|
79
|
+
const cost =
|
|
80
|
+
usage.cost ??
|
|
81
|
+
({
|
|
82
|
+
input: 0,
|
|
83
|
+
output: 0,
|
|
84
|
+
cacheRead: 0,
|
|
85
|
+
cacheWrite: 0,
|
|
86
|
+
total: 0,
|
|
87
|
+
} satisfies Usage["cost"]);
|
|
88
|
+
|
|
89
|
+
target.input += input;
|
|
90
|
+
target.output += output;
|
|
91
|
+
target.cacheRead += cacheRead;
|
|
92
|
+
target.cacheWrite += cacheWrite;
|
|
93
|
+
target.totalTokens += totalTokens;
|
|
94
|
+
target.cost.input += cost.input;
|
|
95
|
+
target.cost.output += cost.output;
|
|
96
|
+
target.cost.cacheRead += cost.cacheRead;
|
|
97
|
+
target.cost.cacheWrite += cost.cacheWrite;
|
|
98
|
+
target.cost.total += cost.total;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Re-export types and utilities
|
|
102
|
+
export { loadBundledAgents as BUNDLED_AGENTS } from "./agents";
|
|
103
|
+
export { discoverCommands, expandCommand, getCommand } from "./commands";
|
|
104
|
+
export { discoverAgents, getAgent } from "./discovery";
|
|
105
|
+
export { AgentOutputManager } from "./output-manager";
|
|
106
|
+
export * from "./read-only-policy";
|
|
107
|
+
export type {
|
|
108
|
+
AgentDefinition,
|
|
109
|
+
AgentProgress,
|
|
110
|
+
SingleResult,
|
|
111
|
+
SubagentEventPayload,
|
|
112
|
+
SubagentLifecyclePayload,
|
|
113
|
+
SubagentProgressPayload,
|
|
114
|
+
TaskParams,
|
|
115
|
+
TaskToolDetails,
|
|
116
|
+
} from "./types";
|
|
117
|
+
export {
|
|
118
|
+
TASK_SUBAGENT_EVENT_CHANNEL,
|
|
119
|
+
TASK_SUBAGENT_LIFECYCLE_CHANNEL,
|
|
120
|
+
TASK_SUBAGENT_PROGRESS_CHANNEL,
|
|
121
|
+
taskSchema,
|
|
122
|
+
} from "./types";
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Preview text for a child result. Falls back to "(no output)" — annotated
|
|
126
|
+
* with the request count when the child actually did work, so the parent can
|
|
127
|
+
* tell a no-op child from one that burned requests before being cancelled.
|
|
128
|
+
*/
|
|
129
|
+
export function formatResultOutputFallback(result: Pick<SingleResult, "output" | "stderr" | "requests">): string {
|
|
130
|
+
const base = result.output.trim() || result.stderr.trim();
|
|
131
|
+
if (base) return base;
|
|
132
|
+
return result.requests > 0 ? `(no output) after ${result.requests} req` : "(no output)";
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
interface TaskDescriptionOptions {
|
|
136
|
+
agents: AgentDefinition[];
|
|
137
|
+
isolationEnabled: boolean;
|
|
138
|
+
applyIsolatedChanges: boolean;
|
|
139
|
+
disabledAgents: string[];
|
|
140
|
+
batchEnabled: boolean;
|
|
141
|
+
effortEnabled: boolean;
|
|
142
|
+
asyncEnabled: boolean;
|
|
143
|
+
ircEnabled: boolean;
|
|
144
|
+
parentSpawns: string;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** Render the tool description from a cached agent list and current settings. */
|
|
148
|
+
function renderDescription(options: TaskDescriptionOptions): string {
|
|
149
|
+
const spawnPolicy = resolveSpawnPolicy(options.parentSpawns);
|
|
150
|
+
const spawningDisabled = !spawnPolicy.enabled;
|
|
151
|
+
let filteredAgents =
|
|
152
|
+
options.disabledAgents.length > 0
|
|
153
|
+
? options.agents.filter(agent => !options.disabledAgents.includes(agent.name))
|
|
154
|
+
: options.agents;
|
|
155
|
+
if (spawningDisabled) {
|
|
156
|
+
filteredAgents = [];
|
|
157
|
+
} else if (spawnPolicy.allowedAgents !== null) {
|
|
158
|
+
const allowed = new Set(spawnPolicy.allowedAgents);
|
|
159
|
+
filteredAgents = filteredAgents.filter(agent => allowed.has(agent.name));
|
|
160
|
+
}
|
|
161
|
+
const renderedAgents = filteredAgents.map(agent => ({
|
|
162
|
+
name: agent.name,
|
|
163
|
+
description: agent.description,
|
|
164
|
+
readOnly: isReadOnlyAgent(agent),
|
|
165
|
+
blocking: agent.blocking === true,
|
|
166
|
+
}));
|
|
167
|
+
const scoutAvailable = isScoutSpawnable(options.disabledAgents, options.parentSpawns);
|
|
168
|
+
return prompt.render(taskDescriptionTemplate, {
|
|
169
|
+
agents: renderedAgents,
|
|
170
|
+
scoutAvailable,
|
|
171
|
+
spawningDisabled,
|
|
172
|
+
defaultAgent: spawnPolicy.defaultAgent,
|
|
173
|
+
isolationEnabled: options.isolationEnabled,
|
|
174
|
+
applyIsolatedChanges: options.applyIsolatedChanges,
|
|
175
|
+
batchEnabled: options.batchEnabled,
|
|
176
|
+
effortEnabled: options.effortEnabled,
|
|
177
|
+
asyncEnabled: options.asyncEnabled,
|
|
178
|
+
hasBlockingAgents: renderedAgents.some(agent => agent.blocking),
|
|
179
|
+
ircEnabled: options.ircEnabled,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function createTaskModeError(text: string): AgentToolResult<TaskToolDetails> {
|
|
184
|
+
return {
|
|
185
|
+
content: [{ type: "text", text }],
|
|
186
|
+
details: { projectAgentsDir: null, results: [], totalDurationMs: 0 },
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Reject legacy fields and shape/configuration combinations the current tool
|
|
192
|
+
* cannot accept. `outputSchema` is a first-class per-spawn field; stale
|
|
193
|
+
* `schema` remains an eval-only alias and is rejected.
|
|
194
|
+
*/
|
|
195
|
+
function validateShapeParams(batchEnabled: boolean, params: TaskParams): string | undefined {
|
|
196
|
+
if (Object.hasOwn(params, "schema")) {
|
|
197
|
+
return "The task tool uses `outputSchema`; rename the stale `schema` field.";
|
|
198
|
+
}
|
|
199
|
+
if (!batchEnabled) {
|
|
200
|
+
const disallowed = (["tasks", "context"] as const).filter(field => params[field] !== undefined);
|
|
201
|
+
if (disallowed.length > 0) {
|
|
202
|
+
return `task.batch is disabled, so the task tool does not accept ${disallowed.map(f => `\`${f}\``).join(" or ")}. Spawn one agent per call with \`task\`, or enable the task.batch setting.`;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Validate the spawn parameter contract against the wire shapes. With
|
|
210
|
+
* `task.batch` the model-facing shape is `{ context, tasks[] }` — `tasks`
|
|
211
|
+
* non-empty with per-item `task` instructions and unique names, `context`
|
|
212
|
+
* non-empty, no top-level `task` alongside. The flat `{ agent?, ...item }`
|
|
213
|
+
* form stays accepted at runtime under either setting (internal callers, stale
|
|
214
|
+
* transcripts). Missing `agent` values resolve against the session spawn
|
|
215
|
+
* policy later, in `spawnParamsFor`. Returns a problem description, or
|
|
216
|
+
* undefined when valid.
|
|
217
|
+
*/
|
|
218
|
+
|
|
219
|
+
/** Reject an out-of-range `effort` selector on internal/stale-transcript calls that bypass the wire schema. */
|
|
220
|
+
function validateEffort(effort: TaskEffort | undefined, label: string): string | undefined {
|
|
221
|
+
if (effort === undefined || TASK_EFFORTS.includes(effort)) return undefined;
|
|
222
|
+
return `${label} has an invalid \`effort\` value ${JSON.stringify(effort)}. Use "lo", "med", or "hi".`;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function validateSpawnParams(params: TaskParams, batchEnabled: boolean): string | undefined {
|
|
226
|
+
const hasTask = typeof params.task === "string" && params.task.trim() !== "";
|
|
227
|
+
const tasks = params.tasks;
|
|
228
|
+
if (batchEnabled && tasks !== undefined) {
|
|
229
|
+
if (!Array.isArray(tasks) || tasks.length === 0) {
|
|
230
|
+
return "Missing `tasks`. Provide at least one task item ({ name?, agent?, task }).";
|
|
231
|
+
}
|
|
232
|
+
if (hasTask) {
|
|
233
|
+
return "Top-level `task` is not part of the batch shape. Put the work in `tasks[]` items.";
|
|
234
|
+
}
|
|
235
|
+
for (let i = 0; i < tasks.length; i++) {
|
|
236
|
+
const item = tasks[i];
|
|
237
|
+
if (!item || typeof item.task !== "string" || item.task.trim() === "") {
|
|
238
|
+
return `Task ${i + 1}${item?.name ? ` (\`${item.name}\`)` : ""} is missing \`task\`. Every task needs complete, self-contained instructions.`;
|
|
239
|
+
}
|
|
240
|
+
const effortError = validateEffort(item.effort, `Task ${i + 1}${item.name ? ` (\`${item.name}\`)` : ""}`);
|
|
241
|
+
if (effortError) return effortError;
|
|
242
|
+
}
|
|
243
|
+
const seen = new Map<string, string>();
|
|
244
|
+
for (const item of tasks) {
|
|
245
|
+
const name = item.name?.trim();
|
|
246
|
+
if (!name) continue;
|
|
247
|
+
const key = name.toLowerCase();
|
|
248
|
+
const existing = seen.get(key);
|
|
249
|
+
if (existing !== undefined) {
|
|
250
|
+
return `Duplicate task name ${existing === name ? `\`${name}\`` : `\`${existing}\` / \`${name}\``}. Provided names must be unique within a call (case-insensitive).`;
|
|
251
|
+
}
|
|
252
|
+
seen.set(key, name);
|
|
253
|
+
}
|
|
254
|
+
if (typeof params.context !== "string" || params.context.trim() === "") {
|
|
255
|
+
return "Missing `context`. Provide the shared background for this batch — goal, constraints, and any contract the tasks share.";
|
|
256
|
+
}
|
|
257
|
+
return undefined;
|
|
258
|
+
}
|
|
259
|
+
if (!hasTask) {
|
|
260
|
+
return batchEnabled
|
|
261
|
+
? "Missing `tasks`. Provide a `tasks` array (one subagent per item) with a shared `context`."
|
|
262
|
+
: "Missing `task`. Provide complete, self-contained instructions for the agent.";
|
|
263
|
+
}
|
|
264
|
+
return validateEffort(params.effort, "The call");
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Normalize a validated call into its spawn list: the `tasks[]` batch when
|
|
269
|
+
* provided, otherwise the single top-level spawn. The flat form's `isolated`
|
|
270
|
+
* flag is only materialized when the caller sent one — `#runSpawn`
|
|
271
|
+
* distinguishes an absent key from an explicit value.
|
|
272
|
+
*/
|
|
273
|
+
function resolveSpawnItems(params: TaskParams): TaskItem[] {
|
|
274
|
+
if (Array.isArray(params.tasks) && params.tasks.length > 0) {
|
|
275
|
+
return params.tasks;
|
|
276
|
+
}
|
|
277
|
+
const item: TaskItem = { name: params.name, agent: params.agent, task: params.task };
|
|
278
|
+
if ("outputSchema" in params) item.outputSchema = params.outputSchema;
|
|
279
|
+
if ("schemaMode" in params) item.schemaMode = params.schemaMode;
|
|
280
|
+
if ("effort" in params) item.effort = params.effort;
|
|
281
|
+
if ("isolated" in params) item.isolated = params.isolated;
|
|
282
|
+
return [item];
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Per-spawn params handed to the executor path: top-level call fields with the
|
|
287
|
+
* item's identity substituted in. Each spawn's `agent` resolves here —
|
|
288
|
+
* the item's own value, else `defaultAgent` from the session spawn policy.
|
|
289
|
+
* `tasks` never leaks into a spawn; the shared `context` rides along
|
|
290
|
+
* unchanged. Keys are only materialized when present — `#runSpawn`
|
|
291
|
+
* distinguishes an absent `isolated` from an explicit one. The item's
|
|
292
|
+
* `isolated` (batch form) wins over the top-level flag (flat form).
|
|
293
|
+
*/
|
|
294
|
+
function spawnParamsFor(params: TaskParams, item: TaskItem, defaultAgent: string): TaskParams {
|
|
295
|
+
const spawn: TaskParams = { agent: item.agent?.trim() || defaultAgent };
|
|
296
|
+
if (item.name !== undefined) spawn.name = item.name;
|
|
297
|
+
if (item.task !== undefined) spawn.task = item.task;
|
|
298
|
+
if (params.context !== undefined) spawn.context = params.context;
|
|
299
|
+
if ("outputSchema" in item) spawn.outputSchema = item.outputSchema;
|
|
300
|
+
if ("schemaMode" in item) spawn.schemaMode = item.schemaMode;
|
|
301
|
+
if ("effort" in item) spawn.effort = item.effort;
|
|
302
|
+
if (item.isolated !== undefined) {
|
|
303
|
+
spawn.isolated = item.isolated;
|
|
304
|
+
} else if ("isolated" in params) {
|
|
305
|
+
spawn.isolated = params.isolated;
|
|
306
|
+
}
|
|
307
|
+
return spawn;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** One sync-executed spawn: its item, position in the original call, and (for mixed calls) a pre-claimed agent id. */
|
|
311
|
+
interface SyncSpawnRef {
|
|
312
|
+
item: TaskItem;
|
|
313
|
+
index: number;
|
|
314
|
+
preAllocatedId?: string;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/** Merged view of a sync spawn set's payloads: joined text plus flattened results/usage/paths. */
|
|
318
|
+
interface MergedSyncPayloads {
|
|
319
|
+
contentParts: string[];
|
|
320
|
+
results: SingleResult[];
|
|
321
|
+
usage?: Usage;
|
|
322
|
+
outputPaths?: string[];
|
|
323
|
+
projectAgentsDir: string | null;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Merge per-spawn sync payloads into one result view. `index` is each spawn's
|
|
328
|
+
* position in the original call so batch rows keep stable ordering; a missing
|
|
329
|
+
* payload (cancelled before start) becomes an explanatory content line.
|
|
330
|
+
*/
|
|
331
|
+
function mergeSyncPayloads(
|
|
332
|
+
spawns: SyncSpawnRef[],
|
|
333
|
+
payloads: (AgentToolResult<TaskToolDetails> | undefined)[],
|
|
334
|
+
): MergedSyncPayloads {
|
|
335
|
+
const results: SingleResult[] = [];
|
|
336
|
+
const contentParts: string[] = [];
|
|
337
|
+
const outputPaths: string[] = [];
|
|
338
|
+
const usageTotals = createUsageTotals();
|
|
339
|
+
let hasUsage = false;
|
|
340
|
+
let projectAgentsDir: string | null = null;
|
|
341
|
+
for (let position = 0; position < spawns.length; position++) {
|
|
342
|
+
const payload = payloads[position];
|
|
343
|
+
const { item, index } = spawns[position];
|
|
344
|
+
if (!payload) {
|
|
345
|
+
contentParts.push(`Task ${item.name?.trim() || `#${index + 1}`}: cancelled before start.`);
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
projectAgentsDir ??= payload.details?.projectAgentsDir ?? null;
|
|
349
|
+
const text = payload.content.find(part => part.type === "text")?.text;
|
|
350
|
+
if (text) contentParts.push(text);
|
|
351
|
+
for (const result of payload.details?.results ?? []) {
|
|
352
|
+
results.push({ ...result, index });
|
|
353
|
+
if (result.usage) {
|
|
354
|
+
addUsageTotals(usageTotals, result.usage);
|
|
355
|
+
hasUsage = true;
|
|
356
|
+
}
|
|
357
|
+
if (result.outputPath) outputPaths.push(result.outputPath);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
return {
|
|
361
|
+
contentParts,
|
|
362
|
+
results,
|
|
363
|
+
usage: hasUsage ? usageTotals : undefined,
|
|
364
|
+
outputPaths: outputPaths.length > 0 ? outputPaths : undefined,
|
|
365
|
+
projectAgentsDir,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/** Generic worker agent types; several in one call usually means a more specific type exists. */
|
|
370
|
+
const GENERIC_SPAWN_AGENTS: ReadonlySet<string> = new Set(["task", "sonic"]);
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Advisory — never a rejection — nudging the spawner toward tailored
|
|
374
|
+
* specific agent types when one call resolves ≥2 items to a generic
|
|
375
|
+
* `task`/`sonic` worker and the spawner still holds spawn capacity
|
|
376
|
+
* (DepthCapacity: it currently has the `task` tool). `agentNames` are the
|
|
377
|
+
* per-item resolved agent types. Returns undefined when no nudge applies.
|
|
378
|
+
*/
|
|
379
|
+
export function buildSpecializationAdvisory(
|
|
380
|
+
agentNames: string[],
|
|
381
|
+
depthCapacity: boolean,
|
|
382
|
+
scoutAvailable = true,
|
|
383
|
+
): string | undefined {
|
|
384
|
+
if (!depthCapacity) return undefined;
|
|
385
|
+
const generics = agentNames.filter(name => GENERIC_SPAWN_AGENTS.has(name));
|
|
386
|
+
if (generics.length < 2) return undefined;
|
|
387
|
+
const specialist = scoutAvailable
|
|
388
|
+
? `Check the agent list for a closer specialist type — e.g. read-only research belongs on ` +
|
|
389
|
+
`\`agent: "scout"\`, which runs on a faster model.`
|
|
390
|
+
: `Check the agent list for a closer specialist type.`;
|
|
391
|
+
return `Tip: this call spawned ${generics.length} generic \`${generics[0]}\` workers. ${specialist}`;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Suggestion — never a rejection — nudging the spawner to coordinate via the
|
|
396
|
+
* hub when one call creates ≥2 live siblings and it still holds spawn
|
|
397
|
+
* capacity. Returns undefined when there is nothing to coordinate or peer
|
|
398
|
+
* messaging is unavailable.
|
|
399
|
+
*/
|
|
400
|
+
export function buildCoordinationAdvisory(
|
|
401
|
+
items: TaskItem[],
|
|
402
|
+
depthCapacity: boolean,
|
|
403
|
+
ircEnabled: boolean,
|
|
404
|
+
): string | undefined {
|
|
405
|
+
if (!depthCapacity || !ircEnabled || items.length < 2) return undefined;
|
|
406
|
+
return (
|
|
407
|
+
`Coordinate: ${items.length} siblings are running together. If their work overlaps, have them ` +
|
|
408
|
+
`message each other via \`hub\` (by id, or "all" to broadcast) before editing shared files — ` +
|
|
409
|
+
`live coordination beats a serial handoff. Check \`hub\` op:"list" to see who is doing what.`
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Compose the non-blocking advisory appended to a `task` result: the
|
|
415
|
+
* specialization nudge (from the per-item resolved agent types), plus — only
|
|
416
|
+
* when some spawns keep running after this call (`willRunAsync`) — the
|
|
417
|
+
* coordination suggestion over those still-live spawns (`items`). Coordination
|
|
418
|
+
* is gated on async because a sync spawn has already finished by the time the
|
|
419
|
+
* call returns, so a "coordinate while they run" hint would misfire. Returns
|
|
420
|
+
* undefined when neither applies.
|
|
421
|
+
*/
|
|
422
|
+
export function composeSpawnAdvisory(args: {
|
|
423
|
+
agents: string[];
|
|
424
|
+
items: TaskItem[];
|
|
425
|
+
depthCapacity: boolean;
|
|
426
|
+
ircEnabled: boolean;
|
|
427
|
+
willRunAsync: boolean;
|
|
428
|
+
scoutAvailable?: boolean;
|
|
429
|
+
}): string | undefined {
|
|
430
|
+
return (
|
|
431
|
+
[
|
|
432
|
+
buildSpecializationAdvisory(args.agents, args.depthCapacity, args.scoutAvailable),
|
|
433
|
+
args.willRunAsync ? buildCoordinationAdvisory(args.items, args.depthCapacity, args.ircEnabled) : undefined,
|
|
434
|
+
]
|
|
435
|
+
.filter(Boolean)
|
|
436
|
+
.join("\n\n") || undefined
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/** Sentinel for async jobs whose subagent finished with a failing result; progress is already updated. */
|
|
441
|
+
class TaskJobError extends Error {}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Process-level memo for create-time agent discovery, keyed by resolved cwd.
|
|
445
|
+
*
|
|
446
|
+
* `TaskTool.create` runs for every (sub)agent session in this process and the
|
|
447
|
+
* walk-up + plugin-registry scan in `discoverAgents` is identical for a given
|
|
448
|
+
* cwd, so repeat creations reuse the first scan. Execution-time discovery
|
|
449
|
+
* (`#runSpawn`) intentionally stays fresh. The memo also tracks the live
|
|
450
|
+
* `discoverAgents` binding: test spies swap that binding, which invalidates
|
|
451
|
+
* the memo automatically.
|
|
452
|
+
*/
|
|
453
|
+
const discoveryMemo = new Map<string, Promise<DiscoveryResult>>();
|
|
454
|
+
let discoveryMemoFn: typeof discoverAgents | undefined;
|
|
455
|
+
|
|
456
|
+
function discoverAgentsForCreate(cwd: string): Promise<DiscoveryResult> {
|
|
457
|
+
const fn = discoverAgents;
|
|
458
|
+
if (discoveryMemoFn !== fn) {
|
|
459
|
+
discoveryMemoFn = fn;
|
|
460
|
+
discoveryMemo.clear();
|
|
461
|
+
}
|
|
462
|
+
const key = path.resolve(cwd);
|
|
463
|
+
let pending = discoveryMemo.get(key);
|
|
464
|
+
if (!pending) {
|
|
465
|
+
pending = fn(cwd);
|
|
466
|
+
discoveryMemo.set(key, pending);
|
|
467
|
+
pending.catch(() => {
|
|
468
|
+
if (discoveryMemo.get(key) === pending) discoveryMemo.delete(key);
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
return pending;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
475
|
+
// Tool Class
|
|
476
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Task tool - Delegate tasks to specialized agents.
|
|
480
|
+
*
|
|
481
|
+
* Each call spawns one subagent — or, with `task.batch`, one per `tasks[]`
|
|
482
|
+
* item. When `async.enabled` is on, spawns run as AsyncJobManager jobs; when
|
|
483
|
+
* disabled, the tool blocks until every spawn finishes.
|
|
484
|
+
*/
|
|
485
|
+
export class TaskTool implements AgentTool<TaskToolSchemaInstance, TaskToolDetails, Theme> {
|
|
486
|
+
readonly name = "task";
|
|
487
|
+
readonly approval = "exec" as const;
|
|
488
|
+
readonly formatApprovalDetails = (args: unknown): string[] => {
|
|
489
|
+
const params = args as Partial<TaskParams>;
|
|
490
|
+
const lines: string[] = [];
|
|
491
|
+
if (typeof params.agent === "string") {
|
|
492
|
+
lines.push(`Agent: ${truncateForPrompt(params.agent)}`);
|
|
493
|
+
}
|
|
494
|
+
if (typeof params.name === "string" && params.name.trim()) {
|
|
495
|
+
lines.push(`Name: ${truncateForPrompt(params.name)}`);
|
|
496
|
+
}
|
|
497
|
+
if (typeof params.task === "string") {
|
|
498
|
+
lines.push(`Task:\n${truncateForPrompt(params.task)}`);
|
|
499
|
+
}
|
|
500
|
+
if (typeof params.context === "string" && params.context.trim()) {
|
|
501
|
+
lines.push(`Context:\n${truncateForPrompt(params.context)}`);
|
|
502
|
+
}
|
|
503
|
+
const tasks: unknown[] = Array.isArray(params.tasks) ? params.tasks : [];
|
|
504
|
+
if (tasks.length > 0) {
|
|
505
|
+
const defaultAgent = resolveSpawnPolicy(this.session.getSessionSpawns()).defaultAgent;
|
|
506
|
+
const effectiveAgent = (item: unknown): string => {
|
|
507
|
+
if (item && typeof item === "object" && "agent" in item) {
|
|
508
|
+
const agent = item.agent;
|
|
509
|
+
if (typeof agent === "string" && agent.trim()) return agent.trim();
|
|
510
|
+
}
|
|
511
|
+
return defaultAgent;
|
|
512
|
+
};
|
|
513
|
+
const agentCounts = new Map<string, number>();
|
|
514
|
+
for (const item of tasks) {
|
|
515
|
+
const agent = effectiveAgent(item);
|
|
516
|
+
agentCounts.set(agent, (agentCounts.get(agent) ?? 0) + 1);
|
|
517
|
+
}
|
|
518
|
+
const agentSummary = [...agentCounts].map(([agent, count]) => `${agent} ×${count}`).join(", ");
|
|
519
|
+
lines.push(`Batch agents: ${truncateForPrompt(agentSummary)}`);
|
|
520
|
+
|
|
521
|
+
const firstTask = tasks[0];
|
|
522
|
+
if (firstTask && typeof firstTask === "object") {
|
|
523
|
+
if ("name" in firstTask && typeof firstTask.name === "string" && firstTask.name.trim()) {
|
|
524
|
+
lines.push(`Name: ${truncateForPrompt(firstTask.name)}`);
|
|
525
|
+
}
|
|
526
|
+
lines.push(`Agent: ${truncateForPrompt(effectiveAgent(firstTask))}`);
|
|
527
|
+
if ("task" in firstTask && typeof firstTask.task === "string") {
|
|
528
|
+
lines.push(`Task:\n${truncateForPrompt(firstTask.task)}`);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
if (tasks.length > 1) {
|
|
532
|
+
lines.push(`+${tasks.length - 1} more task${tasks.length === 2 ? "" : "s"}`);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
return lines;
|
|
536
|
+
};
|
|
537
|
+
readonly label = "Task";
|
|
538
|
+
readonly summary = "Spawn subagents to complete delegated tasks";
|
|
539
|
+
readonly strict = false;
|
|
540
|
+
readonly loadMode = "essential";
|
|
541
|
+
// Arktype validates model calls against the active wire schema, but the flat
|
|
542
|
+
// single-spawn schema carries `"+": "delete"`: a batch `{ context, tasks[] }`
|
|
543
|
+
// payload has those keys stripped, then fails on the now-missing `task` with
|
|
544
|
+
// the misleading `task must be a string (was missing)`. That preempts the
|
|
545
|
+
// tool's own actionable shape checks (`validateShapeParams` /
|
|
546
|
+
// `validateSpawnParams`), which never run. Lenient validation forwards the
|
|
547
|
+
// raw args to `execute()` on any arktype failure so those checks surface the
|
|
548
|
+
// real reason ("enable task.batch, or use the flat `task` shape"). Valid
|
|
549
|
+
// calls still normalize through arktype; `execute()` resolves `agent`
|
|
550
|
+
// defaults independently, so the success path is unchanged.
|
|
551
|
+
readonly lenientArgValidation = true;
|
|
552
|
+
readonly renderResult = renderResult;
|
|
553
|
+
// Suppress the streaming call preview once a (partial or final) result exists
|
|
554
|
+
// so the task renders as ONE block that transitions in place — not a pending
|
|
555
|
+
// call frame stacked above the result frame. Mirrors `taskToolRenderer`.
|
|
556
|
+
readonly mergeCallAndResult = true;
|
|
557
|
+
readonly #discoveredAgents: AgentDefinition[];
|
|
558
|
+
readonly #blockedAgent: string | undefined;
|
|
559
|
+
/**
|
|
560
|
+
* One semaphore per TaskTool instance (i.e. per session): bounds concurrent
|
|
561
|
+
* subagents across parallel `task` calls within the session. Resized in
|
|
562
|
+
* place from `task.maxConcurrency` before every acquire/release so a
|
|
563
|
+
* mid-session settings change (UI toggle, `/settings`) applies to both new
|
|
564
|
+
* spawns and work already parked in the semaphore queue.
|
|
565
|
+
*/
|
|
566
|
+
#spawnSemaphore: Semaphore | undefined;
|
|
567
|
+
|
|
568
|
+
get parameters(): TaskToolSchemaInstance {
|
|
569
|
+
const planMode = this.session.getPlanModeState?.()?.enabled === true;
|
|
570
|
+
const isolationEnabled = !planMode && this.session.settings.get("task.isolation.mode") !== "none";
|
|
571
|
+
const defaultAgent = resolveSpawnPolicy(this.session.getSessionSpawns()).defaultAgent;
|
|
572
|
+
return getTaskSchema({
|
|
573
|
+
isolationEnabled,
|
|
574
|
+
batchEnabled: this.#isBatchEnabled(),
|
|
575
|
+
effortEnabled: this.session.settings.get("task.enableEffort"),
|
|
576
|
+
defaultAgent,
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
renderCall(args: unknown, options: Parameters<typeof renderTaskCall>[1], theme: Theme) {
|
|
581
|
+
return renderTaskCall(repairTaskParams(args as TaskParams), options, theme);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/** Dynamic description that reflects current task settings. */
|
|
585
|
+
get description(): string {
|
|
586
|
+
const disabledAgents = this.session.settings.get("task.disabledAgents") as string[];
|
|
587
|
+
const planMode = this.session.getPlanModeState?.()?.enabled === true;
|
|
588
|
+
const isolationMode = this.session.settings.get("task.isolation.mode");
|
|
589
|
+
return renderDescription({
|
|
590
|
+
agents: this.#discoveredAgents,
|
|
591
|
+
isolationEnabled: !planMode && isolationMode !== "none",
|
|
592
|
+
applyIsolatedChanges: this.session.settings.get("task.isolation.apply"),
|
|
593
|
+
disabledAgents,
|
|
594
|
+
batchEnabled: this.#isBatchEnabled(),
|
|
595
|
+
effortEnabled: this.session.settings.get("task.enableEffort"),
|
|
596
|
+
asyncEnabled: this.session.settings.get("async.enabled"),
|
|
597
|
+
ircEnabled: isIrcEnabled(this.session.settings, this.session.taskDepth ?? 0),
|
|
598
|
+
parentSpawns: this.session.getSessionSpawns() ?? "*",
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
private constructor(
|
|
602
|
+
private readonly session: ToolSession,
|
|
603
|
+
discoveredAgents: AgentDefinition[],
|
|
604
|
+
) {
|
|
605
|
+
this.#blockedAgent = $env.PI_BLOCKED_AGENT;
|
|
606
|
+
this.#discoveredAgents = discoveredAgents;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
#isBatchEnabled(): boolean {
|
|
610
|
+
return this.session.settings.get("task.batch");
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
#getSpawnSemaphore(): Semaphore {
|
|
614
|
+
const max = this.session.settings.get("task.maxConcurrency");
|
|
615
|
+
if (this.#spawnSemaphore) {
|
|
616
|
+
this.#spawnSemaphore.resize(max);
|
|
617
|
+
} else {
|
|
618
|
+
this.#spawnSemaphore = new Semaphore(max);
|
|
619
|
+
}
|
|
620
|
+
return this.#spawnSemaphore;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
#releaseSpawnSemaphore(): void {
|
|
624
|
+
this.#getSpawnSemaphore().release();
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Resolve the shared policy before detached work exists. The resulting
|
|
629
|
+
* policy intentionally stays local: executor dispatch resolves again from
|
|
630
|
+
* normalized task params rather than smuggling internal policy over the
|
|
631
|
+
* task wire contract.
|
|
632
|
+
*/
|
|
633
|
+
#resolveSpawnPreflight(params: TaskParams) {
|
|
634
|
+
return resolveEffectiveSubagentPolicy({
|
|
635
|
+
session: this.session,
|
|
636
|
+
invocationKind: "task",
|
|
637
|
+
assignment: (params.task ?? "").trim(),
|
|
638
|
+
context: this.#isBatchEnabled() ? params.context?.trim() || undefined : undefined,
|
|
639
|
+
agent: params.agent,
|
|
640
|
+
...(Object.hasOwn(params, "outputSchema") ? { outputSchema: params.outputSchema } : {}),
|
|
641
|
+
...(Object.hasOwn(params, "schemaMode") ? { schemaMode: params.schemaMode } : {}),
|
|
642
|
+
...(params.effort !== undefined ? { effort: params.effort } : {}),
|
|
643
|
+
...("isolated" in params ? { isolation: { requested: params.isolated } } : {}),
|
|
644
|
+
blockedAgent: this.#blockedAgent,
|
|
645
|
+
enableLsp: (this.session.enableLsp ?? true) && this.session.settings.get("task.enableLsp"),
|
|
646
|
+
enableIrc: isIrcEnabled(this.session.settings, this.session.taskDepth ?? 0),
|
|
647
|
+
maxRuntimeMs: this.session.settings.get("task.maxRuntimeMs"),
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Create a TaskTool instance with async agent discovery.
|
|
653
|
+
*/
|
|
654
|
+
static async create(session: ToolSession): Promise<TaskTool> {
|
|
655
|
+
const { agents } = await discoverAgentsForCreate(session.cwd);
|
|
656
|
+
return new TaskTool(session, agents);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
async execute(
|
|
660
|
+
toolCallId: string,
|
|
661
|
+
rawParams: unknown,
|
|
662
|
+
signal?: AbortSignal,
|
|
663
|
+
onUpdate?: AgentToolUpdateCallback<TaskToolDetails>,
|
|
664
|
+
): Promise<AgentToolResult<TaskToolDetails>> {
|
|
665
|
+
const params = repairTaskParams(rawParams as TaskParams);
|
|
666
|
+
// Schema defaults fill `agent` for model calls, but internal callers
|
|
667
|
+
// and stale transcripts can bypass arktype. `spawnParamsFor` resolves each
|
|
668
|
+
// item's agent type against the session's actual default agent.
|
|
669
|
+
const defaultAgent = resolveSpawnPolicy(this.session.getSessionSpawns()).defaultAgent;
|
|
670
|
+
const batchEnabled = this.#isBatchEnabled();
|
|
671
|
+
const validationError = validateShapeParams(batchEnabled, params) ?? validateSpawnParams(params, batchEnabled);
|
|
672
|
+
if (validationError) {
|
|
673
|
+
return createTaskModeError(validationError);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
const spawnItems = resolveSpawnItems(params);
|
|
677
|
+
const normalizedSpawnParams = spawnItems.map(item => spawnParamsFor(params, item, defaultAgent));
|
|
678
|
+
const resolvedAgents = normalizedSpawnParams.map(spawn => spawn.agent ?? defaultAgent);
|
|
679
|
+
// Resolve every item before choosing an execution path. No executor or
|
|
680
|
+
// job manager may observe a batch unless every effective policy is valid.
|
|
681
|
+
const preflights = await Promise.all(
|
|
682
|
+
normalizedSpawnParams.map(async spawn => {
|
|
683
|
+
try {
|
|
684
|
+
return { policy: await this.#resolveSpawnPreflight(spawn) };
|
|
685
|
+
} catch (error) {
|
|
686
|
+
return { error: error instanceof StructuredSubagentError ? error.message : String(error) };
|
|
687
|
+
}
|
|
688
|
+
}),
|
|
689
|
+
);
|
|
690
|
+
const preflightFailures = preflights
|
|
691
|
+
.map((preflight, index) => ("error" in preflight ? { index, error: preflight.error } : undefined))
|
|
692
|
+
.filter((failure): failure is { index: number; error: string } => failure !== undefined);
|
|
693
|
+
if (preflightFailures.length > 0) {
|
|
694
|
+
if (!batchEnabled) {
|
|
695
|
+
return createTaskModeError(`Task execution failed: ${preflightFailures[0]!.error}`);
|
|
696
|
+
}
|
|
697
|
+
return createTaskModeError(
|
|
698
|
+
preflightFailures
|
|
699
|
+
.map(({ index, error }) => {
|
|
700
|
+
const item = spawnItems[index]!;
|
|
701
|
+
return `Task ${item.name?.trim() || `#${index + 1}`} failed preflight: ${error}`;
|
|
702
|
+
})
|
|
703
|
+
.join("\n"),
|
|
704
|
+
);
|
|
705
|
+
}
|
|
706
|
+
const policies = preflights.map(preflight => preflight.policy!);
|
|
707
|
+
const itemBlocking = policies.map(policy => policy.effectiveAgent.blocking === true);
|
|
708
|
+
|
|
709
|
+
// Execution mode is per item: an item whose agent type declares
|
|
710
|
+
// `blocking: true` runs inline on this turn (the parent waits on its
|
|
711
|
+
// result); every other item becomes a background job when async
|
|
712
|
+
// execution is available.
|
|
713
|
+
const asyncEnabled = this.session.settings.get("async.enabled");
|
|
714
|
+
const manager = asyncEnabled ? this.session.asyncJobManager : undefined;
|
|
715
|
+
const asyncItems = manager ? spawnItems.filter((_, index) => !itemBlocking[index]) : [];
|
|
716
|
+
const depthCapacity = canSpawnAtDepth(
|
|
717
|
+
this.session.settings.get("task.maxRecursionDepth") ?? 2,
|
|
718
|
+
this.session.taskDepth ?? 0,
|
|
719
|
+
);
|
|
720
|
+
const ircEnabled = isIrcEnabled(this.session.settings, this.session.taskDepth ?? 0);
|
|
721
|
+
|
|
722
|
+
if (!manager || asyncItems.length === 0) {
|
|
723
|
+
// Sync fallback: async execution disabled, orphaned host that never
|
|
724
|
+
// wired a job manager, or every item's agent type declares
|
|
725
|
+
// `blocking: true`.
|
|
726
|
+
if (asyncEnabled && !this.session.asyncJobManager) {
|
|
727
|
+
logger.warn("task: no AsyncJobManager registered; falling back to sync execution");
|
|
728
|
+
}
|
|
729
|
+
const advisory = this.session.suppressSpawnAdvisory
|
|
730
|
+
? undefined
|
|
731
|
+
: composeSpawnAdvisory({
|
|
732
|
+
agents: resolvedAgents,
|
|
733
|
+
items: asyncItems,
|
|
734
|
+
depthCapacity,
|
|
735
|
+
ircEnabled,
|
|
736
|
+
willRunAsync: false,
|
|
737
|
+
scoutAvailable: isScoutSpawnable(
|
|
738
|
+
this.session.settings.get("task.disabledAgents") as string[] | undefined,
|
|
739
|
+
this.session.getSessionSpawns?.() ?? "*",
|
|
740
|
+
),
|
|
741
|
+
});
|
|
742
|
+
const result = await this.#executeSyncFanout(
|
|
743
|
+
toolCallId,
|
|
744
|
+
params,
|
|
745
|
+
spawnItems.map((item, index) => ({ item, index })),
|
|
746
|
+
defaultAgent,
|
|
747
|
+
signal,
|
|
748
|
+
onUpdate,
|
|
749
|
+
);
|
|
750
|
+
if (!advisory) return result;
|
|
751
|
+
let appended = false;
|
|
752
|
+
const content = result.content.map(part => {
|
|
753
|
+
if (!appended && part.type === "text" && typeof part.text === "string") {
|
|
754
|
+
appended = true;
|
|
755
|
+
return { ...part, text: `${part.text}\n\n${advisory}` };
|
|
756
|
+
}
|
|
757
|
+
return part;
|
|
758
|
+
});
|
|
759
|
+
if (!appended) content.push({ type: "text", text: advisory });
|
|
760
|
+
return { ...result, content };
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// Coordination only makes sense for spawns that keep running after this
|
|
764
|
+
// call returns (the async subset). Blocking items have already completed
|
|
765
|
+
// by then, so a "coordinate while they run" hint would misfire.
|
|
766
|
+
const advisory = this.session.suppressSpawnAdvisory
|
|
767
|
+
? undefined
|
|
768
|
+
: composeSpawnAdvisory({
|
|
769
|
+
agents: resolvedAgents,
|
|
770
|
+
items: asyncItems,
|
|
771
|
+
depthCapacity,
|
|
772
|
+
ircEnabled,
|
|
773
|
+
willRunAsync: asyncItems.length > 0,
|
|
774
|
+
scoutAvailable: isScoutSpawnable(
|
|
775
|
+
this.session.settings.get("task.disabledAgents") as string[] | undefined,
|
|
776
|
+
this.session.getSessionSpawns?.() ?? "*",
|
|
777
|
+
),
|
|
778
|
+
});
|
|
779
|
+
// Returns a fresh result (copied content array, copied text part) rather
|
|
780
|
+
// than mutating the caller's — task results are short-lived here, but an
|
|
781
|
+
// in-place edit on a shared/cached AgentToolResult would be a hidden trap.
|
|
782
|
+
const withAdvisory = (result: AgentToolResult<TaskToolDetails>): AgentToolResult<TaskToolDetails> => {
|
|
783
|
+
if (!advisory) return result;
|
|
784
|
+
let appended = false;
|
|
785
|
+
const content = result.content.map(part => {
|
|
786
|
+
if (!appended && part.type === "text" && typeof part.text === "string") {
|
|
787
|
+
appended = true;
|
|
788
|
+
return { ...part, text: `${part.text}\n\n${advisory}` };
|
|
789
|
+
}
|
|
790
|
+
return part;
|
|
791
|
+
});
|
|
792
|
+
if (!appended) content.push({ type: "text", text: advisory });
|
|
793
|
+
return { ...result, content };
|
|
794
|
+
};
|
|
795
|
+
if (asyncItems.length === 0) {
|
|
796
|
+
return withAdvisory(
|
|
797
|
+
await this.#executeSyncFanout(
|
|
798
|
+
toolCallId,
|
|
799
|
+
params,
|
|
800
|
+
spawnItems.map((item, index) => ({ item, index })),
|
|
801
|
+
defaultAgent,
|
|
802
|
+
signal,
|
|
803
|
+
onUpdate,
|
|
804
|
+
),
|
|
805
|
+
);
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// Async IDs are claimed before job registration, so retain the fallback
|
|
809
|
+
// manager on the session rather than recreating it for every call.
|
|
810
|
+
let outputManager = this.session.agentOutputManager;
|
|
811
|
+
if (!outputManager) {
|
|
812
|
+
outputManager = new AgentOutputManager(this.session.getArtifactsDir ?? (() => null));
|
|
813
|
+
this.session.agentOutputManager = outputManager;
|
|
814
|
+
}
|
|
815
|
+
const callStartedAt = Date.now();
|
|
816
|
+
const spawns: Array<{
|
|
817
|
+
agentId: string;
|
|
818
|
+
item: TaskItem;
|
|
819
|
+
index: number;
|
|
820
|
+
blocking: boolean;
|
|
821
|
+
progress: AgentProgress;
|
|
822
|
+
}> = [];
|
|
823
|
+
for (const [index, item] of spawnItems.entries()) {
|
|
824
|
+
const agentType = resolvedAgents[index]!;
|
|
825
|
+
const policy = policies[index]!;
|
|
826
|
+
const agentSource = policy.agent.source;
|
|
827
|
+
const agentId = await outputManager.allocate(item.name?.trim() || generateTaskName());
|
|
828
|
+
const assignment = (item.task ?? "").trim();
|
|
829
|
+
spawns.push({
|
|
830
|
+
agentId,
|
|
831
|
+
item,
|
|
832
|
+
index,
|
|
833
|
+
blocking: itemBlocking[index],
|
|
834
|
+
progress: {
|
|
835
|
+
index,
|
|
836
|
+
id: agentId,
|
|
837
|
+
agent: agentType,
|
|
838
|
+
agentSource,
|
|
839
|
+
modelRole: policy.modelRole,
|
|
840
|
+
status: "pending",
|
|
841
|
+
task: renderSubagentUserPrompt(assignment),
|
|
842
|
+
assignment,
|
|
843
|
+
recentTools: [],
|
|
844
|
+
recentOutput: [],
|
|
845
|
+
toolCount: 0,
|
|
846
|
+
requests: 0,
|
|
847
|
+
tokens: 0,
|
|
848
|
+
cost: 0,
|
|
849
|
+
durationMs: 0,
|
|
850
|
+
},
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
const asyncSpawns = spawns.filter(spawn => !spawn.blocking);
|
|
854
|
+
const syncSpawns = spawns.filter(spawn => spawn.blocking);
|
|
855
|
+
const agentLabel = [...new Set(asyncSpawns.map(spawn => spawn.progress.agent))].join(", ");
|
|
856
|
+
|
|
857
|
+
// Aggregate state for the one tool call. Async spawns report into the
|
|
858
|
+
// shared progress snapshot through their jobs: the async half stays
|
|
859
|
+
// "running" until every job settles, then turns "failed" if any spawn
|
|
860
|
+
// failed. Blocking spawns run inline below and land in `results` before
|
|
861
|
+
// the call returns, so post-return job updates never drop them.
|
|
862
|
+
let settledCount = 0;
|
|
863
|
+
let failedCount = 0;
|
|
864
|
+
let primaryJobId = asyncSpawns[0].agentId;
|
|
865
|
+
const syncResults: SingleResult[] = [];
|
|
866
|
+
let syncUsage: Usage | undefined;
|
|
867
|
+
let syncOutputPaths: string[] | undefined;
|
|
868
|
+
let syncProjectAgentsDir: string | null = null;
|
|
869
|
+
const buildAsyncDetails = (): TaskToolDetails => ({
|
|
870
|
+
projectAgentsDir: syncProjectAgentsDir,
|
|
871
|
+
results: [...syncResults],
|
|
872
|
+
totalDurationMs: Date.now() - callStartedAt,
|
|
873
|
+
usage: syncUsage,
|
|
874
|
+
outputPaths: syncOutputPaths,
|
|
875
|
+
progress: spawns.map(spawn => ({ ...spawn.progress })),
|
|
876
|
+
async: {
|
|
877
|
+
state: settledCount < asyncSpawns.length ? "running" : failedCount > 0 ? "failed" : "completed",
|
|
878
|
+
jobId: primaryJobId,
|
|
879
|
+
type: "task",
|
|
880
|
+
},
|
|
881
|
+
});
|
|
882
|
+
|
|
883
|
+
const started: Array<{ agentId: string; jobId: string }> = [];
|
|
884
|
+
const failedSchedules: string[] = [];
|
|
885
|
+
for (const spawn of asyncSpawns) {
|
|
886
|
+
try {
|
|
887
|
+
const jobId = this.#registerSpawnJob({
|
|
888
|
+
manager,
|
|
889
|
+
toolCallId,
|
|
890
|
+
spawnParams: spawnParamsFor(params, spawn.item, defaultAgent),
|
|
891
|
+
agentId: spawn.agentId,
|
|
892
|
+
progress: spawn.progress,
|
|
893
|
+
ircEnabled,
|
|
894
|
+
buildDetails: buildAsyncDetails,
|
|
895
|
+
onUpdate,
|
|
896
|
+
onSettled: failed => {
|
|
897
|
+
settledCount += 1;
|
|
898
|
+
if (failed) failedCount += 1;
|
|
899
|
+
},
|
|
900
|
+
});
|
|
901
|
+
if (started.length === 0) primaryJobId = jobId;
|
|
902
|
+
started.push({ agentId: spawn.agentId, jobId });
|
|
903
|
+
} catch (error) {
|
|
904
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
905
|
+
failedSchedules.push(`${spawn.agentId}: ${message}`);
|
|
906
|
+
spawn.progress.status = "failed";
|
|
907
|
+
settledCount += 1;
|
|
908
|
+
failedCount += 1;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
if (started.length === 0 && syncSpawns.length === 0) {
|
|
913
|
+
return {
|
|
914
|
+
content: [
|
|
915
|
+
{
|
|
916
|
+
type: "text",
|
|
917
|
+
text: `Failed to start background task job${failedSchedules.length === 1 ? "" : "s"}: ${failedSchedules.join("; ")}`,
|
|
918
|
+
},
|
|
919
|
+
],
|
|
920
|
+
details: { projectAgentsDir: null, results: [], totalDurationMs: 0 },
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
const scheduleFailureSummary =
|
|
925
|
+
failedSchedules.length > 0
|
|
926
|
+
? ` Failed to schedule ${failedSchedules.length} spawn${failedSchedules.length === 1 ? "" : "s"}: ${failedSchedules.join("; ")}.`
|
|
927
|
+
: "";
|
|
928
|
+
const coordinationHint = [
|
|
929
|
+
started.length === 1
|
|
930
|
+
? ircEnabled
|
|
931
|
+
? `DM \`${started[0].agentId}\` via \`hub\` send to coordinate while it runs; use \`hub\` only to inspect (\`jobs\`), wait, or cancel a stuck task.`
|
|
932
|
+
: `Use \`hub\` to inspect (\`jobs\`), wait, or cancel a stuck task.`
|
|
933
|
+
: ircEnabled
|
|
934
|
+
? `DM these ids via \`hub\` send to coordinate while they run; use \`hub\` only to inspect (\`jobs\`), wait, or cancel a stuck task.`
|
|
935
|
+
: `Use \`hub\` to inspect (\`jobs\`), wait, or cancel a stuck task by id.`,
|
|
936
|
+
taskAsyncContractTemplate.trim(),
|
|
937
|
+
].join("\n");
|
|
938
|
+
|
|
939
|
+
if (syncSpawns.length === 0) {
|
|
940
|
+
if (spawns.length === 1) {
|
|
941
|
+
const { agentId, jobId } = started[0];
|
|
942
|
+
onUpdate?.({
|
|
943
|
+
content: [{ type: "text", text: `Spawned agent \`${agentId}\`...` }],
|
|
944
|
+
details: buildAsyncDetails(),
|
|
945
|
+
});
|
|
946
|
+
return withAdvisory({
|
|
947
|
+
content: [
|
|
948
|
+
{
|
|
949
|
+
type: "text",
|
|
950
|
+
text: `Spawned agent \`${agentId}\` (job \`${jobId}\`). Its result auto-delivers on yield unless a settled \`hub jobs\`/\`wait\` snapshot consumes it first. ${coordinationHint}`,
|
|
951
|
+
},
|
|
952
|
+
],
|
|
953
|
+
details: buildAsyncDetails(),
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
const startedListing = started.map(({ agentId, jobId }) => `- \`${agentId}\` (job \`${jobId}\`)`).join("\n");
|
|
957
|
+
onUpdate?.({
|
|
958
|
+
content: [{ type: "text", text: `Spawned ${started.length} agents...` }],
|
|
959
|
+
details: buildAsyncDetails(),
|
|
960
|
+
});
|
|
961
|
+
return withAdvisory({
|
|
962
|
+
content: [
|
|
963
|
+
{
|
|
964
|
+
type: "text",
|
|
965
|
+
text: `Spawned ${started.length} background agents using ${agentLabel}.${scheduleFailureSummary} Each result auto-delivers on yield unless a settled \`hub jobs\`/\`wait\` snapshot consumes it first.\n${startedListing}\n${coordinationHint}`,
|
|
966
|
+
},
|
|
967
|
+
],
|
|
968
|
+
details: buildAsyncDetails(),
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
// Mixed call: the async jobs above already run detached; the blocking
|
|
973
|
+
// subset runs inline and gates the call's return — exactly what each
|
|
974
|
+
// agent type declares (`blocking: true` = the parent waits on it).
|
|
975
|
+
const syncLabel = syncSpawns.map(spawn => `\`${spawn.agentId}\``).join(", ");
|
|
976
|
+
onUpdate?.({
|
|
977
|
+
content: [
|
|
978
|
+
{
|
|
979
|
+
type: "text",
|
|
980
|
+
text: `Running ${syncLabel} inline; ${started.length} background agent${started.length === 1 ? "" : "s"} spawned...`,
|
|
981
|
+
},
|
|
982
|
+
],
|
|
983
|
+
details: buildAsyncDetails(),
|
|
984
|
+
});
|
|
985
|
+
const payloads = await this.#runSyncSpawns({
|
|
986
|
+
toolCallId,
|
|
987
|
+
params,
|
|
988
|
+
defaultAgent,
|
|
989
|
+
signal,
|
|
990
|
+
spawns: syncSpawns.map(spawn => ({ item: spawn.item, index: spawn.index, preAllocatedId: spawn.agentId })),
|
|
991
|
+
onItemProgress: onUpdate
|
|
992
|
+
? (index, progress) => {
|
|
993
|
+
const spawn = spawns.find(candidate => candidate.index === index);
|
|
994
|
+
if (spawn) spawn.progress = { ...progress, index };
|
|
995
|
+
onUpdate({
|
|
996
|
+
content: [{ type: "text", text: `Running ${syncLabel} inline...` }],
|
|
997
|
+
details: buildAsyncDetails(),
|
|
998
|
+
});
|
|
999
|
+
}
|
|
1000
|
+
: undefined,
|
|
1001
|
+
});
|
|
1002
|
+
const merged = mergeSyncPayloads(
|
|
1003
|
+
syncSpawns.map(spawn => ({ item: spawn.item, index: spawn.index })),
|
|
1004
|
+
payloads,
|
|
1005
|
+
);
|
|
1006
|
+
syncResults.push(...merged.results);
|
|
1007
|
+
syncUsage = merged.usage;
|
|
1008
|
+
syncOutputPaths = merged.outputPaths;
|
|
1009
|
+
syncProjectAgentsDir = merged.projectAgentsDir;
|
|
1010
|
+
// Settle the inline spawns' progress rows from their merged results so
|
|
1011
|
+
// post-return job updates carry final statuses, not the last snapshot.
|
|
1012
|
+
for (let position = 0; position < syncSpawns.length; position++) {
|
|
1013
|
+
const spawn = syncSpawns[position];
|
|
1014
|
+
const result = merged.results.find(r => r.id === spawn.agentId);
|
|
1015
|
+
if (result) {
|
|
1016
|
+
spawn.progress.status = result.aborted
|
|
1017
|
+
? "aborted"
|
|
1018
|
+
: result.exitCode === 0 && !result.error
|
|
1019
|
+
? "completed"
|
|
1020
|
+
: "failed";
|
|
1021
|
+
spawn.progress.durationMs = result.durationMs;
|
|
1022
|
+
} else {
|
|
1023
|
+
spawn.progress.status = payloads[position] ? "failed" : "aborted";
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
const spawnedSummary =
|
|
1028
|
+
started.length > 0
|
|
1029
|
+
? `Spawned ${started.length} background agent${started.length === 1 ? "" : "s"}.${scheduleFailureSummary} Each result auto-delivers on yield unless a settled \`hub jobs\`/\`wait\` snapshot consumes it first.\n${started.map(({ agentId, jobId }) => `- \`${agentId}\` (job \`${jobId}\`)`).join("\n")}\n${coordinationHint}`
|
|
1030
|
+
: scheduleFailureSummary.trim();
|
|
1031
|
+
const text = [merged.contentParts.join("\n\n"), spawnedSummary]
|
|
1032
|
+
.filter(section => section.trim().length > 0)
|
|
1033
|
+
.join("\n\n");
|
|
1034
|
+
return withAdvisory({
|
|
1035
|
+
content: [{ type: "text", text: text.length > 0 ? text : "No results." }],
|
|
1036
|
+
details: buildAsyncDetails(),
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* Register one background job that runs a single spawn to completion and
|
|
1042
|
+
* delivers its yield text. The job body mirrors the sync path; `buildDetails`
|
|
1043
|
+
* supplies the (possibly batch-shared) progress snapshot and `onSettled`
|
|
1044
|
+
* feeds the caller's aggregate counters.
|
|
1045
|
+
*/
|
|
1046
|
+
#registerSpawnJob(options: {
|
|
1047
|
+
manager: AsyncJobManager;
|
|
1048
|
+
toolCallId: string;
|
|
1049
|
+
spawnParams: TaskParams;
|
|
1050
|
+
agentId: string;
|
|
1051
|
+
progress: AgentProgress;
|
|
1052
|
+
ircEnabled: boolean;
|
|
1053
|
+
buildDetails: () => TaskToolDetails;
|
|
1054
|
+
onUpdate?: AgentToolUpdateCallback<TaskToolDetails>;
|
|
1055
|
+
onSettled?: (failed: boolean) => void;
|
|
1056
|
+
}): string {
|
|
1057
|
+
const { manager, toolCallId, spawnParams, agentId, progress, ircEnabled, buildDetails, onUpdate, onSettled } =
|
|
1058
|
+
options;
|
|
1059
|
+
const buildFollowUpHint = async (aborted: boolean): Promise<string> => {
|
|
1060
|
+
if (aborted) {
|
|
1061
|
+
const ref = AgentRegistry.global().get(agentId);
|
|
1062
|
+
const transcript = (await hasResolvableTranscript(agentId))
|
|
1063
|
+
? `transcript at history://${agentId}`
|
|
1064
|
+
: "transcript unavailable";
|
|
1065
|
+
if (ref?.status === "idle" || ref?.status === "parked") {
|
|
1066
|
+
const followUp = ircEnabled ? "message it via `hub` to resume; " : "";
|
|
1067
|
+
return `\n\n${agentId} was stopped but is still resumable — ${followUp}${transcript}`;
|
|
1068
|
+
}
|
|
1069
|
+
return `\n\n${agentId} was aborted — ${transcript}`;
|
|
1070
|
+
}
|
|
1071
|
+
const followUp = ircEnabled ? "message it via `hub` to follow up; " : "";
|
|
1072
|
+
return `\n\n${agentId} is now idle — ${followUp}transcript at history://${agentId}`;
|
|
1073
|
+
};
|
|
1074
|
+
return manager.register(
|
|
1075
|
+
"task",
|
|
1076
|
+
agentId,
|
|
1077
|
+
async ({ signal: runSignal, reportProgress, markRunning }) => {
|
|
1078
|
+
const startedAt = Date.now();
|
|
1079
|
+
const semaphore = this.#getSpawnSemaphore();
|
|
1080
|
+
let semaphoreHeld = false;
|
|
1081
|
+
// Every release funnels through here: the flag flips before the
|
|
1082
|
+
// release so no path — acquire-time abort, executor failure, or a
|
|
1083
|
+
// future refactor that reorders the branches — can return a permit
|
|
1084
|
+
// twice. Releasing a permit this job never acquired would steal one
|
|
1085
|
+
// from a running job and let a later spawn start past
|
|
1086
|
+
// task.maxConcurrency.
|
|
1087
|
+
const releasePermit = () => {
|
|
1088
|
+
if (!semaphoreHeld) return;
|
|
1089
|
+
semaphoreHeld = false;
|
|
1090
|
+
this.#releaseSpawnSemaphore();
|
|
1091
|
+
};
|
|
1092
|
+
try {
|
|
1093
|
+
await semaphore.acquire(runSignal);
|
|
1094
|
+
semaphoreHeld = true;
|
|
1095
|
+
} catch {
|
|
1096
|
+
// Fall through so an acquire-time abort goes through the same
|
|
1097
|
+
// path as the post-acquire race below: progress + onSettled
|
|
1098
|
+
// have to fire even when the spawn never reached the executor,
|
|
1099
|
+
// otherwise the batch aggregate state stays "running" forever.
|
|
1100
|
+
}
|
|
1101
|
+
const acquiredAt = Date.now();
|
|
1102
|
+
if (!semaphoreHeld || runSignal.aborted) {
|
|
1103
|
+
releasePermit();
|
|
1104
|
+
progress.status = "aborted";
|
|
1105
|
+
onSettled?.(true);
|
|
1106
|
+
throw new Error("Aborted before execution");
|
|
1107
|
+
}
|
|
1108
|
+
try {
|
|
1109
|
+
markRunning();
|
|
1110
|
+
progress.status = "running";
|
|
1111
|
+
await reportProgress(
|
|
1112
|
+
`Running background task ${agentId}...`,
|
|
1113
|
+
buildDetails() as unknown as Record<string, unknown>,
|
|
1114
|
+
);
|
|
1115
|
+
const forwardSyncProgress: AgentToolUpdateCallback<TaskToolDetails> = async update => {
|
|
1116
|
+
const nextProgress = update.details?.progress?.[0];
|
|
1117
|
+
if (nextProgress) {
|
|
1118
|
+
// The job body owns status and identity (id/index/agent);
|
|
1119
|
+
// copy only the live metrics the subagent streams so the
|
|
1120
|
+
// polling row reflects the resolved model, reasoning level,
|
|
1121
|
+
// and running counters without reverting the "running"
|
|
1122
|
+
// status back to the subagent's initial "pending" snapshot.
|
|
1123
|
+
progress.modelRole = nextProgress.modelRole ?? progress.modelRole;
|
|
1124
|
+
progress.resolvedModel = nextProgress.resolvedModel;
|
|
1125
|
+
progress.resolvedModelIsFallback =
|
|
1126
|
+
nextProgress.resolvedModelIsFallback ?? progress.resolvedModelIsFallback;
|
|
1127
|
+
progress.tokens = nextProgress.tokens;
|
|
1128
|
+
progress.requests = nextProgress.requests;
|
|
1129
|
+
progress.contextTokens = nextProgress.contextTokens;
|
|
1130
|
+
progress.contextWindow = nextProgress.contextWindow;
|
|
1131
|
+
progress.cost = nextProgress.cost;
|
|
1132
|
+
progress.toolCount = nextProgress.toolCount;
|
|
1133
|
+
progress.currentTool = nextProgress.currentTool;
|
|
1134
|
+
progress.lastIntent = nextProgress.lastIntent;
|
|
1135
|
+
progress.recentTools = nextProgress.recentTools.slice();
|
|
1136
|
+
progress.recentOutput = nextProgress.recentOutput.slice();
|
|
1137
|
+
progress.retryState = nextProgress.retryState;
|
|
1138
|
+
progress.retryFailure = nextProgress.retryFailure;
|
|
1139
|
+
}
|
|
1140
|
+
const updateText =
|
|
1141
|
+
update.content.find(part => part.type === "text")?.text ?? `Running background task ${agentId}...`;
|
|
1142
|
+
await reportProgress(updateText, buildDetails() as unknown as Record<string, unknown>);
|
|
1143
|
+
};
|
|
1144
|
+
const result = await this.#executeSync(
|
|
1145
|
+
toolCallId,
|
|
1146
|
+
spawnParams,
|
|
1147
|
+
runSignal,
|
|
1148
|
+
forwardSyncProgress,
|
|
1149
|
+
agentId,
|
|
1150
|
+
progress.index,
|
|
1151
|
+
true,
|
|
1152
|
+
{ invokedAt: startedAt, acquiredAt },
|
|
1153
|
+
);
|
|
1154
|
+
const finalText = result.content.find(part => part.type === "text")?.text ?? "(no output)";
|
|
1155
|
+
const singleResult = result.details?.results[0];
|
|
1156
|
+
// A missing result means the sync path failed at the tool level
|
|
1157
|
+
// (results: []) — treat it as a failure, not success.
|
|
1158
|
+
const resultFailed = !singleResult || (singleResult.aborted ?? false) || singleResult.exitCode !== 0;
|
|
1159
|
+
progress.status = singleResult?.aborted ? "aborted" : resultFailed ? "failed" : "completed";
|
|
1160
|
+
progress.durationMs = singleResult?.durationMs ?? Math.max(0, Date.now() - startedAt);
|
|
1161
|
+
progress.tokens = singleResult?.tokens ?? 0;
|
|
1162
|
+
progress.requests = singleResult?.requests ?? 0;
|
|
1163
|
+
progress.contextTokens = singleResult?.contextTokens;
|
|
1164
|
+
progress.contextWindow = singleResult?.contextWindow;
|
|
1165
|
+
progress.cost = singleResult?.usage?.cost.total ?? 0;
|
|
1166
|
+
progress.extractedToolData = singleResult?.extractedToolData;
|
|
1167
|
+
progress.retryFailure = singleResult?.retryFailure;
|
|
1168
|
+
progress.retryState = undefined;
|
|
1169
|
+
progress.modelRole = singleResult?.modelRole ?? progress.modelRole;
|
|
1170
|
+
if (singleResult?.resolvedModel) {
|
|
1171
|
+
progress.resolvedModel = singleResult.resolvedModel;
|
|
1172
|
+
progress.resolvedModelIsFallback =
|
|
1173
|
+
singleResult.resolvedModelIsFallback ?? progress.resolvedModelIsFallback;
|
|
1174
|
+
} else {
|
|
1175
|
+
delete progress.resolvedModel;
|
|
1176
|
+
delete progress.resolvedModelIsFallback;
|
|
1177
|
+
}
|
|
1178
|
+
onSettled?.(resultFailed);
|
|
1179
|
+
const statusText = resultFailed
|
|
1180
|
+
? `Background task ${agentId} failed.`
|
|
1181
|
+
: `Background task ${agentId} complete.`;
|
|
1182
|
+
await reportProgress(statusText, buildDetails() as unknown as Record<string, unknown>);
|
|
1183
|
+
const deliveryText = `${finalText}${await buildFollowUpHint(singleResult?.aborted === true)}`;
|
|
1184
|
+
if (resultFailed) {
|
|
1185
|
+
// Mark the job itself failed; the failed agent stays interrogable.
|
|
1186
|
+
throw new TaskJobError(deliveryText);
|
|
1187
|
+
}
|
|
1188
|
+
return deliveryText;
|
|
1189
|
+
} catch (error) {
|
|
1190
|
+
if (error instanceof TaskJobError) {
|
|
1191
|
+
throw error;
|
|
1192
|
+
}
|
|
1193
|
+
progress.status = "failed";
|
|
1194
|
+
progress.durationMs = Math.max(0, Date.now() - startedAt);
|
|
1195
|
+
onSettled?.(true);
|
|
1196
|
+
const statusText = `Background task ${agentId} failed.`;
|
|
1197
|
+
await reportProgress(statusText, buildDetails() as unknown as Record<string, unknown>);
|
|
1198
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1199
|
+
const hint = AgentRegistry.global().get(agentId) ? await buildFollowUpHint(false) : "";
|
|
1200
|
+
throw new TaskJobError(`${message}${hint}`);
|
|
1201
|
+
} finally {
|
|
1202
|
+
releasePermit();
|
|
1203
|
+
}
|
|
1204
|
+
},
|
|
1205
|
+
{
|
|
1206
|
+
id: agentId,
|
|
1207
|
+
agentId,
|
|
1208
|
+
queued: true,
|
|
1209
|
+
ownerId: this.session.getAgentId?.() ?? undefined,
|
|
1210
|
+
onProgress: text => {
|
|
1211
|
+
onUpdate?.({ content: [{ type: "text", text }], details: buildDetails() });
|
|
1212
|
+
},
|
|
1213
|
+
},
|
|
1214
|
+
);
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
/**
|
|
1218
|
+
* Sync fan-out (async unavailable, or every item's agent type is
|
|
1219
|
+
* `blocking: true`): run every spawn to completion inline and merge the
|
|
1220
|
+
* per-spawn payloads into a single tool result. The session-scoped
|
|
1221
|
+
* semaphore still bounds concurrency across parallel task calls.
|
|
1222
|
+
*/
|
|
1223
|
+
async #executeSyncFanout(
|
|
1224
|
+
toolCallId: string,
|
|
1225
|
+
params: TaskParams,
|
|
1226
|
+
spawns: SyncSpawnRef[],
|
|
1227
|
+
defaultAgent: string,
|
|
1228
|
+
signal?: AbortSignal,
|
|
1229
|
+
onUpdate?: AgentToolUpdateCallback<TaskToolDetails>,
|
|
1230
|
+
): Promise<AgentToolResult<TaskToolDetails>> {
|
|
1231
|
+
if (spawns.length === 1) {
|
|
1232
|
+
const spawn = spawns[0]!;
|
|
1233
|
+
const semaphore = this.#getSpawnSemaphore();
|
|
1234
|
+
const invokedAt = Date.now();
|
|
1235
|
+
await semaphore.acquire(signal);
|
|
1236
|
+
const acquiredAt = Date.now();
|
|
1237
|
+
try {
|
|
1238
|
+
return await this.#executeSync(
|
|
1239
|
+
toolCallId,
|
|
1240
|
+
spawnParamsFor(params, spawn.item, defaultAgent),
|
|
1241
|
+
signal,
|
|
1242
|
+
onUpdate,
|
|
1243
|
+
spawn.preAllocatedId,
|
|
1244
|
+
spawn.index,
|
|
1245
|
+
false,
|
|
1246
|
+
{ invokedAt, acquiredAt },
|
|
1247
|
+
);
|
|
1248
|
+
} finally {
|
|
1249
|
+
this.#releaseSpawnSemaphore();
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
const startTime = Date.now();
|
|
1254
|
+
const latestProgress = new Map<number, AgentProgress>();
|
|
1255
|
+
const emitCombined = () => {
|
|
1256
|
+
onUpdate?.({
|
|
1257
|
+
content: [{ type: "text", text: `Running ${spawns.length} agents...` }],
|
|
1258
|
+
details: {
|
|
1259
|
+
projectAgentsDir: null,
|
|
1260
|
+
results: [],
|
|
1261
|
+
totalDurationMs: Date.now() - startTime,
|
|
1262
|
+
progress: Array.from(latestProgress.entries())
|
|
1263
|
+
.sort((a, b) => a[0] - b[0])
|
|
1264
|
+
.map(([, progress]) => progress),
|
|
1265
|
+
},
|
|
1266
|
+
});
|
|
1267
|
+
};
|
|
1268
|
+
|
|
1269
|
+
const payloads = await this.#runSyncSpawns({
|
|
1270
|
+
toolCallId,
|
|
1271
|
+
params,
|
|
1272
|
+
defaultAgent,
|
|
1273
|
+
signal,
|
|
1274
|
+
spawns,
|
|
1275
|
+
onItemProgress: onUpdate
|
|
1276
|
+
? (index, progress) => {
|
|
1277
|
+
latestProgress.set(index, { ...progress, index });
|
|
1278
|
+
emitCombined();
|
|
1279
|
+
}
|
|
1280
|
+
: undefined,
|
|
1281
|
+
});
|
|
1282
|
+
|
|
1283
|
+
const merged = mergeSyncPayloads(spawns, payloads);
|
|
1284
|
+
return {
|
|
1285
|
+
content: [{ type: "text", text: merged.contentParts.join("\n\n") }],
|
|
1286
|
+
details: {
|
|
1287
|
+
projectAgentsDir: merged.projectAgentsDir,
|
|
1288
|
+
results: merged.results,
|
|
1289
|
+
totalDurationMs: Date.now() - startTime,
|
|
1290
|
+
usage: merged.usage,
|
|
1291
|
+
outputPaths: merged.outputPaths,
|
|
1292
|
+
},
|
|
1293
|
+
};
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
/**
|
|
1297
|
+
* Run a set of spawns to completion inline, bounded by the session spawn
|
|
1298
|
+
* semaphore. `preAllocatedId` reuses an id claimed up front (mixed calls);
|
|
1299
|
+
* `index` is each item's position in the original call so progress rows and
|
|
1300
|
+
* merged results keep stable ordering. Per-item progress snapshots flow
|
|
1301
|
+
* through `onItemProgress`. Returns per-spawn payloads in input order;
|
|
1302
|
+
* `undefined` marks a spawn cancelled before it started.
|
|
1303
|
+
*/
|
|
1304
|
+
async #runSyncSpawns(args: {
|
|
1305
|
+
toolCallId: string;
|
|
1306
|
+
params: TaskParams;
|
|
1307
|
+
defaultAgent: string;
|
|
1308
|
+
spawns: SyncSpawnRef[];
|
|
1309
|
+
signal?: AbortSignal;
|
|
1310
|
+
onItemProgress?: (index: number, progress: AgentProgress) => void;
|
|
1311
|
+
}): Promise<(AgentToolResult<TaskToolDetails> | undefined)[]> {
|
|
1312
|
+
const { toolCallId, params, defaultAgent, spawns, signal, onItemProgress } = args;
|
|
1313
|
+
const semaphore = this.#getSpawnSemaphore();
|
|
1314
|
+
const { results } = await mapWithConcurrencyLimitAllSettled(
|
|
1315
|
+
spawns,
|
|
1316
|
+
spawns.length,
|
|
1317
|
+
async (spawn, _position, workerSignal) => {
|
|
1318
|
+
const invokedAt = Date.now();
|
|
1319
|
+
let semaphoreHeld = false;
|
|
1320
|
+
try {
|
|
1321
|
+
await semaphore.acquire(workerSignal);
|
|
1322
|
+
semaphoreHeld = true;
|
|
1323
|
+
} catch (error) {
|
|
1324
|
+
if (workerSignal.aborted) return undefined;
|
|
1325
|
+
throw error;
|
|
1326
|
+
}
|
|
1327
|
+
const acquiredAt = Date.now();
|
|
1328
|
+
try {
|
|
1329
|
+
const itemOnUpdate: AgentToolUpdateCallback<TaskToolDetails> | undefined = onItemProgress
|
|
1330
|
+
? update => {
|
|
1331
|
+
const progress = update.details?.progress?.[0];
|
|
1332
|
+
if (progress) onItemProgress(spawn.index, progress);
|
|
1333
|
+
}
|
|
1334
|
+
: undefined;
|
|
1335
|
+
return await this.#executeSync(
|
|
1336
|
+
toolCallId,
|
|
1337
|
+
spawnParamsFor(params, spawn.item, defaultAgent),
|
|
1338
|
+
workerSignal,
|
|
1339
|
+
itemOnUpdate,
|
|
1340
|
+
spawn.preAllocatedId,
|
|
1341
|
+
spawn.index,
|
|
1342
|
+
false,
|
|
1343
|
+
{ invokedAt, acquiredAt },
|
|
1344
|
+
);
|
|
1345
|
+
} finally {
|
|
1346
|
+
if (semaphoreHeld) this.#releaseSpawnSemaphore();
|
|
1347
|
+
}
|
|
1348
|
+
},
|
|
1349
|
+
signal,
|
|
1350
|
+
);
|
|
1351
|
+
return results.map((settled, position) => {
|
|
1352
|
+
if (!settled) return undefined;
|
|
1353
|
+
if (settled.status === "fulfilled") return settled.value;
|
|
1354
|
+
const message = settled.reason instanceof Error ? settled.reason.message : String(settled.reason);
|
|
1355
|
+
const item = spawns[position].item;
|
|
1356
|
+
return {
|
|
1357
|
+
content: [
|
|
1358
|
+
{
|
|
1359
|
+
type: "text",
|
|
1360
|
+
text: `Task ${item.name?.trim() || `#${spawns[position].index + 1}`} failed: ${message}`,
|
|
1361
|
+
},
|
|
1362
|
+
],
|
|
1363
|
+
details: { projectAgentsDir: null, results: [], totalDurationMs: 0 },
|
|
1364
|
+
};
|
|
1365
|
+
});
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
/**
|
|
1369
|
+
* Synchronous execution of one spawn. Used as the body of every
|
|
1370
|
+
* async job and directly by the sync fallback (no job manager / blocking
|
|
1371
|
+
* agent) and by in-process callers that need the result inline (e.g. the
|
|
1372
|
+
* commit flow's analyze_files tool).
|
|
1373
|
+
*/
|
|
1374
|
+
async #executeSync(
|
|
1375
|
+
toolCallId: string,
|
|
1376
|
+
params: TaskParams,
|
|
1377
|
+
signal?: AbortSignal,
|
|
1378
|
+
onUpdate?: AgentToolUpdateCallback<TaskToolDetails>,
|
|
1379
|
+
preAllocatedId?: string,
|
|
1380
|
+
spawnIndex = 0,
|
|
1381
|
+
detached = false,
|
|
1382
|
+
launchTiming?: { invokedAt: number; acquiredAt: number },
|
|
1383
|
+
): Promise<AgentToolResult<TaskToolDetails>> {
|
|
1384
|
+
return this.#runSpawn(toolCallId, params, signal, onUpdate, preAllocatedId, spawnIndex, detached, launchTiming);
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
/** Spawn a fresh subagent and run it to completion. */
|
|
1388
|
+
async #runSpawn(
|
|
1389
|
+
toolCallId: string,
|
|
1390
|
+
params: TaskParams,
|
|
1391
|
+
signal?: AbortSignal,
|
|
1392
|
+
onUpdate?: AgentToolUpdateCallback<TaskToolDetails>,
|
|
1393
|
+
preAllocatedId?: string,
|
|
1394
|
+
spawnIndex = 0,
|
|
1395
|
+
detached = false,
|
|
1396
|
+
launchTiming?: { invokedAt: number; acquiredAt: number },
|
|
1397
|
+
): Promise<AgentToolResult<TaskToolDetails>> {
|
|
1398
|
+
const startTime = Date.now();
|
|
1399
|
+
const assignment = (params.task ?? "").trim();
|
|
1400
|
+
const context = this.#isBatchEnabled() ? params.context?.trim() || undefined : undefined;
|
|
1401
|
+
let latestProgress: AgentProgress | undefined;
|
|
1402
|
+
try {
|
|
1403
|
+
const execution = await runStructuredSubagent({
|
|
1404
|
+
session: this.session,
|
|
1405
|
+
invocationKind: "task",
|
|
1406
|
+
assignment,
|
|
1407
|
+
context,
|
|
1408
|
+
agent: params.agent,
|
|
1409
|
+
...(Object.hasOwn(params, "outputSchema") ? { outputSchema: params.outputSchema } : {}),
|
|
1410
|
+
...(Object.hasOwn(params, "schemaMode") ? { schemaMode: params.schemaMode } : {}),
|
|
1411
|
+
...(params.effort !== undefined ? { effort: params.effort } : {}),
|
|
1412
|
+
identity: { id: preAllocatedId, label: params.name },
|
|
1413
|
+
index: spawnIndex,
|
|
1414
|
+
parentToolCallId: toolCallId,
|
|
1415
|
+
detached,
|
|
1416
|
+
invokedAt: launchTiming?.invokedAt,
|
|
1417
|
+
acquiredAt: launchTiming?.acquiredAt,
|
|
1418
|
+
...("isolated" in params ? { isolation: { requested: params.isolated } } : {}),
|
|
1419
|
+
blockedAgent: this.#blockedAgent,
|
|
1420
|
+
enableLsp: (this.session.enableLsp ?? true) && this.session.settings.get("task.enableLsp"),
|
|
1421
|
+
enableIrc: isIrcEnabled(this.session.settings, this.session.taskDepth ?? 0),
|
|
1422
|
+
maxRuntimeMs: this.session.settings.get("task.maxRuntimeMs"),
|
|
1423
|
+
signal,
|
|
1424
|
+
onProgress: progress => {
|
|
1425
|
+
latestProgress = { ...progress, recentTools: progress.recentTools.slice() };
|
|
1426
|
+
onUpdate?.({
|
|
1427
|
+
content: [{ type: "text", text: `Running agent ${progress.id}...` }],
|
|
1428
|
+
details: {
|
|
1429
|
+
projectAgentsDir: null,
|
|
1430
|
+
results: [],
|
|
1431
|
+
totalDurationMs: Date.now() - startTime,
|
|
1432
|
+
progress: [latestProgress],
|
|
1433
|
+
},
|
|
1434
|
+
});
|
|
1435
|
+
},
|
|
1436
|
+
});
|
|
1437
|
+
return this.#buildResultPayload(
|
|
1438
|
+
execution.result,
|
|
1439
|
+
execution.policy.discovery.projectAgentsDir,
|
|
1440
|
+
Date.now() - startTime,
|
|
1441
|
+
execution.mergeSummary,
|
|
1442
|
+
);
|
|
1443
|
+
} catch (error) {
|
|
1444
|
+
const message = error instanceof StructuredSubagentError ? error.message : String(error);
|
|
1445
|
+
return {
|
|
1446
|
+
content: [{ type: "text", text: `Task execution failed: ${message}` }],
|
|
1447
|
+
details: {
|
|
1448
|
+
projectAgentsDir: null,
|
|
1449
|
+
results: [],
|
|
1450
|
+
totalDurationMs: Date.now() - startTime,
|
|
1451
|
+
...(latestProgress ? { progress: [latestProgress] } : {}),
|
|
1452
|
+
},
|
|
1453
|
+
};
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
/** Build the tool result (summary text + details) for a settled run. */
|
|
1458
|
+
#buildResultPayload(
|
|
1459
|
+
result: SingleResult,
|
|
1460
|
+
projectAgentsDir: string | null,
|
|
1461
|
+
totalDurationMs: number,
|
|
1462
|
+
mergeSummary: string,
|
|
1463
|
+
): AgentToolResult<TaskToolDetails> {
|
|
1464
|
+
const status = result.aborted
|
|
1465
|
+
? "cancelled"
|
|
1466
|
+
: result.exitCode === 0 && result.error
|
|
1467
|
+
? "merge failed"
|
|
1468
|
+
: result.exitCode === 0
|
|
1469
|
+
? "completed"
|
|
1470
|
+
: `failed (exit ${result.exitCode})`;
|
|
1471
|
+
const output = formatResultOutputFallback(result);
|
|
1472
|
+
const outputCharCount = result.outputMeta?.charCount ?? output.length;
|
|
1473
|
+
const fullOutputThreshold = 5000;
|
|
1474
|
+
let preview = output;
|
|
1475
|
+
let truncated = false;
|
|
1476
|
+
if (outputCharCount > fullOutputThreshold) {
|
|
1477
|
+
const slice = output.slice(0, fullOutputThreshold);
|
|
1478
|
+
const lastNewline = slice.lastIndexOf("\n");
|
|
1479
|
+
preview = lastNewline >= 0 ? slice.slice(0, lastNewline) : slice;
|
|
1480
|
+
truncated = true;
|
|
1481
|
+
}
|
|
1482
|
+
// A stopped-but-adopted agent (soft-budget stop) stays messageable; tell
|
|
1483
|
+
// the parent so it can resume via irc instead of redoing the work.
|
|
1484
|
+
const refStatus = AgentRegistry.global().get(result.id)?.status;
|
|
1485
|
+
const resumable = result.aborted && (refStatus === "idle" || refStatus === "parked");
|
|
1486
|
+
const summary = prompt.render(taskSummaryTemplate, {
|
|
1487
|
+
agentName: result.agent,
|
|
1488
|
+
id: result.id,
|
|
1489
|
+
status,
|
|
1490
|
+
duration: formatDuration(totalDurationMs),
|
|
1491
|
+
abortReason: result.aborted ? result.abortReason : undefined,
|
|
1492
|
+
resumable,
|
|
1493
|
+
preview,
|
|
1494
|
+
truncated,
|
|
1495
|
+
meta: result.outputMeta
|
|
1496
|
+
? {
|
|
1497
|
+
lineCount: result.outputMeta.lineCount,
|
|
1498
|
+
charSize: formatBytes(result.outputMeta.charCount),
|
|
1499
|
+
}
|
|
1500
|
+
: undefined,
|
|
1501
|
+
mergeSummary,
|
|
1502
|
+
});
|
|
1503
|
+
|
|
1504
|
+
return {
|
|
1505
|
+
content: [{ type: "text", text: summary }],
|
|
1506
|
+
details: {
|
|
1507
|
+
projectAgentsDir,
|
|
1508
|
+
results: [result],
|
|
1509
|
+
totalDurationMs,
|
|
1510
|
+
usage: result.usage,
|
|
1511
|
+
outputPaths: result.outputPath ? [result.outputPath] : undefined,
|
|
1512
|
+
},
|
|
1513
|
+
};
|
|
1514
|
+
}
|
|
1515
|
+
}
|