@narumitw/pi-subagents 0.53.0 → 1.0.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 (66) hide show
  1. package/README.md +85 -15
  2. package/package.json +1 -1
  3. package/src/agents/built-ins.ts +124 -0
  4. package/src/agents/catalog.ts +224 -0
  5. package/src/agents/discovery.ts +249 -0
  6. package/src/agents/types.ts +98 -0
  7. package/src/agents.ts +47 -670
  8. package/src/auto-transport.ts +2 -1
  9. package/src/automation.ts +7 -2
  10. package/src/capability-router.ts +1 -1
  11. package/src/completion-delivery.ts +82 -11
  12. package/src/config-status.ts +2 -2
  13. package/src/config-ui.ts +8 -8
  14. package/src/consult-resources.ts +1 -1
  15. package/src/consult.ts +9 -7
  16. package/src/create-stateful-transport.ts +2 -1
  17. package/src/cwd-policy.ts +1 -1
  18. package/src/execution/budget.ts +56 -0
  19. package/src/execution/runtime-policy.ts +19 -0
  20. package/src/execution-plan.ts +1 -1
  21. package/src/execution-profiles.ts +1 -1
  22. package/src/execution-ui.ts +1 -1
  23. package/src/execution.ts +269 -100
  24. package/src/in-process-transport.ts +3 -2
  25. package/src/inspect.ts +39 -8
  26. package/src/limits.ts +1 -0
  27. package/src/orchestration-metrics.ts +12 -5
  28. package/src/panel-execution.ts +1 -1
  29. package/src/panel-planning.ts +1 -1
  30. package/src/params.ts +3 -1
  31. package/src/persistence.ts +106 -7
  32. package/src/registry-types.ts +22 -5
  33. package/src/registry.ts +205 -37
  34. package/src/render.ts +1 -1
  35. package/src/retained-semantic-state.ts +1 -1
  36. package/src/rpc-transport-metadata.ts +1 -1
  37. package/src/rpc-transport.ts +2 -1
  38. package/src/runner.ts +6 -1
  39. package/src/settings/inspection.ts +275 -0
  40. package/src/settings/schema.ts +186 -0
  41. package/src/settings.ts +72 -420
  42. package/src/spawn-idempotency.ts +1 -1
  43. package/src/stateful-agent-view.ts +87 -0
  44. package/src/stateful-config.ts +1 -1
  45. package/src/stateful-guidance.ts +2 -2
  46. package/src/stateful-limits.ts +1 -1
  47. package/src/stateful-prompt.ts +2 -2
  48. package/src/stateful-render.ts +0 -1
  49. package/src/stateful-safety.ts +2 -1
  50. package/src/stateful-tool-params.ts +13 -20
  51. package/src/stateful.ts +36 -117
  52. package/src/subagents.ts +8 -9
  53. package/src/subprocess-transport.ts +2 -6
  54. package/src/transport-types.ts +1 -1
  55. package/src/transport-ui.ts +1 -1
  56. package/src/verification-harness.ts +516 -0
  57. package/src/verification-receipt.ts +275 -0
  58. package/src/verified-execution-benchmark.ts +86 -0
  59. package/src/verified-execution-contract.ts +219 -0
  60. package/src/work-item-ledger.ts +510 -37
  61. package/src/work-item-persistence.ts +31 -0
  62. package/src/workflow-completion-controller.ts +397 -0
  63. package/src/workflow-plan-compiler.ts +1 -1
  64. package/src/workflow-plan-patch.ts +1 -1
  65. package/src/workflow-planning.ts +11 -1
  66. package/src/workflow-ui.ts +1 -1
package/src/registry.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { randomUUID } from "node:crypto";
6
6
  import { projectAgentRecords } from "./agent-projection.js";
