@selesai/code 0.2.1 → 0.3.1
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/dist/config.d.ts +4 -15
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +5 -45
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +1 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +8 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/diagnostics.d.ts +1 -0
- package/dist/core/diagnostics.d.ts.map +1 -1
- package/dist/core/diagnostics.js.map +1 -1
- package/dist/core/model-registry.d.ts +4 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +101 -51
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/package-manager.d.ts +10 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +93 -8
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/package-manager.test.d.ts +2 -0
- package/dist/core/package-manager.test.d.ts.map +1 -0
- package/dist/core/package-manager.test.js +20 -0
- package/dist/core/package-manager.test.js.map +1 -0
- package/dist/core/resource-loader.d.ts +3 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +10 -0
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/defaults/models.json +64 -113
- package/dist/extensions/caveman/caveman-instructions.cjs +39 -0
- package/dist/extensions/caveman/index.js +116 -0
- package/dist/extensions/caveman/package.json +8 -0
- package/dist/extensions/caveman/test/extension.test.js +185 -0
- package/dist/extensions/caveman/test/helpers.test.js +67 -0
- package/dist/extensions/copy-turn.ts +2 -2
- package/dist/extensions/pi-intercom/broker/broker.ts +2 -3
- package/dist/extensions/pi-intercom/broker/paths.ts +10 -5
- package/dist/extensions/pi-intercom/broker/spawn.ts +2 -3
- package/dist/extensions/pi-intercom/config.ts +2 -2
- package/dist/extensions/pi-intercom/index.ts +2 -2
- package/dist/extensions/pi-intercom/package.json +2 -2
- package/dist/extensions/pi-intercom/ui/compose.ts +3 -3
- package/dist/extensions/pi-intercom/ui/inline-message.ts +3 -3
- package/dist/extensions/pi-intercom/ui/session-list.ts +3 -3
- package/dist/extensions/pi-powerline-footer/bash-mode/editor.ts +2 -2
- package/dist/extensions/pi-powerline-footer/bash-mode/history.ts +2 -1
- package/dist/extensions/pi-powerline-footer/index.ts +40 -47
- package/dist/extensions/pi-powerline-footer/package.json +2 -2
- package/dist/extensions/pi-powerline-footer/tests/bash-mode.test.ts +10 -10
- package/dist/extensions/pi-powerline-footer/tests/jump-shortcuts.test.ts +1 -1
- package/dist/extensions/pi-powerline-footer/tests/working-vibes.test.ts +2 -2
- package/dist/extensions/pi-powerline-footer/theme.ts +6 -6
- package/dist/extensions/pi-powerline-footer/tps.ts +1 -1
- package/dist/extensions/pi-powerline-footer/types.ts +7 -7
- package/dist/extensions/pi-powerline-footer/welcome.ts +23 -16
- package/dist/extensions/pi-powerline-footer/working-vibes.ts +52 -59
- package/dist/extensions/pi-rewind-hook/index.ts +1 -1
- package/dist/extensions/pi-rewind-hook/package.json +1 -1
- package/dist/extensions/pi-subagents/README.md +224 -52
- package/dist/extensions/pi-subagents/agents/architect.md +188 -0
- package/dist/extensions/pi-subagents/agents/builder.md +120 -0
- package/dist/extensions/pi-subagents/agents/commentator.md +131 -0
- package/dist/extensions/pi-subagents/agents/explorer.md +51 -0
- package/dist/extensions/pi-subagents/agents/recapper.md +21 -0
- package/dist/extensions/pi-subagents/install.mjs +93 -0
- package/dist/extensions/pi-subagents/package.json +4 -5
- package/dist/extensions/pi-subagents/prompts/parallel-context-build.md +1 -1
- package/dist/extensions/pi-subagents/prompts/parallel-handoff-plan.md +1 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +76 -13
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +179 -2
- package/dist/extensions/pi-subagents/src/agents/agent-memory.ts +254 -0
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +11 -0
- package/dist/extensions/pi-subagents/src/agents/agents.ts +193 -19
- package/dist/extensions/pi-subagents/src/agents/chain-serializer.ts +27 -2
- package/dist/extensions/pi-subagents/src/extension/config.ts +27 -4
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +1 -7
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +3 -2
- package/dist/extensions/pi-subagents/src/extension/index.ts +73 -71
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +369 -0
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +54 -10
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +200 -0
- package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +21 -253
- package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +519 -0
- package/dist/extensions/pi-subagents/src/profiles/profiles.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +195 -105
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +88 -2
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +67 -10
- package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +34 -4
- package/dist/extensions/pi-subagents/src/runs/background/completion-batcher.ts +166 -0
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +156 -1
- package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +515 -0
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +161 -44
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +1 -2
- package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +3 -2
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +167 -6
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +514 -0
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +28 -1
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +873 -204
- package/dist/extensions/pi-subagents/src/runs/background/wait.ts +353 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +123 -27
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +174 -70
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +569 -81
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +45 -22
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +3 -1
- package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +172 -21
- package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +128 -0
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +89 -0
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +50 -1
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +35 -4
- package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +63 -45
- package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +125 -5
- package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +74 -0
- package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +52 -0
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +28 -5
- package/dist/extensions/pi-subagents/src/shared/artifacts.ts +16 -1
- package/dist/extensions/pi-subagents/src/shared/atomic-json.ts +15 -2
- package/dist/extensions/pi-subagents/src/shared/child-transcript.ts +212 -0
- package/dist/extensions/pi-subagents/src/shared/fork-context.ts +133 -22
- package/dist/extensions/pi-subagents/src/shared/settings.ts +3 -1
- package/dist/extensions/pi-subagents/src/shared/types.ts +197 -4
- package/dist/extensions/pi-subagents/src/shared/utils.ts +108 -17
- package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +330 -0
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +135 -4
- package/dist/extensions/pi-subagents/src/tui/render.ts +32 -12
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +94 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +2772 -0
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +1107 -0
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +463 -0
- package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +274 -0
- package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +1535 -0
- package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +242 -0
- package/dist/extensions/pi-subagents/test/integration/doctor-executor.test.ts +128 -0
- package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +252 -0
- package/dist/extensions/pi-subagents/test/integration/foreground-result-size.test.ts +188 -0
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +1306 -0
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +1033 -0
- package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +397 -0
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +583 -0
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +691 -0
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +892 -0
- package/dist/extensions/pi-subagents/test/integration/session-tokens.test.ts +62 -0
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1824 -0
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1284 -0
- package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +127 -0
- package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +299 -0
- package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +37 -0
- package/dist/extensions/pi-subagents/test/support/helpers.ts +189 -0
- package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +335 -0
- package/dist/extensions/pi-subagents/test/support/mock-pi.ts +129 -0
- package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +184 -0
- package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +285 -0
- package/dist/extensions/pi-subagents/test/support/register-loader.mjs +15 -0
- package/dist/extensions/pi-subagents/test/support/ts-loader.mjs +108 -0
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +421 -0
- package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +213 -0
- package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +343 -0
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +1199 -0
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +556 -0
- package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +420 -0
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +579 -0
- package/dist/extensions/pi-subagents/test/unit/agent-scope.test.ts +20 -0
- package/dist/extensions/pi-subagents/test/unit/agent-selection.test.ts +88 -0
- package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +24 -0
- package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +86 -0
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +221 -0
- package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +98 -0
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +285 -0
- package/dist/extensions/pi-subagents/test/unit/atomic-json.test.ts +112 -0
- package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +206 -0
- package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +159 -0
- package/dist/extensions/pi-subagents/test/unit/chain-serializer.test.ts +229 -0
- package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +225 -0
- package/dist/extensions/pi-subagents/test/unit/close-grace-timer.test.ts +101 -0
- package/dist/extensions/pi-subagents/test/unit/completion-batcher.test.ts +228 -0
- package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +36 -0
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +152 -0
- package/dist/extensions/pi-subagents/test/unit/config-dir-runtime.test.ts +72 -0
- package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +327 -0
- package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +161 -0
- package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +159 -0
- package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +217 -0
- package/dist/extensions/pi-subagents/test/unit/extra-agent-dirs.test.ts +88 -0
- package/dist/extensions/pi-subagents/test/unit/file-coalescer.test.ts +68 -0
- package/dist/extensions/pi-subagents/test/unit/foreground-tool-call-compaction.test.ts +78 -0
- package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +415 -0
- package/dist/extensions/pi-subagents/test/unit/get-final-output.test.ts +126 -0
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +271 -0
- package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +173 -0
- package/dist/extensions/pi-subagents/test/unit/jsonl-writer.test.ts +119 -0
- package/dist/extensions/pi-subagents/test/unit/live-async-resume.test.ts +170 -0
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +346 -0
- package/dist/extensions/pi-subagents/test/unit/model-info.test.ts +62 -0
- package/dist/extensions/pi-subagents/test/unit/model-scope-settings.test.ts +87 -0
- package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +145 -0
- package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +162 -0
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +470 -0
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +329 -0
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +319 -0
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +70 -0
- package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +247 -0
- package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +113 -0
- package/dist/extensions/pi-subagents/test/unit/path-resolution.test.ts +94 -0
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +803 -0
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +209 -0
- package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +238 -0
- package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +118 -0
- package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +299 -0
- package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +408 -0
- package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +134 -0
- package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +257 -0
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +209 -0
- package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +226 -0
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +294 -0
- package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +147 -0
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +997 -0
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +478 -0
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +562 -0
- package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +213 -0
- package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +438 -0
- package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +54 -0
- package/dist/extensions/pi-subagents/test/unit/slash-chain-groups.test.ts +464 -0
- package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +255 -0
- package/dist/extensions/pi-subagents/test/unit/status-format.test.ts +19 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +245 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +517 -0
- package/dist/extensions/pi-subagents/test/unit/temp-paths.test.ts +72 -0
- package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +52 -0
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +237 -0
- package/dist/extensions/pi-subagents/test/unit/total-cost.test.ts +60 -0
- package/dist/extensions/pi-subagents/test/unit/ts-loader.test.ts +33 -0
- package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +202 -0
- package/dist/extensions/pi-subagents/test/unit/types-fork-preamble.test.ts +23 -0
- package/dist/extensions/pi-subagents/test/unit/wait.test.ts +398 -0
- package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +88 -0
- package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +26 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-graph.test.ts +134 -0
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +479 -0
- package/dist/extensions/pi-web-agent/package.json +2 -2
- package/dist/extensions/pi-web-agent/src/backends/settings-reader.ts +2 -2
- package/dist/extensions/pi-web-agent/src/changelog-notice.ts +5 -2
- package/dist/extensions/pi-web-agent/src/commands/web-agent-config.ts +1 -1
- package/dist/extensions/pi-web-agent/src/extension.ts +1 -1
- package/dist/extensions/pi-web-agent/src/presentation/config-store.ts +6 -4
- package/dist/extensions/question/helpers.ts +3 -3
- package/dist/extensions/question/index.ts +2 -2
- package/dist/extensions/question/navigation.ts +2 -2
- package/dist/extensions/question/package.json +2 -2
- package/dist/extensions/question/question-list.ts +2 -2
- package/dist/extensions/question/tests/question-list.test.ts +2 -2
- package/dist/extensions/question/tui-adapter.ts +2 -2
- package/dist/extensions/question/types.ts +2 -2
- package/dist/extensions/question/ui-protocol.ts +2 -2
- package/dist/extensions/rtk.ts +2 -2
- package/dist/extensions/tokenin-onboarding.ts +2 -2
- package/dist/extensions/undo.ts +1 -1
- package/dist/extensions/web-agent-onboarding.ts +3 -3
- package/dist/extensions/workflow/adapter.ts +16 -8
- package/dist/extensions/workflow/extension.ts +1 -1
- package/dist/extensions/workflow/package.json +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +4 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +2 -0
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +19 -5
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/skills/caveman/SKILL.md +49 -0
- package/dist/skills/handoff-text/SKILL.md +13 -0
- package/dist/utils/thinking-tags.d.ts +7 -0
- package/dist/utils/thinking-tags.d.ts.map +1 -0
- package/dist/utils/thinking-tags.js +63 -0
- package/dist/utils/thinking-tags.js.map +1 -0
- package/docs/docs.json +4 -0
- package/docs/extensions.md +2 -0
- package/docs/settings.md +15 -0
- package/docs/shared-host-extensions.md +109 -0
- package/package.json +2 -2
|
@@ -14,11 +14,12 @@ import { applyThinkingSuffix } from "../shared/pi-args.ts";
|
|
|
14
14
|
import { injectOutputPathSystemPrompt, injectSingleOutputInstruction, normalizeSingleOutputOverride, resolveSingleOutputPath, validateFileOnlyOutputMode } from "../shared/single-output.ts";
|
|
15
15
|
import { buildChainInstructions, isDynamicParallelStep, isParallelStep, resolveStepBehavior, suppressProgressForReadOnlyTask, writeInitialProgressFile, type ChainStep, type ResolvedStepBehavior, type SequentialStep, type StepOverrides } from "../../shared/settings.ts";
|
|
16
16
|
import type { RunnerStep } from "../shared/parallel-utils.ts";
|
|
17
|
-
import {
|
|
17
|
+
import { resolveSelesaiPackageRoot } from "../shared/pi-spawn.ts";
|
|
18
18
|
import { buildSkillInjection, normalizeSkillInput, resolveSkillsWithFallback } from "../../agents/skills.ts";
|
|
19
|
-
import {
|
|
20
|
-
import { resolveChildCwd } from "../../shared/utils.ts";
|
|
19
|
+
import { buildAgentMemoryInjection } from "../../agents/agent-memory.ts";
|
|
20
|
+
import { SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV, resolveChildCwd } from "../../shared/utils.ts";
|
|
21
21
|
import { buildModelCandidates, resolveModelCandidate, resolveSubagentModelOverride, type AvailableModelInfo, type ParentModel } from "../shared/model-fallback.ts";
|
|
22
|
+
import type { ModelScopeConfig } from "../shared/model-scope.ts";
|
|
22
23
|
import { resolveEffectiveThinking } from "../../shared/model-info.ts";
|
|
23
24
|
import { resolveExpectedWorktreeAgentCwd } from "../shared/worktree.ts";
|
|
24
25
|
import { buildWorkflowGraphSnapshot } from "../shared/workflow-graph.ts";
|
|
@@ -32,19 +33,24 @@ import {
|
|
|
32
33
|
type MaxOutputConfig,
|
|
33
34
|
type NestedRouteInfo,
|
|
34
35
|
type ResolvedControlConfig,
|
|
36
|
+
type ResolvedTurnBudget,
|
|
37
|
+
type ResolvedToolBudget,
|
|
35
38
|
type SubagentRunMode,
|
|
36
39
|
ASYNC_DIR,
|
|
37
40
|
RESULTS_DIR,
|
|
38
41
|
SUBAGENT_ASYNC_STARTED_EVENT,
|
|
42
|
+
SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
|
|
39
43
|
TEMP_ROOT_DIR,
|
|
40
44
|
getAsyncConfigPath,
|
|
41
45
|
resolveChildMaxSubagentDepth,
|
|
42
46
|
} from "../../shared/types.ts";
|
|
43
47
|
import { nestedResultsPath, resolveInheritedNestedRouteFromEnv, resolveNestedParentAddressFromEnv, writeNestedEvent } from "../shared/nested-events.ts";
|
|
48
|
+
import { initialTurnBudgetState } from "../shared/turn-budget.ts";
|
|
49
|
+
import { validateToolBudgetConfig } from "../shared/tool-budget.ts";
|
|
44
50
|
import type { ImportedAsyncRoot } from "./chain-root-attachment.ts";
|
|
45
51
|
|
|
46
52
|
const require = createRequire(import.meta.url);
|
|
47
|
-
const
|
|
53
|
+
const selesaiPackageRoot = resolveSelesaiPackageRoot();
|
|
48
54
|
|
|
49
55
|
function resolveJitiCliFromPackageJson(packageJsonPath: string): string | undefined {
|
|
50
56
|
if (!fs.existsSync(packageJsonPath)) return undefined;
|
|
@@ -67,15 +73,15 @@ function resolveJitiCliFromPackageJson(packageJsonPath: string): string | undefi
|
|
|
67
73
|
function resolveJitiCliPath(): string | undefined {
|
|
68
74
|
const candidates: Array<() => string | undefined> = [
|
|
69
75
|
() => require.resolve("jiti/package.json"),
|
|
70
|
-
() =>
|
|
71
|
-
? createRequire(path.join(
|
|
76
|
+
() => selesaiPackageRoot
|
|
77
|
+
? createRequire(path.join(selesaiPackageRoot, "package.json")).resolve("jiti/package.json")
|
|
72
78
|
: undefined,
|
|
73
79
|
() => {
|
|
74
80
|
if (!process.argv[1]) return undefined;
|
|
75
81
|
const piEntry = fs.realpathSync(process.argv[1]);
|
|
76
82
|
return createRequire(piEntry).resolve("jiti/package.json");
|
|
77
83
|
},
|
|
78
|
-
() =>
|
|
84
|
+
() => selesaiPackageRoot ? path.join(selesaiPackageRoot, "node_modules", "jiti", "package.json") : undefined,
|
|
79
85
|
];
|
|
80
86
|
for (const candidate of candidates) {
|
|
81
87
|
try {
|
|
@@ -100,6 +106,8 @@ interface AsyncExecutionContext {
|
|
|
100
106
|
parentSessionId?: string;
|
|
101
107
|
currentModelProvider?: string;
|
|
102
108
|
currentModel?: ParentModel;
|
|
109
|
+
/** Optional model-scope enforcement resolved from subagent settings. */
|
|
110
|
+
modelScope?: ModelScopeConfig;
|
|
103
111
|
}
|
|
104
112
|
|
|
105
113
|
interface AsyncChainParams {
|
|
@@ -118,16 +126,24 @@ interface AsyncChainParams {
|
|
|
118
126
|
sessionRoot?: string;
|
|
119
127
|
chainSkills?: string[];
|
|
120
128
|
sessionFilesByFlatIndex?: (string | undefined)[];
|
|
129
|
+
thinkingOverridesByFlatIndex?: (AgentConfig["thinking"] | undefined)[];
|
|
121
130
|
progressDir?: string;
|
|
122
131
|
dynamicFanoutMaxItems?: number;
|
|
123
132
|
maxSubagentDepth: number;
|
|
124
133
|
worktreeSetupHook?: string;
|
|
125
134
|
worktreeSetupHookTimeoutMs?: number;
|
|
135
|
+
worktreeBaseDir?: string;
|
|
126
136
|
controlConfig?: ResolvedControlConfig;
|
|
127
137
|
controlIntercomTarget?: string;
|
|
128
138
|
childIntercomTarget?: (agent: string, index: number) => string | undefined;
|
|
129
139
|
nestedRoute?: NestedRouteInfo;
|
|
130
140
|
acceptance?: AcceptanceInput;
|
|
141
|
+
timeoutMs?: number;
|
|
142
|
+
turnBudget?: ResolvedTurnBudget;
|
|
143
|
+
toolBudget?: ResolvedToolBudget;
|
|
144
|
+
configToolBudget?: ResolvedToolBudget;
|
|
145
|
+
/** Global cap on simultaneously-running subagent tasks within the async run. */
|
|
146
|
+
globalConcurrencyLimit?: number;
|
|
131
147
|
}
|
|
132
148
|
|
|
133
149
|
interface AsyncSingleParams {
|
|
@@ -145,16 +161,23 @@ interface AsyncSingleParams {
|
|
|
145
161
|
skills?: string[];
|
|
146
162
|
output?: string | boolean;
|
|
147
163
|
outputMode?: "inline" | "file-only";
|
|
164
|
+
outputBaseDir?: string;
|
|
148
165
|
modelOverride?: string;
|
|
166
|
+
thinkingOverride?: AgentConfig["thinking"];
|
|
149
167
|
availableModels?: AvailableModelInfo[];
|
|
150
168
|
maxSubagentDepth: number;
|
|
151
169
|
worktreeSetupHook?: string;
|
|
152
170
|
worktreeSetupHookTimeoutMs?: number;
|
|
171
|
+
worktreeBaseDir?: string;
|
|
153
172
|
controlConfig?: ResolvedControlConfig;
|
|
154
173
|
controlIntercomTarget?: string;
|
|
155
174
|
childIntercomTarget?: (agent: string, index: number) => string | undefined;
|
|
156
175
|
nestedRoute?: NestedRouteInfo;
|
|
157
176
|
acceptance?: AcceptanceInput;
|
|
177
|
+
timeoutMs?: number;
|
|
178
|
+
turnBudget?: ResolvedTurnBudget;
|
|
179
|
+
toolBudget?: ResolvedToolBudget;
|
|
180
|
+
configToolBudget?: ResolvedToolBudget;
|
|
158
181
|
}
|
|
159
182
|
|
|
160
183
|
interface AsyncExecutionResult {
|
|
@@ -174,11 +197,16 @@ export interface AsyncRunnerStepBuildParams {
|
|
|
174
197
|
cwd?: string;
|
|
175
198
|
chainSkills?: string[];
|
|
176
199
|
sessionFilesByFlatIndex?: (string | undefined)[];
|
|
200
|
+
thinkingOverridesByFlatIndex?: (AgentConfig["thinking"] | undefined)[];
|
|
177
201
|
progressDir?: string;
|
|
178
202
|
dynamicFanoutMaxItems?: number;
|
|
179
203
|
maxSubagentDepth: number;
|
|
204
|
+
worktreeBaseDir?: string;
|
|
180
205
|
asyncDir: string;
|
|
206
|
+
outputBaseDir?: string;
|
|
181
207
|
validateOutputBindings?: boolean;
|
|
208
|
+
toolBudget?: ResolvedToolBudget;
|
|
209
|
+
configToolBudget?: ResolvedToolBudget;
|
|
182
210
|
}
|
|
183
211
|
|
|
184
212
|
export type AsyncRunnerStepBuildResult =
|
|
@@ -196,8 +224,8 @@ export function formatAsyncStartedMessage(headline: string): string {
|
|
|
196
224
|
headline,
|
|
197
225
|
"",
|
|
198
226
|
"The async run is detached. Do not run sleep timers or polling loops just to wait for it.",
|
|
199
|
-
"If you have independent work, continue that work.
|
|
200
|
-
"Use subagent({ action: \"status\", id: \"...\" }) when you need
|
|
227
|
+
"If you have independent work, continue that work. When you have nothing left to do until the async result arrives, call wait() — it blocks until the run finishes and delivers the completion here. Only if you are certain you will get another turn (an interactive session where the user will prompt you again) can you instead stop and let Pi wake you; inside a skill that must run to completion, or in a non-interactive run, there is no next turn, so use wait().",
|
|
228
|
+
"Use subagent({ action: \"status\", id: \"...\" }) when you need a one-shot status/result or to inspect a blocked/stale run. To block until completion, prefer wait(). Do not poll in a loop just to wait.",
|
|
201
229
|
].join("\n");
|
|
202
230
|
}
|
|
203
231
|
|
|
@@ -205,74 +233,58 @@ export function formatAsyncStartedMessage(headline: string): string {
|
|
|
205
233
|
* Check if jiti is available for async execution
|
|
206
234
|
*/
|
|
207
235
|
export function isAsyncAvailable(): boolean {
|
|
208
|
-
return
|
|
236
|
+
return jitiCliPath !== undefined;
|
|
209
237
|
}
|
|
210
238
|
|
|
211
|
-
function
|
|
212
|
-
const basename = path.basename(
|
|
213
|
-
|
|
214
|
-
return process.execPath;
|
|
215
|
-
}
|
|
216
|
-
return process.platform === "win32" ? "node.exe" : "node";
|
|
239
|
+
function isNodeExecutableName(execPath: string): boolean {
|
|
240
|
+
const basename = path.basename(execPath).toLowerCase();
|
|
241
|
+
return basename === "node" || basename === "node.exe" || basename === "nodejs" || basename === "nodejs.exe";
|
|
217
242
|
}
|
|
218
243
|
|
|
219
|
-
function
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
].filter((candidate): candidate is string => Boolean(candidate));
|
|
226
|
-
for (const candidate of candidates) {
|
|
227
|
-
if (fs.existsSync(candidate)) return candidate;
|
|
244
|
+
function canUseCurrentNodeExecutable(execPath: string): boolean {
|
|
245
|
+
try {
|
|
246
|
+
fs.accessSync(execPath, process.platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK);
|
|
247
|
+
return true;
|
|
248
|
+
} catch {
|
|
249
|
+
return false;
|
|
228
250
|
}
|
|
229
|
-
return undefined;
|
|
230
251
|
}
|
|
231
252
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
if (runnerScript?.endsWith(".js")) return "compiled";
|
|
238
|
-
return "cli";
|
|
253
|
+
function resolveAsyncRunnerNodeCommand(): string {
|
|
254
|
+
if (isNodeExecutableName(process.execPath) && canUseCurrentNodeExecutable(process.execPath)) {
|
|
255
|
+
return process.execPath;
|
|
256
|
+
}
|
|
257
|
+
return process.platform === "win32" ? "node.exe" : "node";
|
|
239
258
|
}
|
|
240
259
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
260
|
+
export function resolveAsyncRunnerLogPaths(cfg: object): { stdoutPath: string; stderrPath: string } | undefined {
|
|
261
|
+
const asyncDir = typeof (cfg as { asyncDir?: unknown }).asyncDir === "string"
|
|
262
|
+
? (cfg as { asyncDir: string }).asyncDir
|
|
263
|
+
: undefined;
|
|
264
|
+
if (!asyncDir) return undefined;
|
|
265
|
+
return {
|
|
266
|
+
stdoutPath: path.join(asyncDir, "runner.stdout.log"),
|
|
267
|
+
stderrPath: path.join(asyncDir, "runner.stderr.log"),
|
|
268
|
+
};
|
|
245
269
|
}
|
|
246
270
|
|
|
247
|
-
function
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
if (mode === "cli") {
|
|
255
|
-
const spawnSpec = getSelesaiSpawnCommand(["--offline", "--mode", "json", "-p"], {
|
|
256
|
-
...(piPackageRoot ? { piPackageRoot } : {}),
|
|
257
|
-
});
|
|
258
|
-
return {
|
|
259
|
-
command: spawnSpec.command,
|
|
260
|
-
args: spawnSpec.args,
|
|
261
|
-
env: { ...process.env, SELESAI_SUBAGENT_RUNNER_CONFIG: cfgPath },
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
if (!jitiCliPath) {
|
|
265
|
-
return { error: "upstream jiti for TypeScript execution could not be found; ensure package dependencies are installed" };
|
|
271
|
+
function closeFd(fd: number | undefined): void {
|
|
272
|
+
if (fd === undefined) return;
|
|
273
|
+
try {
|
|
274
|
+
fs.closeSync(fd);
|
|
275
|
+
} catch {
|
|
276
|
+
// Best-effort cleanup; child process already owns its duplicated stdio fd.
|
|
266
277
|
}
|
|
267
|
-
const runnerScript = resolveRunnerScript();
|
|
268
|
-
if (!runnerScript) return { error: "async runner script could not be resolved" };
|
|
269
|
-
return { command: resolveAsyncRunnerNodeCommand(), args: [jitiCliPath, runnerScript, cfgPath] };
|
|
270
278
|
}
|
|
271
279
|
|
|
272
280
|
/**
|
|
273
281
|
* Spawn the async runner process
|
|
274
282
|
*/
|
|
275
283
|
function spawnRunner(cfg: object, suffix: string, cwd: string): { pid?: number; error?: string } {
|
|
284
|
+
if (!jitiCliPath) {
|
|
285
|
+
return { error: "upstream jiti for TypeScript execution could not be found; ensure package dependencies are installed" };
|
|
286
|
+
}
|
|
287
|
+
|
|
276
288
|
try {
|
|
277
289
|
const cwdStats = fs.statSync(cwd);
|
|
278
290
|
if (!cwdStats.isDirectory()) {
|
|
@@ -285,32 +297,43 @@ function spawnRunner(cfg: object, suffix: string, cwd: string): { pid?: number;
|
|
|
285
297
|
fs.mkdirSync(TEMP_ROOT_DIR, { recursive: true });
|
|
286
298
|
const cfgPath = getAsyncConfigPath(suffix);
|
|
287
299
|
fs.writeFileSync(cfgPath, JSON.stringify(cfg));
|
|
288
|
-
const
|
|
289
|
-
const
|
|
290
|
-
const markers = createSpawnTimingMarkers();
|
|
291
|
-
emitSpawnTiming({ eventsPath, marker: "spawn_start", markers, runId: suffix });
|
|
292
|
-
|
|
293
|
-
const spec = buildAsyncRunnerSpawnSpec(cfgPath);
|
|
294
|
-
if ("error" in spec) {
|
|
295
|
-
return { error: spec.error };
|
|
296
|
-
}
|
|
297
|
-
emitSpawnTiming({ eventsPath, marker: "spawn_command_resolved", markers, runId: suffix });
|
|
300
|
+
const runner = path.join(path.dirname(fileURLToPath(import.meta.url)), "subagent-runner.ts");
|
|
301
|
+
const nodeCommand = resolveAsyncRunnerNodeCommand();
|
|
298
302
|
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
303
|
+
const logPaths = resolveAsyncRunnerLogPaths(cfg);
|
|
304
|
+
let stdoutFd: number | undefined;
|
|
305
|
+
let stderrFd: number | undefined;
|
|
306
|
+
try {
|
|
307
|
+
if (logPaths) {
|
|
308
|
+
fs.mkdirSync(path.dirname(logPaths.stdoutPath), { recursive: true });
|
|
309
|
+
stdoutFd = fs.openSync(logPaths.stdoutPath, "a");
|
|
310
|
+
stderrFd = fs.openSync(logPaths.stderrPath, "a");
|
|
311
|
+
}
|
|
312
|
+
const proc = spawn(nodeCommand, [jitiCliPath, runner, cfgPath], {
|
|
313
|
+
cwd,
|
|
314
|
+
detached: true,
|
|
315
|
+
stdio: ["ignore", stdoutFd ?? "ignore", stderrFd ?? "ignore"],
|
|
316
|
+
windowsHide: true,
|
|
317
|
+
env: {
|
|
318
|
+
...process.env,
|
|
319
|
+
...(selesaiPackageRoot ? { [SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV]: selesaiPackageRoot } : {}),
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
closeFd(stdoutFd);
|
|
323
|
+
closeFd(stderrFd);
|
|
324
|
+
proc.on("error", (error) => {
|
|
325
|
+
console.error(`[pi-subagents] async spawn failed: ${error.message}`);
|
|
326
|
+
});
|
|
327
|
+
if (typeof proc.pid !== "number") {
|
|
328
|
+
return { error: `async runner did not produce a pid for cwd: ${cwd}` };
|
|
329
|
+
}
|
|
330
|
+
proc.unref();
|
|
331
|
+
return { pid: proc.pid };
|
|
332
|
+
} catch (error) {
|
|
333
|
+
closeFd(stdoutFd);
|
|
334
|
+
closeFd(stderrFd);
|
|
335
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
311
336
|
}
|
|
312
|
-
proc.unref();
|
|
313
|
-
return { pid: proc.pid };
|
|
314
337
|
}
|
|
315
338
|
|
|
316
339
|
function formatAsyncStartError(mode: SubagentRunMode, message: string): AsyncExecutionResult {
|
|
@@ -333,9 +356,12 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
333
356
|
ctx,
|
|
334
357
|
cwd,
|
|
335
358
|
sessionFilesByFlatIndex,
|
|
359
|
+
thinkingOverridesByFlatIndex,
|
|
336
360
|
maxSubagentDepth,
|
|
361
|
+
worktreeBaseDir,
|
|
337
362
|
asyncDir,
|
|
338
363
|
} = params;
|
|
364
|
+
const outputBaseDir = params.outputBaseDir;
|
|
339
365
|
const resultMode = params.resultMode ?? "chain";
|
|
340
366
|
const chainSkills = params.chainSkills ?? [];
|
|
341
367
|
const availableModels = params.availableModels;
|
|
@@ -392,8 +418,11 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
392
418
|
...(s.model ? { model: s.model } : {}),
|
|
393
419
|
};
|
|
394
420
|
};
|
|
395
|
-
const buildSeqStep = (s: SequentialStep, sessionFile?: string, behaviorCwd?: string, progressPrecreated = false, resolvedBehavior?: ResolvedStepBehavior) => {
|
|
421
|
+
const buildSeqStep = (s: SequentialStep, sessionFile?: string, behaviorCwd?: string, progressPrecreated = false, resolvedBehavior?: ResolvedStepBehavior, flatIndex?: number) => {
|
|
396
422
|
const a = agents.find((x) => x.name === s.agent)!;
|
|
423
|
+
const toolBudgetInput = s.toolBudget ?? params.toolBudget ?? a.toolBudget ?? params.configToolBudget;
|
|
424
|
+
const resolvedToolBudget = validateToolBudgetConfig(toolBudgetInput, s.toolBudget ? "toolBudget" : a.toolBudget ? "agent.toolBudget" : "config.toolBudget");
|
|
425
|
+
if (resolvedToolBudget.error) throw new AsyncStartValidationError(resolvedToolBudget.error);
|
|
397
426
|
const stepCwd = resolveChildCwd(runnerCwd, s.cwd);
|
|
398
427
|
const instructionCwd = behaviorCwd ?? stepCwd;
|
|
399
428
|
const behavior = suppressProgressForReadOnlyTask(resolvedBehavior ?? resolveStepBehavior(a, buildStepOverrides(s), chainSkills), s.task, originalTask);
|
|
@@ -406,12 +435,16 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
406
435
|
const injection = buildSkillInjection(resolvedSkills);
|
|
407
436
|
systemPrompt = systemPrompt ? `${systemPrompt}\n\n${injection}` : injection;
|
|
408
437
|
}
|
|
438
|
+
const memoryInjection = buildAgentMemoryInjection(a, stepCwd);
|
|
439
|
+
if (memoryInjection) {
|
|
440
|
+
systemPrompt = systemPrompt ? `${systemPrompt}\n\n${memoryInjection}` : memoryInjection;
|
|
441
|
+
}
|
|
409
442
|
|
|
410
443
|
const readInstructions = buildChainInstructions({ ...behavior, output: false, progress: false }, instructionCwd, false);
|
|
411
444
|
const isFirstProgressAgent = behavior.progress && !progressPrecreated && !progressInstructionCreated;
|
|
412
445
|
if (behavior.progress) progressInstructionCreated = true;
|
|
413
446
|
const progressInstructions = buildChainInstructions({ ...behavior, output: false, reads: false }, progressDir, isFirstProgressAgent);
|
|
414
|
-
const outputPath = resolveSingleOutputPath(behavior.output, ctx.cwd, instructionCwd);
|
|
447
|
+
const outputPath = resolveSingleOutputPath(behavior.output, ctx.cwd, instructionCwd, outputBaseDir);
|
|
415
448
|
systemPrompt = injectOutputPathSystemPrompt(systemPrompt, outputPath);
|
|
416
449
|
const validationError = validateFileOnlyOutputMode(behavior.outputMode, outputPath, `Async step (${s.agent})`);
|
|
417
450
|
if (validationError) throw new AsyncStartValidationError(validationError);
|
|
@@ -421,8 +454,10 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
421
454
|
const task = injectSingleOutputInstruction(`${readInstructions.prefix}${taskTemplate}${progressInstructions.suffix}`, outputPath);
|
|
422
455
|
|
|
423
456
|
const requestedModel = behavior.model ?? a.model;
|
|
424
|
-
const primaryModel = resolveSubagentModelOverride(requestedModel, ctx.currentModel, availableModels, ctx.currentModelProvider);
|
|
425
|
-
const
|
|
457
|
+
const primaryModel = resolveSubagentModelOverride(requestedModel, ctx.currentModel, availableModels, ctx.currentModelProvider, { scope: ctx.modelScope, source: behavior.model ? "explicit" : "inherited" });
|
|
458
|
+
const thinkingOverride = flatIndex === undefined ? undefined : thinkingOverridesByFlatIndex?.[flatIndex];
|
|
459
|
+
const effectiveThinking = thinkingOverride ?? a.thinking;
|
|
460
|
+
const model = applyThinkingSuffix(primaryModel, effectiveThinking, thinkingOverride !== undefined);
|
|
426
461
|
return {
|
|
427
462
|
parentSessionId: ctx.parentSessionId ?? ctx.currentSessionId,
|
|
428
463
|
agent: s.agent,
|
|
@@ -433,9 +468,9 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
433
468
|
structured: Boolean(s.outputSchema),
|
|
434
469
|
cwd: stepCwd,
|
|
435
470
|
model,
|
|
436
|
-
thinking: resolveEffectiveThinking(model,
|
|
437
|
-
modelCandidates: buildModelCandidates(primaryModel, a.fallbackModels, availableModels, ctx.currentModelProvider).map((candidate) =>
|
|
438
|
-
applyThinkingSuffix(candidate,
|
|
471
|
+
thinking: resolveEffectiveThinking(model, effectiveThinking),
|
|
472
|
+
modelCandidates: buildModelCandidates(primaryModel, a.fallbackModels, availableModels, ctx.currentModelProvider, { scope: ctx.modelScope }).map((candidate) =>
|
|
473
|
+
applyThinkingSuffix(candidate, effectiveThinking, thinkingOverride !== undefined),
|
|
439
474
|
),
|
|
440
475
|
tools: a.tools,
|
|
441
476
|
extensions: a.extensions,
|
|
@@ -461,14 +496,21 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
461
496
|
}),
|
|
462
497
|
...(s.outputSchema ? { structuredOutputSchema: s.outputSchema } : {}),
|
|
463
498
|
...(s.outputSchema ? { structuredOutput: createStructuredOutputRuntime(s.outputSchema, path.join(asyncDir, "structured-output")) } : {}),
|
|
499
|
+
...(resolvedToolBudget.budget ? { toolBudget: resolvedToolBudget.budget } : {}),
|
|
464
500
|
};
|
|
465
501
|
};
|
|
466
502
|
|
|
467
503
|
let flatStepIndex = 0;
|
|
468
|
-
const
|
|
504
|
+
const nextFlatStep = (): { index: number; sessionFile?: string; thinkingOverride?: AgentConfig["thinking"] } => {
|
|
505
|
+
const index = flatStepIndex;
|
|
469
506
|
const sessionFile = sessionFilesByFlatIndex?.[flatStepIndex];
|
|
507
|
+
const thinkingOverride = thinkingOverridesByFlatIndex?.[flatStepIndex];
|
|
470
508
|
flatStepIndex++;
|
|
471
|
-
return
|
|
509
|
+
return {
|
|
510
|
+
index,
|
|
511
|
+
...(sessionFile ? { sessionFile } : {}),
|
|
512
|
+
...(thinkingOverride ? { thinkingOverride } : {}),
|
|
513
|
+
};
|
|
472
514
|
};
|
|
473
515
|
|
|
474
516
|
try {
|
|
@@ -488,12 +530,13 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
488
530
|
let behaviorCwd: string | undefined;
|
|
489
531
|
if (s.worktree) {
|
|
490
532
|
try {
|
|
491
|
-
behaviorCwd = resolveExpectedWorktreeAgentCwd(runnerCwd, `${id}-s${stepIndex}`, taskIndex);
|
|
533
|
+
behaviorCwd = resolveExpectedWorktreeAgentCwd(runnerCwd, `${id}-s${stepIndex}`, taskIndex, worktreeBaseDir);
|
|
492
534
|
} catch {
|
|
493
535
|
behaviorCwd = undefined;
|
|
494
536
|
}
|
|
495
537
|
}
|
|
496
|
-
|
|
538
|
+
const staticStep = nextFlatStep();
|
|
539
|
+
return buildSeqStep(t, staticStep.sessionFile, behaviorCwd, progressPrecreated, parallelBehaviors[taskIndex], staticStep.index);
|
|
497
540
|
}),
|
|
498
541
|
concurrency: s.concurrency,
|
|
499
542
|
failFast: s.failFast,
|
|
@@ -508,6 +551,8 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
508
551
|
writeInitialProgressFile(progressDir);
|
|
509
552
|
progressInstructionCreated = true;
|
|
510
553
|
}
|
|
554
|
+
const maxItems = s.expand.maxItems ?? params.dynamicFanoutMaxItems ?? 0;
|
|
555
|
+
const dynamicFlatSteps = Array.from({ length: maxItems }, () => nextFlatStep());
|
|
511
556
|
return {
|
|
512
557
|
expand: s.expand,
|
|
513
558
|
parallel: buildSeqStep(s.parallel as SequentialStep, undefined, undefined, progressPrecreated, behavior),
|
|
@@ -516,6 +561,8 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
516
561
|
failFast: s.failFast,
|
|
517
562
|
phase: s.phase,
|
|
518
563
|
label: s.label,
|
|
564
|
+
sessionFiles: dynamicFlatSteps.map((step) => step.sessionFile),
|
|
565
|
+
thinkingOverrides: dynamicFlatSteps.map((step) => step.thinkingOverride),
|
|
519
566
|
effectiveAcceptance: resolveEffectiveAcceptance({
|
|
520
567
|
explicit: s.acceptance,
|
|
521
568
|
agentName: s.parallel.agent,
|
|
@@ -526,7 +573,8 @@ export function buildAsyncRunnerSteps(id: string, params: AsyncRunnerStepBuildPa
|
|
|
526
573
|
}),
|
|
527
574
|
};
|
|
528
575
|
}
|
|
529
|
-
|
|
576
|
+
const staticStep = nextFlatStep();
|
|
577
|
+
return buildSeqStep(s as SequentialStep, staticStep.sessionFile, undefined, false, undefined, staticStep.index);
|
|
530
578
|
});
|
|
531
579
|
const steps = params.attachRoot
|
|
532
580
|
? [{
|
|
@@ -569,9 +617,11 @@ export function executeAsyncChain(
|
|
|
569
617
|
shareEnabled,
|
|
570
618
|
sessionRoot,
|
|
571
619
|
sessionFilesByFlatIndex,
|
|
620
|
+
thinkingOverridesByFlatIndex,
|
|
572
621
|
maxSubagentDepth,
|
|
573
622
|
worktreeSetupHook,
|
|
574
623
|
worktreeSetupHookTimeoutMs,
|
|
624
|
+
worktreeBaseDir,
|
|
575
625
|
controlConfig,
|
|
576
626
|
controlIntercomTarget,
|
|
577
627
|
childIntercomTarget,
|
|
@@ -605,10 +655,15 @@ export function executeAsyncChain(
|
|
|
605
655
|
cwd,
|
|
606
656
|
chainSkills: params.chainSkills,
|
|
607
657
|
sessionFilesByFlatIndex,
|
|
608
|
-
|
|
658
|
+
thinkingOverridesByFlatIndex,
|
|
659
|
+
progressDir: params.progressDir ?? (artifactsDir ? path.join(artifactsDir, "progress", id) : resultMode === "parallel" ? path.join(asyncDir, "progress") : undefined),
|
|
660
|
+
outputBaseDir: artifactsDir ? path.join(artifactsDir, "outputs", id) : undefined,
|
|
609
661
|
dynamicFanoutMaxItems: params.dynamicFanoutMaxItems,
|
|
610
662
|
maxSubagentDepth,
|
|
663
|
+
worktreeBaseDir,
|
|
611
664
|
asyncDir,
|
|
665
|
+
toolBudget: params.toolBudget,
|
|
666
|
+
configToolBudget: params.configToolBudget,
|
|
612
667
|
});
|
|
613
668
|
if ("error" in built) {
|
|
614
669
|
try {
|
|
@@ -619,6 +674,8 @@ export function executeAsyncChain(
|
|
|
619
674
|
return formatAsyncStartError(resultMode, built.error);
|
|
620
675
|
}
|
|
621
676
|
const { steps, runnerCwd, workflowGraph, eventChain } = built;
|
|
677
|
+
const deadlineAt = params.timeoutMs !== undefined ? Date.now() + params.timeoutMs : undefined;
|
|
678
|
+
const initialTurnBudget = params.turnBudget ? initialTurnBudgetState(params.turnBudget) : undefined;
|
|
622
679
|
let childTargetIndex = 0;
|
|
623
680
|
const childIntercomTargets = childIntercomTarget ? steps.flatMap((step) => {
|
|
624
681
|
if (!("parallel" in step) && step.importAsyncRoot) {
|
|
@@ -651,15 +708,21 @@ export function executeAsyncChain(
|
|
|
651
708
|
sessionDir: sessionRoot ? path.join(sessionRoot, `async-${id}`) : undefined,
|
|
652
709
|
asyncDir,
|
|
653
710
|
sessionId: ctx.currentSessionId,
|
|
654
|
-
|
|
711
|
+
selesaiPackageRoot,
|
|
655
712
|
piArgv1: process.argv[1],
|
|
656
713
|
worktreeSetupHook,
|
|
657
714
|
worktreeSetupHookTimeoutMs,
|
|
715
|
+
worktreeBaseDir,
|
|
658
716
|
controlConfig,
|
|
717
|
+
turnBudget: params.turnBudget,
|
|
718
|
+
toolBudget: params.toolBudget,
|
|
659
719
|
controlIntercomTarget,
|
|
660
720
|
childIntercomTargets,
|
|
661
721
|
resultMode,
|
|
662
722
|
dynamicFanoutMaxItems: params.dynamicFanoutMaxItems,
|
|
723
|
+
timeoutMs: params.timeoutMs,
|
|
724
|
+
deadlineAt,
|
|
725
|
+
globalConcurrencyLimit: params.globalConcurrencyLimit,
|
|
663
726
|
workflowGraph,
|
|
664
727
|
nestedRoute: nestedRoute ?? inheritedNestedRoute,
|
|
665
728
|
nestedSelf: inheritedNestedRoute && nestedAddress ? {
|
|
@@ -732,6 +795,8 @@ export function executeAsyncChain(
|
|
|
732
795
|
agents: flatAgents,
|
|
733
796
|
chainStepCount: eventChain.length,
|
|
734
797
|
parallelGroups,
|
|
798
|
+
...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}),
|
|
799
|
+
...(initialTurnBudget ? { turnBudget: initialTurnBudget } : {}),
|
|
735
800
|
startedAt: now,
|
|
736
801
|
lastUpdate: now,
|
|
737
802
|
},
|
|
@@ -741,6 +806,7 @@ export function executeAsyncChain(
|
|
|
741
806
|
}
|
|
742
807
|
}
|
|
743
808
|
ctx.pi.events.emit(SUBAGENT_ASYNC_STARTED_EVENT, {
|
|
809
|
+
lifecycleArtifactVersion: SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
|
|
744
810
|
id,
|
|
745
811
|
pid: spawnResult.pid,
|
|
746
812
|
sessionId: ctx.currentSessionId,
|
|
@@ -760,6 +826,8 @@ export function executeAsyncChain(
|
|
|
760
826
|
workflowGraph,
|
|
761
827
|
cwd: runnerCwd,
|
|
762
828
|
asyncDir,
|
|
829
|
+
...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}),
|
|
830
|
+
...(initialTurnBudget ? { turnBudget: initialTurnBudget } : {}),
|
|
763
831
|
nestedRoute,
|
|
764
832
|
});
|
|
765
833
|
}
|
|
@@ -772,7 +840,7 @@ export function executeAsyncChain(
|
|
|
772
840
|
|
|
773
841
|
return {
|
|
774
842
|
content: [{ type: "text", text: formatAsyncStartedMessage(`Async ${resultMode}: ${chainDesc} [${id}]`) }],
|
|
775
|
-
details: { mode: resultMode, runId: id, results: [], asyncId: id, asyncDir, workflowGraph },
|
|
843
|
+
details: { mode: resultMode, runId: id, results: [], asyncId: id, asyncDir, workflowGraph, ...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}), ...(params.turnBudget ? { turnBudget: params.turnBudget } : {}), ...(params.toolBudget ? { toolBudget: params.toolBudget } : {}) },
|
|
776
844
|
};
|
|
777
845
|
}
|
|
778
846
|
|
|
@@ -797,6 +865,7 @@ export function executeAsyncSingle(
|
|
|
797
865
|
maxSubagentDepth,
|
|
798
866
|
worktreeSetupHook,
|
|
799
867
|
worktreeSetupHookTimeoutMs,
|
|
868
|
+
worktreeBaseDir,
|
|
800
869
|
controlConfig,
|
|
801
870
|
controlIntercomTarget,
|
|
802
871
|
childIntercomTarget,
|
|
@@ -813,6 +882,10 @@ export function executeAsyncSingle(
|
|
|
813
882
|
const injection = buildSkillInjection(resolvedSkills);
|
|
814
883
|
systemPrompt = systemPrompt ? `${systemPrompt}\n\n${injection}` : injection;
|
|
815
884
|
}
|
|
885
|
+
const memoryInjection = buildAgentMemoryInjection(agentConfig, runnerCwd);
|
|
886
|
+
if (memoryInjection) {
|
|
887
|
+
systemPrompt = systemPrompt ? `${systemPrompt}\n\n${memoryInjection}` : memoryInjection;
|
|
888
|
+
}
|
|
816
889
|
|
|
817
890
|
const inheritedNestedRoute = resolveInheritedNestedRouteFromEnv();
|
|
818
891
|
const nestedAddress = inheritedNestedRoute ? resolveNestedParentAddressFromEnv() : undefined;
|
|
@@ -831,7 +904,7 @@ export function executeAsyncSingle(
|
|
|
831
904
|
}
|
|
832
905
|
|
|
833
906
|
const effectiveOutput = normalizeSingleOutputOverride(params.output, agentConfig.output);
|
|
834
|
-
const outputPath = resolveSingleOutputPath(effectiveOutput, ctx.cwd, runnerCwd);
|
|
907
|
+
const outputPath = resolveSingleOutputPath(effectiveOutput, ctx.cwd, runnerCwd, params.outputBaseDir ?? (artifactsDir ? path.join(artifactsDir, "outputs", id) : undefined));
|
|
835
908
|
systemPrompt = injectOutputPathSystemPrompt(systemPrompt, outputPath);
|
|
836
909
|
const outputMode = params.outputMode ?? "inline";
|
|
837
910
|
const validationError = validateFileOnlyOutputMode(outputMode, outputPath, `Async single run (${agent})`);
|
|
@@ -843,7 +916,13 @@ export function executeAsyncSingle(
|
|
|
843
916
|
availableModels,
|
|
844
917
|
ctx.currentModelProvider,
|
|
845
918
|
);
|
|
846
|
-
const
|
|
919
|
+
const effectiveThinking = params.thinkingOverride ?? agentConfig.thinking;
|
|
920
|
+
const model = applyThinkingSuffix(primaryModel, effectiveThinking, params.thinkingOverride !== undefined);
|
|
921
|
+
const toolBudgetInput = params.toolBudget ?? agentConfig.toolBudget ?? params.configToolBudget;
|
|
922
|
+
const resolvedToolBudget = validateToolBudgetConfig(toolBudgetInput, params.toolBudget ? "toolBudget" : agentConfig.toolBudget ? "agent.toolBudget" : "config.toolBudget");
|
|
923
|
+
if (resolvedToolBudget.error) return formatAsyncStartError("single", resolvedToolBudget.error);
|
|
924
|
+
const deadlineAt = params.timeoutMs !== undefined ? Date.now() + params.timeoutMs : undefined;
|
|
925
|
+
const initialTurnBudget = params.turnBudget ? initialTurnBudgetState(params.turnBudget) : undefined;
|
|
847
926
|
let spawnResult: { pid?: number; error?: string } = {};
|
|
848
927
|
try {
|
|
849
928
|
spawnResult = spawnRunner(
|
|
@@ -856,9 +935,9 @@ export function executeAsyncSingle(
|
|
|
856
935
|
task: taskWithOutputInstruction,
|
|
857
936
|
cwd: runnerCwd,
|
|
858
937
|
model,
|
|
859
|
-
thinking: resolveEffectiveThinking(model,
|
|
860
|
-
modelCandidates: buildModelCandidates(primaryModel, agentConfig.fallbackModels, availableModels, ctx.currentModelProvider).map((candidate) =>
|
|
861
|
-
applyThinkingSuffix(candidate,
|
|
938
|
+
thinking: resolveEffectiveThinking(model, effectiveThinking),
|
|
939
|
+
modelCandidates: buildModelCandidates(primaryModel, agentConfig.fallbackModels, availableModels, ctx.currentModelProvider, { scope: ctx.modelScope }).map((candidate) =>
|
|
940
|
+
applyThinkingSuffix(candidate, effectiveThinking, params.thinkingOverride !== undefined),
|
|
862
941
|
),
|
|
863
942
|
tools: agentConfig.tools,
|
|
864
943
|
extensions: agentConfig.extensions,
|
|
@@ -881,6 +960,7 @@ export function executeAsyncSingle(
|
|
|
881
960
|
mode: "single",
|
|
882
961
|
async: true,
|
|
883
962
|
}),
|
|
963
|
+
...(resolvedToolBudget.budget ? { toolBudget: resolvedToolBudget.budget } : {}),
|
|
884
964
|
},
|
|
885
965
|
],
|
|
886
966
|
resultPath: inheritedNestedRoute ? nestedResultsPath(inheritedNestedRoute.rootRunId, id) : path.join(RESULTS_DIR, `${id}.json`),
|
|
@@ -893,11 +973,16 @@ export function executeAsyncSingle(
|
|
|
893
973
|
sessionDir: sessionRoot ? path.join(sessionRoot, `async-${id}`) : undefined,
|
|
894
974
|
asyncDir,
|
|
895
975
|
sessionId: ctx.currentSessionId,
|
|
896
|
-
|
|
976
|
+
selesaiPackageRoot,
|
|
897
977
|
piArgv1: process.argv[1],
|
|
898
978
|
worktreeSetupHook,
|
|
899
979
|
worktreeSetupHookTimeoutMs,
|
|
980
|
+
worktreeBaseDir,
|
|
900
981
|
controlConfig,
|
|
982
|
+
timeoutMs: params.timeoutMs,
|
|
983
|
+
deadlineAt,
|
|
984
|
+
turnBudget: params.turnBudget,
|
|
985
|
+
toolBudget: params.toolBudget,
|
|
901
986
|
controlIntercomTarget,
|
|
902
987
|
childIntercomTargets: childIntercomTarget ? [childIntercomTarget(agent, 0)] : undefined,
|
|
903
988
|
resultMode: "single",
|
|
@@ -947,6 +1032,8 @@ export function executeAsyncSingle(
|
|
|
947
1032
|
agent,
|
|
948
1033
|
agents: [agent],
|
|
949
1034
|
chainStepCount: 1,
|
|
1035
|
+
...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}),
|
|
1036
|
+
...(initialTurnBudget ? { turnBudget: initialTurnBudget } : {}),
|
|
950
1037
|
startedAt: now,
|
|
951
1038
|
lastUpdate: now,
|
|
952
1039
|
},
|
|
@@ -956,6 +1043,7 @@ export function executeAsyncSingle(
|
|
|
956
1043
|
}
|
|
957
1044
|
}
|
|
958
1045
|
ctx.pi.events.emit(SUBAGENT_ASYNC_STARTED_EVENT, {
|
|
1046
|
+
lifecycleArtifactVersion: SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
|
|
959
1047
|
id,
|
|
960
1048
|
pid: spawnResult.pid,
|
|
961
1049
|
sessionId: ctx.currentSessionId,
|
|
@@ -964,12 +1052,14 @@ export function executeAsyncSingle(
|
|
|
964
1052
|
task: task?.slice(0, 50),
|
|
965
1053
|
cwd: runnerCwd,
|
|
966
1054
|
asyncDir,
|
|
1055
|
+
...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}),
|
|
1056
|
+
...(initialTurnBudget ? { turnBudget: initialTurnBudget } : {}),
|
|
967
1057
|
nestedRoute,
|
|
968
1058
|
});
|
|
969
1059
|
}
|
|
970
1060
|
|
|
971
1061
|
return {
|
|
972
1062
|
content: [{ type: "text", text: formatAsyncStartedMessage(`Async: ${agent} [${id}]`) }],
|
|
973
|
-
details: { mode: "single", runId: id, results: [], asyncId: id, asyncDir },
|
|
1063
|
+
details: { mode: "single", runId: id, results: [], asyncId: id, asyncDir, ...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}), ...(params.turnBudget ? { turnBudget: params.turnBudget } : {}), ...(params.toolBudget ? { toolBudget: params.toolBudget } : {}) },
|
|
974
1064
|
};
|
|
975
1065
|
}
|