pi-subagents 0.65.1 → 0.67.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.
Files changed (148) hide show
  1. package/CHANGELOG.md +123 -0
  2. package/README.md +5 -4
  3. package/agents/evidence-auditor.md +34 -0
  4. package/agents/researcher.md +23 -13
  5. package/agents/reviewer.md +3 -2
  6. package/docs/agents.md +20 -3
  7. package/docs/configuration.md +25 -5
  8. package/docs/extension-api.md +124 -18
  9. package/docs/missions.md +8 -0
  10. package/docs/models.md +59 -2
  11. package/docs/observability.md +46 -6
  12. package/docs/standalone-background.md +49 -0
  13. package/docs/tool-reference.md +20 -10
  14. package/docs/watchdog.md +35 -4
  15. package/docs/workflows.md +40 -19
  16. package/inspector-runner.mjs +2 -2
  17. package/package.json +2 -1
  18. package/prompts/parallel-review.md +1 -1
  19. package/{runner-server-preload.mjs → runner-peer-preload.mjs} +8 -3
  20. package/skills/pi-subagents/SKILL.md +14 -0
  21. package/skills/pi-subagents/references/execution-controls.md +20 -5
  22. package/skills/pi-subagents/references/management-authoring-rpc.md +2 -1
  23. package/skills/pi-subagents/references/prompting-and-roles.md +2 -2
  24. package/src/agents/advertised-agent-prompt.ts +94 -0
  25. package/src/agents/agent-management.ts +14 -1
  26. package/src/agents/agent-serializer.ts +2 -0
  27. package/src/agents/agents.ts +14 -0
  28. package/src/agents/builtin-names.ts +1 -0
  29. package/src/api/delegation.ts +4 -0
  30. package/src/api/preflight.ts +76 -45
  31. package/src/api/shared-types.ts +3 -1
  32. package/src/api/workflow-resources.ts +6 -0
  33. package/src/extension/fanout-child.ts +63 -4
  34. package/src/extension/index.ts +58 -8
  35. package/src/extension/public-execution.ts +4 -3
  36. package/src/extension/rpc.ts +8 -21
  37. package/src/extension/schemas.ts +71 -80
  38. package/src/extension/tool-description.ts +29 -81
  39. package/src/inspectors/actions.ts +148 -0
  40. package/src/inspectors/ghostty/actions.ts +74 -0
  41. package/src/inspectors/ghostty/plugin.ts +17 -0
  42. package/src/inspectors/herdr/actions.ts +99 -179
  43. package/src/inspectors/herdr/plugin.ts +20 -0
  44. package/src/inspectors/herdr/project-panes.ts +1 -1
  45. package/src/inspectors/{herdr/inspector-runner.ts → inspector-runner.ts} +12 -12
  46. package/src/inspectors/plugins.ts +8 -0
  47. package/src/inspectors/{herdr/session-roots-codec.ts → session-roots-codec.ts} +3 -14
  48. package/src/inspectors/types.ts +51 -0
  49. package/src/intercom/intercom-bridge.ts +50 -8
  50. package/src/intercom/native-supervisor-channel.ts +104 -67
  51. package/src/runs/background/active-async-capacity.ts +22 -18
  52. package/src/runs/background/async-execution.ts +45 -56
  53. package/src/runs/background/async-job-tracker.ts +35 -3
  54. package/src/runs/background/async-resume.ts +5 -9
  55. package/src/runs/background/async-status-snapshot.ts +10 -12
  56. package/src/runs/background/async-status.ts +17 -9
  57. package/src/runs/background/auto-drain.ts +44 -30
  58. package/src/runs/background/binary-bootstrap.ts +33 -0
  59. package/src/runs/background/chain-root-attachment.ts +8 -0
  60. package/src/runs/background/control-channel.ts +78 -44
  61. package/src/runs/background/fleet-view.ts +30 -2
  62. package/src/runs/background/notify.ts +117 -13
  63. package/src/runs/background/owned-process-tree.ts +35 -8
  64. package/src/runs/background/process-terminal.ts +23 -23
  65. package/src/runs/background/run-child-session.ts +121 -36
  66. package/src/runs/background/run-status.ts +78 -5
  67. package/src/runs/background/runner-aliases.ts +28 -9
  68. package/src/runs/background/runner-child-launch.ts +88 -0
  69. package/src/runs/background/runner-child-sessions.ts +5 -4
  70. package/src/runs/background/scheduled-runs.ts +40 -13
  71. package/src/runs/background/stale-run-reconciler.ts +3 -1
  72. package/src/runs/background/steering.ts +20 -2
  73. package/src/runs/background/subagent-runner.ts +458 -239
  74. package/src/runs/background/subagent-wait.ts +54 -8
  75. package/src/runs/background/wait-completions.ts +4 -0
  76. package/src/runs/background/wait-tool.ts +1 -1
  77. package/src/runs/foreground/async-steering-action.ts +37 -7
  78. package/src/runs/foreground/execution.ts +145 -56
  79. package/src/runs/foreground/prompt-audit.ts +3 -1
  80. package/src/runs/foreground/subagent-executor.ts +584 -297
  81. package/src/runs/foreground/workflow-detach-reconcile.ts +10 -5
  82. package/src/runs/foreground/workflow-foreground-steering.ts +57 -2
  83. package/src/runs/shared/acceptance.ts +7 -4
  84. package/src/runs/shared/agent-contract.ts +1 -1
  85. package/src/runs/shared/async-status-projection.ts +51 -47
  86. package/src/runs/shared/capability-ceiling.ts +2 -0
  87. package/src/runs/shared/child-hooks.ts +167 -3
  88. package/src/runs/shared/child-launch.ts +28 -13
  89. package/src/runs/shared/child-lifecycle.ts +6 -3
  90. package/src/runs/shared/child-runtime-config.ts +3 -1
  91. package/src/runs/shared/child-session.ts +75 -8
  92. package/src/runs/shared/child-tool-plan.ts +124 -5
  93. package/src/runs/shared/completion-evidence.ts +2 -2
  94. package/src/runs/shared/completion-guard.ts +6 -3
  95. package/src/runs/shared/effective-system-prompt.ts +33 -0
  96. package/src/runs/shared/external-cli-runner.ts +9 -7
  97. package/src/runs/shared/host-step-status.ts +11 -11
  98. package/src/runs/shared/llm-intent-arbiter.ts +21 -11
  99. package/src/runs/shared/model-fallback.ts +12 -6
  100. package/src/runs/shared/nested-events.ts +5 -5
  101. package/src/runs/shared/orca-progress-tabs.ts +7 -1
  102. package/src/runs/shared/parallel-handoff.ts +57 -12
  103. package/src/runs/shared/parallel-utils.ts +2 -2
  104. package/src/runs/shared/pi-spawn.ts +10 -0
  105. package/src/runs/shared/readonly-drain-observation.ts +42 -0
  106. package/src/runs/shared/readonly-model-continuation.ts +69 -0
  107. package/src/runs/shared/readonly-session-evidence.ts +307 -0
  108. package/src/runs/shared/run-fanout-budget.ts +8 -8
  109. package/src/runs/shared/runtime-acknowledged-extensions.ts +3 -3
  110. package/src/runs/shared/subagent-prompt-runtime.ts +20 -4
  111. package/src/runs/shared/task-intent.ts +46 -13
  112. package/src/runs/shared/workflow-async-child-guidance.ts +18 -0
  113. package/src/runs/shared/worktree-setup-command.ts +190 -0
  114. package/src/runs/shared/worktree.ts +366 -208
  115. package/src/shared/fork-context.ts +15 -72
  116. package/src/shared/launch-contract.ts +65 -2
  117. package/src/shared/opencode-session-headers.ts +30 -0
  118. package/src/shared/types.ts +85 -61
  119. package/src/shared/utils.ts +7 -2
  120. package/src/shared/workflow-child-permit.ts +18 -13
  121. package/src/slash/delegation-adapters.ts +3 -1
  122. package/src/slash/delegation-request.ts +14 -0
  123. package/src/slash/slash-commands.ts +2 -1
  124. package/src/slash/subagents-admin.ts +11 -4
  125. package/src/tui/fleet-status.ts +164 -19
  126. package/src/tui/fleet.ts +27 -19
  127. package/src/tui/render.ts +172 -33
  128. package/src/watchdog/child-status.ts +8 -0
  129. package/src/watchdog/model-selection.ts +20 -0
  130. package/src/watchdog/permission-arbiter.ts +3 -1
  131. package/src/watchdog/register-child.ts +1 -0
  132. package/src/watchdog/register-main.ts +31 -27
  133. package/src/watchdog/review.ts +132 -67
  134. package/src/watchdog/runtime.ts +82 -20
  135. package/src/watchdog/scope.ts +1 -1
  136. package/src/watchdog/settings.ts +9 -3
  137. package/src/watchdog/tool-actions.ts +13 -12
  138. package/src/watchdog/turn-delta.ts +23 -0
  139. package/src/watchdog/types.ts +4 -0
  140. package/src/workflows/chat-progress.ts +3 -3
  141. package/src/workflows/scripted-workflow.ts +275 -17
  142. package/src/workflows/workflow-checklist.ts +13 -17
  143. package/src/workflows/workflow-child-summary.ts +57 -8
  144. package/src/workflows/workflow-preflight.ts +19 -19
  145. package/src/workflows/workflow-receipt.ts +3 -3
  146. package/src/workflows/workflow-resources.ts +96 -21
  147. package/src/workflows/workflow-settlement.ts +3 -0
  148. /package/src/inspectors/{herdr/shell-command.ts → shell-command.ts} +0 -0
