@opengeni/api-router 0.30.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 (436) hide show
  1. package/dist/access-grant-rls.d.ts +3 -0
  2. package/dist/admission-trace.d.ts +8 -0
  3. package/dist/api-websocket.d.ts +18 -0
  4. package/dist/app.d.ts +50 -2
  5. package/dist/app.js +12 -1
  6. package/dist/artifact-catalog-cursor.d.ts +27 -0
  7. package/dist/auth/managed-auth-attempt-context.d.ts +10 -0
  8. package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
  9. package/dist/auth/managed-auth-session-adapter.d.ts +6 -0
  10. package/dist/auth/managed-auth.d.ts +102 -3
  11. package/dist/auth/managed-email.d.ts +29 -0
  12. package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
  13. package/dist/auth/new-signups-gate.d.ts +23 -0
  14. package/dist/auth/organization-user-setup.d.ts +80 -0
  15. package/dist/auth/signup-funnel-metrics.d.ts +44 -0
  16. package/dist/browser-controller-authority.d.ts +1 -61
  17. package/dist/browser-ephemeral.d.ts +5 -0
  18. package/dist/browser-state-authority.d.ts +1 -27
  19. package/dist/chunk-6TZ5LG3O.js +123948 -0
  20. package/dist/chunk-6TZ5LG3O.js.map +1 -0
  21. package/dist/chunk-OGQDXVXY.js +18 -0
  22. package/dist/chunk-OGQDXVXY.js.map +1 -0
  23. package/dist/claude-subscription-account-conflicts.d.ts +1 -0
  24. package/dist/claude-subscription-account-usage.d.ts +39 -0
  25. package/dist/claude-subscription-oauth.d.ts +25 -0
  26. package/dist/claude-subscription-profile.d.ts +9 -0
  27. package/dist/claude-subscription-usage.d.ts +44 -0
  28. package/dist/claude-workspace-connection.d.ts +15 -0
  29. package/dist/codemode.d.ts +32 -1
  30. package/dist/company-brain-okf.d.ts +24 -0
  31. package/dist/connected-machine-computer-access.d.ts +11 -0
  32. package/dist/connection-ownership.d.ts +54 -0
  33. package/dist/controller-data-plane.d.ts +32 -0
  34. package/dist/editable-artifact-office-import.d.ts +7 -4
  35. package/dist/editable-artifact-source-session.d.ts +3 -0
  36. package/dist/editable-artifact-websocket.d.ts +10 -18
  37. package/dist/editable-artifact-workspace-files.d.ts +1 -1
  38. package/dist/fatal-process-boundary.d.ts +25 -0
  39. package/dist/github-access.d.ts +31 -2
  40. package/dist/http/acting-person.d.ts +24 -0
  41. package/dist/http/api-contract-compat.d.ts +19 -0
  42. package/dist/http/api-error.d.ts +27 -1
  43. package/dist/http/cors.d.ts +17 -0
  44. package/dist/http/deprecation.d.ts +42 -0
  45. package/dist/http/interaction-control-error.d.ts +13 -0
  46. package/dist/http/keyed-admission.d.ts +12 -0
  47. package/dist/http/local-browser-boundary.d.ts +72 -0
  48. package/dist/http/metrics-listener.d.ts +22 -0
  49. package/dist/http/path-identifier.d.ts +17 -0
  50. package/dist/http/registered-route-label.d.ts +16 -0
  51. package/dist/http/request-body.d.ts +27 -0
  52. package/dist/http/request-source.d.ts +52 -0
  53. package/dist/http/sse.d.ts +17 -6
  54. package/dist/http/unmatched-route.d.ts +18 -0
  55. package/dist/http/user-content.d.ts +36 -0
  56. package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
  57. package/dist/index.d.ts +10 -3
  58. package/dist/index.js +1129 -166
  59. package/dist/index.js.map +1 -1
  60. package/dist/integration-endpoint-test.d.ts +20 -0
  61. package/dist/integrations/api-integrations.d.ts +2 -2
  62. package/dist/integrations/atlassian.d.ts +29 -3
  63. package/dist/integrations/connect-authority.d.ts +1 -0
  64. package/dist/integrations/connect-callback-return.d.ts +6 -0
  65. package/dist/integrations/fiken.d.ts +16 -2
  66. package/dist/integrations/github-app-connect.d.ts +47 -0
  67. package/dist/integrations/github-installation-proof.d.ts +3 -0
  68. package/dist/integrations/github-lens-connect.d.ts +116 -0
  69. package/dist/integrations/github-skill-source.d.ts +1 -5
  70. package/dist/integrations/google-drive.d.ts +25 -0
  71. package/dist/integrations/integration-commit-authority.d.ts +13 -0
  72. package/dist/integrations/marketplace-plugin.d.ts +2691 -0
  73. package/dist/integrations/oauth-client.d.ts +178 -18
  74. package/dist/integrations/oauth-profiles.d.ts +222 -0
  75. package/dist/integrations/oauth-return-path.d.ts +1 -0
  76. package/dist/integrations/personal-github-repositories.d.ts +84 -0
  77. package/dist/integrations/personal-github.d.ts +42 -0
  78. package/dist/integrations/pr-review-provider.d.ts +22 -0
  79. package/dist/integrations/provider-oauth.d.ts +19 -1
  80. package/dist/integrations/slack-app-home.d.ts +24 -0
  81. package/dist/integrations/slack-bot.d.ts +367 -12
  82. package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
  83. package/dist/integrations/slack-install.d.ts +20 -0
  84. package/dist/integrations/slack-interactions.d.ts +113 -10
  85. package/dist/integrations/slack-mrkdwn.d.ts +41 -0
  86. package/dist/integrations/slack-routing.d.ts +120 -0
  87. package/dist/integrations/slack-session-defaults.d.ts +58 -0
  88. package/dist/integrations/slack-task-file-upload.d.ts +36 -0
  89. package/dist/integrations/social-oauth.d.ts +7 -0
  90. package/dist/interaction-agent-access.d.ts +15 -0
  91. package/dist/interaction-frame-proxy.d.ts +68 -0
  92. package/dist/interaction-metrics.d.ts +2 -0
  93. package/dist/mcp/action-catalog-types.d.ts +9 -0
  94. package/dist/mcp/action-catalog.gen.d.ts +2 -0
  95. package/dist/mcp/capability-account-readiness.d.ts +7 -0
  96. package/dist/mcp/child-read-evidence.d.ts +9 -0
  97. package/dist/mcp/command-read.d.ts +24 -0
  98. package/dist/mcp/company-profile-agent-admin.d.ts +44 -0
  99. package/dist/mcp/contract-input.d.ts +11 -0
  100. package/dist/mcp/documents.d.ts +7 -5
  101. package/dist/mcp/files.d.ts +2 -2
  102. package/dist/mcp/first-party-tool-permissions.d.ts +650 -0
  103. package/dist/mcp/knowledge-entries.d.ts +5 -0
  104. package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
  105. package/dist/mcp/receipts.d.ts +9 -0
  106. package/dist/mcp/request-abort.d.ts +19 -0
  107. package/dist/mcp/scheduled-task-input.d.ts +1189 -0
  108. package/dist/mcp/scheduled-task-view.d.ts +22 -4
  109. package/dist/mcp/server.d.ts +255 -3
  110. package/dist/mcp/session-event-view.d.ts +94 -0
  111. package/dist/mcp/session-view.d.ts +66 -2
  112. package/dist/mcp/session-wait.d.ts +174 -0
  113. package/dist/mcp-oauth.d.ts +52 -0
  114. package/dist/model-catalog.d.ts +11 -31
  115. package/dist/observability.d.ts +3 -1
  116. package/dist/organization-mcp.d.ts +52 -0
  117. package/dist/organization-recovery-notifications.d.ts +41 -0
  118. package/dist/routes/analytics-consent.d.ts +26 -0
  119. package/dist/routes/api-integrations.d.ts +25 -0
  120. package/dist/routes/api-keys.d.ts +17 -0
  121. package/dist/routes/artifact-catalog.d.ts +6 -0
  122. package/dist/routes/automations.d.ts +19 -0
  123. package/dist/routes/billing.d.ts +49 -0
  124. package/dist/routes/browser-sessions.d.ts +71 -3
  125. package/dist/routes/claude-subscription-accounts.d.ts +3 -0
  126. package/dist/routes/claude-subscription-oauth.d.ts +3 -0
  127. package/dist/routes/client-errors.d.ts +146 -0
  128. package/dist/routes/codex.d.ts +76 -2
  129. package/dist/routes/company-brain.d.ts +3 -0
  130. package/dist/routes/company-profile.d.ts +2 -1
  131. package/dist/routes/computer-sessions.d.ts +14 -0
  132. package/dist/routes/connect.d.ts +5 -0
  133. package/dist/routes/editable-artifacts.d.ts +2 -0
  134. package/dist/routes/external-identity-links.d.ts +6 -0
  135. package/dist/routes/feedback.d.ts +3 -0
  136. package/dist/routes/files.d.ts +4 -0
  137. package/dist/routes/github-browser-pages.d.ts +12 -0
  138. package/dist/routes/github.d.ts +2 -0
  139. package/dist/routes/insights-response-cache.d.ts +10 -0
  140. package/dist/routes/insights-usage.d.ts +12 -0
  141. package/dist/routes/insights.d.ts +30 -1
  142. package/dist/routes/knowledge.d.ts +3 -0
  143. package/dist/routes/managed-auth-session-sets.d.ts +26 -0
  144. package/dist/routes/managed-onboarding.d.ts +29 -0
  145. package/dist/routes/managed-sign-in-methods.d.ts +6 -0
  146. package/dist/routes/model-connection-access.d.ts +3 -0
  147. package/dist/routes/organization-integration-policy.d.ts +3 -0
  148. package/dist/routes/organization-integrations.d.ts +6 -0
  149. package/dist/routes/organization-mcp-connections.d.ts +3 -0
  150. package/dist/routes/organization-model-providers.d.ts +3 -0
  151. package/dist/routes/organization-recovery.d.ts +19 -0
  152. package/dist/routes/organization-service-accounts.d.ts +3 -0
  153. package/dist/routes/organization-sessions.d.ts +26 -0
  154. package/dist/routes/personal-github-git-broker.d.ts +29 -0
  155. package/dist/routes/personal-github.d.ts +3 -0
  156. package/dist/routes/pr-review-github.d.ts +3 -0
  157. package/dist/routes/pr-review.d.ts +3 -0
  158. package/dist/routes/session-artifact-associations.d.ts +4 -0
  159. package/dist/routes/session-history-imports.d.ts +9 -0
  160. package/dist/routes/sessions.d.ts +44 -6
  161. package/dist/routes/skill-content.d.ts +4 -0
  162. package/dist/routes/skill-install-authority.d.ts +6 -0
  163. package/dist/routes/subscription-account-pools.d.ts +34 -0
  164. package/dist/routes/subscription-pool-access.d.ts +16 -0
  165. package/dist/routes/supergrok.d.ts +6 -1
  166. package/dist/routes/usage-allowances.d.ts +12 -0
  167. package/dist/routes/user-resource-authorities.d.ts +3 -0
  168. package/dist/routes/workspace-artifacts.d.ts +2 -1
  169. package/dist/routes/workspace-capture.d.ts +10 -2
  170. package/dist/routes/workspace-integrations.d.ts +35 -0
  171. package/dist/routes/workspace-learning.d.ts +3 -0
  172. package/dist/routes/workspace-model-providers.d.ts +4 -0
  173. package/dist/routes/workspaces.d.ts +29 -0
  174. package/dist/sandbox/auth-callout.d.ts +8 -0
  175. package/dist/sandbox/channel-a.d.ts +19 -1
  176. package/dist/sandbox/connection-authority.d.ts +3 -0
  177. package/dist/sandbox/enrollment.d.ts +9 -1
  178. package/dist/sandbox/machines.d.ts +5 -2
  179. package/dist/sandbox/metrics-ingestion.d.ts +28 -20
  180. package/dist/sandbox/rematerialize.d.ts +2 -0
  181. package/dist/sandbox/session-attach-variable-sets.d.ts +30 -0
  182. package/dist/sandbox/viewer.d.ts +26 -1
  183. package/dist/sandbox-file-artifacts.d.ts +50 -0
  184. package/dist/scheduled-task-deletion.d.ts +13 -0
  185. package/dist/session-create-observability.d.ts +5 -0
  186. package/dist/session-event-view-MPS2OZD3.js +292 -0
  187. package/dist/session-event-view-MPS2OZD3.js.map +1 -0
  188. package/dist/site-session-origin.d.ts +13 -0
  189. package/dist/site-uploads.d.ts +41 -0
  190. package/dist/slack-reaction-files.d.ts +1 -1
  191. package/dist/temporal-schedule-cleanup.d.ts +1 -0
  192. package/dist/temporal-schedule-sync.d.ts +26 -0
  193. package/dist/transcription/providers/xai-subscription.d.ts +1 -0
  194. package/dist/transcription/service.d.ts +2 -1
  195. package/dist/work-discovery-observability.d.ts +33 -0
  196. package/dist/workspace-artifact-content.d.ts +28 -0
  197. package/dist/workspace-artifact-provenance.d.ts +7 -0
  198. package/dist/workspace-delete-observability.d.ts +10 -0
  199. package/dist/workspace-deletion.d.ts +6 -0
  200. package/dist/workspace-state-projection.d.ts +3 -5
  201. package/dist/workspace-tool-gateway-observability.d.ts +17 -0
  202. package/dist/workspace-tool-gateway.d.ts +123 -0
  203. package/dist/workspace-webhook-dispatch.d.ts +26 -0
  204. package/package.json +23 -19
  205. package/src/access-grant-rls.ts +75 -0
  206. package/src/admission-trace.ts +14 -0
  207. package/src/api-websocket.ts +23 -0
  208. package/src/app.ts +1974 -256
  209. package/src/artifact-catalog-cursor.ts +60 -0
  210. package/src/auth/managed-auth-attempt-context.ts +70 -0
  211. package/src/auth/managed-auth-rate-limits.ts +252 -0
  212. package/src/auth/managed-auth-session-adapter.ts +222 -0
  213. package/src/auth/managed-auth.ts +536 -60
  214. package/src/auth/managed-email.ts +174 -0
  215. package/src/auth/managed-sign-in-notifications.ts +81 -0
  216. package/src/auth/new-signups-gate.ts +49 -0
  217. package/src/auth/organization-user-setup.ts +307 -0
  218. package/src/auth/signup-funnel-metrics.ts +164 -0
  219. package/src/browser-controller-authority.ts +1 -186
  220. package/src/browser-ephemeral.ts +39 -0
  221. package/src/browser-state-authority.ts +1 -236
  222. package/src/claude-subscription-account-conflicts.ts +12 -0
  223. package/src/claude-subscription-account-usage.ts +48 -0
  224. package/src/claude-subscription-oauth.ts +362 -0
  225. package/src/claude-subscription-profile.ts +73 -0
  226. package/src/claude-subscription-usage.ts +97 -0
  227. package/src/claude-workspace-connection.ts +82 -0
  228. package/src/codemode.ts +194 -30
  229. package/src/codex-realtime.ts +8 -2
  230. package/src/company-brain-okf.ts +340 -0
  231. package/src/connected-machine-computer-access.ts +33 -0
  232. package/src/connection-ownership.ts +199 -0
  233. package/src/controller-data-plane.ts +81 -0
  234. package/src/editable-artifact-native-kernel.ts +26 -15
  235. package/src/editable-artifact-office-import.ts +77 -9
  236. package/src/editable-artifact-production.ts +23 -7
  237. package/src/editable-artifact-source-session.ts +123 -0
  238. package/src/editable-artifact-websocket.ts +27 -21
  239. package/src/editable-artifact-workspace-files.ts +31 -6
  240. package/src/fatal-process-boundary.ts +246 -0
  241. package/src/gateway-realtime.ts +1 -1
  242. package/src/github-access.ts +147 -5
  243. package/src/http/acting-person.ts +71 -0
  244. package/src/http/api-contract-compat.ts +49 -0
  245. package/src/http/api-error.ts +115 -1
  246. package/src/http/auth.ts +48 -0
  247. package/src/http/cors.ts +67 -0
  248. package/src/http/deprecation.ts +118 -0
  249. package/src/http/interaction-control-error.ts +164 -0
  250. package/src/http/keyed-admission.ts +29 -0
  251. package/src/http/local-browser-boundary.ts +343 -0
  252. package/src/http/metrics-listener.ts +57 -0
  253. package/src/http/path-identifier.ts +54 -0
  254. package/src/http/registered-route-label.ts +34 -0
  255. package/src/http/request-body.ts +127 -0
  256. package/src/http/request-source.ts +178 -0
  257. package/src/http/sse.ts +486 -132
  258. package/src/http/unmatched-route.ts +60 -0
  259. package/src/http/user-content.ts +158 -0
  260. package/src/http/websocket-upgrade-dispatch.ts +29 -0
  261. package/src/index.ts +157 -52
  262. package/src/integration-endpoint-test.ts +291 -0
  263. package/src/integrations/api-integrations.ts +98 -11
  264. package/src/integrations/atlassian.ts +474 -136
  265. package/src/integrations/connect-authority.ts +2 -0
  266. package/src/integrations/connect-callback-return.ts +86 -0
  267. package/src/integrations/fiken.ts +354 -64
  268. package/src/integrations/github-app-connect.ts +435 -0
  269. package/src/integrations/github-installation-proof.ts +60 -0
  270. package/src/integrations/github-lens-connect.ts +76 -0
  271. package/src/integrations/github-skill-source.ts +2 -142
  272. package/src/integrations/google-drive.ts +820 -222
  273. package/src/integrations/integration-commit-authority.ts +69 -0
  274. package/src/integrations/marketplace-plugin.ts +48 -0
  275. package/src/integrations/oauth-client.ts +1356 -459
  276. package/src/integrations/oauth-profiles.ts +537 -0
  277. package/src/integrations/oauth-return-path.ts +18 -0
  278. package/src/integrations/personal-github-repositories.ts +674 -0
  279. package/src/integrations/personal-github.ts +825 -0
  280. package/src/integrations/pr-review-provider.ts +246 -0
  281. package/src/integrations/provider-oauth.ts +250 -22
  282. package/src/integrations/slack-app-home.ts +300 -0
  283. package/src/integrations/slack-bot.ts +963 -239
  284. package/src/integrations/slack-file-upload-flow.ts +147 -0
  285. package/src/integrations/slack-install.ts +83 -0
  286. package/src/integrations/slack-interactions.ts +3170 -474
  287. package/src/integrations/slack-mrkdwn.ts +193 -0
  288. package/src/integrations/slack-routing.ts +337 -0
  289. package/src/integrations/slack-session-defaults.ts +224 -0
  290. package/src/integrations/slack-task-file-upload.ts +323 -0
  291. package/src/integrations/social-oauth.ts +213 -15
  292. package/src/interaction-agent-access.ts +48 -0
  293. package/src/interaction-frame-proxy.ts +409 -0
  294. package/src/interaction-metrics.ts +30 -0
  295. package/src/mcp/action-catalog-types.ts +9 -0
  296. package/src/mcp/action-catalog.gen.ts +6696 -0
  297. package/src/mcp/capability-account-readiness.ts +17 -0
  298. package/src/mcp/child-read-evidence.ts +19 -0
  299. package/src/mcp/command-read.ts +109 -0
  300. package/src/mcp/company-profile-agent-admin.ts +198 -0
  301. package/src/mcp/contract-input.ts +141 -0
  302. package/src/mcp/documents.ts +65 -377
  303. package/src/mcp/editable-artifacts.ts +12 -6
  304. package/src/mcp/files.ts +80 -38
  305. package/src/mcp/first-party-tool-permissions.ts +305 -0
  306. package/src/mcp/knowledge-entries.ts +322 -0
  307. package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
  308. package/src/mcp/receipts.ts +34 -0
  309. package/src/mcp/request-abort.ts +44 -0
  310. package/src/mcp/scheduled-task-input.ts +76 -0
  311. package/src/mcp/scheduled-task-view.ts +44 -3
  312. package/src/mcp/server.ts +3030 -1267
  313. package/src/mcp/session-event-view.ts +383 -0
  314. package/src/mcp/session-view.ts +84 -3
  315. package/src/mcp/session-wait.ts +665 -0
  316. package/src/mcp-oauth.ts +1123 -0
  317. package/src/model-catalog.ts +91 -333
  318. package/src/observability.ts +15 -1
  319. package/src/organization-mcp.ts +397 -0
  320. package/src/organization-recovery-notifications.ts +103 -0
  321. package/src/routes/analytics-consent.ts +123 -0
  322. package/src/routes/api-integrations.ts +364 -74
  323. package/src/routes/api-keys.ts +336 -10
  324. package/src/routes/artifact-catalog.ts +279 -0
  325. package/src/routes/automations.ts +768 -0
  326. package/src/routes/billing.ts +461 -46
  327. package/src/routes/browser-sessions.ts +839 -131
  328. package/src/routes/canonical-human-identities.ts +90 -14
  329. package/src/routes/capabilities.ts +107 -6
  330. package/src/routes/channels.ts +20 -3
  331. package/src/routes/claude-subscription-accounts.ts +334 -0
  332. package/src/routes/claude-subscription-oauth.ts +142 -0
  333. package/src/routes/client-errors.ts +362 -0
  334. package/src/routes/codex.ts +833 -116
  335. package/src/routes/company-brain.ts +322 -0
  336. package/src/routes/company-profile.ts +65 -1
  337. package/src/routes/computer-sessions.ts +557 -106
  338. package/src/routes/connect.ts +1938 -0
  339. package/src/routes/connections.ts +1040 -349
  340. package/src/routes/documents.ts +488 -287
  341. package/src/routes/editable-artifacts.ts +79 -9
  342. package/src/routes/enrollments.ts +135 -39
  343. package/src/routes/environments.ts +154 -58
  344. package/src/routes/external-identity-links.ts +201 -0
  345. package/src/routes/feedback.ts +113 -0
  346. package/src/routes/files.ts +337 -39
  347. package/src/routes/github-browser-pages.ts +162 -0
  348. package/src/routes/github.ts +446 -144
  349. package/src/routes/insights-response-cache.ts +83 -0
  350. package/src/routes/insights-usage.ts +345 -0
  351. package/src/routes/insights.ts +153 -19
  352. package/src/routes/install.ts +133 -38
  353. package/src/routes/integration-facets.ts +107 -33
  354. package/src/routes/interaction-resources.ts +30 -3
  355. package/src/routes/knowledge.ts +488 -0
  356. package/src/routes/machines.ts +313 -15
  357. package/src/routes/managed-auth-session-sets.ts +1218 -0
  358. package/src/routes/managed-onboarding.ts +337 -0
  359. package/src/routes/managed-sign-in-methods.ts +433 -0
  360. package/src/routes/memory-slack-publications.ts +3 -2
  361. package/src/routes/model-connection-access.ts +208 -0
  362. package/src/routes/organization-integration-policy.ts +116 -0
  363. package/src/routes/organization-integrations.ts +326 -0
  364. package/src/routes/organization-mcp-connections.ts +178 -0
  365. package/src/routes/organization-memberships.ts +1019 -27
  366. package/src/routes/organization-model-providers.ts +293 -0
  367. package/src/routes/organization-recovery.ts +325 -0
  368. package/src/routes/organization-service-accounts.ts +128 -0
  369. package/src/routes/organization-sessions.ts +350 -0
  370. package/src/routes/personal-github-git-broker.ts +785 -0
  371. package/src/routes/personal-github.ts +370 -0
  372. package/src/routes/plugins.ts +251 -22
  373. package/src/routes/pr-review-github.ts +881 -0
  374. package/src/routes/pr-review.ts +622 -0
  375. package/src/routes/preference-registry.ts +12 -93
  376. package/src/routes/rigs.ts +167 -50
  377. package/src/routes/scheduled-tasks.ts +346 -41
  378. package/src/routes/session-artifact-associations.ts +87 -0
  379. package/src/routes/session-history-imports.ts +280 -0
  380. package/src/routes/sessions.ts +2306 -264
  381. package/src/routes/skill-content.ts +297 -0
  382. package/src/routes/skill-install-authority.ts +64 -0
  383. package/src/routes/skills.ts +62 -9
  384. package/src/routes/social.ts +46 -18
  385. package/src/routes/subscription-account-pools.ts +436 -0
  386. package/src/routes/subscription-pool-access.ts +126 -0
  387. package/src/routes/supergrok.ts +219 -303
  388. package/src/routes/transcription-recordings.ts +38 -3
  389. package/src/routes/transcriptions.ts +4 -0
  390. package/src/routes/usage-allowances.ts +378 -0
  391. package/src/routes/user-resource-authorities.ts +138 -0
  392. package/src/routes/video-generation.ts +14 -10
  393. package/src/routes/workspace-artifacts.ts +275 -69
  394. package/src/routes/workspace-capture.ts +21 -0
  395. package/src/routes/workspace-integrations.ts +576 -0
  396. package/src/routes/workspace-learning.ts +159 -0
  397. package/src/routes/workspace-model-providers.ts +148 -0
  398. package/src/routes/workspace-state.ts +38 -25
  399. package/src/routes/workspaces.ts +1004 -127
  400. package/src/sandbox/auth-callout.ts +96 -19
  401. package/src/sandbox/channel-a.ts +323 -24
  402. package/src/sandbox/connection-authority.ts +3 -0
  403. package/src/sandbox/enrollment.ts +81 -6
  404. package/src/sandbox/machines.ts +218 -76
  405. package/src/sandbox/metrics-ingestion.ts +411 -62
  406. package/src/sandbox/rematerialize.ts +121 -19
  407. package/src/sandbox/session-attach-variable-sets.ts +131 -0
  408. package/src/sandbox/viewer.ts +280 -25
  409. package/src/sandbox-file-artifacts.ts +413 -0
  410. package/src/scheduled-task-deletion.ts +138 -0
  411. package/src/session-create-observability.ts +46 -0
  412. package/src/session-realtime-context.ts +6 -3
  413. package/src/site-session-origin.ts +48 -0
  414. package/src/site-uploads.ts +224 -0
  415. package/src/slack-reaction-files.ts +16 -5
  416. package/src/temporal-schedule-cleanup.ts +13 -0
  417. package/src/temporal-schedule-sync.ts +74 -0
  418. package/src/transcription/providers/codex-subscription.ts +2 -0
  419. package/src/transcription/providers/openai.ts +1 -0
  420. package/src/transcription/providers/xai-subscription.ts +49 -3
  421. package/src/transcription/segmenter.ts +8 -2
  422. package/src/transcription/service.ts +43 -6
  423. package/src/work-discovery-observability.ts +121 -0
  424. package/src/workspace-artifact-content.ts +144 -0
  425. package/src/workspace-artifact-provenance.ts +104 -0
  426. package/src/workspace-delete-observability.ts +75 -0
  427. package/src/workspace-deletion.ts +73 -0
  428. package/src/workspace-state-projection.ts +18 -148
  429. package/src/workspace-tool-gateway-observability.ts +100 -0
  430. package/src/workspace-tool-gateway.ts +870 -0
  431. package/src/workspace-webhook-dispatch.ts +190 -0
  432. package/src/xai-subscription-auth.ts +9 -2
  433. package/dist/chunk-2PQMSRCB.js +0 -49759
  434. package/dist/chunk-2PQMSRCB.js.map +0 -1
  435. package/dist/routes/packs.d.ts +0 -3
  436. package/src/routes/packs.ts +0 -729
