@opengeni/api-router 3.0.1 → 3.1.2

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 (546) hide show
  1. package/dist/access-grant-rls.d.ts +8 -1
  2. package/dist/admission-trace.d.ts +8 -0
  3. package/dist/app.d.ts +50 -3
  4. package/dist/app.js +10 -1
  5. package/dist/artifact-catalog-cursor.d.ts +1 -0
  6. package/dist/attached-browser-viewer.d.ts +11 -0
  7. package/dist/auth/managed-auth-attempt-context.d.ts +2 -0
  8. package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
  9. package/dist/auth/managed-auth-session-adapter.d.ts +9 -1
  10. package/dist/auth/managed-auth.d.ts +72 -5
  11. package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
  12. package/dist/auth/new-signups-gate.d.ts +23 -0
  13. package/dist/auth/signup-funnel-metrics.d.ts +44 -0
  14. package/dist/azure-live.d.ts +28 -0
  15. package/dist/browser-action-fences.d.ts +13 -0
  16. package/dist/browser-controller-authority.d.ts +1 -61
  17. package/dist/browser-ephemeral.d.ts +5 -0
  18. package/dist/browser-lost-runtime-end.d.ts +24 -0
  19. package/dist/browser-state-authority.d.ts +1 -27
  20. package/dist/chunk-OGQDXVXY.js +18 -0
  21. package/dist/chunk-OGQDXVXY.js.map +1 -0
  22. package/dist/{chunk-AJ62T5QN.js → chunk-OT56OY4V.js} +80503 -39869
  23. package/dist/chunk-OT56OY4V.js.map +1 -0
  24. package/dist/claude-default-models.d.ts +19 -0
  25. package/dist/claude-subscription-core.d.ts +50 -0
  26. package/dist/claude-subscription-oauth.d.ts +36 -0
  27. package/dist/claude-subscription-profile.d.ts +9 -0
  28. package/dist/claude-subscription-usage.d.ts +6 -0
  29. package/dist/claude-workspace-connection.d.ts +15 -0
  30. package/dist/codemode.d.ts +40 -5
  31. package/dist/codex-realtime.d.ts +29 -3
  32. package/dist/codex-session-pointers.d.ts +19 -0
  33. package/dist/connection-ownership.d.ts +6 -3
  34. package/dist/controller-data-plane.d.ts +16 -0
  35. package/dist/credit-promotion-snapshot.d.ts +6 -0
  36. package/dist/editable-artifact-source-session.d.ts +3 -0
  37. package/dist/editable-artifact-websocket.d.ts +5 -3
  38. package/dist/fatal-process-boundary.d.ts +9 -1
  39. package/dist/github-access.d.ts +7 -1
  40. package/dist/github-browser-flow.d.ts +1 -1
  41. package/dist/http/acting-person.d.ts +36 -0
  42. package/dist/http/api-contract-compat.d.ts +19 -0
  43. package/dist/http/api-error.d.ts +50 -1
  44. package/dist/http/auth.d.ts +8 -1
  45. package/dist/http/cors.d.ts +12 -0
  46. package/dist/http/deprecation.d.ts +42 -0
  47. package/dist/http/keyed-admission.d.ts +12 -0
  48. package/dist/http/local-browser-boundary.d.ts +72 -0
  49. package/dist/http/metrics-listener.d.ts +22 -0
  50. package/dist/http/path-identifier.d.ts +17 -0
  51. package/dist/http/registered-route-label.d.ts +16 -0
  52. package/dist/http/rejection-telemetry.d.ts +34 -0
  53. package/dist/http/request-body.d.ts +27 -0
  54. package/dist/http/request-source.d.ts +41 -3
  55. package/dist/http/sse.d.ts +12 -1
  56. package/dist/http/unmatched-route.d.ts +18 -0
  57. package/dist/http/user-content.d.ts +36 -0
  58. package/dist/http/variable-sets-removed.d.ts +41 -0
  59. package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
  60. package/dist/index.js +1279 -108
  61. package/dist/index.js.map +1 -1
  62. package/dist/integration-connect-metrics.d.ts +35 -0
  63. package/dist/integration-endpoint-test.d.ts +20 -0
  64. package/dist/integrations/api-integrations.d.ts +2 -2
  65. package/dist/integrations/atlassian.d.ts +8 -3
  66. package/dist/integrations/fiken.d.ts +3 -1
  67. package/dist/integrations/github-lens-connect.d.ts +37 -66
  68. package/dist/integrations/google-drive.d.ts +2 -0
  69. package/dist/integrations/integration-commit-authority.d.ts +13 -0
  70. package/dist/integrations/marketplace-plugin.d.ts +43 -43
  71. package/dist/integrations/oauth-client.d.ts +171 -12
  72. package/dist/integrations/oauth-profiles.d.ts +42 -13
  73. package/dist/integrations/onepassword-vault-provider.d.ts +9 -0
  74. package/dist/integrations/slack-bot.d.ts +285 -7
  75. package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
  76. package/dist/integrations/slack-interactions.d.ts +89 -10
  77. package/dist/integrations/slack-mrkdwn.d.ts +41 -0
  78. package/dist/integrations/slack-routing.d.ts +1 -1
  79. package/dist/integrations/slack-session-defaults.d.ts +58 -0
  80. package/dist/integrations/slack-task-file-upload.d.ts +36 -0
  81. package/dist/integrations/slack-tool-review.d.ts +5 -0
  82. package/dist/interaction-agent-access.d.ts +13 -8
  83. package/dist/interaction-agent-version.d.ts +21 -0
  84. package/dist/interaction-holder-heartbeat.d.ts +5 -0
  85. package/dist/interaction-metrics.d.ts +27 -2
  86. package/dist/interaction-route-stages.d.ts +25 -0
  87. package/dist/interaction-secrets-vault.d.ts +20 -0
  88. package/dist/interaction-secrets.d.ts +103 -0
  89. package/dist/mcp/action-catalog-types.d.ts +14 -0
  90. package/dist/mcp/action-catalog.gen.d.ts +2 -0
  91. package/dist/mcp/action-descriptions.d.ts +4 -0
  92. package/dist/mcp/action-schema-imports.gen.d.ts +1 -0
  93. package/dist/mcp/capability-account-readiness.d.ts +7 -0
  94. package/dist/mcp/child-read-evidence.d.ts +9 -0
  95. package/dist/mcp/company-profile-agent-admin.d.ts +12 -0
  96. package/dist/mcp/contract-input.d.ts +13 -0
  97. package/dist/mcp/documents.d.ts +2 -0
  98. package/dist/mcp/first-party-tool-permissions.d.ts +3 -606
  99. package/dist/mcp/notification-tools.d.ts +26 -0
  100. package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
  101. package/dist/mcp/scheduled-task-input.d.ts +1309 -0
  102. package/dist/mcp/scheduled-task-view.d.ts +217 -3
  103. package/dist/mcp/secret-tools.d.ts +14 -0
  104. package/dist/mcp/server.d.ts +108 -5
  105. package/dist/mcp/session-admin-access-tools.d.ts +33 -0
  106. package/dist/mcp/session-event-errors.d.ts +28 -0
  107. package/dist/mcp/session-event-view.d.ts +62 -0
  108. package/dist/mcp/session-view.d.ts +15 -0
  109. package/dist/mcp/session-wait.d.ts +18 -0
  110. package/dist/mcp/site-agent-clamp-tools.d.ts +38 -0
  111. package/dist/mcp/site-data-tools.d.ts +22 -0
  112. package/dist/mcp/site-publication-tools.d.ts +19 -0
  113. package/dist/mcp/site-sql-tools.d.ts +27 -0
  114. package/dist/mcp-oauth.d.ts +37 -4
  115. package/dist/model-calls/chat-completions.d.ts +87 -0
  116. package/dist/model-calls/pending-usage-settlements.d.ts +57 -0
  117. package/dist/model-calls/service.d.ts +36 -0
  118. package/dist/model-catalog.d.ts +9 -3
  119. package/dist/native-push-dispatch.d.ts +69 -0
  120. package/dist/observability.d.ts +3 -1
  121. package/dist/organization-mcp.d.ts +82 -0
  122. package/dist/prepared-mcp-actor.d.ts +77 -0
  123. package/dist/prepared-mcp-permissions.d.ts +8 -0
  124. package/dist/routes/analytics-consent.d.ts +26 -0
  125. package/dist/routes/api-integrations.d.ts +11 -0
  126. package/dist/routes/api-keys.d.ts +7 -7
  127. package/dist/routes/automations.d.ts +2 -0
  128. package/dist/routes/billing.d.ts +59 -0
  129. package/dist/routes/browser-sessions.d.ts +65 -2
  130. package/dist/routes/chat-completions.d.ts +11 -0
  131. package/dist/routes/claude-core-usage.d.ts +20 -0
  132. package/dist/routes/claude-subscription-accounts.d.ts +3 -0
  133. package/dist/routes/claude-subscription-oauth.d.ts +3 -0
  134. package/dist/routes/client-errors.d.ts +182 -0
  135. package/dist/routes/codex-core.d.ts +401 -0
  136. package/dist/routes/codex.d.ts +64 -2
  137. package/dist/routes/computer-sessions.d.ts +6 -1
  138. package/dist/routes/desktop-distribution.d.ts +32 -0
  139. package/dist/routes/github-browser-fonts.gen.d.ts +2 -0
  140. package/dist/routes/github-browser-pages.d.ts +27 -0
  141. package/dist/routes/inbox.d.ts +13 -0
  142. package/dist/routes/insights-response-cache.d.ts +10 -0
  143. package/dist/routes/insights-usage.d.ts +12 -0
  144. package/dist/routes/insights.d.ts +28 -0
  145. package/dist/routes/interaction-placement-message.d.ts +7 -0
  146. package/dist/routes/managed-sign-in-methods.d.ts +6 -0
  147. package/dist/routes/model-account-choice.d.ts +13 -0
  148. package/dist/routes/model-account-settings.d.ts +19 -0
  149. package/dist/routes/native-app-auth.d.ts +12 -0
  150. package/dist/routes/organization-integration-policy.d.ts +8 -0
  151. package/dist/routes/organization-integrations.d.ts +6 -0
  152. package/dist/routes/organization-mcp-connections.d.ts +3 -0
  153. package/dist/routes/organization-model-defaults.d.ts +9 -0
  154. package/dist/routes/organization-service-accounts.d.ts +3 -0
  155. package/dist/routes/personal-api-keys.d.ts +3 -0
  156. package/dist/routes/session-admin-access.d.ts +3 -0
  157. package/dist/routes/session-artifact-associations.d.ts +4 -0
  158. package/dist/routes/session-history-imports.d.ts +20 -0
  159. package/dist/routes/sessions.d.ts +38 -2
  160. package/dist/routes/site-data.d.ts +18 -0
  161. package/dist/routes/site-publishing.d.ts +5 -0
  162. package/dist/routes/site-runtime.d.ts +31 -0
  163. package/dist/routes/site-sql.d.ts +16 -0
  164. package/dist/routes/slack-bot-access.d.ts +3 -0
  165. package/dist/routes/subscription-account-pools.d.ts +21 -0
  166. package/dist/routes/subscription-core-http.d.ts +5 -0
  167. package/dist/routes/subscription-pool-access.d.ts +37 -0
  168. package/dist/routes/subscription-pool-core.d.ts +153 -0
  169. package/dist/routes/supergrok.d.ts +6 -6
  170. package/dist/routes/usage-allowances.d.ts +12 -0
  171. package/dist/routes/variable-sets-removed.d.ts +2 -0
  172. package/dist/routes/vault-providers.d.ts +34 -0
  173. package/dist/routes/vaults.d.ts +3 -0
  174. package/dist/routes/workspace-integrations.d.ts +35 -0
  175. package/dist/routes/workspace-model-providers.d.ts +4 -0
  176. package/dist/routes/workspaces.d.ts +11 -2
  177. package/dist/sandbox/agent-update.d.ts +64 -0
  178. package/dist/sandbox/auth-callout.d.ts +8 -0
  179. package/dist/sandbox/channel-a.d.ts +15 -1
  180. package/dist/sandbox/enrollment.d.ts +26 -4
  181. package/dist/sandbox/machine-audience.d.ts +29 -0
  182. package/dist/sandbox/machines.d.ts +15 -2
  183. package/dist/sandbox/metrics-ingestion.d.ts +6 -2
  184. package/dist/sandbox/screen-control.d.ts +85 -0
  185. package/dist/sandbox/viewer.d.ts +5 -1
  186. package/dist/sandbox-file-artifacts.d.ts +17 -1
  187. package/dist/scheduled-task-blockers.d.ts +39 -0
  188. package/dist/scheduled-task-deletion.d.ts +3 -4
  189. package/dist/scheduled-task-lifecycle.d.ts +14 -0
  190. package/dist/secret-answers.d.ts +40 -0
  191. package/dist/session-create-observability.d.ts +5 -0
  192. package/dist/session-event-view-36GO3IL7.js +528 -0
  193. package/dist/session-event-view-36GO3IL7.js.map +1 -0
  194. package/dist/signed-state-secret.d.ts +18 -0
  195. package/dist/site-agent-guard.d.ts +53 -0
  196. package/dist/site-data/operations.d.ts +103 -0
  197. package/dist/site-data/service.d.ts +203 -0
  198. package/dist/site-frame-guard.d.ts +32 -0
  199. package/dist/site-publishing/agent-data-tools.d.ts +84 -0
  200. package/dist/site-publishing/agent-model.d.ts +58 -0
  201. package/dist/site-publishing/agent-session.d.ts +16 -0
  202. package/dist/site-publishing/content-scanner.d.ts +31 -0
  203. package/dist/site-publishing/edge-sync.d.ts +48 -0
  204. package/dist/site-publishing/gateway-signature.d.ts +56 -0
  205. package/dist/site-publishing/limits.d.ts +63 -0
  206. package/dist/site-publishing/page-tool-authority.d.ts +30 -0
  207. package/dist/site-publishing/platform-usage.d.ts +113 -0
  208. package/dist/site-publishing/platform.d.ts +21 -0
  209. package/dist/site-publishing/readiness.d.ts +62 -0
  210. package/dist/site-publishing/runtime.d.ts +179 -0
  211. package/dist/site-publishing/service.d.ts +264 -0
  212. package/dist/site-publishing/session-events.d.ts +22 -0
  213. package/dist/site-publishing/session-views.d.ts +36 -0
  214. package/dist/site-publishing/viewer.d.ts +40 -0
  215. package/dist/site-session-origin.d.ts +31 -6
  216. package/dist/site-sql/format.d.ts +47 -0
  217. package/dist/site-sql/gateway.d.ts +50 -0
  218. package/dist/site-sql/service.d.ts +213 -0
  219. package/dist/temporal-schedule-sync.d.ts +26 -0
  220. package/dist/transcription/billing-refusal.d.ts +8 -0
  221. package/dist/transcription/normalize.d.ts +23 -0
  222. package/dist/transcription/providers/azure-mai.d.ts +12 -0
  223. package/dist/transcription/providers/azure-openai.d.ts +4 -0
  224. package/dist/transcription/providers/openai.d.ts +16 -0
  225. package/dist/transcription/providers/subscription-core.d.ts +39 -0
  226. package/dist/transcription/service.d.ts +10 -1
  227. package/dist/transcription/wav-duration.d.ts +8 -0
  228. package/dist/workspace-tool-gateway-attestations.d.ts +37 -0
  229. package/dist/workspace-tool-gateway-observability.d.ts +16 -0
  230. package/dist/workspace-tool-gateway-secrets.d.ts +27 -0
  231. package/dist/workspace-tool-gateway.d.ts +102 -6
  232. package/dist/workspace-tool-target-fence.d.ts +116 -0
  233. package/dist/workspace-tool-target.d.ts +225 -0
  234. package/dist/workspace-webhook-dispatch.d.ts +26 -0
  235. package/dist/xai-subscription-core.d.ts +60 -0
  236. package/package.json +25 -20
  237. package/src/access-grant-rls.ts +64 -14
  238. package/src/admission-trace.ts +14 -0
  239. package/src/app.ts +1684 -252
  240. package/src/artifact-catalog-cursor.ts +1 -0
  241. package/src/attached-browser-viewer.ts +26 -0
  242. package/src/auth/managed-auth-attempt-context.ts +9 -0
  243. package/src/auth/managed-auth-rate-limits.ts +252 -0
  244. package/src/auth/managed-auth-session-adapter.ts +64 -29
  245. package/src/auth/managed-auth.ts +303 -35
  246. package/src/auth/managed-email.ts +18 -1
  247. package/src/auth/managed-sign-in-notifications.ts +81 -0
  248. package/src/auth/new-signups-gate.ts +49 -0
  249. package/src/auth/organization-user-setup.ts +3 -3
  250. package/src/auth/signup-funnel-metrics.ts +164 -0
  251. package/src/azure-live.ts +103 -0
  252. package/src/browser-action-fences.ts +45 -0
  253. package/src/browser-controller-authority.ts +1 -186
  254. package/src/browser-ephemeral.ts +39 -0
  255. package/src/browser-lost-runtime-end.ts +71 -0
  256. package/src/browser-state-authority.ts +1 -236
  257. package/src/claude-default-models.ts +37 -0
  258. package/src/claude-subscription-core.ts +154 -0
  259. package/src/claude-subscription-oauth.ts +352 -0
  260. package/src/claude-subscription-profile.ts +73 -0
  261. package/src/claude-subscription-usage.ts +51 -0
  262. package/src/claude-workspace-connection.ts +82 -0
  263. package/src/codemode.ts +236 -39
  264. package/src/codex-realtime.ts +181 -53
  265. package/src/codex-session-pointers.ts +80 -0
  266. package/src/company-brain-okf.ts +1 -1
  267. package/src/connected-machine-computer-access.ts +2 -1
  268. package/src/connection-ownership.ts +19 -13
  269. package/src/controller-data-plane.ts +34 -0
  270. package/src/credit-promotion-snapshot.ts +36 -0
  271. package/src/editable-artifact-production.ts +10 -0
  272. package/src/editable-artifact-source-session.ts +123 -0
  273. package/src/editable-artifact-websocket.ts +16 -3
  274. package/src/fatal-process-boundary.ts +67 -3
  275. package/src/gateway-realtime.ts +12 -8
  276. package/src/github-access.ts +31 -5
  277. package/src/github-browser-flow.ts +1 -1
  278. package/src/http/acting-person.ts +105 -0
  279. package/src/http/api-contract-compat.ts +49 -0
  280. package/src/http/api-error.ts +210 -2
  281. package/src/http/auth.ts +68 -4
  282. package/src/http/cors.ts +37 -5
  283. package/src/http/deprecation.ts +118 -0
  284. package/src/http/keyed-admission.ts +29 -0
  285. package/src/http/local-browser-boundary.ts +343 -0
  286. package/src/http/metrics-listener.ts +57 -0
  287. package/src/http/path-identifier.ts +54 -0
  288. package/src/http/registered-route-label.ts +34 -0
  289. package/src/http/rejection-telemetry.ts +120 -0
  290. package/src/http/request-body.ts +127 -0
  291. package/src/http/request-source.ts +154 -13
  292. package/src/http/sse.ts +88 -28
  293. package/src/http/unmatched-route.ts +60 -0
  294. package/src/http/user-content.ts +158 -0
  295. package/src/http/variable-sets-removed.ts +122 -0
  296. package/src/http/websocket-upgrade-dispatch.ts +29 -0
  297. package/src/index.ts +107 -57
  298. package/src/integration-connect-metrics.ts +228 -0
  299. package/src/integration-endpoint-test.ts +291 -0
  300. package/src/integrations/api-integrations.ts +81 -7
  301. package/src/integrations/atlassian.ts +202 -83
  302. package/src/integrations/fiken.ts +66 -38
  303. package/src/integrations/github-app-connect.ts +64 -18
  304. package/src/integrations/github-lens-connect.ts +8 -29
  305. package/src/integrations/google-drive.ts +448 -152
  306. package/src/integrations/integration-commit-authority.ts +69 -0
  307. package/src/integrations/marketplace-plugin.ts +1 -1
  308. package/src/integrations/oauth-client.ts +733 -193
  309. package/src/integrations/oauth-profiles.ts +116 -45
  310. package/src/integrations/onepassword-vault-provider.ts +16 -0
  311. package/src/integrations/personal-github-repositories.ts +1 -1
  312. package/src/integrations/personal-github.ts +61 -35
  313. package/src/integrations/provider-oauth.ts +67 -85
  314. package/src/integrations/slack-app-home.ts +5 -5
  315. package/src/integrations/slack-bot.ts +893 -201
  316. package/src/integrations/slack-file-upload-flow.ts +147 -0
  317. package/src/integrations/slack-install.ts +7 -7
  318. package/src/integrations/slack-interactions.ts +1589 -299
  319. package/src/integrations/slack-mrkdwn.ts +193 -0
  320. package/src/integrations/slack-routing.ts +2 -2
  321. package/src/integrations/slack-session-defaults.ts +224 -0
  322. package/src/integrations/slack-task-file-upload.ts +323 -0
  323. package/src/integrations/slack-tool-review.ts +65 -0
  324. package/src/integrations/social-oauth.ts +90 -58
  325. package/src/interaction-agent-access.ts +40 -20
  326. package/src/interaction-agent-version.ts +85 -0
  327. package/src/interaction-holder-heartbeat.ts +24 -8
  328. package/src/interaction-metrics.ts +164 -2
  329. package/src/interaction-route-stages.ts +94 -0
  330. package/src/interaction-secrets-vault.ts +213 -0
  331. package/src/interaction-secrets.ts +426 -0
  332. package/src/mcp/action-catalog-types.ts +14 -0
  333. package/src/mcp/action-catalog.gen.ts +8014 -0
  334. package/src/mcp/action-descriptions.ts +299 -0
  335. package/src/mcp/action-schema-imports.gen.ts +304 -0
  336. package/src/mcp/capability-account-readiness.ts +17 -0
  337. package/src/mcp/child-read-evidence.ts +19 -0
  338. package/src/mcp/company-profile-agent-admin.ts +13 -0
  339. package/src/mcp/contract-input.ts +165 -0
  340. package/src/mcp/documents.ts +9 -2
  341. package/src/mcp/editable-artifacts.ts +29 -11
  342. package/src/mcp/files.ts +5 -1
  343. package/src/mcp/first-party-tool-permissions.ts +7 -285
  344. package/src/mcp/knowledge-entries.ts +108 -34
  345. package/src/mcp/notification-tools.ts +480 -0
  346. package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
  347. package/src/mcp/scheduled-task-input.ts +89 -0
  348. package/src/mcp/scheduled-task-view.ts +63 -3
  349. package/src/mcp/secret-tools.ts +185 -0
  350. package/src/mcp/server.ts +2213 -1116
  351. package/src/mcp/session-admin-access-tools.ts +163 -0
  352. package/src/mcp/session-event-errors.ts +123 -0
  353. package/src/mcp/session-event-view.ts +395 -13
  354. package/src/mcp/session-view.ts +3 -0
  355. package/src/mcp/session-wait.ts +67 -7
  356. package/src/mcp/site-agent-clamp-tools.ts +140 -0
  357. package/src/mcp/site-data-tools.ts +339 -0
  358. package/src/mcp/site-publication-tools.ts +201 -0
  359. package/src/mcp/site-sql-tools.ts +427 -0
  360. package/src/mcp-oauth.ts +635 -45
  361. package/src/model-calls/chat-completions.ts +352 -0
  362. package/src/model-calls/pending-usage-settlements.ts +125 -0
  363. package/src/model-calls/service.ts +694 -0
  364. package/src/model-catalog.ts +68 -17
  365. package/src/native-push-dispatch.ts +457 -0
  366. package/src/observability.ts +15 -1
  367. package/src/organization-mcp.ts +485 -0
  368. package/src/prepared-mcp-actor.ts +154 -0
  369. package/src/prepared-mcp-permissions.ts +38 -0
  370. package/src/routes/analytics-consent.ts +123 -0
  371. package/src/routes/api-integrations.ts +268 -9
  372. package/src/routes/api-keys.ts +164 -25
  373. package/src/routes/artifact-catalog.ts +111 -0
  374. package/src/routes/automations.ts +163 -90
  375. package/src/routes/billing.ts +535 -59
  376. package/src/routes/browser-sessions.ts +966 -342
  377. package/src/routes/canonical-human-identities.ts +61 -0
  378. package/src/routes/capabilities.ts +112 -5
  379. package/src/routes/channels.ts +4 -3
  380. package/src/routes/chat-completions.ts +235 -0
  381. package/src/routes/claude-core-usage.ts +147 -0
  382. package/src/routes/claude-subscription-accounts.ts +233 -0
  383. package/src/routes/claude-subscription-oauth.ts +175 -0
  384. package/src/routes/client-errors.ts +394 -0
  385. package/src/routes/codex-core.ts +687 -0
  386. package/src/routes/codex.ts +1277 -1119
  387. package/src/routes/company-brain.ts +4 -0
  388. package/src/routes/computer-sessions.ts +319 -85
  389. package/src/routes/connect.ts +277 -175
  390. package/src/routes/connections.ts +690 -363
  391. package/src/routes/desktop-distribution.ts +217 -0
  392. package/src/routes/documents.ts +13 -7
  393. package/src/routes/editable-artifacts.ts +74 -4
  394. package/src/routes/enrollments.ts +110 -16
  395. package/src/routes/external-identity-links.ts +13 -12
  396. package/src/routes/files.ts +41 -16
  397. package/src/routes/github-browser-fonts.gen.ts +12 -0
  398. package/src/routes/github-browser-pages.ts +258 -0
  399. package/src/routes/github.ts +200 -75
  400. package/src/routes/inbox.ts +353 -0
  401. package/src/routes/insights-response-cache.ts +83 -0
  402. package/src/routes/insights-usage.ts +345 -0
  403. package/src/routes/insights.ts +103 -8
  404. package/src/routes/install.ts +51 -10
  405. package/src/routes/integration-facets.ts +70 -28
  406. package/src/routes/interaction-placement-message.ts +12 -0
  407. package/src/routes/knowledge.ts +136 -27
  408. package/src/routes/machines.ts +189 -135
  409. package/src/routes/managed-auth-session-sets.ts +43 -10
  410. package/src/routes/managed-onboarding.ts +39 -19
  411. package/src/routes/managed-sign-in-methods.ts +433 -0
  412. package/src/routes/memory-slack-publications.ts +3 -2
  413. package/src/routes/model-account-choice.ts +194 -0
  414. package/src/routes/model-account-settings.ts +235 -0
  415. package/src/routes/model-connection-access.ts +210 -48
  416. package/src/routes/native-app-auth.ts +296 -0
  417. package/src/routes/organization-integration-policy.ts +116 -0
  418. package/src/routes/organization-integrations.ts +326 -0
  419. package/src/routes/organization-mcp-connections.ts +183 -0
  420. package/src/routes/organization-memberships.ts +205 -19
  421. package/src/routes/organization-model-defaults.ts +110 -0
  422. package/src/routes/organization-model-providers.ts +74 -3
  423. package/src/routes/organization-service-accounts.ts +128 -0
  424. package/src/routes/organization-sessions.ts +21 -5
  425. package/src/routes/personal-api-keys.ts +184 -0
  426. package/src/routes/personal-github-git-broker.ts +2 -2
  427. package/src/routes/personal-github.ts +9 -4
  428. package/src/routes/plugins.ts +46 -7
  429. package/src/routes/pr-review-github.ts +105 -118
  430. package/src/routes/pr-review.ts +88 -82
  431. package/src/routes/preference-registry.ts +18 -0
  432. package/src/routes/rigs.ts +48 -13
  433. package/src/routes/scheduled-tasks.ts +347 -27
  434. package/src/routes/session-admin-access.ts +271 -0
  435. package/src/routes/session-artifact-associations.ts +164 -0
  436. package/src/routes/session-history-imports.ts +305 -0
  437. package/src/routes/sessions.ts +1682 -363
  438. package/src/routes/site-data.ts +340 -0
  439. package/src/routes/site-publishing.ts +584 -0
  440. package/src/routes/site-runtime.ts +1944 -0
  441. package/src/routes/site-sql.ts +263 -0
  442. package/src/routes/skill-content.ts +72 -7
  443. package/src/routes/skills.ts +5 -4
  444. package/src/routes/slack-bot-access.ts +108 -0
  445. package/src/routes/social.ts +27 -15
  446. package/src/routes/subscription-account-pools.ts +209 -0
  447. package/src/routes/subscription-core-http.ts +18 -0
  448. package/src/routes/subscription-pool-access.ts +180 -0
  449. package/src/routes/subscription-pool-core.ts +552 -0
  450. package/src/routes/supergrok.ts +174 -655
  451. package/src/routes/transcription-recordings.ts +71 -4
  452. package/src/routes/transcriptions.ts +26 -2
  453. package/src/routes/usage-allowances.ts +381 -0
  454. package/src/routes/variable-sets-removed.ts +19 -0
  455. package/src/routes/vault-providers.ts +782 -0
  456. package/src/routes/vaults.ts +421 -0
  457. package/src/routes/video-generation.ts +30 -12
  458. package/src/routes/workspace-artifacts.ts +165 -53
  459. package/src/routes/workspace-integrations.ts +576 -0
  460. package/src/routes/workspace-model-providers.ts +148 -0
  461. package/src/routes/workspace-state.ts +4 -0
  462. package/src/routes/workspaces.ts +625 -117
  463. package/src/sandbox/agent-update.ts +315 -0
  464. package/src/sandbox/auth-callout.ts +104 -21
  465. package/src/sandbox/channel-a.ts +165 -55
  466. package/src/sandbox/enrollment.ts +131 -22
  467. package/src/sandbox/machine-audience.ts +192 -0
  468. package/src/sandbox/machines.ts +75 -31
  469. package/src/sandbox/metrics-ingestion.ts +133 -2
  470. package/src/sandbox/rematerialize.ts +51 -21
  471. package/src/sandbox/screen-control.ts +289 -0
  472. package/src/sandbox/viewer.ts +33 -58
  473. package/src/sandbox-file-artifacts.ts +53 -27
  474. package/src/scheduled-task-blockers.ts +293 -0
  475. package/src/scheduled-task-deletion.ts +13 -3
  476. package/src/scheduled-task-lifecycle.ts +84 -0
  477. package/src/secret-answers.ts +119 -0
  478. package/src/session-create-observability.ts +46 -0
  479. package/src/session-realtime-context.ts +26 -4
  480. package/src/signed-state-secret.ts +58 -0
  481. package/src/site-agent-guard.ts +261 -0
  482. package/src/site-data/operations.ts +777 -0
  483. package/src/site-data/service.ts +1043 -0
  484. package/src/site-frame-guard.ts +107 -0
  485. package/src/site-publishing/agent-data-tools.ts +250 -0
  486. package/src/site-publishing/agent-model.ts +127 -0
  487. package/src/site-publishing/agent-session.ts +148 -0
  488. package/src/site-publishing/content-scanner.ts +93 -0
  489. package/src/site-publishing/edge-sync.ts +148 -0
  490. package/src/site-publishing/gateway-signature.ts +198 -0
  491. package/src/site-publishing/limits.ts +315 -0
  492. package/src/site-publishing/page-tool-authority.ts +111 -0
  493. package/src/site-publishing/platform-usage.ts +479 -0
  494. package/src/site-publishing/platform.ts +98 -0
  495. package/src/site-publishing/readiness.ts +330 -0
  496. package/src/site-publishing/runtime.ts +831 -0
  497. package/src/site-publishing/service.ts +1282 -0
  498. package/src/site-publishing/session-events.ts +262 -0
  499. package/src/site-publishing/session-views.ts +262 -0
  500. package/src/site-publishing/viewer.ts +75 -0
  501. package/src/site-session-origin.ts +91 -6
  502. package/src/site-sql/format.ts +134 -0
  503. package/src/site-sql/gateway.ts +168 -0
  504. package/src/site-sql/service.ts +1636 -0
  505. package/src/site-uploads.ts +27 -5
  506. package/src/temporal-schedule-sync.ts +74 -0
  507. package/src/transcription/billing-refusal.ts +14 -0
  508. package/src/transcription/normalize.ts +77 -0
  509. package/src/transcription/providers/azure-mai.ts +98 -0
  510. package/src/transcription/providers/azure-openai.ts +16 -7
  511. package/src/transcription/providers/codex-subscription.ts +190 -67
  512. package/src/transcription/providers/openai.ts +79 -5
  513. package/src/transcription/providers/subscription-core.ts +125 -0
  514. package/src/transcription/providers/xai-subscription.ts +81 -83
  515. package/src/transcription/segmenter.ts +7 -1
  516. package/src/transcription/service.ts +239 -10
  517. package/src/transcription/wav-duration.ts +39 -0
  518. package/src/workspace-deletion.ts +25 -1
  519. package/src/workspace-tool-gateway-attestations.ts +133 -0
  520. package/src/workspace-tool-gateway-observability.ts +64 -0
  521. package/src/workspace-tool-gateway-secrets.ts +104 -0
  522. package/src/workspace-tool-gateway.ts +921 -103
  523. package/src/workspace-tool-target-fence.ts +380 -0
  524. package/src/workspace-tool-target.ts +554 -0
  525. package/src/workspace-webhook-dispatch.ts +225 -0
  526. package/src/xai-realtime.ts +85 -81
  527. package/src/xai-subscription-core.ts +172 -0
  528. package/dist/browser-auth-broker.d.ts +0 -20
  529. package/dist/chunk-AJ62T5QN.js.map +0 -1
  530. package/dist/connection-authority-owner.d.ts +0 -59
  531. package/dist/routes/connection-authorities.d.ts +0 -3
  532. package/dist/routes/environments.d.ts +0 -5
  533. package/dist/routes/host-mcp-bindings.d.ts +0 -5
  534. package/dist/routes/host-mcp-resolvers.d.ts +0 -3
  535. package/dist/routes/packs.d.ts +0 -3
  536. package/dist/session-event-view-MU3HMNV3.js +0 -264
  537. package/dist/session-event-view-MU3HMNV3.js.map +0 -1
  538. package/dist/xai-subscription-auth.d.ts +0 -23
  539. package/src/browser-auth-broker.ts +0 -155
  540. package/src/connection-authority-owner.ts +0 -61
  541. package/src/routes/connection-authorities.ts +0 -139
  542. package/src/routes/environments.ts +0 -388
  543. package/src/routes/host-mcp-bindings.ts +0 -122
  544. package/src/routes/host-mcp-resolvers.ts +0 -41
  545. package/src/routes/packs.ts +0 -784
  546. package/src/xai-subscription-auth.ts +0 -139
