@opengeni/contracts 0.44.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (382) hide show
  1. package/dist/agent-authored-durable-text.d.ts +70 -0
  2. package/dist/agent-config.d.ts +869 -0
  3. package/dist/agent-instruction-changes.d.ts +110 -0
  4. package/dist/agent-learning.d.ts +243 -0
  5. package/dist/agent-topology.d.ts +292 -0
  6. package/dist/allowance-refusal.d.ts +9 -0
  7. package/dist/allowance-refusal.js +50 -0
  8. package/dist/allowance-refusal.js.map +1 -0
  9. package/dist/analytics-consent-report.d.ts +19 -0
  10. package/dist/analytics-consent-report.js +10 -0
  11. package/dist/analytics-consent-report.js.map +1 -0
  12. package/dist/api-key-presets.d.ts +19 -0
  13. package/dist/artifact-catalog.d.ts +161 -0
  14. package/dist/artifacts.d.ts +135 -11
  15. package/dist/atlassian-native-retirement.d.ts +16 -0
  16. package/dist/atlassian-native-retirement.js +30 -0
  17. package/dist/atlassian-native-retirement.js.map +1 -0
  18. package/dist/atlassian.d.ts +2 -0
  19. package/dist/atlassian.js +27 -11
  20. package/dist/browser-storage.d.ts +5 -0
  21. package/dist/browser-storage.js +9 -0
  22. package/dist/browser-storage.js.map +1 -0
  23. package/dist/bundled-skills.d.ts +40 -0
  24. package/dist/canonical-human-identities.d.ts +157 -0
  25. package/dist/canonical-human-identities.js +23 -0
  26. package/dist/canonical-human-identities.js.map +1 -0
  27. package/dist/chunk-2ACYHZFB.js +292 -0
  28. package/dist/chunk-2ACYHZFB.js.map +1 -0
  29. package/dist/chunk-2VORLN2R.js +353 -0
  30. package/dist/chunk-2VORLN2R.js.map +1 -0
  31. package/dist/{chunk-Y3MLSLB4.js → chunk-3SIZGL3O.js} +42 -30
  32. package/dist/chunk-3SIZGL3O.js.map +1 -0
  33. package/dist/chunk-46KLD2UH.js +186 -0
  34. package/dist/chunk-46KLD2UH.js.map +1 -0
  35. package/dist/chunk-4JGHSSB7.js +11 -0
  36. package/dist/chunk-4JGHSSB7.js.map +1 -0
  37. package/dist/{chunk-52SGB2QO.js → chunk-5IXYF6XN.js} +50 -10
  38. package/dist/chunk-5IXYF6XN.js.map +1 -0
  39. package/dist/chunk-BCS7WHCK.js +139 -0
  40. package/dist/chunk-BCS7WHCK.js.map +1 -0
  41. package/dist/chunk-EK7NDGFR.js +128 -0
  42. package/dist/chunk-EK7NDGFR.js.map +1 -0
  43. package/dist/{chunk-5UDNP7AO.js → chunk-FZ6BXQHL.js} +78 -38
  44. package/dist/chunk-FZ6BXQHL.js.map +1 -0
  45. package/dist/chunk-GRG7PHWQ.js +25 -0
  46. package/dist/chunk-GRG7PHWQ.js.map +1 -0
  47. package/dist/chunk-JUFK3T4Q.js +80 -0
  48. package/dist/chunk-JUFK3T4Q.js.map +1 -0
  49. package/dist/chunk-KHHZTBP7.js +11 -0
  50. package/dist/chunk-KHHZTBP7.js.map +1 -0
  51. package/dist/chunk-KR2V42UZ.js +187 -0
  52. package/dist/chunk-KR2V42UZ.js.map +1 -0
  53. package/dist/chunk-MZLBPKFE.js +168 -0
  54. package/dist/chunk-MZLBPKFE.js.map +1 -0
  55. package/dist/{chunk-H5BVCZKF.js → chunk-NRMCVHAU.js} +6 -5
  56. package/dist/chunk-NRMCVHAU.js.map +1 -0
  57. package/dist/{chunk-TZ6YEYN4.js → chunk-NVJMJWLL.js} +3 -1
  58. package/dist/chunk-NVJMJWLL.js.map +1 -0
  59. package/dist/chunk-O77VSFYZ.js +70 -0
  60. package/dist/chunk-O77VSFYZ.js.map +1 -0
  61. package/dist/chunk-PX3VCKAU.js +29 -0
  62. package/dist/chunk-PX3VCKAU.js.map +1 -0
  63. package/dist/chunk-QR5D2IQC.js +61 -0
  64. package/dist/chunk-QR5D2IQC.js.map +1 -0
  65. package/dist/chunk-RJ76DRPO.js +117 -0
  66. package/dist/chunk-RJ76DRPO.js.map +1 -0
  67. package/dist/chunk-RKX3NQYS.js +28 -0
  68. package/dist/chunk-RKX3NQYS.js.map +1 -0
  69. package/dist/{chunk-FJBG5E4O.js → chunk-SIOU2K4U.js} +45 -22
  70. package/dist/chunk-SIOU2K4U.js.map +1 -0
  71. package/dist/chunk-TSCDAGET.js +75 -0
  72. package/dist/chunk-TSCDAGET.js.map +1 -0
  73. package/dist/{chunk-LSB7GRLG.js → chunk-TXTQIYCV.js} +15 -11
  74. package/dist/chunk-TXTQIYCV.js.map +1 -0
  75. package/dist/chunk-X7ETVO4P.js +26544 -0
  76. package/dist/chunk-X7ETVO4P.js.map +1 -0
  77. package/dist/{chunk-CADSX6UN.js → chunk-Y3KNXVTD.js} +2 -2
  78. package/dist/chunk-YBW5JSA3.js +251 -0
  79. package/dist/chunk-YBW5JSA3.js.map +1 -0
  80. package/dist/chunk-YRXAWWCU.js +45 -0
  81. package/dist/chunk-YRXAWWCU.js.map +1 -0
  82. package/dist/claude-provider-account-authority.d.ts +18 -0
  83. package/dist/claude-subscription-oauth.d.ts +42 -0
  84. package/dist/claude-subscription-usage.d.ts +159 -0
  85. package/dist/client-error-report.d.ts +109 -0
  86. package/dist/client-error-report.js +87 -0
  87. package/dist/client-error-report.js.map +1 -0
  88. package/dist/code-search.d.ts +52 -0
  89. package/dist/code-search.js +40 -0
  90. package/dist/code-search.js.map +1 -0
  91. package/dist/codex-provider-account-authority.d.ts +23 -0
  92. package/dist/codex-provider-account-authority.js +23 -0
  93. package/dist/codex-provider-account-authority.js.map +1 -0
  94. package/dist/company-brain-governed-writes.d.ts +475 -0
  95. package/dist/company-brain.d.ts +336 -0
  96. package/dist/company-profile.d.ts +566 -0
  97. package/dist/connect.d.ts +325 -0
  98. package/dist/connect.js +191 -0
  99. package/dist/connect.js.map +1 -0
  100. package/dist/connection-account-label.d.ts +2 -0
  101. package/dist/connection-account-label.js +35 -0
  102. package/dist/connection-account-label.js.map +1 -0
  103. package/dist/connection-authority.d.ts +193 -0
  104. package/dist/connection-authority.js +50 -0
  105. package/dist/connection-authority.js.map +1 -0
  106. package/dist/connector-attachments.d.ts +95 -0
  107. package/dist/connector-attachments.js +51 -0
  108. package/dist/connector-attachments.js.map +1 -0
  109. package/dist/connector-tool-permissions.d.ts +73 -0
  110. package/dist/direct-model-provider.d.ts +36 -0
  111. package/dist/editable-artifact-codec-registry.d.ts +16 -7
  112. package/dist/editable-artifact-codec-registry.js +19 -9
  113. package/dist/editable-artifact-committed-transaction.d.ts +2 -2
  114. package/dist/editable-artifact-committed-transaction.js +2 -2
  115. package/dist/editable-artifact-live.d.ts +11 -12
  116. package/dist/editable-artifact-live.js +110 -45
  117. package/dist/editable-artifact-live.js.map +1 -1
  118. package/dist/editable-artifact-serialized-commit.d.ts +2 -1
  119. package/dist/editable-artifact-serialized-commit.js +8 -7
  120. package/dist/editable-artifact-versions.d.ts +20 -5
  121. package/dist/editable-artifact-versions.js +23 -5
  122. package/dist/editable-artifacts.d.ts +2 -0
  123. package/dist/editable-artifacts.js +48 -36
  124. package/dist/external-identities.d.ts +784 -0
  125. package/dist/external-identities.js +44 -0
  126. package/dist/external-identities.js.map +1 -0
  127. package/dist/feedback.d.ts +51 -0
  128. package/dist/github-repository-contracts.d.ts +36 -0
  129. package/dist/github-repository-contracts.js +59 -0
  130. package/dist/github-repository-contracts.js.map +1 -0
  131. package/dist/github-repository.d.ts +14 -0
  132. package/dist/github-repository.js +36 -0
  133. package/dist/github-repository.js.map +1 -0
  134. package/dist/google-drive.d.ts +90 -1
  135. package/dist/google-drive.js +91 -15
  136. package/dist/google-drive.js.map +1 -1
  137. package/dist/governed-learning-activation.d.ts +154 -0
  138. package/dist/governed-learning-evaluator.d.ts +152 -0
  139. package/dist/host-mcp-bindings.d.ts +326 -0
  140. package/dist/host-mcp-bindings.js +252 -0
  141. package/dist/host-mcp-bindings.js.map +1 -0
  142. package/dist/image-generation.d.ts +1 -0
  143. package/dist/index.d.ts +27574 -5374
  144. package/dist/index.js +2531 -177
  145. package/dist/insights-usage.d.ts +877 -0
  146. package/dist/insights-usage.js +509 -0
  147. package/dist/insights-usage.js.map +1 -0
  148. package/dist/interaction.d.ts +1752 -13
  149. package/dist/knowledge-entries.d.ts +982 -0
  150. package/dist/knowledge-preparation.d.ts +237 -0
  151. package/dist/knowledge.d.ts +740 -0
  152. package/dist/managed-auth-session-sets.d.ts +241 -0
  153. package/dist/managed-auth-session-sets.js +191 -0
  154. package/dist/managed-auth-session-sets.js.map +1 -0
  155. package/dist/managed-sign-in-methods.d.ts +56 -0
  156. package/dist/managed-sign-in-methods.js +46 -0
  157. package/dist/managed-sign-in-methods.js.map +1 -0
  158. package/dist/mcp-catalog-limits.d.ts +2 -0
  159. package/dist/mcp-endpoint.d.ts +7 -0
  160. package/dist/mcp-endpoint.js +9 -0
  161. package/dist/mcp-endpoint.js.map +1 -0
  162. package/dist/mcp-oauth.d.ts +71 -0
  163. package/dist/modal-native-proof-v2.d.ts +587 -0
  164. package/dist/modal-native-proof-v2.js +37 -0
  165. package/dist/modal-native-proof-v2.js.map +1 -0
  166. package/dist/model-availability.d.ts +15 -0
  167. package/dist/model-connection-access.d.ts +24 -0
  168. package/dist/model-context-inspector.d.ts +329 -0
  169. package/dist/model-display.d.ts +38 -0
  170. package/dist/model-display.js +134 -0
  171. package/dist/model-display.js.map +1 -0
  172. package/dist/model-picker-order.d.ts +25 -0
  173. package/dist/model-picker-order.js +42 -0
  174. package/dist/model-picker-order.js.map +1 -0
  175. package/dist/organization-access.d.ts +231 -0
  176. package/dist/organization-access.js +34 -0
  177. package/dist/organization-access.js.map +1 -0
  178. package/dist/organization-integration-policy.d.ts +27 -0
  179. package/dist/organization-membership-lifecycle.d.ts +1022 -0
  180. package/dist/organization-model-usage.d.ts +146 -0
  181. package/dist/organization-model-usage.js +67 -0
  182. package/dist/organization-model-usage.js.map +1 -0
  183. package/dist/organization-recovery.d.ts +337 -0
  184. package/dist/organization-recovery.js +37 -0
  185. package/dist/organization-recovery.js.map +1 -0
  186. package/dist/organization-usage.d.ts +138 -0
  187. package/dist/permissions.d.ts +54 -0
  188. package/dist/personal-github.d.ts +320 -0
  189. package/dist/personal-github.js +222 -0
  190. package/dist/personal-github.js.map +1 -0
  191. package/dist/plugin-discovery.d.ts +35 -0
  192. package/dist/plugin-discovery.js +7 -0
  193. package/dist/plugin-discovery.js.map +1 -0
  194. package/dist/preference-registry.d.ts +44 -1
  195. package/dist/product-analytics.d.ts +113 -0
  196. package/dist/product-lifecycle-facts.d.ts +73 -0
  197. package/dist/remember.d.ts +350 -0
  198. package/dist/retained-output.d.ts +8 -0
  199. package/dist/sandbox-file-artifacts.d.ts +57 -0
  200. package/dist/sandbox-provider-command.d.ts +113 -0
  201. package/dist/sandbox-recovery.d.ts +146 -0
  202. package/dist/sandbox-snapshots.d.ts +39 -0
  203. package/dist/session-final-reply.d.ts +6 -0
  204. package/dist/session-final-reply.js +9 -0
  205. package/dist/session-final-reply.js.map +1 -0
  206. package/dist/session-goal-reports.d.ts +21 -0
  207. package/dist/session-history-import.d.ts +947 -0
  208. package/dist/session-list-entries.d.ts +4 -0
  209. package/dist/session-list-entries.js +51 -0
  210. package/dist/session-list-entries.js.map +1 -0
  211. package/dist/session-mcp-projections.d.ts +215 -0
  212. package/dist/session-message-search.d.ts +68 -0
  213. package/dist/session-titles.d.ts +68 -0
  214. package/dist/session-titles.js +25 -0
  215. package/dist/session-titles.js.map +1 -0
  216. package/dist/session-topology-primitives.d.ts +22 -0
  217. package/dist/signup-attribution.d.ts +39 -0
  218. package/dist/site-request-headers.test.d.ts +1 -0
  219. package/dist/site-session-http.d.ts +11 -0
  220. package/dist/site-session-http.js +11 -0
  221. package/dist/site-session-http.js.map +1 -0
  222. package/dist/skill-catalog-context.d.ts +7 -0
  223. package/dist/skill-files.d.ts +12 -0
  224. package/dist/skill-metadata.d.ts +9 -0
  225. package/dist/skill-use.d.ts +61 -0
  226. package/dist/skills.d.ts +185 -0
  227. package/dist/slack-bot-scopes.d.ts +46 -21
  228. package/dist/slack-bot-scopes.js +14 -3
  229. package/dist/slack-rest-mcp.d.ts +31 -0
  230. package/dist/slack-rest-mcp.js +19 -0
  231. package/dist/slack-rest-mcp.js.map +1 -0
  232. package/dist/slack-task-policy.d.ts +294 -0
  233. package/dist/spreadsheet-artifact-commands.d.ts +2 -3
  234. package/dist/spreadsheet-artifact-commands.js +4 -2
  235. package/dist/spreadsheet-artifact-query.js +3 -2
  236. package/dist/subscription-account-pools.d.ts +292 -0
  237. package/dist/task-notes.d.ts +169 -0
  238. package/dist/tool-catalog.d.ts +286 -0
  239. package/dist/tool-result-spill.d.ts +16 -0
  240. package/dist/usage-allowances.d.ts +285 -0
  241. package/dist/usage-allowances.js +49 -0
  242. package/dist/usage-allowances.js.map +1 -0
  243. package/dist/video-generation.d.ts +51 -0
  244. package/dist/video-generation.js +9 -1
  245. package/dist/work-claims.d.ts +411 -0
  246. package/dist/workspace-instruction-policies.d.ts +94 -0
  247. package/dist/workspace-integration-wire.d.ts +36 -0
  248. package/dist/workspace-integration-wire.js +23 -0
  249. package/dist/workspace-integration-wire.js.map +1 -0
  250. package/dist/workspace-integrations.d.ts +948 -0
  251. package/dist/workspace-learning-administration.d.ts +289 -0
  252. package/dist/workspace-learning-policy.d.ts +1 -1
  253. package/dist/workspace-state.d.ts +85 -416
  254. package/dist/xai-provider-account-authority.d.ts +26 -0
  255. package/dist/xai-provider-account-authority.js +9 -0
  256. package/dist/xai-provider-account-authority.js.map +1 -0
  257. package/package.json +146 -1
  258. package/src/agent-authored-durable-text.ts +116 -0
  259. package/src/agent-config.ts +1527 -0
  260. package/src/agent-instruction-changes.ts +98 -0
  261. package/src/agent-learning.ts +161 -0
  262. package/src/agent-topology.ts +69 -0
  263. package/src/allowance-refusal.ts +81 -0
  264. package/src/analytics-consent-report.ts +20 -0
  265. package/src/api-key-presets.ts +25 -0
  266. package/src/artifact-catalog.ts +60 -0
  267. package/src/artifacts.ts +146 -18
  268. package/src/atlassian-native-retirement.ts +33 -0
  269. package/src/browser-storage.ts +10 -0
  270. package/src/bundled-skills.ts +73 -0
  271. package/src/canonical-human-identities.ts +93 -0
  272. package/src/claude-provider-account-authority.ts +12 -0
  273. package/src/claude-subscription-oauth.ts +62 -0
  274. package/src/claude-subscription-usage.ts +59 -0
  275. package/src/client-error-report.ts +184 -0
  276. package/src/code-search.ts +105 -0
  277. package/src/codex-provider-account-authority.ts +37 -0
  278. package/src/company-brain-governed-writes.ts +356 -0
  279. package/src/company-brain.ts +201 -0
  280. package/src/company-profile.ts +167 -1
  281. package/src/connect.ts +202 -0
  282. package/src/connection-account-label.ts +46 -0
  283. package/src/connection-authority.ts +213 -0
  284. package/src/connector-attachments.ts +327 -0
  285. package/src/connector-tool-permissions.ts +60 -0
  286. package/src/direct-model-provider.ts +98 -0
  287. package/src/editable-artifact-codec-registry.ts +55 -17
  288. package/src/editable-artifact-committed-transaction.ts +44 -31
  289. package/src/editable-artifact-live.ts +123 -57
  290. package/src/editable-artifact-serialized-commit.ts +2 -1
  291. package/src/editable-artifact-versions.ts +26 -5
  292. package/src/editable-artifacts.ts +2 -0
  293. package/src/external-identities.ts +285 -0
  294. package/src/feedback.ts +39 -0
  295. package/src/github-repository-contracts.ts +85 -0
  296. package/src/github-repository.ts +59 -0
  297. package/src/google-drive.ts +76 -4
  298. package/src/governed-learning-activation.ts +191 -0
  299. package/src/governed-learning-evaluator.ts +176 -0
  300. package/src/host-mcp-bindings.ts +298 -0
  301. package/src/image-generation.ts +8 -2
  302. package/src/index.ts +8019 -1799
  303. package/src/insights-usage.ts +679 -0
  304. package/src/interaction.ts +1102 -6
  305. package/src/knowledge-entries.ts +375 -0
  306. package/src/knowledge-preparation.ts +50 -0
  307. package/src/knowledge.ts +335 -0
  308. package/src/managed-auth-session-sets.ts +253 -0
  309. package/src/managed-sign-in-methods.ts +37 -0
  310. package/src/mcp-catalog-limits.ts +2 -0
  311. package/src/mcp-endpoint.ts +30 -0
  312. package/src/mcp-oauth.ts +66 -0
  313. package/src/modal-native-proof-v2.ts +398 -0
  314. package/src/model-availability.ts +22 -0
  315. package/src/model-connection-access.ts +17 -0
  316. package/src/model-context-inspector.ts +139 -0
  317. package/src/model-display.ts +195 -0
  318. package/src/model-picker-order.ts +97 -0
  319. package/src/organization-access.ts +176 -0
  320. package/src/organization-integration-policy.ts +54 -0
  321. package/src/organization-membership-lifecycle.ts +559 -0
  322. package/src/organization-model-usage.ts +72 -0
  323. package/src/organization-recovery.ts +186 -0
  324. package/src/organization-usage.ts +79 -0
  325. package/src/permissions.ts +58 -0
  326. package/src/personal-github.ts +267 -0
  327. package/src/plugin-discovery.ts +33 -0
  328. package/src/preference-registry.ts +20 -1
  329. package/src/product-analytics.ts +253 -0
  330. package/src/product-lifecycle-facts.ts +121 -0
  331. package/src/remember.ts +243 -0
  332. package/src/retained-output.ts +20 -3
  333. package/src/sandbox-file-artifacts.ts +73 -0
  334. package/src/sandbox-provider-command.ts +82 -0
  335. package/src/sandbox-recovery.ts +116 -0
  336. package/src/sandbox-snapshots.ts +142 -0
  337. package/src/session-final-reply.ts +16 -0
  338. package/src/session-goal-reports.ts +55 -0
  339. package/src/session-history-import.ts +159 -0
  340. package/src/session-list-entries.ts +91 -0
  341. package/src/session-mcp-projections.ts +273 -0
  342. package/src/session-message-search.ts +54 -0
  343. package/src/session-titles.ts +467 -0
  344. package/src/session-topology-primitives.ts +21 -0
  345. package/src/signup-attribution.ts +81 -0
  346. package/src/site-request-headers.test.ts +28 -0
  347. package/src/site-session-http.ts +63 -0
  348. package/src/skill-catalog-context.ts +50 -0
  349. package/src/skill-files.ts +52 -0
  350. package/src/skill-metadata.ts +40 -0
  351. package/src/skill-use.ts +77 -0
  352. package/src/skills.ts +136 -0
  353. package/src/slack-bot-scopes.ts +106 -42
  354. package/src/slack-rest-mcp.ts +194 -0
  355. package/src/slack-task-policy.ts +215 -0
  356. package/src/spreadsheet-artifact-commands.ts +12 -13
  357. package/src/subscription-account-pools.ts +44 -0
  358. package/src/task-notes.ts +105 -0
  359. package/src/tool-catalog.ts +155 -0
  360. package/src/tool-result-spill.ts +35 -0
  361. package/src/usage-allowances.ts +187 -0
  362. package/src/video-generation.ts +43 -6
  363. package/src/work-claims.ts +266 -0
  364. package/src/workspace-instruction-policies.ts +31 -0
  365. package/src/workspace-integration-wire.ts +99 -0
  366. package/src/workspace-integrations.ts +640 -0
  367. package/src/workspace-learning-administration.ts +88 -0
  368. package/src/workspace-learning-policy.ts +4 -3
  369. package/src/workspace-state.ts +16 -126
  370. package/src/xai-provider-account-authority.ts +38 -0
  371. package/dist/chunk-52SGB2QO.js.map +0 -1
  372. package/dist/chunk-5UDNP7AO.js.map +0 -1
  373. package/dist/chunk-BVGIYW7D.js +0 -11
  374. package/dist/chunk-BVGIYW7D.js.map +0 -1
  375. package/dist/chunk-FJBG5E4O.js.map +0 -1
  376. package/dist/chunk-H5BVCZKF.js.map +0 -1
  377. package/dist/chunk-LSB7GRLG.js.map +0 -1
  378. package/dist/chunk-TZ6YEYN4.js.map +0 -1
  379. package/dist/chunk-VA22KRHS.js +0 -15177
  380. package/dist/chunk-VA22KRHS.js.map +0 -1
  381. package/dist/chunk-Y3MLSLB4.js.map +0 -1
  382. /package/dist/{chunk-CADSX6UN.js.map → chunk-Y3KNXVTD.js.map} +0 -0
