@selesai/code 0.8.4 → 0.8.5
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 +10 -0
- package/README.md +7 -1
- package/dist/core/slash-commands.js +1 -0
- package/dist/defaults/models.json +41 -55
- package/dist/defaults/settings.json +7 -8
- package/dist/extensions/pi-subagents/CHANGELOG.md +26 -3
- package/dist/extensions/pi-subagents/README.md +2 -0
- package/dist/extensions/pi-subagents/docs/configuration.md +46 -2
- package/dist/extensions/pi-subagents/docs/observability.md +1 -1
- package/dist/extensions/pi-subagents/docs/tool-reference.md +1 -1
- package/dist/extensions/pi-subagents/package-lock.json +2 -2
- package/dist/extensions/pi-subagents/package.json +1 -1
- package/dist/extensions/pi-subagents/src/agents/agents.ts +9 -3
- package/dist/extensions/pi-subagents/src/extension/config.ts +6 -0
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +40 -0
- package/dist/extensions/pi-subagents/src/extension/index.ts +21 -0
- package/dist/extensions/pi-subagents/src/extension/public-execution.ts +5 -0
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +3 -9
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +2 -2
- package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +4 -1
- package/dist/extensions/pi-subagents/src/missions/lifecycle.ts +4 -7
- package/dist/extensions/pi-subagents/src/missions/store.ts +4 -4
- package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +6 -2
- package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +374 -0
- package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +9 -5
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +117 -29
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +7 -1
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +11 -5
- package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +33 -15
- package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +104 -0
- package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +17 -3
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +5 -1
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -3
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +84 -36
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +37 -2
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +135 -22
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +12 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +171 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +614 -187
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +13 -4
- package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +286 -0
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +23 -0
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +44 -1
- package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +280 -0
- package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +4 -2
- package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +19 -3
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +17 -5
- package/dist/extensions/pi-subagents/src/shared/types.ts +92 -0
- package/dist/extensions/pi-subagents/src/shared/utils.ts +3 -1
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +7 -5
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +225 -12
- package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +22 -5
- package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +87 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +96 -6
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +28 -5
- package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +8 -5
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +83 -2
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +211 -15
- package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +41 -3
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +314 -10
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +31 -1
- package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +317 -0
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +21 -2
- package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +16 -1
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +6 -1
- package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +75 -4
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +18 -0
- package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +29 -1
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +31 -5
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +139 -1
- package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +10 -0
- package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +2 -1
- package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +171 -0
- package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +30 -4
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +14 -0
- package/dist/extensions/pi-subagents/test/unit/owned-process-tree.test.ts +69 -0
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +83 -0
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +55 -2
- package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +12 -1
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +7 -7
- package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +121 -0
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +9 -0
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +4 -3
- package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +28 -0
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +10 -1
- package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +39 -0
- package/dist/extensions/pi-subagents/test/unit/timeout-defaults.test.ts +65 -0
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +61 -0
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.js +48 -1
- package/docs/quickstart.md +27 -43
- package/docs/settings.md +4 -0
- package/docs/usage.md +1 -0
- package/package.json +2 -1
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
import { discoverAvailableSkills, normalizeSkillInput } from "../../agents/skills.ts";
|
|
35
35
|
import { INTERCOM_BRIDGE_MARKER } from "../../intercom/intercom-bridge.ts";
|
|
36
36
|
import { runSync } from "./execution.ts";
|
|
37
|
+
import { createTaskMutationArbiter } from "../shared/llm-intent-arbiter.ts";
|
|
37
38
|
import { workflowForegroundSteeringLaunchOptions } from "./workflow-foreground-steering.ts";
|
|
38
39
|
import {
|
|
39
40
|
beginForegroundChild,
|
|
@@ -42,6 +43,7 @@ import {
|
|
|
42
43
|
settleForegroundSchedulingOwner,
|
|
43
44
|
updateForegroundChild,
|
|
44
45
|
} from "./foreground-control.ts";
|
|
46
|
+
import { updateLiveEffectivePrompt } from "./prompt-audit.ts";
|
|
45
47
|
import { buildChainSummary } from "../../shared/formatters.ts";
|
|
46
48
|
import { compactForegroundDetails, getSingleResultOutput, mapConcurrent, resolveChildCwd, sumResultsCost, sumResultsUsage } from "../../shared/utils.ts";
|
|
47
49
|
import { DEFAULT_GLOBAL_CONCURRENCY_LIMIT, Semaphore } from "../shared/parallel-utils.ts";
|
|
@@ -71,6 +73,7 @@ import {
|
|
|
71
73
|
type ResolvedControlConfig,
|
|
72
74
|
type ResolvedTurnBudget,
|
|
73
75
|
type ResolvedToolBudget,
|
|
76
|
+
type RunFanoutBudgetDescriptor,
|
|
74
77
|
type SingleResult,
|
|
75
78
|
type ToolBudgetConfig,
|
|
76
79
|
type ChainCheckpointState,
|
|
@@ -86,6 +89,7 @@ import { ChainOutputValidationError, outputEntryFromResult, resolveOutputReferen
|
|
|
86
89
|
import { createStructuredOutputRuntime } from "../shared/structured-output.ts";
|
|
87
90
|
import { collectDynamicResults, DynamicFanoutError, materializeDynamicParallelStep, validateDynamicCollection, type DynamicCollectedResult } from "../shared/dynamic-fanout.ts";
|
|
88
91
|
import { acceptanceFailureMessage, aggregateAcceptanceReport, evaluateAcceptance, resolveEffectiveAcceptance } from "../shared/acceptance.ts";
|
|
92
|
+
import { claimRunFanoutBatch, RunFanoutLimitError } from "../shared/run-fanout-budget.ts";
|
|
89
93
|
import { isAgentContractV1 } from "../shared/agent-contract.ts";
|
|
90
94
|
import type { ChainOutputMap } from "../../shared/types.ts";
|
|
91
95
|
import { validateToolBudgetConfig } from "../shared/tool-budget.ts";
|
|
@@ -167,6 +171,7 @@ interface ParallelChainRunInput {
|
|
|
167
171
|
configToolBudget?: ToolBudgetConfig;
|
|
168
172
|
globalSemaphore?: Semaphore;
|
|
169
173
|
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
174
|
+
runFanoutBudget?: RunFanoutBudgetDescriptor;
|
|
170
175
|
permissions?: PermissionConfig;
|
|
171
176
|
dynamic?: boolean;
|
|
172
177
|
}
|
|
@@ -368,7 +373,11 @@ async function runParallelChainTasks(input: ParallelChainRunInput): Promise<Sing
|
|
|
368
373
|
beginForegroundChild(input.foregroundControl, {
|
|
369
374
|
index: childIndex,
|
|
370
375
|
agent: task.agent,
|
|
371
|
-
|
|
376
|
+
authoredTask: cleanTask,
|
|
377
|
+
effectivePrompt: taskStr,
|
|
378
|
+
cwd: taskCwd,
|
|
379
|
+
...(outputPath ? { outputPath } : {}),
|
|
380
|
+
description: `${task.agent} child`,
|
|
372
381
|
...(effectiveModel ? { model: effectiveModel } : {}),
|
|
373
382
|
...(thinking ? { thinking } : {}),
|
|
374
383
|
interrupt: () => {
|
|
@@ -388,8 +397,10 @@ async function runParallelChainTasks(input: ParallelChainRunInput): Promise<Sing
|
|
|
388
397
|
result = await runSync(input.ctx.cwd, input.agents, task.agent, taskStr, {
|
|
389
398
|
permissions: input.permissions,
|
|
390
399
|
parentSessionId: input.ctx.sessionManager.getSessionId() ?? undefined,
|
|
400
|
+
llmIntentArbiter: createTaskMutationArbiter(input.ctx),
|
|
391
401
|
...workflowForegroundSteeringLaunchOptions(input.foregroundControl, childIndex),
|
|
392
402
|
capabilityCeiling: input.capabilityCeiling,
|
|
403
|
+
runFanoutBudget: input.runFanoutBudget ? { ...input.runFanoutBudget, parentPath: `${input.runFanoutBudget.parentPath ? `${input.runFanoutBudget.parentPath}/` : ""}chain[${input.stepIndex}]${input.dynamic ? `.expand[${taskIndex}]` : `.parallel[${taskIndex}]`}` } : undefined,
|
|
393
404
|
context: input.contextForAgent?.(task.agent),
|
|
394
405
|
cwd: taskCwd,
|
|
395
406
|
signal: input.signal,
|
|
@@ -422,6 +433,7 @@ async function runParallelChainTasks(input: ParallelChainRunInput): Promise<Sing
|
|
|
422
433
|
agentContract,
|
|
423
434
|
acceptance: task.acceptance,
|
|
424
435
|
acceptanceContext: { mode: "chain", dynamic: input.dynamic && task.acceptance === undefined },
|
|
436
|
+
onEffectivePrompt: input.foregroundControl ? (prompt) => updateLiveEffectivePrompt(input.foregroundControl!, childIndex, prompt) : undefined,
|
|
425
437
|
timeoutMs: input.timeoutMs,
|
|
426
438
|
deadlineAt: input.deadlineAt,
|
|
427
439
|
turnBudget: input.turnBudget,
|
|
@@ -540,6 +552,7 @@ interface ChainExecutionParams {
|
|
|
540
552
|
/** Global cap on simultaneously-running tasks within this chain. Defaults to DEFAULT_GLOBAL_CONCURRENCY_LIMIT. */
|
|
541
553
|
globalConcurrencyLimit?: number;
|
|
542
554
|
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
555
|
+
runFanoutBudget?: RunFanoutBudgetDescriptor;
|
|
543
556
|
}
|
|
544
557
|
|
|
545
558
|
interface ChainExecutionResult {
|
|
@@ -876,6 +889,7 @@ ${step.message}` : ""}` }],
|
|
|
876
889
|
configToolBudget: params.configToolBudget,
|
|
877
890
|
globalSemaphore,
|
|
878
891
|
permissions: params.permissions,
|
|
892
|
+
runFanoutBudget: params.runFanoutBudget,
|
|
879
893
|
});
|
|
880
894
|
globalTaskIndex += step.parallel.length;
|
|
881
895
|
|
|
@@ -1002,6 +1016,19 @@ ${step.message}` : ""}` }],
|
|
|
1002
1016
|
return buildChainExecutionErrorResult(message, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex }));
|
|
1003
1017
|
}
|
|
1004
1018
|
|
|
1019
|
+
try {
|
|
1020
|
+
if (params.runFanoutBudget) claimRunFanoutBatch(params.runFanoutBudget, materialized.parallel.map((_, itemIndex) => `chain[${stepIndex}].expand[${itemIndex}]`));
|
|
1021
|
+
} catch (error) {
|
|
1022
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1023
|
+
dynamicGroupStatuses[stepIndex] = { status: "failed", error: message };
|
|
1024
|
+
const result = buildChainExecutionErrorResult(message, makeDetailsInput({ currentStepIndex: stepIndex, currentFlatIndex: globalTaskIndex }));
|
|
1025
|
+
if (error instanceof RunFanoutLimitError) {
|
|
1026
|
+
result.details.runFanoutBudget = error.snapshot;
|
|
1027
|
+
result.details.runFanoutRejection = error.rejection;
|
|
1028
|
+
}
|
|
1029
|
+
return result;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1005
1032
|
dynamicChildren[stepIndex] = materialized.items.map((item, itemIndex) => ({
|
|
1006
1033
|
agent: step.parallel.agent,
|
|
1007
1034
|
label: materialized.parallel[itemIndex]?.label,
|
|
@@ -1137,6 +1164,7 @@ ${step.message}` : ""}` }],
|
|
|
1137
1164
|
configToolBudget: params.configToolBudget,
|
|
1138
1165
|
globalSemaphore,
|
|
1139
1166
|
permissions: params.permissions,
|
|
1167
|
+
runFanoutBudget: params.runFanoutBudget,
|
|
1140
1168
|
dynamic: true,
|
|
1141
1169
|
});
|
|
1142
1170
|
globalTaskIndex = dynamicStartIndex + reservedDynamicItems;
|
|
@@ -1332,7 +1360,11 @@ ${step.message}` : ""}` }],
|
|
|
1332
1360
|
beginForegroundChild(foregroundControl, {
|
|
1333
1361
|
index: childIndex,
|
|
1334
1362
|
agent: seqStep.agent,
|
|
1335
|
-
|
|
1363
|
+
authoredTask: cleanTask,
|
|
1364
|
+
effectivePrompt: stepTask,
|
|
1365
|
+
cwd,
|
|
1366
|
+
...(outputPath ? { outputPath } : {}),
|
|
1367
|
+
description: `${seqStep.agent} child`,
|
|
1336
1368
|
...(effectiveModel ? { model: effectiveModel } : {}),
|
|
1337
1369
|
...(thinking ? { thinking } : {}),
|
|
1338
1370
|
interrupt: () => {
|
|
@@ -1369,8 +1401,10 @@ ${step.message}` : ""}` }],
|
|
|
1369
1401
|
r = await runSync(ctx.cwd, agents, seqStep.agent, stepTask, {
|
|
1370
1402
|
permissions: params.permissions,
|
|
1371
1403
|
parentSessionId: ctx.sessionManager.getSessionId() ?? undefined,
|
|
1404
|
+
llmIntentArbiter: createTaskMutationArbiter(ctx),
|
|
1372
1405
|
...workflowForegroundSteeringLaunchOptions(params.foregroundControl, childIndex),
|
|
1373
1406
|
capabilityCeiling: params.capabilityCeiling,
|
|
1407
|
+
runFanoutBudget: params.runFanoutBudget ? { ...params.runFanoutBudget, parentPath: `${params.runFanoutBudget.parentPath ? `${params.runFanoutBudget.parentPath}/` : ""}chain[${stepIndex}]` } : undefined,
|
|
1374
1408
|
context: params.contextForAgent?.(seqStep.agent),
|
|
1375
1409
|
cwd: resolveChildCwd(cwd ?? ctx.cwd, seqStep.cwd),
|
|
1376
1410
|
signal,
|
|
@@ -1403,6 +1437,7 @@ ${step.message}` : ""}` }],
|
|
|
1403
1437
|
agentContract,
|
|
1404
1438
|
acceptance: seqStep.acceptance,
|
|
1405
1439
|
acceptanceContext: { mode: "chain" },
|
|
1440
|
+
onEffectivePrompt: foregroundControl ? (prompt) => updateLiveEffectivePrompt(foregroundControl, childIndex, prompt) : undefined,
|
|
1406
1441
|
timeoutMs: params.timeoutMs,
|
|
1407
1442
|
deadlineAt,
|
|
1408
1443
|
turnBudget: params.turnBudget,
|
|
@@ -54,22 +54,25 @@ import {
|
|
|
54
54
|
import { buildSkillInjection, resolveSkillsWithFallback } from "../../agents/skills.ts";
|
|
55
55
|
import { buildAgentMemoryInjection } from "../../agents/agent-memory.ts";
|
|
56
56
|
import { evaluateCompletionMutationGuard } from "../shared/completion-guard.ts";
|
|
57
|
+
import { arbitrateCompletionGuardRescue } from "../shared/llm-intent-arbiter.ts";
|
|
57
58
|
import { getPiSpawnCommand } from "../shared/pi-spawn.ts";
|
|
58
59
|
import { createJsonlWriter } from "../../shared/jsonl-writer.ts";
|
|
59
60
|
import { attachPostExitStdioGuard, trySignalChild } from "../../shared/post-exit-stdio-guard.ts";
|
|
60
61
|
import { resolvePermissionRules } from "../shared/permissions.ts";
|
|
61
|
-
import { applyThinkingSuffix, buildPiArgs, cleanupTempDir, projectLaunchResolvedChildExtensions, resolvePiLaunchToolPlan } from "../shared/pi-args.ts";
|
|
62
|
+
import { applyThinkingSuffix, buildPiArgs, cleanupTempDir, projectLaunchResolvedChildExtensions, resolvePiLaunchToolPlan, type SubagentTaskDelivery } from "../shared/pi-args.ts";
|
|
62
63
|
import { readRuntimeAcknowledgedExtensions } from "../shared/runtime-acknowledged-extensions.ts";
|
|
63
64
|
import { assertAgentAllowedByCapabilityCeiling, decodeSubagentCapabilityCeiling, intersectSubagentCapabilityCeilings, resolveCurrentSubagentCapabilityCeiling, SUBAGENT_CAPABILITY_CEILING_ENV } from "../shared/capability-ceiling.ts";
|
|
64
65
|
import { resolveEffectiveThinking } from "../../shared/model-info.ts";
|
|
65
66
|
import { MISSING_STRUCTURED_OUTPUT_CALL_ERROR, readStructuredOutput } from "../shared/structured-output.ts";
|
|
66
67
|
import { formatProcessSignalError, isUnexplainedProcessSignal } from "../shared/process-signal.ts";
|
|
67
68
|
import { readChildToolDiagnosticError } from "../shared/tool-availability.ts";
|
|
68
|
-
import { captureSingleOutputSnapshot, extractChildWrittenOutput, formatSavedOutputReference, injectOutputPathSystemPrompt, resolveSingleOutput, validateFileOnlyOutputMode, type SingleOutputSnapshot } from "../shared/single-output.ts";
|
|
69
|
+
import { captureSingleOutputSnapshot, extractChildWrittenOutput, finalizeSingleOutput, formatSavedOutputReference, injectOutputPathSystemPrompt, resolveSingleOutput, validateFileOnlyOutputMode, type SingleOutputSnapshot } from "../shared/single-output.ts";
|
|
69
70
|
import {
|
|
70
71
|
buildModelCandidates,
|
|
71
72
|
formatModelAttemptNote,
|
|
73
|
+
formatModelRetryNote,
|
|
72
74
|
isRetryableModelFailure,
|
|
75
|
+
MODEL_RETRY_DELAYS_MS,
|
|
73
76
|
} from "../shared/model-fallback.ts";
|
|
74
77
|
import {
|
|
75
78
|
SUBAGENT_STARTUP_RETRY_DELAYS_MS,
|
|
@@ -90,6 +93,7 @@ import {
|
|
|
90
93
|
summarizeRecentMutatingFailures,
|
|
91
94
|
} from "../shared/long-running-guard.ts";
|
|
92
95
|
import { acceptanceFailureMessage, buildSkippedAcceptanceLedger, evaluateAcceptance, formatAcceptancePrompt, resolveEffectiveAcceptance, stripAcceptanceReport, validateAcceptanceInput } from "../shared/acceptance.ts";
|
|
96
|
+
import { PROMPT_REDACTED } from "../../shared/utils.ts";
|
|
93
97
|
import { attachContractProjections, isAgentContractV1 } from "../shared/agent-contract.ts";
|
|
94
98
|
import { appendTurnBudgetSystemPrompt, formatTurnBudgetOutput, initialTurnBudgetState, turnBudgetDecision, turnBudgetDeferredNote, turnBudgetDeferredState, turnBudgetExceededMessage, turnBudgetSoftNote, turnBudgetState } from "../shared/turn-budget.ts";
|
|
95
99
|
import { initialToolBudgetState, toolBudgetState } from "../shared/tool-budget.ts";
|
|
@@ -117,6 +121,12 @@ function withRunContext<T extends SingleResult>(result: T, context: RunSyncOptio
|
|
|
117
121
|
return result;
|
|
118
122
|
}
|
|
119
123
|
|
|
124
|
+
function redactResultPrompt<T extends SingleResult>(result: T): T {
|
|
125
|
+
result.task = PROMPT_REDACTED;
|
|
126
|
+
if (result.progress) result.progress.task = PROMPT_REDACTED;
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
|
|
120
130
|
function sumUsage(target: Usage, source: Usage): void {
|
|
121
131
|
target.input += source.input;
|
|
122
132
|
target.output += source.output;
|
|
@@ -139,7 +149,7 @@ function persistSingleResultMetadata(input: {
|
|
|
139
149
|
writeMetadata(input.metadataPath, {
|
|
140
150
|
runId: input.runId,
|
|
141
151
|
agent: input.agent,
|
|
142
|
-
task:
|
|
152
|
+
task: PROMPT_REDACTED,
|
|
143
153
|
exitCode: target.exitCode,
|
|
144
154
|
processSignal: target.processSignal,
|
|
145
155
|
usage: target.usage,
|
|
@@ -231,6 +241,7 @@ function stripAcceptanceReportsFromMessages(messages: Message[] | undefined): vo
|
|
|
231
241
|
function snapshotProgress(progress: AgentProgress): AgentProgress {
|
|
232
242
|
return {
|
|
233
243
|
...progress,
|
|
244
|
+
task: PROMPT_REDACTED,
|
|
234
245
|
skills: progress.skills ? [...progress.skills] : undefined,
|
|
235
246
|
recentTools: boundStreamedRecentTools(progress.recentTools),
|
|
236
247
|
recentOutput: boundStreamedRecentOutput(progress.recentOutput),
|
|
@@ -240,6 +251,7 @@ function snapshotProgress(progress: AgentProgress): AgentProgress {
|
|
|
240
251
|
function snapshotResult(result: SingleResult, progress: AgentProgress): SingleResult {
|
|
241
252
|
return {
|
|
242
253
|
...result,
|
|
254
|
+
task: PROMPT_REDACTED,
|
|
243
255
|
messages: result.outputMode === "file-only" && result.savedOutputPath ? undefined : result.messages ? [...result.messages] : undefined,
|
|
244
256
|
usage: { ...result.usage },
|
|
245
257
|
skills: result.skills ? [...result.skills] : undefined,
|
|
@@ -291,6 +303,7 @@ async function runSingleAttempt(
|
|
|
291
303
|
attemptNotes: string[];
|
|
292
304
|
outputSnapshot?: SingleOutputSnapshot;
|
|
293
305
|
originalTask?: string;
|
|
306
|
+
taskDelivery?: SubagentTaskDelivery;
|
|
294
307
|
},
|
|
295
308
|
): Promise<SingleResult> {
|
|
296
309
|
const effectiveThinking = options.thinkingOverride ?? agent.thinking;
|
|
@@ -312,6 +325,7 @@ async function runSingleAttempt(
|
|
|
312
325
|
const { args, env: sharedEnv, tempDir, toolDiagnosticPath, runtimeAcknowledgedExtensionsPath, capabilityAudit } = buildPiArgs({
|
|
313
326
|
baseArgs: ["--mode", "json", "-p"],
|
|
314
327
|
task,
|
|
328
|
+
taskDelivery: shared.taskDelivery,
|
|
315
329
|
sessionEnabled: shared.sessionEnabled,
|
|
316
330
|
sessionDir: options.sessionDir,
|
|
317
331
|
sessionFile: options.sessionFile,
|
|
@@ -337,6 +351,7 @@ async function runSingleAttempt(
|
|
|
337
351
|
parentControlInbox: options.nestedRoute?.controlInbox,
|
|
338
352
|
parentRootRunId: options.nestedRoute?.rootRunId,
|
|
339
353
|
parentCapabilityToken: options.nestedRoute?.capabilityToken,
|
|
354
|
+
runFanoutBudget: options.runFanoutBudget,
|
|
340
355
|
parentSessionId: options.parentSessionId,
|
|
341
356
|
steerInboxDir: options.steerInboxDir,
|
|
342
357
|
steerCapabilityPath: options.steerCapabilityPath,
|
|
@@ -1277,15 +1292,38 @@ async function runSingleAttempt(
|
|
|
1277
1292
|
mcpDirectTools: agent.mcpDirectTools,
|
|
1278
1293
|
})
|
|
1279
1294
|
: undefined;
|
|
1280
|
-
|
|
1295
|
+
let completionGuardTriggered = completionGuard?.triggered === true && !observedMutationAttempt;
|
|
1296
|
+
// The classifier is deliberately narrow, so a read-only review task can
|
|
1297
|
+
// still be misread as implementation. Arbitrate BEFORE any failure side
|
|
1298
|
+
// effect is published (effects, exit code, progress, notifications,
|
|
1299
|
+
// acceptance, output persistence): only a confident read-only verdict
|
|
1300
|
+
// rescues, and the task text alone is evidence — never the child's own
|
|
1301
|
+
// final message.
|
|
1302
|
+
let arbiterRescued = false;
|
|
1303
|
+
if (completionGuardTriggered) {
|
|
1304
|
+
const arbitration = await arbitrateCompletionGuardRescue({
|
|
1305
|
+
guardTriggered: true,
|
|
1306
|
+
task: shared.originalTask ?? task,
|
|
1307
|
+
arbiter: options.llmIntentArbiter,
|
|
1308
|
+
});
|
|
1309
|
+
completionGuardTriggered = arbitration.triggered;
|
|
1310
|
+
arbiterRescued = arbitration.rescued;
|
|
1311
|
+
}
|
|
1281
1312
|
if (completionGuard) {
|
|
1282
1313
|
result.effects = {
|
|
1283
1314
|
...(result.effects ?? {}),
|
|
1284
1315
|
fileMutation: {
|
|
1285
|
-
status: completionGuard.expectedMutation
|
|
1316
|
+
status: completionGuard.expectedMutation
|
|
1317
|
+
? completionGuardTriggered
|
|
1318
|
+
? "missing"
|
|
1319
|
+
: arbiterRescued
|
|
1320
|
+
? "not-applicable"
|
|
1321
|
+
: "observed"
|
|
1322
|
+
: "not-applicable",
|
|
1286
1323
|
expected: completionGuard.expectedMutation,
|
|
1287
1324
|
attempted: completionGuard.attemptedMutation || observedMutationAttempt,
|
|
1288
1325
|
...(completionGuardTriggered ? { message: "Subagent completed without making edits for an implementation task." } : {}),
|
|
1326
|
+
...(arbiterRescued ? { resolvedBy: "llm-intent-arbiter" } : {}),
|
|
1289
1327
|
},
|
|
1290
1328
|
};
|
|
1291
1329
|
}
|
|
@@ -1355,7 +1393,7 @@ async function runSyncCompletion(
|
|
|
1355
1393
|
};
|
|
1356
1394
|
const agent = agents.find((a) => a.name === agentName);
|
|
1357
1395
|
if (!agent) {
|
|
1358
|
-
return withRunContext({
|
|
1396
|
+
return redactResultPrompt(withRunContext({
|
|
1359
1397
|
index: options.index ?? 0,
|
|
1360
1398
|
agent: agentName,
|
|
1361
1399
|
task,
|
|
@@ -1363,12 +1401,12 @@ async function runSyncCompletion(
|
|
|
1363
1401
|
messages: [],
|
|
1364
1402
|
usage: emptyUsage(),
|
|
1365
1403
|
error: `Unknown agent: ${agentName}`,
|
|
1366
|
-
}, options.context);
|
|
1404
|
+
}, options.context));
|
|
1367
1405
|
}
|
|
1368
1406
|
try {
|
|
1369
1407
|
assertAgentAllowedByCapabilityCeiling(agent.name, options.capabilityCeiling);
|
|
1370
1408
|
} catch (error) {
|
|
1371
|
-
return withRunContext({
|
|
1409
|
+
return redactResultPrompt(withRunContext({
|
|
1372
1410
|
index: options.index ?? 0,
|
|
1373
1411
|
agent: agent.name,
|
|
1374
1412
|
task,
|
|
@@ -1377,11 +1415,11 @@ async function runSyncCompletion(
|
|
|
1377
1415
|
usage: emptyUsage(),
|
|
1378
1416
|
error: error instanceof Error ? error.message : String(error),
|
|
1379
1417
|
...(options.capabilityCeiling ? { capabilityCeiling: options.capabilityCeiling } : {}),
|
|
1380
|
-
}, options.context);
|
|
1418
|
+
}, options.context));
|
|
1381
1419
|
}
|
|
1382
1420
|
const acceptanceErrors = validateAcceptanceInput(options.acceptance);
|
|
1383
1421
|
if (acceptanceErrors.length > 0) {
|
|
1384
|
-
return withRunContext({
|
|
1422
|
+
return redactResultPrompt(withRunContext({
|
|
1385
1423
|
index: options.index ?? 0,
|
|
1386
1424
|
agent: agentName,
|
|
1387
1425
|
task,
|
|
@@ -1389,11 +1427,11 @@ async function runSyncCompletion(
|
|
|
1389
1427
|
messages: [],
|
|
1390
1428
|
usage: emptyUsage(),
|
|
1391
1429
|
error: acceptanceErrors.join(" "),
|
|
1392
|
-
}, options.context);
|
|
1430
|
+
}, options.context));
|
|
1393
1431
|
}
|
|
1394
1432
|
const outputModeValidationError = validateFileOnlyOutputMode(options.outputMode, options.outputPath, `Single run (${agentName})`);
|
|
1395
1433
|
if (outputModeValidationError) {
|
|
1396
|
-
return withRunContext({
|
|
1434
|
+
return redactResultPrompt(withRunContext({
|
|
1397
1435
|
index: options.index ?? 0,
|
|
1398
1436
|
agent: agentName,
|
|
1399
1437
|
task,
|
|
@@ -1402,7 +1440,7 @@ async function runSyncCompletion(
|
|
|
1402
1440
|
usage: emptyUsage(),
|
|
1403
1441
|
outputMode: options.outputMode,
|
|
1404
1442
|
error: outputModeValidationError,
|
|
1405
|
-
}, options.context);
|
|
1443
|
+
}, options.context));
|
|
1406
1444
|
}
|
|
1407
1445
|
|
|
1408
1446
|
const shareEnabled = options.share === true;
|
|
@@ -1419,6 +1457,7 @@ async function runSyncCompletion(
|
|
|
1419
1457
|
});
|
|
1420
1458
|
const acceptancePrompt = formatAcceptancePrompt(effectiveAcceptance, { reportOptional: isAgentContractV1(options.agentContract) });
|
|
1421
1459
|
const taskWithAcceptance = acceptancePrompt ? `${task}\n${acceptancePrompt}` : task;
|
|
1460
|
+
options.onEffectivePrompt?.(taskWithAcceptance);
|
|
1422
1461
|
const sessionEnabled = Boolean(options.sessionFile || options.sessionDir) || shareEnabled;
|
|
1423
1462
|
if (options.context === "fork" && options.sessionFile && existsSync(options.sessionFile)) {
|
|
1424
1463
|
alignForkedSessionCwd(options.sessionFile, options.cwd ?? runtimeCwd);
|
|
@@ -1433,7 +1472,7 @@ async function runSyncCompletion(
|
|
|
1433
1472
|
agent.filePath ? path.dirname(agent.filePath) : skillCwd,
|
|
1434
1473
|
);
|
|
1435
1474
|
if (skillNames.some((skill) => skill.trim() === "pi-subagents") && missingSkills.includes("pi-subagents")) {
|
|
1436
|
-
return withRunContext({
|
|
1475
|
+
return redactResultPrompt(withRunContext({
|
|
1437
1476
|
index: options.index ?? 0,
|
|
1438
1477
|
agent: agentName,
|
|
1439
1478
|
task,
|
|
@@ -1441,7 +1480,7 @@ async function runSyncCompletion(
|
|
|
1441
1480
|
messages: [],
|
|
1442
1481
|
usage: emptyUsage(),
|
|
1443
1482
|
error: "Skills not found: pi-subagents",
|
|
1444
|
-
}, options.context);
|
|
1483
|
+
}, options.context));
|
|
1445
1484
|
}
|
|
1446
1485
|
let systemPrompt = agent.systemPrompt?.trim() || "";
|
|
1447
1486
|
if (resolvedSkills.length > 0) {
|
|
@@ -1476,7 +1515,7 @@ async function runSyncCompletion(
|
|
|
1476
1515
|
artifactPathsResult = getArtifactPaths(options.artifactsDir, options.runId, agentName, options.index);
|
|
1477
1516
|
ensureArtifactsDir(options.artifactsDir);
|
|
1478
1517
|
if (options.artifactConfig?.includeInput !== false) {
|
|
1479
|
-
|
|
1518
|
+
writeArtifact(artifactPathsResult.inputPath, `# Task for ${agentName}\n\n${PROMPT_REDACTED}; live Prompt Audit only.\n`);
|
|
1480
1519
|
}
|
|
1481
1520
|
if (options.artifactConfig?.includeJsonl !== false) {
|
|
1482
1521
|
jsonlPath = artifactPathsResult.jsonlPath;
|
|
@@ -1490,7 +1529,7 @@ async function runSyncCompletion(
|
|
|
1490
1529
|
childIndex: options.index,
|
|
1491
1530
|
cwd: options.cwd ?? runtimeCwd,
|
|
1492
1531
|
});
|
|
1493
|
-
transcriptWriter.writeInitialUserMessage(
|
|
1532
|
+
transcriptWriter.writeInitialUserMessage(`${PROMPT_REDACTED}; live Prompt Audit only.`);
|
|
1494
1533
|
}
|
|
1495
1534
|
}
|
|
1496
1535
|
|
|
@@ -1526,6 +1565,10 @@ async function runSyncCompletion(
|
|
|
1526
1565
|
};
|
|
1527
1566
|
let lastResult: SingleResult | undefined;
|
|
1528
1567
|
const modelsToTry = candidates.length > 0 ? candidates : [undefined];
|
|
1568
|
+
let modelRetryIndex = 0;
|
|
1569
|
+
// Escalated to "file" after an unexplained zero-activity startup failure so
|
|
1570
|
+
// retries keep the task text out of argv (endpoint pre-exec scans may deny it).
|
|
1571
|
+
let taskDeliveryOverride: SubagentTaskDelivery | undefined;
|
|
1529
1572
|
modelAttemptsLoop: for (let modelIndex = 0; modelIndex < modelsToTry.length; modelIndex++) {
|
|
1530
1573
|
const candidate = modelsToTry[modelIndex];
|
|
1531
1574
|
for (let startupAttemptIndex = 0; ; startupAttemptIndex++) {
|
|
@@ -1544,6 +1587,7 @@ async function runSyncCompletion(
|
|
|
1544
1587
|
.filter((modelCandidate): modelCandidate is string => Boolean(modelCandidate)),
|
|
1545
1588
|
outputSnapshot,
|
|
1546
1589
|
originalTask: task,
|
|
1590
|
+
taskDelivery: taskDeliveryOverride,
|
|
1547
1591
|
});
|
|
1548
1592
|
lastResult = result;
|
|
1549
1593
|
if (startupAttemptIndex === 0) {
|
|
@@ -1612,6 +1656,10 @@ async function runSyncCompletion(
|
|
|
1612
1656
|
}
|
|
1613
1657
|
break modelAttemptsLoop;
|
|
1614
1658
|
}
|
|
1659
|
+
if (!taskDeliveryOverride && result.processSignal === "SIGKILL") {
|
|
1660
|
+
taskDeliveryOverride = "file";
|
|
1661
|
+
attemptNotes.push("[startup-retry] retrying with file task delivery to keep the task text out of the child process argv.");
|
|
1662
|
+
}
|
|
1615
1663
|
attempt.error = retryNote;
|
|
1616
1664
|
attemptNotes.push(retryNote);
|
|
1617
1665
|
continue;
|
|
@@ -1630,9 +1678,48 @@ async function runSyncCompletion(
|
|
|
1630
1678
|
attempt.error = startupError;
|
|
1631
1679
|
break modelAttemptsLoop;
|
|
1632
1680
|
}
|
|
1633
|
-
if (
|
|
1634
|
-
|
|
1635
|
-
|
|
1681
|
+
if (isRetryableModelFailure(result.error)) {
|
|
1682
|
+
if (modelIndex < modelsToTry.length - 1) {
|
|
1683
|
+
attemptNotes.push(formatModelAttemptNote(attempt, modelsToTry[modelIndex + 1]));
|
|
1684
|
+
modelRetryIndex = 0;
|
|
1685
|
+
break;
|
|
1686
|
+
}
|
|
1687
|
+
const modelRetryDelayMs = MODEL_RETRY_DELAYS_MS[modelRetryIndex];
|
|
1688
|
+
if (modelRetryDelayMs !== undefined) {
|
|
1689
|
+
const retryNote = formatModelRetryNote({
|
|
1690
|
+
model: attempt.model,
|
|
1691
|
+
attempt: modelRetryIndex + 1,
|
|
1692
|
+
maxAttempts: MODEL_RETRY_DELAYS_MS.length + 1,
|
|
1693
|
+
delayMs: modelRetryDelayMs,
|
|
1694
|
+
});
|
|
1695
|
+
const shouldRetry = await waitForSubagentStartupRetry(modelRetryDelayMs, [options.signal, options.interruptSignal]);
|
|
1696
|
+
if (!shouldRetry) {
|
|
1697
|
+
if (options.interruptSignal?.aborted) {
|
|
1698
|
+
result.exitCode = 0;
|
|
1699
|
+
result.interrupted = true;
|
|
1700
|
+
result.error = undefined;
|
|
1701
|
+
result.finalOutput = "Interrupted. Waiting for explicit next action.";
|
|
1702
|
+
if (result.progress) {
|
|
1703
|
+
result.progress.status = "running";
|
|
1704
|
+
result.progress.error = undefined;
|
|
1705
|
+
}
|
|
1706
|
+
} else {
|
|
1707
|
+
const cancellationError = "Subagent model retry cancelled before relaunch.";
|
|
1708
|
+
result.error = cancellationError;
|
|
1709
|
+
result.finalOutput = cancellationError;
|
|
1710
|
+
attempt.error = cancellationError;
|
|
1711
|
+
if (result.progress) result.progress.error = cancellationError;
|
|
1712
|
+
}
|
|
1713
|
+
break modelAttemptsLoop;
|
|
1714
|
+
}
|
|
1715
|
+
attempt.error = retryNote;
|
|
1716
|
+
attemptNotes.push(retryNote);
|
|
1717
|
+
modelRetryIndex += 1;
|
|
1718
|
+
startupAttemptIndex = -1;
|
|
1719
|
+
continue;
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
break modelAttemptsLoop;
|
|
1636
1723
|
}
|
|
1637
1724
|
}
|
|
1638
1725
|
|
|
@@ -1726,13 +1813,39 @@ async function runSyncCompletion(
|
|
|
1726
1813
|
stripAcceptanceReportsFromMessages(result.messages);
|
|
1727
1814
|
if (acceptanceFailure && result.acceptance.explicit && result.exitCode === 0 && !result.interrupted && !result.timedOut && !isAgentContractV1(options.agentContract)) {
|
|
1728
1815
|
result.exitCode = 1;
|
|
1816
|
+
if (result.savedOutputPath) {
|
|
1817
|
+
result.finalOutput = finalizeSingleOutput({
|
|
1818
|
+
fullOutput: result.finalOutput ?? "",
|
|
1819
|
+
outputPath: options.outputPath,
|
|
1820
|
+
outputMode: result.outputMode,
|
|
1821
|
+
exitCode: result.exitCode,
|
|
1822
|
+
preserveSavedOutput: true,
|
|
1823
|
+
savedPath: result.savedOutputPath,
|
|
1824
|
+
outputReference: result.outputReference,
|
|
1825
|
+
}).displayOutput;
|
|
1826
|
+
artifactOutputByResult.set(result, result.finalOutput);
|
|
1827
|
+
}
|
|
1729
1828
|
result.error = result.error ? `${result.error}\n${acceptanceFailure}` : acceptanceFailure;
|
|
1829
|
+
if (artifactPathsResult && options.artifactConfig?.enabled !== false && options.artifactConfig?.includeOutput !== false) {
|
|
1830
|
+
try {
|
|
1831
|
+
writeArtifact(artifactPathsResult.outputPath, formatOutputArtifactContent({
|
|
1832
|
+
output: artifactOutputByResult.get(result) ?? result.finalOutput ?? "",
|
|
1833
|
+
error: result.error,
|
|
1834
|
+
transcriptPath: result.transcriptPath,
|
|
1835
|
+
metadataPath: options.artifactConfig?.includeMetadata === false ? undefined : artifactPathsResult.metadataPath,
|
|
1836
|
+
}));
|
|
1837
|
+
} catch (error) {
|
|
1838
|
+
const message = `Artifact output post-processing failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
1839
|
+
result.outputSaveError = result.outputSaveError ? `${result.outputSaveError}\n${message}` : message;
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1730
1842
|
if (result.progress) {
|
|
1731
1843
|
result.progress.status = "failed";
|
|
1732
1844
|
result.progress.error = result.error;
|
|
1733
1845
|
}
|
|
1734
1846
|
}
|
|
1735
1847
|
if (isAgentContractV1(options.agentContract)) attachContractProjections(result);
|
|
1848
|
+
redactResultPrompt(result);
|
|
1736
1849
|
try {
|
|
1737
1850
|
persistResultMetadata(result);
|
|
1738
1851
|
} catch (error) {
|
|
@@ -1817,7 +1930,7 @@ export async function runSync(
|
|
|
1817
1930
|
durationMs: publishedReceipt.progressSummary?.durationMs ?? 0,
|
|
1818
1931
|
error: failureMessage,
|
|
1819
1932
|
};
|
|
1820
|
-
const failedResult: SingleResult = {
|
|
1933
|
+
const failedResult: SingleResult = redactResultPrompt({
|
|
1821
1934
|
...publishedReceipt,
|
|
1822
1935
|
detached: undefined,
|
|
1823
1936
|
detachedReason,
|
|
@@ -1833,7 +1946,7 @@ export async function runSync(
|
|
|
1833
1946
|
acceptance: publishedReceipt.acceptance
|
|
1834
1947
|
? buildSkippedAcceptanceLedger(publishedReceipt.acceptance.effectiveAcceptance, { id: "completion-pipeline", message: failureMessage })
|
|
1835
1948
|
: undefined,
|
|
1836
|
-
};
|
|
1949
|
+
});
|
|
1837
1950
|
if (strictContract) attachContractProjections(failedResult);
|
|
1838
1951
|
try {
|
|
1839
1952
|
// Replace the provisional detach receipt metadata with the authoritative
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import type { AgentProgress, ForegroundChildControl, ForegroundRunControl } from "../../shared/types.ts";
|
|
2
|
+
import { registerLivePromptAudit, removeLivePromptAudit, type PromptAuditRerunContract } from "./prompt-audit.ts";
|
|
2
3
|
|
|
3
4
|
interface BeginForegroundChildInput {
|
|
4
5
|
index: number;
|
|
5
6
|
agent: string;
|
|
6
7
|
description?: string;
|
|
8
|
+
authoredTask: string;
|
|
9
|
+
effectivePrompt: string;
|
|
10
|
+
cwd?: string;
|
|
11
|
+
outputPath?: string;
|
|
12
|
+
rerun?: PromptAuditRerunContract;
|
|
7
13
|
model?: string;
|
|
8
14
|
thinking?: string;
|
|
9
15
|
interrupt: () => boolean;
|
|
@@ -109,6 +115,11 @@ export function beginForegroundChild(control: ForegroundRunControl, input: Begin
|
|
|
109
115
|
}
|
|
110
116
|
control.activeChildren ??= new Map();
|
|
111
117
|
control.activeChildren.set(input.index, child);
|
|
118
|
+
registerLivePromptAudit(control, input.index, input.authoredTask, input.effectivePrompt, {
|
|
119
|
+
...(input.cwd ? { cwd: input.cwd } : {}),
|
|
120
|
+
...(input.outputPath ? { outputPath: input.outputPath } : {}),
|
|
121
|
+
...(input.rerun ? { rerun: input.rerun } : {}),
|
|
122
|
+
});
|
|
112
123
|
syncCurrentChild(control, child);
|
|
113
124
|
}
|
|
114
125
|
|
|
@@ -121,6 +132,7 @@ export function updateForegroundChild(control: ForegroundRunControl, index: numb
|
|
|
121
132
|
}
|
|
122
133
|
|
|
123
134
|
export function finishForegroundChild(control: ForegroundRunControl, index: number): void {
|
|
135
|
+
removeLivePromptAudit(control, index);
|
|
124
136
|
control.activeChildren?.delete(index);
|
|
125
137
|
if (control.currentIndex === index) {
|
|
126
138
|
const next = [...(control.activeChildren?.values() ?? [])]
|