@narumitw/pi-subagents 0.53.0 → 0.54.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 (64) hide show
  1. package/README.md +75 -6
  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 +2 -3
  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 +35 -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 +1 -1
  32. package/src/registry-types.ts +1 -1
  33. package/src/registry.ts +1 -1
  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 +1 -1
  46. package/src/stateful-limits.ts +1 -1
  47. package/src/stateful-prompt.ts +2 -2
  48. package/src/stateful-safety.ts +2 -1
  49. package/src/stateful.ts +23 -103
  50. package/src/subagents.ts +8 -9
  51. package/src/subprocess-transport.ts +2 -6
  52. package/src/transport-types.ts +1 -1
  53. package/src/transport-ui.ts +1 -1
  54. package/src/verification-harness.ts +516 -0
  55. package/src/verification-receipt.ts +275 -0
  56. package/src/verified-execution-benchmark.ts +86 -0
  57. package/src/verified-execution-contract.ts +219 -0
  58. package/src/work-item-ledger.ts +510 -37
  59. package/src/work-item-persistence.ts +31 -0
  60. package/src/workflow-completion-controller.ts +397 -0
  61. package/src/workflow-plan-compiler.ts +1 -1
  62. package/src/workflow-plan-patch.ts +1 -1
  63. package/src/workflow-planning.ts +11 -1
  64. package/src/workflow-ui.ts +1 -1
@@ -1,7 +1,8 @@
1
1
  import { realpathSync } from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
4
- import { type AgentScope, discoverAgents, type SubagentSettings } from "./agents.js";
4
+ import { discoverAgents } from "./agents/discovery.js";
5
+ import type { AgentScope, SubagentSettings } from "./agents/types.js";
5
6
  import type { AgentRegistry, ManagedAgent } from "./registry.js";
6
7
  import { safeTerminalLine } from "./safe-text.js";
7
8
  import { readSubagentSettings } from "./settings.js";
package/src/stateful.ts CHANGED
@@ -2,20 +2,21 @@
2
2
  * Stateful registration remains one lifecycle owner so session replacement, persistence,
3
3
  * capability revocation, workspace cleanup, and completion delivery cannot reorder.
4
4
  */
5
+
5
6
  import { randomUUID } from "node:crypto";
6
7
  import { StringEnum } from "@earendil-works/pi-ai";
7
8
  import { defineTool, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
8
9
  import { Type } from "typebox";
10
+ import { discoverAgents } from "./agents/discovery.js";
9
11
  import {
10
12
  type AgentScope,
11
13
  type CompletionDelivery,
12
- discoverAgents,
13
14
  isThinkingLevel,
14
15
  type SubagentRuntimeSettings,
15
16
  type SubagentSettings,
16
17
  type SubagentTransportKind,
17
18
  THINKING_LEVELS,
18
- } from "./agents.js";
19
+ } from "./agents/types.js";
19
20
  import { issueCapabilityGrant } from "./capability-grant.js";
20
21
  import { CompletionDeliveryBroker } from "./completion-delivery.js";
21
22
  import { buildContextSnapshot, type ContextMode, redactPrivateText } from "./context.js";
@@ -26,9 +27,14 @@ import {
26
27
  targetPolicyAudit,
27
28
  } from "./cwd-policy.js";
28
29
  import { DelegationContractSchema, normalizeDelegationContract } from "./delegation-contract.js";
29
- import { assertSubagentDepthAllowed } from "./execution.js";
30
+ import { assertSubagentDepthAllowed } from "./execution/runtime-policy.js";
30
31
  import type { ChildSessionFactory, ParentRuntimeSnapshot } from "./in-process-transport.js";
31
- import { DEFAULT_MAX_CONTEXT_BYTES, MAX_SUBAGENT_TIMEOUT_MS, truncateUtf8 } from "./limits.js";
32
+ import {
33
+ DEFAULT_MAX_CONTEXT_BYTES,
34
+ MAX_SUBAGENT_TIMEOUT_MS,
35
+ MAX_TOOL_MESSAGE_BYTES,
36
+ truncateUtf8,
37
+ } from "./limits.js";
32
38
  import { AgentPersistence } from "./persistence.js";
