pi-subagents 0.76.0 → 0.77.0
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 +92 -0
- package/README.md +1 -1
- package/agents/oracle.md +8 -19
- package/agents/researcher.md +0 -3
- package/agents/reviewer.md +17 -61
- package/agents/scout.md +1 -4
- package/agents/worker.md +8 -25
- package/docs/agents.md +70 -3
- package/docs/configuration.md +55 -6
- package/docs/extension-api.md +36 -11
- package/docs/missions.md +24 -17
- package/docs/models.md +1 -1
- package/docs/observability.md +10 -5
- package/docs/tool-reference.md +101 -83
- package/docs/watchdog.md +8 -6
- package/docs/workflows.md +15 -6
- package/index.d.ts.map +1 -1
- package/index.js +5 -0
- package/index.js.map +1 -1
- package/package.json +2 -1
- package/prompts/council.md +1 -1
- package/skills/pi-subagents/SKILL.md +1 -1
- package/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
- package/skills/pi-subagents/references/execution-controls.md +16 -16
- package/skills/pi-subagents/references/management-authoring-rpc.md +16 -12
- package/skills/pi-subagents/references/prompting-and-roles.md +3 -3
- package/src/agents/advertised-agent-prompt.d.ts +5 -1
- package/src/agents/advertised-agent-prompt.d.ts.map +1 -1
- package/src/agents/advertised-agent-prompt.js +8 -2
- package/src/agents/advertised-agent-prompt.js.map +1 -1
- package/src/agents/agent-management.d.ts.map +1 -1
- package/src/agents/agent-management.js +5 -0
- package/src/agents/agent-management.js.map +1 -1
- package/src/agents/agent-scope.d.ts +1 -0
- package/src/agents/agent-scope.d.ts.map +1 -1
- package/src/agents/agent-scope.js +3 -0
- package/src/agents/agent-scope.js.map +1 -1
- package/src/agents/agent-serializer.d.ts.map +1 -1
- package/src/agents/agent-serializer.js +3 -0
- package/src/agents/agent-serializer.js.map +1 -1
- package/src/agents/agents.d.ts +14 -2
- package/src/agents/agents.d.ts.map +1 -1
- package/src/agents/agents.js +94 -36
- package/src/agents/agents.js.map +1 -1
- package/src/api/preflight.d.ts +2 -0
- package/src/api/preflight.d.ts.map +1 -1
- package/src/api/preflight.js +6 -2
- package/src/api/preflight.js.map +1 -1
- package/src/extension/config.d.ts.map +1 -1
- package/src/extension/config.js +23 -2
- package/src/extension/config.js.map +1 -1
- package/src/extension/control-notices.d.ts +0 -2
- package/src/extension/control-notices.d.ts.map +1 -1
- package/src/extension/control-notices.js +1 -7
- package/src/extension/control-notices.js.map +1 -1
- package/src/extension/declaration-pinning.d.ts +14 -0
- package/src/extension/declaration-pinning.d.ts.map +1 -0
- package/src/extension/declaration-pinning.js +147 -0
- package/src/extension/declaration-pinning.js.map +1 -0
- package/src/extension/doctor.d.ts +3 -1
- package/src/extension/doctor.d.ts.map +1 -1
- package/src/extension/doctor.js +3 -9
- package/src/extension/doctor.js.map +1 -1
- package/src/extension/fanout-child.d.ts.map +1 -1
- package/src/extension/fanout-child.js +6 -8
- package/src/extension/fanout-child.js.map +1 -1
- package/src/extension/index.d.ts +1 -1
- package/src/extension/index.d.ts.map +1 -1
- package/src/extension/index.js +68 -116
- package/src/extension/index.js.map +1 -1
- package/src/extension/rpc.d.ts.map +1 -1
- package/src/extension/rpc.js +12 -6
- package/src/extension/rpc.js.map +1 -1
- package/src/extension/schemas.d.ts +137 -1
- package/src/extension/schemas.d.ts.map +1 -1
- package/src/extension/schemas.js +22 -22
- package/src/extension/schemas.js.map +1 -1
- package/src/extension/subagent-guide.d.ts +1 -0
- package/src/extension/subagent-guide.d.ts.map +1 -1
- package/src/extension/subagent-guide.js +80 -6
- package/src/extension/subagent-guide.js.map +1 -1
- package/src/extension/subagent-options.d.ts +8 -0
- package/src/extension/subagent-options.d.ts.map +1 -0
- package/src/extension/subagent-options.js +52 -0
- package/src/extension/subagent-options.js.map +1 -0
- package/src/extension/tool-activation.d.ts.map +1 -1
- package/src/extension/tool-activation.js +3 -2
- package/src/extension/tool-activation.js.map +1 -1
- package/src/extension/tool-description.d.ts +4 -7
- package/src/extension/tool-description.d.ts.map +1 -1
- package/src/extension/tool-description.js +45 -59
- package/src/extension/tool-description.js.map +1 -1
- package/src/inspectors/actions.d.ts +2 -0
- package/src/inspectors/actions.d.ts.map +1 -1
- package/src/inspectors/actions.js +41 -13
- package/src/inspectors/actions.js.map +1 -1
- package/src/inspectors/plugins.d.ts.map +1 -1
- package/src/inspectors/plugins.js +3 -2
- package/src/inspectors/plugins.js.map +1 -1
- package/src/inspectors/tmux/actions.d.ts +26 -0
- package/src/inspectors/tmux/actions.d.ts.map +1 -0
- package/src/inspectors/tmux/actions.js +182 -0
- package/src/inspectors/tmux/actions.js.map +1 -0
- package/src/inspectors/tmux/client.d.ts +28 -0
- package/src/inspectors/tmux/client.d.ts.map +1 -0
- package/src/inspectors/tmux/client.js +65 -0
- package/src/inspectors/tmux/client.js.map +1 -0
- package/src/inspectors/tmux/plugin.d.ts +8 -0
- package/src/inspectors/tmux/plugin.d.ts.map +1 -0
- package/src/inspectors/tmux/plugin.js +15 -0
- package/src/inspectors/tmux/plugin.js.map +1 -0
- package/src/integrations/herdr-status.d.ts +0 -1
- package/src/integrations/herdr-status.d.ts.map +1 -1
- package/src/integrations/herdr-status.js +18 -52
- package/src/integrations/herdr-status.js.map +1 -1
- package/src/integrations/program-status.d.ts +31 -0
- package/src/integrations/program-status.d.ts.map +1 -0
- package/src/integrations/program-status.js +189 -0
- package/src/integrations/program-status.js.map +1 -0
- package/src/intercom/native-supervisor-channel.d.ts +1 -0
- package/src/intercom/native-supervisor-channel.d.ts.map +1 -1
- package/src/intercom/native-supervisor-channel.js +77 -3
- package/src/intercom/native-supervisor-channel.js.map +1 -1
- package/src/intercom/result-intercom.js +1 -1
- package/src/intercom/result-intercom.js.map +1 -1
- package/src/intercom/supervisor-ui.d.ts +2 -12
- package/src/intercom/supervisor-ui.d.ts.map +1 -1
- package/src/intercom/supervisor-ui.js +2 -154
- package/src/intercom/supervisor-ui.js.map +1 -1
- package/src/missions/store.d.ts.map +1 -1
- package/src/missions/store.js +27 -5
- package/src/missions/store.js.map +1 -1
- package/src/runs/background/async-execution.d.ts +9 -1
- package/src/runs/background/async-execution.d.ts.map +1 -1
- package/src/runs/background/async-execution.js +250 -141
- package/src/runs/background/async-execution.js.map +1 -1
- package/src/runs/background/async-job-tracker.d.ts +4 -1
- package/src/runs/background/async-job-tracker.d.ts.map +1 -1
- package/src/runs/background/async-job-tracker.js +3 -2
- package/src/runs/background/async-job-tracker.js.map +1 -1
- package/src/runs/background/async-resume.d.ts.map +1 -1
- package/src/runs/background/async-resume.js +6 -2
- package/src/runs/background/async-resume.js.map +1 -1
- package/src/runs/background/await-async-run.d.ts +8 -4
- package/src/runs/background/await-async-run.d.ts.map +1 -1
- package/src/runs/background/await-async-run.js +14 -8
- package/src/runs/background/await-async-run.js.map +1 -1
- package/src/runs/background/binary-bootstrap.d.ts.map +1 -1
- package/src/runs/background/binary-bootstrap.js +2 -1
- package/src/runs/background/binary-bootstrap.js.map +1 -1
- package/src/runs/background/chain-root-attachment.d.ts +2 -0
- package/src/runs/background/chain-root-attachment.d.ts.map +1 -1
- package/src/runs/background/chain-root-attachment.js +5 -2
- package/src/runs/background/chain-root-attachment.js.map +1 -1
- package/src/runs/background/fleet-view.js +5 -5
- package/src/runs/background/fleet-view.js.map +1 -1
- package/src/runs/background/notify.d.ts +12 -2
- package/src/runs/background/notify.d.ts.map +1 -1
- package/src/runs/background/notify.js +148 -13
- package/src/runs/background/notify.js.map +1 -1
- package/src/runs/background/result-files.d.ts +29 -0
- package/src/runs/background/result-files.d.ts.map +1 -1
- package/src/runs/background/result-files.js +104 -6
- package/src/runs/background/result-files.js.map +1 -1
- package/src/runs/background/result-watcher.d.ts.map +1 -1
- package/src/runs/background/result-watcher.js +60 -64
- package/src/runs/background/result-watcher.js.map +1 -1
- package/src/runs/background/resume-guidance.js +2 -2
- package/src/runs/background/resume-guidance.js.map +1 -1
- package/src/runs/background/run-child-session.d.ts.map +1 -1
- package/src/runs/background/run-child-session.js +2 -1
- package/src/runs/background/run-child-session.js.map +1 -1
- package/src/runs/background/run-id-resolver.d.ts.map +1 -1
- package/src/runs/background/run-id-resolver.js +9 -6
- package/src/runs/background/run-id-resolver.js.map +1 -1
- package/src/runs/background/run-status.d.ts.map +1 -1
- package/src/runs/background/run-status.js +19 -15
- package/src/runs/background/run-status.js.map +1 -1
- package/src/runs/background/runner-child-launch.d.ts.map +1 -1
- package/src/runs/background/runner-child-launch.js +1 -0
- package/src/runs/background/runner-child-launch.js.map +1 -1
- package/src/runs/background/runner-http-dispatcher.d.ts +3 -0
- package/src/runs/background/runner-http-dispatcher.d.ts.map +1 -1
- package/src/runs/background/runner-http-dispatcher.js +2 -0
- package/src/runs/background/runner-http-dispatcher.js.map +1 -1
- package/src/runs/background/scheduled-runs.d.ts +9 -0
- package/src/runs/background/scheduled-runs.d.ts.map +1 -1
- package/src/runs/background/scheduled-runs.js +124 -36
- package/src/runs/background/scheduled-runs.js.map +1 -1
- package/src/runs/background/subagent-runner-bootstrap.d.ts.map +1 -1
- package/src/runs/background/subagent-runner-bootstrap.js +5 -1
- package/src/runs/background/subagent-runner-bootstrap.js.map +1 -1
- package/src/runs/background/subagent-runner.d.ts +3 -1
- package/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/src/runs/background/subagent-runner.js +15 -6
- package/src/runs/background/subagent-runner.js.map +1 -1
- package/src/runs/background/subagent-wait.d.ts +2 -0
- package/src/runs/background/subagent-wait.d.ts.map +1 -1
- package/src/runs/background/subagent-wait.js +34 -20
- package/src/runs/background/subagent-wait.js.map +1 -1
- package/src/runs/background/terminal-run-index.d.ts +1 -0
- package/src/runs/background/terminal-run-index.d.ts.map +1 -1
- package/src/runs/background/terminal-run-index.js +47 -1
- package/src/runs/background/terminal-run-index.js.map +1 -1
- package/src/runs/background/wait-tool.d.ts.map +1 -1
- package/src/runs/background/wait-tool.js +36 -23
- package/src/runs/background/wait-tool.js.map +1 -1
- package/src/runs/foreground/async-stop-action.d.ts +7 -1
- package/src/runs/foreground/async-stop-action.d.ts.map +1 -1
- package/src/runs/foreground/async-stop-action.js +49 -25
- package/src/runs/foreground/async-stop-action.js.map +1 -1
- package/src/runs/foreground/execution.d.ts.map +1 -1
- package/src/runs/foreground/execution.js +50 -24
- package/src/runs/foreground/execution.js.map +1 -1
- package/src/runs/foreground/subagent-executor.d.ts +5 -1
- package/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/src/runs/foreground/subagent-executor.js +174 -65
- package/src/runs/foreground/subagent-executor.js.map +1 -1
- package/src/runs/shared/child-hooks.js +6 -5
- package/src/runs/shared/child-hooks.js.map +1 -1
- package/src/runs/shared/child-launch.d.ts +2 -0
- package/src/runs/shared/child-launch.d.ts.map +1 -1
- package/src/runs/shared/child-launch.js +1 -0
- package/src/runs/shared/child-launch.js.map +1 -1
- package/src/runs/shared/child-session.d.ts +4 -0
- package/src/runs/shared/child-session.d.ts.map +1 -1
- package/src/runs/shared/child-session.js +28 -23
- package/src/runs/shared/child-session.js.map +1 -1
- package/src/runs/shared/child-tool-plan.d.ts.map +1 -1
- package/src/runs/shared/child-tool-plan.js +11 -10
- package/src/runs/shared/child-tool-plan.js.map +1 -1
- package/src/runs/shared/dynamic-fanout.js +1 -1
- package/src/runs/shared/dynamic-fanout.js.map +1 -1
- package/src/runs/shared/herdr-placed-run.d.ts +1 -0
- package/src/runs/shared/herdr-placed-run.d.ts.map +1 -1
- package/src/runs/shared/herdr-placed-run.js +10 -6
- package/src/runs/shared/herdr-placed-run.js.map +1 -1
- package/src/runs/shared/model-resolution-diagnostic.d.ts +10 -0
- package/src/runs/shared/model-resolution-diagnostic.d.ts.map +1 -1
- package/src/runs/shared/model-resolution-diagnostic.js +24 -0
- package/src/runs/shared/model-resolution-diagnostic.js.map +1 -1
- package/src/runs/shared/model-resolution.d.ts.map +1 -1
- package/src/runs/shared/model-resolution.js +29 -1
- package/src/runs/shared/model-resolution.js.map +1 -1
- package/src/runs/shared/nested-events.d.ts +2 -0
- package/src/runs/shared/nested-events.d.ts.map +1 -1
- package/src/runs/shared/nested-events.js +4 -0
- package/src/runs/shared/nested-events.js.map +1 -1
- package/src/runs/shared/parallel-handoff.js +2 -2
- package/src/runs/shared/parallel-handoff.js.map +1 -1
- package/src/runs/shared/parallel-utils.d.ts +2 -0
- package/src/runs/shared/parallel-utils.d.ts.map +1 -1
- package/src/runs/shared/parallel-utils.js.map +1 -1
- package/src/runs/shared/runner-launcher.d.ts +12 -0
- package/src/runs/shared/runner-launcher.d.ts.map +1 -0
- package/src/runs/shared/runner-launcher.js +25 -0
- package/src/runs/shared/runner-launcher.js.map +1 -0
- package/src/runs/shared/single-output.d.ts +20 -0
- package/src/runs/shared/single-output.d.ts.map +1 -1
- package/src/runs/shared/single-output.js +57 -0
- package/src/runs/shared/single-output.js.map +1 -1
- package/src/runs/shared/structured-output.d.ts.map +1 -1
- package/src/runs/shared/structured-output.js +17 -8
- package/src/runs/shared/structured-output.js.map +1 -1
- package/src/runs/shared/subagent-control.js +3 -3
- package/src/runs/shared/subagent-control.js.map +1 -1
- package/src/runs/shared/subagent-prompt-runtime.d.ts +8 -2
- package/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
- package/src/runs/shared/subagent-prompt-runtime.js +43 -20
- package/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
- package/src/runs/shared/workflow-async-child-guidance.js +1 -1
- package/src/runs/shared/workflow-async-child-guidance.js.map +1 -1
- package/src/runs/shared/worktree-cleanup-plan.js +1 -1
- package/src/runs/shared/worktree-cleanup-plan.js.map +1 -1
- package/src/shared/atomic-json.d.ts +4 -3
- package/src/shared/atomic-json.d.ts.map +1 -1
- package/src/shared/atomic-json.js +3 -1
- package/src/shared/atomic-json.js.map +1 -1
- package/src/shared/edit-distance.d.ts +5 -0
- package/src/shared/edit-distance.d.ts.map +1 -0
- package/src/shared/edit-distance.js +33 -0
- package/src/shared/edit-distance.js.map +1 -0
- package/src/shared/formatters.d.ts.map +1 -1
- package/src/shared/formatters.js +1 -6
- package/src/shared/formatters.js.map +1 -1
- package/src/shared/model-info.d.ts +8 -0
- package/src/shared/model-info.d.ts.map +1 -1
- package/src/shared/model-info.js +22 -0
- package/src/shared/model-info.js.map +1 -1
- package/src/shared/package-version.d.ts +3 -0
- package/src/shared/package-version.d.ts.map +1 -0
- package/src/shared/package-version.js +15 -0
- package/src/shared/package-version.js.map +1 -0
- package/src/shared/parent-wake.d.ts +18 -0
- package/src/shared/parent-wake.d.ts.map +1 -0
- package/src/shared/parent-wake.js +60 -0
- package/src/shared/parent-wake.js.map +1 -0
- package/src/shared/pruned-fork.d.ts +1 -1
- package/src/shared/pruned-fork.d.ts.map +1 -1
- package/src/shared/pruned-fork.js +6 -0
- package/src/shared/pruned-fork.js.map +1 -1
- package/src/shared/runtime-module-path.d.ts +11 -0
- package/src/shared/runtime-module-path.d.ts.map +1 -0
- package/src/shared/runtime-module-path.js +17 -0
- package/src/shared/runtime-module-path.js.map +1 -0
- package/src/shared/types.d.ts +26 -2
- package/src/shared/types.d.ts.map +1 -1
- package/src/shared/types.js +3 -0
- package/src/shared/types.js.map +1 -1
- package/src/shared/utils.d.ts.map +1 -1
- package/src/shared/utils.js +8 -7
- package/src/shared/utils.js.map +1 -1
- package/src/slash/slash-commands.js +3 -3
- package/src/slash/slash-commands.js.map +1 -1
- package/src/slash/subagents-admin.d.ts.map +1 -1
- package/src/slash/subagents-admin.js +2 -1
- package/src/slash/subagents-admin.js.map +1 -1
- package/src/tui/fleet-transcript.d.ts +2 -0
- package/src/tui/fleet-transcript.d.ts.map +1 -1
- package/src/tui/fleet-transcript.js +7 -2
- package/src/tui/fleet-transcript.js.map +1 -1
- package/src/tui/fleet.d.ts.map +1 -1
- package/src/tui/fleet.js +9 -4
- package/src/tui/fleet.js.map +1 -1
- package/src/tui/render.d.ts +2 -2
- package/src/tui/render.d.ts.map +1 -1
- package/src/tui/render.js +19 -17
- package/src/tui/render.js.map +1 -1
- package/src/tui/subagent-messages.d.ts +23 -0
- package/src/tui/subagent-messages.d.ts.map +1 -0
- package/src/tui/subagent-messages.js +270 -0
- package/src/tui/subagent-messages.js.map +1 -0
- package/src/watchdog/register-main.d.ts.map +1 -1
- package/src/watchdog/register-main.js +1 -19
- package/src/watchdog/register-main.js.map +1 -1
- package/src/watchdog/render.d.ts +2 -10
- package/src/watchdog/render.d.ts.map +1 -1
- package/src/watchdog/render.js +1 -19
- package/src/watchdog/render.js.map +1 -1
- package/src/watchdog/tool-actions.js +2 -2
- package/src/watchdog/tool-actions.js.map +1 -1
- package/src/workflows/scripted-workflow.d.ts.map +1 -1
- package/src/workflows/scripted-workflow.js +20 -6
- package/src/workflows/scripted-workflow.js.map +1 -1
- package/src/workflows/workflow-resources.d.ts.map +1 -1
- package/src/workflows/workflow-resources.js +12 -0
- package/src/workflows/workflow-resources.js.map +1 -1
|
@@ -18,12 +18,13 @@ import { applyThinkingSuffix, projectLaunchResolvedChildExtensions, resolvePiLau
|
|
|
18
18
|
import { assertClaudeCodeModelScope, isClaudeCodeAdapterId, resolveClaudeCodeOverride } from "../shared/claude-code-adapter.js";
|
|
19
19
|
import { injectSingleOutputInstruction, normalizeSingleOutputOverride, resolveSingleOutputPath, validateFileOnlyOutputMode } from "../shared/single-output.js";
|
|
20
20
|
import { applyWatchdogLaunchRules, sendRuleViolationWarning } from "../../watchdog/rules.js";
|
|
21
|
-
import { buildChainInstructions, isDynamicParallelStep, isParallelStep, resolveExistingReadInstructionPaths, resolveExistingReadPaths, writeInitialProgressFile } from "../../shared/settings.js";
|
|
21
|
+
import { buildChainInstructions, getStepAgents, isDynamicParallelStep, isParallelStep, resolveExistingReadInstructionPaths, resolveExistingReadPaths, writeInitialProgressFile } from "../../shared/settings.js";
|
|
22
22
|
import { isDynamicRunnerGroup, isParallelGroup } from "../shared/parallel-utils.js";
|
|
23
23
|
import { PI_CODING_AGENT_PACKAGE, resolveBunPiExecutable, resolveInstalledPiPackageRoot, resolvePiPackageRoot } from "../shared/pi-spawn.js";
|
|
24
24
|
import { JITI_ALIAS_ENV, resolveHostPeerAliases } from "./runner-aliases.js";
|
|
25
25
|
import { preflightLaunchCwd } from "../shared/launch-cwd.js";
|
|
26
26
|
import { resolveNodeExecutable } from "../../shared/node-executable.js";
|
|
27
|
+
import { resolveRuntimeModulePath } from "../../shared/runtime-module-path.js";
|
|
27
28
|
import { backgroundProcessOptions } from "../shared/background-process-options.js";
|
|
28
29
|
import { normalizeSkillInput, resolveSkillsWithFallback } from "../../agents/skills.js";
|
|
29
30
|
import { PI_CODING_AGENT_PACKAGE_ROOT_ENV, PROMPT_REDACTED, resolveChildCwd } from "../../shared/utils.js";
|
|
@@ -51,6 +52,8 @@ import { finalizeProcessTerminal, initializeProcessTerminal, readProcessTerminal
|
|
|
51
52
|
import { persistRunnerStartupFailure } from "./runner-startup-failure.js";
|
|
52
53
|
import { statusStepDescription } from "./chain-append.js";
|
|
53
54
|
import { currentPidNamespaceScope } from "./pid-namespace.js";
|
|
55
|
+
import { checkPidLiveness } from "./stale-run-reconciler.js";
|
|
56
|
+
import { lookupRunnerLauncher, resolveAgentRunnerLauncher, runnerLauncherPlacementError } from "../shared/runner-launcher.js";
|
|
54
57
|
import { SUBAGENT_PROCESS_TERMINAL_EVENT } from "../../shared/types.js";
|
|
55
58
|
import { assertAgentAllowedByCapabilityCeiling, intersectSubagentCapabilityCeilings, resolveCurrentSubagentCapabilityCeiling } from "../shared/capability-ceiling.js";
|
|
56
59
|
import { resolveLaunchBinding } from "../../shared/launch-contract.js";
|
|
@@ -122,28 +125,29 @@ function resolveJitiCliPath() {
|
|
|
122
125
|
return undefined;
|
|
123
126
|
}
|
|
124
127
|
const jitiCliPath = resolveJitiCliPath();
|
|
125
|
-
const
|
|
126
|
-
|
|
128
|
+
const asyncRunnerModuleDir = path.dirname(fileURLToPath(import.meta.url));
|
|
129
|
+
// Resolved per launch: an in-place package update can swap a sibling's .ts for .js.
|
|
130
|
+
function asyncRunnerSourcePath() {
|
|
131
|
+
return resolveRuntimeModulePath(asyncRunnerModuleDir, "subagent-runner-bootstrap");
|
|
132
|
+
}
|
|
133
|
+
function sourceUnderNodeModules() {
|
|
134
|
+
return asyncRunnerSourcePath().split(path.sep).some((segment) => segment.toLowerCase() === "node_modules");
|
|
135
|
+
}
|
|
127
136
|
function supportsNativeRunner(nodeExecutable) {
|
|
128
137
|
return Boolean(process.features.typescript)
|
|
129
138
|
&& typeof nodeModule.registerHooks === "function"
|
|
130
139
|
&& nodeExecutable === process.execPath
|
|
131
|
-
&& !sourceUnderNodeModules;
|
|
140
|
+
&& !sourceUnderNodeModules();
|
|
132
141
|
}
|
|
133
142
|
export const DEFAULT_ASYNC_TIMEOUT_MS = 30 * 60 * 1000;
|
|
134
143
|
export function formatAsyncStartedMessage(headline, interactive) {
|
|
135
144
|
const guidance = interactive
|
|
136
145
|
? [
|
|
137
|
-
"
|
|
138
|
-
"
|
|
139
|
-
"Use bg_wait only for provider, detached, or other background work that lacks a native completion notification.",
|
|
140
|
-
"If the current turn must receive results from work without a native notification before it ends, call blocking bg_wait(); ordinary async subagent runs do not need a wait call because their completion is delivered natively.",
|
|
141
|
-
"Otherwise, continue any independent work or return control to the user. Use subagent({ action: \"status\", id: \"...\" }) for a one-shot status/result or to inspect a blocked/stale run, never as a wait loop.",
|
|
146
|
+
"Detached. Return control now: native completion wakes you, so do not sleep, poll, or call bg_wait for it.",
|
|
147
|
+
"One-shot check: subagent({ action: \"status\", id: \"...\" }).",
|
|
142
148
|
]
|
|
143
149
|
: [
|
|
144
|
-
"
|
|
145
|
-
"This is a non-interactive run: Pi auto-drains current-session subagent work at agent_end so detached children are not abandoned. Use bg_wait only when this turn must receive provider, detached, or other background-work results that have no native completion notification.",
|
|
146
|
-
"Use subagent({ action: \"status\", id: \"...\" }) when you need a one-shot status/result or to inspect a blocked/stale run; do not poll in a loop.",
|
|
150
|
+
"Detached non-interactive run: Pi auto-drains current-session subagent work at agent_end. Do not run sleep timers or polling loops. Use bg_wait only for results this turn needs from work without native notification, and subagent({ action: \"status\", id: \"...\" }) for a one-shot check.",
|
|
147
151
|
];
|
|
148
152
|
return [headline, "", ...guidance].join("\n");
|
|
149
153
|
}
|
|
@@ -191,7 +195,7 @@ function readRunnerStartup(startupPath, expectedState, expectedToken) {
|
|
|
191
195
|
if (typeof payload.token !== "string" || (expectedToken !== undefined && payload.token !== expectedToken)) {
|
|
192
196
|
return { ok: false, error: `Async runner wrote an invalid ${expectedState} startup handshake: ${startupPath}`, startupDidNotProceed: true };
|
|
193
197
|
}
|
|
194
|
-
return { ok: true, token: payload.token };
|
|
198
|
+
return { ok: true, token: payload.token, pid: payload.pid, pidNamespaceScope: payload.pidNamespaceScope };
|
|
195
199
|
}
|
|
196
200
|
catch (error) {
|
|
197
201
|
return { ok: false, error: `Failed to read async runner startup handshake '${startupPath}': ${error instanceof Error ? error.message : String(error)}`, startupDidNotProceed: true };
|
|
@@ -276,7 +280,7 @@ function terminateRunnerBeforeProceed(pid) {
|
|
|
276
280
|
}
|
|
277
281
|
return !runnerIsAlive(pid);
|
|
278
282
|
}
|
|
279
|
-
async function
|
|
283
|
+
async function terminateRunnerBeforeProceedAsyncDefault(proc, processClosed) {
|
|
280
284
|
for (const signal of ["SIGTERM", "SIGKILL"]) {
|
|
281
285
|
if (proc.pid === undefined || !runnerIsAlive(proc.pid))
|
|
282
286
|
return true;
|
|
@@ -293,9 +297,17 @@ async function terminateRunnerBeforeProceedAsync(proc, processClosed) {
|
|
|
293
297
|
}
|
|
294
298
|
return proc.pid === undefined || !runnerIsAlive(proc.pid);
|
|
295
299
|
}
|
|
296
|
-
async function completeRunnerStartupHandshake(startupPath, startupAckPath, startupConfirmPath, startupProceedPath, proc, processClosed, getObservedProcessExit, runnerProcessInstanceId, persistStartupFailure
|
|
300
|
+
async function completeRunnerStartupHandshake(startupPath, startupAckPath, startupConfirmPath, startupProceedPath, proc, processClosed, getObservedProcessExit, runnerProcessInstanceId, persistStartupFailure,
|
|
301
|
+
// Behind a launcher the spawned pid is only the wrapper's: adopt the runner-reported pid and never signal the wrapper.
|
|
302
|
+
launcherIdentity) {
|
|
303
|
+
const terminateRunnerBeforeProceedAsync = async (proc, processClosed) => launcherIdentity ? launcherIdentity.terminate() : terminateRunnerBeforeProceedAsyncDefault(proc, processClosed);
|
|
297
304
|
try {
|
|
298
305
|
const ready = await waitForRunnerStartup(startupPath, "ready", RUNNER_STARTUP_TIMEOUT_MS, undefined, processClosed);
|
|
306
|
+
const identityError = ready.ok && launcherIdentity ? launcherIdentity.adopt(ready.pid, ready.pidNamespaceScope) : undefined;
|
|
307
|
+
if (identityError) {
|
|
308
|
+
persistStartupFailure(identityError);
|
|
309
|
+
return { runnerProcessInstanceId, error: identityError, terminationObserved: await terminateRunnerBeforeProceedAsync(proc, processClosed), startupDidNotProceed: true };
|
|
310
|
+
}
|
|
299
311
|
if (ready.ok === false) {
|
|
300
312
|
persistStartupFailure(ready.error);
|
|
301
313
|
const terminationObserved = await terminateRunnerBeforeProceedAsync(proc, processClosed);
|
|
@@ -401,13 +413,13 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
|
|
|
401
413
|
const binaryHost = resolveBunPiExecutable();
|
|
402
414
|
const nodeExecutable = resolveNodeExecutable();
|
|
403
415
|
const nativeRunnerSupported = supportsNativeRunner(nodeExecutable);
|
|
404
|
-
const runner = asyncRunnerSourcePath;
|
|
416
|
+
const runner = asyncRunnerSourcePath();
|
|
405
417
|
const runnerIsJavaScript = path.extname(runner) === ".js";
|
|
406
|
-
const bootstrap =
|
|
418
|
+
const bootstrap = resolveRuntimeModulePath(path.dirname(runner), "binary-bootstrap");
|
|
407
419
|
if (binaryHost && !fs.existsSync(bootstrap))
|
|
408
420
|
return { error: `Background runner bootstrap not found: ${bootstrap}` };
|
|
409
421
|
if (!binaryHost && !runnerIsJavaScript && !nativeRunnerSupported && !jitiCliPath) {
|
|
410
|
-
return { error: sourceUnderNodeModules
|
|
422
|
+
return { error: sourceUnderNodeModules()
|
|
411
423
|
? "Background runner source is installed under node_modules, so upstream jiti is required for TypeScript execution."
|
|
412
424
|
: "Background runner requires enabled native TypeScript with synchronous module hooks, or installed upstream jiti for TypeScript execution." };
|
|
413
425
|
}
|
|
@@ -447,6 +459,30 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
|
|
|
447
459
|
fs.rmSync(startupConfirmPath, { force: true });
|
|
448
460
|
if (startupProceedPath)
|
|
449
461
|
fs.rmSync(startupProceedPath, { force: true });
|
|
462
|
+
// A broker launcher may start the runner outside its own process, so the spawned pid is only the
|
|
463
|
+
// wrapper's. The runner reports its own identity before it is allowed to proceed.
|
|
464
|
+
const launcher = launchConfig.launcher;
|
|
465
|
+
const identityPath = launcher && launchBarrierToken && launchAsyncDir ? path.join(launchAsyncDir, "runner-startup.json") : undefined;
|
|
466
|
+
if (identityPath)
|
|
467
|
+
fs.rmSync(identityPath, { force: true });
|
|
468
|
+
let runnerIdentity;
|
|
469
|
+
// Wrapper exit is not runner exit, so only a reported runner in this namespace may be signalled.
|
|
470
|
+
const terminateBeforeProceed = (pid) => !launcher
|
|
471
|
+
? terminateRunnerBeforeProceed(pid)
|
|
472
|
+
: runnerIdentity !== undefined && runnerIdentity.pidNamespaceScope === currentPidNamespaceScope() && terminateRunnerBeforeProceed(runnerIdentity.pid);
|
|
473
|
+
const adoptRunnerIdentity = (pid, pidNamespaceScope) => {
|
|
474
|
+
if (typeof pid !== "number" || !Number.isSafeInteger(pid) || pid < 1)
|
|
475
|
+
return `Async runner reported an invalid process identity in '${launchAsyncDir}'.`;
|
|
476
|
+
runnerIdentity = { pid, ...(typeof pidNamespaceScope === "string" ? { pidNamespaceScope } : {}) };
|
|
477
|
+
try {
|
|
478
|
+
const status = JSON.parse(fs.readFileSync(initialStatusPath, "utf-8"));
|
|
479
|
+
writePrivateAtomicJson(initialStatusPath, { ...status, pid, ...(runnerIdentity.pidNamespaceScope !== undefined ? { pidNamespaceScope: runnerIdentity.pidNamespaceScope } : {}) });
|
|
480
|
+
return undefined;
|
|
481
|
+
}
|
|
482
|
+
catch (error) {
|
|
483
|
+
return `Failed to record async runner identity: ${error instanceof Error ? error.message : String(error)}`;
|
|
484
|
+
}
|
|
485
|
+
};
|
|
450
486
|
const logPaths = resolveAsyncRunnerLogPaths(launchConfig);
|
|
451
487
|
let stdoutFd;
|
|
452
488
|
let stderrFd;
|
|
@@ -481,7 +517,8 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
|
|
|
481
517
|
delete runnerEnv[SUBAGENT_PARENT_SESSION_ENV];
|
|
482
518
|
else
|
|
483
519
|
runnerEnv[SUBAGENT_PARENT_SESSION_ENV] = launchParentSessionId;
|
|
484
|
-
const
|
|
520
|
+
const [spawnCommand, ...spawnArgs] = launcher ? [...launcher.argv, command, ...args] : [command, ...args];
|
|
521
|
+
const proc = spawn(spawnCommand, spawnArgs, {
|
|
485
522
|
cwd,
|
|
486
523
|
...backgroundProcessOptions(),
|
|
487
524
|
stdio: ["ignore", stdoutFd ?? "ignore", stderrFd ?? "ignore"],
|
|
@@ -507,6 +544,18 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
|
|
|
507
544
|
const runId = launch.id;
|
|
508
545
|
if (typeof asyncDir !== "string" || typeof runId !== "string")
|
|
509
546
|
return;
|
|
547
|
+
if (launcher) {
|
|
548
|
+
try {
|
|
549
|
+
writePrivateAtomicJson(path.join(asyncDir, "launcher-close.json"), { version: 1, runId, runnerProcessInstanceId, closeObservedAt: Date.now(), exitCode, signal, ...(runnerIdentity ? { runnerPid: runnerIdentity.pid } : {}) });
|
|
550
|
+
}
|
|
551
|
+
catch {
|
|
552
|
+
// Diagnostic only; process-terminal proof stays authoritative.
|
|
553
|
+
}
|
|
554
|
+
// The runner may outlive its wrapper; only a confirmed-dead runner in this pid namespace finalizes here,
|
|
555
|
+
// otherwise status-pid reconciliation does it later.
|
|
556
|
+
if (!runnerIdentity || runnerIdentity.pidNamespaceScope !== currentPidNamespaceScope() || checkPidLiveness(runnerIdentity.pid, process.kill, runnerIdentity.pidNamespaceScope !== undefined) !== "dead")
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
510
559
|
finalizeProcessTerminal(asyncDir, runId, {
|
|
511
560
|
processInstanceId: runnerProcessInstanceId,
|
|
512
561
|
closeObservedAt: Date.now(),
|
|
@@ -566,8 +615,7 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
|
|
|
566
615
|
try {
|
|
567
616
|
writePrivateAtomicJson(initialStatusPath, {
|
|
568
617
|
...initialStatus,
|
|
569
|
-
pid: proc.pid,
|
|
570
|
-
pidNamespaceScope: currentPidNamespaceScope(),
|
|
618
|
+
...(launcher ? {} : { pid: proc.pid, pidNamespaceScope: currentPidNamespaceScope() }),
|
|
571
619
|
processTerminal: { version: 1, state: "pending", runId: initialStatus.runId, runnerProcessInstanceId },
|
|
572
620
|
});
|
|
573
621
|
// Aggregate waits must see the launch before the runner's first status update.
|
|
@@ -577,7 +625,7 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
|
|
|
577
625
|
const message = `Failed to persist initial async status: ${error instanceof Error ? error.message : String(error)}`;
|
|
578
626
|
if (launchAsyncDir)
|
|
579
627
|
persistPreProceedStartupFailure(launchAsyncDir, launchRunId, runnerProcessInstanceId, launchSessionId, launchCompletionOwnerId, message);
|
|
580
|
-
const terminationObserved =
|
|
628
|
+
const terminationObserved = terminateBeforeProceed(proc.pid);
|
|
581
629
|
return { pid: proc.pid, runnerProcessInstanceId, error: message, terminationObserved, startupDidNotProceed: true };
|
|
582
630
|
}
|
|
583
631
|
try {
|
|
@@ -589,7 +637,7 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
|
|
|
589
637
|
const message = `Failed to establish async runner lifecycle sidecar: ${error instanceof Error ? error.message : String(error)}`;
|
|
590
638
|
if (launchAsyncDir)
|
|
591
639
|
persistPreProceedStartupFailure(launchAsyncDir, launchRunId, runnerProcessInstanceId, launchSessionId, launchCompletionOwnerId, message);
|
|
592
|
-
const terminationObserved =
|
|
640
|
+
const terminationObserved = terminateBeforeProceed(proc.pid);
|
|
593
641
|
return { pid: proc.pid, runnerProcessInstanceId, error: message, terminationObserved, startupDidNotProceed: true };
|
|
594
642
|
}
|
|
595
643
|
try {
|
|
@@ -599,9 +647,31 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
|
|
|
599
647
|
const message = `Failed to establish async runner capacity ownership: ${error instanceof Error ? error.message : String(error)}`;
|
|
600
648
|
if (launchAsyncDir)
|
|
601
649
|
persistPreProceedStartupFailure(launchAsyncDir, launchRunId, runnerProcessInstanceId, launchSessionId, launchCompletionOwnerId, message);
|
|
602
|
-
const terminationObserved =
|
|
650
|
+
const terminationObserved = terminateBeforeProceed(proc.pid);
|
|
603
651
|
return { pid: proc.pid, runnerProcessInstanceId, error: message, terminationObserved, startupDidNotProceed: true };
|
|
604
652
|
}
|
|
653
|
+
if (identityPath && launchBarrierToken && startupProceedPath) {
|
|
654
|
+
proc.unref();
|
|
655
|
+
const fail = (message) => {
|
|
656
|
+
if (launchAsyncDir)
|
|
657
|
+
persistPreProceedStartupFailure(launchAsyncDir, launchRunId, runnerProcessInstanceId, launchSessionId, launchCompletionOwnerId, message);
|
|
658
|
+
return { ...(runnerIdentity ? { pid: runnerIdentity.pid } : {}), runnerProcessInstanceId, error: message, terminationObserved: terminateBeforeProceed(proc.pid), startupDidNotProceed: true };
|
|
659
|
+
};
|
|
660
|
+
return waitForRunnerStartup(identityPath, "identified", RUNNER_STARTUP_TIMEOUT_MS, launchBarrierToken, processClosed).then((identified) => {
|
|
661
|
+
if (identified.ok === false)
|
|
662
|
+
return fail(identified.error);
|
|
663
|
+
const identityError = adoptRunnerIdentity(identified.pid, identified.pidNamespaceScope);
|
|
664
|
+
if (identityError)
|
|
665
|
+
return fail(identityError);
|
|
666
|
+
try {
|
|
667
|
+
writeRunnerStartupControl(startupProceedPath, { action: "proceed", token: launchBarrierToken });
|
|
668
|
+
}
|
|
669
|
+
catch (error) {
|
|
670
|
+
return fail(`Failed to authorize async runner startup: ${error instanceof Error ? error.message : String(error)}`);
|
|
671
|
+
}
|
|
672
|
+
return { pid: identified.pid, runnerProcessInstanceId };
|
|
673
|
+
});
|
|
674
|
+
}
|
|
605
675
|
if (launchBarrierToken && startupProceedPath) {
|
|
606
676
|
try {
|
|
607
677
|
writeRunnerStartupControl(startupProceedPath, { action: "proceed", token: launchBarrierToken });
|
|
@@ -610,7 +680,7 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
|
|
|
610
680
|
const message = `Failed to authorize async runner startup: ${error instanceof Error ? error.message : String(error)}`;
|
|
611
681
|
if (launchAsyncDir)
|
|
612
682
|
persistPreProceedStartupFailure(launchAsyncDir, launchRunId, runnerProcessInstanceId, launchSessionId, launchCompletionOwnerId, message);
|
|
613
|
-
const terminationObserved =
|
|
683
|
+
const terminationObserved = terminateBeforeProceed(proc.pid);
|
|
614
684
|
return { pid: proc.pid, runnerProcessInstanceId, error: message, terminationObserved, startupDidNotProceed: true };
|
|
615
685
|
}
|
|
616
686
|
}
|
|
@@ -620,7 +690,10 @@ function spawnRunner(cfg, suffix, cwd, initialStatus, initialStatusPath, launchP
|
|
|
620
690
|
if (launchAsyncDir)
|
|
621
691
|
persistPreProceedStartupFailure(launchAsyncDir, launchRunId, runnerProcessInstanceId, launchSessionId, launchCompletionOwnerId, message);
|
|
622
692
|
};
|
|
623
|
-
|
|
693
|
+
const handshake = completeRunnerStartupHandshake(startupPath, startupAckPath, startupConfirmPath, startupProceedPath, proc, processClosed, () => observedProcessExit ?? (proc.exitCode !== null || proc.signalCode !== null ? { exitCode: proc.exitCode, signal: proc.signalCode } : undefined), runnerProcessInstanceId, persistStartupFailure, launcher ? { adopt: adoptRunnerIdentity, terminate: () => terminateBeforeProceed(proc.pid) } : undefined);
|
|
694
|
+
if (!launcher)
|
|
695
|
+
return handshake;
|
|
696
|
+
return handshake.then(({ pid: _wrapperPid, ...result }) => ({ ...result, ...(runnerIdentity ? { pid: runnerIdentity.pid } : {}) }));
|
|
624
697
|
}
|
|
625
698
|
return { pid: proc.pid, runnerProcessInstanceId };
|
|
626
699
|
}
|
|
@@ -660,6 +733,14 @@ class AsyncStartValidationError extends Error {
|
|
|
660
733
|
}
|
|
661
734
|
export function buildAsyncRunnerSteps(id, params) {
|
|
662
735
|
const { chain, agents, ctx, cwd, sessionFilesByFlatIndex, thinkingOverridesByFlatIndex, maxSubagentDepth, worktreeBaseDir, worktreeProvider, worktreeBranchPrefix, asyncDir, } = params;
|
|
736
|
+
// One runner hosts every new step, so they share one launcher or none. Covers initial chains and
|
|
737
|
+
// appends to a running runner; the attached root runs in its own runner.
|
|
738
|
+
const stepLaunchers = [...new Set(chain.flatMap(getStepAgents))].map((name) => ({ name, launcher: agents.find((agent) => agent.name === name)?.launcher }));
|
|
739
|
+
const launcherNames = new Set(stepLaunchers.map(({ launcher }) => launcher));
|
|
740
|
+
if (launcherNames.size > 1) {
|
|
741
|
+
return { error: `Every agent in one background runner must use the same launcher or none: ${stepLaunchers.map(({ name, launcher }) => `${name} (${launcher ?? "none"})`).join(", ")}.` };
|
|
742
|
+
}
|
|
743
|
+
const launcher = [...launcherNames][0];
|
|
663
744
|
const launchParentSessionId = ctx.parentSessionId ?? ctx.currentSessionId;
|
|
664
745
|
const outputBaseDir = params.outputBaseDir;
|
|
665
746
|
const resultMode = params.resultMode ?? "chain";
|
|
@@ -742,6 +823,9 @@ export function buildAsyncRunnerSteps(id, params) {
|
|
|
742
823
|
const machineUnsupported = formatHerdrMachineRunnerUnsupported({ machine: requestedMachine, agentName: a.name, runnerType: a.runner?.type, adapter: a.runner?.type === "external-cli" ? a.runner.adapter : undefined, worktree: s.worktree });
|
|
743
824
|
if (machineUnsupported)
|
|
744
825
|
throw new AsyncStartValidationError(machineUnsupported);
|
|
826
|
+
const launcherError = runnerLauncherPlacementError(a, requestedMachine);
|
|
827
|
+
if (launcherError)
|
|
828
|
+
throw new AsyncStartValidationError(launcherError);
|
|
745
829
|
const registeredExtensions = resolveRequiredChildExtensions(ctx.parentSessionId ?? ctx.currentSessionId ?? undefined);
|
|
746
830
|
try {
|
|
747
831
|
assertRequiredChildExtensionsAdmitted([params.requiredExtensions, ctx.childRuntime?.requiredExtensions, registeredExtensions], { agent: a.name, runnerType: a.runner?.type, machine: requestedMachine });
|
|
@@ -917,6 +1001,7 @@ export function buildAsyncRunnerSteps(id, params) {
|
|
|
917
1001
|
}
|
|
918
1002
|
return {
|
|
919
1003
|
parentSessionId: launchParentSessionId,
|
|
1004
|
+
...(ctx.parentSessionFile ? { parentSessionFile: ctx.parentSessionFile } : {}),
|
|
920
1005
|
permissionRules,
|
|
921
1006
|
...(params.capabilityCeiling ? { capabilityCeiling: params.capabilityCeiling } : {}),
|
|
922
1007
|
...(runFanoutPath ? { runFanoutPath } : {}),
|
|
@@ -1092,6 +1177,7 @@ export function buildAsyncRunnerSteps(id, params) {
|
|
|
1092
1177
|
const steps = params.attachRoot
|
|
1093
1178
|
? [{
|
|
1094
1179
|
parentSessionId: launchParentSessionId,
|
|
1180
|
+
...(ctx.parentSessionFile ? { parentSessionFile: ctx.parentSessionFile } : {}),
|
|
1095
1181
|
agent: params.attachRoot.agent,
|
|
1096
1182
|
task: "",
|
|
1097
1183
|
label: params.attachRoot.label ?? `Attached root ${params.attachRoot.runId}`,
|
|
@@ -1122,7 +1208,7 @@ export function buildAsyncRunnerSteps(id, params) {
|
|
|
1122
1208
|
seen.set(task.outputPath, { index, agent: task.agent });
|
|
1123
1209
|
}
|
|
1124
1210
|
}
|
|
1125
|
-
return { steps: steps, runnerCwd, workflowGraph, eventChain: graphChain, ...(originalTask !== undefined ? { originalTask } : {}) };
|
|
1211
|
+
return { steps: steps, runnerCwd, workflowGraph, eventChain: graphChain, ...(originalTask !== undefined ? { originalTask } : {}), ...(launcher !== undefined ? { launcher } : {}) };
|
|
1126
1212
|
}
|
|
1127
1213
|
catch (error) {
|
|
1128
1214
|
if (error instanceof UnavailableSubagentSkillError || error instanceof AsyncStartValidationError)
|
|
@@ -1141,6 +1227,11 @@ export function executeAsyncChain(id, params) {
|
|
|
1141
1227
|
});
|
|
1142
1228
|
if (acceptanceErrors.length > 0)
|
|
1143
1229
|
return formatAsyncStartError(resultMode, acceptanceErrors.join(" "));
|
|
1230
|
+
// Refuse an undefined launcher before the run directory exists and before step building can write progress files.
|
|
1231
|
+
const undefinedLauncher = chain.flatMap(getStepAgents).map((name) => agents.find((agent) => agent.name === name)?.launcher)
|
|
1232
|
+
.find((name) => name !== undefined && !lookupRunnerLauncher(ctx.runnerLaunchers, name));
|
|
1233
|
+
if (undefinedLauncher !== undefined)
|
|
1234
|
+
return formatAsyncStartError(resultMode, `Launcher '${undefinedLauncher}' used by this ${resultMode} is not defined in runnerLaunchers in the user subagent config.`);
|
|
1144
1235
|
const capabilityCeiling = params.capabilityCeiling ?? resolveCurrentSubagentCapabilityCeiling(ctx.currentSessionId);
|
|
1145
1236
|
const inheritedNestedRoute = inheritedNestedRouteOf(ctx.childRuntime);
|
|
1146
1237
|
const nestedAddress = inheritedNestedRoute ? inheritedNestedParentAddressOf(ctx.childRuntime) : undefined;
|
|
@@ -1208,6 +1299,7 @@ export function executeAsyncChain(id, params) {
|
|
|
1208
1299
|
return formatAsyncStartError(resultMode, built.error);
|
|
1209
1300
|
}
|
|
1210
1301
|
const { steps, runnerCwd, workflowGraph, eventChain } = built;
|
|
1302
|
+
const launcher = built.launcher === undefined ? undefined : lookupRunnerLauncher(ctx.runnerLaunchers, built.launcher);
|
|
1211
1303
|
const deadlineAt = params.timeoutMs !== undefined ? Date.now() + params.timeoutMs : undefined;
|
|
1212
1304
|
const initialUsageBudget = usageBudgetState(params.usageBudget, undefined);
|
|
1213
1305
|
let childTargetIndex = 0;
|
|
@@ -1250,9 +1342,9 @@ export function executeAsyncChain(id, params) {
|
|
|
1250
1342
|
fs.rmSync(asyncDir, { recursive: true, force: true });
|
|
1251
1343
|
return formatAsyncStartError(resultMode, `Failed to record required child extensions: ${error instanceof Error ? error.message : String(error)}`);
|
|
1252
1344
|
}
|
|
1253
|
-
let
|
|
1345
|
+
let spawnResultOrPromise = {};
|
|
1254
1346
|
try {
|
|
1255
|
-
|
|
1347
|
+
spawnResultOrPromise = spawnRunner({
|
|
1256
1348
|
id,
|
|
1257
1349
|
steps,
|
|
1258
1350
|
resultPath: inheritedNestedRoute ? nestedResultsPath(inheritedNestedRoute.rootRunId, id) : resultFilePath(DIRS.results, id),
|
|
@@ -1298,6 +1390,7 @@ export function executeAsyncChain(id, params) {
|
|
|
1298
1390
|
depth: nestedAddress.depth,
|
|
1299
1391
|
path: nestedAddress.path,
|
|
1300
1392
|
} : undefined,
|
|
1393
|
+
...(launcher ? { launcher } : {}),
|
|
1301
1394
|
}, id, runnerCwd, {
|
|
1302
1395
|
lifecycleArtifactVersion: SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
|
|
1303
1396
|
runId: id,
|
|
@@ -1310,6 +1403,7 @@ export function executeAsyncChain(id, params) {
|
|
|
1310
1403
|
currentStep: 0,
|
|
1311
1404
|
chainStepCount: eventChain.length,
|
|
1312
1405
|
...(initialParallelGroups.length ? { parallelGroups: initialParallelGroups } : {}),
|
|
1406
|
+
...(launcher ? { launcher } : {}),
|
|
1313
1407
|
steps: initialStatusSteps,
|
|
1314
1408
|
}, path.join(asyncDir, "status.json"), launchParentSessionId, (proof) => emitProcessTerminalEvent(ctx, proof), (runnerProcessInstanceId) => params.activeAsyncCapacity?.markStarted(runnerProcessInstanceId));
|
|
1315
1409
|
}
|
|
@@ -1318,127 +1412,131 @@ export function executeAsyncChain(id, params) {
|
|
|
1318
1412
|
const message = error instanceof Error ? error.message : String(error);
|
|
1319
1413
|
return formatAsyncStartError(resultMode, `Failed to start async ${resultMode} '${id}': ${message}`);
|
|
1320
1414
|
}
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1415
|
+
// A launcher run's spawn resolves once the runner reports its identity.
|
|
1416
|
+
const finishSpawnResult = (spawnResult) => {
|
|
1417
|
+
if (spawnResult.error) {
|
|
1418
|
+
if (spawnResult.startupDidNotProceed) {
|
|
1419
|
+
if (!spawnResult.runnerProcessInstanceId || params.activeAsyncCapacity?.rollbackBeforeRunnerProceed(spawnResult.runnerProcessInstanceId) !== true)
|
|
1420
|
+
params.activeAsyncCapacity?.rollback();
|
|
1421
|
+
}
|
|
1422
|
+
else if (!spawnResult.pid || !spawnResult.runnerProcessInstanceId)
|
|
1324
1423
|
params.activeAsyncCapacity?.rollback();
|
|
1424
|
+
else
|
|
1425
|
+
params.activeAsyncCapacity?.markStarted(spawnResult.runnerProcessInstanceId);
|
|
1426
|
+
return formatAsyncStartError(resultMode, `Failed to start async ${resultMode} '${id}': ${spawnResult.error}`);
|
|
1325
1427
|
}
|
|
1326
|
-
|
|
1428
|
+
if (!spawnResult.pid || !spawnResult.runnerProcessInstanceId) {
|
|
1327
1429
|
params.activeAsyncCapacity?.rollback();
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
return formatAsyncStartError(resultMode, `Failed to start async ${resultMode} '${id}': runner identity unavailable`);
|
|
1335
|
-
}
|
|
1336
|
-
if (spawnResult.pid) {
|
|
1337
|
-
const eventFirstStep = eventChain[0];
|
|
1338
|
-
if (!eventFirstStep) {
|
|
1339
|
-
return formatAsyncStartError(resultMode, `Failed to start async ${resultMode} '${id}': event chain has no steps`);
|
|
1340
|
-
}
|
|
1341
|
-
const firstAgents = isParallelStep(eventFirstStep)
|
|
1342
|
-
? eventFirstStep.parallel.map((t) => t.agent)
|
|
1343
|
-
: isDynamicParallelStep(eventFirstStep)
|
|
1344
|
-
? [eventFirstStep.parallel.agent]
|
|
1345
|
-
: [eventFirstStep.agent];
|
|
1346
|
-
const firstTask = isParallelStep(eventFirstStep)
|
|
1347
|
-
? eventFirstStep.parallel[0]?.task
|
|
1348
|
-
: isDynamicParallelStep(eventFirstStep)
|
|
1349
|
-
? eventFirstStep.parallel.task
|
|
1350
|
-
: eventFirstStep.task;
|
|
1351
|
-
const workflowGoal = params.goal ?? (params.task?.trim() || firstTask);
|
|
1352
|
-
const parallelGroups = [];
|
|
1353
|
-
const flatAgents = [];
|
|
1354
|
-
let flatStepStart = 0;
|
|
1355
|
-
for (let stepIndex = 0; stepIndex < eventChain.length; stepIndex++) {
|
|
1356
|
-
const step = eventChain[stepIndex];
|
|
1357
|
-
if (isParallelStep(step)) {
|
|
1358
|
-
parallelGroups.push({ start: flatStepStart, count: step.parallel.length, stepIndex });
|
|
1359
|
-
flatAgents.push(...step.parallel.map((task) => task.agent));
|
|
1360
|
-
flatStepStart += step.parallel.length;
|
|
1361
|
-
}
|
|
1362
|
-
else if (isDynamicParallelStep(step)) {
|
|
1363
|
-
parallelGroups.push({ start: flatStepStart, count: 1, stepIndex });
|
|
1364
|
-
flatAgents.push(step.parallel.agent);
|
|
1365
|
-
flatStepStart++;
|
|
1430
|
+
return formatAsyncStartError(resultMode, `Failed to start async ${resultMode} '${id}': runner identity unavailable`);
|
|
1431
|
+
}
|
|
1432
|
+
if (spawnResult.pid) {
|
|
1433
|
+
const eventFirstStep = eventChain[0];
|
|
1434
|
+
if (!eventFirstStep) {
|
|
1435
|
+
return formatAsyncStartError(resultMode, `Failed to start async ${resultMode} '${id}': event chain has no steps`);
|
|
1366
1436
|
}
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1437
|
+
const firstAgents = isParallelStep(eventFirstStep)
|
|
1438
|
+
? eventFirstStep.parallel.map((t) => t.agent)
|
|
1439
|
+
: isDynamicParallelStep(eventFirstStep)
|
|
1440
|
+
? [eventFirstStep.parallel.agent]
|
|
1441
|
+
: [eventFirstStep.agent];
|
|
1442
|
+
const firstTask = isParallelStep(eventFirstStep)
|
|
1443
|
+
? eventFirstStep.parallel[0]?.task
|
|
1444
|
+
: isDynamicParallelStep(eventFirstStep)
|
|
1445
|
+
? eventFirstStep.parallel.task
|
|
1446
|
+
: eventFirstStep.task;
|
|
1447
|
+
const workflowGoal = params.goal ?? (params.task?.trim() || firstTask);
|
|
1448
|
+
const parallelGroups = [];
|
|
1449
|
+
const flatAgents = [];
|
|
1450
|
+
let flatStepStart = 0;
|
|
1451
|
+
for (let stepIndex = 0; stepIndex < eventChain.length; stepIndex++) {
|
|
1452
|
+
const step = eventChain[stepIndex];
|
|
1453
|
+
if (isParallelStep(step)) {
|
|
1454
|
+
parallelGroups.push({ start: flatStepStart, count: step.parallel.length, stepIndex });
|
|
1455
|
+
flatAgents.push(...step.parallel.map((task) => task.agent));
|
|
1456
|
+
flatStepStart += step.parallel.length;
|
|
1457
|
+
}
|
|
1458
|
+
else if (isDynamicParallelStep(step)) {
|
|
1459
|
+
parallelGroups.push({ start: flatStepStart, count: 1, stepIndex });
|
|
1460
|
+
flatAgents.push(step.parallel.agent);
|
|
1461
|
+
flatStepStart++;
|
|
1462
|
+
}
|
|
1463
|
+
else {
|
|
1464
|
+
flatAgents.push(step.agent);
|
|
1465
|
+
flatStepStart++;
|
|
1466
|
+
}
|
|
1370
1467
|
}
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
ts: now,
|
|
1378
|
-
parentRunId: nestedAddress.parentRunId,
|
|
1379
|
-
parentStepIndex: nestedAddress.parentStepIndex,
|
|
1380
|
-
child: {
|
|
1381
|
-
id,
|
|
1468
|
+
if (inheritedNestedRoute && nestedAddress) {
|
|
1469
|
+
const now = Date.now();
|
|
1470
|
+
try {
|
|
1471
|
+
writeNestedEvent(inheritedNestedRoute, {
|
|
1472
|
+
type: "subagent.nested.started",
|
|
1473
|
+
ts: now,
|
|
1382
1474
|
parentRunId: nestedAddress.parentRunId,
|
|
1383
1475
|
parentStepIndex: nestedAddress.parentStepIndex,
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1476
|
+
child: {
|
|
1477
|
+
id,
|
|
1478
|
+
parentRunId: nestedAddress.parentRunId,
|
|
1479
|
+
parentStepIndex: nestedAddress.parentStepIndex,
|
|
1480
|
+
depth: nestedAddress.depth,
|
|
1481
|
+
path: nestedAddress.path,
|
|
1482
|
+
asyncDir,
|
|
1483
|
+
pid: spawnResult.pid,
|
|
1484
|
+
ownerIntercomTarget: ctx.childRuntime?.intercomSessionName,
|
|
1485
|
+
leafIntercomTarget: childIntercomTargets?.[0],
|
|
1486
|
+
intercomTarget: childIntercomTargets?.[0],
|
|
1487
|
+
ownerState: "live",
|
|
1488
|
+
mode: resultMode,
|
|
1489
|
+
state: "running",
|
|
1490
|
+
agent: firstAgents[0],
|
|
1491
|
+
agents: flatAgents,
|
|
1492
|
+
chainStepCount: eventChain.length,
|
|
1493
|
+
parallelGroups,
|
|
1494
|
+
...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}),
|
|
1495
|
+
startedAt: now,
|
|
1496
|
+
lastUpdate: now,
|
|
1497
|
+
...(capabilityCeiling ? { capabilityCeiling } : {}),
|
|
1498
|
+
},
|
|
1499
|
+
});
|
|
1500
|
+
}
|
|
1501
|
+
catch (error) {
|
|
1502
|
+
console.error("Failed to emit nested async start event:", error);
|
|
1503
|
+
}
|
|
1407
1504
|
}
|
|
1505
|
+
ctx.pi.events.emit(SUBAGENT_ASYNC_STARTED_EVENT, {
|
|
1506
|
+
lifecycleArtifactVersion: SUBAGENT_LIFECYCLE_ARTIFACT_VERSION,
|
|
1507
|
+
id,
|
|
1508
|
+
pid: spawnResult.pid,
|
|
1509
|
+
sessionId: ctx.currentSessionId,
|
|
1510
|
+
completionOwnerId: ctx.completionOwnerId ?? currentCompletionOwnerId(),
|
|
1511
|
+
mode: resultMode,
|
|
1512
|
+
agent: firstAgents[0],
|
|
1513
|
+
agents: flatAgents,
|
|
1514
|
+
task: firstTask?.trim() ? PROMPT_REDACTED : undefined,
|
|
1515
|
+
goal: workflowGoal?.trim() ? PROMPT_REDACTED : undefined,
|
|
1516
|
+
chain: eventChain.map((s) => isParallelStep(s) ? `[${s.parallel.map((t) => t.agent).join("+")}]` : isDynamicParallelStep(s) ? `expand:${s.parallel.agent}` : s.agent),
|
|
1517
|
+
chainStepCount: eventChain.length,
|
|
1518
|
+
parallelGroups,
|
|
1519
|
+
workflowGraph,
|
|
1520
|
+
cwd: runnerCwd,
|
|
1521
|
+
asyncDir,
|
|
1522
|
+
...(sessionRoot ? { sessionRoot } : {}),
|
|
1523
|
+
...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}),
|
|
1524
|
+
...(initialUsageBudget ? { usageBudget: initialUsageBudget } : {}),
|
|
1525
|
+
...(capabilityCeiling ? { capabilityCeiling } : {}),
|
|
1526
|
+
...(params.parentWorkflowRunId ? { parentWorkflowRunId: params.parentWorkflowRunId } : {}),
|
|
1527
|
+
...(params.workflowKey ? { workflowKey: params.workflowKey } : {}),
|
|
1528
|
+
nestedRoute,
|
|
1529
|
+
});
|
|
1408
1530
|
}
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
agent: firstAgents[0],
|
|
1417
|
-
agents: flatAgents,
|
|
1418
|
-
task: firstTask?.trim() ? PROMPT_REDACTED : undefined,
|
|
1419
|
-
goal: workflowGoal?.trim() ? PROMPT_REDACTED : undefined,
|
|
1420
|
-
chain: eventChain.map((s) => isParallelStep(s) ? `[${s.parallel.map((t) => t.agent).join("+")}]` : isDynamicParallelStep(s) ? `expand:${s.parallel.agent}` : s.agent),
|
|
1421
|
-
chainStepCount: eventChain.length,
|
|
1422
|
-
parallelGroups,
|
|
1423
|
-
workflowGraph,
|
|
1424
|
-
cwd: runnerCwd,
|
|
1425
|
-
asyncDir,
|
|
1426
|
-
...(sessionRoot ? { sessionRoot } : {}),
|
|
1427
|
-
...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}),
|
|
1428
|
-
...(initialUsageBudget ? { usageBudget: initialUsageBudget } : {}),
|
|
1429
|
-
...(capabilityCeiling ? { capabilityCeiling } : {}),
|
|
1430
|
-
...(params.parentWorkflowRunId ? { parentWorkflowRunId: params.parentWorkflowRunId } : {}),
|
|
1431
|
-
...(params.workflowKey ? { workflowKey: params.workflowKey } : {}),
|
|
1432
|
-
nestedRoute,
|
|
1433
|
-
});
|
|
1434
|
-
}
|
|
1435
|
-
const chainDesc = chain
|
|
1436
|
-
.map((s) => isParallelStep(s) ? `[${s.parallel.map((t) => t.agent).join("+")}]` : isDynamicParallelStep(s) ? `expand:${s.parallel.agent}` : s.agent)
|
|
1437
|
-
.join(" -> ");
|
|
1438
|
-
return {
|
|
1439
|
-
content: [{ type: "text", text: formatAsyncStartedMessage(`Async ${resultMode}: ${chainDesc} [${id}]`, ctx.interactive === true) }],
|
|
1440
|
-
details: { mode: resultMode, runId: id, results: [], asyncId: id, asyncDir, workflowGraph, ...(capabilityCeiling ? { capabilityCeiling } : {}), ...(params.parentWorkflowRunId ? { parentWorkflowRunId: params.parentWorkflowRunId } : {}), ...(params.workflowKey ? { workflowKey: params.workflowKey } : {}), ...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}), ...(params.toolBudget ? { toolBudget: params.toolBudget } : {}), ...(initialUsageBudget ? { usageBudget: initialUsageBudget } : {}) },
|
|
1531
|
+
const chainDesc = chain
|
|
1532
|
+
.map((s) => isParallelStep(s) ? `[${s.parallel.map((t) => t.agent).join("+")}]` : isDynamicParallelStep(s) ? `expand:${s.parallel.agent}` : s.agent)
|
|
1533
|
+
.join(" -> ");
|
|
1534
|
+
return {
|
|
1535
|
+
content: [{ type: "text", text: formatAsyncStartedMessage(`Async ${resultMode}: ${chainDesc} [${id}]`, ctx.interactive === true) }],
|
|
1536
|
+
details: { mode: resultMode, runId: id, results: [], asyncId: id, asyncDir, workflowGraph, ...(capabilityCeiling ? { capabilityCeiling } : {}), ...(params.parentWorkflowRunId ? { parentWorkflowRunId: params.parentWorkflowRunId } : {}), ...(params.workflowKey ? { workflowKey: params.workflowKey } : {}), ...(params.timeoutMs !== undefined ? { timeoutMs: params.timeoutMs, deadlineAt } : {}), ...(params.toolBudget ? { toolBudget: params.toolBudget } : {}), ...(initialUsageBudget ? { usageBudget: initialUsageBudget } : {}) },
|
|
1537
|
+
};
|
|
1441
1538
|
};
|
|
1539
|
+
return spawnResultOrPromise instanceof Promise ? spawnResultOrPromise.then(finishSpawnResult) : finishSpawnResult(spawnResultOrPromise);
|
|
1442
1540
|
}
|
|
1443
1541
|
/**
|
|
1444
1542
|
* Execute a single agent asynchronously
|
|
@@ -1510,6 +1608,10 @@ export function executeAsyncSingle(id, params) {
|
|
|
1510
1608
|
const machineUnsupported = formatHerdrMachineRunnerUnsupported({ machine: requestedMachine, agentName: agentConfig.name, runnerType: agentConfig.runner?.type, adapter: agentConfig.runner?.type === "external-cli" ? agentConfig.runner.adapter : undefined, worktree: params.worktree });
|
|
1511
1609
|
if (machineUnsupported)
|
|
1512
1610
|
return formatAsyncStartError("single", machineUnsupported);
|
|
1611
|
+
const resolvedLauncher = resolveAgentRunnerLauncher(agentConfig, ctx.runnerLaunchers, requestedMachine);
|
|
1612
|
+
if (resolvedLauncher.error)
|
|
1613
|
+
return formatAsyncStartError("single", resolvedLauncher.error);
|
|
1614
|
+
const launcher = resolvedLauncher.launcher;
|
|
1513
1615
|
const registeredExtensions = resolveRequiredChildExtensions(ctx.parentSessionId ?? ctx.currentSessionId ?? undefined);
|
|
1514
1616
|
try {
|
|
1515
1617
|
assertRequiredChildExtensionsAdmitted([params.requiredExtensions, ctx.childRuntime?.requiredExtensions, registeredExtensions], { agent: agentConfig.name, runnerType: agentConfig.runner?.type, machine: requestedMachine });
|
|
@@ -1774,6 +1876,7 @@ export function executeAsyncSingle(id, params) {
|
|
|
1774
1876
|
...(params.context ? { context: params.context } : {}),
|
|
1775
1877
|
...(params.intercomBridge !== undefined ? { intercomBridge: params.intercomBridge } : {}),
|
|
1776
1878
|
...(params.baseRef !== undefined ? { baseRef: params.baseRef } : {}),
|
|
1879
|
+
...(launcher ? { launcher: launcher.name } : {}),
|
|
1777
1880
|
...(deadlineAt !== undefined ? { absoluteDeadlineAt: deadlineAt } : {}),
|
|
1778
1881
|
...(resolvedToolBudget.budget ? { initialToolBudget: resolvedToolBudget.budget } : {}),
|
|
1779
1882
|
maxSubagentDepth: resolveChildMaxSubagentDepth(maxSubagentDepth, recoveryAgentConfig.maxSubagentDepth),
|
|
@@ -1799,9 +1902,11 @@ export function executeAsyncSingle(id, params) {
|
|
|
1799
1902
|
try {
|
|
1800
1903
|
spawnResultOrPromise = spawnRunner({
|
|
1801
1904
|
id,
|
|
1905
|
+
...(params.toolCallId ? { toolCallId: params.toolCallId } : {}),
|
|
1802
1906
|
steps: [
|
|
1803
1907
|
{
|
|
1804
1908
|
parentSessionId: launchParentSessionId,
|
|
1909
|
+
...(ctx.parentSessionFile ? { parentSessionFile: ctx.parentSessionFile } : {}),
|
|
1805
1910
|
permissionRules,
|
|
1806
1911
|
...(capabilityCeiling ? { capabilityCeiling } : {}),
|
|
1807
1912
|
agent,
|
|
@@ -1904,6 +2009,7 @@ export function executeAsyncSingle(id, params) {
|
|
|
1904
2009
|
...(lane ? { lane } : {}),
|
|
1905
2010
|
...(params.revivalLease ? { revivalLease: params.revivalLease } : {}),
|
|
1906
2011
|
nestedRoute: nestedRoute ?? inheritedNestedRoute,
|
|
2012
|
+
...(launcher ? { launcher } : {}),
|
|
1907
2013
|
nestedSelf: inheritedNestedRoute && nestedAddress ? {
|
|
1908
2014
|
parentRunId: nestedAddress.parentRunId,
|
|
1909
2015
|
parentStepIndex: nestedAddress.parentStepIndex,
|
|
@@ -1916,12 +2022,14 @@ export function executeAsyncSingle(id, params) {
|
|
|
1916
2022
|
...(ctx.currentSessionId ? { sessionId: ctx.currentSessionId } : {}),
|
|
1917
2023
|
...(initialCompletionOwnerId ? { completionOwnerId: initialCompletionOwnerId } : {}),
|
|
1918
2024
|
mode: "single",
|
|
2025
|
+
...(params.toolCallId ? { toolCallId: params.toolCallId } : {}),
|
|
1919
2026
|
state: "running",
|
|
1920
2027
|
startedAt: initialStatusAt,
|
|
1921
2028
|
lastUpdate: initialStatusAt,
|
|
1922
2029
|
currentStep: 0,
|
|
1923
2030
|
chainStepCount: 1,
|
|
1924
2031
|
...(lane ? { lane } : {}),
|
|
2032
|
+
...(launcher ? { launcher } : {}),
|
|
1925
2033
|
steps: [{ agent, status: "pending", ...(lane ? { lane } : {}), ...(model ? { model } : {}), ...(contextLimit !== undefined ? { contextLimit } : {}) }],
|
|
1926
2034
|
}, path.join(asyncDir, "status.json"), launchParentSessionId, (proof) => emitProcessTerminalEvent(ctx, proof), (runnerProcessInstanceId) => params.activeAsyncCapacity?.markStarted(runnerProcessInstanceId), params.requestedCwd ?? runnerCwd);
|
|
1927
2035
|
}
|
|
@@ -1990,6 +2098,7 @@ export function executeAsyncSingle(id, params) {
|
|
|
1990
2098
|
sessionId: ctx.currentSessionId,
|
|
1991
2099
|
completionOwnerId: ctx.completionOwnerId ?? currentCompletionOwnerId(),
|
|
1992
2100
|
mode: "single",
|
|
2101
|
+
...(params.toolCallId ? { toolCallId: params.toolCallId } : {}),
|
|
1993
2102
|
agent,
|
|
1994
2103
|
task: task?.trim() ? PROMPT_REDACTED : undefined,
|
|
1995
2104
|
goal: (params.goal ?? task).trim() ? PROMPT_REDACTED : undefined,
|
|
@@ -2008,7 +2117,7 @@ export function executeAsyncSingle(id, params) {
|
|
|
2008
2117
|
}
|
|
2009
2118
|
return {
|
|
2010
2119
|
content: [{ type: "text", text: formatAsyncStartedMessage(`Async: ${agent} [${id}]`, ctx.interactive === true) }],
|
|
2011
|
-
details: { mode: "single", runId: id, results: [], asyncId: id, asyncDir, launchContractDigest, launchResolvedExtensions, ...(capabilityCeiling ? { capabilityCeiling } : {}), ...(params.context ? { context: params.context } : {}), ...(timeoutMs !== undefined ? { timeoutMs, deadlineAt } : {}), ...(params.toolBudget ? { toolBudget: resolvedToolBudget.budget ?? params.toolBudget } : {}), ...(initialUsageBudget ? { usageBudget: initialUsageBudget } : {}) },
|
|
2120
|
+
details: { mode: "single", runId: id, ...(params.toolCallId ? { toolCallId: params.toolCallId } : {}), results: [], asyncId: id, asyncDir, launchContractDigest, launchResolvedExtensions, ...(capabilityCeiling ? { capabilityCeiling } : {}), ...(params.context ? { context: params.context } : {}), ...(timeoutMs !== undefined ? { timeoutMs, deadlineAt } : {}), ...(params.toolBudget ? { toolBudget: resolvedToolBudget.budget ?? params.toolBudget } : {}), ...(initialUsageBudget ? { usageBudget: initialUsageBudget } : {}) },
|
|
2012
2121
|
};
|
|
2013
2122
|
};
|
|
2014
2123
|
return spawnResultOrPromise instanceof Promise ? spawnResultOrPromise.then(finishSpawnResult) : finishSpawnResult(spawnResultOrPromise);
|