@opengeni/contracts 0.50.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (369) 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 +26 -12
  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/chunk-2ACYHZFB.js +292 -0
  25. package/dist/chunk-2ACYHZFB.js.map +1 -0
  26. package/dist/chunk-2VORLN2R.js +353 -0
  27. package/dist/chunk-2VORLN2R.js.map +1 -0
  28. package/dist/{chunk-Y3MLSLB4.js → chunk-3SIZGL3O.js} +42 -30
  29. package/dist/chunk-3SIZGL3O.js.map +1 -0
  30. package/dist/chunk-46KLD2UH.js +186 -0
  31. package/dist/chunk-46KLD2UH.js.map +1 -0
  32. package/dist/chunk-4JGHSSB7.js +11 -0
  33. package/dist/chunk-4JGHSSB7.js.map +1 -0
  34. package/dist/{chunk-M5ZGRVIQ.js → chunk-5IXYF6XN.js} +14 -5
  35. package/dist/chunk-5IXYF6XN.js.map +1 -0
  36. package/dist/chunk-BCS7WHCK.js +139 -0
  37. package/dist/chunk-BCS7WHCK.js.map +1 -0
  38. package/dist/chunk-EK7NDGFR.js +128 -0
  39. package/dist/chunk-EK7NDGFR.js.map +1 -0
  40. package/dist/{chunk-5UDNP7AO.js → chunk-FZ6BXQHL.js} +78 -38
  41. package/dist/chunk-FZ6BXQHL.js.map +1 -0
  42. package/dist/{chunk-CM6BMECR.js → chunk-GRG7PHWQ.js} +2 -1
  43. package/dist/chunk-GRG7PHWQ.js.map +1 -0
  44. package/dist/chunk-KHHZTBP7.js +11 -0
  45. package/dist/chunk-KHHZTBP7.js.map +1 -0
  46. package/dist/chunk-KR2V42UZ.js +187 -0
  47. package/dist/chunk-KR2V42UZ.js.map +1 -0
  48. package/dist/chunk-MZLBPKFE.js +168 -0
  49. package/dist/chunk-MZLBPKFE.js.map +1 -0
  50. package/dist/{chunk-LW7OH6CS.js → chunk-NRMCVHAU.js} +6 -5
  51. package/dist/chunk-NRMCVHAU.js.map +1 -0
  52. package/dist/{chunk-TZ6YEYN4.js → chunk-NVJMJWLL.js} +3 -1
  53. package/dist/chunk-NVJMJWLL.js.map +1 -0
  54. package/dist/chunk-O77VSFYZ.js +70 -0
  55. package/dist/chunk-O77VSFYZ.js.map +1 -0
  56. package/dist/chunk-PX3VCKAU.js +29 -0
  57. package/dist/chunk-PX3VCKAU.js.map +1 -0
  58. package/dist/chunk-QR5D2IQC.js +61 -0
  59. package/dist/chunk-QR5D2IQC.js.map +1 -0
  60. package/dist/chunk-RJ76DRPO.js +117 -0
  61. package/dist/chunk-RJ76DRPO.js.map +1 -0
  62. package/dist/chunk-RKX3NQYS.js +28 -0
  63. package/dist/chunk-RKX3NQYS.js.map +1 -0
  64. package/dist/{chunk-JBCIY7QD.js → chunk-SIOU2K4U.js} +45 -22
  65. package/dist/chunk-SIOU2K4U.js.map +1 -0
  66. package/dist/chunk-TSCDAGET.js +75 -0
  67. package/dist/chunk-TSCDAGET.js.map +1 -0
  68. package/dist/{chunk-LSB7GRLG.js → chunk-TXTQIYCV.js} +15 -11
  69. package/dist/chunk-TXTQIYCV.js.map +1 -0
  70. package/dist/chunk-X7ETVO4P.js +26544 -0
  71. package/dist/chunk-X7ETVO4P.js.map +1 -0
  72. package/dist/{chunk-CADSX6UN.js → chunk-Y3KNXVTD.js} +2 -2
  73. package/dist/chunk-YBW5JSA3.js +251 -0
  74. package/dist/chunk-YBW5JSA3.js.map +1 -0
  75. package/dist/chunk-YRXAWWCU.js +45 -0
  76. package/dist/chunk-YRXAWWCU.js.map +1 -0
  77. package/dist/claude-provider-account-authority.d.ts +18 -0
  78. package/dist/claude-subscription-oauth.d.ts +42 -0
  79. package/dist/claude-subscription-usage.d.ts +159 -0
  80. package/dist/client-error-report.d.ts +109 -0
  81. package/dist/client-error-report.js +87 -0
  82. package/dist/client-error-report.js.map +1 -0
  83. package/dist/code-search.d.ts +52 -0
  84. package/dist/code-search.js +40 -0
  85. package/dist/code-search.js.map +1 -0
  86. package/dist/company-brain-governed-writes.d.ts +475 -0
  87. package/dist/company-brain.d.ts +336 -0
  88. package/dist/company-profile.d.ts +566 -0
  89. package/dist/connect.d.ts +325 -0
  90. package/dist/connect.js +191 -0
  91. package/dist/connect.js.map +1 -0
  92. package/dist/connection-account-label.d.ts +2 -0
  93. package/dist/connection-account-label.js +35 -0
  94. package/dist/connection-account-label.js.map +1 -0
  95. package/dist/connection-authority.d.ts +193 -0
  96. package/dist/connection-authority.js +50 -0
  97. package/dist/connection-authority.js.map +1 -0
  98. package/dist/connector-attachments.d.ts +95 -0
  99. package/dist/connector-attachments.js +51 -0
  100. package/dist/connector-attachments.js.map +1 -0
  101. package/dist/connector-tool-permissions.d.ts +73 -0
  102. package/dist/direct-model-provider.d.ts +36 -0
  103. package/dist/editable-artifact-codec-registry.d.ts +16 -7
  104. package/dist/editable-artifact-codec-registry.js +18 -8
  105. package/dist/editable-artifact-committed-transaction.d.ts +2 -2
  106. package/dist/editable-artifact-committed-transaction.js +2 -2
  107. package/dist/editable-artifact-live.d.ts +11 -12
  108. package/dist/editable-artifact-live.js +110 -45
  109. package/dist/editable-artifact-live.js.map +1 -1
  110. package/dist/editable-artifact-serialized-commit.d.ts +2 -1
  111. package/dist/editable-artifact-serialized-commit.js +8 -7
  112. package/dist/editable-artifact-versions.d.ts +20 -5
  113. package/dist/editable-artifact-versions.js +23 -5
  114. package/dist/editable-artifacts.d.ts +2 -0
  115. package/dist/editable-artifacts.js +47 -35
  116. package/dist/external-identities.d.ts +784 -0
  117. package/dist/external-identities.js +44 -0
  118. package/dist/external-identities.js.map +1 -0
  119. package/dist/feedback.d.ts +51 -0
  120. package/dist/github-repository-contracts.d.ts +36 -0
  121. package/dist/github-repository-contracts.js +59 -0
  122. package/dist/github-repository-contracts.js.map +1 -0
  123. package/dist/github-repository.d.ts +14 -0
  124. package/dist/github-repository.js +36 -0
  125. package/dist/github-repository.js.map +1 -0
  126. package/dist/google-drive.d.ts +90 -1
  127. package/dist/google-drive.js +90 -16
  128. package/dist/google-drive.js.map +1 -1
  129. package/dist/governed-learning-activation.d.ts +154 -0
  130. package/dist/governed-learning-evaluator.d.ts +152 -0
  131. package/dist/host-mcp-bindings.d.ts +326 -0
  132. package/dist/host-mcp-bindings.js +252 -0
  133. package/dist/host-mcp-bindings.js.map +1 -0
  134. package/dist/image-generation.d.ts +1 -0
  135. package/dist/index.d.ts +32396 -11386
  136. package/dist/index.js +2198 -164
  137. package/dist/insights-usage.d.ts +877 -0
  138. package/dist/insights-usage.js +509 -0
  139. package/dist/insights-usage.js.map +1 -0
  140. package/dist/interaction.d.ts +344 -0
  141. package/dist/knowledge-entries.d.ts +982 -0
  142. package/dist/knowledge-preparation.d.ts +237 -0
  143. package/dist/knowledge.d.ts +197 -0
  144. package/dist/managed-auth-session-sets.d.ts +241 -0
  145. package/dist/managed-auth-session-sets.js +191 -0
  146. package/dist/managed-auth-session-sets.js.map +1 -0
  147. package/dist/managed-sign-in-methods.d.ts +56 -0
  148. package/dist/managed-sign-in-methods.js +46 -0
  149. package/dist/managed-sign-in-methods.js.map +1 -0
  150. package/dist/mcp-catalog-limits.d.ts +2 -0
  151. package/dist/mcp-endpoint.d.ts +7 -0
  152. package/dist/mcp-endpoint.js +9 -0
  153. package/dist/mcp-endpoint.js.map +1 -0
  154. package/dist/mcp-oauth.d.ts +71 -0
  155. package/dist/modal-native-proof-v2.d.ts +587 -0
  156. package/dist/modal-native-proof-v2.js +37 -0
  157. package/dist/modal-native-proof-v2.js.map +1 -0
  158. package/dist/model-availability.d.ts +15 -0
  159. package/dist/model-connection-access.d.ts +24 -0
  160. package/dist/model-context-inspector.d.ts +329 -0
  161. package/dist/model-display.d.ts +38 -0
  162. package/dist/model-display.js +134 -0
  163. package/dist/model-display.js.map +1 -0
  164. package/dist/model-picker-order.d.ts +25 -0
  165. package/dist/model-picker-order.js +42 -0
  166. package/dist/model-picker-order.js.map +1 -0
  167. package/dist/organization-access.d.ts +231 -0
  168. package/dist/organization-access.js +34 -0
  169. package/dist/organization-access.js.map +1 -0
  170. package/dist/organization-integration-policy.d.ts +27 -0
  171. package/dist/organization-membership-lifecycle.d.ts +1022 -0
  172. package/dist/organization-model-usage.d.ts +146 -0
  173. package/dist/organization-model-usage.js +67 -0
  174. package/dist/organization-model-usage.js.map +1 -0
  175. package/dist/organization-recovery.d.ts +337 -0
  176. package/dist/organization-recovery.js +37 -0
  177. package/dist/organization-recovery.js.map +1 -0
  178. package/dist/organization-usage.d.ts +138 -0
  179. package/dist/permissions.d.ts +54 -0
  180. package/dist/personal-github.d.ts +320 -0
  181. package/dist/personal-github.js +222 -0
  182. package/dist/personal-github.js.map +1 -0
  183. package/dist/plugin-discovery.d.ts +35 -0
  184. package/dist/plugin-discovery.js +7 -0
  185. package/dist/plugin-discovery.js.map +1 -0
  186. package/dist/preference-registry.d.ts +44 -1
  187. package/dist/product-analytics.d.ts +113 -0
  188. package/dist/product-lifecycle-facts.d.ts +73 -0
  189. package/dist/remember.d.ts +350 -0
  190. package/dist/retained-output.d.ts +8 -0
  191. package/dist/sandbox-file-artifacts.d.ts +57 -0
  192. package/dist/sandbox-provider-command.d.ts +113 -0
  193. package/dist/sandbox-recovery.d.ts +146 -0
  194. package/dist/sandbox-snapshots.d.ts +39 -0
  195. package/dist/session-final-reply.d.ts +6 -0
  196. package/dist/session-final-reply.js +9 -0
  197. package/dist/session-final-reply.js.map +1 -0
  198. package/dist/session-goal-reports.d.ts +21 -0
  199. package/dist/session-history-import.d.ts +947 -0
  200. package/dist/session-list-entries.d.ts +4 -0
  201. package/dist/session-list-entries.js +51 -0
  202. package/dist/session-list-entries.js.map +1 -0
  203. package/dist/session-mcp-projections.d.ts +215 -0
  204. package/dist/session-message-search.d.ts +68 -0
  205. package/dist/session-titles.d.ts +68 -0
  206. package/dist/session-titles.js +25 -0
  207. package/dist/session-titles.js.map +1 -0
  208. package/dist/session-topology-primitives.d.ts +22 -0
  209. package/dist/signup-attribution.d.ts +39 -0
  210. package/dist/site-request-headers.test.d.ts +1 -0
  211. package/dist/site-session-http.d.ts +11 -0
  212. package/dist/site-session-http.js +11 -0
  213. package/dist/site-session-http.js.map +1 -0
  214. package/dist/skill-catalog-context.d.ts +7 -0
  215. package/dist/skill-files.d.ts +12 -0
  216. package/dist/skill-metadata.d.ts +9 -0
  217. package/dist/skill-use.d.ts +61 -0
  218. package/dist/skills.d.ts +185 -0
  219. package/dist/slack-bot-scopes.d.ts +46 -21
  220. package/dist/slack-bot-scopes.js +14 -3
  221. package/dist/slack-rest-mcp.d.ts +31 -0
  222. package/dist/slack-rest-mcp.js +19 -0
  223. package/dist/slack-rest-mcp.js.map +1 -0
  224. package/dist/spreadsheet-artifact-commands.d.ts +2 -3
  225. package/dist/spreadsheet-artifact-commands.js +4 -2
  226. package/dist/spreadsheet-artifact-query.js +3 -2
  227. package/dist/subscription-account-pools.d.ts +292 -0
  228. package/dist/task-notes.d.ts +42 -1
  229. package/dist/tool-catalog.d.ts +286 -0
  230. package/dist/tool-result-spill.d.ts +16 -0
  231. package/dist/usage-allowances.d.ts +285 -0
  232. package/dist/usage-allowances.js +49 -0
  233. package/dist/usage-allowances.js.map +1 -0
  234. package/dist/video-generation.d.ts +3 -0
  235. package/dist/video-generation.js +1 -1
  236. package/dist/work-claims.d.ts +411 -0
  237. package/dist/workspace-instruction-policies.d.ts +94 -0
  238. package/dist/workspace-integration-wire.d.ts +36 -0
  239. package/dist/workspace-integration-wire.js +23 -0
  240. package/dist/workspace-integration-wire.js.map +1 -0
  241. package/dist/workspace-integrations.d.ts +948 -0
  242. package/dist/workspace-learning-administration.d.ts +289 -0
  243. package/dist/workspace-learning-policy.d.ts +1 -1
  244. package/dist/workspace-state.d.ts +85 -416
  245. package/dist/xai-provider-account-authority.d.ts +3 -0
  246. package/dist/xai-provider-account-authority.js +1 -1
  247. package/package.json +134 -1
  248. package/src/agent-authored-durable-text.ts +116 -0
  249. package/src/agent-config.ts +1527 -0
  250. package/src/agent-instruction-changes.ts +98 -0
  251. package/src/agent-learning.ts +161 -0
  252. package/src/agent-topology.ts +69 -0
  253. package/src/allowance-refusal.ts +81 -0
  254. package/src/analytics-consent-report.ts +20 -0
  255. package/src/api-key-presets.ts +25 -0
  256. package/src/artifact-catalog.ts +60 -0
  257. package/src/artifacts.ts +146 -18
  258. package/src/atlassian-native-retirement.ts +33 -0
  259. package/src/browser-storage.ts +10 -0
  260. package/src/bundled-skills.ts +73 -0
  261. package/src/claude-provider-account-authority.ts +12 -0
  262. package/src/claude-subscription-oauth.ts +62 -0
  263. package/src/claude-subscription-usage.ts +59 -0
  264. package/src/client-error-report.ts +184 -0
  265. package/src/code-search.ts +105 -0
  266. package/src/company-brain-governed-writes.ts +356 -0
  267. package/src/company-brain.ts +201 -0
  268. package/src/company-profile.ts +167 -1
  269. package/src/connect.ts +202 -0
  270. package/src/connection-account-label.ts +46 -0
  271. package/src/connection-authority.ts +213 -0
  272. package/src/connector-attachments.ts +327 -0
  273. package/src/connector-tool-permissions.ts +60 -0
  274. package/src/direct-model-provider.ts +98 -0
  275. package/src/editable-artifact-codec-registry.ts +55 -17
  276. package/src/editable-artifact-committed-transaction.ts +44 -31
  277. package/src/editable-artifact-live.ts +123 -57
  278. package/src/editable-artifact-serialized-commit.ts +2 -1
  279. package/src/editable-artifact-versions.ts +26 -5
  280. package/src/editable-artifacts.ts +2 -0
  281. package/src/external-identities.ts +285 -0
  282. package/src/feedback.ts +39 -0
  283. package/src/github-repository-contracts.ts +85 -0
  284. package/src/github-repository.ts +59 -0
  285. package/src/google-drive.ts +76 -4
  286. package/src/governed-learning-activation.ts +191 -0
  287. package/src/governed-learning-evaluator.ts +176 -0
  288. package/src/host-mcp-bindings.ts +298 -0
  289. package/src/image-generation.ts +8 -2
  290. package/src/index.ts +7093 -1466
  291. package/src/insights-usage.ts +679 -0
  292. package/src/interaction.ts +220 -5
  293. package/src/knowledge-entries.ts +375 -0
  294. package/src/knowledge-preparation.ts +50 -0
  295. package/src/knowledge.ts +134 -6
  296. package/src/managed-auth-session-sets.ts +253 -0
  297. package/src/managed-sign-in-methods.ts +37 -0
  298. package/src/mcp-catalog-limits.ts +2 -0
  299. package/src/mcp-endpoint.ts +30 -0
  300. package/src/mcp-oauth.ts +66 -0
  301. package/src/modal-native-proof-v2.ts +398 -0
  302. package/src/model-availability.ts +22 -0
  303. package/src/model-connection-access.ts +17 -0
  304. package/src/model-context-inspector.ts +139 -0
  305. package/src/model-display.ts +195 -0
  306. package/src/model-picker-order.ts +97 -0
  307. package/src/organization-access.ts +176 -0
  308. package/src/organization-integration-policy.ts +54 -0
  309. package/src/organization-membership-lifecycle.ts +559 -0
  310. package/src/organization-model-usage.ts +72 -0
  311. package/src/organization-recovery.ts +186 -0
  312. package/src/organization-usage.ts +79 -0
  313. package/src/permissions.ts +58 -0
  314. package/src/personal-github.ts +267 -0
  315. package/src/plugin-discovery.ts +33 -0
  316. package/src/preference-registry.ts +20 -1
  317. package/src/product-analytics.ts +253 -0
  318. package/src/product-lifecycle-facts.ts +121 -0
  319. package/src/remember.ts +243 -0
  320. package/src/retained-output.ts +20 -3
  321. package/src/sandbox-file-artifacts.ts +73 -0
  322. package/src/sandbox-provider-command.ts +82 -0
  323. package/src/sandbox-recovery.ts +116 -0
  324. package/src/sandbox-snapshots.ts +142 -0
  325. package/src/session-final-reply.ts +16 -0
  326. package/src/session-goal-reports.ts +55 -0
  327. package/src/session-history-import.ts +159 -0
  328. package/src/session-list-entries.ts +91 -0
  329. package/src/session-mcp-projections.ts +273 -0
  330. package/src/session-message-search.ts +54 -0
  331. package/src/session-titles.ts +467 -0
  332. package/src/session-topology-primitives.ts +21 -0
  333. package/src/signup-attribution.ts +81 -0
  334. package/src/site-request-headers.test.ts +28 -0
  335. package/src/site-session-http.ts +63 -0
  336. package/src/skill-catalog-context.ts +50 -0
  337. package/src/skill-files.ts +52 -0
  338. package/src/skill-metadata.ts +40 -0
  339. package/src/skill-use.ts +77 -0
  340. package/src/skills.ts +136 -0
  341. package/src/slack-bot-scopes.ts +106 -42
  342. package/src/slack-rest-mcp.ts +194 -0
  343. package/src/spreadsheet-artifact-commands.ts +12 -13
  344. package/src/subscription-account-pools.ts +44 -0
  345. package/src/task-notes.ts +14 -1
  346. package/src/tool-catalog.ts +155 -0
  347. package/src/tool-result-spill.ts +35 -0
  348. package/src/usage-allowances.ts +187 -0
  349. package/src/work-claims.ts +266 -0
  350. package/src/workspace-instruction-policies.ts +31 -0
  351. package/src/workspace-integration-wire.ts +99 -0
  352. package/src/workspace-integrations.ts +640 -0
  353. package/src/workspace-learning-administration.ts +88 -0
  354. package/src/workspace-learning-policy.ts +4 -3
  355. package/src/workspace-state.ts +16 -126
  356. package/src/xai-provider-account-authority.ts +1 -0
  357. package/dist/chunk-5UDNP7AO.js.map +0 -1
  358. package/dist/chunk-BVGIYW7D.js +0 -11
  359. package/dist/chunk-BVGIYW7D.js.map +0 -1
  360. package/dist/chunk-CM6BMECR.js.map +0 -1
  361. package/dist/chunk-JBCIY7QD.js.map +0 -1
  362. package/dist/chunk-LSB7GRLG.js.map +0 -1
  363. package/dist/chunk-LW7OH6CS.js.map +0 -1
  364. package/dist/chunk-M5ZGRVIQ.js.map +0 -1
  365. package/dist/chunk-Q6A7XT2N.js +0 -16734
  366. package/dist/chunk-Q6A7XT2N.js.map +0 -1
  367. package/dist/chunk-TZ6YEYN4.js.map +0 -1
  368. package/dist/chunk-Y3MLSLB4.js.map +0 -1
  369. /package/dist/{chunk-CADSX6UN.js.map → chunk-Y3KNXVTD.js.map} +0 -0