33
39
  import {
34
40
  AgentRegistry,
@@ -39,12 +45,14 @@ import {
39
45
  import { SUBAGENT_RESULT_FORMATS, type SubagentResultFormat } from "./result-contract.js";
40
46
  import { buildRetainedSemanticState } from "./retained-semantic-state.js";
41
47
  import { evaluateSemanticCompatibility } from "./semantic-snapshot.js";
42
- import { DEFAULT_DELEGATION_CWD_POLICY, readSubagentSettings } from "./settings.js";
48
+ import { DEFAULT_DELEGATION_CWD_POLICY } from "./settings/inspection.js";
49
+ import { readSubagentSettings } from "./settings.js";
43
50
  import {
44
51
  assertSpawnIdempotencyKey,
45
52
  hashSpawnRequest,
46
53
  MAX_SPAWN_IDEMPOTENCY_KEY_LENGTH,
47
54
  } from "./spawn-idempotency.js";
55
+ import { formatStatefulAgentLine, summarizeStatefulAgent } from "./stateful-agent-view.js";
48
56
  import { resolveCompletionDelivery, resolveStatefulTransportKind } from "./stateful-config.js";
49
57
  import { createSpawnPromptGuidelines } from "./stateful-guidance.js";
50
58
  import {
@@ -119,8 +127,6 @@ const StatefulTurnLimitFields = {
119
127
  }),
120
128
  ),
121
129
  };
122
- const MAX_TOOL_MESSAGE_BYTES = 2 * 1024;
123
-
124
130
  export interface StatefulSubagentDependencies {
125
131
  blockingEnabled?: boolean;
126
132
  createInProcessSession?: ChildSessionFactory;
@@ -848,10 +854,12 @@ export function registerStatefulSubagents(
848
854
  content: [
849
855
  {
850
856
  type: "text",
851
- text: agents.length ? agents.map(formatLine).join("\n") : "No stateful subagents.",
857
+ text: agents.length
858
+ ? agents.map(formatStatefulAgentLine).join("\n")
859
+ : "No stateful subagents.",
852
860
  },
853
861
  ],
854
- details: { agents: agents.map(summarizeAgent) },
862
+ details: { agents: agents.map(summarizeStatefulAgent) },
855
863
  };
856
864
  }
857
865
  const agentId = operation.agentId;
@@ -862,8 +870,8 @@ export function registerStatefulSubagents(
862
870
  return {
863
871
  content: [{ type: "text", text: `Interrupted ${agents.length} active agent(s).` }],
864
872
  details: {
865
- agent: summarizeAgent(ownedAgent(agentId)),
866
- agents: agents.map(summarizeAgent),
873
+ agent: summarizeStatefulAgent(ownedAgent(agentId)),
874
+ agents: agents.map(summarizeStatefulAgent),
867
875
  },
868
876
  };
869
877
  }
@@ -890,8 +898,8 @@ export function registerStatefulSubagents(
890
898
  return {
891
899
  content: [{ type: "text", text: `Closed ${agents.length} agent(s).` }],
892
900
  details: {
893
- agent: summarizeAgent(ownedAgent(agentId)),
894
- agents: agents.map(summarizeAgent),
901
+ agent: summarizeStatefulAgent(ownedAgent(agentId)),
902
+ agents: agents.map(summarizeStatefulAgent),
895
903
  },
896
904
  };
897
905
  }
@@ -970,95 +978,6 @@ export function resolveSpawnContextMode(
970
978
  return normalizeContextMode(value);
971
979
  }
972
980
 