@@ -1,16 +1,26 @@
1
- import { resolveVoiceInputProviderRegistry, type Settings } from "@opengeni/config";
1
+ import {
2
+ resolveVoiceInputProviderRegistry,
3
+ voiceInputCreditBillingActive,
4
+ type Settings,
5
+ } from "@opengeni/config";
2
6
  import { VOICE_INPUT_ACCEPTED_MIME_TYPES } from "@opengeni/contracts";
7
+ import { voiceTranscriptionSettlementKeys } from "@opengeni/db";
3
8
  import {
9
+ createVoiceInputBilling,
4
10
  filenameForMimeType,
5
11
  isAcceptedMimeType,
6
12
  normalizeMimeType,
7
13
  TRANSCRIPTION_PROVIDER_REQUEST_TIMEOUT_MILLISECONDS,
8
14
  type TranscriptionAvailabilityContext,
15
+ type TranscriptionBilling,
16
+ type TranscriptionBillingContext,
9
17
  type TranscriptionProvider,
10
18
  type TranscriptionService,
11
19
  TranscriptionServiceError,
12
20
  } from "@opengeni/core";
13
21
  import type { Database } from "@opengeni/db";
22
+ import { createFfmpegAudioNormalizer, type TranscriptionAudioNormalizer } from "./normalize";
23
+ import { createMaiTranscriptionProvider } from "./providers/azure-mai";
14
24
  import { createAzureOpenAiTranscriptionProvider } from "./providers/azure-openai";