@@ -0,0 +1,73 @@
1
+ import { z } from "zod";
2
+
3
+ import { RetainedArtifactReferenceSchema } from "./retained-output";
4
+
5
+ /**
6
+ * Channel-A currently returns one bounded binary-safe read. Keep publication
7
+ * below that ceiling so an extra sentinel byte can distinguish an exact file
8
+ * from a truncated prefix.
9
+ */
10
+ export const SANDBOX_FILE_ARTIFACT_MAX_BYTES = 25 * 1024 * 1024 - 1;
11
+
12
+ export const PublishSandboxFileArtifactRequest = z
13
+ .object({
14
+ path: z.string().min(1).max(4_096),
15
+ })
16
+ .strict();
17
+ export type PublishSandboxFileArtifactRequest = z.infer<typeof PublishSandboxFileArtifactRequest>;
18
+
19
+ /**
20
+ * Closed model/UI receipt for one exact sandbox-file publication. Storage
21
+ * locators and signed URLs never cross this boundary.
22
+ */
23
+ export const SandboxFileArtifactReceipt = z
24
+ .object({
25
+ type: z.literal("sandbox_file"),
26
+ sandboxPath: z.string().min(1).max(4_096),
27
+ filename: z.string().min(1).max(1_024),
28
+ artifact: RetainedArtifactReferenceSchema,
29
+ })
30
+ .strict()
31
+ .superRefine((value, context) => {
32
+ const pathSegments = value.sandboxPath.split("/");
33
+ // This is a receipt, not read authority. The publisher confines the path
34
+ // against its resolved provider root; receipts preserve that native path.
35
+ const unc = value.sandboxPath.startsWith("//");
36
+ const absolute = unc
37
+ ? /^\/\/[^/]+\/[^/]+\/.+/u.test(value.sandboxPath) && !value.sandboxPath.startsWith("//?/")
38
+ : value.sandboxPath.startsWith("/") || /^[A-Z]:\//u.test(value.sandboxPath);
39
+ if (
40
+ !absolute ||
41
+ /[\\\u0000-\u001f\u007f]/u.test(value.sandboxPath) ||
42
+ pathSegments.some(
43
+ (segment, index) =>
44
+ index >= (unc ? 2 : 1) && (!segment || segment === "." || segment === ".."),
45
+ ) ||
46
+ pathSegments.at(-1) !== value.filename
47
+ ) {
48
+ context.addIssue({
49
+ code: "custom",
50
+ path: ["sandboxPath"],
51
+ message:
52
+ "sandbox path must canonically identify the published filename at an absolute host path",
53
+ });
54
+ }
55
+ if (value.artifact.kind !== "file" || value.artifact.retention.policy !== "workspace_file") {
56
+ context.addIssue({
57
+ code: "custom",
58
+ path: ["artifact"],
59
+ message: "sandbox files require a permanent workspace-file artifact",
60
+ });
61
+ }
62
+ if (
63
+ value.artifact.originalBytes < 1 ||
64
+ value.artifact.originalBytes > SANDBOX_FILE_ARTIFACT_MAX_BYTES
65
+ ) {
66
+ context.addIssue({
67
+ code: "custom",
68
+ path: ["artifact", "originalBytes"],
69
+ message: "sandbox file size is outside the publication byte limit",
70
+ });
71
+ }
72
+ });
73
+ export type SandboxFileArtifactReceipt = z.infer<typeof SandboxFileArtifactReceipt>;
@@ -0,0 +1,82 @@
1
+ import { z } from "zod";
2
+
3
+ const ModalOutputCursor = z
4
+ .object({
5
+ batchIndex: z.number().int().nonnegative().safe(),
6
+ utf8Remainder: z
7
+ .string()
8
+ .max(8)
9
+ .regex(/^[A-Za-z0-9+/]*={0,2}$/u),
10
+ exitCode: z.number().int().nullable(),
11
+ })
12
+ .strict();
13
+
14
+ /** Provider-owned execution identity and acknowledged output cursors. These
15
+ * values are retained by the control plane, never recovered from sandbox files. */
16
+ export const ModalLegacyProviderCommand = z
17
+ .object({
18
+ kind: z.literal("modal-control-v1"),
19
+ sandboxId: z.string().min(1).max(200),
20
+ taskId: z.string().min(1).max(200),
21
+ execId: z.string().min(1).max(200),
22
+ pty: z.boolean().optional(),
23
+ streams: z.object({ stdout: ModalOutputCursor, stderr: ModalOutputCursor }).strict(),
24
+ })
25
+ .strict();
26
+ export type ModalLegacyProviderCommand = z.infer<typeof ModalLegacyProviderCommand>;
27
+
28
+ const ModalByteCursor = z
29
+ .object({
30
+ byteOffset: z.number().int().nonnegative().safe(),
31
+ utf8Remainder: z
32
+ .string()
33
+ .max(8)
34
+ .regex(/^[A-Za-z0-9+/]*={0,2}$/u),
35
+ eof: z.boolean(),
36
+ exitCode: z.number().int().nullable(),
37
+ })
38
+ .strict()
39
+ .refine((cursor) => cursor.exitCode === null || cursor.eof, {
40
+ message: "A terminal output cursor must have reached EOF",
41
+ });
42
+
43
+ export const CommandSupervisionDescriptor = z
44
+ .object({
45
+ protocol: z.literal("native-subreaper-v1"),
46
+ invocationId: z.string().uuid(),
47
+ nonce: z.string().regex(/^[a-f0-9]{64}$/u),
48
+ controlPath: z.string().regex(/^\/tmp\/opengeni-supervision\/[a-f0-9-]{36}\.sock$/u),
49
+ })
50
+ .strict();
51
+ export type CommandSupervisionDescriptor = z.infer<typeof CommandSupervisionDescriptor>;
52
+
53
+ export const CommandSupervisionReceipt = z
54
+ .object({
55
+ protocol: z.literal("native-subreaper-v1"),
56
+ invocationId: z.string().uuid(),
57
+ receiptId: z.string().uuid(),
58
+ leaderExitCode: z.number().int(),
59
+ })
60
+ .strict();
61
+ export type CommandSupervisionReceipt = z.infer<typeof CommandSupervisionReceipt>;
62
+
63
+ export const ModalRouterProviderCommand = z
64
+ .object({
65
+ kind: z.literal("modal-router-v1"),
66
+ sandboxId: z.string().min(1).max(200),
67
+ taskId: z.string().min(1).max(200),
68
+ execId: z.string().uuid(),
69
+ pty: z.boolean().optional(),
70
+ supervision: CommandSupervisionDescriptor.optional(),
71
+ streams: z.object({ stdout: ModalByteCursor, stderr: ModalByteCursor }).strict(),
72
+ })
73
+ .strict();
74
+ export type ModalRouterProviderCommand = z.infer<typeof ModalRouterProviderCommand>;
75
+
76
+ /** Legacy locators are read-only compatibility for already launched commands;
77
+ * new starts use authenticated task-router byte offsets, never batch indices. */
78
+ export const SandboxProviderCommand = z.discriminatedUnion("kind", [
79
+ ModalLegacyProviderCommand,
80
+ ModalRouterProviderCommand,
81
+ ]);
82
+ export type SandboxProviderCommand = z.infer<typeof SandboxProviderCommand>;
@@ -0,0 +1,116 @@
1
+ import { z } from "zod";
2
+
3
+ /** Public, content-free selection. Never include native provider bindings. */
4
+ export const SandboxRecoverySelection = z
5
+ .object({
6
+ version: z.literal(1),
7
+ sessionId: z.string().uuid(),
8
+ sandboxGroupId: z.string().uuid(),
9
+ leaseId: z.string().uuid(),
10
+ routeEpoch: z.number().int().nonnegative(),
11
+ authorityEpoch: z.number().int().positive(),
12
+ leaseEpoch: z.number().int().nonnegative(),
13
+ workspaceGeneration: z.number().int().nonnegative(),
14
+ archiveGeneration: z.number().int().nonnegative(),
15
+ artifactId: z.string().uuid(),
16
+ revision: z.string().min(1).max(512),
17
+ capturedAt: z.string().datetime(),
18
+ })
19
+ .strict();
20
+ export type SandboxRecoverySelection = z.infer<typeof SandboxRecoverySelection>;
21
+
22
+ export const SandboxRecoveryProjection = z
23
+ .object({
24
+ version: z.literal(1),
25
+ status: z.enum([
26
+ "unsupported",
27
+ "blocked",
28
+ "eligible",
29
+ "consent_accepted",
30
+ "restoring",
31
+ "restored",
32
+ ]),
33
+ reason: z.string().max(128).nullable(),
34
+ checkpoint: SandboxRecoverySelection.nullable(),
35
+ operationId: z.string().uuid().nullable(),
36
+ /** Retry may elect a system-selected verified checkpoint; no consent POST. */
37
+ automaticAvailable: z.boolean().optional(),
38
+ /** What an automatic Retry will do: restore `checkpoint`, or continue on a
39
+ * new empty workspace because no usable checkpoint survived the loss. */
40
+ automaticLane: z.enum(["checkpoint", "fresh_workspace"]).optional(),
41
+ /** For a timed recovery wait: the earliest time a Retry or a new message
42
+ * can let OpenGeni decide again. Nothing proceeds by itself before then. */
43
+ availableAt: z.string().datetime().optional(),
44
+ })
45
+ .strict();
46
+ export type SandboxRecoveryProjection = z.infer<typeof SandboxRecoveryProjection>;
47
+
48
+ /** Why a definitively lost managed sandbox continues on an empty workspace. */
49
+ export const SandboxFreshWorkspaceReason = z.enum([
50
+ "archive_unavailable",
51
+ "archive_unverified",
52
+ "checkpoint_unrestorable",
53
+ "checkpoint_restore_failed",
54
+ ]);
55
+ export type SandboxFreshWorkspaceReason = z.infer<typeof SandboxFreshWorkspaceReason>;
56
+
57
+ /** Durable, content-free fresh-workspace decision for one group member. */
58
+ export const SandboxFreshWorkspaceRecovery = z
59
+ .object({
60
+ version: z.literal(1),
61
+ sessionId: z.string().uuid(),
62
+ sandboxGroupId: z.string().uuid(),
63
+ leaseId: z.string().uuid(),
64
+ leaseEpoch: z.number().int().nonnegative(),
65
+ workspaceGeneration: z.number().int().nonnegative(),
66
+ archiveGeneration: z.number().int().nonnegative().nullable(),
67
+ lostAt: z.string().datetime(),
68
+ reason: SandboxFreshWorkspaceReason,
69
+ })
70
+ .strict();
71
+ export type SandboxFreshWorkspaceRecovery = z.infer<typeof SandboxFreshWorkspaceRecovery>;
72
+
73
+ export const SandboxRecoveryRequest = z
74
+ .object({
75
+ operationId: z.string().uuid(),
76
+ acceptHistoricalCheckpoint: z.literal(true),
77
+ selection: SandboxRecoverySelection,
78
+ })
79
+ .strict();
80
+ export type SandboxRecoveryRequest = z.infer<typeof SandboxRecoveryRequest>;
81
+
82
+ export const SandboxRecoveryResponse = z
83
+ .object({
84
+ outcome: z.enum(["accepted", "replayed"]),
85
+ operationId: z.string().uuid(),
86
+ recovery: SandboxRecoveryProjection,
87
+ })
88
+ .strict();
89
+ export type SandboxRecoveryResponse = z.infer<typeof SandboxRecoveryResponse>;
90
+
91
+ /** Re-injected from durable receipts on every attempt, not lossy transcript state. */
92
+ export function sandboxRecoveryDiscontinuity(selection: SandboxRecoverySelection): string {
93
+ return `Filesystem discontinuity: the human explicitly consented to restoring this session's workspace from the checkpoint captured at ${selection.capturedAt} (archive generation ${selection.archiveGeneration}, pre-recovery workspace generation ${selection.workspaceGeneration}). Newer filesystem changes are unavailable. The generation gap is not a count of lost files or edits. Conversation and tool receipts remain historical evidence, not proof that their files still exist. External effects are not undone. Verify the current filesystem before relying on previous work. Never automatically replay prior commands or operations with unknown outcomes to rebuild missing files. Consent alone is not proof that restoration succeeded.`;
94
+ }
95
+
96
+ /** Stable tail instructions, sourced from a durable system recovery receipt.
97
+ * `shared` names the sandbox this session shares with other sessions; every
98
+ * member of that group receives its own receipt for the same selection. */
99
+ export function automaticSandboxRecoveryDiscontinuity(
100
+ selection: SandboxRecoverySelection,
101
+ scope: "session" | "shared" = "session",
102
+ ): string {
103
+ const subject =
104
+ scope === "shared"
105
+ ? "the latest verified checkpoint of the sandbox this session shares with other sessions"
106
+ : "this session's latest verified checkpoint";
107
+ return `Filesystem discontinuity: after the managed sandbox was lost, OpenGeni selected ${subject}, captured at ${selection.capturedAt} (archive generation ${selection.archiveGeneration}, pre-recovery workspace generation ${selection.workspaceGeneration}). Newer filesystem changes may be unavailable; the generation gap is not a count of lost files or edits. Conversation and tool receipts remain historical evidence, not proof that their files still exist. External effects are not undone. Verify the restored filesystem before relying on previous work. Never automatically replay prior commands or operations with unknown outcomes. Checkpoint selection alone is not proof that restoration succeeded.`;
108
+ }
109
+
110
+ /** Stable tail instructions for continuing on a new empty workspace. The text
111
+ * is true on every later turn too: it names the loss, not the current tree. */
112
+ export function freshWorkspaceSandboxRecoveryDiscontinuity(
113
+ recovery: SandboxFreshWorkspaceRecovery,
114
+ ): string {
115
+ return `Filesystem discontinuity: the previous managed sandbox was lost at ${recovery.lostAt} and there is no checkpoint OpenGeni can restore automatically, so OpenGeni continued this session on a new empty workspace. Files, repository clones, installed packages and running processes from before that time are not available in this workspace; do not assume they exist. Anything now in the workspace was created after that loss. Conversation and tool receipts from before it remain historical evidence, not proof that their files still exist. External effects are not undone. Verify the current filesystem before relying on previous work, and recreate what you need deliberately. Never automatically replay prior commands or operations with unknown outcomes.`;
116
+ }
@@ -52,6 +52,148 @@ export type NativeSnapshotDescriptor = {
52
52
 
53
53
  export type WorkspaceArchiveDescriptor = TarWorkspaceArchiveDescriptor | NativeSnapshotDescriptor;
54
54
 
55
+ export const WORKSPACE_ARCHIVE_OBJECT_REF_SCHEMA = "sandbox_archive_object_v1" as const;
56
+
57
+ /** Compact object-storage locator for portable tar bytes. The SHA-256/size in
58
+ * `workspaceArchiveMeta` remain the verification authority. */
59
+ export type WorkspaceArchiveObjectRef = {
60
+ schema: typeof WORKSPACE_ARCHIVE_OBJECT_REF_SCHEMA;
61
+ key: string;
62
+ sha256: string;
63
+ bytes: number;
64
+ backend: string;
65
+ };
66
+
67
+ // Keep legacy scope/key spelling readable. New physical upload identities must
68
+ // be a complete RFC UUID (including version and variant), never arbitrary text.
69
+ const UPLOAD_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
70
+ const OBJECT_KEY =
71
+ /^sandbox-archives\/v1\/([0-9a-f-]{36})\/([0-9a-f-]{36})\/([0-9a-f-]{36})\/(wa1:[0-9]{13}:[0-9a-f]{64})(?:\.([0-9a-f-]+))?\.tar$/i;
72
+
73
+ export type WorkspaceArchiveObjectKey = {
74
+ accountId: string;
75
+ workspaceId: string;
76
+ sandboxGroupId: string;
77
+ revision: string;
78
+ uploadId: string | null;
79
+ };
80
+
81
+ export function parseWorkspaceArchiveObjectKey(value: unknown): WorkspaceArchiveObjectKey | null {
82
+ if (typeof value !== "string") return null;
83
+ const match = OBJECT_KEY.exec(value);
84
+ // JS $ may match before a final newline; a locator must match in full.
85
+ if (!match || match[0] !== value || (match[5] !== undefined && !UPLOAD_ID.test(match[5]))) {
86
+ return null;
87
+ }
88
+ return {
89
+ accountId: match[1]!,
90
+ workspaceId: match[2]!,
91
+ sandboxGroupId: match[3]!,
92
+ revision: match[4]!,
93
+ uploadId: match[5] ?? null,
94
+ };
95
+ }
96
+
97
+ export function parseWorkspaceArchiveObjectRef(value: unknown): WorkspaceArchiveObjectRef | null {
98
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
99
+ const candidate = value as Partial<WorkspaceArchiveObjectRef>;
100
+ if (
101
+ candidate.schema !== WORKSPACE_ARCHIVE_OBJECT_REF_SCHEMA ||
102
+ typeof candidate.key !== "string" ||
103
+ !parseWorkspaceArchiveObjectKey(candidate.key) ||
104
+ typeof candidate.sha256 !== "string" ||
105
+ !SHA256.test(candidate.sha256) ||
106
+ !nonnegativeInteger(candidate.bytes) ||
107
+ candidate.bytes <= 0 ||
108
+ typeof candidate.backend !== "string" ||
109
+ candidate.backend.length === 0 ||
110
+ candidate.backend.length > 64
111
+ ) {
112
+ return null;
113
+ }
114
+ return {
115
+ schema: WORKSPACE_ARCHIVE_OBJECT_REF_SCHEMA,
116
+ key: candidate.key,
117
+ sha256: candidate.sha256,
118
+ bytes: candidate.bytes,
119
+ backend: candidate.backend,
120
+ };
121
+ }
122
+
123
+ export function workspaceArchiveObjectKey(input: {
124
+ accountId: string;
125
+ workspaceId: string;
126
+ sandboxGroupId: string;
127
+ revision: string;
128
+ /** New upload invocations supply a fresh randomUUID; omission is legacy-only. */
129
+ uploadId?: string;
130
+ }): string {
131
+ if (
132
+ input.uploadId !== undefined &&
133
+ (!UPLOAD_ID.test(input.uploadId) || input.uploadId.length !== 36)
134
+ ) {
135
+ throw new Error("Invalid workspace archive upload UUID");
136
+ }
137
+ return `sandbox-archives/v1/${input.accountId}/${input.workspaceId}/${input.sandboxGroupId}/${input.revision}${input.uploadId === undefined ? "" : `.${input.uploadId}`}.tar`;
138
+ }
139
+
140
+ /** Bind a stored locator to its publication/restore scope and verified tar
141
+ * descriptor. A logical revision never substitutes for the exact physical key. */
142
+ export function validateWorkspaceArchiveObjectRef(
143
+ value: unknown,
144
+ input: {
145
+ accountId: string;
146
+ workspaceId: string;
147
+ sandboxGroupId: string;
148
+ descriptor: WorkspaceArchiveDescriptor;
149
+ },
150
+ ): WorkspaceArchiveObjectRef | null {
151
+ const ref = parseWorkspaceArchiveObjectRef(value);
152
+ const key = ref && parseWorkspaceArchiveObjectKey(ref.key);
153
+ const descriptor = parseWorkspaceArchiveDescriptor(input.descriptor);
154
+ if (
155
+ !ref ||
156
+ !key ||
157
+ descriptor?.version !== 1 ||
158
+ key.accountId.toLowerCase() !== input.accountId.toLowerCase() ||
159
+ key.workspaceId.toLowerCase() !== input.workspaceId.toLowerCase() ||
160
+ key.sandboxGroupId.toLowerCase() !== input.sandboxGroupId.toLowerCase() ||
161
+ key.revision !== descriptor.revision ||
162
+ ref.sha256 !== descriptor.archiveSha256 ||
163
+ ref.bytes !== descriptor.archiveBytes
164
+ )
165
+ return null;
166
+ return ref;
167
+ }
168
+
169
+ export function workspaceArchivePayloadPresent(
170
+ sessionState: Record<string, unknown> | null | undefined,
171
+ ): boolean {
172
+ if (!sessionState) return false;
173
+ if (
174
+ typeof sessionState.workspaceArchive === "string" &&
175
+ sessionState.workspaceArchive.length > 0
176
+ ) {
177
+ return true;
178
+ }
179
+ return parseWorkspaceArchiveObjectRef(sessionState.workspaceArchiveRef) !== null;
180
+ }
181
+
182
+ /** Restore may inline object bytes in memory for hydrate. That copy must never
183
+ * be published onto a lease when a durable object-storage ref exists. */
184
+ export function omitInlineWorkspaceArchiveWhenObjectRefPresent(
185
+ sessionState: Record<string, unknown>,
186
+ ): Record<string, unknown> {
187
+ const next = { ...sessionState };
188
+ if (parseWorkspaceArchiveObjectRef(next.workspaceArchiveRef)) {
189
+ delete next.workspaceArchive;
190
+ }
191
+ if (parseWorkspaceArchiveObjectRef(next.workspaceArchivePrevRef)) {
192
+ delete next.workspaceArchivePrev;
193
+ }
194
+ return next;
195
+ }
196
+
55
197
  export const NATIVE_SNAPSHOT_PREFIXES: ReadonlyArray<{
56
198
  provider: NativeSnapshotProvider;
57
199
  prefix: string;
@@ -0,0 +1,16 @@
1
+ /** A response-quality notice, not a failed turn or a completed deliverable. */
2
+ export const EMPTY_FINAL_REPLY_NOTICE =
3
+ "The model returned no final reply after a reply reminder. Completed work is preserved; the goal and later updates are unaffected.";
4
+
5
+ export type EmptyFinalReplyCompletion = {
6
+ emptyFinalReply: true;
7
+ };
8
+
9
+ export function turnCompletedWithEmptyFinalReply(payload: unknown): boolean {
10
+ return (
11
+ payload !== null &&
12
+ typeof payload === "object" &&
13
+ !Array.isArray(payload) &&
14
+ (payload as { emptyFinalReply?: unknown }).emptyFinalReply === true
15
+ );
16
+ }
@@ -0,0 +1,55 @@
1
+ import { z } from "zod";
2
+
3
+ export const SessionGoalReportRequirement = z
4
+ .object({
5
+ id: z
6
+ .string()
7
+ .max(64)
8
+ .describe(
9
+ "Stable report requirement identifier, at most 64 ASCII characters; not a title or status.",
10
+ )
11
+ .regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/),
12
+ title: z
13
+ .string()
14
+ .trim()
15
+ .min(1)
16
+ .max(512)
17
+ .describe(
18
+ "Short human-readable report title, at most 512 UTF-8 bytes. Keep normal spaces; do not put the report or a progress transcript here.",
19
+ )
20
+ .refine(
21
+ (value) => new TextEncoder().encode(value).byteLength <= 512,
22
+ "Report title exceeds 512 UTF-8 bytes",
23
+ ),
24
+ })
25
+ .strict();
26
+ export type SessionGoalReportRequirement = z.infer<typeof SessionGoalReportRequirement>;
27
+
28
+ export const SessionGoalReportRequirements = z
29
+ .array(SessionGoalReportRequirement)
30
+ .max(16)
31
+ .superRefine((requirements, context) => {
32
+ if (new Set(requirements.map((item) => item.id)).size !== requirements.length) {
33
+ context.addIssue({ code: "custom", message: "Duplicate report requirement IDs" });
34
+ }
35
+ });
36
+
37
+ export const SessionGoalReportDelivery = z
38
+ .object({
39
+ requirementId: SessionGoalReportRequirement.shape.id,
40
+ artifactId: z
41
+ .string()
42
+ .regex(/^[0-9a-f]{32}$/)
43
+ .refine((value) => !/^0+$/.test(value)),
44
+ inspectionReceiptId: z.string().uuid(),
45
+ })
46
+ .strict();
47
+ export type SessionGoalReportDelivery = z.infer<typeof SessionGoalReportDelivery>;
48
+ export const SessionGoalReportDeliveries = z
49
+ .array(SessionGoalReportDelivery)
50
+ .max(16)
51
+ .superRefine((deliveries, context) => {
52
+ if (new Set(deliveries.map((item) => item.requirementId)).size !== deliveries.length) {
53
+ context.addIssue({ code: "custom", message: "Duplicate report delivery requirement IDs" });
54
+ }
55
+ });
@@ -0,0 +1,159 @@
1
+ import { z } from "zod";
2
+ import { Session } from "./index";
3
+ import type { SessionEventType } from "./index";
4
+
5
+ /** Import is a server-side migration boundary, not an execution/history API. */
6
+ export const SESSION_HISTORY_IMPORT_MAX_EVENTS = 100;
7
+ export const SESSION_HISTORY_IMPORT_MAX_BODY_BYTES = 1_048_576;
8
+ export const SESSION_HISTORY_IMPORT_MAX_EVENT_BYTES = 262_144;
9
+
10
+ /** Historical facts only: no approval, credential, control or execution inputs. */
11
+ export const ARCHIVED_SESSION_IMPORT_EVENT_TYPES = [
12
+ "user.message",
13
+ "agent.message.delta",
14
+ "agent.message.completed",
15
+ "agent.reasoning.delta",
16
+ "agent.toolCall.created",
17
+ "agent.toolCall.output",
18
+ "artifact.created",
19
+ "turn.started",
20
+ "turn.completed",
21
+ "turn.failed",
22
+ "turn.cancelled",
23
+ "turn.superseded",
24
+ "goal.set",
25
+ "goal.updated",
26
+ "goal.progress",
27
+ "goal.completed",
28
+ "goal.paused",
29
+ "goal.resumed",
30
+ "goal.cleared",
31
+ ] as const satisfies readonly SessionEventType[];
32
+
33
+ export const SessionImportedArchive = /* @__PURE__ */ z
34
+ .object({
35
+ importId: z.string().min(1).max(200),
36
+ importedAt: z.iso.datetime({ offset: true }),
37
+ readOnly: z.literal(true),
38
+ })
39
+ .strict();
40
+ export type SessionImportedArchive = z.infer<typeof SessionImportedArchive>;
41
+
42
+ /** JS/SQL session seams preserve millisecond precision; never silently truncate. */
43
+ const sourceTimestamp = /* @__PURE__ */ z.iso
44
+ .datetime({ offset: true })
45
+ .refine((value) => !/\.\d{4}/u.test(value), "Source timestamp supports at most milliseconds");
46
+
47
+ /** Validate JSON without coercing dates, dropping undefined, or rewriting text. */
48
+ function isImportJson(value: unknown): boolean {
49
+ const pending: Array<{ value: unknown; depth: number }> = [{ value, depth: 0 }];
50
+ const seen = new Set<object>();
51
+ let nodes = 0;
52
+ while (pending.length > 0) {
53
+ const entry = pending.pop()!;
54
+ if (++nodes > 100_000 || entry.depth > 64) return false;
55
+ const current = entry.value;
56
+ if (current === null || typeof current === "string" || typeof current === "boolean") continue;
57
+ if (typeof current === "number") {
58
+ if (!Number.isFinite(current) || Object.is(current, -0)) return false;
59
+ continue;
60
+ }
61
+ if (typeof current !== "object" || seen.has(current)) return false;
62
+ seen.add(current);
63
+ if (Array.isArray(current)) {
64
+ for (let index = 0; index < current.length; index++) {
65
+ if (!Object.hasOwn(current, index)) return false;
66
+ pending.push({ value: current[index], depth: entry.depth + 1 });
67
+ }
68
+ } else {
69
+ const prototype = Object.getPrototypeOf(current);
70
+ if (prototype !== Object.prototype && prototype !== null) return false;
71
+ for (const descriptor of Object.values(Object.getOwnPropertyDescriptors(current))) {
72
+ if (!descriptor.enumerable || !Object.hasOwn(descriptor, "value")) return false;
73
+ pending.push({ value: descriptor.value, depth: entry.depth + 1 });
74
+ }
75
+ if (Object.getOwnPropertySymbols(current).length > 0) return false;
76
+ }
77
+ }
78
+ return true;
79
+ }
80
+
81
+ function jsonBytes(value: unknown): number {
82
+ try {
83
+ return new TextEncoder().encode(JSON.stringify(value)).byteLength;
84
+ } catch {
85
+ return Number.POSITIVE_INFINITY;
86
+ }
87
+ }
88
+
89
+ export const ArchivedSessionImportEvent = /* @__PURE__ */ z
90
+ .object({
91
+ type: z.enum(ARCHIVED_SESSION_IMPORT_EVENT_TYPES),
92
+ createdAt: sourceTimestamp,
93
+ /** Source turn identity is presentation correlation; no execution row is created. */
94
+ turnId: z.string().uuid().nullable().optional(),
95
+ payload: z.record(z.string(), z.unknown()).refine(isImportJson, "Payload must be bounded JSON"),
96
+ })
97
+ .strict()
98
+ .refine(
99
+ (event) => isImportJson(event) && jsonBytes(event) <= SESSION_HISTORY_IMPORT_MAX_EVENT_BYTES,
100
+ "Imported event exceeds its JSON or byte limit",
101
+ );
102
+ export type ArchivedSessionImportEvent = z.infer<typeof ArchivedSessionImportEvent>;
103
+
104
+ const importEvents = /* @__PURE__ */ z
105
+ .array(ArchivedSessionImportEvent)
106
+ .max(SESSION_HISTORY_IMPORT_MAX_EVENTS);
107
+
108
+ export const ImportArchivedSessionRequest = /* @__PURE__ */ z
109
+ .object({
110
+ importId: z.string().min(1).max(200),
111
+ title: z.string().min(1).max(200),
112
+ createdAt: sourceTimestamp,
113
+ /** The authenticated asUser actor supplies creator/owner, never a display label. */
114
+ visibility: z.enum(["workspace_shared", "user_private"]).optional(),
115
+ events: importEvents.default([]),
116
+ })
117
+ .strict()
118
+ .refine(
119
+ (request) => jsonBytes(request) <= SESSION_HISTORY_IMPORT_MAX_BODY_BYTES,
120
+ "Import request exceeds its byte limit",
121
+ );
122
+ export type ImportArchivedSessionRequest = z.input<typeof ImportArchivedSessionRequest>;
123
+
124
+ export const AppendArchivedSessionEventsRequest = /* @__PURE__ */ z
125
+ .object({
126
+ batchId: z.string().min(1).max(200),
127
+ offset: z
128
+ .number()
129
+ .int()
130
+ .nonnegative()
131
+ .max(Number.MAX_SAFE_INTEGER)
132
+ .refine((value) => !Object.is(value, -0)),
133
+ events: importEvents.min(1),
134
+ })
135
+ .strict()
136
+ .refine(
137
+ (request) => jsonBytes(request) <= SESSION_HISTORY_IMPORT_MAX_BODY_BYTES,
138
+ "Import batch exceeds its byte limit",
139
+ );
140
+ export type AppendArchivedSessionEventsRequest = z.infer<typeof AppendArchivedSessionEventsRequest>;
141
+
142
+ // Lazy to preserve the root contracts initialization order; SDK uses types only.
143
+ export const ImportArchivedSessionResponse = /* @__PURE__ */ z.object({
144
+ session: /* @__PURE__ */ z.lazy(() => Session),
145
+ importId: z.string(),
146
+ created: z.boolean(),
147
+ nextOffset: z.number().int().nonnegative(),
148
+ });
149
+ export type ImportArchivedSessionResponse = z.infer<typeof ImportArchivedSessionResponse>;
150
+
151
+ export const AppendArchivedSessionEventsResponse = /* @__PURE__ */ z.object({
152
+ sessionId: z.string().uuid(),
153
+ importId: z.string(),
154
+ nextOffset: z.number().int().nonnegative(),
155
+ replayed: z.boolean(),
156
+ });
157
+ export type AppendArchivedSessionEventsResponse = z.infer<
158
+ typeof AppendArchivedSessionEventsResponse
159
+ >;