@@ -0,0 +1,33 @@
1
+ export type ConnectedMachineComputerAccessState = {
2
+ hasDisplay: boolean;
3
+ desktopUnavailableReason: string | null;
4
+ allowScreenControl: boolean;
5
+ };
6
+
7
+ export type ConnectedMachineComputerAccessError = {
8
+ status: 403 | 409;
9
+ message: string;
10
+ };
11
+
12
+ /** Keep passive desktop viewing separate from input consent. */
13
+ export function connectedMachineComputerAccessError(
14
+ state: ConnectedMachineComputerAccessState,
15
+ requiresControl: boolean,
16
+ ): ConnectedMachineComputerAccessError | null {
17
+ if (!state.hasDisplay) {
18
+ const reason = state.desktopUnavailableReason?.trim();
19
+ return {
20
+ status: 409,
21
+ message: reason
22
+ ? `Connected Machine desktop is unavailable. ${reason}`
23
+ : "Connected Machine desktop is unavailable because this machine has no capturable display.",
24
+ };
25
+ }
26
+ if (requiresControl && !state.allowScreenControl) {
27
+ return {
28
+ status: 403,
29
+ message: "Screen control is not enabled for this Connected Machine.",
30
+ };
31
+ }
32
+ return null;
33
+ }
@@ -0,0 +1,199 @@
1
+ import type { ConnectionOwnership } from "@opengeni/contracts";
2
+ import {
3
+ externalActorContinuationForAuthorization,
4
+ isVerifiedDelegatedHumanAuthorization,
5
+ type AccessGrantAuthorization,
6
+ } from "@opengeni/core";
7
+ import { HTTPException } from "hono/http-exception";
8
+
9
+ /** Signing in to a third-party provider is the person's own step in the
10
+ * browser; an agent acting as them through the organization MCP server is told
11
+ * to finish it there. */
12
+ export function requireProviderConsentInBrowser(access: AccessGrantAuthorization): void {
13
+ if (isVerifiedDelegatedHumanAuthorization(access))
14
+ throw new HTTPException(403, {
15
+ message:
16
+ "Signing in to a provider has to be done by the person in the Opengeni app in a browser.",
17
+ });
18
+ }
19
+
20
+ /** A verified external actor must not enter a native callback that has no
21
+ * corresponding key/identity reauthorization proof. Remove at an entry point
22
+ * only when that provider's signed continuation and commit fence are wired. */
23
+ export function requireLegacyOAuthActor(access: AccessGrantAuthorization): void {
24
+ requireProviderConsentInBrowser(access);
25
+ if (externalActorContinuationForAuthorization(access))
26
+ throw new HTTPException(422, {
27
+ message: "This provider does not yet support external-user OAuth continuation",
28
+ });
29
+ }
30
+
31
+ /**
32
+ * Who may own a *personal* Connection.
33
+ *
34
+ * Connection setup defaults to a workspace-owned Connection; personal ownership
35
+ * is the explicit "Connect only for me" choice (AGENTS.md, "Connection
36
+ * ownership and executable personal authority are separate from turn
37
+ * initiation"). Only a managed human can own one, for two independent reasons:
38
+ * personal authority executes only through the immutable delegation snapshot
39
+ * frozen on a *human's* causal turn or scheduled task, and
40
+ * `bind_connection_authority` (migration 0256) can mint the `user` authority
41
+ * scope only for a subject holding an active organization membership. A
42
+ * machine-owned personal row therefore lands on the `legacy_user` compatibility
43
+ * lane and can never become a real organization-scoped authority.
44
+ *
45
+ * `principalKind` is the trusted, allow-listed signal: exactly `human_session`
46
+ * passes and every other value - including absent/unknown provenance - fails
47
+ * closed. The delegated-token contract forbids a `human_session` claim from
48
+ * carrying `serviceInitiator` or exact agent-attempt authority, so the claim
49
+ * cannot be combined with machine authority.
50
+ */
51
+
52
+ /**
53
+ * Subject namespaces OpenGeni itself mints for machines. This is deliberately
54
+ * NOT an allow-list of human subjects: `docs/embedding.md` states that
55
+ * `subjectId` "remains opaque to OpenGeni" and that the kind must not be
56
+ * inferred from a subject-id prefix "because the host owns that namespace", so
57
+ * a trusted embedding host legitimately signs `human_session` over an opaque
58
+ * subject that is not `user:`-prefixed. Restricting personal ownership to
59
+ * `user:`/`dev` would break those hosts and would itself be the prefix-based
60
+ * kind inference the embedding contract forbids.
61
+ *
62
+ * The allow-list that actually decides is `principalKind === "human_session"`.
63
+ * This list is defence-in-depth against exactly one residual threat: a holder
64
+ * of the first-party delegation secret signing a human claim over an
65
+ * OpenGeni-minted machine subject.
66
+ *
67
+ * `connection-ownership.test.ts` asserts that every machine subject named in
68
+ * its list is rejected. Note what that does and does not buy: it catches a
69
+ * namespace being *removed* from this constant, and it documents the known
70
+ * machine subjects, but it is a hand-maintained list on both sides, so it
71
+ * cannot fail when a genuinely new machine namespace is introduced elsewhere in
72
+ * the repo. Adding one here is a manual step. That residual gap is acceptable
73
+ * only because this check is not the deciding signal anywhere: a new machine
74
+ * namespace still arrives with a non-`human_session` `principalKind` and is
75
+ * refused on that basis.
76
+ *
77
+ * It is also no longer the sole signal on any OAuth callback: a callback that
78
+ * persists a personal owner requires the HMAC-signed `personalOwnerVerified`
79
+ * state claim minted by a start path that saw the live principal.
80
+ */
81
+ const RESERVED_MACHINE_SUBJECT_NAMESPACES = [
82
+ // packages/core/src/access/index.ts
83
+ "api_key",
84
+ "configured",
85
+ // packages/runtime/src/index.ts (signFirstPartyDelegatedBearer default)
86
+ "worker",
87
+ // packages/runtime/src/sandbox/codemode-authority.ts
88
+ "sandbox",
89
+ // apps/worker/src/activities/scheduled-tasks.ts
90
+ "scheduled_task",
91
+ // packages/db/src/session-queue-commands.ts
92
+ "attempt",
93
+ // Service principals (e.g. governed-learning activation).
94
+ "service",
95
+ ] as const;
96
+
97
+ /** True only for an exact authenticated managed human. Unknown provenance fails closed. */
98
+ export function isPersonalConnectionOwnerPrincipal(access: AccessGrantAuthorization): boolean {
99
+ const { grant } = access;
100
+ return (
101
+ // Every context grant must agree on the authenticated principal and account.
102
+ access.contextIntegrity &&
103
+ access.authenticatedSubjectId === grant.subjectId &&
104
+ grant.principalKind === "human_session" &&
105
+ !grant.serviceInitiator &&
106
+ !grant.serviceInitiatorContext &&
107
+ isPersonalConnectionOwnerSubject(grant.subjectId)
108
+ );
109
+ }
110
+
111
+ /** Rejects an OpenGeni-minted machine subject; see the namespace list's rationale. */
112
+ export function isPersonalConnectionOwnerSubject(subjectId: string): boolean {
113
+ const separator = subjectId.indexOf(":");
114
+ if (separator < 0) {
115
+ return true;
116
+ }
117
+ const namespace = subjectId.slice(0, separator);
118
+ return !RESERVED_MACHINE_SUBJECT_NAMESPACES.some((reserved) => reserved === namespace);
119
+ }
120
+
121
+ export const PERSONAL_CONNECTION_PRINCIPAL_MESSAGE =
122
+ "personal Connection ownership requires an authenticated human; API keys, configured keys, " +
123
+ "services, and agent attempts can create only workspace-owned Connections";
124
+
125
+ /** Personal-only connectors cannot degrade to workspace ownership, so they say so exactly. */
126
+ export function personalOnlyConnectionPrincipalMessage(label: string): string {
127
+ return (
128
+ `${label} connects only as a personal Connection, which requires an authenticated human; ` +
129
+ "API keys, configured keys, services, and agent attempts cannot own one"
130
+ );
131
+ }
132
+
133
+ /**
134
+ * Rejects a non-human principal before a personal Connection is created.
135
+ * `label` names a personal-only connector, whose message must not suggest a
136
+ * workspace-owned alternative that its provider profile forbids.
137
+ *
138
+ * This shares that helper's core caller-integrity checks, then additionally
139
+ * rejects every reserved machine-subject namespace as defence-in-depth. The
140
+ * sibling guards a self-service authority surface where the caller claims to
141
+ * *be* the owner (403 "not you"), while this one rejects an ownership *value*
142
+ * that is unavailable to the caller (422).
143
+ */
144
+ export function assertPersonalConnectionOwnerPrincipal(
145
+ access: AccessGrantAuthorization,
146
+ label?: string,
147
+ ): void {
148
+ if (isPersonalConnectionOwnerPrincipal(access)) {
149
+ return;
150
+ }
151
+ throw new HTTPException(422, {
152
+ message: label
153
+ ? personalOnlyConnectionPrincipalMessage(label)
154
+ : PERSONAL_CONNECTION_PRINCIPAL_MESSAGE,
155
+ });
156
+ }
157
+
158
+ /** The same fence expressed for a flow that resolves ownership after admission. */
159
+ export function assertConnectionOwnershipAllowedForPrincipal(
160
+ ownership: ConnectionOwnership,
161
+ personalOwnershipAllowed: boolean,
162
+ ): void {
163
+ if (ownership === "personal" && !personalOwnershipAllowed) {
164
+ throw new HTTPException(422, { message: PERSONAL_CONNECTION_PRINCIPAL_MESSAGE });
165
+ }
166
+ }
167
+
168
+ /**
169
+ * The claim a start path mints into its HMAC-signed OAuth state when it has
170
+ * verified the live principal may own a personal Connection.
171
+ *
172
+ * An OAuth callback carries signed state, not a live principal, so it cannot
173
+ * re-evaluate `principalKind`. Requiring this claim makes the callback enforce
174
+ * exactly what the start path decided with the full signal, instead of guessing
175
+ * from the subject's shape. A state minted before this claim existed simply
176
+ * lacks it and fails closed for personal ownership - which is precisely the
177
+ * in-flight rolling-deploy window these fences exist to close.
178
+ */
179
+ export const PERSONAL_OWNER_VERIFIED_STATE_CLAIM = "personalOwnerVerified" as const;
180
+
181
+ /** True only for an explicit boolean `true` claim; absent or malformed fails closed. */
182
+ export function personalOwnerVerifiedInState(payload: Record<string, unknown>): boolean {
183
+ return payload[PERSONAL_OWNER_VERIFIED_STATE_CLAIM] === true;
184
+ }
185
+
186
+ /**
187
+ * Callback-side fence for every path that persists a personal owner. Requires
188
+ * both the signed start-time verification and a non-machine subject.
189
+ */
190
+ export function personalOwnerStateAccepted(state: {
191
+ ownership: ConnectionOwnership;
192
+ subjectId: string;
193
+ personalOwnerVerified: boolean;
194
+ }): boolean {
195
+ if (state.ownership !== "personal") {
196
+ return true;
197
+ }
198
+ return state.personalOwnerVerified && isPersonalConnectionOwnerSubject(state.subjectId);
199
+ }
@@ -1,7 +1,56 @@
1
1
  import {
2
2
  BrowserControlRequestError,
3
3
  BrowserControlTransportError,
4
+ exposedPortAllowsHostFetch,
5
+ exposedPortEndpointFromUrl,
6
+ parseOpenSandboxSignedUriPath,
7
+ signedEndpointNeedsRefresh,
4
8
  } from "@opengeni/runtime/sandbox";