@@ -0,0 +1,194 @@
1
+ /** The catalog and OAuth identity stay stable while calls use the ordinary Web API. */
2
+ export const OFFICIAL_SLACK_MCP_URL = "https://mcp.slack.com/mcp";
3
+ export const SLACK_REST_API_BASE = "https://slack.com/api/";
4
+
5
+ export const OPENGENI_SLACK_REST_USER_SCOPES = [
6
+ "channels:read",
7
+ "groups:read",
8
+ "im:read",
9
+ "mpim:read",
10
+ "channels:history",
11
+ "groups:history",
12
+ "im:history",
13
+ "mpim:history",
14
+ "users:read",
15
+ "im:write",
16
+ "chat:write",
17
+ ] as const;
18
+
19
+ /** Slack returns comma-delimited scopes, including in existing saved grants. */
20
+ export function normalizeSlackScopes(
21
+ scopes: readonly string[] | string | undefined | null,
22
+ ): string[] {
23
+ return [
24
+ ...new Set(
25
+ (typeof scopes === "string" ? [scopes] : (scopes ?? []))
26
+ .flatMap((entry) => entry.split(/[\s,]+/u))
27
+ .filter(Boolean),
28
+ ),
29
+ ].sort();
30
+ }
31
+
32
+ export type SlackRestMcpTool = {
33
+ name: string;
34
+ description: string;
35
+ inputSchema: {
36
+ type: "object";
37
+ properties: Record<string, unknown>;
38
+ required: string[];
39
+ additionalProperties: false;
40
+ };
41
+ annotations: {
42
+ readOnlyHint: boolean;
43
+ destructiveHint: false;
44
+ idempotentHint: boolean;
45
+ openWorldHint: true;
46
+ };
47
+ };
48
+
49
+ const conversationScopes = ["channels:read", "groups:read", "im:read", "mpim:read"];
50
+ const historyScopes = ["channels:history", "groups:history", "im:history", "mpim:history"];
51
+ const channel = { type: "string", description: "Slack conversation ID, such as C123 or D123." };
52
+ const cursor = { type: "string", maxLength: 4096, description: "Cursor from the previous page." };
53
+ const directoryPage = { type: "integer", minimum: 1, maximum: 100, default: 100 };
54
+ const historyPage = { type: "integer", minimum: 1, maximum: 15, default: 15 };
55
+ const timestamp = { type: "string", pattern: "^[0-9]+\\.[0-9]+$" };
56
+
57
+ function tool(
58
+ name: string,
59
+ description: string,
60
+ properties: Record<string, unknown>,
61
+ required: string[] = [],
62
+ mutation = false,
63
+ ): SlackRestMcpTool {
64
+ return {
65
+ name,
66
+ description,
67
+ inputSchema: { type: "object", properties, required, additionalProperties: false },
68
+ annotations: {
69
+ readOnlyHint: !mutation,
70
+ destructiveHint: false,
71
+ idempotentHint: !mutation,
72
+ openWorldHint: true,
73
+ },
74
+ };
75
+ }
76
+
77
+ /** Static reviewed pilot surface. Each call reads only one explicitly requested page. */
78
+ export const SLACK_REST_MCP_TOOLS: SlackRestMcpTool[] = [
79
+ tool(
80
+ "slack_list_channels",
81
+ "Lists one page of conversations visible to your connected Slack account. Conversation types without a granted read scope are omitted.",
82
+ {
83
+ types: {
84
+ type: "array",
85
+ items: { type: "string", enum: ["public_channel", "private_channel", "im", "mpim"] },
86
+ minItems: 1,
87
+ maxItems: 4,
88
+ },
89
+ cursor,
90
+ limit: directoryPage,
91
+ exclude_archived: { type: "boolean", default: true },
92
+ },
93
+ ),
94
+ tool(
95
+ "slack_get_channel_info",
96
+ "Gets metadata for one conversation visible to your connected Slack account.",
97
+ { channel },
98
+ ["channel"],
99
+ ),
100
+ tool(
101
+ "slack_list_channel_members",
102
+ "Lists one page of members in a visible channel or group conversation.",
103
+ { channel, cursor, limit: directoryPage },
104
+ ["channel"],
105
+ ),
106
+ tool("slack_list_users", "Lists one page of users in the connected Slack workspace.", {
107
+ cursor,
108
+ limit: directoryPage,
109
+ }),
110
+ tool(
111
+ "slack_get_user_info",
112
+ "Gets a user's profile by their Slack user ID. Email is included only when Slack has granted that scope.",
113
+ { user: { type: "string" } },
114
+ ["user"],
115
+ ),
116
+ tool(
117
+ "slack_read_channel",
118
+ "Reads one page of at most 15 messages from a selected conversation. Slack history limits are shared across the workspace. No automatic pagination or backfill.",
119
+ {
120
+ channel,
121
+ cursor,
122
+ limit: historyPage,
123
+ oldest: timestamp,
124
+ latest: timestamp,
125
+ inclusive: { type: "boolean", default: false },
126
+ },
127
+ ["channel"],
128
+ ),
129
+ tool(
130
+ "slack_read_thread",
131
+ "Reads one page of at most 15 messages in a selected thread. Slack thread limits are shared across the workspace. No automatic pagination or backfill.",
132
+ {
133
+ channel,
134
+ ts: { ...timestamp, description: "Thread root message timestamp." },
135
+ cursor,
136
+ limit: historyPage,
137
+ },
138
+ ["channel", "ts"],
139
+ ),
140
+ tool(
141
+ "slack_open_dm",
142
+ "Opens or resumes a direct message with one Slack user as your connected account.",
143
+ { user: { type: "string" } },
144
+ ["user"],
145
+ true,
146
+ ),
147
+ tool(
148
+ "slack_send_message",
149
+ "Sends a message as your connected Slack account. Supply thread_ts to reply in a thread. Review the recipient and text before approving. An uncertain submission is never automatically retried.",
150
+ {
151
+ channel,
152
+ text: { type: "string", minLength: 1, maxLength: 40000 },
153
+ thread_ts: { ...timestamp, description: "Optional thread root timestamp for a reply." },
154
+ unfurl_links: { type: "boolean", default: false },
155
+ unfurl_media: { type: "boolean", default: false },
156
+ },
157
+ ["channel", "text"],
158
+ true,
159
+ ),
160
+ ];
161
+
162
+ const REQUIRED_ANY_SCOPES: Readonly<Record<string, readonly string[]>> = {
163
+ slack_list_channels: conversationScopes,
164
+ slack_get_channel_info: conversationScopes,
165
+ slack_list_channel_members: ["channels:read", "groups:read", "mpim:read"],
166
+ slack_list_users: ["users:read"],
167
+ slack_get_user_info: ["users:read"],
168
+ slack_read_channel: historyScopes,
169
+ slack_read_thread: historyScopes,
170
+ slack_open_dm: ["im:write"],
171
+ slack_send_message: ["chat:write"],
172
+ };
173
+
174
+ export function slackRestMcpToolsForScopes(scopes: readonly string[] | string): SlackRestMcpTool[] {
175
+ const granted = new Set(normalizeSlackScopes(scopes));
176
+ return SLACK_REST_MCP_TOOLS.filter((entry) =>
177
+ REQUIRED_ANY_SCOPES[entry.name]?.some((scope) => granted.has(scope)),
178
+ ).map((entry) => ({
179
+ ...entry,
180
+ inputSchema: {
181
+ ...entry.inputSchema,
182
+ required: [...entry.inputSchema.required],
183
+ properties: { ...entry.inputSchema.properties },
184
+ },
185
+ annotations: { ...entry.annotations },
186
+ }));
187
+ }
188
+
189
+ export const SLACK_CONVERSATION_READ_SCOPE_BY_TYPE = {
190
+ public_channel: "channels:read",
191
+ private_channel: "groups:read",
192
+ im: "im:read",
193
+ mpim: "mpim:read",
194
+ } as const;
@@ -2,6 +2,7 @@ import {
2
2
  canonicalSpreadsheetDateFromMilliseconds,
3
3
  canonicalSpreadsheetDateMilliseconds,
4
4
  } from "./spreadsheet-artifact-date";
