@narumitw/pi-subagents 2.0.6 → 2.1.1

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 (180) hide show
  1. package/README.md +171 -60
  2. package/dist/chunks/{auto-transport-SY2VHUFH.ts → auto-transport-FUUKFDIG.ts} +6 -6
  3. package/dist/chunks/{capability-grant-CGEWOEKE.ts → capability-grant-PR72SWWS.ts} +4 -4
  4. package/dist/chunks/{chunk-CBP76ARQ.ts → chunk-2LMJU25E.ts} +172 -74
  5. package/dist/chunks/chunk-2LMJU25E.ts.map +7 -0
  6. package/dist/chunks/{chunk-DPPVEQAM.ts → chunk-4AQSF7AS.ts} +1 -1
  7. package/dist/chunks/chunk-4AQSF7AS.ts.map +7 -0
  8. package/dist/chunks/chunk-6H6TBBED.ts +108 -0
  9. package/dist/chunks/chunk-6H6TBBED.ts.map +7 -0
  10. package/dist/chunks/{chunk-YBUWBRF7.ts → chunk-6NSJVPXX.ts} +6 -16
  11. package/dist/chunks/{chunk-YBUWBRF7.ts.map → chunk-6NSJVPXX.ts.map} +2 -2
  12. package/dist/chunks/{chunk-DSOOH73Y.ts → chunk-7AAJEUSL.ts} +3 -3
  13. package/dist/chunks/{chunk-DSOOH73Y.ts.map → chunk-7AAJEUSL.ts.map} +2 -2
  14. package/dist/chunks/{chunk-7QPPBBXZ.ts → chunk-D4CR7T73.ts} +21 -3
  15. package/dist/chunks/chunk-D4CR7T73.ts.map +7 -0
  16. package/dist/chunks/{chunk-NIF42QMF.ts → chunk-FEVPWRMU.ts} +7 -4
  17. package/dist/chunks/chunk-FEVPWRMU.ts.map +7 -0
  18. package/dist/chunks/{chunk-S2IWVK3J.ts → chunk-ILEQ27AL.ts} +3 -2
  19. package/dist/chunks/chunk-ILEQ27AL.ts.map +7 -0
  20. package/dist/chunks/{chunk-DQMN4OYM.ts → chunk-ITVWPNU4.ts} +12 -106
  21. package/dist/chunks/chunk-ITVWPNU4.ts.map +7 -0
  22. package/dist/chunks/{chunk-QDVGH2X7.ts → chunk-IWC32VPY.ts} +2 -1
  23. package/dist/chunks/{chunk-QDVGH2X7.ts.map → chunk-IWC32VPY.ts.map} +2 -2
  24. package/dist/chunks/{chunk-I2FAK44T.ts → chunk-JSZIP73U.ts} +48 -10
  25. package/dist/chunks/chunk-JSZIP73U.ts.map +7 -0
  26. package/dist/chunks/{chunk-ZHTNCZIA.ts → chunk-JU6LUNLP.ts} +2 -2
  27. package/dist/chunks/{chunk-PSK43Y6A.ts → chunk-LASD73CM.ts} +2 -2
  28. package/dist/chunks/{chunk-C4L6P266.ts → chunk-LEOYDZI3.ts} +1 -1
  29. package/dist/chunks/{chunk-C4L6P266.ts.map → chunk-LEOYDZI3.ts.map} +2 -2
  30. package/dist/chunks/{chunk-H3BFJ7HJ.ts → chunk-LL4LP2T7.ts} +5 -5
  31. package/dist/chunks/chunk-N2T5IN4X.ts +18 -0
  32. package/dist/chunks/chunk-N2T5IN4X.ts.map +7 -0
  33. package/dist/chunks/chunk-NLT67IZS.ts +322 -0
  34. package/dist/chunks/chunk-NLT67IZS.ts.map +7 -0
  35. package/dist/chunks/{chunk-G3RSMSXJ.ts → chunk-NTRPLF46.ts} +1 -1
  36. package/dist/chunks/chunk-NTRPLF46.ts.map +7 -0
  37. package/dist/chunks/{chunk-EFBPISNT.ts → chunk-PBZMBTNJ.ts} +104 -103
  38. package/dist/chunks/chunk-PBZMBTNJ.ts.map +7 -0
  39. package/dist/chunks/{chunk-SCZ33MYW.ts → chunk-PGLSFLYW.ts} +2 -2
  40. package/dist/chunks/{chunk-O4VO6JUJ.ts → chunk-TM2R67J3.ts} +3 -3
  41. package/dist/chunks/{chunk-QBORTI4W.ts → chunk-TMZRHIIK.ts} +32 -3
  42. package/dist/chunks/chunk-TMZRHIIK.ts.map +7 -0
  43. package/dist/chunks/chunk-TZ34IQ3M.ts +59 -0
  44. package/dist/chunks/chunk-TZ34IQ3M.ts.map +7 -0
  45. package/dist/chunks/{chunk-7OBINKFM.ts → chunk-VDG7LTYE.ts} +11 -11
  46. package/dist/chunks/chunk-VDG7LTYE.ts.map +7 -0
  47. package/dist/chunks/{chunk-AEUYS7JC.ts → chunk-X4NMONPE.ts} +1 -1
  48. package/dist/chunks/chunk-X4NMONPE.ts.map +7 -0
  49. package/dist/chunks/{chunk-HKC4ES4B.ts → chunk-YPJEN6NU.ts} +2 -2
  50. package/dist/chunks/{chunk-434NII74.ts → chunk-YU53SHA7.ts} +54 -8
  51. package/dist/chunks/chunk-YU53SHA7.ts.map +7 -0
  52. package/dist/chunks/{completion-delivery-YPOWSSV3.ts → completion-delivery-RSJU6BXL.ts} +5 -4
  53. package/dist/chunks/{config-status-J4GPWP46.ts → config-status-FKGDECZ3.ts} +7 -6
  54. package/dist/chunks/{config-ui-2YUCUEBM.ts → config-ui-ABHYNGQ7.ts} +297 -231
  55. package/dist/chunks/config-ui-ABHYNGQ7.ts.map +7 -0
  56. package/dist/chunks/{consult-IV7UBNQQ.ts → consult-LJU3IQY5.ts} +14 -13
  57. package/dist/chunks/consult-LJU3IQY5.ts.map +7 -0
  58. package/dist/chunks/{create-stateful-transport-ZP3IXNV3.ts → create-stateful-transport-JWC2EFYL.ts} +6 -6
  59. package/dist/chunks/{delegation-contract-WJPT4FVS.ts → delegation-contract-LA56I5DT.ts} +2 -2
  60. package/dist/chunks/{discovery-K25T3SH4.ts → discovery-MIFB2U4Y.ts} +3 -3
  61. package/dist/chunks/{execution-LA7HN5YF.ts → execution-Q2JZLKJA.ts} +19 -16
  62. package/dist/chunks/execution-Q2JZLKJA.ts.map +7 -0
  63. package/dist/chunks/{in-process-transport-4RF3J6XK.ts → in-process-transport-HJ6TZXC3.ts} +9 -9
  64. package/dist/chunks/{inspect-XV2QALMR.ts → inspect-UH2TKH6E.ts} +25 -10
  65. package/dist/chunks/inspect-UH2TKH6E.ts.map +7 -0
  66. package/dist/chunks/{persistence-VSGXAW4P.ts → persistence-UY3PY6E5.ts} +11 -7
  67. package/dist/chunks/persistence-UY3PY6E5.ts.map +7 -0
  68. package/dist/chunks/{registry-E6XPJB7L.ts → registry-BT54L6CY.ts} +136 -15
  69. package/dist/chunks/registry-BT54L6CY.ts.map +7 -0
  70. package/dist/chunks/{retained-semantic-state-7WXSGRJU.ts → retained-semantic-state-GM75FZGE.ts} +3 -3
  71. package/dist/chunks/{rpc-transport-NEHBHWX4.ts → rpc-transport-7R7DVCEB.ts} +12 -16
  72. package/dist/chunks/rpc-transport-7R7DVCEB.ts.map +7 -0
  73. package/dist/chunks/{spawn-idempotency-QGHO2WKC.ts → spawn-idempotency-BNHOSMZW.ts} +2 -2
  74. package/dist/chunks/{subprocess-transport-NSHOGDC4.ts → subprocess-transport-VHZJRBTW.ts} +15 -14
  75. package/dist/chunks/subprocess-transport-VHZJRBTW.ts.map +7 -0
  76. package/dist/chunks/usage-recording-store-CW3EH2SZ.ts +164 -0
  77. package/dist/chunks/usage-recording-store-CW3EH2SZ.ts.map +7 -0
  78. package/dist/index.ts +682 -82
  79. package/dist/index.ts.map +3 -3
  80. package/docs/async-runtime-protocol.md +83 -0
  81. package/docs/implementation-notes/pi-subagents-capability-matrix.md +62 -0
  82. package/docs/implementation-notes/pi-subagents-current-direction.md +99 -0
  83. package/docs/implementation-notes/pi-subagents-rpc-v1.md +153 -0
  84. package/docs/pi-subagents-diagrams.md +183 -0
  85. package/package.json +9 -8
  86. package/src/agents/types.ts +2 -0
  87. package/src/async-subagent-benchmark.ts +532 -0
  88. package/src/completion-delivery.ts +71 -4
  89. package/src/completion-render.ts +1 -0
  90. package/src/completion-requirement.ts +479 -0
  91. package/src/config-registration.ts +5 -5
  92. package/src/config-status.ts +66 -70
  93. package/src/config-ui.ts +244 -150
  94. package/src/consult-registration.ts +4 -12
  95. package/src/consult-resources.ts +1 -1
  96. package/src/consult.ts +3 -8
  97. package/src/delegation-contract.ts +55 -9
  98. package/src/execution-plan.ts +1 -1
  99. package/src/execution-ui.ts +40 -29
  100. package/src/execution.ts +2 -3
  101. package/src/inspect.ts +24 -1
  102. package/src/orchestration-metrics.ts +1 -1
  103. package/src/panel-execution.ts +2 -3
  104. package/src/panel-failure.ts +1 -1
  105. package/src/panel-render.ts +1 -1
  106. package/src/parallel-limit-ui.ts +6 -5
  107. package/src/params.ts +2 -1
  108. package/src/persistence.ts +9 -0
  109. package/src/process-control.ts +43 -0
  110. package/src/registry-types.ts +5 -0
  111. package/src/registry.ts +162 -18
  112. package/src/render.ts +2 -1
  113. package/src/rpc-transport.ts +1 -1
  114. package/src/runner-outcome.ts +1 -1
  115. package/src/runner-result.ts +1 -1
  116. package/src/runner-types.ts +102 -0
  117. package/src/runner.ts +11 -192
  118. package/src/session-guidance-contract.ts +309 -0
  119. package/src/settings/inspection.ts +27 -0
  120. package/src/settings/schema.ts +9 -0
  121. package/src/settings-reader.ts +7 -0
  122. package/src/settings.ts +20 -0
  123. package/src/spawn-idempotency.ts +5 -0
  124. package/src/stateful-agent-view.ts +15 -19
  125. package/src/stateful-guidance.ts +11 -18
  126. package/src/stateful-limit-ui.ts +23 -20
  127. package/src/stateful-limits.ts +10 -10
  128. package/src/stateful-registration.ts +126 -36
  129. package/src/stateful-render.ts +27 -2
  130. package/src/subagent-details.ts +43 -0
  131. package/src/subagents-extension.ts +116 -68
  132. package/src/subagents.ts +2 -0
  133. package/src/subprocess-transport.ts +2 -1
  134. package/src/supervision.ts +2 -1
  135. package/src/timeout-finalization.ts +1 -1
  136. package/src/tool-schema-compatibility.ts +73 -0
  137. package/src/transport-types.ts +6 -0
  138. package/src/transport-ui.ts +18 -46
  139. package/src/usage-recording-config.ts +13 -0
  140. package/src/usage-recording-store.ts +183 -0
  141. package/src/usage-recording.ts +478 -0
  142. package/src/verification-harness.ts +1 -1
  143. package/src/workflow-ui.ts +17 -9
  144. package/dist/chunks/chunk-434NII74.ts.map +0 -7
  145. package/dist/chunks/chunk-7OBINKFM.ts.map +0 -7
  146. package/dist/chunks/chunk-7QPPBBXZ.ts.map +0 -7
  147. package/dist/chunks/chunk-AEUYS7JC.ts.map +0 -7
  148. package/dist/chunks/chunk-CBP76ARQ.ts.map +0 -7
  149. package/dist/chunks/chunk-DPPVEQAM.ts.map +0 -7
  150. package/dist/chunks/chunk-DQMN4OYM.ts.map +0 -7
  151. package/dist/chunks/chunk-EFBPISNT.ts.map +0 -7
  152. package/dist/chunks/chunk-G3RSMSXJ.ts.map +0 -7
  153. package/dist/chunks/chunk-I2FAK44T.ts.map +0 -7
  154. package/dist/chunks/chunk-NIF42QMF.ts.map +0 -7
  155. package/dist/chunks/chunk-QBORTI4W.ts.map +0 -7
  156. package/dist/chunks/chunk-S2IWVK3J.ts.map +0 -7
  157. package/dist/chunks/config-ui-2YUCUEBM.ts.map +0 -7
  158. package/dist/chunks/consult-IV7UBNQQ.ts.map +0 -7
  159. package/dist/chunks/execution-LA7HN5YF.ts.map +0 -7
  160. package/dist/chunks/inspect-XV2QALMR.ts.map +0 -7
  161. package/dist/chunks/persistence-VSGXAW4P.ts.map +0 -7
  162. package/dist/chunks/registry-E6XPJB7L.ts.map +0 -7
  163. package/dist/chunks/rpc-transport-NEHBHWX4.ts.map +0 -7
  164. package/dist/chunks/subprocess-transport-NSHOGDC4.ts.map +0 -7
  165. /package/dist/chunks/{auto-transport-SY2VHUFH.ts.map → auto-transport-FUUKFDIG.ts.map} +0 -0
  166. /package/dist/chunks/{capability-grant-CGEWOEKE.ts.map → capability-grant-PR72SWWS.ts.map} +0 -0
  167. /package/dist/chunks/{chunk-ZHTNCZIA.ts.map → chunk-JU6LUNLP.ts.map} +0 -0
  168. /package/dist/chunks/{chunk-PSK43Y6A.ts.map → chunk-LASD73CM.ts.map} +0 -0
  169. /package/dist/chunks/{chunk-H3BFJ7HJ.ts.map → chunk-LL4LP2T7.ts.map} +0 -0
  170. /package/dist/chunks/{chunk-SCZ33MYW.ts.map → chunk-PGLSFLYW.ts.map} +0 -0
  171. /package/dist/chunks/{chunk-O4VO6JUJ.ts.map → chunk-TM2R67J3.ts.map} +0 -0
  172. /package/dist/chunks/{chunk-HKC4ES4B.ts.map → chunk-YPJEN6NU.ts.map} +0 -0
  173. /package/dist/chunks/{completion-delivery-YPOWSSV3.ts.map → completion-delivery-RSJU6BXL.ts.map} +0 -0
  174. /package/dist/chunks/{config-status-J4GPWP46.ts.map → config-status-FKGDECZ3.ts.map} +0 -0
  175. /package/dist/chunks/{create-stateful-transport-ZP3IXNV3.ts.map → create-stateful-transport-JWC2EFYL.ts.map} +0 -0
  176. /package/dist/chunks/{delegation-contract-WJPT4FVS.ts.map → delegation-contract-LA56I5DT.ts.map} +0 -0
  177. /package/dist/chunks/{discovery-K25T3SH4.ts.map → discovery-MIFB2U4Y.ts.map} +0 -0
  178. /package/dist/chunks/{in-process-transport-4RF3J6XK.ts.map → in-process-transport-HJ6TZXC3.ts.map} +0 -0
  179. /package/dist/chunks/{retained-semantic-state-7WXSGRJU.ts.map → retained-semantic-state-GM75FZGE.ts.map} +0 -0
  180. /package/dist/chunks/{spawn-idempotency-QGHO2WKC.ts.map → spawn-idempotency-BNHOSMZW.ts.map} +0 -0
