@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
|
@@ -7,6 +7,7 @@ import * as path from "node:path";
|
|
|
7
7
|
import type { Message } from "@earendil-works/pi-ai";
|
|
8
8
|
import type { FSWatcher } from "node:fs";
|
|
9
9
|
import type { ExtensionContext } from "@selesai/code";
|
|
10
|
+
import type { ModelScopeConfig } from "../runs/shared/model-scope.ts";
|
|
10
11
|
|
|
11
12
|
// ============================================================================
|
|
12
13
|
// Basic Types
|
|
@@ -88,6 +89,47 @@ export interface Usage {
|
|
|
88
89
|
turns: number;
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
export interface TurnBudgetConfig {
|
|
93
|
+
maxTurns: number;
|
|
94
|
+
graceTurns?: number;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface ResolvedTurnBudget {
|
|
98
|
+
maxTurns: number;
|
|
99
|
+
graceTurns: number;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface ToolBudgetConfig {
|
|
103
|
+
soft?: number;
|
|
104
|
+
hard: number;
|
|
105
|
+
block?: string[] | "*";
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface ResolvedToolBudget {
|
|
109
|
+
soft?: number;
|
|
110
|
+
hard: number;
|
|
111
|
+
block: string[] | "*";
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export type ToolBudgetOutcome = "within-budget" | "soft-reached" | "hard-blocked";
|
|
115
|
+
|
|
116
|
+
export interface ToolBudgetState extends ResolvedToolBudget {
|
|
117
|
+
outcome: ToolBudgetOutcome;
|
|
118
|
+
toolCount: number;
|
|
119
|
+
softReachedAt?: number;
|
|
120
|
+
hardReachedAt?: number;
|
|
121
|
+
blockedTool?: string;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export type TurnBudgetOutcome = "within-budget" | "wrap-up-requested" | "exceeded";
|
|
125
|
+
|
|
126
|
+
export interface TurnBudgetState extends ResolvedTurnBudget {
|
|
127
|
+
outcome: TurnBudgetOutcome;
|
|
128
|
+
turnCount: number;
|
|
129
|
+
wrapUpRequestedAtTurn?: number;
|
|
130
|
+
exceededAtTurn?: number;
|
|
131
|
+
}
|
|
132
|
+
|
|
91
133
|
export interface TokenUsage {
|
|
92
134
|
input: number;
|
|
93
135
|
output: number;
|
|
@@ -120,6 +162,25 @@ export interface ResolvedControlConfig {
|
|
|
120
162
|
notifyChannels: ControlNotificationChannel[];
|
|
121
163
|
}
|
|
122
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Smart completion batching for async-completion notifications. Successful
|
|
167
|
+
* sibling completions are held briefly so they arrive as one grouped message;
|
|
168
|
+
* failure and attention signals bypass grouping and always fire immediately.
|
|
169
|
+
*/
|
|
170
|
+
export interface CompletionBatchConfig {
|
|
171
|
+
enabled?: boolean;
|
|
172
|
+
/** Idle window after each arrival; resets on every new item. */
|
|
173
|
+
debounceMs?: number;
|
|
174
|
+
/** Hard cap measured from the first item in a group. */
|
|
175
|
+
maxWaitMs?: number;
|
|
176
|
+
/** Shorter idle window for straggler groups. */
|
|
177
|
+
stragglerDebounceMs?: number;
|
|
178
|
+
/** Shorter hard cap for straggler groups. */
|
|
179
|
+
stragglerMaxWaitMs?: number;
|
|
180
|
+
/** Arrivals within this window after an emit join a straggler group. */
|
|
181
|
+
stragglerWindowMs?: number;
|
|
182
|
+
}
|
|
183
|
+
|
|
123
184
|
export interface ControlEvent {
|
|
124
185
|
type: ControlEventType;
|
|
125
186
|
from?: ActivityState;
|
|
@@ -144,17 +205,25 @@ export interface ControlEvent {
|
|
|
144
205
|
|
|
145
206
|
export type SubagentResultStatus = "completed" | "failed" | "paused" | "detached";
|
|
146
207
|
export type SubagentRunMode = "single" | "parallel" | "chain";
|
|
208
|
+
export const SUBAGENT_LIFECYCLE_ARTIFACT_VERSION = 1;
|
|
209
|
+
export type SubagentLifecycleArtifactVersion = typeof SUBAGENT_LIFECYCLE_ARTIFACT_VERSION;
|
|
147
210
|
|
|
148
211
|
export type PublicNestedStepSummary = Pick<
|
|
149
212
|
NestedStepSummary,
|
|
150
|
-
"agent" | "status" | "sessionFile" | "activityState" | "lastActivityAt" | "currentTool" | "currentToolStartedAt" | "currentPath" | "turnCount" | "toolCount" | "startedAt" | "endedAt" | "error"
|
|
213
|
+
"agent" | "status" | "sessionFile" | "transcriptPath" | "transcriptError" | "activityState" | "lastActivityAt" | "currentTool" | "currentToolStartedAt" | "currentPath" | "turnCount" | "toolCount" | "toolBudget" | "toolBudgetBlocked" | "startedAt" | "endedAt" | "error" | "timedOut"
|
|
151
214
|
> & {
|
|
152
215
|
children?: PublicNestedRunSummary[];
|
|
153
216
|
};
|
|
154
217
|
|
|
218
|
+
export type CostSummary = {
|
|
219
|
+
inputTokens: number;
|
|
220
|
+
outputTokens: number;
|
|
221
|
+
costUsd: number;
|
|
222
|
+
};
|
|
223
|
+
|
|
155
224
|
export type PublicNestedRunSummary = Pick<
|
|
156
225
|
NestedRunSummary,
|
|
157
|
-
"id" | "parentRunId" | "parentStepIndex" | "parentAgent" | "depth" | "path" | "asyncDir" | "sessionId" | "sessionFile" | "intercomTarget" | "ownerIntercomTarget" | "leafIntercomTarget" | "ownerState" | "mode" | "state" | "agent" | "agents" | "currentStep" | "chainStepCount" | "parallelGroups" | "activityState" | "lastActivityAt" | "currentTool" | "currentToolStartedAt" | "currentPath" | "turnCount" | "toolCount" | "totalTokens" | "startedAt" | "endedAt" | "lastUpdate" | "error"
|
|
226
|
+
"id" | "parentRunId" | "parentStepIndex" | "parentAgent" | "depth" | "path" | "asyncDir" | "sessionId" | "sessionFile" | "intercomTarget" | "ownerIntercomTarget" | "leafIntercomTarget" | "ownerState" | "mode" | "state" | "agent" | "agents" | "currentStep" | "chainStepCount" | "parallelGroups" | "activityState" | "lastActivityAt" | "currentTool" | "currentToolStartedAt" | "currentPath" | "turnCount" | "toolCount" | "toolBudget" | "toolBudgetBlocked" | "totalTokens" | "totalCost" | "startedAt" | "endedAt" | "lastUpdate" | "error" | "timeoutMs" | "deadlineAt" | "timedOut" | "turnBudget" | "turnBudgetExceeded" | "wrapUpRequested"
|
|
158
227
|
> & {
|
|
159
228
|
steps?: PublicNestedStepSummary[];
|
|
160
229
|
children?: PublicNestedRunSummary[];
|
|
@@ -392,6 +461,11 @@ export interface SingleResult {
|
|
|
392
461
|
detachedReason?: string;
|
|
393
462
|
interrupted?: boolean;
|
|
394
463
|
timedOut?: boolean;
|
|
464
|
+
turnBudget?: TurnBudgetState;
|
|
465
|
+
turnBudgetExceeded?: boolean;
|
|
466
|
+
wrapUpRequested?: boolean;
|
|
467
|
+
toolBudget?: ToolBudgetState;
|
|
468
|
+
toolBudgetBlocked?: boolean;
|
|
395
469
|
messages?: Message[];
|
|
396
470
|
usage: Usage;
|
|
397
471
|
model?: string;
|
|
@@ -416,6 +490,9 @@ export interface SingleResult {
|
|
|
416
490
|
structuredOutputPath?: string;
|
|
417
491
|
structuredOutputSchemaPath?: string;
|
|
418
492
|
acceptance?: AcceptanceLedger;
|
|
493
|
+
transcriptPath?: string;
|
|
494
|
+
transcriptError?: string;
|
|
495
|
+
children?: NestedRunSummary[];
|
|
419
496
|
}
|
|
420
497
|
|
|
421
498
|
export interface Details {
|
|
@@ -426,6 +503,11 @@ export interface Details {
|
|
|
426
503
|
controlEvents?: ControlEvent[];
|
|
427
504
|
asyncId?: string;
|
|
428
505
|
asyncDir?: string;
|
|
506
|
+
timeoutMs?: number;
|
|
507
|
+
deadlineAt?: number;
|
|
508
|
+
timedOut?: boolean;
|
|
509
|
+
turnBudget?: ResolvedTurnBudget;
|
|
510
|
+
toolBudget?: ResolvedToolBudget;
|
|
429
511
|
progress?: AgentProgress[];
|
|
430
512
|
progressSummary?: ProgressSummary;
|
|
431
513
|
artifacts?: {
|
|
@@ -444,6 +526,10 @@ export interface Details {
|
|
|
444
526
|
currentStepIndex?: number; // 0-indexed current step (for running chains)
|
|
445
527
|
workflowGraph?: WorkflowGraphSnapshot;
|
|
446
528
|
outputs?: ChainOutputMap;
|
|
529
|
+
// Aggregated child usage across all agents in the run
|
|
530
|
+
totalChildUsage?: Usage;
|
|
531
|
+
// Aggregated cost across all agents in the run
|
|
532
|
+
totalCost?: CostSummary;
|
|
447
533
|
}
|
|
448
534
|
|
|
449
535
|
// ============================================================================
|
|
@@ -454,6 +540,7 @@ export interface ArtifactPaths {
|
|
|
454
540
|
inputPath: string;
|
|
455
541
|
outputPath: string;
|
|
456
542
|
jsonlPath: string;
|
|
543
|
+
transcriptPath: string;
|
|
457
544
|
metadataPath: string;
|
|
458
545
|
}
|
|
459
546
|
|
|
@@ -462,6 +549,7 @@ export interface ArtifactConfig {
|
|
|
462
549
|
includeInput: boolean;
|
|
463
550
|
includeOutput: boolean;
|
|
464
551
|
includeJsonl: boolean;
|
|
552
|
+
includeTranscript?: boolean;
|
|
465
553
|
includeMetadata: boolean;
|
|
466
554
|
cleanupDays: number;
|
|
467
555
|
}
|
|
@@ -492,6 +580,8 @@ export interface NestedStepSummary {
|
|
|
492
580
|
agent: string;
|
|
493
581
|
status: "pending" | "running" | "complete" | "completed" | "failed" | "paused";
|
|
494
582
|
sessionFile?: string;
|
|
583
|
+
transcriptPath?: string;
|
|
584
|
+
transcriptError?: string;
|
|
495
585
|
activityState?: ActivityState;
|
|
496
586
|
lastActivityAt?: number;
|
|
497
587
|
currentTool?: string;
|
|
@@ -502,6 +592,12 @@ export interface NestedStepSummary {
|
|
|
502
592
|
startedAt?: number;
|
|
503
593
|
endedAt?: number;
|
|
504
594
|
error?: string;
|
|
595
|
+
timedOut?: boolean;
|
|
596
|
+
turnBudget?: TurnBudgetState;
|
|
597
|
+
turnBudgetExceeded?: boolean;
|
|
598
|
+
wrapUpRequested?: boolean;
|
|
599
|
+
toolBudget?: ToolBudgetState;
|
|
600
|
+
toolBudgetBlocked?: boolean;
|
|
505
601
|
children?: NestedRunSummary[];
|
|
506
602
|
}
|
|
507
603
|
|
|
@@ -533,9 +629,18 @@ export interface NestedRunSummary extends NestedRunAddress {
|
|
|
533
629
|
turnCount?: number;
|
|
534
630
|
toolCount?: number;
|
|
535
631
|
totalTokens?: TokenUsage;
|
|
632
|
+
totalCost?: CostSummary;
|
|
536
633
|
startedAt?: number;
|
|
537
634
|
endedAt?: number;
|
|
538
635
|
lastUpdate?: number;
|
|
636
|
+
timeoutMs?: number;
|
|
637
|
+
deadlineAt?: number;
|
|
638
|
+
timedOut?: boolean;
|
|
639
|
+
turnBudget?: TurnBudgetState;
|
|
640
|
+
turnBudgetExceeded?: boolean;
|
|
641
|
+
wrapUpRequested?: boolean;
|
|
642
|
+
toolBudget?: ToolBudgetState;
|
|
643
|
+
toolBudgetBlocked?: boolean;
|
|
539
644
|
error?: string;
|
|
540
645
|
}
|
|
541
646
|
|
|
@@ -547,6 +652,7 @@ export interface NestedRouteInfo {
|
|
|
547
652
|
}
|
|
548
653
|
|
|
549
654
|
export interface AsyncStartedEvent {
|
|
655
|
+
lifecycleArtifactVersion?: SubagentLifecycleArtifactVersion;
|
|
550
656
|
id?: string;
|
|
551
657
|
asyncDir?: string;
|
|
552
658
|
pid?: number;
|
|
@@ -558,14 +664,19 @@ export interface AsyncStartedEvent {
|
|
|
558
664
|
chainStepCount?: number;
|
|
559
665
|
parallelGroups?: AsyncParallelGroupStatus[];
|
|
560
666
|
workflowGraph?: WorkflowGraphSnapshot;
|
|
667
|
+
timeoutMs?: number;
|
|
668
|
+
deadlineAt?: number;
|
|
669
|
+
turnBudget?: TurnBudgetState;
|
|
561
670
|
nestedRoute?: NestedRouteInfo;
|
|
562
671
|
}
|
|
563
672
|
|
|
564
673
|
export interface AsyncStatus {
|
|
674
|
+
lifecycleArtifactVersion?: SubagentLifecycleArtifactVersion;
|
|
565
675
|
runId: string;
|
|
566
676
|
sessionId?: string;
|
|
567
677
|
mode: SubagentRunMode;
|
|
568
678
|
state: "queued" | "running" | "complete" | "failed" | "paused";
|
|
679
|
+
error?: string;
|
|
569
680
|
activityState?: ActivityState;
|
|
570
681
|
lastActivityAt?: number;
|
|
571
682
|
currentTool?: string;
|
|
@@ -573,9 +684,19 @@ export interface AsyncStatus {
|
|
|
573
684
|
currentPath?: string;
|
|
574
685
|
turnCount?: number;
|
|
575
686
|
toolCount?: number;
|
|
687
|
+
steerCount?: number;
|
|
688
|
+
lastSteerAt?: number;
|
|
576
689
|
startedAt: number;
|
|
577
690
|
endedAt?: number;
|
|
578
691
|
lastUpdate?: number;
|
|
692
|
+
timeoutMs?: number;
|
|
693
|
+
deadlineAt?: number;
|
|
694
|
+
timedOut?: boolean;
|
|
695
|
+
turnBudget?: TurnBudgetState;
|
|
696
|
+
turnBudgetExceeded?: boolean;
|
|
697
|
+
wrapUpRequested?: boolean;
|
|
698
|
+
toolBudget?: ToolBudgetState;
|
|
699
|
+
toolBudgetBlocked?: boolean;
|
|
579
700
|
pid?: number;
|
|
580
701
|
cwd?: string;
|
|
581
702
|
currentStep?: number;
|
|
@@ -592,6 +713,8 @@ export interface AsyncStatus {
|
|
|
592
713
|
status: "pending" | "running" | "complete" | "completed" | "failed" | "paused";
|
|
593
714
|
children?: NestedRunSummary[];
|
|
594
715
|
sessionFile?: string;
|
|
716
|
+
transcriptPath?: string;
|
|
717
|
+
transcriptError?: string;
|
|
595
718
|
activityState?: ActivityState;
|
|
596
719
|
lastActivityAt?: number;
|
|
597
720
|
currentTool?: string;
|
|
@@ -606,12 +729,21 @@ export interface AsyncStatus {
|
|
|
606
729
|
endedAt?: number;
|
|
607
730
|
durationMs?: number;
|
|
608
731
|
exitCode?: number | null;
|
|
732
|
+
timedOut?: boolean;
|
|
733
|
+
turnBudget?: TurnBudgetState;
|
|
734
|
+
turnBudgetExceeded?: boolean;
|
|
735
|
+
wrapUpRequested?: boolean;
|
|
736
|
+
toolBudget?: ToolBudgetState;
|
|
737
|
+
toolBudgetBlocked?: boolean;
|
|
609
738
|
tokens?: TokenUsage;
|
|
610
739
|
skills?: string[];
|
|
611
740
|
model?: string;
|
|
612
741
|
thinking?: string;
|
|
613
742
|
attemptedModels?: string[];
|
|
614
743
|
modelAttempts?: ModelAttempt[];
|
|
744
|
+
totalCost?: CostSummary;
|
|
745
|
+
steerCount?: number;
|
|
746
|
+
lastSteerAt?: number;
|
|
615
747
|
error?: string;
|
|
616
748
|
structuredOutput?: unknown;
|
|
617
749
|
structuredOutputPath?: string;
|
|
@@ -621,6 +753,7 @@ export interface AsyncStatus {
|
|
|
621
753
|
sessionDir?: string;
|
|
622
754
|
outputFile?: string;
|
|
623
755
|
totalTokens?: TokenUsage;
|
|
756
|
+
totalCost?: CostSummary;
|
|
624
757
|
sessionFile?: string;
|
|
625
758
|
outputs?: ChainOutputMap;
|
|
626
759
|
}
|
|
@@ -642,6 +775,8 @@ export interface AsyncJobState {
|
|
|
642
775
|
currentPath?: string;
|
|
643
776
|
turnCount?: number;
|
|
644
777
|
toolCount?: number;
|
|
778
|
+
steerCount?: number;
|
|
779
|
+
lastSteerAt?: number;
|
|
645
780
|
mode?: SubagentRunMode;
|
|
646
781
|
agents?: string[];
|
|
647
782
|
currentStep?: number;
|
|
@@ -655,6 +790,14 @@ export interface AsyncJobState {
|
|
|
655
790
|
activeParallelGroup?: boolean;
|
|
656
791
|
startedAt?: number;
|
|
657
792
|
updatedAt?: number;
|
|
793
|
+
timeoutMs?: number;
|
|
794
|
+
deadlineAt?: number;
|
|
795
|
+
timedOut?: boolean;
|
|
796
|
+
turnBudget?: TurnBudgetState;
|
|
797
|
+
turnBudgetExceeded?: boolean;
|
|
798
|
+
wrapUpRequested?: boolean;
|
|
799
|
+
toolBudget?: ToolBudgetState;
|
|
800
|
+
toolBudgetBlocked?: boolean;
|
|
658
801
|
sessionDir?: string;
|
|
659
802
|
outputFile?: string;
|
|
660
803
|
totalTokens?: TokenUsage;
|
|
@@ -669,6 +812,13 @@ export interface ForegroundResumeChild {
|
|
|
669
812
|
index: number;
|
|
670
813
|
sessionFile?: string;
|
|
671
814
|
status: SubagentResultStatus;
|
|
815
|
+
exitCode?: number;
|
|
816
|
+
finalOutput?: string;
|
|
817
|
+
artifactPaths?: ArtifactPaths;
|
|
818
|
+
transcriptPath?: string;
|
|
819
|
+
transcriptError?: string;
|
|
820
|
+
detachedReason?: string;
|
|
821
|
+
updatedAt?: number;
|
|
672
822
|
}
|
|
673
823
|
|
|
674
824
|
export interface ForegroundResumeRun {
|
|
@@ -683,6 +833,7 @@ export interface SubagentState {
|
|
|
683
833
|
baseCwd: string;
|
|
684
834
|
currentSessionId: string | null;
|
|
685
835
|
subagentInProgress?: boolean;
|
|
836
|
+
subagentSpawns?: { sessionId: string | null; count: number };
|
|
686
837
|
asyncJobs: Map<string, AsyncJobState>;
|
|
687
838
|
foregroundRuns?: Map<string, ForegroundResumeRun>;
|
|
688
839
|
foregroundControls: Map<string, {
|
|
@@ -763,10 +914,13 @@ export interface RunSyncOptions {
|
|
|
763
914
|
interruptSignal?: AbortSignal;
|
|
764
915
|
timeoutMs?: number;
|
|
765
916
|
deadlineAt?: number;
|
|
917
|
+
turnBudget?: ResolvedTurnBudget;
|
|
918
|
+
toolBudget?: ResolvedToolBudget;
|
|
766
919
|
allowIntercomDetach?: boolean;
|
|
767
920
|
intercomEvents?: IntercomEventBus;
|
|
768
921
|
onUpdate?: (r: import("@earendil-works/pi-agent-core").AgentToolResult<Details>) => void;
|
|
769
922
|
onControlEvent?: (event: ControlEvent) => void;
|
|
923
|
+
onDetachedExit?: (result: SingleResult) => void;
|
|
770
924
|
controlConfig?: ResolvedControlConfig;
|
|
771
925
|
intercomSessionName?: string;
|
|
772
926
|
orchestratorIntercomTarget?: string;
|
|
@@ -784,10 +938,14 @@ export interface RunSyncOptions {
|
|
|
784
938
|
nestedRoute?: NestedRouteInfo;
|
|
785
939
|
/** Override the agent's default model (format: "provider/id" or just "id") */
|
|
786
940
|
modelOverride?: string;
|
|
941
|
+
/** Override the agent's default thinking level for this run */
|
|
942
|
+
thinkingOverride?: AgentConfig["thinking"];
|
|
787
943
|
/** Registry models available for heuristic bare-model resolution */
|
|
788
944
|
availableModels?: Array<{ provider: string; id: string; fullId: string }>;
|
|
789
945
|
/** Current parent-session provider to prefer for ambiguous bare model ids */
|
|
790
946
|
preferredModelProvider?: string;
|
|
947
|
+
/** Optional subagent model-scope enforcement for fallback candidates */
|
|
948
|
+
modelScope?: ModelScopeConfig;
|
|
791
949
|
/** Skills to make available (overrides agent default if provided) */
|
|
792
950
|
skills?: string[];
|
|
793
951
|
structuredOutput?: {
|
|
@@ -829,18 +987,37 @@ export interface ProactiveSkillSubagentsConfig {
|
|
|
829
987
|
preferredAgent?: string;
|
|
830
988
|
}
|
|
831
989
|
|
|
990
|
+
export type ToolDescriptionMode = "full" | "compact" | "custom";
|
|
991
|
+
|
|
992
|
+
export interface ScheduledRunsConfig {
|
|
993
|
+
enabled?: boolean;
|
|
994
|
+
maxLatenessMs?: number;
|
|
995
|
+
maxPending?: number;
|
|
996
|
+
}
|
|
997
|
+
|
|
832
998
|
export interface ExtensionConfig {
|
|
833
999
|
asyncByDefault?: boolean;
|
|
1000
|
+
/** Tool description variant registered for the parent-facing subagent tool. Defaults to full. */
|
|
1001
|
+
toolDescriptionMode?: ToolDescriptionMode;
|
|
834
1002
|
forceTopLevelAsync?: boolean;
|
|
835
1003
|
defaultSessionDir?: string;
|
|
1004
|
+
singleRunOutputBaseDir?: string;
|
|
836
1005
|
maxSubagentDepth?: number;
|
|
1006
|
+
maxSubagentSpawnsPerSession?: number;
|
|
1007
|
+
/** Global cap on simultaneously-running subagent tasks within a single run. Defaults to 20. */
|
|
1008
|
+
globalConcurrencyLimit?: number;
|
|
837
1009
|
control?: ControlConfig;
|
|
1010
|
+
completionBatch?: CompletionBatchConfig;
|
|
1011
|
+
turnBudget?: TurnBudgetConfig;
|
|
1012
|
+
toolBudget?: ToolBudgetConfig;
|
|
838
1013
|
parallel?: TopLevelParallelConfig;
|
|
839
1014
|
chain?: ExtensionChainConfig;
|
|
840
1015
|
worktreeSetupHook?: string;
|
|
841
1016
|
worktreeSetupHookTimeoutMs?: number;
|
|
1017
|
+
worktreeBaseDir?: string;
|
|
842
1018
|
intercomBridge?: IntercomBridgeConfig;
|
|
843
1019
|
proactiveSkillSubagents?: ProactiveSkillSubagentsConfig | false;
|
|
1020
|
+
scheduledRuns?: ScheduledRunsConfig;
|
|
844
1021
|
}
|
|
845
1022
|
|
|
846
1023
|
// ============================================================================
|
|
@@ -857,6 +1034,7 @@ export const DEFAULT_ARTIFACT_CONFIG: ArtifactConfig = {
|
|
|
857
1034
|
includeInput: true,
|
|
858
1035
|
includeOutput: true,
|
|
859
1036
|
includeJsonl: false,
|
|
1037
|
+
includeTranscript: true,
|
|
860
1038
|
includeMetadata: true,
|
|
861
1039
|
cleanupDays: 7,
|
|
862
1040
|
};
|
|
@@ -932,7 +1110,8 @@ export const SLASH_SUBAGENT_CANCEL_EVENT = "subagent:slash:cancel";
|
|
|
932
1110
|
export const POLL_INTERVAL_MS = 250;
|
|
933
1111
|
export const MAX_WIDGET_JOBS = 4;
|
|
934
1112
|
export const DEFAULT_SUBAGENT_MAX_DEPTH = 2;
|
|
935
|
-
export const
|
|
1113
|
+
export const DEFAULT_MAX_SUBAGENT_SPAWNS_PER_SESSION = 40;
|
|
1114
|
+
export const SUBAGENT_ACTIONS = ["list", "get", "models", "create", "update", "delete", "eject", "disable", "enable", "reset", "status", "interrupt", "resume", "steer", "append-step", "doctor", "schedule", "schedule-list", "schedule-status", "schedule-cancel"] as const;
|
|
936
1115
|
|
|
937
1116
|
export const DEFAULT_FORK_PREAMBLE =
|
|
938
1117
|
"You are a delegated subagent running from a fork of the parent session. " +
|
|
@@ -975,12 +1154,16 @@ export function wrapForkTask(task: string, preamble?: string | false): string {
|
|
|
975
1154
|
// Recursion Depth Guard
|
|
976
1155
|
// ============================================================================
|
|
977
1156
|
|
|
978
|
-
|
|
1157
|
+
function normalizeNonNegativeInteger(value: unknown): number | undefined {
|
|
979
1158
|
const parsed = typeof value === "number" ? value : typeof value === "string" ? Number(value) : NaN;
|
|
980
1159
|
if (!Number.isInteger(parsed) || parsed < 0) return undefined;
|
|
981
1160
|
return parsed;
|
|
982
1161
|
}
|
|
983
1162
|
|
|
1163
|
+
export function normalizeMaxSubagentDepth(value: unknown): number | undefined {
|
|
1164
|
+
return normalizeNonNegativeInteger(value);
|
|
1165
|
+
}
|
|
1166
|
+
|
|
984
1167
|
export function resolveCurrentMaxSubagentDepth(configMaxDepth?: number): number {
|
|
985
1168
|
return normalizeMaxSubagentDepth(process.env.SELESAI_SUBAGENT_MAX_DEPTH)
|
|
986
1169
|
?? normalizeMaxSubagentDepth(configMaxDepth)
|
|
@@ -1009,6 +1192,16 @@ export function getSubagentDepthEnv(maxDepth?: number): Record<string, string> {
|
|
|
1009
1192
|
};
|
|
1010
1193
|
}
|
|
1011
1194
|
|
|
1195
|
+
export function normalizeMaxSubagentSpawnsPerSession(value: unknown): number | undefined {
|
|
1196
|
+
return normalizeNonNegativeInteger(value);
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
export function resolveMaxSubagentSpawnsPerSession(configMaxSpawns?: number): number {
|
|
1200
|
+
return normalizeMaxSubagentSpawnsPerSession(process.env.SELESAI_SUBAGENT_MAX_SPAWNS_PER_SESSION)
|
|
1201
|
+
?? normalizeMaxSubagentSpawnsPerSession(configMaxSpawns)
|
|
1202
|
+
?? DEFAULT_MAX_SUBAGENT_SPAWNS_PER_SESSION;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1012
1205
|
// ============================================================================
|
|
1013
1206
|
// Utility Functions
|
|
1014
1207
|
// ============================================================================
|
|
@@ -5,22 +5,61 @@
|
|
|
5
5
|
import * as fs from "node:fs";
|
|
6
6
|
import * as os from "node:os";
|
|
7
7
|
import * as path from "node:path";
|
|
8
|
-
import * as piCodingAgent from "@selesai/code";
|
|
9
8
|
import type { Message } from "@earendil-works/pi-ai";
|
|
9
|
+
import { stripThinkingTagsFromText } from "../../../../utils/thinking-tags.js"; // ponytail: .js not .ts — extension .ts is copied verbatim into dist/, only compiled .js exists there
|
|
10
10
|
import { formatToolCall } from "./formatters.ts";
|
|
11
|
-
import type { AgentProgress, AsyncStatus, Details, DisplayItem, ErrorInfo, SingleResult, ToolCallSummary } from "./types.ts";
|
|
11
|
+
import type { AgentProgress, AsyncStatus, Details, DisplayItem, ErrorInfo, NestedRunSummary, SingleResult, ToolCallSummary, Usage } from "./types.ts";
|
|
12
12
|
|
|
13
13
|
// ============================================================================
|
|
14
14
|
// File System Utilities
|
|
15
15
|
// ============================================================================
|
|
16
16
|
|
|
17
17
|
const DEFAULT_CONFIG_DIR_NAME = ".selesai";
|
|
18
|
+
const SELESAI_CODING_AGENT_PACKAGE_NAME = "@selesai/code";
|
|
19
|
+
export const SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV = "SELESAI_SUBAGENTS_SELESAI_PACKAGE_ROOT";
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
function validConfigDirName(value: unknown): string | undefined {
|
|
22
|
+
return typeof value === "string" && value.trim() ? value : undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function readConfigDirNameFromPackageRoot(packageRoot: string | undefined): string | undefined {
|
|
26
|
+
if (!packageRoot) return undefined;
|
|
27
|
+
try {
|
|
28
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf-8")) as {
|
|
29
|
+
name?: unknown;
|
|
30
|
+
piConfig?: { configDir?: unknown };
|
|
31
|
+
};
|
|
32
|
+
if (pkg.name !== SELESAI_CODING_AGENT_PACKAGE_NAME) return undefined;
|
|
33
|
+
return validConfigDirName(pkg.piConfig?.configDir);
|
|
34
|
+
} catch {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function resolveConfigDirNameFromPackageJson(entryPoint = process.argv[1], packageRoot = process.env[SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV]): string | undefined {
|
|
40
|
+
const packageRootValue = readConfigDirNameFromPackageRoot(packageRoot);
|
|
41
|
+
if (packageRootValue) return packageRootValue;
|
|
42
|
+
if (!entryPoint) return undefined;
|
|
43
|
+
try {
|
|
44
|
+
let dir = path.dirname(fs.realpathSync(entryPoint));
|
|
45
|
+
while (dir !== path.dirname(dir)) {
|
|
46
|
+
const value = readConfigDirNameFromPackageRoot(dir);
|
|
47
|
+
if (value) return value;
|
|
48
|
+
dir = path.dirname(dir);
|
|
49
|
+
}
|
|
50
|
+
} catch {
|
|
51
|
+
// Package metadata lookup is best-effort; detached runners must not fail here.
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function resolveConfigDirName(codingAgentModule?: unknown, entryPoint?: string, packageRoot?: string): string {
|
|
57
|
+
const moduleValue = codingAgentModule && typeof codingAgentModule === "object"
|
|
58
|
+
? validConfigDirName((codingAgentModule as { CONFIG_DIR_NAME?: unknown }).CONFIG_DIR_NAME)
|
|
22
59
|
: undefined;
|
|
23
|
-
return
|
|
60
|
+
return moduleValue
|
|
61
|
+
?? resolveConfigDirNameFromPackageJson(entryPoint, packageRoot)
|
|
62
|
+
?? DEFAULT_CONFIG_DIR_NAME;
|
|
24
63
|
}
|
|
25
64
|
|
|
26
65
|
export function getConfigDirName(): string {
|
|
@@ -204,19 +243,28 @@ function writePrompt(agent: string, prompt: string): { dir: string; path: string
|
|
|
204
243
|
* Get the final text output from a list of messages
|
|
205
244
|
*/
|
|
206
245
|
export function getFinalOutput(messages: Message[]): string {
|
|
246
|
+
const validTextParts: string[] = [];
|
|
207
247
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
208
248
|
const msg = messages[i];
|
|
209
|
-
if (msg.role
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
249
|
+
if (msg.role !== "assistant") continue;
|
|
250
|
+
const hasAssistantError = ("errorMessage" in msg && typeof msg.errorMessage === "string" && msg.errorMessage.length > 0)
|
|
251
|
+
|| ("stopReason" in msg && msg.stopReason === "error");
|
|
252
|
+
if (hasAssistantError) continue;
|
|
253
|
+
for (let j = msg.content.length - 1; j >= 0; j--) {
|
|
254
|
+
const part = msg.content[j];
|
|
255
|
+
if (part.type !== "text" || part.text.trim().length === 0) continue;
|
|
256
|
+
validTextParts.push(part.text);
|
|
257
|
+
if (/```acceptance-report\s*\n[\s\S]*?```/i.test(part.text)) return part.text;
|
|
258
|
+
for (const match of part.text.matchAll(/```(?:json|jsonc|json5)\s*\n([\s\S]*?)```/gi)) {
|
|
259
|
+
const body = match[1] ?? "";
|
|
260
|
+
if (/"criteriaSatisfied"/.test(body) && /"(?:changedFiles|testsAddedOrUpdated|commandsRun|validationOutput|residualRisks|noStagedFiles|diffSummary|reviewFindings|manualNotes)"/.test(body)) {
|
|
261
|
+
return part.text;
|
|
262
|
+
}
|
|
216
263
|
}
|
|
264
|
+
if (/ACCEPTANCE_REPORT\s*:/i.test(part.text)) return part.text;
|
|
217
265
|
}
|
|
218
266
|
}
|
|
219
|
-
return "";
|
|
267
|
+
return validTextParts[0] ?? "";
|
|
220
268
|
}
|
|
221
269
|
|
|
222
270
|
export function getSingleResultOutput(result: Pick<SingleResult, "finalOutput" | "messages">): string {
|
|
@@ -278,6 +326,44 @@ function extractToolCallSummaries(messages: Message[] | undefined): ToolCallSumm
|
|
|
278
326
|
return summaries;
|
|
279
327
|
}
|
|
280
328
|
|
|
329
|
+
export function sumResultsUsage(results: SingleResult[]): Usage {
|
|
330
|
+
const usage: Usage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 };
|
|
331
|
+
for (const result of results) {
|
|
332
|
+
usage.input += result.usage.input;
|
|
333
|
+
usage.output += result.usage.output;
|
|
334
|
+
usage.cacheRead += result.usage.cacheRead;
|
|
335
|
+
usage.cacheWrite += result.usage.cacheWrite;
|
|
336
|
+
usage.cost += result.usage.cost;
|
|
337
|
+
usage.turns += result.usage.turns;
|
|
338
|
+
}
|
|
339
|
+
return usage;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function addNestedCost(total: NonNullable<Details["totalCost"]>, children: NestedRunSummary[] | undefined): void {
|
|
343
|
+
for (const child of children ?? []) {
|
|
344
|
+
if (child.totalCost) {
|
|
345
|
+
total.inputTokens += child.totalCost.inputTokens;
|
|
346
|
+
total.outputTokens += child.totalCost.outputTokens;
|
|
347
|
+
total.costUsd += child.totalCost.costUsd;
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
addNestedCost(total, child.children);
|
|
351
|
+
for (const step of child.steps ?? []) addNestedCost(total, step.children);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/** Sum input tokens, output tokens, and cost across a set of SingleResults. */
|
|
356
|
+
export function sumResultsCost(results: SingleResult[]): NonNullable<Details["totalCost"]> {
|
|
357
|
+
const total = { inputTokens: 0, outputTokens: 0, costUsd: 0 };
|
|
358
|
+
for (const result of results) {
|
|
359
|
+
total.inputTokens += result.usage.input;
|
|
360
|
+
total.outputTokens += result.usage.output;
|
|
361
|
+
total.costUsd += result.usage.cost;
|
|
362
|
+
addNestedCost(total, result.children);
|
|
363
|
+
}
|
|
364
|
+
return total;
|
|
365
|
+
}
|
|
366
|
+
|
|
281
367
|
export function compactForegroundResult(result: SingleResult): SingleResult {
|
|
282
368
|
if (result.progress?.status === "running") return result;
|
|
283
369
|
const toolCalls = result.toolCalls?.length ? result.toolCalls : extractToolCallSummaries(result.messages);
|
|
@@ -438,7 +524,7 @@ export function extractToolArgsPreview(args: Record<string, unknown>): string {
|
|
|
438
524
|
export function extractTextFromContent(content: unknown): string {
|
|
439
525
|
if (!content) return "";
|
|
440
526
|
// Handle string content directly
|
|
441
|
-
if (typeof content === "string") return content;
|
|
527
|
+
if (typeof content === "string") return stripThinkingTagsFromText(content);
|
|
442
528
|
// Handle array content
|
|
443
529
|
if (!Array.isArray(content)) return "";
|
|
444
530
|
const texts: string[] = [];
|
|
@@ -446,7 +532,11 @@ export function extractTextFromContent(content: unknown): string {
|
|
|
446
532
|
if (part && typeof part === "object") {
|
|
447
533
|
// Handle { type: "text", text: "..." }
|
|
448
534
|
if ("type" in part && part.type === "text" && "text" in part) {
|
|
449
|
-
|
|
535
|
+
const text = stripThinkingTagsFromText(String(part.text));
|
|
536
|
+
if (text) texts.push(text);
|
|
537
|
+
}
|
|
538
|
+
else if ("type" in part && part.type === "thinking") {
|
|
539
|
+
continue;
|
|
450
540
|
}
|
|
451
541
|
// Handle { type: "tool_result", content: "..." }
|
|
452
542
|
else if ("type" in part && part.type === "tool_result" && "content" in part) {
|
|
@@ -455,7 +545,8 @@ export function extractTextFromContent(content: unknown): string {
|
|
|
455
545
|
}
|
|
456
546
|
// Handle { text: "..." } without type
|
|
457
547
|
else if ("text" in part) {
|
|
458
|
-
|
|
548
|
+
const text = stripThinkingTagsFromText(String(part.text));
|
|
549
|
+
if (text) texts.push(text);
|
|
459
550
|
}
|
|
460
551
|
}
|
|
461
552
|
}
|