9
+ import type { InteractionPlacement } from "@opengeni/contracts";
10
+ import type { ChannelAOperation } from "./sandbox/channel-a";
11
+
12
+ /** Modal/Daytona/Blaxel tunnels serve browserd at `/`, so a cached
13
+ * controller-only session can host-fetch JSON. OpenSandbox's lifecycle proxy
14
+ * prefixes `/v1/sandboxes/<id>/proxy/<port>` and rewrites Authorization; JSON
15
+ * must stay on an exec-capable in-box curl session. OSEP-0011 signed URIs are
16
+ * Authorization-preserving and host-fetch like a native tunnel, but they are
17
+ * not durable cache keys. */
18
+ export function controllerCacheAllowsHostFetch(url: string): boolean {
19
+ try {
20
+ return exposedPortAllowsHostFetch(exposedPortEndpointFromUrl(url));
21
+ } catch {
22
+ return false;
23
+ }
24
+ }
25
+
26
+ export function isOpenSandboxSignedControllerUrl(url: string): boolean {
27
+ try {
28
+ return parseOpenSandboxSignedUriPath(new URL(url).pathname) !== null;
29
+ } catch {
30
+ return false;
31
+ }
32
+ }
33
+
34
+ /** Signed Channel B URLs expire. Do not treat a lease-cached signed URI as an
35
+ * infinite controller endpoint. Unsigned native `/` tunnels stay cacheable. */
36
+ export function controllerCachedUrlIsUsable(url: string, nowMs = Date.now()): boolean {
37
+ if (!controllerCacheAllowsHostFetch(url)) return false;
38
+ if (!isOpenSandboxSignedControllerUrl(url)) return true;
39
+ try {
40
+ return !signedEndpointNeedsRefresh(new URL(url).pathname, nowMs);
41
+ } catch {
42
+ return false;
43
+ }
44
+ }
45
+
46
+ export function shouldPersistControllerDataPlaneUrl(input: {
47
+ backend: string | null | undefined;
48
+ signedEndpoints: boolean;
49
+ url: string;
50
+ }): boolean {
51
+ if (input.backend === "opensandbox" && input.signedEndpoints) return false;
52
+ return controllerCachedUrlIsUsable(input.url);
53
+ }
5
54
 