15
25
  import { createCodexSubscriptionTranscriptionProvider } from "./providers/codex-subscription";
16
26
  import { createOpenAiTranscriptionProvider } from "./providers/openai";
@@ -26,6 +36,14 @@ export function createTranscriptionService(input: {
26
36
  providerRequestTimeoutMilliseconds?: number;
27
37
  /** Test seam for evaluating persisted absolute deadlines after delayed setup. */
28
38
  now?: () => Date;
39
+ /** Credit admission/settlement for deployment-funded providers. */
40
+ billing?: TranscriptionBilling;
41
+ /** Test seam: trusted one-shot decode + duration (defaults to ffmpeg). */
42
+ normalizeAudio?: TranscriptionAudioNormalizer;
43
+ /** Loud operator log for settlement failures after provider success. */
44
+ log?: (message: string, attributes: Record<string, string | number | boolean>) => void;
45
+ /** In-process settlement retry pacing after an inline failure. */
46
+ settlementRetryDelaysMilliseconds?: readonly number[];
29
47
  }): TranscriptionService {
30
48
  const providers: TranscriptionProvider[] = resolveVoiceInputProviderRegistry(input.settings).map(
31
49
  (config) => {
@@ -35,6 +53,12 @@ export function createTranscriptionService(input: {
35
53
  ...config,
36
54
  ...(input.fetch ? { fetch: input.fetch } : {}),
37
55
  });
56
+ case "azure-mai":
57
+ return createMaiTranscriptionProvider({
58
+ ...config,
59
+ ffmpegPath: input.settings.voiceInputFfmpegPath,
60
+ ...(input.fetch ? { fetch: input.fetch } : {}),
61
+ });
38
62
  case "azure-openai":
39
63
  return createAzureOpenAiTranscriptionProvider({
40
64
  ...config,
@@ -66,16 +90,119 @@ export function createTranscriptionService(input: {
66
90
  const providerRequestTimeoutMilliseconds =
67
91
  input.providerRequestTimeoutMilliseconds ?? TRANSCRIPTION_PROVIDER_REQUEST_TIMEOUT_MILLISECONDS;
68
92
  const now = input.now ?? (() => new Date());
93
+ const log =
94
+ input.log ??
95
+ ((message: string, attributes: Record<string, string | number | boolean>) => {
96
+ console.error(message, attributes);
97
+ });
98
+ const billing =
99
+ input.billing ??
100
+ createVoiceInputBilling({
101
+ db: input.db,
102
+ settings: input.settings,
103
+ onReconcileError: (error, scope) => {
104
+ log("Voice input charge reconciliation failed", {
105
+ ...scope,
106
+ errorClass: error instanceof Error ? error.name : "UnknownError",
107
+ error: boundedErrorMessage(error),
108
+ });
109
+ },
110
+ });
111
+ let normalizer: TranscriptionAudioNormalizer | undefined = input.normalizeAudio;
112
+ const normalizeAudio: TranscriptionAudioNormalizer = (request) => {
113
+ normalizer ??= createFfmpegAudioNormalizer({ ffmpegPath: input.settings.voiceInputFfmpegPath });
114
+ return normalizer(request);
115
+ };
116
+ const retryDelays = input.settlementRetryDelaysMilliseconds ?? [2_000, 15_000, 60_000];
117
+ type Settlement = Parameters<TranscriptionBilling["settle"]>[0];
118
+ /**
119
+ * Post-use settlement never fails the request: the provider already returned
120
+ * text the user is waiting for. A failure is logged with the exact
121
+ * idempotency keys and retried in-process; if the receipt committed but the
122
+ * debit did not, the next admission in the workspace reconciles it.
123
+ */
124
+ const settleWithoutFailing = async (settlement: Settlement): Promise<number> => {
125
+ try {
126
+ return (await billing.settle(settlement)).creditCostMicros;
127
+ } catch (error) {
128
+ reportUnsettled(settlement, error, 0, retryDelays.length > 0 && !deterministic(error));
129
+ if (!deterministic(error)) scheduleSettlementRetry(settlement, 0);
130
+ return 0;
131
+ }
132
+ };
133
+ const deterministic = (error: unknown) => error instanceof TranscriptionServiceError;
134
+ const scheduleSettlementRetry = (settlement: Settlement, attempt: number) => {
135
+ const delay = retryDelays[attempt];
136
+ if (delay === undefined) return;
137
+ const timer = setTimeout(() => {
138
+ void billing.settle(settlement).then(
139
+ () => {
140
+ log("Voice input charge settled on retry", {
141
+ ...settlementAttributes(settlement),
142
+ attempt: attempt + 1,
143
+ });
144
+ },
145
+ (error: unknown) => {
146
+ const more = attempt + 1 < retryDelays.length;
147
+ reportUnsettled(settlement, error, attempt + 1, more);
148
+ if (more) scheduleSettlementRetry(settlement, attempt + 1);
149
+ },
150
+ );
151
+ }, delay);
152
+ (timer as ReturnType<typeof setTimeout> & { unref?: () => void }).unref?.();
153
+ };
154
+ const reportUnsettled = (
155
+ settlement: Settlement,
156
+ error: unknown,
157
+ attempt: number,
158
+ willRetry: boolean,
159
+ ) => {
160
+ log(
161
+ willRetry
162
+ ? "Voice input charge is unsettled after provider success; retrying"
163
+ : "Voice input charge is UNSETTLED after provider success; manual reconciliation needed unless its usage receipt committed",
164
+ {
165
+ ...settlementAttributes(settlement),
166
+ attempt,
167
+ willRetry,
168
+ errorClass: error instanceof Error ? error.name : "UnknownError",
169
+ error: boundedErrorMessage(error),
170
+ },
171
+ );
172
+ };
173
+ const creditBillingActive = voiceInputCreditBillingActive(input.settings);
174
+ /** Deployment-funded calls are charged; the workspace's own subscriptions never are. */
175
+ const chargeable = (provider: TranscriptionProvider) =>
176
+ creditBillingActive && provider.deploymentFunded !== undefined;
69
177
  return {
70
178
  limits: () => limits,
71
179
  async available(context) {
72
- return (await Promise.all(providers.map((provider) => provider.available(context)))).some(
73
- Boolean,
180
+ return Boolean(
181
+ await firstAvailable(orderedProviders(providers, context ?? {}), context ?? {}),
182
+ );
183
+ },
184
+ async availableProviderIds(context) {
185
+ // Every ready provider, for the workspace provider picker. One failing
186
+ // probe means that provider is not ready; it never fails the caller.
187
+ const available = await Promise.all(
188
+ providers.map(async (provider) => {
189
+ try {
190
+ return (await provider.available(context)) ? provider.id : null;
191
+ } catch {
192
+ return null;
193
+ }
194
+ }),
74
195
  );
196
+ return available.filter((id): id is string => id !== null);
75
197
  },
76
198
  async selectProvider(context) {
77
199
  return (await firstAvailable(orderedProviders(providers, context), context))?.id ?? null;
78
200
  },
201
+ async admit({ providerId, accountId, workspaceId, attribution }) {
202
+ const provider = providers.find((candidate) => candidate.id === providerId);
203
+ if (!provider || !chargeable(provider)) return;
204
+ await billing.admit({ accountId, workspaceId, attribution });
205
+ },
79
206
  async transcribe(request) {
80
207
  const mimeType = normalizeMimeType(request.mimeType);
81
208
  if (!isAcceptedMimeType(mimeType, limits.acceptedMimeTypes)) {
@@ -120,6 +247,65 @@ export function createTranscriptionService(input: {
120
247
  message: "Transcription provider does not support bounded requests.",
121
248
  });
122
249
  }
250
+ if (chargeable(provider)) {
251
+ // Fail closed: a deployment-paid call is never sent without a price
252
+ // and a trusted settlement identity.
253
+ if (!provider.deploymentFunded?.pricing || !request.billing) {
254
+ throw new TranscriptionServiceError({
255
+ code: "unavailable",
256
+ message: "Transcription billing is not configured.",
257
+ });
258
+ }
259
+ try {
260
+ await billing.admit({
261
+ accountId: request.accountId,
262
+ workspaceId: request.workspaceId,
263
+ attribution: request.billing.attribution,
264
+ });
265
+ } catch (error) {
266
+ // Nothing was sent yet: a fallback-safe refusal (Opengeni credits
267
+ // turned off here) lets the next provider, such as a connected
268
+ // subscription, serve the request.
269
+ if (
270
+ error instanceof TranscriptionServiceError &&
271
+ error.fallbackSafe &&
272
+ !request.providerId &&
273
+ request.fallbackEnabled !== false &&
274
+ !request.signal?.aborted
275
+ ) {
276
+ const excludedProviders = [...(request.excludedProviders ?? []), provider.id];
277
+ if (
278
+ await firstAvailable(
279
+ orderedProviders(providers, { ...request, excludedProviders }),
280
+ request,
281
+ )
282
+ ) {
283
+ return await this.transcribe({ ...request, excludedProviders });
284
+ }
285
+ }
286
+ throw error;
287
+ }
288
+ }
289
+ let audio = request.audio;
290
+ let providerMimeType = mimeType;
291
+ let billingContext: TranscriptionBillingContext | undefined = request.billing;
292
+ let audioSeconds = request.durationSeconds ?? 0;
293
+ if (chargeable(provider) && billingContext?.trustedDurationSeconds === undefined) {
294
+ // A deployment-paid one-shot upload is decoded by the server first, so
295
+ // the call always carries a duration the server measured from bytes it
296
+ // produced. That bills any usage shape we cannot price, and bounds
297
+ // what is sent upstream to the configured maximum recording length.
298
+ const normalized = await normalizeAudio({
299
+ audio,
300
+ mimeType,
301
+ maxDurationSeconds: limits.maxDurationSeconds,
302
+ ...(request.signal ? { signal: request.signal } : {}),
303
+ });
304
+ audio = normalized.bytes;
305
+ providerMimeType = "audio/wav";
306
+ audioSeconds = normalized.durationSeconds;
307
+ billingContext = { ...billingContext!, trustedDurationSeconds: normalized.durationSeconds };
308
+ }
123
309
  const startedAt = performance.now();
124
310
  const remainingMilliseconds = request.providerDeadlineAt
125
311
  ? remainingTranscriptionProviderRequestMilliseconds(request.providerDeadlineAt, now())
@@ -135,12 +321,12 @@ export function createTranscriptionService(input: {
135
321
  });
136
322
  }
137
323
  const deadline = createProviderRequestDeadline(request.signal, remainingMilliseconds);
138
- let result: { text: string; languages: string[] };
324
+ let result: Awaited<ReturnType<TranscriptionProvider["transcribe"]>>;
139
325
  try {
140
326
  result = await provider.transcribe({
141
- audio: request.audio,
142
- mimeType,
143
- filename: filenameForMimeType(mimeType),
327
+ audio,
328
+ mimeType: providerMimeType,
329
+ filename: filenameForMimeType(providerMimeType),
144
330
  workspaceId: request.workspaceId,
145
331
  accountId: request.accountId,
146
332
  subjectId: request.subjectId,
@@ -183,11 +369,30 @@ export function createTranscriptionService(input: {
183
369
  } finally {
184
370
  deadline.dispose();
185
371
  }
372
+ const latencyMs = Math.round(performance.now() - startedAt);
373
+ let creditCostMicros = 0;
374
+ const settle = async () => {
375
+ if (chargeable(provider) && provider.deploymentFunded?.pricing && billingContext) {
376
+ creditCostMicros = await settleWithoutFailing({
377
+ accountId: request.accountId,
378
+ workspaceId: request.workspaceId,
379
+ providerId: provider.id,
380
+ model: provider.deploymentFunded.model,
381
+ pricing: provider.deploymentFunded.pricing,
382
+ usage: result.usage ?? null,
383
+ billing: billingContext,
384
+ });
385
+ }
386
+ };
387
+ if (!request.deferBillingSettlement) await settle();
186
388
  return {
187
- ...result,
389
+ text: result.text,
390
+ languages: result.languages,
188
391
  providerId: provider.id,
189
- audioSeconds: request.durationSeconds ?? 0,
190
- latencyMs: Math.round(performance.now() - startedAt),
392
+ audioSeconds,
393
+ latencyMs,
394
+ creditCostMicros,
395
+ ...(request.deferBillingSettlement ? { settleBilling: settle } : {}),
191
396
  };
192
397
  },
193
398
  };
@@ -272,3 +477,27 @@ async function exactAvailable(
272
477
  const provider = providers.find((candidate) => candidate.id === providerId);
273
478
  return provider && (await provider.available(context)) ? provider : null;
274
479
  }
480
+
481
+ function settlementAttributes(settlement: {
482
+ accountId: string;
483
+ workspaceId: string;
484
+ providerId: string;
485
+ billing: TranscriptionBillingContext;
486
+ }): Record<string, string> {
487
+ const keys = voiceTranscriptionSettlementKeys({
488
+ workspaceId: settlement.workspaceId,
489
+ sourceId: settlement.billing.sourceId,
490
+ });
491
+ return {
492
+ accountId: settlement.accountId,
493
+ workspaceId: settlement.workspaceId,
494
+ providerId: settlement.providerId,
495
+ sourceId: settlement.billing.sourceId,
496
+ usageIdempotencyKey: keys.usageIdempotencyKey,
497
+ debitIdempotencyKey: keys.debitIdempotencyKey,
498
+ };
499
+ }
500
+
501
+ function boundedErrorMessage(error: unknown): string {
502
+ return (error instanceof Error ? error.message : String(error)).slice(0, 500);
503
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Duration of a PCM RIFF/WAVE buffer the server itself produced (resumable
3
+ * provider segments are ffmpeg-normalized WAV). Used only as the trusted
4
+ * billing fallback when a provider reports no usage; never applied to
5
+ * client-uploaded bytes. Returns null for anything that is not a well-formed
6
+ * WAV with a positive byte rate.
7
+ */
8
+ export function wavDurationSeconds(bytes: Uint8Array): number | null {
9
+ if (bytes.byteLength < 12) return null;
10
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
11
+ if (ascii(bytes, 0) !== "RIFF" || ascii(bytes, 8) !== "WAVE") return null;
12
+ let offset = 12;
13
+ let byteRate: number | null = null;
14
+ while (offset + 8 <= bytes.byteLength) {
15
+ const id = ascii(bytes, offset);
16
+ const size = view.getUint32(offset + 4, true);
17
+ const body = offset + 8;
18
+ if (id === "fmt " && body + 12 <= bytes.byteLength) {
19
+ byteRate = view.getUint32(body + 8, true);
20
+ } else if (id === "data") {
21
+ if (!byteRate) return null;
22
+ // Streamed WAV writes a placeholder size; the actual payload is the rest.
23
+ const available = bytes.byteLength - body;
24
+ const dataBytes = size === 0 || size === 0xffffffff ? available : Math.min(size, available);
25
+ return dataBytes / byteRate;
26
+ }
27
+ offset = body + size + (size % 2);
28
+ }
29
+ return null;
30
+ }
31
+
32
+ function ascii(bytes: Uint8Array, offset: number): string {
33
+ return String.fromCharCode(
34
+ bytes[offset] ?? 0,
35
+ bytes[offset + 1] ?? 0,
36
+ bytes[offset + 2] ?? 0,
37
+ bytes[offset + 3] ?? 0,
38
+ );
39
+ }
@@ -1,7 +1,12 @@
1
- import { deleteWorkspaceIfQuiescent, nestedPostgresSqlState } from "@opengeni/db";
1
+ import {
2
+ deleteWorkspaceIfQuiescent,
3
+ nestedPostgresSqlState,
4
+ safeDatabaseErrorFacts,
5
+ } from "@opengeni/db";
2
6
  import type { ApiRouteDeps } from "@opengeni/core";
3
7
  import { HTTPException } from "hono/http-exception";
4
8
 
9
+ import { dropSiteSqlDatabases, siteSqlSitesOfWorkspace } from "./site-sql/service";
5
10
  import { processTemporalScheduleCleanupClaims } from "./temporal-schedule-cleanup";
6
11
  import { workspaceDeleteObserver } from "./workspace-delete-observability";
7
12
 
@@ -14,6 +19,9 @@ export async function deleteWorkspaceForRequest(
14
19
  },
15
20
  ): Promise<void> {
16
21
  const observer = workspaceDeleteObserver(deps.observability, input);
22
+ // Site SQL rows in Postgres cascade with the workspace; the Durable Objects
23
+ // holding the data do not, so note them first and drop them after.
24
+ const siteSqlSites = await siteSqlSitesOfWorkspace(deps, input);
17
25
  let deleted;
18
26
  try {
19
27
  deleted = await deleteWorkspaceIfQuiescent(deps.db, {
@@ -28,6 +36,21 @@ export async function deleteWorkspaceForRequest(
28
36
  if (state === "P0002") {
29
37
  throw new HTTPException(404, { message: "workspace not found" });
30
38
  }
39
+ if (state === "23503") {
40
+ // Retention and linked-record FKs are intentional deletion boundaries.
41
+ // The failed transaction has rolled back: do not erase history, retry
42
+ // the cascade, or dispatch any external schedule cleanup.
43
+ // Editable documents, spreadsheets, and presentations keep immutable
44
+ // version history that only the organization retention lifecycle may
45
+ // erase, so name that cause without exposing the constraint itself.
46
+ const constraint = safeDatabaseErrorFacts(error).constraint ?? "";
47
+ const retainedRecords = constraint.startsWith("editable_artifact")
48
+ ? "the workspace's editable documents, spreadsheets, or presentations, whose version history is retained"
49
+ : "retained or linked records";
50
+ throw new HTTPException(409, {
51
+ message: `workspace deletion is blocked by ${retainedRecords}; keep the workspace, revoke access, and disable scheduled work instead`,
52
+ });
53
+ }
31
54
  throw error;
32
55
  }
33
56
 
@@ -61,4 +84,5 @@ export async function deleteWorkspaceForRequest(
61
84
  },
62
85
  deleted.temporalScheduleCleanups,
63
86
  );
87
+ await dropSiteSqlDatabases(deps, siteSqlSites, { workspaceId: input.workspaceId });
64
88
  }
@@ -0,0 +1,133 @@
1
+ import type { ToolGatewayCatalog, ToolGatewayIdentity } from "@opengeni/contracts";
2
+ import { digestCanonicalJson } from "@opengeni/tool-gateway";
3
+
4
+ /**
5
+ * Content-free memory of complete workspace tool catalogs this API process
6
+ * produced for one exact caller scope.
7
+ *
8
+ * A complete catalog digest covers every enabled connector, so verifying a
9
+ * call's `catalogDigest` used to require connecting and listing every
10
+ * connector again. The attestation remembers, per complete digest, only the
11
+ * canonical digest of each entry. A later call can then prepare just its
12
+ * target connector live and prove that the entry it is about to execute is
13
+ * byte-for-byte the entry its caller saw in that complete catalog.
14
+ *
15
+ * It never stores credentials, prepared gateways, connections, schemas,
16
+ * arguments, or results, and grants no authority: every call still resolves
17
+ * live caller, account, connection, policy, and Site authority. A miss,
18
+ * expiry, or entry mismatch falls back to complete preparation and the exact
19
+ * historical stale-catalog contract.
20
+ */
21
+ export type WorkspaceToolGatewayCatalogAttestations = {
22
+ record(scope: string, catalog: Pick<ToolGatewayCatalog, "digest" | "entries">): void;
23
+ /** The attested entry digest, or `undefined` when the catalog is unknown or expired. */
24
+ entryDigest(
25
+ scope: string,
26
+ catalogDigest: string,
27
+ identity: ToolGatewayIdentity,
28
+ ): string | undefined;
29
+ /** Entry digests currently retained (bounded by `maxEntries`). */
30
+ readonly retainedEntries: number;
31
+ };
32
+
33
+ export type WorkspaceToolGatewayCatalogAttestationOptions = {
34
+ /** Fixed lifetime from complete preparation; use never extends it. */
35
+ ttlMs?: number;
36
+ maxScopes?: number;
37
+ maxCatalogsPerScope?: number;
38
+ /** Global bound on retained entry digests across all scopes and catalogs. */
39
+ maxEntries?: number;
40
+ now?: () => number;
41
+ };
42
+
43
+ export const WORKSPACE_TOOL_GATEWAY_ATTESTATION_TTL_MS = 10 * 60_000;
44
+ const DEFAULT_MAX_SCOPES = 512;
45
+ const DEFAULT_MAX_CATALOGS_PER_SCOPE = 4;
46
+ // About 250k entries * a few hundred bytes: on the order of 100 MiB per API
47
+ // process in the worst case, typically far less.
48
+ const DEFAULT_MAX_ENTRIES = 250_000;
49
+
50
+ type AttestedCatalog = { expiresAt: number; entries: ReadonlyMap<string, string> };
51
+
52
+ export function createWorkspaceToolGatewayCatalogAttestations(
53
+ options: WorkspaceToolGatewayCatalogAttestationOptions = {},
54
+ ): WorkspaceToolGatewayCatalogAttestations {
55
+ const ttlMs = options.ttlMs ?? WORKSPACE_TOOL_GATEWAY_ATTESTATION_TTL_MS;
56
+ const maxScopes = options.maxScopes ?? DEFAULT_MAX_SCOPES;
57
+ const maxCatalogsPerScope = options.maxCatalogsPerScope ?? DEFAULT_MAX_CATALOGS_PER_SCOPE;
58
+ const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
59
+ const now = options.now ?? Date.now;
60
+ // Map insertion order is the eviction order (least recently recorded first).
61
+ const scopes = new Map<string, Map<string, AttestedCatalog>>();
62
+ let retainedEntries = 0;
63
+ const drop = (scope: string, catalogs: Map<string, AttestedCatalog>, digest: string) => {
64
+ const attested = catalogs.get(digest);
65
+ if (!attested) return;
66
+ retainedEntries -= attested.entries.size;
67
+ catalogs.delete(digest);
68
+ if (catalogs.size === 0) scopes.delete(scope);
69
+ };
70
+ const dropOldest = (): boolean => {
71
+ const oldest = scopes.entries().next().value;
72
+ if (!oldest) return false;
73
+ drop(oldest[0], oldest[1], oldest[1].keys().next().value!);
74
+ return true;
75
+ };
76
+ const overBudget = (): boolean => scopes.size > maxScopes || retainedEntries > maxEntries;
77
+ return {
78
+ record(scope, catalog) {
79
+ const at = now();
80
+ for (const [candidateScope, catalogs] of [...scopes]) {
81
+ for (const [digest, attested] of [...catalogs]) {
82
+ if (attested.expiresAt <= at) drop(candidateScope, catalogs, digest);
83
+ }
84
+ }
85
+ // A catalog larger than the whole budget is simply not attested; its
86
+ // calls keep using complete preparation.
87
+ if (catalog.entries.length > maxEntries) return;
88
+ const entries = new Map<string, string>();
89
+ for (const entry of catalog.entries) {
90
+ entries.set(
91
+ workspaceToolGatewayIdentityKey(entry.identity),
92
+ digestWorkspaceToolGatewayCatalogEntry(entry),
93
+ );
94
+ }
95
+ const existing = scopes.get(scope);
96
+ if (existing) drop(scope, existing, catalog.digest);
97
+ const catalogs = scopes.get(scope) ?? new Map<string, AttestedCatalog>();
98
+ scopes.delete(scope);
99
+ catalogs.set(catalog.digest, { expiresAt: at + ttlMs, entries });
100
+ retainedEntries += entries.size;
101
+ while (catalogs.size > maxCatalogsPerScope) {
102
+ const oldestDigest = catalogs.keys().next().value!;
103
+ retainedEntries -= catalogs.get(oldestDigest)!.entries.size;
104
+ catalogs.delete(oldestDigest);
105
+ }
106
+ scopes.set(scope, catalogs);
107
+ while (overBudget()) {
108
+ if (!dropOldest()) break;
109
+ }
110
+ },
111
+ entryDigest(scope, catalogDigest, identity) {
112
+ const catalogs = scopes.get(scope);
113
+ const attested = catalogs?.get(catalogDigest);
114
+ if (!catalogs || !attested) return undefined;
115
+ if (attested.expiresAt <= now()) {
116
+ drop(scope, catalogs, catalogDigest);
117
+ return undefined;
118
+ }
119
+ return attested.entries.get(workspaceToolGatewayIdentityKey(identity));
120
+ },
121
+ get retainedEntries() {
122
+ return retainedEntries;
123
+ },
124
+ };
125
+ }
126
+
127
+ export function digestWorkspaceToolGatewayCatalogEntry(entry: unknown): string {
128
+ return digestCanonicalJson(entry);
129
+ }
130
+
131
+ function workspaceToolGatewayIdentityKey(identity: ToolGatewayIdentity): string {
132
+ return JSON.stringify([identity.serverId, identity.toolName]);
133
+ }
@@ -15,6 +15,70 @@ export type WorkspaceToolGatewayOutcome =
15
15
 
16
16
  const DURATION_BUCKETS = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60];
17
17
 
18
+ export function recordWorkspaceToolTargetOperation(
19
+ observability: Observability | null | undefined,
20
+ input: {
21
+ operation: "resolve" | "invoke" | "target-approvals" | "manifest";
22
+ outcome: "ok" | "failed";
23
+ durationSeconds: number;
24
+ },
25
+ ): void {
26
+ try {
27
+ const labels = { operation: input.operation, outcome: input.outcome };
28
+ observability?.incrementCounter({
29
+ name: "opengeni_tool_target_operations_total",
30
+ help: "Targeted workspace tool requests; never full-catalog fallback.",
31
+ labels,
32
+ });
33
+ observability?.observeHistogram({
34
+ name: "opengeni_tool_target_duration_seconds",
35
+ help: "Total targeted request time including metadata, provider preparation and execution.",
36
+ labels,
37
+ buckets: DURATION_BUCKETS,
38
+ value: Math.max(0, input.durationSeconds),
39
+ });
40
+ } catch {
41
+ /* Observation never changes execution. */
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Bounded preparation telemetry: how long the request spent constructing,
47
+ * credentialing, connecting, and listing connectors before any execution, and
48
+ * whether a call used target-only preparation through a catalog attestation.
49
+ */
50
+ export function recordWorkspaceToolGatewayPreparation(
51
+ observability: Observability | null | undefined,
52
+ input: {
53
+ operation: "catalog" | "call";
54
+ scope: "complete" | "target";
55
+ attestation: "hit" | "miss" | "mismatch" | "bypass" | "record";
56
+ durationSeconds: number;
57
+ },
58
+ ): void {
59
+ try {
60
+ const labels = {
61
+ operation: input.operation,
62
+ scope: input.scope,
63
+ attestation: input.attestation,
64
+ };
65
+ observability?.incrementCounter({
66
+ name: "opengeni_tool_gateway_preparations_total",
67
+ help: "Workspace tool gateway HTTP preparations by bounded operation, scope, and catalog attestation outcome.",
68
+ labels,
69
+ });
70
+ observability?.observeHistogram({
71
+ name: "opengeni_tool_gateway_preparation_duration_seconds",
72
+ help: "Workspace tool gateway HTTP preparation wall time in seconds, before execution.",
73
+ labels,
74
+ buckets: DURATION_BUCKETS,
75
+ value: Math.max(0, input.durationSeconds),
76
+ });
77
+ } catch {
78
+ // Telemetry must never change gateway execution truth.
79
+ }
80
+ }
81
+
18
82
  /**
19
83
  * Low-cardinality gateway telemetry shared by HTTP/SDK/Site and aggregate MCP
20
84
  * adapters. Tool names, workspace/subject ids, arguments, results, credentials,