pi-subagents 0.35.1 → 0.37.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 +71 -0
- package/README.md +224 -31
- package/agents/advisor.md +73 -0
- package/agents/delegate.md +2 -0
- package/agents/worker.md +2 -0
- package/package.json +11 -13
- package/skills/pi-subagents/SKILL.md +42 -13
- package/src/agents/agent-management.ts +7 -1
- package/src/agents/agents.ts +121 -17
- package/src/api/capability-ceiling.ts +17 -0
- package/src/api/delegation.ts +127 -0
- package/src/api/preflight.ts +399 -0
- package/src/extension/config.ts +7 -1
- package/src/extension/index.ts +52 -38
- package/src/extension/rpc.ts +31 -2
- package/src/extension/schemas.ts +29 -3
- package/src/extension/tool-description.ts +4 -2
- package/src/intercom/intercom-bridge.ts +1 -1
- package/src/intercom/native-supervisor-channel.ts +45 -6
- package/src/intercom/result-intercom.ts +7 -0
- package/src/runs/background/async-execution.ts +158 -17
- package/src/runs/background/async-job-tracker.ts +4 -0
- package/src/runs/background/async-resume.ts +47 -8
- package/src/runs/background/async-status.ts +94 -3
- package/src/runs/background/chain-append.ts +2 -0
- package/src/runs/background/completion-batcher.ts +6 -4
- package/src/runs/background/completion-dedupe.ts +2 -11
- package/src/runs/background/fleet-view.ts +9 -4
- package/src/runs/background/notify.ts +132 -120
- package/src/runs/background/process-terminal.ts +280 -0
- package/src/runs/background/result-watcher.ts +138 -78
- package/src/runs/background/run-status.ts +10 -2
- package/src/runs/background/scheduled-runs.ts +6 -1
- package/src/runs/background/stale-run-reconciler.ts +6 -0
- package/src/runs/background/subagent-runner.ts +406 -54
- package/src/runs/background/subagent-wait.ts +130 -4
- package/src/runs/background/wait-tool.ts +2 -2
- package/src/runs/foreground/chain-execution.ts +181 -111
- package/src/runs/foreground/execution.ts +147 -47
- package/src/runs/foreground/foreground-control.ts +90 -0
- package/src/runs/foreground/subagent-executor.ts +426 -165
- package/src/runs/shared/acceptance.ts +94 -41
- package/src/runs/shared/agent-contract.ts +38 -0
- package/src/runs/shared/capability-ceiling.ts +177 -0
- package/src/runs/shared/child-protocol.ts +1 -1
- package/src/runs/shared/completion-guard.ts +36 -5
- package/src/runs/shared/context-mode.ts +44 -0
- package/src/runs/shared/dynamic-fanout.ts +5 -5
- package/src/runs/shared/long-running-guard.ts +4 -0
- package/src/runs/shared/mcp-direct-tool-allowlist.ts +12 -6
- package/src/runs/shared/nested-events.ts +35 -3
- package/src/runs/shared/parallel-handoff.ts +154 -0
- package/src/runs/shared/parallel-utils.ts +11 -0
- package/src/runs/shared/pi-args.ts +148 -56
- package/src/runs/shared/run-history.ts +90 -5
- package/src/runs/shared/session-lease.ts +25 -5
- package/src/runs/shared/structured-output.ts +112 -7
- package/src/runs/shared/subagent-control.ts +4 -0
- package/src/runs/shared/subagent-prompt-runtime.ts +31 -19
- package/src/runs/shared/task-intent.ts +10 -5
- package/src/runs/shared/tool-availability.ts +21 -3
- package/src/runs/shared/tool-budget.ts +11 -5
- package/src/runs/shared/turn-budget.ts +2 -1
- package/src/runs/shared/worktree.ts +63 -14
- package/src/shared/accessible-dir.ts +25 -0
- package/src/shared/artifacts.ts +37 -7
- package/src/shared/atomic-json.ts +14 -42
- package/src/shared/child-transcript.ts +52 -0
- package/src/shared/file-system-retry.ts +47 -0
- package/src/shared/launch-contract.ts +123 -0
- package/src/shared/settings.ts +9 -1
- package/src/shared/types.ts +314 -28
- package/src/shared/utils.ts +17 -42
- package/src/slash/delegation-adapters.ts +153 -6
- package/src/slash/delegation-json.ts +108 -0
- package/src/slash/delegation-request.ts +182 -36
- package/src/slash/prompt-template-bridge.ts +222 -37
- package/src/slash/selector.ts +147 -0
- package/src/slash/slash-commands.ts +15 -6
- package/src/slash/slash-live-state.ts +2 -2
- package/src/slash/subagents-admin.ts +42 -42
- package/src/tui/fleet-status.ts +362 -0
- package/src/tui/fleet-transcript.ts +472 -0
- package/src/tui/fleet.ts +318 -59
- package/src/tui/render.ts +17 -15
- package/src/watchdog/change-signature.ts +105 -12
- package/src/watchdog/review.ts +7 -2
- package/src/watchdog/runtime.ts +5 -3
- package/src/slash/subagents-editor.ts +0 -86
package/src/shared/types.ts
CHANGED
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
import * as os from "node:os";
|
|
6
6
|
import * as path from "node:path";
|
|
7
7
|
import type { Message } from "@earendil-works/pi-ai";
|
|
8
|
+
import type { AgentConfig } from "../agents/agents.ts";
|
|
8
9
|
import type { FSWatcher } from "node:fs";
|
|
9
10
|
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
10
11
|
import type { ModelScopeConfig } from "../runs/shared/model-scope.ts";
|
|
12
|
+
import type { ResolvedSubagentCapabilityCeiling, SubagentCapabilityAudit } from "../runs/shared/capability-ceiling.ts";
|
|
11
13
|
|
|
12
14
|
// ============================================================================
|
|
13
15
|
// Basic Types
|
|
@@ -201,7 +203,7 @@ export interface ControlEvent {
|
|
|
201
203
|
nestedRunId?: string;
|
|
202
204
|
nestingPath?: NestedRunAddress["path"];
|
|
203
205
|
message: string;
|
|
204
|
-
reason?: "idle" | "completion_guard" | "active_long_running" | "tool_failures" | "time_threshold" | "turn_threshold" | "token_threshold";
|
|
206
|
+
reason?: "idle" | "completion_guard" | "active_long_running" | "tool_failures" | "supervisor_request" | "time_threshold" | "turn_threshold" | "token_threshold";
|
|
205
207
|
turns?: number;
|
|
206
208
|
tokens?: number;
|
|
207
209
|
toolCount?: number;
|
|
@@ -214,9 +216,171 @@ export interface ControlEvent {
|
|
|
214
216
|
|
|
215
217
|
export type SubagentResultStatus = "completed" | "failed" | "paused" | "stopped" | "detached";
|
|
216
218
|
export type SubagentRunMode = "single" | "parallel" | "chain";
|
|
217
|
-
|
|
219
|
+
|
|
220
|
+
export interface ParallelHandoffPatch {
|
|
221
|
+
path: string;
|
|
222
|
+
branch: string;
|
|
223
|
+
changed: boolean;
|
|
224
|
+
diffStat: string;
|
|
225
|
+
filesChanged: number;
|
|
226
|
+
insertions: number;
|
|
227
|
+
deletions: number;
|
|
228
|
+
error?: string;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export interface ParallelHandoffChild {
|
|
232
|
+
index: number;
|
|
233
|
+
taskIndex: number;
|
|
234
|
+
agent: string;
|
|
235
|
+
status: SubagentResultStatus;
|
|
236
|
+
summary: string;
|
|
237
|
+
outputPath?: string;
|
|
238
|
+
structuredOutput?: unknown;
|
|
239
|
+
structuredOutputPath?: string;
|
|
240
|
+
sessionPath?: string;
|
|
241
|
+
patch: ParallelHandoffPatch;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export interface ParallelHandoffCleanupTask {
|
|
245
|
+
index: number;
|
|
246
|
+
path: string;
|
|
247
|
+
branch: string;
|
|
248
|
+
worktreeRemoved: boolean;
|
|
249
|
+
branchRemoved: boolean;
|
|
250
|
+
errors?: string[];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export interface ParallelHandoffGroup {
|
|
254
|
+
stepIndex: number;
|
|
255
|
+
baseCommit: string;
|
|
256
|
+
repoRoot: string;
|
|
257
|
+
children: ParallelHandoffChild[];
|
|
258
|
+
cleanup: {
|
|
259
|
+
state: "complete" | "partial";
|
|
260
|
+
tasks: ParallelHandoffCleanupTask[];
|
|
261
|
+
pruned: boolean;
|
|
262
|
+
errors?: string[];
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export interface ParallelHandoffManifest {
|
|
267
|
+
version: 1;
|
|
268
|
+
runId: string;
|
|
269
|
+
mode: "parallel" | "chain";
|
|
270
|
+
source: "foreground" | "async";
|
|
271
|
+
cwd: string;
|
|
272
|
+
createdAt: number;
|
|
273
|
+
updatedAt: number;
|
|
274
|
+
groups: ParallelHandoffGroup[];
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export interface ParallelHandoffReference {
|
|
278
|
+
version: 1;
|
|
279
|
+
path: string;
|
|
280
|
+
groupCount: number;
|
|
281
|
+
childCount: number;
|
|
282
|
+
changedPatches: number;
|
|
283
|
+
cleanupState: "complete" | "partial";
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export interface AgentContract {
|
|
287
|
+
version: 1;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export type ChainGateLayer = "execution" | "acceptance";
|
|
291
|
+
|
|
292
|
+
export type ExecutionProjectionStatus = "completed" | "failed" | "paused" | "stopped" | "detached";
|
|
293
|
+
|
|
294
|
+
export interface ExecutionProjection {
|
|
295
|
+
status: ExecutionProjectionStatus;
|
|
296
|
+
success: boolean;
|
|
297
|
+
exitCode: number;
|
|
298
|
+
error?: string;
|
|
299
|
+
interrupted?: boolean;
|
|
300
|
+
timedOut?: boolean;
|
|
301
|
+
stopped?: boolean;
|
|
302
|
+
detached?: boolean;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export interface ReviewProjection {
|
|
306
|
+
status: "not-requested" | "review-required" | "reviewed" | "blockers";
|
|
307
|
+
findings?: AcceptanceReviewResult["findings"];
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export interface FileMutationEffect {
|
|
311
|
+
status: "not-requested" | "not-applicable" | "observed" | "missing";
|
|
312
|
+
expected: boolean;
|
|
313
|
+
attempted: boolean;
|
|
314
|
+
message?: string;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export interface EffectsProjection {
|
|
318
|
+
fileMutation?: FileMutationEffect;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export const SUBAGENT_LIFECYCLE_ARTIFACT_VERSION = 3;
|
|
218
322
|
export type SubagentLifecycleArtifactVersion = typeof SUBAGENT_LIFECYCLE_ARTIFACT_VERSION;
|
|
219
323
|
|
|
324
|
+
export type ProcessTerminalState = "pending" | "observed" | "unknown" | "not-started";
|
|
325
|
+
export type ProcessTerminalReason =
|
|
326
|
+
| "observer-unavailable"
|
|
327
|
+
| "runner-candidate-missing"
|
|
328
|
+
| "runner-instance-mismatch"
|
|
329
|
+
| "writer-close-unverified"
|
|
330
|
+
| "canonical-session-unavailable"
|
|
331
|
+
| "canonical-session-lease-active"
|
|
332
|
+
| "canonical-session-release-unverified"
|
|
333
|
+
| "proof-write-failed"
|
|
334
|
+
| "stale-repair";
|
|
335
|
+
|
|
336
|
+
export interface RunnerProcessInstanceExitV1 {
|
|
337
|
+
processInstanceId: string;
|
|
338
|
+
kind: "runner";
|
|
339
|
+
closeObservedAt: number;
|
|
340
|
+
exitCode: number | null;
|
|
341
|
+
signal: string | null;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export interface PiWriterProcessInstanceExitV1 {
|
|
345
|
+
processInstanceId: string;
|
|
346
|
+
kind: "pi-writer";
|
|
347
|
+
attempt: number;
|
|
348
|
+
closeObservedAt: number;
|
|
349
|
+
exitCode: number | null;
|
|
350
|
+
signal: string | null;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export type ProcessInstanceExitV1 = RunnerProcessInstanceExitV1 | PiWriterProcessInstanceExitV1;
|
|
354
|
+
|
|
355
|
+
export interface CanonicalSessionTerminalV1 {
|
|
356
|
+
canonicalSessionId: string;
|
|
357
|
+
leaseDisposition: "released" | "not-held";
|
|
358
|
+
freeAtObservation: true;
|
|
359
|
+
canonicalSessionLeaseReleased?: true;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
interface ProcessTerminalBaseV1 {
|
|
363
|
+
version: 1;
|
|
364
|
+
runId: string;
|
|
365
|
+
childIndex?: number;
|
|
366
|
+
runnerProcessInstanceId: string;
|
|
367
|
+
resumeDisposition?: "resumable" | "non-resumable" | "unavailable";
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export type ProcessTerminalV1 =
|
|
371
|
+
| (ProcessTerminalBaseV1 & { state: "pending" | "not-started" })
|
|
372
|
+
| (ProcessTerminalBaseV1 & {
|
|
373
|
+
state: "observed";
|
|
374
|
+
observedAt: number;
|
|
375
|
+
instances: ProcessInstanceExitV1[];
|
|
376
|
+
canonicalSession?: CanonicalSessionTerminalV1;
|
|
377
|
+
})
|
|
378
|
+
| (ProcessTerminalBaseV1 & {
|
|
379
|
+
state: "unknown";
|
|
380
|
+
reason: ProcessTerminalReason;
|
|
381
|
+
diagnostic?: string;
|
|
382
|
+
});
|
|
383
|
+
|
|
220
384
|
export type SteeringActionState = "delivered" | "scheduled" | "pending" | "partial" | "recovered" | "failed";
|
|
221
385
|
export type SteeringTargetState = "scheduled" | "routed" | "delivered" | "late" | "failed" | "recovered";
|
|
222
386
|
|
|
@@ -281,7 +445,9 @@ export interface SteeringNotice {
|
|
|
281
445
|
|
|
282
446
|
export interface SteeringRecoveryDescriptor {
|
|
283
447
|
version: 1;
|
|
448
|
+
launchContractDigest?: string;
|
|
284
449
|
sourceRunId: string;
|
|
450
|
+
agentContract?: AgentContract;
|
|
285
451
|
agent: string;
|
|
286
452
|
sessionFile?: string;
|
|
287
453
|
cwd: string;
|
|
@@ -303,6 +469,7 @@ export interface SteeringRecoveryDescriptor {
|
|
|
303
469
|
memory?: { scope: "project" | "user"; path: string };
|
|
304
470
|
outputPath?: string;
|
|
305
471
|
outputMode: "inline" | "file-only";
|
|
472
|
+
structuredOutputSchema?: JsonSchemaObject;
|
|
306
473
|
acceptance?: AcceptanceInput;
|
|
307
474
|
controlConfig?: ResolvedControlConfig;
|
|
308
475
|
absoluteDeadlineAt?: number;
|
|
@@ -310,6 +477,7 @@ export interface SteeringRecoveryDescriptor {
|
|
|
310
477
|
initialToolBudget?: ResolvedToolBudget;
|
|
311
478
|
maxSubagentDepth: number;
|
|
312
479
|
maxOutput?: MaxOutputConfig;
|
|
480
|
+
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
313
481
|
share: boolean;
|
|
314
482
|
sessionDir?: string;
|
|
315
483
|
artifactsDir?: string;
|
|
@@ -365,6 +533,7 @@ export interface SubagentResultIntercomPayload {
|
|
|
365
533
|
index?: number;
|
|
366
534
|
artifactPath?: string;
|
|
367
535
|
sessionPath?: string;
|
|
536
|
+
parallelHandoff?: ParallelHandoffReference;
|
|
368
537
|
}
|
|
369
538
|
|
|
370
539
|
// ============================================================================
|
|
@@ -426,7 +595,7 @@ export interface ModelAttempt {
|
|
|
426
595
|
usage?: Usage;
|
|
427
596
|
}
|
|
428
597
|
|
|
429
|
-
export type AcceptanceLevel = "auto" | "none" | "attested" | "checked" | "verified"
|
|
598
|
+
export type AcceptanceLevel = "auto" | "none" | "attested" | "checked" | "verified";
|
|
430
599
|
|
|
431
600
|
export type AcceptanceEvidenceKind =
|
|
432
601
|
| "changed-files"
|
|
@@ -535,7 +704,7 @@ export interface AcceptanceVerifyResult {
|
|
|
535
704
|
}
|
|
536
705
|
|
|
537
706
|
export interface AcceptanceReviewResult {
|
|
538
|
-
status: "
|
|
707
|
+
status: "review-required" | "reviewed" | "blockers";
|
|
539
708
|
findings: Array<{
|
|
540
709
|
severity: "blocker" | "non-blocking";
|
|
541
710
|
file?: string;
|
|
@@ -544,19 +713,24 @@ export interface AcceptanceReviewResult {
|
|
|
544
713
|
}>;
|
|
545
714
|
}
|
|
546
715
|
|
|
547
|
-
export type
|
|
716
|
+
export type AcceptanceEvidenceStatus =
|
|
548
717
|
| "pending"
|
|
549
718
|
| "not-required"
|
|
550
719
|
| "claimed"
|
|
551
720
|
| "attested"
|
|
552
721
|
| "checked"
|
|
553
722
|
| "verified"
|
|
554
|
-
| "reviewed"
|
|
555
|
-
| "accepted"
|
|
556
723
|
| "rejected";
|
|
557
724
|
|
|
725
|
+
export type AcceptanceLedgerStatus =
|
|
726
|
+
| AcceptanceEvidenceStatus
|
|
727
|
+
| "review-required"
|
|
728
|
+
| "reviewed"
|
|
729
|
+
| "accepted";
|
|
730
|
+
|
|
558
731
|
export interface AcceptanceLedger {
|
|
559
732
|
status: AcceptanceLedgerStatus;
|
|
733
|
+
evidenceStatus: AcceptanceEvidenceStatus;
|
|
560
734
|
explicit: boolean;
|
|
561
735
|
effectiveAcceptance: ResolvedAcceptanceConfig;
|
|
562
736
|
inferredReason: string[];
|
|
@@ -585,6 +759,8 @@ export interface ProtocolOutputLimit {
|
|
|
585
759
|
export interface SingleResult {
|
|
586
760
|
agent: string;
|
|
587
761
|
task: string;
|
|
762
|
+
/** Resolved launch context for this child. */
|
|
763
|
+
context?: "fresh" | "fork";
|
|
588
764
|
exitCode: number;
|
|
589
765
|
detached?: boolean;
|
|
590
766
|
detachedReason?: string;
|
|
@@ -599,6 +775,8 @@ export interface SingleResult {
|
|
|
599
775
|
messages?: Message[];
|
|
600
776
|
usage: Usage;
|
|
601
777
|
model?: string;
|
|
778
|
+
/** Effective thinking level used by this foreground child, when known. */
|
|
779
|
+
thinking?: string;
|
|
602
780
|
attemptedModels?: string[];
|
|
603
781
|
modelAttempts?: ModelAttempt[];
|
|
604
782
|
controlEvents?: ControlEvent[];
|
|
@@ -618,13 +796,21 @@ export interface SingleResult {
|
|
|
618
796
|
outputReference?: SavedOutputReference;
|
|
619
797
|
outputSaveError?: string;
|
|
620
798
|
structuredOutput?: unknown;
|
|
799
|
+
structuredOutputFailed?: boolean;
|
|
621
800
|
structuredOutputPath?: string;
|
|
622
801
|
structuredOutputSchemaPath?: string;
|
|
623
802
|
acceptance?: AcceptanceLedger;
|
|
803
|
+
agentContract?: AgentContract;
|
|
804
|
+
launchContractDigest?: string;
|
|
805
|
+
execution?: ExecutionProjection;
|
|
806
|
+
review?: ReviewProjection;
|
|
807
|
+
effects?: EffectsProjection;
|
|
624
808
|
transcriptPath?: string;
|
|
625
809
|
transcriptError?: string;
|
|
626
810
|
children?: NestedRunSummary[];
|
|
627
811
|
watchdog?: ChildWatchdogProgress;
|
|
812
|
+
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
813
|
+
capabilityAudit?: SubagentCapabilityAudit;
|
|
628
814
|
}
|
|
629
815
|
|
|
630
816
|
export interface SpawnBudgetGrant {
|
|
@@ -648,7 +834,8 @@ export interface SpawnBudgetSnapshot {
|
|
|
648
834
|
export interface Details {
|
|
649
835
|
mode: SubagentRunMode | "management";
|
|
650
836
|
runId?: string;
|
|
651
|
-
context
|
|
837
|
+
/** Run-level context summary. "mixed" when children resolved to different modes. */
|
|
838
|
+
context?: "fresh" | "fork" | "mixed";
|
|
652
839
|
results: SingleResult[];
|
|
653
840
|
controlEvents?: ControlEvent[];
|
|
654
841
|
steering?: SteerActionResult;
|
|
@@ -683,6 +870,13 @@ export interface Details {
|
|
|
683
870
|
// Aggregated cost across all agents in the run
|
|
684
871
|
totalCost?: CostSummary;
|
|
685
872
|
spawnBudget?: SpawnBudgetSnapshot;
|
|
873
|
+
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
874
|
+
capabilityAudit?: SubagentCapabilityAudit;
|
|
875
|
+
parallelHandoff?: ParallelHandoffReference;
|
|
876
|
+
lifecycleStatus?: {
|
|
877
|
+
processTerminal?: ProcessTerminalV1;
|
|
878
|
+
};
|
|
879
|
+
launchContractDigest?: string;
|
|
686
880
|
}
|
|
687
881
|
|
|
688
882
|
// ============================================================================
|
|
@@ -697,8 +891,11 @@ export interface ArtifactPaths {
|
|
|
697
891
|
metadataPath: string;
|
|
698
892
|
}
|
|
699
893
|
|
|
894
|
+
export type ArtifactDirPreference = "project" | "session" | "temp";
|
|
895
|
+
|
|
700
896
|
export interface ArtifactConfig {
|
|
701
897
|
enabled: boolean;
|
|
898
|
+
dir?: ArtifactDirPreference;
|
|
702
899
|
includeInput: boolean;
|
|
703
900
|
includeOutput: boolean;
|
|
704
901
|
includeJsonl: boolean;
|
|
@@ -753,6 +950,9 @@ export interface NestedStepSummary {
|
|
|
753
950
|
wrapUpRequested?: boolean;
|
|
754
951
|
toolBudget?: ToolBudgetState;
|
|
755
952
|
toolBudgetBlocked?: boolean;
|
|
953
|
+
processTerminal?: ProcessTerminalV1;
|
|
954
|
+
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
955
|
+
capabilityAudit?: SubagentCapabilityAudit;
|
|
756
956
|
children?: NestedRunSummary[];
|
|
757
957
|
}
|
|
758
958
|
|
|
@@ -768,6 +968,9 @@ export interface NestedRunSummary extends NestedRunAddress {
|
|
|
768
968
|
controlInbox?: string;
|
|
769
969
|
capabilityToken?: string;
|
|
770
970
|
mode?: SubagentRunMode;
|
|
971
|
+
processTerminal?: ProcessTerminalV1;
|
|
972
|
+
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
973
|
+
capabilityAudit?: SubagentCapabilityAudit;
|
|
771
974
|
state: NestedRunState;
|
|
772
975
|
agent?: string;
|
|
773
976
|
agents?: string[];
|
|
@@ -811,6 +1014,8 @@ export interface AsyncStartedEvent {
|
|
|
811
1014
|
lifecycleArtifactVersion?: SubagentLifecycleArtifactVersion;
|
|
812
1015
|
id?: string;
|
|
813
1016
|
asyncDir?: string;
|
|
1017
|
+
/** Parent-resolved launch directory, used as a trusted artifact root while this session is live. */
|
|
1018
|
+
cwd?: string;
|
|
814
1019
|
pid?: number;
|
|
815
1020
|
sessionId?: string;
|
|
816
1021
|
mode?: SubagentRunMode;
|
|
@@ -824,10 +1029,12 @@ export interface AsyncStartedEvent {
|
|
|
824
1029
|
chainStepCount?: number;
|
|
825
1030
|
parallelGroups?: AsyncParallelGroupStatus[];
|
|
826
1031
|
workflowGraph?: WorkflowGraphSnapshot;
|
|
1032
|
+
launchContractDigest?: string;
|
|
827
1033
|
timeoutMs?: number;
|
|
828
1034
|
deadlineAt?: number;
|
|
829
1035
|
turnBudget?: TurnBudgetState;
|
|
830
1036
|
nestedRoute?: NestedRouteInfo;
|
|
1037
|
+
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
831
1038
|
}
|
|
832
1039
|
|
|
833
1040
|
export interface AsyncStatus {
|
|
@@ -865,8 +1072,14 @@ export interface AsyncStatus {
|
|
|
865
1072
|
pendingAppends?: number;
|
|
866
1073
|
parallelGroups?: AsyncParallelGroupStatus[];
|
|
867
1074
|
workflowGraph?: WorkflowGraphSnapshot;
|
|
1075
|
+
processTerminal?: ProcessTerminalV1;
|
|
1076
|
+
launchContractDigest?: string;
|
|
1077
|
+
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
1078
|
+
capabilityAudit?: SubagentCapabilityAudit;
|
|
868
1079
|
steps?: Array<{
|
|
869
1080
|
agent: string;
|
|
1081
|
+
/** Resolved launch context for this child step. */
|
|
1082
|
+
context?: "fresh" | "fork";
|
|
870
1083
|
phase?: string;
|
|
871
1084
|
label?: string;
|
|
872
1085
|
outputName?: string;
|
|
@@ -910,7 +1123,15 @@ export interface AsyncStatus {
|
|
|
910
1123
|
structuredOutputPath?: string;
|
|
911
1124
|
structuredOutputSchemaPath?: string;
|
|
912
1125
|
acceptance?: AcceptanceLedger;
|
|
1126
|
+
agentContract?: AgentContract;
|
|
1127
|
+
launchContractDigest?: string;
|
|
1128
|
+
execution?: ExecutionProjection;
|
|
1129
|
+
review?: ReviewProjection;
|
|
1130
|
+
effects?: EffectsProjection;
|
|
913
1131
|
watchdog?: ChildWatchdogProgress;
|
|
1132
|
+
processTerminal?: ProcessTerminalV1;
|
|
1133
|
+
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
1134
|
+
capabilityAudit?: SubagentCapabilityAudit;
|
|
914
1135
|
}>;
|
|
915
1136
|
sessionDir?: string;
|
|
916
1137
|
outputFile?: string;
|
|
@@ -918,6 +1139,7 @@ export interface AsyncStatus {
|
|
|
918
1139
|
totalCost?: CostSummary;
|
|
919
1140
|
sessionFile?: string;
|
|
920
1141
|
outputs?: ChainOutputMap;
|
|
1142
|
+
parallelHandoff?: ParallelHandoffReference;
|
|
921
1143
|
}
|
|
922
1144
|
|
|
923
1145
|
export type AsyncJobStep = NonNullable<AsyncStatus["steps"]>[number] & {
|
|
@@ -927,7 +1149,11 @@ export type AsyncJobStep = NonNullable<AsyncStatus["steps"]>[number] & {
|
|
|
927
1149
|
export interface AsyncJobState {
|
|
928
1150
|
asyncId: string;
|
|
929
1151
|
asyncDir: string;
|
|
1152
|
+
/** Parent-resolved launch directory retained for trusted live artifact lookup. */
|
|
1153
|
+
cwd?: string;
|
|
930
1154
|
status: "queued" | "running" | "complete" | "failed" | "paused" | "stopped";
|
|
1155
|
+
/** Short caller-facing task/goal shown in fleet surfaces when available. */
|
|
1156
|
+
description?: string;
|
|
931
1157
|
pid?: number;
|
|
932
1158
|
sessionId?: string;
|
|
933
1159
|
activityState?: ActivityState;
|
|
@@ -939,6 +1165,8 @@ export interface AsyncJobState {
|
|
|
939
1165
|
toolCount?: number;
|
|
940
1166
|
steering?: SteeringStatus;
|
|
941
1167
|
mode?: SubagentRunMode;
|
|
1168
|
+
/** Run-level context summary derived from step contexts. */
|
|
1169
|
+
context?: "fresh" | "fork" | "mixed";
|
|
942
1170
|
agents?: string[];
|
|
943
1171
|
currentStep?: number;
|
|
944
1172
|
chainStepCount?: number;
|
|
@@ -972,8 +1200,17 @@ export interface AsyncJobState {
|
|
|
972
1200
|
export interface ForegroundResumeChild {
|
|
973
1201
|
agent: string;
|
|
974
1202
|
index: number;
|
|
1203
|
+
context?: "fresh" | "fork";
|
|
975
1204
|
sessionFile?: string;
|
|
976
1205
|
status: SubagentResultStatus;
|
|
1206
|
+
activityState?: ActivityState;
|
|
1207
|
+
lastActivityAt?: number;
|
|
1208
|
+
currentTool?: string;
|
|
1209
|
+
currentToolStartedAt?: number;
|
|
1210
|
+
currentPath?: string;
|
|
1211
|
+
turnCount?: number;
|
|
1212
|
+
tokens?: number;
|
|
1213
|
+
toolCount?: number;
|
|
977
1214
|
exitCode?: number;
|
|
978
1215
|
error?: string;
|
|
979
1216
|
finalOutput?: string;
|
|
@@ -985,6 +1222,12 @@ export interface ForegroundResumeChild {
|
|
|
985
1222
|
transcriptError?: string;
|
|
986
1223
|
detachedReason?: string;
|
|
987
1224
|
acceptance?: AcceptanceLedger;
|
|
1225
|
+
agentContract?: AgentContract;
|
|
1226
|
+
execution?: ExecutionProjection;
|
|
1227
|
+
review?: ReviewProjection;
|
|
1228
|
+
effects?: EffectsProjection;
|
|
1229
|
+
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
1230
|
+
capabilityAudit?: SubagentCapabilityAudit;
|
|
988
1231
|
updatedAt?: number;
|
|
989
1232
|
}
|
|
990
1233
|
|
|
@@ -998,9 +1241,55 @@ export interface ForegroundResumeRun {
|
|
|
998
1241
|
children: ForegroundResumeChild[];
|
|
999
1242
|
}
|
|
1000
1243
|
|
|
1244
|
+
export interface ForegroundChildControl {
|
|
1245
|
+
index: number;
|
|
1246
|
+
agent: string;
|
|
1247
|
+
description?: string;
|
|
1248
|
+
startedAt: number;
|
|
1249
|
+
updatedAt: number;
|
|
1250
|
+
currentActivityState?: ActivityState;
|
|
1251
|
+
lastActivityAt?: number;
|
|
1252
|
+
currentTool?: string;
|
|
1253
|
+
currentToolStartedAt?: number;
|
|
1254
|
+
currentPath?: string;
|
|
1255
|
+
turnCount?: number;
|
|
1256
|
+
tokens?: number;
|
|
1257
|
+
toolCount?: number;
|
|
1258
|
+
interrupt?: () => boolean;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
export interface ForegroundRunControl {
|
|
1262
|
+
runId: string;
|
|
1263
|
+
mode: SubagentRunMode;
|
|
1264
|
+
startedAt: number;
|
|
1265
|
+
updatedAt: number;
|
|
1266
|
+
/** Effective working directory used to resolve live transcript artifacts. */
|
|
1267
|
+
cwd?: string;
|
|
1268
|
+
currentAgent?: string;
|
|
1269
|
+
currentIndex?: number;
|
|
1270
|
+
/** Short caller-facing task/goal shown in fleet surfaces when available. */
|
|
1271
|
+
description?: string;
|
|
1272
|
+
currentActivityState?: ActivityState;
|
|
1273
|
+
lastActivityAt?: number;
|
|
1274
|
+
currentTool?: string;
|
|
1275
|
+
currentToolStartedAt?: number;
|
|
1276
|
+
currentPath?: string;
|
|
1277
|
+
turnCount?: number;
|
|
1278
|
+
tokens?: number;
|
|
1279
|
+
toolCount?: number;
|
|
1280
|
+
/** Independently tracked children for foreground parallel work and fleet inspection. */
|
|
1281
|
+
activeChildren?: Map<number, ForegroundChildControl>;
|
|
1282
|
+
nestedRoute?: NestedRouteInfo;
|
|
1283
|
+
nestedChildren?: NestedRunSummary[];
|
|
1284
|
+
interrupt?: () => boolean;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1001
1287
|
export interface SubagentState {
|
|
1002
1288
|
baseCwd: string;
|
|
1003
1289
|
currentSessionId: string | null;
|
|
1290
|
+
/** Runtime-owned artifact resolution inputs used by Fleet transcript targeting. */
|
|
1291
|
+
artifactDirPreference?: ArtifactDirPreference;
|
|
1292
|
+
parentSessionFile?: string | null;
|
|
1004
1293
|
subagentInProgress?: boolean;
|
|
1005
1294
|
subagentSpawns?: {
|
|
1006
1295
|
sessionId: string | null;
|
|
@@ -1012,26 +1301,10 @@ export interface SubagentState {
|
|
|
1012
1301
|
asyncJobs: Map<string, AsyncJobState>;
|
|
1013
1302
|
/** Current-session active and recent async runs for the native fleet inspector. */
|
|
1014
1303
|
fleetJobs?: Map<string, AsyncJobState>;
|
|
1304
|
+
/** Suppress dynamic status widgets while the fleet overlay owns the viewport. */
|
|
1305
|
+
fleetInspectorOpen?: boolean;
|
|
1015
1306
|
foregroundRuns?: Map<string, ForegroundResumeRun>;
|
|
1016
|
-
foregroundControls: Map<string,
|
|
1017
|
-
runId: string;
|
|
1018
|
-
mode: SubagentRunMode;
|
|
1019
|
-
startedAt: number;
|
|
1020
|
-
updatedAt: number;
|
|
1021
|
-
currentAgent?: string;
|
|
1022
|
-
currentIndex?: number;
|
|
1023
|
-
currentActivityState?: ActivityState;
|
|
1024
|
-
lastActivityAt?: number;
|
|
1025
|
-
currentTool?: string;
|
|
1026
|
-
currentToolStartedAt?: number;
|
|
1027
|
-
currentPath?: string;
|
|
1028
|
-
turnCount?: number;
|
|
1029
|
-
tokens?: number;
|
|
1030
|
-
toolCount?: number;
|
|
1031
|
-
nestedRoute?: NestedRouteInfo;
|
|
1032
|
-
nestedChildren?: NestedRunSummary[];
|
|
1033
|
-
interrupt?: () => boolean;
|
|
1034
|
-
}>;
|
|
1307
|
+
foregroundControls: Map<string, ForegroundRunControl>;
|
|
1035
1308
|
lastForegroundControlId: string | null;
|
|
1036
1309
|
pendingForegroundControlNotices?: Map<string, ReturnType<typeof setTimeout>>;
|
|
1037
1310
|
cleanupTimers: Map<string, ReturnType<typeof setTimeout>>;
|
|
@@ -1074,6 +1347,7 @@ export const INTERCOM_DETACH_REQUEST_EVENT = "pi-intercom:detach-request";
|
|
|
1074
1347
|
export const INTERCOM_DETACH_RESPONSE_EVENT = "pi-intercom:detach-response";
|
|
1075
1348
|
export const SUBAGENT_ASYNC_STARTED_EVENT = "subagent:async-started";
|
|
1076
1349
|
export const SUBAGENT_ASYNC_COMPLETE_EVENT = "subagent:async-complete";
|
|
1350
|
+
export const SUBAGENT_PROCESS_TERMINAL_EVENT = "subagent:process-terminal";
|
|
1077
1351
|
export const SUBAGENT_FOREGROUND_COMPLETE_EVENT = "subagent:foreground-complete";
|
|
1078
1352
|
export const SUBAGENT_CONTROL_EVENT = "subagent:control-event";
|
|
1079
1353
|
export const SUBAGENT_CONTROL_INTERCOM_EVENT = "subagent:control-intercom";
|
|
@@ -1088,13 +1362,18 @@ export const SUBAGENT_RESULT_INTERCOM_DELIVERY_EVENT = "subagent:result-intercom
|
|
|
1088
1362
|
export interface RunSyncOptions {
|
|
1089
1363
|
/** Session id of the direct parent session for permission-system ask forwarding. */
|
|
1090
1364
|
parentSessionId?: string;
|
|
1365
|
+
/** Resolved launch context for this child. */
|
|
1366
|
+
context?: "fresh" | "fork";
|
|
1091
1367
|
cwd?: string;
|
|
1092
1368
|
signal?: AbortSignal;
|
|
1093
1369
|
interruptSignal?: AbortSignal;
|
|
1094
1370
|
timeoutMs?: number;
|
|
1095
1371
|
deadlineAt?: number;
|
|
1096
1372
|
turnBudget?: ResolvedTurnBudget;
|
|
1373
|
+
/** Enforce maxTurns + graceTurns as a hard model-turn boundary. */
|
|
1374
|
+
enforceHardTurnLimit?: boolean;
|
|
1097
1375
|
toolBudget?: ResolvedToolBudget;
|
|
1376
|
+
allowZeroToolBudget?: boolean;
|
|
1098
1377
|
allowIntercomDetach?: boolean;
|
|
1099
1378
|
intercomEvents?: IntercomEventBus;
|
|
1100
1379
|
onUpdate?: (r: import("@earendil-works/pi-agent-core").AgentToolResult<Details>) => void;
|
|
@@ -1116,6 +1395,7 @@ export interface RunSyncOptions {
|
|
|
1116
1395
|
maxSubagentDepth?: number;
|
|
1117
1396
|
/** Effective parent wait-tool setting propagated to the child runtime. */
|
|
1118
1397
|
waitToolEnabled?: boolean;
|
|
1398
|
+
capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
|
|
1119
1399
|
nestedRoute?: NestedRouteInfo;
|
|
1120
1400
|
/** Override the agent's default model (format: "provider/id" or just "id") */
|
|
1121
1401
|
modelOverride?: string;
|
|
@@ -1134,6 +1414,7 @@ export interface RunSyncOptions {
|
|
|
1134
1414
|
schemaPath: string;
|
|
1135
1415
|
outputPath: string;
|
|
1136
1416
|
};
|
|
1417
|
+
agentContract?: AgentContract;
|
|
1137
1418
|
acceptance?: AcceptanceInput;
|
|
1138
1419
|
acceptanceContext?: {
|
|
1139
1420
|
mode?: SubagentRunMode;
|
|
@@ -1178,7 +1459,9 @@ export interface ScheduledRunsConfig {
|
|
|
1178
1459
|
|
|
1179
1460
|
export interface ExtensionConfig {
|
|
1180
1461
|
asyncByDefault?: boolean;
|
|
1181
|
-
/** Show the
|
|
1462
|
+
/** Show the Claude Code-style navigable fleet below the editor. Defaults to true. */
|
|
1463
|
+
fleetView?: boolean;
|
|
1464
|
+
/** Show the legacy above-editor async runs widget. Defaults to true only when fleetView is disabled. */
|
|
1182
1465
|
asyncWidget?: boolean;
|
|
1183
1466
|
/** Tool description variant registered for the parent-facing subagent tool. Defaults to full. */
|
|
1184
1467
|
toolDescriptionMode?: ToolDescriptionMode;
|
|
@@ -1200,6 +1483,8 @@ export interface ExtensionConfig {
|
|
|
1200
1483
|
worktreeSetupHook?: string;
|
|
1201
1484
|
worktreeSetupHookTimeoutMs?: number;
|
|
1202
1485
|
worktreeBaseDir?: string;
|
|
1486
|
+
/** Where to store subagent artifact files. Defaults to "project" (cwd/.pi-subagents). Set to "session" for pi session dir, or "temp" for OS temp. */
|
|
1487
|
+
artifactDir?: ArtifactDirPreference;
|
|
1203
1488
|
intercomBridge?: IntercomBridgeConfig;
|
|
1204
1489
|
proactiveSkillSubagents?: ProactiveSkillSubagentsConfig | false;
|
|
1205
1490
|
scheduledRuns?: ScheduledRunsConfig;
|
|
@@ -1216,6 +1501,7 @@ export const DEFAULT_MAX_OUTPUT: Required<MaxOutputConfig> = {
|
|
|
1216
1501
|
|
|
1217
1502
|
export const DEFAULT_ARTIFACT_CONFIG: ArtifactConfig = {
|
|
1218
1503
|
enabled: true,
|
|
1504
|
+
dir: "project",
|
|
1219
1505
|
includeInput: true,
|
|
1220
1506
|
includeOutput: true,
|
|
1221
1507
|
includeJsonl: false,
|
package/src/shared/utils.ts
CHANGED
|
@@ -412,6 +412,14 @@ export function compactForegroundDetails(details: Details): Details {
|
|
|
412
412
|
};
|
|
413
413
|
}
|
|
414
414
|
|
|
415
|
+
export function hasEmptyTerminalAssistantResponse(messages: Message[]): boolean {
|
|
416
|
+
const lastAssistant = messages.findLast((message) => message.role === "assistant");
|
|
417
|
+
return lastAssistant?.role === "assistant"
|
|
418
|
+
&& Array.isArray(lastAssistant.content)
|
|
419
|
+
&& lastAssistant.content.length === 0
|
|
420
|
+
&& lastAssistant.usage.output === 0;
|
|
421
|
+
}
|
|
422
|
+
|
|
415
423
|
/**
|
|
416
424
|
* Detect errors in subagent execution from messages (only errors with no subsequent success)
|
|
417
425
|
*/
|
|
@@ -438,50 +446,17 @@ export function detectSubagentError(messages: Message[]): ErrorInfo {
|
|
|
438
446
|
const toolName = "toolName" in msg && typeof msg.toolName === "string" ? msg.toolName : undefined;
|
|
439
447
|
const isError = "isError" in msg && msg.isError === true;
|
|
440
448
|
|
|
441
|
-
if (isError)
|
|
442
|
-
const text = msg.content.find((c) => c.type === "text");
|
|
443
|
-
const details = text && "text" in text ? text.text : undefined;
|
|
444
|
-
const exitMatch = details?.match(/exit(?:ed)?\s*(?:with\s*)?(?:code|status)?\s*[:\s]?\s*(\d+)/i);
|
|
445
|
-
return {
|
|
446
|
-
hasError: true,
|
|
447
|
-
exitCode: exitMatch ? parseInt(exitMatch[1], 10) : 1,
|
|
448
|
-
errorType: toolName || "tool",
|
|
449
|
-
details: details?.slice(0, 200),
|
|
450
|
-
};
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
if (toolName !== "bash") continue;
|
|
449
|
+
if (!isError) continue;
|
|
454
450
|
|
|
455
451
|
const text = msg.content.find((c) => c.type === "text");
|
|
456
|
-
|
|
457
|
-
const
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
// NOTE: These patterns can match legitimate output (grep results, logs,
|
|
468
|
-
// testing). With the assistant-message check above, most false positives
|
|
469
|
-
// are mitigated since the agent will have responded after routine errors.
|
|
470
|
-
const fatalPatterns = [
|
|
471
|
-
/command not found/i,
|
|
472
|
-
/permission denied/i,
|
|
473
|
-
/no such file or directory/i,
|
|
474
|
-
/segmentation fault/i,
|
|
475
|
-
/killed|terminated/i,
|
|
476
|
-
/out of memory/i,
|
|
477
|
-
/connection refused/i,
|
|
478
|
-
/timeout/i,
|
|
479
|
-
];
|
|
480
|
-
for (const pattern of fatalPatterns) {
|
|
481
|
-
if (pattern.test(output)) {
|
|
482
|
-
return { hasError: true, exitCode: 1, errorType: "bash", details: output.slice(0, 200) };
|
|
483
|
-
}
|
|
484
|
-
}
|
|
452
|
+
const details = text && "text" in text ? text.text : undefined;
|
|
453
|
+
const exitMatch = details?.match(/exit(?:ed)?\s*(?:with\s*)?(?:code|status)?\s*[:\s]?\s*(\d+)/i);
|
|
454
|
+
return {
|
|
455
|
+
hasError: true,
|
|
456
|
+
exitCode: exitMatch ? parseInt(exitMatch[1], 10) : 1,
|
|
457
|
+
errorType: toolName || "tool",
|
|
458
|
+
details: details?.slice(0, 200),
|
|
459
|
+
};
|
|
485
460
|
}
|
|
486
461
|
|
|
487
462
|
return { hasError: false };
|