6
55
  /** Prefer a lease-fenced controller endpoint for the idempotent create path.
7
56
  * Only a transport-class failure invalidates the cache and provisions once;
@@ -33,3 +82,35 @@ export function isRetryableControllerTransport(error: unknown): boolean {
33
82
  (error instanceof BrowserControlRequestError && error.retryable)
34
83
  );
35
84
  }
85
+
86
+ /** A stopped sidecar needs provisioning on its original, fenced placement.
87
+ * Only reads and journaled actions may recover, once across provider retries.
88
+ * Revalidate controller authority before starting the sidecar. */
89
+ export async function withControllerTransportRecovery<T>(options: {
90
+ channelOperation: ChannelAOperation;
91
+ placementKind: InteractionPlacement["kind"];
92
+ recoveryState: { attempted: boolean };
93
+ transportAlreadyFailed: boolean;
94
+ use: () => Promise<T>;
95
+ admitRecovery: () => Promise<void>;
96
+ recover: () => Promise<T>;
97
+ }): Promise<T> {
98
+ if (
99
+ (options.channelOperation !== "browser.read" &&
100
+ options.channelOperation !== "browser.action") ||
101
+ options.placementKind !== "sandbox_group" ||
102
+ options.recoveryState.attempted
103
+ ) {
104
+ return await options.use();
105
+ }
106
+ if (!options.transportAlreadyFailed) {
107
+ try {
108
+ return await options.use();
109
+ } catch (error) {
110
+ if (!isRetryableControllerTransport(error)) throw error;
111
+ }
112
+ }
113
+ options.recoveryState.attempted = true;
114
+ await options.admitRecovery();
115
+ return await options.recover();
116
+ }
@@ -17,6 +17,13 @@ import {
17
17
  } from "@opengeni/contracts/editable-artifact-causal-frontier";