@@ -47,14 +47,14 @@ export type HostStepMonitorKind = "command" | "ci" | "gate";
47
47
  export type HostStepState = "pending" | "running" | "done" | "cancelled" | "error";
48
48
  export type HostStepVerdict = "pass" | "fail" | "inconclusive";
49
49
 
50
- export interface HostStepFreshnessV1 {
50
+ export interface HostStepFreshness {
51
51
  expectedRef: string;
52
52
  observedRef?: string;
53
53
  stale?: boolean;
54
54
  }
55
55
 
56
56
  /** Bounded, provider-agnostic status for a host-owned workflow monitor. */
57
- export interface HostStepNodeV1 {
57
+ export interface HostStepNode {
58
58
  version: 1;
59
59
  kind: "host-step";
60
60
  /** Explicit monitor category; never inferred from labels or commands. */
@@ -68,7 +68,7 @@ export interface HostStepNodeV1 {
68
68
  reasonCode?: string;
69
69
  detail?: string;
70
70
  target?: string;
71
- freshness?: HostStepFreshnessV1;
71
+ freshness?: HostStepFreshness;
72
72
  reportPath?: string;
73
73
  exitCode?: number | null;
74
74
  updatedAt: number;
@@ -97,7 +97,7 @@ export interface WorkflowGraphNode {
97
97
  structured?: boolean;
98
98
  acceptanceStatus?: AcceptanceLedgerStatus;
99
99
  error?: string;
100
- hostStep?: HostStepNodeV1;
100
+ hostStep?: HostStepNode;
101
101
  }
102
102
 
103
103
  export interface WorkflowGraphSnapshot {
@@ -112,7 +112,7 @@ export type WorkflowPreflightCoverage = "complete" | "partial";
112
112
  export type WorkflowPreflightMode = "mutation" | "review" | "scout" | "gate";
113
113
 
114
114
  /** Bounded, display-only lane hints supplied alongside a workflowScript launch. */
115
- export interface WorkflowPreflightLaneV1 {
115
+ export interface WorkflowPreflightLane {
116
116
  key: string;
117
117
  mode?: WorkflowPreflightMode;
118
118
  decision?: string;
@@ -122,10 +122,10 @@ export interface WorkflowPreflightLaneV1 {
122
122
  }
123
123
 
124
124
  /** Versioned, display-only workflow launch plan; it never grants launch authority. */
125
- export interface WorkflowPreflightV1 {
125
+ export interface WorkflowPreflight {
126
126
  version: 1;
127
127
  coverage: WorkflowPreflightCoverage;
128
- lanes: WorkflowPreflightLaneV1[];
128
+ lanes: WorkflowPreflightLane[];
129
129
  }
130
130
 
131
131
  export type WorkflowReceiptState = "complete" | "failed" | "paused" | "stopped";
@@ -149,7 +149,7 @@ export interface WorkflowRecoveryAction {
149
149
  * Permission/policy extensions can use it to distinguish resolved content from
150
150
  * raw workflow scripts. This audit projection never grants execution authority.
151
151
  */
152
- export interface WorkflowResourceProvenanceV1 {
152
+ export interface WorkflowResourceProvenance {
153
153
  kind: "workflow";
154
154
  name: string;
155
155
  version: number;
@@ -174,7 +174,20 @@ export interface WorkflowLaneMetadata {
174
174
  outputPaths?: string[];
175
175
  }
176
176
 
177
- export interface WorkflowChildSummaryV1 {
177
+ /** Bounded foreground activity; excludes tool arguments and transcript content. */
178
+ export interface WorkflowChildActivity {
179
+ currentTool?: string;
180
+ currentToolStartedAt?: number;
181
+ lastActivityAt?: number;
182
+ durationMs?: number;
183
+ toolCount?: number;
184
+ turnCount?: number;
185
+ tokens?: number;
186
+ inputTokens?: number;
187
+ outputTokens?: number;
188
+ }
189
+
190
+ export interface WorkflowChildSummary {
178
191
  version: 1;
179
192
  parentToolCallId: string;
180
193
  workflowRunId: string;
@@ -188,6 +201,8 @@ export interface WorkflowChildSummaryV1 {
188
201
  sessionName?: string;
189
202
  model?: string;
190
203
  thinking?: string;
204
+ /** Present only while a synchronous foreground child is running. */
205
+ activity?: WorkflowChildActivity;
191
206
  state: "pending" | "running" | "completed" | "failed" | "paused" | "stopped" | "rejected" | "detached";
192
207
  }>;
193
208
  }
@@ -215,9 +230,9 @@ export interface WorkflowReceipt {
215
230
  state: WorkflowReceiptState;
216
231
  createdAt: number;
217
232
  entries: Record<string, WorkflowReceiptEntry>;
218
- resource?: WorkflowResourceProvenanceV1;
219
- hostSteps?: HostStepNodeV1[];
220
- workflowChildren?: WorkflowChildSummaryV1;
233
+ resource?: WorkflowResourceProvenance;
234
+ hostSteps?: HostStepNode[];
235
+ workflowChildren?: WorkflowChildSummary;
221
236
  workflowResolution?: WorkflowTerminalResolution;
222
237
  terminalOutcome?: WorkflowTerminalOutcome;
223
238
  recovery?: WorkflowRecoveryAction[];
@@ -625,7 +640,7 @@ export type ProcessTerminalReason =
625
640
  | "proof-write-failed"
626
641
  | "stale-repair";
627
642
 
628
- export interface RunnerProcessInstanceExitV1 {
643
+ export interface RunnerProcessInstanceExit {
629
644
  processInstanceId: string;
630
645
  kind: "runner";
631
646
  closeObservedAt: number;
@@ -633,7 +648,7 @@ export interface RunnerProcessInstanceExitV1 {
633
648
  signal: string | null;
634
649
  }
635
650
 
636
- export type ProcessTreeTerminalV1 =
651
+ export type ProcessTreeTerminal =
637
652
  | {
638
653
  state: "observed";
639
654
  mechanism: "posix-process-group";
@@ -646,26 +661,26 @@ export type ProcessTreeTerminalV1 =
646
661
  diagnostic?: string;
647
662
  };
648
663
 
649
- export interface PiWriterProcessInstanceExitV1 {
664
+ export interface PiWriterProcessInstanceExit {
650
665
  processInstanceId: string;
651
666
  kind: "pi-writer";
652
667
  attempt: number;
653
668
  closeObservedAt: number;
654
669
  exitCode: number | null;
655
670
  signal: string | null;
656
- processTree: ProcessTreeTerminalV1;
671
+ processTree: ProcessTreeTerminal;
657
672
  }
658
673
 
659
- export type ProcessInstanceExitV1 = RunnerProcessInstanceExitV1 | PiWriterProcessInstanceExitV1;
674
+ export type ProcessInstanceExit = RunnerProcessInstanceExit | PiWriterProcessInstanceExit;
660
675
 
661
- export interface CanonicalSessionTerminalV1 {
676
+ export interface CanonicalSessionTerminal {
662
677
  canonicalSessionId: string;
663
678
  leaseDisposition: "released" | "not-held";
664
679
  freeAtObservation: true;
665
680
  canonicalSessionLeaseReleased?: true;
666
681
  }
667
682
 
668
- interface ProcessTerminalBaseV1 {
683
+ interface ProcessTerminalBase {
669
684
  version: 1;
670
685
  runId: string;
671
686
  childIndex?: number;
@@ -675,15 +690,15 @@ interface ProcessTerminalBaseV1 {
675
690
  resumeDisposition?: "resumable" | "non-resumable" | "unavailable";
676
691
  }
677
692
 
678
- export type ProcessTerminalV1 =
679
- | (ProcessTerminalBaseV1 & { state: "pending" | "not-started" })
680
- | (ProcessTerminalBaseV1 & {
693
+ export type ProcessTerminal =
694
+ | (ProcessTerminalBase & { state: "pending" | "not-started" })
695
+ | (ProcessTerminalBase & {
681
696
  state: "observed";
682
697
  observedAt: number;
683
- instances: ProcessInstanceExitV1[];
684
- canonicalSession?: CanonicalSessionTerminalV1;
698
+ instances: ProcessInstanceExit[];
699
+ canonicalSession?: CanonicalSessionTerminal;
685
700
  })
686
- | (ProcessTerminalBaseV1 & {
701
+ | (ProcessTerminalBase & {
687
702
  state: "unknown";
688
703
  reason: ProcessTerminalReason;
689
704
  diagnostic?: string;
@@ -693,6 +708,7 @@ export type ProcessTerminalV1 =
693
708
  export interface ScheduleOrigin {
694
709
  id: string;
695
710
  name?: string;
711
+ quiet?: boolean;
696
712
  }
697
713
 
698
714
  export type SteeringActionState = "delivered" | "scheduled" | "pending" | "partial" | "recovered" | "failed";
@@ -832,7 +848,7 @@ export interface SteeringRecoveryDescriptor {
832
848
  maxSubagentDepth: number;
833
849
  maxOutput?: MaxOutputConfig;
834
850
  capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
835
- launchResolvedExtensions?: LaunchResolvedChildExtensionsV1;
851
+ launchResolvedExtensions?: LaunchResolvedChildExtensions;
836
852
  share: boolean;
837
853
  sessionDir?: string;
838
854
  artifactsDir?: string;
@@ -1164,7 +1180,7 @@ export interface AcceptanceLedger {
1164
1180
  };
1165
1181
  }
1166
1182
 
1167
- export interface LaunchResolvedChildExtensionsV1 {
1183
+ export interface LaunchResolvedChildExtensions {
1168
1184
  version: 1;
1169
1185
  /** This is parent-resolved launch intent, not child-runtime acknowledgement that extensions loaded. */
1170
1186
  source: "launch-resolved";
@@ -1179,7 +1195,7 @@ export interface LaunchResolvedChildExtensionsV1 {
1179
1195
  };
1180
1196
  }
1181
1197
 
1182
- export interface RuntimeAcknowledgedChildExtensionsV1 {
1198
+ export interface RuntimeAcknowledgedChildExtensions {
1183
1199
  version: 1;
1184
1200
  /** Best-effort child-runtime registration acknowledgement, not extension health. */
1185
1201
  source: "child-runtime";
@@ -1282,8 +1298,8 @@ export interface SingleResult {
1282
1298
  acceptance?: AcceptanceLedger;
1283
1299
  agentContract?: AgentContract;
1284
1300
  launchContractDigest?: string;
1285
- launchResolvedExtensions?: LaunchResolvedChildExtensionsV1;
1286
- runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensionsV1;
1301
+ launchResolvedExtensions?: LaunchResolvedChildExtensions;
1302
+ runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensions;
1287
1303
  execution?: ExecutionProjection;
1288
1304
  review?: ReviewProjection;
1289
1305
  effects?: EffectsProjection;
@@ -1341,6 +1357,7 @@ export interface WaitCompletionChild {
1341
1357
  */
1342
1358
  export interface WaitCompletion {
1343
1359
  runId: string;
1360
+ workflowReceiptPath?: string;
1344
1361
  agent?: string;
1345
1362
  mode?: string;
1346
1363
  state?: string;
@@ -1348,7 +1365,7 @@ export interface WaitCompletion {
1348
1365
  /** Versioned bounded output archive retained with the durable completion replay. */
1349
1366
  archivePath?: string;
1350
1367
  results?: WaitCompletionChild[];
1351
- workflowChildren?: WorkflowChildSummaryV1;
1368
+ workflowChildren?: WorkflowChildSummary;
1352
1369
  }
1353
1370
 
1354
1371
  export interface AgentCapabilitiesSnapshot {
@@ -1374,13 +1391,14 @@ export interface AgentCapabilityRow {
1374
1391
 
1375
1392
  export interface Details {
1376
1393
  mode: SubagentResultMode | "management";
1394
+ workflowReceiptPath?: string;
1377
1395
  runId?: string;
1378
1396
  /** Host tool-call id retained when it differs from the internal run id. */
1379
1397
  toolCallId?: string;
1380
1398
  /** Run-level context summary. "mixed" when children resolved to different modes. */
1381
1399
  context?: "fresh" | "fork" | "mixed";
1382
1400
  results: SingleResult[];
1383
- workflowChildren?: WorkflowChildSummaryV1;
1401
+ workflowChildren?: WorkflowChildSummary;
1384
1402
  /**
1385
1403
  * Terminal completion payloads for runs this bg_wait call observed
1386
1404
  * finishing. Async completions travel as result files that are consumed and
@@ -1423,7 +1441,7 @@ export interface Details {
1423
1441
  currentStepIndex?: number; // 0-indexed current step (for running chains)
1424
1442
  workflowGraph?: WorkflowGraphSnapshot;
1425
1443
  /** Validated, display-only fanout plan supplied with a workflow launch. */
1426
- preflight?: WorkflowPreflightV1;
1444
+ preflight?: WorkflowPreflight;
1427
1445
  preflightWarnings?: string[];
1428
1446
  outputs?: ChainOutputMap;
1429
1447
  // Aggregated child usage across all agents in the run
@@ -1439,11 +1457,11 @@ export interface Details {
1439
1457
  capabilityAudit?: SubagentCapabilityAudit;
1440
1458
  parallelHandoff?: ParallelHandoffReference;
1441
1459
  lifecycleStatus?: {
1442
- processTerminal?: ProcessTerminalV1;
1460
+ processTerminal?: ProcessTerminal;
1443
1461
  };
1444
1462
  launchContractDigest?: string;
1445
- launchResolvedExtensions?: LaunchResolvedChildExtensionsV1;
1446
- runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensionsV1;
1463
+ launchResolvedExtensions?: LaunchResolvedChildExtensions;
1464
+ runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensions;
1447
1465
  /** Original launch contract whose persisted session is being revived. */
1448
1466
  sourceLaunchContractDigest?: string;
1449
1467
  /** Durable mission attached to this run, when mission mode was explicitly used. */
@@ -1454,7 +1472,7 @@ export interface Details {
1454
1472
  mission?: MissionRecord;
1455
1473
  workflow?: {
1456
1474
  value?: unknown;
1457
- resource?: WorkflowResourceProvenanceV1;
1475
+ resource?: WorkflowResourceProvenance;
1458
1476
  preflightWarnings?: string[];
1459
1477
  trace: Array<{
1460
1478
  operation: "run" | "status" | "steer" | "host";
@@ -1567,9 +1585,9 @@ export interface NestedStepSummary {
1567
1585
  wrapUpRequested?: boolean;
1568
1586
  toolBudget?: ToolBudgetState;
1569
1587
  toolBudgetBlocked?: boolean;
1570
- processTerminal?: ProcessTerminalV1;
1571
- launchResolvedExtensions?: LaunchResolvedChildExtensionsV1;
1572
- runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensionsV1;
1588
+ processTerminal?: ProcessTerminal;
1589
+ launchResolvedExtensions?: LaunchResolvedChildExtensions;
1590
+ runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensions;
1573
1591
  capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
1574
1592
  capabilityAudit?: SubagentCapabilityAudit;
1575
1593
  children?: NestedRunSummary[];
@@ -1587,9 +1605,9 @@ export interface NestedRunSummary extends NestedRunAddress {
1587
1605
  controlInbox?: string;
1588
1606
  capabilityToken?: string;
1589
1607
  mode?: SubagentRunMode;
1590
- processTerminal?: ProcessTerminalV1;
1591
- launchResolvedExtensions?: LaunchResolvedChildExtensionsV1;
1592
- runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensionsV1;
1608
+ processTerminal?: ProcessTerminal;
1609
+ launchResolvedExtensions?: LaunchResolvedChildExtensions;
1610
+ runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensions;
1593
1611
  capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
1594
1612
  capabilityAudit?: SubagentCapabilityAudit;
1595
1613
  state: NestedRunState;
@@ -1657,10 +1675,10 @@ export interface AsyncStartedEvent {
1657
1675
  chainStepCount?: number;
1658
1676
  parallelGroups?: AsyncParallelGroupStatus[];
1659
1677
  workflowGraph?: WorkflowGraphSnapshot;
1660
- preflight?: WorkflowPreflightV1;
1678
+ preflight?: WorkflowPreflight;
1661
1679
  launchContractDigest?: string;
1662
- launchResolvedExtensions?: LaunchResolvedChildExtensionsV1;
1663
- runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensionsV1;
1680
+ launchResolvedExtensions?: LaunchResolvedChildExtensions;
1681
+ runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensions;
1664
1682
  usageBudget?: UsageBudgetState;
1665
1683
  timeoutMs?: number;
1666
1684
  deadlineAt?: number;
@@ -1781,6 +1799,8 @@ export interface ExternalProcessStatus {
1781
1799
  }
1782
1800
 
1783
1801
  export interface AsyncStatus {
1802
+ /** Exact reference returned by successful current workflow receipt publication. */
1803
+ workflowReceiptPath?: string;
1784
1804
  lifecycleArtifactVersion?: SubagentLifecycleArtifactVersion;
1785
1805
  runId: string;
1786
1806
  /** Parent Pi process/window that owns local completion delivery. */
@@ -1825,17 +1845,17 @@ export interface AsyncStatus {
1825
1845
  pendingAppends?: number;
1826
1846
  parallelGroups?: AsyncParallelGroupStatus[];
1827
1847
  workflowGraph?: WorkflowGraphSnapshot;
1828
- preflight?: WorkflowPreflightV1;
1829
- processTerminal?: ProcessTerminalV1;
1848
+ preflight?: WorkflowPreflight;
1849
+ processTerminal?: ProcessTerminal;
1830
1850
  runFanoutBudget?: RunFanoutBudgetSnapshot;
1831
1851
  runFanoutBudgetDescriptor?: RunFanoutBudgetDescriptor;
1832
1852
  launchContractDigest?: string;
1833
- launchResolvedExtensions?: LaunchResolvedChildExtensionsV1;
1834
- runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensionsV1;
1853
+ launchResolvedExtensions?: LaunchResolvedChildExtensions;
1854
+ runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensions;
1835
1855
  capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
1836
1856
  capabilityAudit?: SubagentCapabilityAudit;
1837
1857
  workflow?: Details["workflow"];
1838
- workflowChildren?: WorkflowChildSummaryV1;
1858
+ workflowChildren?: WorkflowChildSummary;
1839
1859
  parentWorkflowRunId?: string;
1840
1860
  workflowKey?: string;
1841
1861
  lane?: WorkflowLaneMetadata;
@@ -1921,13 +1941,13 @@ export interface AsyncStatus {
1921
1941
  acceptance?: AcceptanceLedger;
1922
1942
  agentContract?: AgentContract;
1923
1943
  launchContractDigest?: string;
1924
- launchResolvedExtensions?: LaunchResolvedChildExtensionsV1;
1925
- runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensionsV1;
1944
+ launchResolvedExtensions?: LaunchResolvedChildExtensions;
1945
+ runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensions;
1926
1946
  execution?: ExecutionProjection;
1927
1947
  review?: ReviewProjection;
1928
1948
  effects?: EffectsProjection;
1929
1949
  watchdog?: ChildWatchdogProgress;
1930
- processTerminal?: ProcessTerminalV1;
1950
+ processTerminal?: ProcessTerminal;
1931
1951
  capabilityCeiling?: ResolvedSubagentCapabilityCeiling;
1932
1952
  capabilityAudit?: SubagentCapabilityAudit;
1933
1953
  }>;
@@ -1977,11 +1997,11 @@ export interface AsyncJobState {
1977
1997
  chainStepCount?: number;
1978
1998
  parallelGroups?: AsyncParallelGroupStatus[];
1979
1999
  /** Bounded host-owned CI/gate nodes loaded from the workflow status graph. */
1980
- hostSteps?: HostStepNodeV1[];
2000
+ hostSteps?: HostStepNode[];
1981
2001
  /** Full bounded workflow plan, including not-yet-materialized stages. */
1982
2002
  workflowGraph?: WorkflowGraphSnapshot;
1983
2003
  steps?: AsyncJobStep[];
1984
- preflight?: WorkflowPreflightV1;
2004
+ preflight?: WorkflowPreflight;
1985
2005
  stepsTotal?: number;
1986
2006
  runningSteps?: number;
1987
2007
  completedSteps?: number;
@@ -2010,7 +2030,7 @@ export interface AsyncJobState {
2010
2030
  parentWorkflowRunId?: string;
2011
2031
  workflowKey?: string;
2012
2032
  workflow?: Details["workflow"];
2013
- workflowChildren?: WorkflowChildSummaryV1;
2033
+ workflowChildren?: WorkflowChildSummary;
2014
2034
  lane?: WorkflowLaneMetadata;
2015
2035
  }
2016
2036
 
@@ -2059,8 +2079,8 @@ export interface ForegroundResumeChild {
2059
2079
  launchContractDigest?: string;
2060
2080
  /** Private retained launch authority. Never project into status or result output. */
2061
2081
  extensionBindings?: ExtensionBindings;
2062
- launchResolvedExtensions?: LaunchResolvedChildExtensionsV1;
2063
- runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensionsV1;
2082
+ launchResolvedExtensions?: LaunchResolvedChildExtensions;
2083
+ runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensions;
2064
2084
  execution?: ExecutionProjection;
2065
2085
  review?: ReviewProjection;
2066
2086
  effects?: EffectsProjection;
@@ -2187,6 +2207,8 @@ export interface ActiveAsyncCapacitySnapshot {
2187
2207
  export interface SubagentState {
2188
2208
  baseCwd: string;
2189
2209
  currentSessionId: string | null;
2210
+ /** Exact SDK runtime session ID for supervisor ownership; never a session file path. */
2211
+ supervisorOwnerSessionId?: string | null;
2190
2212
  /** Session for which active status projections were restored successfully. */
2191
2213
  statusProjectionSessionId?: string | null;
2192
2214
  /** Reload-stable identity for this parent Pi process/window. */
@@ -2373,7 +2395,7 @@ export interface RunSyncOptions {
2373
2395
  /** Internal foreground receipt proposal; returns true only when the outer waiter accepted it. */
2374
2396
  onDetachReceipt?: (result: SingleResult) => boolean;
2375
2397
  /** Authoritative terminal result, emitted only after the full detached run finalizes. */
2376
- onDetachedExit?: (result: SingleResult) => void;
2398
+ onDetachedExit?: (result: SingleResult) => void | Promise<void>;
2377
2399
  controlConfig?: ResolvedControlConfig;
2378
2400
  intercomSessionName?: string;
2379
2401
  orchestratorIntercomTarget?: string;
@@ -2419,6 +2441,8 @@ export interface RunSyncOptions {
2419
2441
  preferredModelProvider?: string;
2420
2442
  /** Parent Pi event host used to snapshot runtime-registered MCP servers before child launch. */
2421
2443
  runtimeSnapshotHost?: import("../runs/shared/mcp-direct-tool-allowlist.ts").McpRuntimeSnapshotHost;
2444
+ /** Builtin tool names the host runtime provides; used to intersect agent-declared tools. */
2445
+ hostAvailableBuiltins?: readonly string[];
2422
2446
  /** Optional subagent model-scope enforcement for fallback candidates */
2423
2447
  modelScope?: ModelScopeRule | ModelScopeRule[];
2424
2448
  /** Skills to make available (overrides agent default if provided) */
@@ -2733,7 +2757,7 @@ export const POLL_INTERVAL_MS = 250;
2733
2757
  export const WIDGET_ANIMATION_INTERVAL_MS = 1000;
2734
2758
  export const MAX_WIDGET_JOBS = 4;
2735
2759
  export const DEFAULT_SUBAGENT_MAX_DEPTH = 2;
2736
- export const SUBAGENT_ACTIONS = ["list", "get", "models", "children.list", "guide", "validate", "create", "update", "delete", "eject", "disable", "enable", "reset", "mission.create", "mission.list", "mission.show", "mission.update", "mission.resolve-decision", "mission.attach-run", "mission.close", "worktree.discard", "worktree.cleanup", "lane.status", "lane.recordMerge", "lane.recordSupersession", "refine", "refine.show", "refine.rollback", "inspector.open", "inspector.status", "inspector.close", "project.open", "project.status", "project.close", "status", "debug.run", "grant-spawn-budget", "interrupt", "resume", "steer", "stop", "dismiss", "doctor", "watchdog.status", "watchdog.check", "watchdog.configure", "watchdog.recommend-model", "schedule.create", "schedule.list", "schedule.show", "schedule.history", "schedule.pause", "schedule.resume", "schedule.run", "schedule.run-due", "schedule.delete"] as const;
2760
+ export const SUBAGENT_ACTIONS = ["list", "get", "models", "children.list", "guide", "validate", "create", "update", "delete", "eject", "disable", "enable", "reset", "mission.create", "mission.list", "mission.show", "mission.update", "mission.resolve-decision", "mission.attach-run", "mission.close", "worktree.discard", "worktree.cleanup", "lane.status", "lane.recordMerge", "lane.recordSupersession", "refine", "refine.show", "refine.rollback", "inspector.open", "inspector.command", "inspector.status", "inspector.close", "project.open", "project.status", "project.close", "status", "debug.run", "grant-spawn-budget", "interrupt", "resume", "steer", "stop", "dismiss", "doctor", "watchdog.status", "watchdog.check", "watchdog.configure", "watchdog.recommend-model", "schedule.create", "schedule.list", "schedule.show", "schedule.history", "schedule.pause", "schedule.resume", "schedule.run", "schedule.run-due", "schedule.delete"] as const;
2737
2761
 
2738
2762
  export const DEFAULT_FORK_PREAMBLE =
2739
2763
  "You are a delegated subagent running from a fork of the parent session. " +
@@ -457,8 +457,13 @@ export function hasEmptyTerminalAssistantResponse(messages: Message[]): boolean
457
457
  const lastAssistant = messages.findLast((message) => message.role === "assistant");
458
458
  return lastAssistant?.role === "assistant"
459
459
  && Array.isArray(lastAssistant.content)
460
- && lastAssistant.content.length === 0
461
- && lastAssistant.usage.output === 0;
460
+ && ((lastAssistant.content.length === 0 && lastAssistant.usage.output === 0)
461
+ || (messages.at(-1) === lastAssistant
462
+ && lastAssistant.stopReason === "stop"
463
+ && !lastAssistant.errorMessage
464
+ && lastAssistant.content.length > 0
465
+ // Token accounting can be nonzero even when no response text was emitted.
466
+ && lastAssistant.content.every((part) => part.type === "text" && part.text === "")));
462
467
  }
463
468
 
464
469
  export function formatEmptyTerminalAssistantResponseError(messages: Message[]): string {
@@ -1,5 +1,5 @@
1
1
  import { stableJsonDigest } from "./launch-contract.ts";
2
- import type { WorkflowResourceProvenanceV1 } from "./types.ts";
2
+ import type { WorkflowResourceProvenance } from "./types.ts";
3
3
 
4
4
  export interface WorkflowChildPermitInput {
5
5
  issuerPackage: string;
@@ -117,12 +117,12 @@ export function workflowChildPermitConsumed(permit: WorkflowChildPermit): boolea
117
117
  }
118
118
 
119
119
  export interface WorkflowResourceHostAuthority {
120
- keys: readonly string[];
121
- commands: readonly string[];
120
+ key: string;
121
+ command: string;
122
122
  }
123
123
 
124
124
  export interface WorkflowResourceAuthority {
125
- host?: WorkflowResourceHostAuthority;
125
+ host?: readonly WorkflowResourceHostAuthority[];
126
126
  }
127
127
 
128
128
  export interface WorkflowResourcePermitInput {
@@ -143,7 +143,7 @@ interface WorkflowResourcePermitRecord {
143
143
  resourceId: string;
144
144
  scriptDigest: string;
145
145
  authority: WorkflowResourceAuthority;
146
- provenance: WorkflowResourceProvenanceV1;
146
+ provenance: WorkflowResourceProvenance;
147
147
  state: "available" | "consumed";
148
148
  }
149
149
 
@@ -152,11 +152,17 @@ const resourceRecords = new WeakMap<object, WorkflowResourcePermitRecord>();
152
152
  function cloneWorkflowResourceAuthority(authority: WorkflowResourceAuthority): WorkflowResourceAuthority {
153
153
  if (!authority || typeof authority !== "object" || Array.isArray(authority)) throw new Error("Workflow resource authority must be an object.");
154
154
  if (authority.host === undefined) return Object.freeze({});
155
- if (!authority.host || typeof authority.host !== "object" || Array.isArray(authority.host)) throw new Error("Workflow resource host authority must be an object.");
156
- const { keys, commands } = authority.host;
157
- if (!Array.isArray(keys) || keys.some((key) => typeof key !== "string" || !key.trim())) throw new Error("Workflow resource host authority keys must be non-empty strings.");
158
- if (!Array.isArray(commands) || commands.some((command) => typeof command !== "string" || !command.trim())) throw new Error("Workflow resource host authority commands must be non-empty strings.");
159
- return Object.freeze({ host: Object.freeze({ keys: Object.freeze([...keys]), commands: Object.freeze([...commands]) }) });
155
+ if (!Array.isArray(authority.host) || authority.host.length > 32) throw new Error("Workflow resource host authority must be an array of at most 32 grants.");
156
+ const keys = new Set<string>();
157
+ const host = Array.from(authority.host, (grant) => {
158
+ if (!grant || typeof grant !== "object" || Object.keys(grant).some((field) => field !== "key" && field !== "command")) throw new Error("Workflow resource host grant must contain only key and command.");
159
+ const { key, command } = grant;
160
+ if (typeof key !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(key) || keys.has(key)) throw new Error("Workflow resource host grant requires a unique safe key.");
161
+ if (typeof command !== "string" || !command.trim() || Buffer.byteLength(command.trim(), "utf8") > 16 * 1024 || command.includes("\0")) throw new Error("Workflow resource host grant requires a non-empty command of at most 16384 bytes without NUL.");
162
+ keys.add(key);
163
+ return Object.freeze({ key, command: command.trim() });
164
+ });
165
+ return Object.freeze({ host: Object.freeze(host) });
160
166
  }
161
167
 
162
168
  /** Package-internal permit for a workflow resource resolved by the extension. */
@@ -186,7 +192,7 @@ export function createWorkflowResourcePermit(input: WorkflowResourcePermitInput)
186
192
  return permit;
187
193
  }
188
194
 
189
- export function consumeWorkflowResourcePermit(permit: WorkflowResourcePermit, script: string): { provenance: WorkflowResourceProvenanceV1; authority: WorkflowResourceAuthority } | string {
195
+ export function consumeWorkflowResourcePermit(permit: WorkflowResourcePermit, script: string): { provenance: WorkflowResourceProvenance; authority: WorkflowResourceAuthority } | string {
190
196
  const record = resourceRecords.get(permit as object);
191
197
  if (!record) return "Workflow resource permit is invalid.";
192
198
  if (record.state !== "available") return "Workflow resource permit is already consumed.";
@@ -201,7 +207,6 @@ export function authorizeWorkflowResourceHost(permit: WorkflowResourcePermit, ke
201
207
  if (!record || record.state !== "consumed") return "Workflow resource authority is unavailable.";
202
208
  const host = record.authority.host;
203
209
  if (!host) return "runs.host is not allowed for this workflow resource.";
204
- if (!host.keys.includes(key)) return `runs.host('${key}') is not allowed for workflow resource '${record.resourceName}'.`;
205
- if (!host.commands.includes(command.trim())) return `The command for runs.host('${key}') is not allowed for workflow resource '${record.resourceName}'.`;
210
+ if (!host.some((grant) => grant.key === key && grant.command === command.trim())) return `The command for runs.host('${key}') is not allowed for workflow resource '${record.resourceName}'.`;
206
211
  return undefined;
207
212
  }
@@ -6,7 +6,7 @@ import {
6
6
  type SubagentDelegationUpdate,
7
7
  type SubagentDelegationValue,
8
8
  } from "../api/delegation.ts";
9
- import type { AcceptanceInput, AgentContract, EffectsProjection, ExecutionProjection, JsonSchemaObject, ReviewProjection, ToolBudgetConfig, Usage } from "../shared/types.ts";
9
+ import type { AcceptanceInput, AgentContract, EffectsProjection, ExecutionProjection, IntercomBridgeConfig, JsonSchemaObject, ReviewProjection, ToolBudgetConfig, Usage } from "../shared/types.ts";
10
10
  import { cloneJsonWithinByteLimit } from "./delegation-json.ts";
11
11
 
12
12
  export interface PromptTemplateDelegationRequest {
@@ -127,6 +127,7 @@ export interface DelegatedSubagentExecutionParams {
127
127
  agentContract?: AgentContract;
128
128
  acceptance?: AcceptanceInput;
129
129
  artifacts?: boolean;
130
+ intercomBridge?: IntercomBridgeConfig;
130
131
  /** Internal-only thinking override accepted by executeDelegated. */
131
132
  delegatedThinkingOverride?: SubagentDelegationThinking;
132
133
  /** Internal-only capability accepted and stripped by executeDelegated. */
@@ -295,6 +296,7 @@ export function toSubagentDelegationExecutionParams(request: SubagentDelegationR
295
296
  ...(request.result.kind === "structured" ? { outputSchema: request.result.schema } : {}),
296
297
  acceptance: false,
297
298
  artifacts: request.artifacts,
299
+ ...(request.intercomBridge !== undefined ? { intercomBridge: request.intercomBridge } : {}),
298
300
  delegatedThinkingOverride: request.thinking,
299
301
  delegatedAllowZeroToolBudget: true,
300
302
  async: false,
@@ -1,7 +1,9 @@
1
1
  import {
2
2
  type SubagentDelegationRequest,
3
3
  } from "../api/delegation.ts";
4
+ import { validateIntercomBridgeConfig } from "../intercom/intercom-bridge.ts";
4
5
  import { validateToolBudgetConfig } from "../runs/shared/tool-budget.ts";
6
+ import type { IntercomBridgeConfig } from "../shared/types.ts";
5
7
  import { cloneJsonWithinByteLimit } from "./delegation-json.ts";
6
8
 
7
9
  export type SubagentDelegationParseResult =
@@ -22,6 +24,7 @@ const supportedFields = new Set([
22
24
  "toolBudget",
23
25
  "skill",
24
26
  "artifacts",
27
+ "intercomBridge",
25
28
  "result",
26
29
  ]);
27
30
 
@@ -97,6 +100,15 @@ export function parseSubagentDelegationRequest(data: unknown): SubagentDelegatio
97
100
  if (value.artifacts !== undefined && typeof value.artifacts !== "boolean") {
98
101
  return { ok: false, ...identity, error: "artifacts must be a boolean." };
99
102
  }
103
+ let intercomBridge: IntercomBridgeConfig | undefined;
104
+ if (value.intercomBridge !== undefined) {
105
+ const bridge = validateIntercomBridgeConfig({ value: value.intercomBridge, label: "intercomBridge" });
106
+ if (!bridge.ok) return { ok: false, ...identity, error: bridge.error };
107
+ if (typeof bridge.value.instructionFile === "string" && Buffer.byteLength(bridge.value.instructionFile, "utf8") > MAX_SHORT_TEXT_BYTES) {
108
+ return { ok: false, ...identity, error: "intercomBridge.instructionFile exceeds 1 KiB when UTF-8 encoded." };
109
+ }
110
+ intercomBridge = bridge.value;
111
+ }
100
112
  if (Buffer.byteLength(value.task as string, "utf8") > MAX_TASK_BYTES) {
101
113
  return { ok: false, ...identity, error: "Delegation task exceeds 1 MiB when UTF-8 encoded." };
102
114
  }
@@ -154,6 +166,8 @@ export function parseSubagentDelegationRequest(data: unknown): SubagentDelegatio
154
166
  ok: true,
155
167
  request: {
156
168
  ...value,
169
+ // The validated copy replaces the caller's object so the request never aliases untrusted input.
170
+ ...(intercomBridge ? { intercomBridge } : {}),
157
171
  result: structuredSchema
158
172
  ? { kind: "structured", schema: structuredSchema }
159
173
  : { kind: "text" },
@@ -31,6 +31,7 @@ import { registerPromptWorkflowCommands } from "./prompt-workflows.ts";
31
31
  import { openSubagentsAdmin } from "./subagents-admin.ts";
32
32
  import { SUBAGENT_GUIDE_TOPICS } from "../extension/subagent-guide.ts";
33
33
  import { openSubagentFleet } from "../tui/fleet.ts";
34
+ import { createBuiltinInspectorPlugins } from "../inspectors/plugins.ts";
34
35
  import {
35
36
  applySlashUpdate,
36
37
  buildSlashInitialResult,
@@ -860,7 +861,7 @@ export function registerSlashCommands(
860
861
  }
861
862
  fleetOpen = true;
862
863
  try {
863
- await openSubagentFleet(ctx, state, { asyncDirRoot: DIRS.async, resultsDir: DIRS.results, fleetKeybindings: options.fleetKeybindings });
864
+ await openSubagentFleet(ctx, state, { asyncDirRoot: DIRS.async, inspectorPlugins: createBuiltinInspectorPlugins(), resultsDir: DIRS.results, fleetKeybindings: options.fleetKeybindings });
864
865
  } finally {
865
866
  fleetOpen = false;
866
867
  }
@@ -71,9 +71,16 @@ function modelFullId(model: ModelInfo): string {
71
71
  return `${model.provider}/${model.id}`;
72
72
  }
73
73
 
74
- function liveAvailableModels(ctx: ExtensionContext) {
74
+ async function liveAvailableModels(ctx: ExtensionContext) {
75
75
  try {
76
- ctx.modelRegistry.refresh?.();
76
+ // Reload local configuration and cached catalogs without network discovery on picker open.
77
+ const result = await ctx.modelRegistry.refresh?.({ allowNetwork: false, signal: AbortSignal.timeout(5_000) });
78
+ const firstError = result?.errors.entries().next().value;
79
+ if (firstError) {
80
+ ctx.ui.notify(`Could not refresh ${firstError[0]}; using the currently loaded choices. ${firstError[1].message}`, "warning");
81
+ } else if (result?.aborted) {
82
+ ctx.ui.notify("Model registry refresh timed out; using the currently loaded choices.", "warning");
83
+ }
77
84
  } catch (error) {
78
85
  const message = error instanceof Error ? error.message : String(error);
79
86
  ctx.ui.notify(`Could not refresh the model registry; using the last loaded choices. ${message}`, "warning");
@@ -217,7 +224,7 @@ async function selectFromList(ctx: ExtensionContext, title: string, subtitle: st
217
224
  }
218
225
 
219
226
  async function chooseModel(ctx: ExtensionContext, agent: AgentConfig): Promise<string | undefined | null> {
220
- const models = liveAvailableModels(ctx);
227
+ const models = await liveAvailableModels(ctx);
221
228
  const current = agent.model ?? INHERIT_MODEL_CHOICE;
222
229
  const items: SelectorItem[] = [{ value: INHERIT_MODEL_CHOICE, label: INHERIT_MODEL_CHOICE, current: !agent.model }];
223
230
  if (agent.model && !models.some((model) => modelFullId(model) === agent.model)) {
@@ -233,7 +240,7 @@ async function chooseModel(ctx: ExtensionContext, agent: AgentConfig): Promise<s
233
240
  }
234
241
 
235
242
  async function chooseThinking(ctx: ExtensionContext, agent: AgentConfig): Promise<string | undefined | null> {
236
- const availableModels = liveAvailableModels(ctx).map(toModelInfo);
243
+ const availableModels = (await liveAvailableModels(ctx)).map(toModelInfo);
237
244
  const effectiveModel = agent.model ?? (ctx.model ? modelFullId(ctx.model) : undefined);
238
245
  const modelInfo = findModelInfo(effectiveModel, availableModels, ctx.model?.provider);
239
246
  const levels = getSupportedThinkingLevels(modelInfo);