5
+ import { SPREADSHEET_ARTIFACT_COMMAND_VERSION } from "./editable-artifact-versions";
5
6
 
6
7
  /**
7
8
  * Canonical, identity-free spreadsheet mutation commands nested inside
@@ -10,14 +11,14 @@ import {
10
11
  * authority.
11
12
  */
12
13
 
13
- export const SPREADSHEET_ARTIFACT_COMMAND_VERSION = 1 as const;
14
+ export { SPREADSHEET_ARTIFACT_COMMAND_VERSION } from "./editable-artifact-versions";
14
15
  export const SPREADSHEET_ARTIFACT_COMMAND_MAX_BYTES = 4 * 1024 * 1024;
15
16
  export const SPREADSHEET_ARTIFACT_COMMAND_MAX_COMMANDS = 4_096;
16
17
  export const SPREADSHEET_ARTIFACT_COMMAND_MAX_CELLS = 1_000_000;
17
18
  export const SPREADSHEET_ARTIFACT_COMMAND_MAX_STRING_BYTES = 1 * 1024 * 1024;
18
19
  export const SPREADSHEET_ARTIFACT_SHEET_NAME_MAX_UTF16_UNITS = 31;
19
20
 
20
- const MAGIC = new TextEncoder().encode("OGASC001");
21
+ const MAGIC = new TextEncoder().encode("OGASC002");
21
22
  const HEADER_BYTES = 8 + 2 + 2 + 4 + 8;