7
- import type { SubagentThinkingLevel } from "./agents.js";
7
+ import type { SubagentThinkingLevel } from "./agents/types.js";
8
8
  import {
9
9
  type CapabilityGrant,
10
10
  isCapabilityGrantActive,
@@ -21,6 +21,7 @@ import {
21
21
  DEFAULT_MAX_CONTEXT_BYTES,
22
22
  DEFAULT_MAX_OUTPUT_BYTES,
23
23
  MAX_SUBAGENT_TIMEOUT_MS,
24
+ MAX_TOOL_MESSAGE_BYTES,
24
25
  truncateUtf8,
25
26
  } from "./limits.js";
26
27
  import { classifyStructuredOutcome } from "./outcome.js";
@@ -47,6 +48,9 @@ import type { TransportTelemetry } from "./transport-types.js";
47
48
  import { type TurnLimits, validateTurnLimits } from "./turn-budget.js";
48
49
 
49
50
  const DEFAULT_STATEFUL_LIMITS = resolveStatefulLimits();
51
+ const MAX_PENDING_COMPLETIONS_PER_AGENT = 20;
52
+ const INITIAL_PERSISTENCE_RETRY_DELAY_MS = 25;
53
+ const MAX_PERSISTENCE_RETRY_DELAY_MS = 1_000;
50
54
 
51
55
  export type * from "./registry-types.js";
52
56
 
@@ -73,6 +77,8 @@ function validateTurnTimeout(value: number): number {
73
77
 
74
78
  function clearCurrentTurn(agent: ManagedAgent): void {
75
79
  agent.currentTask = undefined;
80
+ agent.currentRunId = undefined;
81
+ agent.currentTurnGeneration = undefined;
76
82
  agent.currentTimeoutMs = undefined;
77
83
  agent.currentIdleTimeoutMs = undefined;
78
84
  agent.currentMaxTurns = undefined;
@@ -86,6 +92,21 @@ function waitAbortError(): Error {
86
92
  return error;
87
93
  }
88
94
 
95
+ function waitForPersistenceRetry(milliseconds: number, signal: AbortSignal): Promise<void> {
96
+ if (signal.aborted) return Promise.reject(signal.reason);
97
+ return new Promise((resolve, reject) => {
98
+ const onAbort = () => {
99
+ clearTimeout(timer);
100
+ reject(signal.reason);
101
+ };
102
+ const timer = setTimeout(() => {
103
+ signal.removeEventListener("abort", onAbort);
104
+ resolve();
105
+ }, milliseconds);
106
+ signal.addEventListener("abort", onAbort, { once: true });
107
+ });
108
+ }
109
+
89
110
  export class AgentRegistry {
90
111
  private readonly agents = new Map<string, ManagedAgent>();
91
112
  private readonly controllers = new Map<string, AbortController>();
@@ -96,6 +117,7 @@ export class AgentRegistry {
96
117
  resolve: (agent: ManagedAgent) => void;
97
118
  }> = [];
98
119
  private changeQueue: Promise<void> = Promise.resolve();
120
+ private readonly shutdownController = new AbortController();
99
121
  private readonly maxAgents: number;
100
122
  private readonly maxActiveTurns: number;
101
123
  private readonly maxHistoryTurns: number;
@@ -108,6 +130,7 @@ export class AgentRegistry {
108
130
  private readonly idleTtlMs: number;
109
131
  private readonly transport: SubagentTransport;
110
132
  private readonly now: () => number;
133
+ private lastCompletionAt = 0;
111
134
 
112
135
  constructor(
113
136
  transport: SubagentTransport | AgentTurnRunner,
@@ -176,6 +199,9 @@ export class AgentRegistry {
176
199
  }
177
200
  const depth = seen.size - 1;
178
201
  if (cyclic || depth > this.maxDepth) continue;
202
+ for (const completion of record.pendingCompletions ?? []) {
203
+ this.lastCompletionAt = Math.max(this.lastCompletionAt, completion.createdAt);
204
+ }
179
205
  this.agents.set(record.id, {
180
206
  ...record,
181
207
  state:
@@ -183,6 +209,12 @@ export class AgentRegistry {
183
209
  rootId,
184
210
  depth,
185
211
  currentTask: undefined,
212
+ turnGeneration: record.turnGeneration ?? 0,
213
+ currentRunId: undefined,
214
+ currentTurnGeneration: undefined,
215
+ pendingCompletions: (record.pendingCompletions ?? []).map((completion) => ({
216
+ ...completion,
217
+ })),
186
218
  currentTimeoutMs: undefined,
187
219
  currentIdleTimeoutMs: undefined,
188
220
  currentMaxTurns: undefined,
@@ -286,6 +318,8 @@ export class AgentRegistry {
286
318
  maxToolCalls: input.maxToolCalls,
287
319
  currentMaxToolCalls: input.maxToolCalls,
288
320
  currentTask: task,
321
+ turnGeneration: 0,
322
+ pendingCompletions: [],
289
323
  history: [],
290
324
  mailbox: [],
291
325
  context: input.context,
@@ -486,19 +520,30 @@ export class AgentRegistry {
486
520
  const index = this.queue.findIndex((entry) => entry.agent.id === id);
487
521
  if (index >= 0) {
488
522
  const [entry] = this.queue.splice(index, 1);
523
+ const persistedCompletion = {
524
+ completionId: `completion:${agent.id}:${randomUUID()}`,
525
+ runId: agent.currentRunId ?? `run:${agent.id}:${randomUUID()}`,
526
+ generation: agent.currentTurnGeneration ?? agent.turnGeneration ?? 1,
527
+ task: truncateUtf8(entry.task, 256).text,
528
+ output: "",
529
+ error: "Interrupted before execution",
530
+ createdAt: this.completionCreatedAt(),
531
+ };
489
532
  agent.state = "interrupted";
533
+ agent.pendingCompletions = [...(agent.pendingCompletions ?? []), persistedCompletion];
490
534
  clearCurrentTurn(agent);
491
535
  agent.updatedAt = this.now();
536
+ const persisted = await this.persistTerminalState().then(
537
+ () => true,
538
+ () => false,
539
+ );
492
540
  const completion: AgentTurnCompletion = {
541
+ ...persistedCompletion,
493
542
  agent: this.copy(agent),
494
- task: entry.task,
495
- output: "",
496
- error: "Interrupted before execution",
497
543
  };
498
544
  entry.resolve(agent);
499
545
  this.running.delete(id);
500
- await this.notifyTurnComplete(completion);
501
- await this.changed();
546
+ if (persisted) await this.notifyTurnComplete(completion);
502
547
  return this.copy(agent);
503
548
  }
504
549
  }
@@ -584,6 +629,7 @@ export class AgentRegistry {
584
629
  }
585
630
 
586
631
  async shutdown(): Promise<void> {
632
+ this.shutdownController.abort(new Error("Subagent registry is shutting down"));
587
633
  for (const entry of this.queue.splice(0)) {
588
634
  if (entry.agent.capabilityGrant?.state === "active") {
589
635
  entry.agent.capabilityGrant = revokeCapabilityGrant(
@@ -629,7 +675,7 @@ export class AgentRegistry {
629
675
  } catch (error) {
630
676
  shutdownError = error;
631
677
  }
632
- await this.changed();
678
+ await this.changed(true);
633
679
  if (shutdownError) throw shutdownError;
634
680
  }
635
681
 
@@ -666,6 +712,8 @@ export class AgentRegistry {
666
712
  maxToolCalls: agent.maxToolCalls,
667
713
  currentMaxToolCalls: agent.currentMaxToolCalls,
668
714
  currentTask: agent.currentTask,
715
+ currentRunId: agent.currentRunId,
716
+ currentTurnGeneration: agent.currentTurnGeneration,
669
717
  error: agent.error,
670
718
  workspaceMode: agent.workspaceMode,
671
719
  contextTurns: agent.contextTurns,
@@ -712,14 +760,60 @@ export class AgentRegistry {
712
760
  return agent ? this.copy(agent) : undefined;
713
761
  }
714
762
 
715
- markCompletionDelivered(id: string, deliveredAt: number): void {
716
- const agent = this.agents.get(id);
717
- if (!agent?.telemetry) return;
718
- agent.telemetry = {
719
- ...agent.telemetry,
720
- updatedAt: deliveredAt,
721
- timing: { ...agent.telemetry.timing, completionDeliveredAt: deliveredAt },
722
- };
763
+ listPendingCompletions(): AgentTurnCompletion[] {
764
+ return [...this.agents.values()]
765
+ .flatMap((agent) =>
766
+ (agent.pendingCompletions ?? []).map((completion) => ({
767
+ ...completion,
768
+ agent: this.copy(agent),
769
+ })),
770
+ )
771
+ .sort(
772
+ (left, right) =>
773
+ left.createdAt - right.createdAt ||
774
+ left.generation - right.generation ||
775
+ left.completionId.localeCompare(right.completionId),
776
+ );
777
+ }
778
+
779
+ async markCompletionDelivered(completionId: string, deliveredAt: number): Promise<void> {
780
+ const agent = [...this.agents.values()].find((candidate) =>
781
+ candidate.pendingCompletions?.some((completion) => completion.completionId === completionId),
782
+ );
783
+ if (!agent) return;
784
+ const acknowledged = (agent.pendingCompletions ?? []).find(
785
+ (completion) => completion.completionId === completionId,
786
+ );
787
+ if (!acknowledged) return;
788
+ agent.pendingCompletions = (agent.pendingCompletions ?? []).filter(
789
+ (completion) => completion.completionId !== completionId,
790
+ );
791
+ if (agent.telemetry) {
792
+ agent.telemetry = {
793
+ ...agent.telemetry,
794
+ updatedAt: deliveredAt,
795
+ timing: { ...agent.telemetry.timing, completionDeliveredAt: deliveredAt },
796
+ };
797
+ }
798
+ agent.updatedAt = Math.max(agent.updatedAt, deliveredAt);
799
+ try {
800
+ await this.changed(true);
801
+ } catch (error) {
802
+ if (
803
+ !agent.pendingCompletions?.some(
804
+ (completion) => completion.completionId === acknowledged.completionId,
805
+ )
806
+ ) {
807
+ agent.pendingCompletions = [...(agent.pendingCompletions ?? []), acknowledged].sort(
808
+ (left, right) => left.createdAt - right.createdAt || left.generation - right.generation,
809
+ );
810
+ }
811
+ if (agent.telemetry?.timing.completionDeliveredAt === deliveredAt) {
812
+ const { completionDeliveredAt: _discarded, ...timing } = agent.telemetry.timing;
813
+ agent.telemetry = { ...agent.telemetry, timing };
814
+ }
815
+ throw error;
816
+ }
723
817
  }
724
818
 
725
819
  async sweepExpired(): Promise<number> {
@@ -740,6 +834,14 @@ export class AgentRegistry {
740
834
  task: string,
741
835
  limits: TurnLimits & { timeoutMs?: number } = {},
742
836
  ): void {
837
+ if ((agent.pendingCompletions?.length ?? 0) >= MAX_PENDING_COMPLETIONS_PER_AGENT) {
838
+ throw new Error(
839
+ `Agent ${agent.id} has ${MAX_PENDING_COMPLETIONS_PER_AGENT} undelivered completions; wait for delivery before another turn`,
840
+ );
841
+ }
842
+ agent.turnGeneration = (agent.turnGeneration ?? 0) + 1;
843
+ agent.currentTurnGeneration = agent.turnGeneration;
844
+ agent.currentRunId = `run:${agent.id}:${randomUUID()}`;
743
845
  agent.state = "starting";
744
846
  agent.error = undefined;
745
847
  agent.currentTask = task;
@@ -790,17 +892,30 @@ export class AgentRegistry {
790
892
  agent.state = "failed";
791
893
  agent.error = "Capability grant expired or no longer matches the accepted plan";
792
894
  agent.outcome = classifyStructuredOutcome("failed", "capability-grant-invalid");
793
- agent.currentTask = undefined;
794
- agent.currentTimeoutMs = undefined;
795
- agent.updatedAt = this.now();
796
- resolveQueued(agent);
797
- this.running.delete(agent.id);
798
- void this.notifyTurnComplete({
799
- agent: this.copy(agent),
800
- task,
895
+ const persistedCompletion = {
896
+ completionId: `completion:${agent.id}:${randomUUID()}`,
897
+ runId: agent.currentRunId ?? `run:${agent.id}:${randomUUID()}`,
898
+ generation: agent.currentTurnGeneration ?? agent.turnGeneration ?? 1,
899
+ task: truncateUtf8(task, 256).text,
801
900
  output: "",
802
- error: agent.error,
803
- }).then(() => this.changed());
901
+ error: truncateUtf8(agent.error, 512).text,
902
+ createdAt: this.completionCreatedAt(),
903
+ };
904
+ agent.pendingCompletions = [...(agent.pendingCompletions ?? []), persistedCompletion];
905
+ clearCurrentTurn(agent);
906
+ agent.updatedAt = this.now();
907
+ void this.persistTerminalState()
908
+ .then(() =>
909
+ this.notifyTurnComplete({
910
+ ...persistedCompletion,
911
+ agent: this.copy(agent),
912
+ }),
913
+ )
914
+ .catch(() => undefined)
915
+ .finally(() => {
916
+ resolveQueued(agent);
917
+ this.running.delete(agent.id);
918
+ });
804
919
  return;
805
920
  }
806
921
  const controller = new AbortController();
@@ -808,6 +923,8 @@ export class AgentRegistry {
808
923
  agent.state = "running";
809
924
  agent.updatedAt = this.now();
810
925
  const startedAt = this.now();
926
+ const runId = agent.currentRunId ?? `run:${agent.id}:${randomUUID()}`;
927
+ const turnGeneration = agent.currentTurnGeneration ?? agent.turnGeneration ?? 1;
811
928
  const completionKey = `completion:${agent.id}:${randomUUID()}`;
812
929
  const acceptedPlanId = agent.executionPlan?.id;
813
930
  let completionContent = "";
@@ -830,6 +947,8 @@ export class AgentRegistry {
830
947
  ? truncateUtf8(outcome.error, this.maxTurnOutputBytes).text
831
948
  : undefined;
832
949
  agent.history.push({
950
+ runId,
951
+ generation: turnGeneration,
833
952
  task,
834
953
  output,
835
954
  startedAt,
@@ -925,6 +1044,8 @@ export class AgentRegistry {
925
1044
  this.maxTurnOutputBytes,
926
1045
  ).text;
927
1046
  agent.history.push({
1047
+ runId,
1048
+ generation: turnGeneration,
928
1049
  task,
929
1050
  output: "",
930
1051
  startedAt,
@@ -947,12 +1068,16 @@ export class AgentRegistry {
947
1068
  return agent;
948
1069
  })
949
1070
  .finally(async () => {
950
- const turnCompletion: AgentTurnCompletion = {
951
- agent: this.copy(agent),
952
- task,
953
- output: completionOutput,
954
- error: completionError,
1071
+ const persistedCompletion = {
1072
+ completionId: completionKey,
1073
+ runId,
1074
+ generation: turnGeneration,
1075
+ task: truncateUtf8(task, 256).text,
1076
+ output: truncateUtf8(completionOutput, MAX_TOOL_MESSAGE_BYTES).text,
1077
+ error: completionError ? truncateUtf8(completionError, 512).text : undefined,
1078
+ createdAt: this.completionCreatedAt(),
955
1079
  };
1080
+ agent.pendingCompletions = [...(agent.pendingCompletions ?? []), persistedCompletion];
956
1081
  if (agent.parentId) {
957
1082
  const parent = this.agents.get(agent.parentId);
958
1083
  if (parent && parent.state !== "closed") {
@@ -961,12 +1086,19 @@ export class AgentRegistry {
961
1086
  }
962
1087
  clearCurrentTurn(agent);
963
1088
  agent.updatedAt = this.now();
1089
+ const persisted = await this.persistTerminalState().then(
1090
+ () => true,
1091
+ () => false,
1092
+ );
964
1093
  this.controllers.delete(agent.id);
1094
+ const turnCompletion: AgentTurnCompletion = {
1095
+ ...persistedCompletion,
1096
+ agent: this.copy(agent),
1097
+ };
965
1098
  this.running.delete(agent.id);
966
1099
  resolveQueued(agent);
967
1100
  this.pumpQueue();
968
- await this.notifyTurnComplete(turnCompletion);
969
- await this.changed();
1101
+ if (persisted) await this.notifyTurnComplete(turnCompletion);
970
1102
  });
971
1103
  }
972
1104
 
@@ -1032,11 +1164,22 @@ export class AgentRegistry {
1032
1164
  return [...this.agents.values()].filter((agent) => agent.state !== "closed").length;
1033
1165
  }
1034
1166
 
1167
+ private completionCreatedAt(): number {
1168
+ this.lastCompletionAt = Math.max(this.now(), this.lastCompletionAt + 1);
1169
+ return this.lastCompletionAt;
1170
+ }
1171
+
1035
1172
  private evictExpired(): ManagedAgent[] {
1036
1173
  const cutoff = this.now() - this.idleTtlMs;
1037
1174
  const protectedIds = new Set<string>();
1038
1175
  for (const agent of this.agents.values()) {
1039
- if (agent.state !== "running" && agent.state !== "starting") continue;
1176
+ if (
1177
+ agent.state !== "running" &&
1178
+ agent.state !== "starting" &&
1179
+ (agent.pendingCompletions?.length ?? 0) === 0
1180
+ ) {
1181
+ continue;
1182
+ }
1040
1183
  let current: ManagedAgent | undefined = agent;
1041
1184
  while (current) {
1042
1185
  protectedIds.add(current.id);
@@ -1081,6 +1224,25 @@ export class AgentRegistry {
1081
1224
  for (const agent of closed.slice(this.maxAgents)) this.agents.delete(agent.id);
1082
1225
  }
1083
1226
 
1227
+ private async persistTerminalState(): Promise<void> {
1228
+ let failures = 0;
1229
+ for (;;) {
1230
+ try {
1231
+ await this.changed(true);
1232
+ return;
1233
+ } catch (error) {
1234
+ if (this.shutdownController.signal.aborted) throw error;
1235
+ failures++;
1236
+ if (failures === 1) continue;
1237
+ const delay = Math.min(
1238
+ INITIAL_PERSISTENCE_RETRY_DELAY_MS * 2 ** (failures - 2),
1239
+ MAX_PERSISTENCE_RETRY_DELAY_MS,
1240
+ );
1241
+ await waitForPersistenceRetry(delay, this.shutdownController.signal);
1242
+ }
1243
+ }
1244
+ }
1245
+
1084
1246
  private async notifyTurnComplete(completion: AgentTurnCompletion): Promise<void> {
1085
1247
  try {
1086
1248
  await this.options.onTurnComplete?.(completion);
@@ -1089,16 +1251,17 @@ export class AgentRegistry {
1089
1251
  }
1090
1252
  }
1091
1253
 
1092
- private changed(): Promise<void> {
1254
+ private changed(propagateError = false): Promise<void> {
1093
1255
  const snapshot = this.list(true);
1094
1256
  const next = this.changeQueue.then(async () => {
1095
1257
  try {
1096
1258
  await this.options.onChange?.(snapshot);
1097
- } catch {
1098
- // Persistence is best-effort; lifecycle operations must remain usable if storage fails.
1259
+ } catch (error) {
1260
+ if (propagateError) throw error;
1261
+ // Non-terminal persistence remains best-effort so lifecycle controls stay usable.
1099
1262
  }
1100
1263
  });
1101
- this.changeQueue = next;
1264
+ this.changeQueue = next.catch(() => undefined);
1102
1265
  return next;
1103
1266
  }
1104
1267
 
@@ -1115,6 +1278,8 @@ export class AgentRegistry {
1115
1278
  updatedAt: agent.updatedAt,
1116
1279
  historyCount: agent.history.length,
1117
1280
  unreadMessages,
1281
+ turnGeneration: agent.turnGeneration ?? 0,
1282
+ pendingCompletionCount: agent.pendingCompletions?.length ?? 0,
1118
1283
  };
1119
1284
  }
1120
1285
 
@@ -1126,6 +1291,9 @@ export class AgentRegistry {
1126
1291
  currentMailboxMessageIds: agent.currentMailboxMessageIds
1127
1292
  ? [...agent.currentMailboxMessageIds]
1128
1293
  : undefined,
1294
+ pendingCompletions: (agent.pendingCompletions ?? []).map((completion) => ({
1295
+ ...completion,
1296
+ })),
1129
1297
  history: agent.history.map((turn) => ({ ...turn })),
1130
1298
  mailbox: agent.mailbox.map((message) => ({ ...message })),
1131
1299
  contract: agent.contract ? structuredClone(agent.contract) : undefined,
package/src/render.ts CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  type ToolRenderResultOptions,
8
8
  } from "@earendil-works/pi-coding-agent";
9
9
  import { Container, Markdown, Spacer, Text } from "@earendil-works/pi-tui";
10
- import type { AgentScope, SubagentThinkingLevel } from "./agents.js";
10
+ import type { AgentScope, SubagentThinkingLevel } from "./agents/types.js";
11
11
  import { renderPanelCall, renderPanelResult } from "./panel-render.js";
12
12
  import { hasUsableAggregator, type SubagentParams } from "./params.js";
13
13
  import { expansionHint, formatToolActivity, safeBlock, safeLine } from "./render-common.js";
@@ -1,6 +1,6 @@
1
1
  import * as path from "node:path";
2
2
  import { getAgentDir } from "@earendil-works/pi-coding-agent";
3
- import type { AgentConfig, SubagentThinkingLevel, SubagentTransportKind } from "./agents.js";
3
+ import type { AgentConfig, SubagentThinkingLevel, SubagentTransportKind } from "./agents/types.js";
4
4
  import type { TargetPolicyAudit } from "./cwd-policy.js";
5
5
  import type { DelegationContract } from "./delegation-contract.js";
6
6
  import {
@@ -1,4 +1,4 @@
1
- import type { AgentConfig, SubagentThinkingLevel } from "./agents.js";
1
+ import type { AgentConfig, SubagentThinkingLevel } from "./agents/types.js";
2
2
  import { DEFAULT_MAX_OUTPUT_BYTES } from "./limits.js";
3
3
  import type { ManagedAgent, TurnOutcome } from "./registry.js";
4
4
  import { boundedPrivateText } from "./safe-text.js";
@@ -3,7 +3,8 @@ import * as fs from "node:fs";
3
3
  import * as os from "node:os";
4
4
  import * as path from "node:path";
5
5
  import type { RpcSessionState } from "@earendil-works/pi-coding-agent";
6
- import { type AgentConfig, discoverAgents, type SubagentSettings } from "./agents.js";
6
+ import { discoverAgents } from "./agents/discovery.js";
7
+ import type { AgentConfig, SubagentSettings } from "./agents/types.js";
7
8
  import {
8
9
  buildCurrentTurnPrompt,
9
10
  type ParentRuntimeSnapshot,
package/src/runner.ts CHANGED
@@ -6,7 +6,12 @@ import type { AgentToolResult } from "@earendil-works/pi-agent-core";
6
6
  import type { Message } from "@earendil-works/pi-ai";
7
7
  import { withFileMutationQueue } from "@earendil-works/pi-coding-agent";
8
8
  import type { SchedulingDecision } from "./adaptive-scheduler.js";
9
- import type { AgentConfig, AgentScope, AgentSource, SubagentThinkingLevel } from "./agents.js";
9
+ import type {
10
+ AgentConfig,
11
+ AgentScope,
12
+ AgentSource,
13
+ SubagentThinkingLevel,
14
+ } from "./agents/types.js";
10
15
  import { type CapabilityGrant, revokeCapabilityGrant } from "./capability-grant.js";
11
16
  import type { TargetPolicyAudit } from "./cwd-policy.js";
12
17
  import type { DelegationContract } from "./delegation-contract.js";