973
- export function formatStatefulAgentLine(agent: ManagedAgent): string {
974
- const elapsedSeconds = Math.max(0, Math.floor((Date.now() - agent.updatedAt) / 1000));
975
- const actions =
976
- agent.state === "running" || agent.state === "starting"
977
- ? "interrupt, close"
978
- : agent.state === "closed"
979
- ? "inspect"
980
- : "send, close";
981
- const task = agent.currentTask ? ` — ${sanitizeStatusLine(agent.currentTask, 80)}` : "";
982
- const unread = agent.mailbox.filter((message) => !message.readAt).length;
983
- const indent = " ".repeat(agent.depth);
984
- const thinking = agent.thinkingLevel ? ` thinking:${agent.thinkingLevel}` : "";
985
- const timeout = agent.currentTimeoutMs ?? agent.timeoutMs;
986
- const timeoutText = timeout ? ` timeout:${timeout}ms` : "";
987
- const idleTimeout = agent.currentIdleTimeoutMs ?? agent.idleTimeoutMs;
988
- const idleText = idleTimeout ? ` idle:${idleTimeout}ms` : "";
989
- const maxTurns = agent.currentMaxTurns ?? agent.maxTurns;
990
- const turnsText = maxTurns ? ` turns:${maxTurns}` : "";
991
- const maxToolCalls = agent.currentMaxToolCalls ?? agent.maxToolCalls;
992
- const toolsText = maxToolCalls ? ` tools:${maxToolCalls}` : "";
993
- const transport = agent.telemetry?.transport ? ` transport:${agent.telemetry.transport}` : "";
994
- const phase = agent.telemetry?.phase ? ` phase:${agent.telemetry.phase}` : "";
995
- const queued = agent.telemetry?.queuePosition ? ` queue:${agent.telemetry.queuePosition}` : "";
996
- return `${indent}${sanitizeStatusLine(agent.id, 128)} ${sanitizeStatusLine(agent.agent, 128)} ${agent.state} ${elapsedSeconds}s${thinking}${timeoutText}${idleText}${turnsText}${toolsText}${transport}${phase}${queued} unread:${unread} [${actions}]${task}`;
997
- }
998
-
999
- function sanitizeStatusLine(value: string, maxLength: number): string {
1000
- return (
1001
- value
1002
- .slice(0, maxLength)
1003
- // biome-ignore lint/suspicious/noControlCharactersInRegex: Escape untrusted terminal controls.
1004
- .replace(/[\u0000-\u001f\u007f-\u009f]/gu, " ")
1005
- .replace(/\s+/gu, " ")
1006
- .trim()
1007
- );
1008
- }
1009
-
1010
- function formatLine(agent: ManagedAgent): string {
1011
- return formatStatefulAgentLine(agent);
1012
- }
1013
-
1014
- function summarizeAgent(agent: ManagedAgent) {
1015
- return {
1016
- id: agent.id,
1017
- agent: agent.agent,
1018
- parentId: agent.parentId,
1019
- rootId: agent.rootId,
1020
- depth: agent.depth,
1021
- children: [...agent.children],
1022
- state: agent.state,
1023
- createdAt: agent.createdAt,
1024
- updatedAt: agent.updatedAt,
1025
- cwd: agent.cwd,
1026
- workspaceMode: agent.workspaceMode ?? "shared",
1027
- thinkingLevel: agent.thinkingLevel,
1028
- timeoutMs: agent.timeoutMs,
1029
- currentTimeoutMs: agent.currentTimeoutMs,
1030
- idleTimeoutMs: agent.idleTimeoutMs,
1031
- currentIdleTimeoutMs: agent.currentIdleTimeoutMs,
1032
- maxTurns: agent.maxTurns,
1033
- currentMaxTurns: agent.currentMaxTurns,
1034
- maxToolCalls: agent.maxToolCalls,
1035
- currentMaxToolCalls: agent.currentMaxToolCalls,
1036
- currentTask: agent.currentTask
1037
- ? truncateUtf8(agent.currentTask, MAX_TOOL_MESSAGE_BYTES).text
1038
- : undefined,
1039
- historyCount: agent.history.length,
1040
- unreadMessages: agent.mailbox.filter((message) => !message.readAt).length,
1041
- context: {
1042
- turns: agent.contextTurns ?? 0,
1043
- sources: agent.contextSourceIds?.length ?? 0,
1044
- bytes: agent.contextBytes ?? 0,
1045
- truncated: agent.contextTruncated === true,
1046
- },
1047
- resultFormat: agent.resultFormat ?? "text",
1048
- structuredResult: agent.structuredResult,
1049
- termination: agent.termination,
1050
- outcome: agent.outcome,
1051
- executionPlan: agent.executionPlan,
1052
- capabilityGrant: agent.capabilityGrant,
1053
- semanticCompatibility: agent.semanticCompatibility,
1054
- semanticSnapshotDigest: agent.semanticSnapshot?.digest,
1055
- telemetry: agent.telemetry,
1056
- error: agent.error ? truncateUtf8(agent.error, MAX_TOOL_MESSAGE_BYTES).text : undefined,
1057
- target: agent.target,
1058
- policy: agent.policy,
1059
- };
1060
- }
1061
-
1062
981
  async function cleanupClosedWorkspaces(
1063
982
  registry: AgentRegistry,
1064
983
  isolatedAgents: Map<string, string>,
@@ -1078,7 +997,7 @@ function appendAgentCatalog(baseDescription: string, catalog: string): string {
1078
997
  function result(agent: ManagedAgent, text: string) {
1079
998
  return {
1080
999
  content: [{ type: "text" as const, text }],
1081
- details: { agent: summarizeAgent(agent) },
1000
+ details: { agent: summarizeStatefulAgent(agent) },
1082
1001
  };
1083
1002
  }
1084
1003
 
@@ -1090,6 +1009,7 @@ export {
1090
1009
  buildDetachedCompletionMessage,
1091
1010
  CompletionDeliveryBroker,
1092
1011
  } from "./completion-delivery.js";
1012
+ export { formatStatefulAgentLine } from "./stateful-agent-view.js";
1093
1013
  export { resolveCompletionDelivery, resolveStatefulTransportKind } from "./stateful-config.js";
1094
1014
  export {
1095
1015
  buildStatefulTurnPrompt,
package/src/subagents.ts CHANGED
@@ -14,14 +14,13 @@ import {
14
14
  type ExtensionAPI,
15
15
  type ToolDefinition,
16
16
  } from "@earendil-works/pi-coding-agent";
17
- import {
18
- type ConsultationCwdPolicy,
19
- type ConsultResourcePolicy,
20
- type DelegationCwdPolicy,
21
- discoverAgentCatalog,
22
- formatAgentCatalog,
23
- type SubagentSettings,
24
- } from "./agents.js";
17
+ import { discoverAgentCatalog, formatAgentCatalog } from "./agents/catalog.js";
18
+ import type {
19
+ ConsultationCwdPolicy,
20
+ ConsultResourcePolicy,
21
+ DelegationCwdPolicy,
22
+ SubagentSettings,
23
+ } from "./agents/types.js";
25
24
  import { registerSubagentAutomation } from "./automation.js";
26
25
  import { registerSubagentConfigCommand, registerSubagentConfigLifecycle } from "./config-ui.js";
27
26
  import { registerSubagentConsult } from "./consult.js";
@@ -256,7 +255,7 @@ function appendAgentCatalog(baseDescription: string, catalog: string): string {
256
255
  return catalog ? `${baseDescription}\n\n${catalog}` : baseDescription;
257
256
  }
258
257
 
259
- export { parsePositiveInteger } from "./execution.js";
258
+ export { parsePositiveInteger } from "./execution/runtime-policy.js";
260
259
  export { formatTokens, formatUsageStats } from "./render.js";
261
260
  export { buildPiArgs } from "./runner.js";
262
261
  export {
@@ -1,9 +1,5 @@
1
- import {
2
- type AgentConfig,
3
- discoverAgents,
4
- type SubagentSettings,
5
- type SubagentThinkingLevel,
6
- } from "./agents.js";
1
+ import { discoverAgents } from "./agents/discovery.js";
2
+ import type { AgentConfig, SubagentSettings, SubagentThinkingLevel } from "./agents/types.js";
7
3
  import { resolvePiPromptResources } from "./prompt-resources.js";
8
4
  import type { ManagedAgent, TurnOutcome } from "./registry.js";
9
5
  import { getResultFinalOutput, runSingleAgent, type SubagentDetails } from "./runner.js";
@@ -1,4 +1,4 @@
1
- import type { SubagentThinkingLevel } from "./agents.js";
1
+ import type { SubagentThinkingLevel } from "./agents/types.js";
2
2
 
3
3
  export const PI_SUBAGENTS_RPC_PROTOCOL = "pi-subagents:v1" as const;
4
4
 
@@ -1,5 +1,5 @@
1
1
  import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
- import type { SubagentTransportKind } from "./agents.js";
2
+ import type { SubagentTransportKind } from "./agents/types.js";
3
3
  import { safeTerminalLine as safeTerminalText } from "./safe-text.js";
4
4
  import { inspectStatefulTransportSettings, updateStatefulTransportSetting } from "./settings.js";
5
5
  import type { StatefulSubagentRuntimeStatus } from "./stateful.js";