@zihanw/pi-forge 0.3.2 → 0.4.0-beta.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 (244) hide show
  1. package/CHANGELOG.md +160 -0
  2. package/PUBLIC_API.md +28 -0
  3. package/README.md +137 -11
  4. package/README.zh-CN.md +137 -11
  5. package/SUBAGENT_ADAPTER_CONTRACT.md +199 -0
  6. package/dist/agent-profile.d.ts +71 -0
  7. package/dist/agent-profile.d.ts.map +1 -0
  8. package/dist/agent-profile.js +303 -0
  9. package/dist/agent-profile.js.map +1 -0
  10. package/dist/forge-config.d.ts +8 -0
  11. package/dist/forge-config.d.ts.map +1 -0
  12. package/dist/forge-config.js +40 -0
  13. package/dist/forge-config.js.map +1 -0
  14. package/dist/forge-extensions.d.ts.map +1 -1
  15. package/dist/forge-extensions.js +19 -3
  16. package/dist/forge-extensions.js.map +1 -1
  17. package/dist/index.d.ts +7 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +75 -361
  20. package/dist/index.js.map +1 -1
  21. package/dist/lifecycle.d.ts +11 -3
  22. package/dist/lifecycle.d.ts.map +1 -1
  23. package/dist/lifecycle.js +90 -4
  24. package/dist/lifecycle.js.map +1 -1
  25. package/dist/loader.d.ts.map +1 -1
  26. package/dist/loader.js +116 -5
  27. package/dist/loader.js.map +1 -1
  28. package/dist/payload-capture.d.ts.map +1 -1
  29. package/dist/payload-capture.js +27 -0
  30. package/dist/payload-capture.js.map +1 -1
  31. package/dist/payload-command.d.ts +3 -3
  32. package/dist/payload-command.d.ts.map +1 -1
  33. package/dist/payload-command.js.map +1 -1
  34. package/dist/preview.d.ts +2 -2
  35. package/dist/preview.d.ts.map +1 -1
  36. package/dist/preview.js +2 -3
  37. package/dist/preview.js.map +1 -1
  38. package/dist/profile-command.d.ts +12 -0
  39. package/dist/profile-command.d.ts.map +1 -0
  40. package/dist/profile-command.js +291 -0
  41. package/dist/profile-command.js.map +1 -0
  42. package/dist/profile-service.d.ts +103 -0
  43. package/dist/profile-service.d.ts.map +1 -0
  44. package/dist/profile-service.js +215 -0
  45. package/dist/profile-service.js.map +1 -0
  46. package/dist/runtime/profile-runtime.d.ts +13 -0
  47. package/dist/runtime/profile-runtime.d.ts.map +1 -0
  48. package/dist/runtime/profile-runtime.js +47 -0
  49. package/dist/runtime/profile-runtime.js.map +1 -0
  50. package/dist/runtime/prompt-stack-runtime.d.ts +22 -0
  51. package/dist/runtime/prompt-stack-runtime.d.ts.map +1 -0
  52. package/dist/runtime/prompt-stack-runtime.js +104 -0
  53. package/dist/runtime/prompt-stack-runtime.js.map +1 -0
  54. package/dist/runtime/subagent-runtime.d.ts +30 -0
  55. package/dist/runtime/subagent-runtime.d.ts.map +1 -0
  56. package/dist/runtime/subagent-runtime.js +114 -0
  57. package/dist/runtime/subagent-runtime.js.map +1 -0
  58. package/dist/runtime/tool-policy-runtime.d.ts +15 -0
  59. package/dist/runtime/tool-policy-runtime.d.ts.map +1 -0
  60. package/dist/runtime/tool-policy-runtime.js +170 -0
  61. package/dist/runtime/tool-policy-runtime.js.map +1 -0
  62. package/dist/runtime/web-editor-runtime.d.ts +9 -0
  63. package/dist/runtime/web-editor-runtime.d.ts.map +1 -0
  64. package/dist/runtime/web-editor-runtime.js +131 -0
  65. package/dist/runtime/web-editor-runtime.js.map +1 -0
  66. package/dist/runtime-state.d.ts +4 -0
  67. package/dist/runtime-state.d.ts.map +1 -1
  68. package/dist/runtime-state.js +2 -0
  69. package/dist/runtime-state.js.map +1 -1
  70. package/dist/storage.d.ts +3 -0
  71. package/dist/storage.d.ts.map +1 -1
  72. package/dist/storage.js +9 -0
  73. package/dist/storage.js.map +1 -1
  74. package/dist/subagent/backend-registry.d.ts +75 -0
  75. package/dist/subagent/backend-registry.d.ts.map +1 -0
  76. package/dist/subagent/backend-registry.js +463 -0
  77. package/dist/subagent/backend-registry.js.map +1 -0
  78. package/dist/subagent/canonical.d.ts +10 -0
  79. package/dist/subagent/canonical.d.ts.map +1 -0
  80. package/dist/subagent/canonical.js +52 -0
  81. package/dist/subagent/canonical.js.map +1 -0
  82. package/dist/subagent/context.d.ts +8 -0
  83. package/dist/subagent/context.d.ts.map +1 -0
  84. package/dist/subagent/context.js +125 -0
  85. package/dist/subagent/context.js.map +1 -0
  86. package/dist/subagent/contract.d.ts +11 -0
  87. package/dist/subagent/contract.d.ts.map +1 -0
  88. package/dist/subagent/contract.js +11 -0
  89. package/dist/subagent/contract.js.map +1 -0
  90. package/dist/subagent/diagnostics.d.ts +3 -0
  91. package/dist/subagent/diagnostics.d.ts.map +1 -0
  92. package/dist/subagent/diagnostics.js +5 -0
  93. package/dist/subagent/diagnostics.js.map +1 -0
  94. package/dist/subagent/index.d.ts +13 -0
  95. package/dist/subagent/index.d.ts.map +1 -0
  96. package/dist/subagent/index.js +13 -0
  97. package/dist/subagent/index.js.map +1 -0
  98. package/dist/subagent/pi-model-runtime.d.ts +8 -0
  99. package/dist/subagent/pi-model-runtime.d.ts.map +1 -0
  100. package/dist/subagent/pi-model-runtime.js +22 -0
  101. package/dist/subagent/pi-model-runtime.js.map +1 -0
  102. package/dist/subagent/pi-sdk-backend.d.ts +23 -0
  103. package/dist/subagent/pi-sdk-backend.d.ts.map +1 -0
  104. package/dist/subagent/pi-sdk-backend.js +383 -0
  105. package/dist/subagent/pi-sdk-backend.js.map +1 -0
  106. package/dist/subagent/pi-subprocess-backend.d.ts +72 -0
  107. package/dist/subagent/pi-subprocess-backend.d.ts.map +1 -0
  108. package/dist/subagent/pi-subprocess-backend.js +756 -0
  109. package/dist/subagent/pi-subprocess-backend.js.map +1 -0
  110. package/dist/subagent/plan.d.ts +14 -0
  111. package/dist/subagent/plan.d.ts.map +1 -0
  112. package/dist/subagent/plan.js +160 -0
  113. package/dist/subagent/plan.js.map +1 -0
  114. package/dist/subagent/preflight.d.ts +4 -0
  115. package/dist/subagent/preflight.d.ts.map +1 -0
  116. package/dist/subagent/preflight.js +108 -0
  117. package/dist/subagent/preflight.js.map +1 -0
  118. package/dist/subagent/request.d.ts +4 -0
  119. package/dist/subagent/request.d.ts.map +1 -0
  120. package/dist/subagent/request.js +122 -0
  121. package/dist/subagent/request.js.map +1 -0
  122. package/dist/subagent/response.d.ts +8 -0
  123. package/dist/subagent/response.d.ts.map +1 -0
  124. package/dist/subagent/response.js +155 -0
  125. package/dist/subagent/response.js.map +1 -0
  126. package/dist/subagent/subprocess-bridge.d.ts +21 -0
  127. package/dist/subagent/subprocess-bridge.d.ts.map +1 -0
  128. package/dist/subagent/subprocess-bridge.js +87 -0
  129. package/dist/subagent/subprocess-bridge.js.map +1 -0
  130. package/dist/subagent/subprocess-report.d.ts +4 -0
  131. package/dist/subagent/subprocess-report.d.ts.map +1 -0
  132. package/dist/subagent/subprocess-report.js +55 -0
  133. package/dist/subagent/subprocess-report.js.map +1 -0
  134. package/dist/subagent/tools.d.ts +4 -0
  135. package/dist/subagent/tools.d.ts.map +1 -0
  136. package/dist/subagent/tools.js +42 -0
  137. package/dist/subagent/tools.js.map +1 -0
  138. package/dist/subagent/types.d.ts +384 -0
  139. package/dist/subagent/types.d.ts.map +1 -0
  140. package/dist/subagent/types.js +3 -0
  141. package/dist/subagent/types.js.map +1 -0
  142. package/dist/subagent/validation.d.ts +35 -0
  143. package/dist/subagent/validation.d.ts.map +1 -0
  144. package/dist/subagent/validation.js +500 -0
  145. package/dist/subagent/validation.js.map +1 -0
  146. package/dist/subagent-command.d.ts +4 -0
  147. package/dist/subagent-command.d.ts.map +1 -0
  148. package/dist/subagent-command.js +153 -0
  149. package/dist/subagent-command.js.map +1 -0
  150. package/dist/subagent-contract.d.ts +8 -0
  151. package/dist/subagent-contract.d.ts.map +1 -0
  152. package/dist/subagent-contract.js +8 -0
  153. package/dist/subagent-contract.js.map +1 -0
  154. package/dist/subagent-host.d.ts +44 -0
  155. package/dist/subagent-host.d.ts.map +1 -0
  156. package/dist/subagent-host.js +291 -0
  157. package/dist/subagent-host.js.map +1 -0
  158. package/dist/subagent-profile-tool.d.ts +26 -0
  159. package/dist/subagent-profile-tool.d.ts.map +1 -0
  160. package/dist/subagent-profile-tool.js +93 -0
  161. package/dist/subagent-profile-tool.js.map +1 -0
  162. package/dist/subagent-tool.d.ts +50 -0
  163. package/dist/subagent-tool.d.ts.map +1 -0
  164. package/dist/subagent-tool.js +385 -0
  165. package/dist/subagent-tool.js.map +1 -0
  166. package/dist/web-editor/client/api.d.ts +9 -0
  167. package/dist/web-editor/client/api.d.ts.map +1 -0
  168. package/dist/web-editor/client/api.js +26 -0
  169. package/dist/web-editor/client/api.js.map +1 -0
  170. package/dist/web-editor/client/dom.d.ts +13 -0
  171. package/dist/web-editor/client/dom.d.ts.map +1 -0
  172. package/dist/web-editor/client/dom.js +30 -0
  173. package/dist/web-editor/client/dom.js.map +1 -0
  174. package/dist/web-editor/client/inspector.d.ts +22 -0
  175. package/dist/web-editor/client/inspector.d.ts.map +1 -0
  176. package/dist/web-editor/client/inspector.js +226 -0
  177. package/dist/web-editor/client/inspector.js.map +1 -0
  178. package/dist/web-editor/client/main.d.ts +2 -0
  179. package/dist/web-editor/client/main.d.ts.map +1 -0
  180. package/dist/web-editor/client/main.js +1468 -0
  181. package/dist/web-editor/client/main.js.map +1 -0
  182. package/dist/web-editor/client/policy-editor.d.ts +16 -0
  183. package/dist/web-editor/client/policy-editor.d.ts.map +1 -0
  184. package/dist/web-editor/client/policy-editor.js +330 -0
  185. package/dist/web-editor/client/policy-editor.js.map +1 -0
  186. package/dist/web-editor/client/regex-editor.d.ts +19 -0
  187. package/dist/web-editor/client/regex-editor.d.ts.map +1 -0
  188. package/dist/web-editor/client/regex-editor.js +281 -0
  189. package/dist/web-editor/client/regex-editor.js.map +1 -0
  190. package/dist/web-editor/client/types.d.ts +60 -0
  191. package/dist/web-editor/client/types.d.ts.map +1 -0
  192. package/dist/web-editor/client/types.js +2 -0
  193. package/dist/web-editor/client/types.js.map +1 -0
  194. package/dist/web-editor/client-script.d.ts +2 -0
  195. package/dist/web-editor/client-script.d.ts.map +1 -0
  196. package/dist/web-editor/client-script.generated.d.ts +2 -0
  197. package/dist/web-editor/client-script.generated.d.ts.map +1 -0
  198. package/dist/web-editor/client-script.generated.js +3 -0
  199. package/dist/web-editor/client-script.generated.js.map +1 -0
  200. package/dist/web-editor/client-script.js +2 -0
  201. package/dist/web-editor/client-script.js.map +1 -0
  202. package/dist/web-editor/page.d.ts.map +1 -1
  203. package/dist/web-editor/page.js +6 -3249
  204. package/dist/web-editor/page.js.map +1 -1
  205. package/dist/web-editor/styles.d.ts +2 -0
  206. package/dist/web-editor/styles.d.ts.map +1 -0
  207. package/dist/web-editor/styles.js +996 -0
  208. package/dist/web-editor/styles.js.map +1 -0
  209. package/dist/web-host.d.ts +3 -3
  210. package/dist/web-host.d.ts.map +1 -1
  211. package/dist/web-host.js +6 -0
  212. package/dist/web-host.js.map +1 -1
  213. package/package.json +42 -14
  214. package/src/compiler.ts +0 -578
  215. package/src/extension-registry.ts +0 -33
  216. package/src/forge-extensions.ts +0 -223
  217. package/src/index.ts +0 -445
  218. package/src/lifecycle.ts +0 -171
  219. package/src/loader.ts +0 -394
  220. package/src/macro-engine.ts +0 -358
  221. package/src/payload-capture.ts +0 -85
  222. package/src/payload-command.ts +0 -138
  223. package/src/policy.ts +0 -42
  224. package/src/preset-command.ts +0 -280
  225. package/src/preview.ts +0 -226
  226. package/src/regex.ts +0 -500
  227. package/src/render-helpers.ts +0 -169
  228. package/src/runtime-state.ts +0 -40
  229. package/src/sillytavern-importer/items.ts +0 -98
  230. package/src/sillytavern-importer/macros.ts +0 -159
  231. package/src/sillytavern-importer/prompt-order.ts +0 -54
  232. package/src/sillytavern-importer/regex.ts +0 -270
  233. package/src/sillytavern-importer/report.ts +0 -202
  234. package/src/sillytavern-importer/types.ts +0 -120
  235. package/src/sillytavern-importer.ts +0 -152
  236. package/src/slot-renderers.ts +0 -414
  237. package/src/stack-migration.ts +0 -159
  238. package/src/storage.ts +0 -45
  239. package/src/types.ts +0 -209
  240. package/src/web-editor/index.ts +0 -2
  241. package/src/web-editor/page.ts +0 -3330
  242. package/src/web-editor/server.ts +0 -294
  243. package/src/web-editor/types.ts +0 -98
  244. package/src/web-host.ts +0 -232