22
23
  const CHECKSUM_BYTES = 8;
23
24
  const textEncoder = new TextEncoder();
@@ -78,7 +79,6 @@ export type SpreadsheetCellScalar =
78
79
  | SpreadsheetFormulaError;
79
80
  export type SpreadsheetFormulaCell = Readonly<{
80
81
  formula: string;
81
- cached: SpreadsheetCellScalar;
82
82
  }>;
83
83
  export type SpreadsheetCellInput = SpreadsheetCellScalar | SpreadsheetFormulaCell;
84
84
 
@@ -491,7 +491,7 @@ function batchRecord(input: unknown): SpreadsheetArtifactCommandBatch {
491
491
  const batch = plainRecord(input, "spreadsheet command batch");
492
492
  exactKeys(batch, ["commands", "version"], "spreadsheet command batch");
493
493
  if (batch.version !== SPREADSHEET_ARTIFACT_COMMAND_VERSION) {
494
- throw new TypeError("spreadsheet command batch version must be 1");
494
+ throw new TypeError("spreadsheet command batch version must be 2");
495
495
  }
496
496
  if (!Array.isArray(batch.commands)) throw new TypeError("commands must be an array");
497
497
  if (
@@ -770,13 +770,12 @@ class BinaryWriter {
770
770
  cell(value: unknown): void {
771
771
  if (isFormulaCell(value)) {
772
772
  const cell = plainRecord(value, "formula cell");
773
- exactKeys(cell, ["cached", "formula"], "formula cell");
773
+ exactKeys(cell, ["formula"], "formula cell");
774
774
  if (typeof cell.formula !== "string" || cell.formula.length === 0) {
775
775
  throw new TypeError("formula source must be a nonempty string");
776
776
  }
777
777
  this.u8(1);
778
778
  this.string(cell.formula, SPREADSHEET_ARTIFACT_COMMAND_MAX_STRING_BYTES);
779
- this.scalar(cell.cached);
780
779
  return;
781
780
  }
782
781
  this.u8(0);
@@ -902,12 +901,12 @@ class BinaryReader {
902
901
  cell(): SpreadsheetCellInput {
903
902
  const formulaTag = this.u8();
904
903
  if (formulaTag > 1) throw new TypeError("spreadsheet formula presence tag is invalid");
905
- const formula =
906
- formulaTag === 1
907
- ? this.nonemptyFormula(this.string(SPREADSHEET_ARTIFACT_COMMAND_MAX_STRING_BYTES))
908
- : null;
909
- const cached = this.scalar();
910
- return formula === null ? cached : Object.freeze({ formula, cached });
904
+ if (formulaTag === 1) {
905
+ return Object.freeze({
906
+ formula: this.nonemptyFormula(this.string(SPREADSHEET_ARTIFACT_COMMAND_MAX_STRING_BYTES)),
907
+ });
908
+ }
909
+ return this.scalar();
911
910
  }
912
911
 
913
912
  done(message: string): void {
@@ -981,7 +980,7 @@ function isFormulaError(value: unknown): value is SpreadsheetFormulaError {
981
980
  typeof value === "object" &&
982
981
  value !== null &&
983
982
  !Array.isArray(value) &&
984
- typeof (value as Record<string, unknown>).error === "string"
983
+ Object.hasOwn(value, "error")
985
984
  );
986
985
  }
987
986
 
@@ -0,0 +1,44 @@
1
+ import { z } from "zod";
2
+ import { ClaudeSubscriptionUsage } from "./claude-subscription-usage";
3
+
4
+ /** Shared, secret-free account list contract for native subscription pools. */
5
+ export const SubscriptionAccountSummary = z.object({
6
+ id: z.string().uuid(),
7
+ scope: z.enum(["organization", "workspace", "user"]),
8
+ subject: z.string().min(1),
9
+ email: z.string().email().nullable(),
10
+ label: z.string().nullable(),
11
+ plan: z.string().nullable(),
12
+ status: z.enum(["active", "needs_relogin", "error", "disabled"]),
13
+ active: z.boolean(),
14
+ expiresAt: z.string().datetime().nullable(),
15
+ lastRefreshAt: z.string().datetime().nullable(),
16
+ lastError: z.string().nullable(),
17
+ allocatorEnabled: z.boolean(),
18
+ allocatorVersion: z.number().int().positive(),
19
+ allocatorUpdatedAt: z.string().datetime().nullable(),
20
+ });
21
+ export type SubscriptionAccountSummary = z.infer<typeof SubscriptionAccountSummary>;
22
+ export const SubscriptionPoolSettings = z
23
+ .object({
24
+ rotationEnabled: z.boolean(),
25
+ rotationStrategy: z.literal("sharded"),
26
+ activeCredentialId: z.string().uuid().nullable(),
27
+ })
28
+ .strict();
29
+ export type SubscriptionPoolSettings = z.infer<typeof SubscriptionPoolSettings>;
30
+ export const ClaudeSubscriptionAccount = SubscriptionAccountSummary.extend({
31
+ version: z.number().int().positive(),
32
+ usage: ClaudeSubscriptionUsage.optional(),
33
+ }).strict();
34
+ export type ClaudeSubscriptionAccount = z.infer<typeof ClaudeSubscriptionAccount>;
35
+ export const ClaudeSubscriptionAccountsResponse = z
36
+ .object({
37
+ accounts: z.array(ClaudeSubscriptionAccount),
38
+ activeAccountId: z.string().uuid().nullable(),
39
+ source: z.enum(["organization", "workspace", "user"]),
40
+ organizationId: z.string().uuid(),
41
+ settings: SubscriptionPoolSettings,
42
+ })
43
+ .strict();
44
+ export type ClaudeSubscriptionAccountsResponse = z.infer<typeof ClaudeSubscriptionAccountsResponse>;
package/src/task-notes.ts CHANGED
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
 
3
3
  export const TASK_NOTE_TEXT_MAX_BYTES = 4_096;
4
4
  export const TASK_NOTE_REASON_MAX_BYTES = 2_048;
5
- export const TASK_NOTE_MAX_LIFETIME_DAYS = 30;
5
+ export const TASK_NOTE_MAX_LIFETIME_DAYS = 90;
6
6
  export const TASK_NOTE_ACTIVE_RECORD_CAP = 500;
7
7
  export const TASK_NOTE_LIST_DEFAULT_LIMIT = 10;
8
8
  export const TASK_NOTE_LIST_MAX_LIMIT = 20;
@@ -77,6 +77,19 @@ export const TaskNoteMutationResult = z.object({
77
77
  });
78
78
  export type TaskNoteMutationResult = z.infer<typeof TaskNoteMutationResult>;
79
79
 
80
+ /** Atomic correction lineage: archive one exact v1 note and create one v1 replacement. */
81
+ export const TaskNoteReplacementResult = z.object({
82
+ operationId: z.string().uuid(),
83
+ inputHash: z.string().regex(/^[0-9a-f]{64}$/),
84
+ replaces: z.object({
85
+ noteId: z.string().uuid(),
86
+ archivedVersion: z.literal(2),
87
+ }),
88
+ replacement: TaskNote,
89
+ replayed: z.boolean(),
90
+ });
91
+ export type TaskNoteReplacementResult = z.infer<typeof TaskNoteReplacementResult>;
92
+
80
93
  export const TaskNoteListResponse = z
81
94
  .object({
82
95
  notes: z.array(TaskNote).max(TASK_NOTE_LIST_MAX_LIMIT),
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
 
3
3
  export const ATTEMPT_TOOL_CATALOG_VERSION = 1 as const;
4
+ export const TOOL_GATEWAY_CATALOG_VERSION = 1 as const;
4
5
  export const ATTEMPT_TOOL_CATALOG_MAX_ENTRIES = 4_096;
5
6
  export const ATTEMPT_TOOL_CATALOG_MAX_BYTES = 16 * 1024 * 1024;
6
7
  export const ATTEMPT_TOOL_CATALOG_MAX_PATH_SEGMENTS = 8;
@@ -43,6 +44,10 @@ export const AttemptToolIdentity = z
43
44
  .strict();
44
45
  export type AttemptToolIdentity = z.infer<typeof AttemptToolIdentity>;
45
46
 
47
+ /** Protocol-neutral tool identity shared by MCP, HTTP/SDK, agents, and Codemode. */
48
+ export const ToolGatewayIdentity = AttemptToolIdentity;
49
+ export type ToolGatewayIdentity = AttemptToolIdentity;
50
+
46
51
  export const AttemptToolCatalogIcon = z
47
52
  .object({
48
53
  src: z.string().min(1).max(8_192),
@@ -69,6 +74,16 @@ export type AttemptToolAnnotations = z.infer<typeof AttemptToolAnnotations>;
69
74
  export const AttemptToolJsonSchema = jsonObject;
70
75
  export type AttemptToolJsonSchema = z.infer<typeof AttemptToolJsonSchema>;
71
76
 
77
+ /** Presentation only; never parsed as execution or account authority. */
78
+ export const ToolDisplayMetadata = z
79
+ .object({
80
+ toolName: toolIdentifier,
81
+ title: z.string().min(1).max(512).optional(),
82
+ accountLabel: z.string().min(1).max(1024).optional(),
83
+ })
84
+ .strict();
85
+ export type ToolDisplayMetadata = z.infer<typeof ToolDisplayMetadata>;
86
+
72
87
  export const AttemptToolCatalogEntry = z
73
88
  .object({
74
89
  identity: AttemptToolIdentity,
@@ -88,6 +103,73 @@ export const AttemptToolCatalogEntry = z
88
103
  .strict();
89
104
  export type AttemptToolCatalogEntry = z.infer<typeof AttemptToolCatalogEntry>;
90
105
 
106
+ /** One canonical gateway entry. Adapter-specific names are projections, never authority. */
107
+ export const ToolGatewayCatalogEntry = AttemptToolCatalogEntry;
108
+ export type ToolGatewayCatalogEntry = AttemptToolCatalogEntry;
109
+
110
+ export const ToolGatewayCatalog = z
111
+ .object({
112
+ version: z.literal(TOOL_GATEWAY_CATALOG_VERSION),
113
+ accountId: z.string().uuid(),
114
+ workspaceId: z.string().uuid(),
115
+ generation: z.number().int().positive(),
116
+ digest: sha256,
117
+ createdAt: z.string().datetime({ offset: true }),
118
+ entries: z.array(ToolGatewayCatalogEntry).max(ATTEMPT_TOOL_CATALOG_MAX_ENTRIES),
119
+ })
120
+ .strict()
121
+ .superRefine((catalog, context) => {
122
+ const identities = new Set<string>();
123
+ const modelNames = new Set<string>();
124
+ const toolPaths = new Set<string>();
125
+ for (const [index, entry] of catalog.entries.entries()) {
126
+ const identity = `${entry.identity.serverId}\u0000${entry.identity.toolName}`;
127
+ const toolPath = entry.codemodePath.join(".");
128
+ if (identities.has(identity)) {
129
+ context.addIssue({
130
+ code: "custom",
131
+ path: ["entries", index, "identity"],
132
+ message: "duplicate tool identity",
133
+ });
134
+ }
135
+ if (modelNames.has(entry.modelName)) {
136
+ context.addIssue({
137
+ code: "custom",
138
+ path: ["entries", index, "modelName"],
139
+ message: "duplicate model tool name",
140
+ });
141
+ }
142
+ if (toolPaths.has(toolPath)) {
143
+ context.addIssue({
144
+ code: "custom",
145
+ path: ["entries", index, "codemodePath"],
146
+ message: "duplicate tool path",
147
+ });
148
+ }
149
+ identities.add(identity);
150
+ modelNames.add(entry.modelName);
151
+ toolPaths.add(toolPath);
152
+ }
153
+ });
154
+ export type ToolGatewayCatalog = z.infer<typeof ToolGatewayCatalog>;
155
+
156
+ export const ToolGatewayCaller = z
157
+ .object({
158
+ kind: z.enum(["model", "codemode", "http", "mcp", "browser"]),
159
+ subjectId: z.string().min(1).max(1_024),
160
+ })
161
+ .strict();
162
+ export type ToolGatewayCaller = z.infer<typeof ToolGatewayCaller>;
163
+
164
+ /**
165
+ * MCP request `_meta` key naming the attempt surface that issued a call to the
166
+ * first-party server: `model` for a direct model tool call, `codemode` for a
167
+ * Codemode script. Only the worker's own tool gateway sets it, and only for the
168
+ * first-party server. A read reached the model's context only when it says
169
+ * `model`; a Codemode script may keep the output to itself.
170
+ */
171
+ export const FIRST_PARTY_MCP_CALLER_META_KEY = "opengeniCaller";
172
+
91
173
  export const AttemptToolCatalog = z
92
174
  .object({
93
175
  version: z.literal(ATTEMPT_TOOL_CATALOG_VERSION),
@@ -251,6 +333,79 @@ export const AttemptToolResult = z
251
333
  .loose();
252
334
  export type AttemptToolResult = z.infer<typeof AttemptToolResult>;
253
335
 
336
+ export const ToolGatewayResult = AttemptToolResult;
337
+ export type ToolGatewayResult = AttemptToolResult;
338
+
339
+ export const ToolGatewayCallRequest = z
340
+ .object({
341
+ operationId: z.string().uuid().optional(),
342
+ catalogDigest: sha256,
343
+ identity: ToolGatewayIdentity,
344
+ arguments: jsonObject,
345
+ /** Host-owned Site context. Publisher-controlled iframe code cannot set it. */
346
+ siteArtifactId: z.string().uuid().optional(),
347
+ siteVersionId: z.string().uuid().optional(),
348
+ /** Opaque, server-issued, single-use capability for an approval-required call. */
349
+ approvalToken: z
350
+ .string()
351
+ .regex(/^ogta_[A-Za-z0-9_-]{43}$/u)
352
+ .optional(),
353
+ })
354
+ .strict()
355
+ .superRefine(requireCompleteSiteToolContext);
356
+ export type ToolGatewayCallRequest = z.infer<typeof ToolGatewayCallRequest>;
357
+
358
+ export const ToolGatewayApprovalRequest = z
359
+ .object({
360
+ operationId: z.string().uuid(),
361
+ catalogDigest: sha256,
362
+ identity: ToolGatewayIdentity,
363
+ arguments: jsonObject,
364
+ })
365
+ .strict();
366
+ export type ToolGatewayApprovalRequest = z.infer<typeof ToolGatewayApprovalRequest>;
367
+
368
+ export const ToolGatewayApprovalResponse = z
369
+ .object({
370
+ operationId: z.string().uuid(),
371
+ catalogDigest: sha256,
372
+ identity: ToolGatewayIdentity,
373
+ approvalToken: z.string().regex(/^ogta_[A-Za-z0-9_-]{43}$/u),
374
+ expiresAt: z.string().datetime({ offset: true }),
375
+ })
376
+ .strict();
377
+ export type ToolGatewayApprovalResponse = z.infer<typeof ToolGatewayApprovalResponse>;
378
+
379
+ export const ToolGatewayCallResponse = z
380
+ .object({
381
+ operationId: z.string().uuid(),
382
+ catalogDigest: sha256,
383
+ result: ToolGatewayResult,
384
+ })
385
+ .strict();
386
+ export type ToolGatewayCallResponse = z.infer<typeof ToolGatewayCallResponse>;
387
+
388
+ export const ToolGatewayDeclarationsResponse = z
389
+ .object({
390
+ catalogDigest: sha256,
391
+ moduleSpecifier: z.string().min(1).max(512),
392
+ source: z.string().max(16 * 1024 * 1024),
393
+ })
394
+ .strict();
395
+ export type ToolGatewayDeclarationsResponse = z.infer<typeof ToolGatewayDeclarationsResponse>;
396
+
397
+ function requireCompleteSiteToolContext(
398
+ value: { siteArtifactId?: string | undefined; siteVersionId?: string | undefined },
399
+ context: z.RefinementCtx,
400
+ ): void {
401
+ if ((value.siteArtifactId === undefined) === (value.siteVersionId === undefined)) return;
402
+ context.addIssue({
403
+ code: "custom",
404
+ message: "siteArtifactId and siteVersionId must be provided together",
405
+ path: [value.siteArtifactId === undefined ? "siteArtifactId" : "siteVersionId"],
406
+ });
407
+ }
408
+
254
409
  export const CodemodeOperationState = z.enum([
255
410
  "queued",
256
411
  "running",
@@ -0,0 +1,35 @@
1
+ import { z } from "zod";
2
+
3
+ /** Model-visible overflow of one tool result. Exact bytes live on a workspace File. */
4
+ export const TOOL_RESULT_SPILLED_TYPE = "tool_result_spilled" as const;
5
+ export const TOOL_RESULT_SPILL_MEDIA_TYPE = "application/json" as const;
6
+ export const TOOL_RESULT_SPILL_MOUNT_PATH = "tool-results" as const;
7
+
8
+ const LOWERCASE_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
9
+
10
+ export const ToolResultSpilledReceipt = z
11
+ .object({
12
+ type: z.literal(TOOL_RESULT_SPILLED_TYPE),
13
+ sandboxPath: z.string().min(1).max(4_096).nullable(),
14
+ fileId: z.string().regex(LOWERCASE_UUID),
15
+ byteSize: z.number().int().positive().safe(),
16
+ mediaType: z.literal(TOOL_RESULT_SPILL_MEDIA_TYPE),
17
+ })
18
+ .strict();
19
+ export type ToolResultSpilledReceipt = z.infer<typeof ToolResultSpilledReceipt>;
20
+
21
+ export function isToolResultSpilledReceipt(value: unknown): value is ToolResultSpilledReceipt {
22
+ return ToolResultSpilledReceipt.safeParse(value).success;
23
+ }
24
+
25
+ export function toolResultSpillSandboxPath(filename: string): string {
26
+ return `/workspace/${TOOL_RESULT_SPILL_MOUNT_PATH}/${filename}`;
27
+ }
28
+
29
+ export function toolResultSpillFilename(operationId: string): string {
30
+ const normalized = operationId.toLowerCase();
31
+ if (!LOWERCASE_UUID.test(normalized)) {
32
+ throw new Error("tool result spill filename requires a lowercase UUID operation id");
33
+ }
34
+ return `${normalized}.json`;
35
+ }