@@ -0,0 +1,18 @@
1
+ // @generated by scripts/build-runtime.mjs; do not edit.
2
+ // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
+
4
+ // src/usage-recording-config.ts
5
+ var USAGE_RECORDING_DIRECTORY = "pi-subagents-usage";
6
+ var USAGE_RECORDING_RETENTION_DAYS = 30;
7
+ var USAGE_RECORDING_STUDY_ID = "pi-subagents-surface-v1";
8
+ function resolveUsageRecordingEnabled(settings) {
9
+ return settings?.enabled === true;
10
+ }
11
+
12
+ export {
13
+ USAGE_RECORDING_DIRECTORY,
14
+ USAGE_RECORDING_RETENTION_DAYS,
15
+ USAGE_RECORDING_STUDY_ID,
16
+ resolveUsageRecordingEnabled
17
+ };
18
+ //# sourceMappingURL=chunk-N2T5IN4X.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/usage-recording-config.ts"],
4
+ "sourcesContent": ["export const USAGE_RECORDING_DIRECTORY = \"pi-subagents-usage\";\nexport const USAGE_RECORDING_RETENTION_DAYS = 30;\nexport const USAGE_RECORDING_STUDY_ID = \"pi-subagents-surface-v1\";\n\nexport interface SubagentUsageRecordingSettings {\n\tenabled?: boolean;\n}\n\nexport function resolveUsageRecordingEnabled(\n\tsettings: SubagentUsageRecordingSettings | undefined,\n): boolean {\n\treturn settings?.enabled === true;\n}\n"],
5
+ "mappings": ";;;;AAAO,IAAM,4BAA4B;AAClC,IAAM,iCAAiC;AACvC,IAAM,2BAA2B;AAMjC,SAAS,6BACf,UACU;AACV,SAAO,UAAU,YAAY;AAC9B;",
6
+ "names": []
7
+ }
@@ -0,0 +1,322 @@
1
+ // @generated by scripts/build-runtime.mjs; do not edit.
2
+ // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
+ import {
4
+ DEFAULT_MAX_CONTEXT_BYTES,
5
+ truncateUtf8
6
+ } from "./chunk-H3FP6DLR.ts";
7
+
8
+ // src/completion-requirement.ts
9
+ import { StringEnum } from "@earendil-works/pi-ai";
10
+ var COMPLETION_REQUIREMENT_MODES = ["background", "required"];
11
+ var CompletionRequirementModeSchema = StringEnum(COMPLETION_REQUIREMENT_MODES, {
12
+ description: "Mark this exact turn as background (default) or required for the parent final answer. Required results are tracked until their exact completion becomes visible, but current Pi versions do not provide a hard pre-display final-answer barrier.",
13
+ default: "background"
14
+ });
15
+ var COMPLETION_REQUIREMENT_VERSION = "pi-subagents:completion-requirement:v1";
16
+ var COMPLETION_REQUIREMENT_CONTEXT_TYPE = "pi-subagent-required-completions";
17
+ var COMPLETION_REQUIREMENT_TRANSITION_TYPE = "pi-subagent-required-completion-transition";
18
+ var COMPLETION_REQUIREMENT_TRANSITION_VERSION = "pi-subagents:completion-requirement-transition:v1";
19
+ var MAX_REQUIREMENTS_PER_AGENT = 20;
20
+ var MAX_UNRESOLVED_REQUIRED_COMPLETIONS = 64;
21
+ function beginCompletionRequirement(records, input) {
22
+ const retained = (records ?? []).filter(
23
+ (record) => record.runId !== input.runId || record.generation !== input.generation
24
+ );
25
+ retained.push({
26
+ version: COMPLETION_REQUIREMENT_VERSION,
27
+ runId: input.runId,
28
+ generation: input.generation,
29
+ state: "pending",
30
+ createdAt: input.createdAt,
31
+ updatedAt: input.createdAt
32
+ });
33
+ return retained.slice(-MAX_REQUIREMENTS_PER_AGENT);
34
+ }
35
+ function makeCompletionAvailable(records, input) {
36
+ return updateExact(records, input.runId, input.generation, (record) => ({
37
+ ...record,
38
+ state: "available",
39
+ completionId: input.completionId,
40
+ terminalState: input.terminalState,
41
+ updatedAt: input.updatedAt
42
+ }));
43
+ }
44
+ function makeCompletionVisible(records, completionId, updatedAt) {
45
+ if (!records?.some((record) => record.completionId === completionId)) {
46
+ return records?.map((record) => ({ ...record }));
47
+ }
48
+ return records.map(
49
+ (record) => record.completionId === completionId ? { ...record, state: "visible", updatedAt } : { ...record }
50
+ );
51
+ }
52
+ function cancelPendingCompletionRequirements(records, terminalState, updatedAt) {
53
+ if (!records?.some((record) => record.state === "pending")) {
54
+ return records?.map((record) => ({ ...record }));
55
+ }
56
+ return records.map(
57
+ (record) => record.state === "pending" ? {
58
+ ...record,
59
+ state: "cancelled",
60
+ terminalState,
61
+ updatedAt
62
+ } : { ...record }
63
+ );
64
+ }
65
+ function requirementForCompletion(agent, completionId) {
66
+ return agent.completionRequirements?.find((record) => record.completionId === completionId);
67
+ }
68
+ function completionRequirementKey(record) {
69
+ return `${record.runId}\0${record.generation}`;
70
+ }
71
+ function completionRequirementsFromBranch(entries) {
72
+ const records = /* @__PURE__ */ new Map();
73
+ let observedState = false;
74
+ for (const entry of entries) {
75
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue;
76
+ const candidate = entry;
77
+ const message = candidate.type === "message" && candidate.message && typeof candidate.message === "object" ? candidate.message : candidate;
78
+ if (message.role === "toolResult" && ["subagent_spawn", "subagent_send", "subagent_await", "subagent_manage"].includes(
79
+ String(message.toolName)
80
+ )) {
81
+ observedState = true;
82
+ const details2 = message.details;
83
+ if (!details2 || typeof details2 !== "object" || Array.isArray(details2)) continue;
84
+ const detailsRecord = details2;
85
+ const agents = [
86
+ detailsRecord.agent,
87
+ ...Array.isArray(detailsRecord.agents) ? detailsRecord.agents : []
88
+ ];
89
+ for (const agent of agents) {
90
+ if (!agent || typeof agent !== "object" || Array.isArray(agent)) continue;
91
+ const requirements = agent.completionRequirements;
92
+ if (!Array.isArray(requirements)) continue;
93
+ for (const requirement of requirements) {
94
+ if (isCompletionRequirementRecord(requirement)) {
95
+ records.set(completionRequirementKey(requirement), { ...requirement });
96
+ }
97
+ }
98
+ }
99
+ continue;
100
+ }
101
+ if (message.role === "custom" && message.customType === COMPLETION_REQUIREMENT_TRANSITION_TYPE) {
102
+ const details2 = message.details;
103
+ if (!details2 || typeof details2 !== "object" || Array.isArray(details2)) continue;
104
+ const detailRecord2 = details2;
105
+ if (detailRecord2.version !== COMPLETION_REQUIREMENT_TRANSITION_VERSION) continue;
106
+ const requirements = Array.isArray(detailRecord2.records) ? detailRecord2.records : [];
107
+ for (const requirement of requirements) {
108
+ if (!isCompletionRequirementRecord(requirement) || requirement.state !== "cancelled") {
109
+ continue;
110
+ }
111
+ observedState = true;
112
+ records.set(completionRequirementKey(requirement), { ...requirement });
113
+ }
114
+ continue;
115
+ }
116
+ if (message.role !== "custom" || message.customType !== "pi-subagent-completion") continue;
117
+ const details = message.details;
118
+ if (!details || typeof details !== "object" || Array.isArray(details)) continue;
119
+ const detailRecord = details;
120
+ const completionRecords = Array.isArray(detailRecord.completions) ? detailRecord.completions : [detailRecord];
121
+ for (const completion of completionRecords) {
122
+ if (!completion || typeof completion !== "object" || Array.isArray(completion)) continue;
123
+ const requirement = completion.completionRequirement;
124
+ if (!isCompletionRequirementRecord(requirement)) continue;
125
+ records.set(completionRequirementKey(requirement), {
126
+ ...requirement,
127
+ state: "visible"
128
+ });
129
+ }
130
+ }
131
+ return { observedState, records, keys: new Set(records.keys()) };
132
+ }
133
+ function pendingRequiredCompletionCount(agent) {
134
+ return (agent.completionRequirements ?? []).filter(
135
+ (record) => record.state === "pending" || record.state === "available"
136
+ ).length;
137
+ }
138
+ function createRequiredCompletionTransition(messages, agents) {
139
+ const summarized = leadingSummaryBoundary(messages) > 0;
140
+ const state = modelRequirementState(agents);
141
+ const visible = completionRequirementsFromBranch(messages).records;
142
+ const records = state.records.filter((record) => {
143
+ if (record.state !== "cancelled") return false;
144
+ const retained = visible.get(completionRequirementKey(record));
145
+ if (modelRequirementStateMatches(retained, record)) return false;
146
+ return !summarized || retained !== void 0;
147
+ });
148
+ if (records.length === 0) return void 0;
149
+ return {
150
+ role: "custom",
151
+ customType: COMPLETION_REQUIREMENT_TRANSITION_TYPE,
152
+ content: requiredCompletionTransitionContent(records, state.omittedCancelled),
153
+ display: false,
154
+ details: {
155
+ version: COMPLETION_REQUIREMENT_TRANSITION_VERSION,
156
+ records: records.map((record) => ({ ...record }))
157
+ },
158
+ timestamp: 0
159
+ };
160
+ }
161
+ function reconcileRequiredCompletionContext(messages, agents, restorationPredecessors = [], restoredBoundaryContent) {
162
+ const existing = messages.filter(isRequiredCompletionContextMessage);
163
+ const withoutPrior = messages.filter((message) => !isRequiredCompletionContextMessage(message));
164
+ const state = modelRequirementState(agents);
165
+ const summaryBoundary = leadingSummaryBoundary(withoutPrior);
166
+ const currentContent = state.records.length > 0 && !hasModelVisibleRequirementState(withoutPrior, state.records) ? requiredCompletionContextContent(state.records, state.omittedCancelled) : void 0;
167
+ const content = summaryBoundary > 0 ? restoredBoundaryContent ?? currentContent : void 0;
168
+ let insertionBoundary = summaryBoundary;
169
+ while (insertionBoundary < withoutPrior.length) {
170
+ const predecessor = withoutPrior[insertionBoundary];
171
+ if (predecessor?.role !== "custom" || !restorationPredecessors.includes(predecessor.customType)) {
172
+ break;
173
+ }
174
+ insertionBoundary += 1;
175
+ }
176
+ if (content !== void 0 && existing.length === 1 && messages[insertionBoundary] === existing[0] && existing[0]?.content === content && hasCompletionRequirementContextVersion(existing[0])) {
177
+ return messages;
178
+ }
179
+ if (existing.length === 0 && content === void 0) return messages;
180
+ if (content === void 0) return withoutPrior;
181
+ return [
182
+ ...withoutPrior.slice(0, insertionBoundary),
183
+ {
184
+ role: "custom",
185
+ customType: COMPLETION_REQUIREMENT_CONTEXT_TYPE,
186
+ content,
187
+ display: false,
188
+ details: { version: COMPLETION_REQUIREMENT_VERSION },
189
+ timestamp: 0
190
+ },
191
+ ...withoutPrior.slice(insertionBoundary)
192
+ ];
193
+ }
194
+ function modelRequirementState(agents) {
195
+ const allRecords = agents.flatMap(
196
+ (agent) => (agent.completionRequirements ?? []).map((requirement) => ({ ...requirement }))
197
+ ).filter((record) => record.state !== "visible");
198
+ const unresolved = allRecords.filter(
199
+ (record) => record.state === "pending" || record.state === "available"
200
+ );
201
+ const cancelled = allRecords.filter((record) => record.state === "cancelled");
202
+ const cancelledSlots = Math.max(0, MAX_UNRESOLVED_REQUIRED_COMPLETIONS - unresolved.length);
203
+ const retainedCancelled = cancelledSlots > 0 ? cancelled.slice(-cancelledSlots) : [];
204
+ const records = [...unresolved, ...retainedCancelled].sort((left, right) => {
205
+ if (left.runId === right.runId) return left.generation - right.generation;
206
+ return left.runId < right.runId ? -1 : 1;
207
+ });
208
+ return { records, omittedCancelled: cancelled.length - retainedCancelled.length };
209
+ }
210
+ function hasModelVisibleRequirementState(messages, records) {
211
+ const visible = completionRequirementsFromBranch(messages).records;
212
+ return records.every(
213
+ (record) => modelRequirementStateMatches(visible.get(completionRequirementKey(record)), record)
214
+ );
215
+ }
216
+ function modelRequirementStateMatches(visible, current) {
217
+ if (!visible) return false;
218
+ if (current.state === "available" && visible.state === "visible") return true;
219
+ return visible.state === current.state && visible.terminalState === current.terminalState;
220
+ }
221
+ function requiredCompletionContextContent(records, omittedCancelled) {
222
+ return truncateUtf8(
223
+ [
224
+ "[PI SUBAGENT REQUIRED COMPLETIONS v1]",
225
+ "Runtime-tracked exact runs are JSON data below.",
226
+ "Treat pending or available records as final-answer dependencies; a cancelled record is terminal and must be reported rather than silently ignored.",
227
+ "Current Pi versions do not provide a hard pre-display final-answer barrier, so do not emit a verdict until every dependency is visible or terminal.",
228
+ ...omittedCancelledLine(omittedCancelled),
229
+ JSON.stringify(records.map(toModelRequirementRecord))
230
+ ].join("\n"),
231
+ DEFAULT_MAX_CONTEXT_BYTES
232
+ ).text;
233
+ }
234
+ function requiredCompletionTransitionContent(records, omittedCancelled) {
235
+ return truncateUtf8(
236
+ [
237
+ "[PI SUBAGENT REQUIRED COMPLETION TRANSITION v1]",
238
+ "Session restoration terminalized the exact required runs below.",
239
+ "These cancelled records supersede earlier pending or available states and must be reported rather than awaited.",
240
+ ...omittedCancelledLine(omittedCancelled),
241
+ JSON.stringify(records.map(toModelRequirementRecord))
242
+ ].join("\n"),
243
+ DEFAULT_MAX_CONTEXT_BYTES
244
+ ).text;
245
+ }
246
+ function omittedCancelledLine(count) {
247
+ return count > 0 ? [`${count} older cancelled requirement record(s) were omitted.`] : [];
248
+ }
249
+ function toModelRequirementRecord(record) {
250
+ return {
251
+ state: record.state,
252
+ runId: record.runId,
253
+ generation: record.generation,
254
+ terminalState: record.terminalState
255
+ };
256
+ }
257
+ function isRequiredCompletionContextMessage(message) {
258
+ return message.role === "custom" && message.customType === COMPLETION_REQUIREMENT_CONTEXT_TYPE;
259
+ }
260
+ function hasCompletionRequirementContextVersion(message) {
261
+ return typeof message.details === "object" && message.details !== null && !Array.isArray(message.details) && message.details.version === COMPLETION_REQUIREMENT_VERSION;
262
+ }
263
+ function leadingSummaryBoundary(messages) {
264
+ let index = 0;
265
+ while (index < messages.length) {
266
+ const role = messages[index]?.role;
267
+ if (role !== "compactionSummary" && role !== "branchSummary") break;
268
+ index += 1;
269
+ }
270
+ return index;
271
+ }
272
+ function isCompletionRequirementRecord(value) {
273
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
274
+ const record = value;
275
+ const state = String(record.state);
276
+ const hasCompletion = typeof record.completionId === "string" && record.completionId.length > 0;
277
+ const hasTerminalState = isAgentLifecycleState(record.terminalState);
278
+ const transitionShapeValid = state === "pending" ? record.completionId === void 0 && record.terminalState === void 0 : state === "available" || state === "visible" ? hasCompletion && hasTerminalState : state === "cancelled" && record.completionId === void 0 && hasTerminalState;
279
+ return transitionShapeValid && record.version === COMPLETION_REQUIREMENT_VERSION && typeof record.runId === "string" && record.runId.length > 0 && record.runId.length <= 256 && typeof record.generation === "number" && Number.isSafeInteger(record.generation) && record.generation >= 1 && ["pending", "available", "visible", "cancelled"].includes(state) && typeof record.createdAt === "number" && Number.isFinite(record.createdAt) && typeof record.updatedAt === "number" && Number.isFinite(record.updatedAt) && record.updatedAt >= record.createdAt && (record.completionId === void 0 || typeof record.completionId === "string" && record.completionId.length <= 256) && (record.terminalState === void 0 || isAgentLifecycleState(record.terminalState));
280
+ }
281
+ function updateExact(records, runId, generation, update) {
282
+ if (!records?.some((record) => record.runId === runId && record.generation === generation)) {
283
+ return records?.map((record) => ({ ...record }));
284
+ }
285
+ return records.map(
286
+ (record) => record.runId === runId && record.generation === generation ? update(record) : { ...record }
287
+ );
288
+ }
289
+ function isAgentLifecycleState(value) {
290
+ return [
291
+ "starting",
292
+ "running",
293
+ "idle",
294
+ "completed",
295
+ "partial",
296
+ "blocked",
297
+ "needs-input",
298
+ "abstained",
299
+ "stale",
300
+ "interrupted",
301
+ "failed",
302
+ "closed"
303
+ ].includes(String(value));
304
+ }
305
+
306
+ export {
307
+ CompletionRequirementModeSchema,
308
+ COMPLETION_REQUIREMENT_CONTEXT_TYPE,
309
+ MAX_UNRESOLVED_REQUIRED_COMPLETIONS,
310
+ beginCompletionRequirement,
311
+ makeCompletionAvailable,
312
+ makeCompletionVisible,
313
+ cancelPendingCompletionRequirements,
314
+ requirementForCompletion,
315
+ completionRequirementKey,
316
+ completionRequirementsFromBranch,
317
+ pendingRequiredCompletionCount,
318
+ createRequiredCompletionTransition,
319
+ reconcileRequiredCompletionContext,
320
+ isCompletionRequirementRecord
321
+ };
322
+ //# sourceMappingURL=chunk-NLT67IZS.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/completion-requirement.ts"],
4
+ "sourcesContent": ["import { StringEnum } from \"@earendil-works/pi-ai\";\nimport type { ContextEvent } from \"@earendil-works/pi-coding-agent\";\nimport { DEFAULT_MAX_CONTEXT_BYTES, truncateUtf8 } from \"./limits.js\";\nimport type { AgentLifecycleState, ManagedAgent } from \"./registry-types.js\";\n\nexport const COMPLETION_REQUIREMENT_MODES = [\"background\", \"required\"] as const;\nexport type CompletionRequirementMode = (typeof COMPLETION_REQUIREMENT_MODES)[number];\n\nexport const CompletionRequirementModeSchema = StringEnum(COMPLETION_REQUIREMENT_MODES, {\n\tdescription:\n\t\t\"Mark this exact turn as background (default) or required for the parent final answer. Required results are tracked until their exact completion becomes visible, but current Pi versions do not provide a hard pre-display final-answer barrier.\",\n\tdefault: \"background\",\n});\n\nexport const COMPLETION_REQUIREMENT_VERSION = \"pi-subagents:completion-requirement:v1\" as const;\nexport const COMPLETION_REQUIREMENT_CONTEXT_TYPE = \"pi-subagent-required-completions\";\nexport const COMPLETION_REQUIREMENT_TRANSITION_TYPE = \"pi-subagent-required-completion-transition\";\nexport const COMPLETION_REQUIREMENT_TRANSITION_VERSION =\n\t\"pi-subagents:completion-requirement-transition:v1\" as const;\nconst MAX_REQUIREMENTS_PER_AGENT = 20;\nexport const MAX_UNRESOLVED_REQUIRED_COMPLETIONS = 64;\n\nexport type CompletionRequirementState = \"pending\" | \"available\" | \"visible\" | \"cancelled\";\n\nexport interface CompletionRequirementRecord {\n\tversion: typeof COMPLETION_REQUIREMENT_VERSION;\n\trunId: string;\n\tgeneration: number;\n\tstate: CompletionRequirementState;\n\tcreatedAt: number;\n\tupdatedAt: number;\n\tcompletionId?: string;\n\tterminalState?: AgentLifecycleState;\n}\n\nexport function beginCompletionRequirement(\n\trecords: readonly CompletionRequirementRecord[] | undefined,\n\tinput: { runId: string; generation: number; createdAt: number },\n): CompletionRequirementRecord[] {\n\tconst retained = (records ?? []).filter(\n\t\t(record) => record.runId !== input.runId || record.generation !== input.generation,\n\t);\n\tretained.push({\n\t\tversion: COMPLETION_REQUIREMENT_VERSION,\n\t\trunId: input.runId,\n\t\tgeneration: input.generation,\n\t\tstate: \"pending\",\n\t\tcreatedAt: input.createdAt,\n\t\tupdatedAt: input.createdAt,\n\t});\n\treturn retained.slice(-MAX_REQUIREMENTS_PER_AGENT);\n}\n\nexport function makeCompletionAvailable(\n\trecords: readonly CompletionRequirementRecord[] | undefined,\n\tinput: {\n\t\trunId: string;\n\t\tgeneration: number;\n\t\tcompletionId: string;\n\t\tterminalState: AgentLifecycleState;\n\t\tupdatedAt: number;\n\t},\n): CompletionRequirementRecord[] | undefined {\n\treturn updateExact(records, input.runId, input.generation, (record) => ({\n\t\t...record,\n\t\tstate: \"available\",\n\t\tcompletionId: input.completionId,\n\t\tterminalState: input.terminalState,\n\t\tupdatedAt: input.updatedAt,\n\t}));\n}\n\nexport function makeCompletionVisible(\n\trecords: readonly CompletionRequirementRecord[] | undefined,\n\tcompletionId: string,\n\tupdatedAt: number,\n): CompletionRequirementRecord[] | undefined {\n\tif (!records?.some((record) => record.completionId === completionId)) {\n\t\treturn records?.map((record) => ({ ...record }));\n\t}\n\treturn records.map((record) =>\n\t\trecord.completionId === completionId\n\t\t\t? { ...record, state: \"visible\" as const, updatedAt }\n\t\t\t: { ...record },\n\t);\n}\n\nexport function cancelPendingCompletionRequirements(\n\trecords: readonly CompletionRequirementRecord[] | undefined,\n\tterminalState: AgentLifecycleState,\n\tupdatedAt: number,\n): CompletionRequirementRecord[] | undefined {\n\tif (!records?.some((record) => record.state === \"pending\")) {\n\t\treturn records?.map((record) => ({ ...record }));\n\t}\n\treturn records.map((record) =>\n\t\trecord.state === \"pending\"\n\t\t\t? {\n\t\t\t\t\t...record,\n\t\t\t\t\tstate: \"cancelled\" as const,\n\t\t\t\t\tterminalState,\n\t\t\t\t\tupdatedAt,\n\t\t\t\t}\n\t\t\t: { ...record },\n\t);\n}\n\nexport function requirementForCompletion(\n\tagent: Pick<ManagedAgent, \"completionRequirements\">,\n\tcompletionId: string,\n): CompletionRequirementRecord | undefined {\n\treturn agent.completionRequirements?.find((record) => record.completionId === completionId);\n}\n\nexport interface BranchCompletionRequirementState {\n\tobservedState: boolean;\n\trecords: Map<string, CompletionRequirementRecord>;\n\tkeys: Set<string>;\n}\n\nexport function completionRequirementKey(\n\trecord: Pick<CompletionRequirementRecord, \"runId\" | \"generation\">,\n): string {\n\treturn `${record.runId}\\u0000${record.generation}`;\n}\n\nexport function completionRequirementsFromBranch(\n\tentries: readonly unknown[],\n): BranchCompletionRequirementState {\n\tconst records = new Map<string, CompletionRequirementRecord>();\n\tlet observedState = false;\n\tfor (const entry of entries) {\n\t\tif (!entry || typeof entry !== \"object\" || Array.isArray(entry)) continue;\n\t\tconst candidate = entry as Record<string, unknown>;\n\t\tconst message =\n\t\t\tcandidate.type === \"message\" && candidate.message && typeof candidate.message === \"object\"\n\t\t\t\t? (candidate.message as Record<string, unknown>)\n\t\t\t\t: candidate;\n\t\tif (\n\t\t\tmessage.role === \"toolResult\" &&\n\t\t\t[\"subagent_spawn\", \"subagent_send\", \"subagent_await\", \"subagent_manage\"].includes(\n\t\t\t\tString(message.toolName),\n\t\t\t)\n\t\t) {\n\t\t\tobservedState = true;\n\t\t\tconst details = message.details;\n\t\t\tif (!details || typeof details !== \"object\" || Array.isArray(details)) continue;\n\t\t\tconst detailsRecord = details as Record<string, unknown>;\n\t\t\tconst agents = [\n\t\t\t\tdetailsRecord.agent,\n\t\t\t\t...(Array.isArray(detailsRecord.agents) ? detailsRecord.agents : []),\n\t\t\t];\n\t\t\tfor (const agent of agents) {\n\t\t\t\tif (!agent || typeof agent !== \"object\" || Array.isArray(agent)) continue;\n\t\t\t\tconst requirements = (agent as Record<string, unknown>).completionRequirements;\n\t\t\t\tif (!Array.isArray(requirements)) continue;\n\t\t\t\tfor (const requirement of requirements) {\n\t\t\t\t\tif (isCompletionRequirementRecord(requirement)) {\n\t\t\t\t\t\trecords.set(completionRequirementKey(requirement), { ...requirement });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (\n\t\t\tmessage.role === \"custom\" &&\n\t\t\tmessage.customType === COMPLETION_REQUIREMENT_TRANSITION_TYPE\n\t\t) {\n\t\t\tconst details = message.details;\n\t\t\tif (!details || typeof details !== \"object\" || Array.isArray(details)) continue;\n\t\t\tconst detailRecord = details as Record<string, unknown>;\n\t\t\tif (detailRecord.version !== COMPLETION_REQUIREMENT_TRANSITION_VERSION) continue;\n\t\t\tconst requirements = Array.isArray(detailRecord.records) ? detailRecord.records : [];\n\t\t\tfor (const requirement of requirements) {\n\t\t\t\tif (!isCompletionRequirementRecord(requirement) || requirement.state !== \"cancelled\") {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tobservedState = true;\n\t\t\t\trecords.set(completionRequirementKey(requirement), { ...requirement });\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (message.role !== \"custom\" || message.customType !== \"pi-subagent-completion\") continue;\n\t\tconst details = message.details;\n\t\tif (!details || typeof details !== \"object\" || Array.isArray(details)) continue;\n\t\tconst detailRecord = details as Record<string, unknown>;\n\t\tconst completionRecords = Array.isArray(detailRecord.completions)\n\t\t\t? detailRecord.completions\n\t\t\t: [detailRecord];\n\t\tfor (const completion of completionRecords) {\n\t\t\tif (!completion || typeof completion !== \"object\" || Array.isArray(completion)) continue;\n\t\t\tconst requirement = (completion as Record<string, unknown>).completionRequirement;\n\t\t\tif (!isCompletionRequirementRecord(requirement)) continue;\n\t\t\trecords.set(completionRequirementKey(requirement), {\n\t\t\t\t...requirement,\n\t\t\t\tstate: \"visible\",\n\t\t\t});\n\t\t}\n\t}\n\treturn { observedState, records, keys: new Set(records.keys()) };\n}\n\nexport function pendingRequiredCompletionCount(\n\tagent: Pick<ManagedAgent, \"completionRequirements\">,\n): number {\n\treturn (agent.completionRequirements ?? []).filter(\n\t\t(record) => record.state === \"pending\" || record.state === \"available\",\n\t).length;\n}\n\nexport function createRequiredCompletionTransition(\n\tmessages: ContextEvent[\"messages\"],\n\tagents: readonly ManagedAgent[],\n) {\n\tconst summarized = leadingSummaryBoundary(messages) > 0;\n\tconst state = modelRequirementState(agents);\n\tconst visible = completionRequirementsFromBranch(messages).records;\n\tconst records = state.records.filter((record) => {\n\t\tif (record.state !== \"cancelled\") return false;\n\t\tconst retained = visible.get(completionRequirementKey(record));\n\t\tif (modelRequirementStateMatches(retained, record)) return false;\n\t\treturn !summarized || retained !== undefined;\n\t});\n\tif (records.length === 0) return undefined;\n\treturn {\n\t\trole: \"custom\" as const,\n\t\tcustomType: COMPLETION_REQUIREMENT_TRANSITION_TYPE,\n\t\tcontent: requiredCompletionTransitionContent(records, state.omittedCancelled),\n\t\tdisplay: false,\n\t\tdetails: {\n\t\t\tversion: COMPLETION_REQUIREMENT_TRANSITION_VERSION,\n\t\t\trecords: records.map((record) => ({ ...record })),\n\t\t},\n\t\ttimestamp: 0,\n\t};\n}\n\nexport function reconcileRequiredCompletionContext(\n\tmessages: ContextEvent[\"messages\"],\n\tagents: readonly ManagedAgent[],\n\trestorationPredecessors: readonly string[] = [],\n\trestoredBoundaryContent?: string,\n): ContextEvent[\"messages\"] {\n\tconst existing = messages.filter(isRequiredCompletionContextMessage);\n\tconst withoutPrior = messages.filter((message) => !isRequiredCompletionContextMessage(message));\n\tconst state = modelRequirementState(agents);\n\tconst summaryBoundary = leadingSummaryBoundary(withoutPrior);\n\tconst currentContent =\n\t\tstate.records.length > 0 && !hasModelVisibleRequirementState(withoutPrior, state.records)\n\t\t\t? requiredCompletionContextContent(state.records, state.omittedCancelled)\n\t\t\t: undefined;\n\tconst content = summaryBoundary > 0 ? (restoredBoundaryContent ?? currentContent) : undefined;\n\tlet insertionBoundary = summaryBoundary;\n\twhile (insertionBoundary < withoutPrior.length) {\n\t\tconst predecessor = withoutPrior[insertionBoundary];\n\t\tif (\n\t\t\tpredecessor?.role !== \"custom\" ||\n\t\t\t!restorationPredecessors.includes(predecessor.customType)\n\t\t) {\n\t\t\tbreak;\n\t\t}\n\t\tinsertionBoundary += 1;\n\t}\n\tif (\n\t\tcontent !== undefined &&\n\t\texisting.length === 1 &&\n\t\tmessages[insertionBoundary] === existing[0] &&\n\t\texisting[0]?.content === content &&\n\t\thasCompletionRequirementContextVersion(existing[0])\n\t) {\n\t\treturn messages;\n\t}\n\tif (existing.length === 0 && content === undefined) return messages;\n\tif (content === undefined) return withoutPrior;\n\treturn [\n\t\t...withoutPrior.slice(0, insertionBoundary),\n\t\t{\n\t\t\trole: \"custom\",\n\t\t\tcustomType: COMPLETION_REQUIREMENT_CONTEXT_TYPE,\n\t\t\tcontent,\n\t\t\tdisplay: false,\n\t\t\tdetails: { version: COMPLETION_REQUIREMENT_VERSION },\n\t\t\ttimestamp: 0,\n\t\t},\n\t\t...withoutPrior.slice(insertionBoundary),\n\t];\n}\n\ninterface ModelRequirementRecord {\n\tstate: CompletionRequirementState;\n\trunId: string;\n\tgeneration: number;\n\tterminalState: AgentLifecycleState | undefined;\n}\n\nfunction modelRequirementState(agents: readonly ManagedAgent[]): {\n\trecords: CompletionRequirementRecord[];\n\tomittedCancelled: number;\n} {\n\tconst allRecords = agents\n\t\t.flatMap((agent) =>\n\t\t\t(agent.completionRequirements ?? []).map((requirement) => ({ ...requirement })),\n\t\t)\n\t\t.filter((record) => record.state !== \"visible\");\n\tconst unresolved = allRecords.filter(\n\t\t(record) => record.state === \"pending\" || record.state === \"available\",\n\t);\n\tconst cancelled = allRecords.filter((record) => record.state === \"cancelled\");\n\tconst cancelledSlots = Math.max(0, MAX_UNRESOLVED_REQUIRED_COMPLETIONS - unresolved.length);\n\tconst retainedCancelled = cancelledSlots > 0 ? cancelled.slice(-cancelledSlots) : [];\n\tconst records = [...unresolved, ...retainedCancelled].sort((left, right) => {\n\t\tif (left.runId === right.runId) return left.generation - right.generation;\n\t\treturn left.runId < right.runId ? -1 : 1;\n\t});\n\treturn { records, omittedCancelled: cancelled.length - retainedCancelled.length };\n}\n\nfunction hasModelVisibleRequirementState(\n\tmessages: ContextEvent[\"messages\"],\n\trecords: readonly CompletionRequirementRecord[],\n): boolean {\n\tconst visible = completionRequirementsFromBranch(messages).records;\n\treturn records.every((record) =>\n\t\tmodelRequirementStateMatches(visible.get(completionRequirementKey(record)), record),\n\t);\n}\n\nfunction modelRequirementStateMatches(\n\tvisible: CompletionRequirementRecord | undefined,\n\tcurrent: CompletionRequirementRecord,\n): boolean {\n\tif (!visible) return false;\n\tif (current.state === \"available\" && visible.state === \"visible\") return true;\n\treturn visible.state === current.state && visible.terminalState === current.terminalState;\n}\n\nfunction requiredCompletionContextContent(\n\trecords: readonly CompletionRequirementRecord[],\n\tomittedCancelled: number,\n): string {\n\treturn truncateUtf8(\n\t\t[\n\t\t\t\"[PI SUBAGENT REQUIRED COMPLETIONS v1]\",\n\t\t\t\"Runtime-tracked exact runs are JSON data below.\",\n\t\t\t\"Treat pending or available records as final-answer dependencies; a cancelled record is terminal and must be reported rather than silently ignored.\",\n\t\t\t\"Current Pi versions do not provide a hard pre-display final-answer barrier, so do not emit a verdict until every dependency is visible or terminal.\",\n\t\t\t...omittedCancelledLine(omittedCancelled),\n\t\t\tJSON.stringify(records.map(toModelRequirementRecord)),\n\t\t].join(\"\\n\"),\n\t\tDEFAULT_MAX_CONTEXT_BYTES,\n\t).text;\n}\n\nfunction requiredCompletionTransitionContent(\n\trecords: readonly CompletionRequirementRecord[],\n\tomittedCancelled: number,\n): string {\n\treturn truncateUtf8(\n\t\t[\n\t\t\t\"[PI SUBAGENT REQUIRED COMPLETION TRANSITION v1]\",\n\t\t\t\"Session restoration terminalized the exact required runs below.\",\n\t\t\t\"These cancelled records supersede earlier pending or available states and must be reported rather than awaited.\",\n\t\t\t...omittedCancelledLine(omittedCancelled),\n\t\t\tJSON.stringify(records.map(toModelRequirementRecord)),\n\t\t].join(\"\\n\"),\n\t\tDEFAULT_MAX_CONTEXT_BYTES,\n\t).text;\n}\n\nfunction omittedCancelledLine(count: number): string[] {\n\treturn count > 0 ? [`${count} older cancelled requirement record(s) were omitted.`] : [];\n}\n\nfunction toModelRequirementRecord(record: CompletionRequirementRecord): ModelRequirementRecord {\n\treturn {\n\t\tstate: record.state,\n\t\trunId: record.runId,\n\t\tgeneration: record.generation,\n\t\tterminalState: record.terminalState,\n\t};\n}\n\ntype RequiredCompletionContextMessage = Extract<\n\tContextEvent[\"messages\"][number],\n\t{ role: \"custom\" }\n> & { content: string };\n\nfunction isRequiredCompletionContextMessage(\n\tmessage: ContextEvent[\"messages\"][number],\n): message is RequiredCompletionContextMessage {\n\treturn message.role === \"custom\" && message.customType === COMPLETION_REQUIREMENT_CONTEXT_TYPE;\n}\n\nfunction hasCompletionRequirementContextVersion(\n\tmessage: RequiredCompletionContextMessage,\n): boolean {\n\treturn (\n\t\ttypeof message.details === \"object\" &&\n\t\tmessage.details !== null &&\n\t\t!Array.isArray(message.details) &&\n\t\t(message.details as Record<string, unknown>).version === COMPLETION_REQUIREMENT_VERSION\n\t);\n}\n\nfunction leadingSummaryBoundary(messages: ContextEvent[\"messages\"]): number {\n\tlet index = 0;\n\twhile (index < messages.length) {\n\t\tconst role = messages[index]?.role;\n\t\tif (role !== \"compactionSummary\" && role !== \"branchSummary\") break;\n\t\tindex += 1;\n\t}\n\treturn index;\n}\n\nexport function isCompletionRequirementRecord(\n\tvalue: unknown,\n): value is CompletionRequirementRecord {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n\tconst record = value as Record<string, unknown>;\n\tconst state = String(record.state);\n\tconst hasCompletion = typeof record.completionId === \"string\" && record.completionId.length > 0;\n\tconst hasTerminalState = isAgentLifecycleState(record.terminalState);\n\tconst transitionShapeValid =\n\t\tstate === \"pending\"\n\t\t\t? record.completionId === undefined && record.terminalState === undefined\n\t\t\t: state === \"available\" || state === \"visible\"\n\t\t\t\t? hasCompletion && hasTerminalState\n\t\t\t\t: state === \"cancelled\" && record.completionId === undefined && hasTerminalState;\n\treturn (\n\t\ttransitionShapeValid &&\n\t\trecord.version === COMPLETION_REQUIREMENT_VERSION &&\n\t\ttypeof record.runId === \"string\" &&\n\t\trecord.runId.length > 0 &&\n\t\trecord.runId.length <= 256 &&\n\t\ttypeof record.generation === \"number\" &&\n\t\tNumber.isSafeInteger(record.generation) &&\n\t\trecord.generation >= 1 &&\n\t\t[\"pending\", \"available\", \"visible\", \"cancelled\"].includes(state) &&\n\t\ttypeof record.createdAt === \"number\" &&\n\t\tNumber.isFinite(record.createdAt) &&\n\t\ttypeof record.updatedAt === \"number\" &&\n\t\tNumber.isFinite(record.updatedAt) &&\n\t\trecord.updatedAt >= record.createdAt &&\n\t\t(record.completionId === undefined ||\n\t\t\t(typeof record.completionId === \"string\" && record.completionId.length <= 256)) &&\n\t\t(record.terminalState === undefined || isAgentLifecycleState(record.terminalState))\n\t);\n}\n\nfunction updateExact(\n\trecords: readonly CompletionRequirementRecord[] | undefined,\n\trunId: string,\n\tgeneration: number,\n\tupdate: (record: CompletionRequirementRecord) => CompletionRequirementRecord,\n): CompletionRequirementRecord[] | undefined {\n\tif (!records?.some((record) => record.runId === runId && record.generation === generation)) {\n\t\treturn records?.map((record) => ({ ...record }));\n\t}\n\treturn records.map((record) =>\n\t\trecord.runId === runId && record.generation === generation ? update(record) : { ...record },\n\t);\n}\n\nfunction isAgentLifecycleState(value: unknown): value is AgentLifecycleState {\n\treturn [\n\t\t\"starting\",\n\t\t\"running\",\n\t\t\"idle\",\n\t\t\"completed\",\n\t\t\"partial\",\n\t\t\"blocked\",\n\t\t\"needs-input\",\n\t\t\"abstained\",\n\t\t\"stale\",\n\t\t\"interrupted\",\n\t\t\"failed\",\n\t\t\"closed\",\n\t].includes(String(value));\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["details", "detailRecord"]
7
+ }
@@ -60,4 +60,4 @@ export {
60
60
  resolveTimeoutFinalizationMs,
61
61
  buildTimeoutFinalizationPrompt
62
62
  };