18
18
  import { decodeEditableArtifactSerializedCommit } from "@opengeni/contracts/editable-artifact-serialized-commit";
19
19
  import { decodeEditableArtifactMutationIntent } from "@opengeni/contracts/editable-artifacts";
20
+ import {
21
+ COMMITTED_TRANSACTION_PROTOCOL_VERSION,
22
+ DOCUMENT_ARTIFACT_MODEL_SCHEMA_VERSION,
23
+ PRESENTATION_ARTIFACT_MODEL_SCHEMA_VERSION,
24
+ SPREADSHEET_ARTIFACT_MODEL_SCHEMA_VERSION,
25
+ SPREADSHEET_COLLABORATION_SNAPSHOT_VERSION,
26
+ } from "@opengeni/contracts/editable-artifact-versions";
20
27
  import {
21
28
  MAX_EDITABLE_ARTIFACT_SNAPSHOT_BYTES,
22
29
  causalFrontiersEqual,
@@ -39,9 +46,6 @@ import {
39
46
  } from "@opengeni/core";
40
47
  import type { BoundedObjectReadPort } from "@opengeni/storage";
41
48
 
42
- const MODEL_SCHEMA_VERSION = 1;
43
- const OPERATION_PROTOCOL_VERSION = 1;
44
- const CRDT_STATE_VERSION = 1;
45
49
  const SNAPSHOT_CHUNK_BYTES = 1024 * 1024;
46
50
 
47
51
  type RuntimeFacadeModule = Readonly<{
@@ -104,7 +108,7 @@ export class NativeEditableArtifactKernelAdapter
104
108
  modality: "spreadsheet" as const,
105
109
  committedTransactionBytes,
106
110
  kernelVersion: this.runtime.buildIdentity,
107
- modelSchemaVersion: MODEL_SCHEMA_VERSION,
111
+ modelSchemaVersion: SPREADSHEET_ARTIFACT_MODEL_SCHEMA_VERSION,
108
112
  });