@@ -0,0 +1,155 @@
1
+ import { canonicalSubagentJson } from "./canonical.js";
2
+ import { SUBAGENT_CONTRACT_VERSION } from "./types.js";
3
+ import { SUBAGENT_LIMIT_NAMES, error, isIsoDate, isNonNegativeFinite, isPositiveInteger, isRecord, isSafeRelativePath, validateAccessReceipt, validateFingerprint, validateLimitReceipt, validateModelReference, validateNamespace, validateOpaqueId, validateUniqueStringArray, validateUsage } from "./validation.js";
4
+ export function validateAgentResponse(response, context) {
5
+ const diagnostics = [];
6
+ if (!isRecord(response))
7
+ return [error("response.type", "AgentResponse must be an object.", "$")];
8
+ if (!SUBAGENT_RESPONSE_STATUSES.includes(response.status))
9
+ diagnostics.push(error("response.status", "Unsupported response status.", "status"));
10
+ if (response.schemaVersion !== SUBAGENT_CONTRACT_VERSION)
11
+ diagnostics.push(error("response.schema-version", "schemaVersion must be 1.", "schemaVersion"));
12
+ for (const id of ["requestId", "runId", "backendId"])
13
+ validateOpaqueId(response[id], id, diagnostics);
14
+ validateFingerprint(response.profileFingerprint, "profileFingerprint", diagnostics);
15
+ validateFingerprint(response.executionFingerprint, "executionFingerprint", diagnostics);
16
+ validateModelReference(response.model, "model", diagnostics);
17
+ if (!Array.isArray(response.effectiveToolIds))
18
+ diagnostics.push(error("response.tools", "effectiveToolIds must be a string array.", "effectiveToolIds"));
19
+ else
20
+ validateUniqueStringArray(response.effectiveToolIds, "effectiveToolIds", diagnostics);
21
+ if (!isNonNegativeFinite(response.durationMs))
22
+ diagnostics.push(error("response.duration", "durationMs must be a non-negative finite number.", "durationMs"));
23
+ if (!Array.isArray(response.artifacts))
24
+ diagnostics.push(error("response.artifacts", "artifacts must be an array.", "artifacts"));
25
+ else
26
+ response.artifacts.forEach((artifact, index) => diagnostics.push(...validateSubagentArtifactReference(artifact, `artifacts[${index}]`)));
27
+ if (response.trace !== undefined) {
28
+ diagnostics.push(...validateSubagentTraceReference(response.trace, "trace"));
29
+ if (isRecord(response.trace) && response.trace.backendId !== response.backendId)
30
+ diagnostics.push(error("response.trace-backend", "Trace backendId must match response backendId.", "trace.backendId"));
31
+ }
32
+ if (response.usage !== undefined)
33
+ validateUsage(response.usage, "usage", diagnostics);
34
+ if (!isRecord(response.enforcement))
35
+ diagnostics.push(error("response.enforcement", "enforcement must be an object.", "enforcement"));
36
+ else {
37
+ validateAccessReceipt(response.enforcement.access, "enforcement.access", diagnostics);
38
+ validateLimitReceipt(response.enforcement.limits, "enforcement.limits", diagnostics);
39
+ }
40
+ validateResponseStatusMatrix(response, diagnostics);
41
+ if (context?.request && response.requestId !== context.request.requestId)
42
+ diagnostics.push(error("response.request-id", "requestId does not match the request.", "requestId"));
43
+ if (context?.plan) {
44
+ if (response.requestId !== context.plan.requestId)
45
+ diagnostics.push(error("response.request-plan-id", "requestId does not match the execution plan.", "requestId"));
46
+ if (response.runId !== context.plan.runId)
47
+ diagnostics.push(error("response.run-id", "runId does not match the execution plan.", "runId"));
48
+ if (response.backendId !== context.plan.backendId)
49
+ diagnostics.push(error("response.backend-id", "backendId does not match the execution plan.", "backendId"));
50
+ if (response.executionFingerprint !== context.plan.executionFingerprint)
51
+ diagnostics.push(error("response.execution-fingerprint", "executionFingerprint does not match the execution plan.", "executionFingerprint"));
52
+ if (response.profileFingerprint !== context.plan.profile.profileFingerprint)
53
+ diagnostics.push(error("response.profile-fingerprint", "profileFingerprint does not match the execution plan.", "profileFingerprint"));
54
+ if (response.status === "timed-out" && response.enforcedTimeoutMs !== context.plan.limits.timeoutMs?.value)
55
+ diagnostics.push(error("response.timeout-receipt", "enforcedTimeoutMs does not match the execution plan timeout receipt.", "enforcedTimeoutMs"));
56
+ if (response.status === "limit-reached" && !context.plan.limits[response.reachedLimit])
57
+ diagnostics.push(error("response.limit-receipt-missing", "reachedLimit has no enforcement receipt in the execution plan.", "reachedLimit"));
58
+ if (response.trace !== undefined && !context.plan.preflight.backend.capabilities.traceInspection)
59
+ diagnostics.push(error("response.trace-capability", "Backend returned a trace without advertising traceInspection.", "trace"));
60
+ if (Array.isArray(response.artifacts) && response.artifacts.length > 0 && !context.plan.preflight.backend.capabilities.artifactRetention)
61
+ diagnostics.push(error("response.artifact-capability", "Backend returned artifacts without advertising artifactRetention.", "artifacts"));
62
+ try {
63
+ if (canonicalSubagentJson(response.model) !== canonicalSubagentJson(context.plan.model))
64
+ diagnostics.push(error("response.model-mismatch", "Response model does not match the execution plan.", "model"));
65
+ if (Array.isArray(response.effectiveToolIds) && canonicalSubagentJson(response.effectiveToolIds) !== canonicalSubagentJson(context.plan.effectiveToolIds))
66
+ diagnostics.push(error("response.tools-mismatch", "effectiveToolIds do not match the execution plan.", "effectiveToolIds"));
67
+ if (isRecord(response.enforcement)) {
68
+ if (canonicalSubagentJson(response.enforcement.access) !== canonicalSubagentJson(context.plan.access))
69
+ diagnostics.push(error("response.access-receipt", "Access enforcement receipt does not match the execution plan.", "enforcement.access"));
70
+ if (canonicalSubagentJson(response.enforcement.limits) !== canonicalSubagentJson(context.plan.limits))
71
+ diagnostics.push(error("response.limit-receipt", "Limit enforcement receipt does not match the execution plan.", "enforcement.limits"));
72
+ }
73
+ }
74
+ catch (validationError) {
75
+ diagnostics.push(error("response.malformed", `Cannot compare malformed response with plan: ${validationError instanceof Error ? validationError.message : String(validationError)}`, "$"));
76
+ }
77
+ }
78
+ return diagnostics;
79
+ }
80
+ export function validateSubagentArtifactReference(value, path = "artifact") {
81
+ const diagnostics = [];
82
+ if (!isRecord(value))
83
+ return [error("artifact.type", "Artifact reference must be an object.", path)];
84
+ validateOpaqueId(value.id, `${path}.id`, diagnostics);
85
+ validateNamespace(value.workspaceNamespace, `${path}.workspaceNamespace`, diagnostics);
86
+ if (!isSafeRelativePath(value.path))
87
+ diagnostics.push(error("artifact.path", "Artifact path must be a normalized relative POSIX path without dot segments.", `${path}.path`));
88
+ if (value.authorization !== "read" && value.authorization !== "write")
89
+ diagnostics.push(error("artifact.authorization", "authorization must be read or write.", `${path}.authorization`));
90
+ if (!SUBAGENT_ARTIFACT_LIFETIMES.includes(value.lifetime))
91
+ diagnostics.push(error("artifact.lifetime", "Unsupported artifact lifetime.", `${path}.lifetime`));
92
+ if (!SUBAGENT_ARTIFACT_CLEANUP.includes(value.cleanup))
93
+ diagnostics.push(error("artifact.cleanup", "Unsupported artifact cleanup owner.", `${path}.cleanup`));
94
+ return diagnostics;
95
+ }
96
+ export function validateSubagentTraceReference(value, path = "trace") {
97
+ const diagnostics = [];
98
+ if (!isRecord(value))
99
+ return [error("trace.type", "Trace reference must be an object.", path)];
100
+ validateOpaqueId(value.handle, `${path}.handle`, diagnostics);
101
+ validateOpaqueId(value.backendId, `${path}.backendId`, diagnostics);
102
+ validateNamespace(value.authorizationScope, `${path}.authorizationScope`, diagnostics);
103
+ if (value.expiresAt !== undefined && !isIsoDate(value.expiresAt))
104
+ diagnostics.push(error("trace.expiry", "expiresAt must be an ISO date-time string.", `${path}.expiresAt`));
105
+ return diagnostics;
106
+ }
107
+ const SUBAGENT_RESPONSE_STATUSES = ["completed", "failed", "cancelled", "timed-out", "limit-reached"];
108
+ const SUBAGENT_ARTIFACT_LIFETIMES = ["run", "session", "persistent"];
109
+ const SUBAGENT_ARTIFACT_CLEANUP = ["backend", "host", "user"];
110
+ function validateResponseStatusMatrix(response, diagnostics) {
111
+ const output = response.output;
112
+ if (output !== undefined) {
113
+ if (!isRecord(output) || typeof output.text !== "string" || typeof output.partial !== "boolean")
114
+ diagnostics.push(error("response.output", "output must contain text and partial.", "output"));
115
+ }
116
+ if (response.status === "completed") {
117
+ if (response.error !== undefined || response.reason !== undefined || response.reachedLimit !== undefined || response.enforcedTimeoutMs !== undefined)
118
+ diagnostics.push(error("response.completed-fields", "Completed responses cannot contain terminal error/reason/limit fields.", "status"));
119
+ if (isRecord(output) && output.partial !== false)
120
+ diagnostics.push(error("response.completed-partial", "Completed output cannot be partial.", "output.partial"));
121
+ }
122
+ else {
123
+ if (isRecord(output) && output.partial !== true)
124
+ diagnostics.push(error("response.partial", "Non-completed output must be marked partial.", "output.partial"));
125
+ if (response.status === "failed") {
126
+ if (!isRecord(response.error) || typeof response.error.code !== "string" || typeof response.error.message !== "string")
127
+ diagnostics.push(error("response.failed-error", "Failed responses require a structured error.", "error"));
128
+ forbidResponseFields(response, ["reason", "reachedLimit", "enforcedTimeoutMs"], diagnostics);
129
+ }
130
+ if (response.status === "cancelled") {
131
+ if (typeof response.reason !== "string" || !response.reason.trim())
132
+ diagnostics.push(error("response.reason", "cancelled responses require a reason.", "reason"));
133
+ forbidResponseFields(response, ["error", "reachedLimit", "enforcedTimeoutMs"], diagnostics);
134
+ }
135
+ if (response.status === "timed-out") {
136
+ if (typeof response.reason !== "string" || !response.reason.trim())
137
+ diagnostics.push(error("response.reason", "timed-out responses require a reason.", "reason"));
138
+ if (!isPositiveInteger(response.enforcedTimeoutMs))
139
+ diagnostics.push(error("response.timeout", "Timed-out responses require enforcedTimeoutMs.", "enforcedTimeoutMs"));
140
+ forbidResponseFields(response, ["error", "reachedLimit"], diagnostics);
141
+ }
142
+ if (response.status === "limit-reached") {
143
+ if (!SUBAGENT_LIMIT_NAMES.includes(response.reachedLimit))
144
+ diagnostics.push(error("response.reached-limit", "limit-reached responses require a valid reachedLimit.", "reachedLimit"));
145
+ forbidResponseFields(response, ["error", "reason", "enforcedTimeoutMs"], diagnostics);
146
+ }
147
+ }
148
+ }
149
+ function forbidResponseFields(response, fields, diagnostics) {
150
+ for (const field of fields) {
151
+ if (response[field] !== undefined)
152
+ diagnostics.push(error("response.forbidden-field", `${response.status} response cannot contain ${field}.`, field));
153
+ }
154
+ }
155
+ //# sourceMappingURL=response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/subagent/response.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+ import type { BackendPreflightAccepted, SubagentPreparedMessage } from "./contract.ts";
3
+ export declare const PI_FORGE_SUBPROCESS_INPUT_ENV = "PI_FORGE_SUBAGENT_BRIDGE_INPUT";
4
+ export interface SubprocessBridgeInput {
5
+ marker: string;
6
+ systemPrompt: string;
7
+ messages: SubagentPreparedMessage[];
8
+ model: BackendPreflightAccepted["model"];
9
+ effectiveToolNames: string[];
10
+ }
11
+ export interface SubprocessBridgeReportEvent {
12
+ type: "message_end";
13
+ message: unknown;
14
+ }
15
+ export interface SubprocessBridgeOptions {
16
+ report?: (event: SubprocessBridgeReportEvent) => void;
17
+ }
18
+ export declare function loadSubprocessBridgeInput(path?: string | undefined): SubprocessBridgeInput;
19
+ export declare function createSubprocessBridge(input: SubprocessBridgeInput, options?: SubprocessBridgeOptions): (pi: ExtensionAPI) => void;
20
+ export default function subprocessBridge(pi: ExtensionAPI): void;
21
+ //# sourceMappingURL=subprocess-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subprocess-bridge.d.ts","sourceRoot":"","sources":["../../src/subagent/subprocess-bridge.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,KAAK,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAMvF,eAAO,MAAM,6BAA6B,mCAAmC,CAAC;AAE9E,MAAM,WAAW,qBAAqB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,uBAAuB,EAAE,CAAC;IACpC,KAAK,EAAE,wBAAwB,CAAC,OAAO,CAAC,CAAC;IACzC,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,2BAA2B;IAC3C,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACvC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,2BAA2B,KAAK,IAAI,CAAC;CACtD;AAED,wBAAgB,yBAAyB,CAAC,IAAI,qBAA6C,GAAG,qBAAqB,CASlH;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,qBAAqB,EAAE,OAAO,GAAE,uBAA4B,IACjG,IAAI,YAAY,KAAG,IAAI,CA4B/B;AAoCD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAE/D"}
@@ -0,0 +1,87 @@
1
+ import { readFileSync, writeSync } from "node:fs";
2
+ import { PI_FORGE_SUBPROCESS_REPORT_FD_ENV, sanitizeSubprocessReportValue, } from "./subprocess-report.js";
3
+ export const PI_FORGE_SUBPROCESS_INPUT_ENV = "PI_FORGE_SUBAGENT_BRIDGE_INPUT";
4
+ export function loadSubprocessBridgeInput(path = process.env[PI_FORGE_SUBPROCESS_INPUT_ENV]) {
5
+ if (!path)
6
+ throw new Error(`Missing ${PI_FORGE_SUBPROCESS_INPUT_ENV}.`);
7
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
8
+ if (typeof parsed.marker !== "string" || !parsed.marker)
9
+ throw new Error("Subprocess bridge input is missing its marker.");
10
+ if (typeof parsed.systemPrompt !== "string")
11
+ throw new Error("Subprocess bridge input is missing its system prompt.");
12
+ if (!Array.isArray(parsed.messages) || parsed.messages.length === 0)
13
+ throw new Error("Subprocess bridge input has no prepared messages.");
14
+ if (!parsed.model || typeof parsed.model.provider !== "string" || typeof parsed.model.id !== "string")
15
+ throw new Error("Subprocess bridge input has no model receipt.");
16
+ if (!Array.isArray(parsed.effectiveToolNames) || parsed.effectiveToolNames.some((name) => typeof name !== "string"))
17
+ throw new Error("Subprocess bridge input has an invalid tool allowlist.");
18
+ return parsed;
19
+ }
20
+ export function createSubprocessBridge(input, options = {}) {
21
+ return (pi) => {
22
+ let markerObserved = false;
23
+ const report = options.report ?? writeSubprocessReportEvent;
24
+ pi.on("before_agent_start", () => ({ systemPrompt: input.systemPrompt }));
25
+ pi.on("context", (event) => {
26
+ const markerIndex = event.messages.findIndex((message) => isMarkerMessage(message, input.marker));
27
+ if (markerIndex === -1) {
28
+ if (!markerObserved)
29
+ throw new Error("Pi Forge subprocess marker was absent before the first provider request.");
30
+ return;
31
+ }
32
+ markerObserved = true;
33
+ return {
34
+ messages: [
35
+ ...event.messages.slice(0, markerIndex),
36
+ ...input.messages.map((message, index) => preparedMessageToAgentMessage(message, input.model, index)),
37
+ ...event.messages.slice(markerIndex + 1),
38
+ ],
39
+ };
40
+ });
41
+ pi.on("tool_call", (event) => {
42
+ if (!input.effectiveToolNames.includes(event.toolName)) {
43
+ return { block: true, reason: `Tool ${event.toolName} is outside the approved Pi Forge subprocess allowlist.` };
44
+ }
45
+ });
46
+ pi.on("message_end", (event) => {
47
+ report({ type: "message_end", message: sanitizeSubprocessReportValue(event.message) });
48
+ });
49
+ };
50
+ }
51
+ function writeSubprocessReportEvent(event) {
52
+ const rawFd = process.env[PI_FORGE_SUBPROCESS_REPORT_FD_ENV];
53
+ const fd = rawFd ? Number(rawFd) : Number.NaN;
54
+ if (!Number.isSafeInteger(fd) || fd < 3)
55
+ throw new Error(`Missing or invalid ${PI_FORGE_SUBPROCESS_REPORT_FD_ENV}.`);
56
+ writeSync(fd, `${JSON.stringify(event)}\n`, undefined, "utf8");
57
+ }
58
+ function isMarkerMessage(message, marker) {
59
+ if (message.role !== "user")
60
+ return false;
61
+ if (typeof message.content === "string")
62
+ return message.content === marker;
63
+ return message.content.length === 1 && message.content[0]?.type === "text" && message.content[0].text === marker;
64
+ }
65
+ function preparedMessageToAgentMessage(message, model, index) {
66
+ if (message.content.some((part) => part.type === "media"))
67
+ throw new Error("Subprocess media preparation is not implemented.");
68
+ const content = message.content.map((part) => ({ type: "text", text: part.type === "text" ? part.text : "" }));
69
+ if (message.role === "user")
70
+ return { role: "user", content: content.length === 1 ? content[0].text : content, timestamp: index };
71
+ if (message.role === "custom")
72
+ return { role: "custom", customType: "pi-forge-subagent", content, display: false, details: {}, timestamp: index };
73
+ return {
74
+ role: "assistant",
75
+ content,
76
+ api: "unknown",
77
+ provider: model.provider,
78
+ model: model.id,
79
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },
80
+ stopReason: "stop",
81
+ timestamp: index,
82
+ };
83
+ }
84
+ export default function subprocessBridge(pi) {
85
+ createSubprocessBridge(loadSubprocessBridgeInput())(pi);
86
+ }
87
+ //# sourceMappingURL=subprocess-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subprocess-bridge.js","sourceRoot":"","sources":["../../src/subagent/subprocess-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare const PI_FORGE_SUBPROCESS_REPORT_FD_ENV = "PI_FORGE_SUBAGENT_REPORT_FD";
2
+ export declare const MAX_SUBPROCESS_REPORT_STRING_BYTES: number;
3
+ export declare function sanitizeSubprocessReportValue(value: unknown): unknown;
4
+ //# sourceMappingURL=subprocess-report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subprocess-report.d.ts","sourceRoot":"","sources":["../../src/subagent/subprocess-report.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iCAAiC,gCAAgC,CAAC;AAC/E,eAAO,MAAM,kCAAkC,QAAY,CAAC;AAI5D,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAarE"}
@@ -0,0 +1,55 @@
1
+ export const PI_FORGE_SUBPROCESS_REPORT_FD_ENV = "PI_FORGE_SUBAGENT_REPORT_FD";
2
+ export const MAX_SUBPROCESS_REPORT_STRING_BYTES = 64 * 1024;
3
+ const MIN_BASE64_REDACTION_BYTES = 4 * 1024;
4
+ export function sanitizeSubprocessReportValue(value) {
5
+ if (Array.isArray(value))
6
+ return value.map(sanitizeSubprocessReportValue);
7
+ if (typeof value === "string")
8
+ return sanitizeReportString(value);
9
+ if (!isRecord(value))
10
+ return value;
11
+ if (value.type === "image" && typeof value.data === "string") {
12
+ const { data, ...metadata } = value;
13
+ return {
14
+ ...Object.fromEntries(Object.entries(metadata).map(([key, item]) => [key, sanitizeSubprocessReportValue(item)])),
15
+ dataOmitted: true,
16
+ encodedBytes: Buffer.byteLength(data, "utf8"),
17
+ };
18
+ }
19
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, sanitizeSubprocessReportValue(item)]));
20
+ }
21
+ function sanitizeReportString(value) {
22
+ const bytes = Buffer.byteLength(value, "utf8");
23
+ if (looksLikeBase64Payload(value, bytes))
24
+ return `[Base64-like data omitted from retained subagent report: ${bytes} encoded bytes]`;
25
+ if (bytes <= MAX_SUBPROCESS_REPORT_STRING_BYTES)
26
+ return value;
27
+ const suffix = `\n[Text truncated in retained subagent report: ${bytes} original bytes]`;
28
+ return `${utf8Prefix(value, MAX_SUBPROCESS_REPORT_STRING_BYTES - Buffer.byteLength(suffix, "utf8"))}${suffix}`;
29
+ }
30
+ function looksLikeBase64Payload(value, bytes) {
31
+ if (bytes < MIN_BASE64_REDACTION_BYTES)
32
+ return false;
33
+ if (/^data:[^,;]+(?:;[^,]*)?;base64,/i.test(value))
34
+ return true;
35
+ const compact = value.replace(/\s/g, "");
36
+ return compact.length >= MIN_BASE64_REDACTION_BYTES
37
+ && compact.length / value.length >= 0.95
38
+ && /^[A-Za-z0-9+/_=-]+$/.test(compact);
39
+ }
40
+ function utf8Prefix(value, maxBytes) {
41
+ if (maxBytes <= 0)
42
+ return "";
43
+ const buffer = Buffer.from(value, "utf8");
44
+ if (buffer.length <= maxBytes)
45
+ return value;
46
+ let end = maxBytes;
47
+ let prefix = buffer.subarray(0, end).toString("utf8");
48
+ while (prefix.endsWith("\uFFFD") && end > 0)
49
+ prefix = buffer.subarray(0, --end).toString("utf8");
50
+ return prefix;
51
+ }
52
+ function isRecord(value) {
53
+ return !!value && typeof value === "object" && !Array.isArray(value);
54
+ }
55
+ //# sourceMappingURL=subprocess-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subprocess-report.js","sourceRoot":"","sources":["../../src/subagent/subprocess-report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { PromptResourcePolicy } from "../types.ts";
2
+ import type { SubagentAccessRequest, SubagentBackendTool, SubagentToolNegotiationResult } from "./types.ts";
3
+ export declare function negotiateSubagentTools(catalog: readonly SubagentBackendTool[], policy: PromptResourcePolicy | undefined, access: SubagentAccessRequest): SubagentToolNegotiationResult;
4
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/subagent/tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAsB,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAGhI,wBAAgB,sBAAsB,CACrC,OAAO,EAAE,SAAS,mBAAmB,EAAE,EACvC,MAAM,EAAE,oBAAoB,GAAG,SAAS,EACxC,MAAM,EAAE,qBAAqB,GAC3B,6BAA6B,CAyB/B"}
@@ -0,0 +1,42 @@
1
+ import { applyResourcePolicy, resourcePatternMatches } from "../policy.js";
2
+ import { validateToolCatalog } from "./validation.js";
3
+ export function negotiateSubagentTools(catalog, policy, access) {
4
+ const diagnostics = [];
5
+ validateToolCatalog(catalog, diagnostics);
6
+ const names = catalog.map((tool) => tool.name);
7
+ const stackSelectedToolNames = applyResourcePolicy(names, policy);
8
+ const selected = new Set(stackSelectedToolNames);
9
+ const effective = catalog.filter((tool) => selected.has(tool.name) && toolAllowedByAccess(tool, access));
10
+ const unmatchedAllowPatterns = policy && "allow" in policy
11
+ ? (policy.allow ?? []).filter((pattern) => pattern !== "*" && !names.some((name) => resourcePatternMatches(name, pattern)))
12
+ : [];
13
+ for (const pattern of unmatchedAllowPatterns) {
14
+ diagnostics.push({ level: "warning", code: "tools.unmatched-allow", path: "tools.allow", message: `Tool allow pattern matches no backend tools: ${pattern}` });
15
+ }
16
+ for (const tool of catalog) {
17
+ if (selected.has(tool.name) && !effective.includes(tool)) {
18
+ diagnostics.push({ level: "info", code: "tools.access-filtered", path: `tools.${tool.name}`, message: `Tool ${tool.name} was removed by request access policy.` });
19
+ }
20
+ }
21
+ return {
22
+ effectiveToolIds: effective.map((tool) => tool.id),
23
+ effectiveToolNames: effective.map((tool) => tool.name),
24
+ stackSelectedToolNames,
25
+ unmatchedAllowPatterns,
26
+ diagnostics,
27
+ };
28
+ }
29
+ function toolAllowedByAccess(tool, access) {
30
+ for (const effect of tool.effects) {
31
+ if (effect === "network" && access.network !== "allow")
32
+ return false;
33
+ if (effect === "process" && access.allowProcess !== true)
34
+ return false;
35
+ if (effect === "filesystem-read" && access.level === "none")
36
+ return false;
37
+ if (effect === "filesystem-write" && access.level !== "workspace-write")
38
+ return false;
39
+ }
40
+ return true;
41
+ }
42
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/subagent/tools.ts"],"names":[],"mappings":"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"}