63
- //# sourceMappingURL=chunk-G3RSMSXJ.ts.map
63
+ //# sourceMappingURL=chunk-NTRPLF46.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/timeout-finalization.ts"],
4
+ "sourcesContent": ["import { redactPrivateText } from \"./context.js\";\nimport { DEFAULT_MAX_CONTEXT_BYTES, truncateUtf8 } from \"./limits.js\";\nimport { appendResultInstruction, type SubagentResultFormat } from \"./result-contract.js\";\nimport type { RecentActivityItem } from \"./runner-types.js\";\nimport {\n\tformatTimeoutCheckpoint,\n\ttype TimeoutCheckpoint,\n\ttype TurnTerminationReason,\n} from \"./timeout-checkpoint.js\";\n\nexport const DEFAULT_TIMEOUT_FINALIZATION_MS = 45_000;\n\nexport interface TimeoutFinalizationEvidence {\n\ttask: string;\n\tpartialOutput?: string;\n\trecentActivity?: readonly RecentActivityItem[];\n\tcheckpoint?: TimeoutCheckpoint;\n\tterminationReason?: TurnTerminationReason;\n\tresultFormat?: SubagentResultFormat;\n}\n\nexport function resolveTimeoutFinalizationMs(workTimeoutMs: number, override?: number): number {\n\tconst requested = override ?? Math.min(workTimeoutMs, DEFAULT_TIMEOUT_FINALIZATION_MS);\n\tif (!Number.isFinite(requested) || requested < 1) {\n\t\tthrow new Error(\"Timeout finalization deadline must be a positive finite number\");\n\t}\n\treturn Math.min(Math.floor(requested), DEFAULT_TIMEOUT_FINALIZATION_MS);\n}\n\nexport function buildTimeoutFinalizationPrompt(\n\tevidence: TimeoutFinalizationEvidence,\n\tmaxBytes = DEFAULT_MAX_CONTEXT_BYTES,\n): string {\n\tconst activity = (evidence.recentActivity ?? [])\n\t\t.slice(-10)\n\t\t.map((item) =>\n\t\t\titem.type === \"text\"\n\t\t\t\t? `- Assistant note: ${redactPrivateText(item.text)}`\n\t\t\t\t: `- Tool activity: ${redactPrivateText(item.name)}`,\n\t\t)\n\t\t.join(\"\\n\");\n\tconst prompt = [\n\t\tterminationHeading(evidence.terminationReason),\n\t\t\"Do not continue investigating, call tools, modify files, or retry the original task.\",\n\t\t\"Return a concise summary of only verified findings and completed evidence already available.\",\n\t\t\"Explicitly label unfinished or unverified areas.\",\n\t\t`Original task:\\n${redactPrivateText(evidence.task)}`,\n\t\tevidence.partialOutput\n\t\t\t? `Partial assistant output:\\n${redactPrivateText(evidence.partialOutput)}`\n\t\t\t: \"Partial assistant output: (none)\",\n\t\tevidence.checkpoint\n\t\t\t? `Deterministic progress checkpoint:\\n${formatTimeoutCheckpoint(evidence.checkpoint)}`\n\t\t\t: undefined,\n\t\tactivity ? `Recent bounded activity:\\n${activity}` : \"Recent bounded activity: (none)\",\n\t]\n\t\t.filter((value): value is string => Boolean(value))\n\t\t.join(\"\\n\\n\");\n\treturn truncateUtf8(appendResultInstruction(prompt, evidence.resultFormat, maxBytes), maxBytes)\n\t\t.text;\n}\n\nfunction terminationHeading(reason: TurnTerminationReason | undefined): string {\n\tswitch (reason) {\n\t\tcase \"idle_timeout\":\n\t\t\treturn \"The idle deadline expired and the active work was aborted.\";\n\t\tcase \"turn_limit\":\n\t\t\treturn \"The assistant-turn budget was exhausted and the active work was aborted.\";\n\t\tcase \"tool_call_limit\":\n\t\t\treturn \"The tool-call budget was exhausted and the active work was aborted.\";\n\t\tcase \"orchestration_timeout\":\n\t\t\treturn \"The orchestration deadline expired and the active work was aborted.\";\n\t\tdefault:\n\t\t\treturn \"Work deadline expired and the active work was aborted.\";\n\t}\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;AAUO,IAAM,kCAAkC;AAWxC,SAAS,6BAA6B,eAAuB,UAA2B;AAC9F,QAAM,YAAY,YAAY,KAAK,IAAI,eAAe,+BAA+B;AACrF,MAAI,CAAC,OAAO,SAAS,SAAS,KAAK,YAAY,GAAG;AACjD,UAAM,IAAI,MAAM,gEAAgE;AAAA,EACjF;AACA,SAAO,KAAK,IAAI,KAAK,MAAM,SAAS,GAAG,+BAA+B;AACvE;AAEO,SAAS,+BACf,UACA,WAAW,2BACF;AACT,QAAM,YAAY,SAAS,kBAAkB,CAAC,GAC5C,MAAM,GAAG,EACT;AAAA,IAAI,CAAC,SACL,KAAK,SAAS,SACX,qBAAqB,kBAAkB,KAAK,IAAI,CAAC,KACjD,oBAAoB,kBAAkB,KAAK,IAAI,CAAC;AAAA,EACpD,EACC,KAAK,IAAI;AACX,QAAM,SAAS;AAAA,IACd,mBAAmB,SAAS,iBAAiB;AAAA,IAC7C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAmB,kBAAkB,SAAS,IAAI,CAAC;AAAA,IACnD,SAAS,gBACN;AAAA,EAA8B,kBAAkB,SAAS,aAAa,CAAC,KACvE;AAAA,IACH,SAAS,aACN;AAAA,EAAuC,wBAAwB,SAAS,UAAU,CAAC,KACnF;AAAA,IACH,WAAW;AAAA,EAA6B,QAAQ,KAAK;AAAA,EACtD,EACE,OAAO,CAAC,UAA2B,QAAQ,KAAK,CAAC,EACjD,KAAK,MAAM;AACb,SAAO,aAAa,wBAAwB,QAAQ,SAAS,cAAc,QAAQ,GAAG,QAAQ,EAC5F;AACH;AAEA,SAAS,mBAAmB,QAAmD;AAC9E,UAAQ,QAAQ;AAAA,IACf,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR,KAAK;AACJ,aAAO;AAAA,IACR;AACC,aAAO;AAAA,EACT;AACD;",
6
+ "names": []
7
+ }