109
113
  }
110
114
  if (session.modality !== request.modality) {
@@ -116,7 +120,7 @@ export class NativeEditableArtifactKernelAdapter
116
120
  nativeReceiptBytes,
117
121
  resultingStateHash: editableArtifactStateHash(session.stateHash()),
118
122
  kernelVersion: this.runtime.buildIdentity,
119
- modelSchemaVersion: MODEL_SCHEMA_VERSION,
123
+ modelSchemaVersion: modelSchemaVersionFor(request.modality),
120
124
  });
121
125
  } finally {
122
126
  session.dispose();
@@ -188,7 +192,7 @@ export class NativeEditableArtifactKernelAdapter
188
192
  ),
189
193
  stateHash: editableArtifactStateHash(session.stateHash()),
190
194
  coveredHeadSequence: 0 as const,
191
- modelSchemaVersion: MODEL_SCHEMA_VERSION,
195
+ modelSchemaVersion: modelSchemaVersionFor(input.modality),
192
196
  kernelVersion: this.runtime.buildIdentity,
193
197
  };
194
198
  if (session.modality === "spreadsheet") {
@@ -196,8 +200,8 @@ export class NativeEditableArtifactKernelAdapter
196
200
  ...common,
197
201
  modality: "spreadsheet" as const,
198
202
  coveredCausalFrontier: domainFrontier(session.frontier()),
199
- operationProtocolVersion: OPERATION_PROTOCOL_VERSION,
200
- crdtStateVersion: CRDT_STATE_VERSION,
203
+ operationProtocolVersion: COMMITTED_TRANSACTION_PROTOCOL_VERSION,
204
+ crdtStateVersion: SPREADSHEET_COLLABORATION_SNAPSHOT_VERSION,
201
205
  });
202
206
  }
203
207
  return Object.freeze({
@@ -239,7 +243,7 @@ export class NativeEditableArtifactKernelAdapter
239
243
  ),
240
244
  stateHash: editableArtifactStateHash(session.stateHash()),
241
245
  coveredHeadSequence: input.state.artifact.headSequence,
242
- modelSchemaVersion: MODEL_SCHEMA_VERSION,
246
+ modelSchemaVersion: modelSchemaVersionFor(input.state.modality),
243
247
  kernelVersion: this.runtime.buildIdentity,
244
248
  } as const;
245
249
  if (session.modality === "spreadsheet") {
@@ -248,8 +252,8 @@ export class NativeEditableArtifactKernelAdapter
248
252
  ...common,
249
253
  modality: session.modality,
250
254
  coveredCausalFrontier: domainFrontier(session.frontier()),
251
- operationProtocolVersion: OPERATION_PROTOCOL_VERSION,
252
- crdtStateVersion: CRDT_STATE_VERSION,
255
+ operationProtocolVersion: COMMITTED_TRANSACTION_PROTOCOL_VERSION,
256
+ crdtStateVersion: SPREADSHEET_COLLABORATION_SNAPSHOT_VERSION,
253
257
  });
254
258
  }
255
259
  if (session.modality !== input.state.modality) throw new Error("Native modality mismatch");
@@ -310,12 +314,12 @@ export class NativeEditableArtifactKernelAdapter
310
314
  canonicalContentHash,
311
315
  coveredHeadSequence,
312
316
  stateHash,
313
- modelSchemaVersion: MODEL_SCHEMA_VERSION,
317
+ modelSchemaVersion: SPREADSHEET_ARTIFACT_MODEL_SCHEMA_VERSION,
314
318
  kernelVersion: this.runtime.buildIdentity,
315
319
  fullCrdtStateVerified: true as const,
316
320
  coveredCausalFrontier,
317
- operationProtocolVersion: OPERATION_PROTOCOL_VERSION,
318
- crdtStateVersion: CRDT_STATE_VERSION,
321
+ operationProtocolVersion: COMMITTED_TRANSACTION_PROTOCOL_VERSION,
322
+ crdtStateVersion: SPREADSHEET_COLLABORATION_SNAPSHOT_VERSION,
319
323
  ...(replayedTarget ? { replayedTarget } : {}),
320
324
  });
321
325
  }
@@ -339,7 +343,7 @@ export class NativeEditableArtifactKernelAdapter
339
343
  canonicalContentHash,
340
344
  coveredHeadSequence,
341
345
  stateHash,
342
- modelSchemaVersion: MODEL_SCHEMA_VERSION,
346
+ modelSchemaVersion: modelSchemaVersionFor(session.modality),
343
347
  kernelVersion: this.runtime.buildIdentity,
344
348
  nativeRevision,
345
349
  ...(replayedTarget ? { replayedTarget } : {}),
@@ -350,6 +354,13 @@ export class NativeEditableArtifactKernelAdapter
350
354
  }
351
355
  }
352
356
 
357
+ function modelSchemaVersionFor(modality: "spreadsheet" | "document" | "presentation"): 1 | 2 {
358
+ if (modality === "spreadsheet") return SPREADSHEET_ARTIFACT_MODEL_SCHEMA_VERSION;
359
+ return modality === "document"
360
+ ? DOCUMENT_ARTIFACT_MODEL_SCHEMA_VERSION
361
+ : PRESENTATION_ARTIFACT_MODEL_SCHEMA_VERSION;
362
+ }
363
+
353
364
  function assertRuntime(
354
365
  candidate: unknown,
355
366
  location: ConfiguredArtifactRuntimeLocation,
@@ -12,13 +12,17 @@ import {
12
12
  editableArtifactReplicaId,
13
13
  editableArtifactStateHash,
14
14
  EditableArtifactOfficeImportError,
15
+ type EditableArtifactActor,
15
16
  type EditableArtifactOfficeImportPort,
16
17
  type EditableArtifactModality,
18
+ type EditableArtifactScope,
17
19
  } from "@opengeni/core/editable-artifacts";
18
- import { getFile } from "@opengeni/db";
20
+ import { requireLiveAgentAttemptAuthorization } from "@opengeni/core";
21
+ import { getFilesForSubject } from "@opengeni/db";
19
22
  import {
20
23
  MAX_BOUNDED_OBJECT_CHUNK_BYTES,
21
24
  type BoundedImmutableObjectWritePort,
25
+ retryWhileMissing,
22
26
  type ObjectStorage,
23
27
  } from "@opengeni/storage";
24
28
  import type { Database } from "@opengeni/db";
@@ -32,23 +36,37 @@ export type EditableArtifactOfficeImportAdapterDependencies = Readonly<{
32
36
  runtime: VerifiedNativeArtifactRuntimeBinding;
33
37
  sourceObjects: BoundedImmutableObjectWritePort;
34
38
  snapshotObjects: BoundedImmutableObjectWritePort;
35
- readFile?: typeof getFile;
39
+ readFiles?: typeof getFilesForSubject;
40
+ resolveFileAuthoritySubjectId?: typeof editableArtifactFileAuthoritySubjectId;
36
41
  prepareOffice?: typeof prepareArtifactOfficeImport;
37
42
  }>;
38
43
 
39
44
  /** Trusted import boundary from one ready workspace file into native sequence-zero state. */
40
45
  export class EditableArtifactOfficeImportAdapter implements EditableArtifactOfficeImportPort {
41
- private readonly readFile: typeof getFile;
46
+ private readonly readFiles: typeof getFilesForSubject;
47
+ private readonly resolveFileAuthoritySubjectId: typeof editableArtifactFileAuthoritySubjectId;
42
48
 
43
49
  constructor(private readonly dependencies: EditableArtifactOfficeImportAdapterDependencies) {
44
- this.readFile = dependencies.readFile ?? getFile;
50
+ this.readFiles = dependencies.readFiles ?? getFilesForSubject;
51
+ this.resolveFileAuthoritySubjectId =
52
+ dependencies.resolveFileAuthoritySubjectId ?? editableArtifactFileAuthoritySubjectId;
45
53
  }
46
54
 
47
55
  async prepare(
48
56
  input: Parameters<EditableArtifactOfficeImportPort["prepare"]>[0],
49
57
  ): ReturnType<EditableArtifactOfficeImportPort["prepare"]> {
50
58
  throwIfAborted(input.signal);
51
- const file = await this.readFile(this.dependencies.db, input.scope.workspaceId, input.fileId);
59
+ const subjectId = await this.resolveFileAuthoritySubjectId(
60
+ this.dependencies.db,
61
+ input.scope,
62
+ input.actor,
63
+ );
64
+ const [file] = await this.readFiles(this.dependencies.db, {
65
+ accountId: input.scope.accountId,
66
+ workspaceId: input.scope.workspaceId,
67
+ subjectId,
68
+ fileIds: [input.fileId],
69
+ });
52
70
  if (!file || file.status !== "ready") {
53
71
  throw new EditableArtifactOfficeImportError("invalid_source");
54
72
  }
@@ -179,11 +197,23 @@ function officeFilenameMatches(filename: string, modality: EditableArtifactModal
179
197
 
180
198
  async function readVerifiedWorkspaceFile(
181
199
  storage: ObjectStorage,
182
- file: NonNullable<Awaited<ReturnType<typeof getFile>>>,
200
+ file: NonNullable<Awaited<ReturnType<typeof getFilesForSubject>>>[number],
183
201
  signal?: AbortSignal,
184
202
  ): Promise<Uint8Array> {
185
203
  throwIfAborted(signal);
186
- const before = await storage.headFile(file);
204
+ const before = await retryWhileMissing(async () => {
205
+ try {
206
+ return await storage.headFile(file);
207
+ } catch (error) {
208
+ if (typeof storage.fileExists === "function" && !(await storage.fileExists(file))) {
209
+ return null;
210
+ }
211
+ throw error;
212
+ }
213
+ });
214
+ if (!before) {
215
+ throw new EditableArtifactOfficeImportError("source_changed");
216
+ }
187
217
  if (
188
218
  before.ContentLength !== file.sizeBytes ||
189
219
  before.ContentType !== file.contentType ||
@@ -198,14 +228,26 @@ async function readVerifiedWorkspaceFile(
198
228
  for (let start = 0; start < file.sizeBytes; start += MAX_BOUNDED_OBJECT_CHUNK_BYTES) {
199
229
  throwIfAborted(signal);
200
230
  const end = Math.min(file.sizeBytes, start + MAX_BOUNDED_OBJECT_CHUNK_BYTES) - 1;
201
- const chunk = await storage.getFileRange(file, { start, end });
231
+ const chunk = await retryWhileMissing(async () => storage.getFileRange(file, { start, end }));
202
232
  if (!chunk || chunk.byteLength !== end - start + 1) {
203
233
  throw new EditableArtifactOfficeImportError("source_changed");
204
234
  }
205
235
  bytes.set(chunk, start);
206
236
  digest.update(chunk);
207
237
  }
208
- const after = await storage.headFile(file);
238
+ const after = await retryWhileMissing(async () => {
239
+ try {
240
+ return await storage.headFile(file);
241
+ } catch (error) {
242
+ if (typeof storage.fileExists === "function" && !(await storage.fileExists(file))) {
243
+ return null;
244
+ }
245
+ throw error;
246
+ }
247
+ });
248
+ if (!after) {
249
+ throw new EditableArtifactOfficeImportError("source_changed");
250
+ }
209
251
  const sha256 = digest.digest("hex");
210
252
  if (
211
253
  after.ContentLength !== before.ContentLength ||
@@ -219,6 +261,32 @@ async function readVerifiedWorkspaceFile(
219
261
  return bytes;
220
262
  }
221
263
 
264
+ export async function editableArtifactFileAuthoritySubjectId(
265
+ db: Database,
266
+ scope: EditableArtifactScope,
267
+ actor: EditableArtifactActor,
268
+ ): Promise<string | null> {
269
+ if (actor.kind !== "agent") return actor.subjectId;
270
+ const authorization = await requireLiveAgentAttemptAuthorization(
271
+ db,
272
+ {
273
+ accountId: scope.accountId,
274
+ workspaceId: scope.workspaceId,
275
+ subjectId: actor.subjectId,
276
+ permissions: [],
277
+ principalKind: "agent_attempt",
278
+ metadata: {
279
+ sessionId: actor.sessionId,
280
+ turnId: actor.turnId,
281
+ attemptId: actor.attemptId,
282
+ executionGeneration: actor.generation,
283
+ },
284
+ },
285
+ actor.sessionId,
286
+ );
287
+ return authorization.initiatingHumanSubjectId;
288
+ }
289
+
222
290
  async function* byteChunks(bytes: Uint8Array): AsyncIterable<Uint8Array> {
223
291
  for (let offset = 0; offset < bytes.byteLength; offset += MAX_BOUNDED_OBJECT_CHUNK_BYTES) {
224
292
  yield bytes.subarray(offset, offset + MAX_BOUNDED_OBJECT_CHUNK_BYTES);
@@ -6,6 +6,7 @@ import {
6
6
  import {
7
7
  EditableArtifactDurableExportService,
8
8
  EditableArtifactAgentApplication,
9
+ EDITABLE_ARTIFACT_EXPORT_FORMATS,
9
10
  EDITABLE_ARTIFACT_EXPORT_MAX_DOWNLOAD_BYTES,
10
11
  EditableArtifactCompactionPipeline,
11
12
  EditableArtifactGenesisPipeline,
@@ -30,7 +31,6 @@ import {
30
31
  type EditableArtifactMaterializationProfilePort,
31
32
  } from "@opengeni/core/editable-artifacts";
32
33
  import {
33
- EDITABLE_ARTIFACT_LIVE_PROTOCOL_VERSION,
34
34
  EditableArtifactApplication,
35
35
  EditableArtifactCompatibilityError,
36
36
  EditableArtifactLiveServer,
@@ -41,12 +41,14 @@ import {
41
41
  type EditableArtifactLiveAuthorizationInvalidationPort,
42
42
  type EditableArtifactLiveCompatibilityPort,
43
43
  } from "@opengeni/core/editable-artifact-live";
44
+ import { currentEditableArtifactCompatibility } from "@opengeni/contracts/editable-artifacts";
44
45
  import {
45
46
  PostgresEditableArtifactLiveReadStore,
46
47
  PostgresEditableArtifactLiveTicketStore,
47
48
  PostgresEditableArtifactStore,
48
49
  listEditableArtifactIdsForSession,
49
50
  touchEditableArtifactSessionLink,
51
+ recordNativeDocumentInspection,
50
52
  dbSql,
51
53
  withRlsContext,
52
54
  type Database,
@@ -167,6 +169,11 @@ export async function createStandaloneEditableArtifactApplication(input: {
167
169
  await touchEditableArtifactSessionLink(input.db, scope, sessionId, artifactId),
168
170
  } satisfies EditableArtifactAgentAssociationPort),
169
171
  inspector: kernel,
172
+ recordInspection: async (inspection) => {
173
+ if (inspection.actor.kind !== "agent")
174
+ throw new Error("Inspection proof requires an agent attempt");
175
+ return recordNativeDocumentInspection(input.db, { ...inspection, actor: inspection.actor });
176
+ },
170
177
  officeImports,
171
178
  workspaceFiles: new EditableArtifactWorkspaceFileAdapter({
172
179
  db: input.db,
@@ -194,10 +201,14 @@ export async function createStandaloneEditableArtifactApplication(input: {
194
201
  assertCompatible(
195
202
  request: Parameters<EditableArtifactLiveCompatibilityPort["assertCompatible"]>[0],
196
203
  ) {
204
+ const current = currentEditableArtifactCompatibility(request.artifact.modality);
197
205
  if (
198
- request.protocolVersion !== EDITABLE_ARTIFACT_LIVE_PROTOCOL_VERSION ||
199
- request.modelSchemaVersion !== 1 ||
200
- request.kernelVersion !== runtime.buildIdentity
206
+ request.modality !== request.artifact.modality ||
207
+ request.liveProtocolVersion !== current.liveProtocolVersion ||
208
+ request.modelSchemaVersion !== current.modelSchemaVersion ||
209
+ request.snapshotVersion !== current.snapshotVersion ||
210
+ request.commandProtocolVersion !== current.commandProtocolVersion ||
211
+ request.committedTransactionProtocolVersion !== current.committedTransactionProtocolVersion
201
212
  ) {
202
213
  throw new EditableArtifactCompatibilityError();
203
214
  }
@@ -334,23 +345,28 @@ class RandomEditableArtifactDurableExportIds implements EditableArtifactDurableE
334
345
  function materializationProfiles(
335
346
  capabilities: EditableArtifactNativeMaterializerCapabilities,
336
347
  ): EditableArtifactMaterializationProfilePort {
348
+ const spreadsheetCompatibility = currentEditableArtifactCompatibility("spreadsheet");
337
349
  if (
338
350
  capabilities.protocol !== "OGAMC001" ||
339
351
  capabilities.runtimeKind !== "native" ||
340
352
  capabilities.maxOutputBytes !== EDITABLE_ARTIFACT_EXPORT_MAX_DOWNLOAD_BYTES ||
341
353
  capabilities.codecVersions["opengeni.xlsx"] === undefined ||
342
- !capabilities.supportedModelSchemaVersions.includes(1) ||
343
- !capabilities.supportedOperationProtocolVersions.includes(1) ||
344
- !capabilities.supportedSnapshotProtocolVersions.includes(1)
354
+ capabilities.supportedModelSchemaVersions[0] !== spreadsheetCompatibility.modelSchemaVersion ||
355
+ capabilities.supportedOperationProtocolVersions[0] !==
356
+ spreadsheetCompatibility.committedTransactionProtocolVersion ||
357
+ capabilities.supportedSnapshotProtocolVersions[0] !== spreadsheetCompatibility.snapshotVersion
345
358
  ) {
346
359
  throw new Error("Verified artifact materializer profile is incompatible");
347
360
  }
348
361
  const codecVersion = capabilities.codecVersions["opengeni.xlsx"];
349
362
  return Object.freeze({
363
+ supportedFormats: EDITABLE_ARTIFACT_EXPORT_FORMATS,
350
364
  async resolve(input: Parameters<EditableArtifactMaterializationProfilePort["resolve"]>[0]) {
365
+ // EDITABLE_ARTIFACT_EXPORT_FORMATS is what agents are told exists.
351
366
  if (
352
367
  input.modality !== "spreadsheet" ||
353
368
  input.format !== "xlsx" ||
369
+ !EDITABLE_ARTIFACT_EXPORT_FORMATS[input.modality].includes(input.format) ||
354
370
  Object.keys(input.options).length !== 0
355
371
  ) {
356
372
  return null;