@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
@@ -0,0 +1,694 @@
1
+ import {
2
+ buildModelResolver,
3
+ CODEX_CLIENT_VERSION,
4
+ CodexReloginRequired,
5
+ codexRequestStorage,
6
+ type CodexFetch,
7
+ type CodexRequestContext,
8
+ type CodexUsagePayload,
9
+ } from "@opengeni/codex";
10
+ import { codexUpstreamModelSlugs, type ConfiguredModel, type Settings } from "@opengeni/config";
11
+ import type { EntitlementsPort } from "@opengeni/contracts";
12
+ import {
13
+ admissibleWorkspaceModel,
14
+ admitModelCall,
15
+ clampReasoningEffortForConfiguredModel,
16
+ isWorkspaceModelAdmissible,
17
+ ModelCallError,
18
+ resolveCallerWorkspaceModelSelections,
19
+ resolveDefaultSessionModelForSelections,
20
+ resolveWorkspaceCatalogSettings,
21
+ recordSessionUsageLimitEvent,
22
+ requireSessionUsageLimitAllows,
23
+ type SessionUsageLimitMetricsSink,
24
+ sessionUsageLimitRefusalFromError,
25
+ settingsWithModelProviderCredentials,
26
+ settleModelUsage,
27
+ type HeldSessionUsageReceipt,
28
+ type ModelCallCaller,
29
+ type ModelCallInput,
30
+ type ModelCallOutput,
31
+ type ModelCallService,
32
+ type WorkspaceModelSelection,
33
+ } from "@opengeni/core";
34
+ import {
35
+ acquireSubscriptionCoreCodexOperationLease,
36
+ buildSubscriptionCoreCodexConnectionTokenResolver,
37
+ ClaudeSubscriptionReconnectRequired,
38
+ connectionModelAllowed,
39
+ fetchSubscriptionCoreCodexUsage,
40
+ getWorkspace,
41
+ listSubscriptionCoreCodexOperationCandidates,
42
+ readCodexCutoverDisposition,
43
+ releaseSubscriptionCoreCodexOperationLease,
44
+ renewSubscriptionCoreCodexOperationLease,
45
+ reserveSubscriptionCoreCodexOperationRequest,
46
+ settleSubscriptionCoreCodexOperationRequest,
47
+ withCreditDebitAttribution,
48
+ fenceSessionUsageReceipt,
49
+ releaseSessionUsageReceipt,
50
+ settleSessionUsageReceipt,
51
+ type Database,
52
+ type SubscriptionCoreCodexOperationLeaseRef,
53
+ type SubscriptionCoreCodexOperationScope,
54
+ } from "@opengeni/db";
55
+ import {
56
+ MultiProviderModelProvider,
57
+ normalizeModelCallUsage,
58
+ runSingleModelCall,
59
+ SingleModelCallProviderError,
60
+ SingleModelCallUnsupportedError,
61
+ type SingleModelCallResult,
62
+ } from "@opengeni/runtime/model-call";
63
+ import { XaiSubscriptionReloginRequired } from "@opengeni/xai-subscription";
64
+ import { PendingUsageSettlements } from "./pending-usage-settlements";
65
+ import {
66
+ creditDebitAttributionForGrant,
67
+ withAccessGrantSessionRlsContext,
68
+ } from "../access-grant-rls";
69
+
70
+ export type ModelCallServiceDeps = {
71
+ db: Database;
72
+ settings: Settings;
73
+ /** Catalog source settings; defaults to `settings`. */
74
+ catalogSourceSettings?: Settings;
75
+ entitlements?: EntitlementsPort | null;
76
+ codexFetch?: CodexFetch;
77
+ log?: (message: string, attributes: Record<string, string | number | boolean>) => void;
78
+ /** Content-free task usage-limit counters (closed-set labels). */
79
+ usageLimitMetrics?: SessionUsageLimitMetricsSink | null;
80
+ /** Retained task usage receipts awaiting DB-only recovery (tests inject one). */
81
+ pendingUsageSettlements?: PendingUsageSettlements;
82
+ };
83
+
84
+ const PROVIDER_MESSAGE_MAX_LENGTH = 512;
85
+
86
+ export function createModelCallService(deps: ModelCallServiceDeps): ModelCallService {
87
+ const catalogSource = deps.catalogSourceSettings ?? deps.settings;
88
+ const pendingSettlements = deps.pendingUsageSettlements ?? new PendingUsageSettlements();
89
+
90
+ async function selections(caller: ModelCallCaller): Promise<{
91
+ catalogSettings: Settings;
92
+ selections: WorkspaceModelSelection[];
93
+ }> {
94
+ return await withAccessGrantSessionRlsContext(deps, caller.grant, async () => {
95
+ const catalogSettings = (
96
+ await resolveWorkspaceCatalogSettings(deps.db, catalogSource, {
97
+ accountId: caller.accountId,
98
+ workspaceId: caller.workspaceId,
99
+ })
100
+ ).settings;
101
+ return {
102
+ catalogSettings,
103
+ selections: await resolveCallerWorkspaceModelSelections(deps.db, catalogSettings, {
104
+ accountId: caller.accountId,
105
+ workspaceId: caller.workspaceId,
106
+ subjectId: caller.subjectId,
107
+ }),
108
+ };
109
+ });
110
+ }
111
+
112
+ async function resolveModel(
113
+ caller: ModelCallCaller,
114
+ requested: string | null,
115
+ ): Promise<{ selection: WorkspaceModelSelection; catalogSettings: Settings }> {
116
+ const resolved = await selections(caller);
117
+ let modelId = requested;
118
+ if (!modelId) {
119
+ const workspace = await getWorkspace(deps.db, caller.workspaceId);
120
+ modelId = (
121
+ await resolveDefaultSessionModelForSelections(deps.db, {
122
+ settings: resolved.catalogSettings,
123
+ accountId: caller.accountId,
124
+ workspaceSettings: workspace?.settings ?? {},
125
+ selections: resolved.selections,
126
+ })
127
+ ).model;
128
+ }
129
+ const selection = admissibleWorkspaceModel(resolved.selections, modelId);
130
+ if (!selection || !servedBySingleModelCalls(selection)) {
131
+ throw new ModelCallError({
132
+ status: 404,
133
+ type: "not_found_error",
134
+ code: "model_not_found",
135
+ param: "model",
136
+ message: `The model '${modelId}' does not exist or is not available in this workspace.`,
137
+ });
138
+ }
139
+ return { selection, catalogSettings: resolved.catalogSettings };
140
+ }
141
+
142
+ return {
143
+ async listModels(caller) {
144
+ const { selections: all } = await selections(caller);
145
+ return all
146
+ .filter((entry) => isWorkspaceModelAdmissible(entry) && servedBySingleModelCalls(entry))
147
+ .map(({ model }) => ({
148
+ id: model.id,
149
+ label: model.label,
150
+ providerLabel: model.providerLabel,
151
+ }));
152
+ },
153
+
154
+ async call(input) {
155
+ const { selection, catalogSettings } = await resolveModel(input, input.model);
156
+ const model = selection.model;
157
+ assertModelSupportsRequest(model, input.request);
158
+ const source = model.credentialSource;
159
+ const subscription = source.kind === "connected_subscription" ? source.provider : null;
160
+ const chargesOpenGeniCredits = model.billing.metering === "opengeni_credits";
161
+ const countsTowardTokenCap = model.billing.upstreamPayer === "deployment";
162
+ // a call made by a live agent attempt (its grant was verified
163
+ // by the attempt boundary) counts against that task's usage limit and is
164
+ // refused once the limit is reached. Other callers have no task.
165
+ const usageLimitSessionId = attemptSessionId(input.grant);
166
+ const sourceId = `model_call:${input.requestId}`;
167
+ if (usageLimitSessionId) {
168
+ if (pendingSettlements.full) {
169
+ // Never drop a retained receipt to make room for another call.
170
+ recordSessionUsageLimitEvent(deps.usageLimitMetrics, "single_call", "unavailable");
171
+ throw sessionUsageUnavailable();
172
+ }
173
+ try {
174
+ await pendingSettlements.flush(usageLimitSessionId);
175
+ } catch {
176
+ recordSessionUsageLimitEvent(deps.usageLimitMetrics, "single_call", "unavailable");
177
+ throw sessionUsageUnavailable();
178
+ }
179
+ // Admission opens this call's durable custody marker in the same
180
+ // statement, so its usage is owed by the task on every replica until
181
+ // settlement fills it (or maintenance discloses it as unpriced).
182
+ await requireSingleCallSessionUsageLimit(deps, {
183
+ accountId: input.accountId,
184
+ workspaceId: input.workspaceId,
185
+ sessionId: usageLimitSessionId,
186
+ runtime: true,
187
+ openSourceId: sourceId,
188
+ });
189
+ }
190
+ const releaseMarker = async (): Promise<void> => {
191
+ if (!usageLimitSessionId) return;
192
+ await releaseSessionUsageReceipt(deps.db, {
193
+ accountId: input.accountId,
194
+ workspaceId: input.workspaceId,
195
+ sessionId: usageLimitSessionId,
196
+ sourceId,
197
+ }).catch(() => {
198
+ // An unreleased marker only blocks after the overdue window and is
199
+ // then disclosed as unpriced by maintenance; never fails the call.
200
+ });
201
+ };
202
+ // Everything between opening the marker and dispatching the request can
203
+ // refuse the call. No request was sent on those exits, so the marker is
204
+ // released; once dispatch starts, custody stays until settlement.
205
+ const prepareDispatch = async () => {
206
+ const admission = await admitModelCall(deps, {
207
+ accountId: input.accountId,
208
+ workspaceId: input.workspaceId,
209
+ model: model.id,
210
+ chargesOpenGeniCredits,
211
+ countsTowardTokenCap,
212
+ subjectId: input.subjectId,
213
+ });
214
+ if (!admission.allowed) {
215
+ throw new ModelCallError({
216
+ status: admission.denial === "insufficient_credits" ? 402 : 429,
217
+ type: "insufficient_quota",
218
+ code: admission.denial,
219
+ message: admission.message,
220
+ });
221
+ }
222
+ const settings = await settingsWithModelProviderCredentials(deps.db, {
223
+ accountId: input.accountId,
224
+ workspaceId: input.workspaceId,
225
+ settings: catalogSettings,
226
+ productModelId: model.id,
227
+ codexSubscriptionActive: subscription === "codex",
228
+ });
229
+ // A single Claude subscription call has no shared-core operation path
230
+ // yet and the legacy Claude pool is deleted (C4): fail closed.
231
+ if (subscription === "claude") throw subscriptionCapacityUnavailable("Claude");
232
+ return { admission, settings };
233
+ };
234
+ let prepared: Awaited<ReturnType<typeof prepareDispatch>>;
235
+ try {
236
+ prepared = await prepareDispatch();
237
+ } catch (error) {
238
+ await releaseMarker();
239
+ throw error;
240
+ }
241
+ const { admission, settings } = prepared;
242
+ const request = {
243
+ ...input.request,
244
+ ...reasoningEffortFor(model, input.request.reasoningEffort),
245
+ ...(input.signal ? { signal: input.signal } : {}),
246
+ };
247
+ const execute = async (): Promise<SingleModelCallResult> => {
248
+ const binding = new MultiProviderModelProvider(settings).resolveBinding(model.id);
249
+ return await runSingleModelCall(
250
+ { client: binding.client, provider: binding.provider, modelId: binding.modelId },
251
+ request,
252
+ input.onTextDelta ? { onTextDelta: input.onTextDelta } : {},
253
+ );
254
+ };
255
+ let result: SingleModelCallResult;
256
+ try {
257
+ result =
258
+ subscription === "codex"
259
+ ? await withCodexOperation(deps, settings, input, model, execute)
260
+ : await execute();
261
+ } catch (error) {
262
+ // No response, so no reported usage to record for this call.
263
+ await releaseMarker();
264
+ const mapped = publicModelCallError(error);
265
+ if (mapped instanceof ModelCallError && mapped.status >= 500) {
266
+ // Names and statuses only: provider messages can echo prompt content.
267
+ deps.log?.("Model call failed", {
268
+ requestId: input.requestId,
269
+ model: model.id,
270
+ code: mapped.code ?? "unknown",
271
+ errorName: error instanceof Error ? error.name : typeof error,
272
+ providerStatus: providerStatus(error) ?? 0,
273
+ });
274
+ }
275
+ throw mapped;
276
+ }
277
+ const usage = result.usage;
278
+ // Settlement failure must not discard a completed answer. Every write
279
+ // below is idempotent on the request's source identity.
280
+ let owedReceipt: HeldSessionUsageReceipt | null = null;
281
+ const logSettlementFailure = (error: unknown) => {
282
+ deps.log?.("Model call usage settlement failed", {
283
+ requestId: input.requestId,
284
+ model: model.id,
285
+ errorName: error instanceof Error ? error.name : typeof error,
286
+ });
287
+ };
288
+ if (usage) {
289
+ await withCreditDebitAttribution(creditDebitAttributionForGrant(input.grant), () =>
290
+ // Execution settings carry the workspace catalog the price resolves from.
291
+ settleModelUsage(settings, deps.db, {
292
+ accountId: input.accountId,
293
+ workspaceId: input.workspaceId,
294
+ model: model.id,
295
+ chargesOpenGeniCredits,
296
+ countsTowardTokenCap,
297
+ creditPolicyRevision: admission.creditPolicyRevision,
298
+ ...(usage.gatewayBilling ? { gatewayBilling: usage.gatewayBilling } : {}),
299
+ normalizedUsage: normalizeModelCallUsage(usage.usage),
300
+ sourceId,
301
+ ...(usageLimitSessionId ? { usageLimitSessionId } : {}),
302
+ usageLimitMetrics: deps.usageLimitMetrics ?? null,
303
+ // A failed task-usage receipt never suppresses the credit
304
+ // settlement that follows it; the receipt is owed below.
305
+ receiptCustody: (held, error) => {
306
+ owedReceipt = held;
307
+ logSettlementFailure(error);
308
+ },
309
+ debitMetadata: { modelCallId: input.requestId },
310
+ }),
311
+ ).catch(async (error: unknown) => {
312
+ logSettlementFailure(error);
313
+ if (!usageLimitSessionId || owedReceipt) return;
314
+ // Settlement failed before or after the task receipt; the amount
315
+ // is unknown here. An unpriced receipt fills a still-open marker
316
+ // (disclosed, never free); a receipt already recorded for this
317
+ // source is kept and this write is a no-op conflict.
318
+ const unknownAmount: HeldSessionUsageReceipt = {
319
+ sessionId: usageLimitSessionId,
320
+ sourceId,
321
+ turnId: null,
322
+ amountMicros: null,
323
+ pricingSource: null,
324
+ model: model.id,
325
+ };
326
+ await writeOwedReceipt(deps.db, input, unknownAmount).catch(() => {
327
+ owedReceipt = unknownAmount;
328
+ });
329
+ });
330
+ } else if (usageLimitSessionId) {
331
+ // A response without a usage report is an unknown amount for the
332
+ // task: disclosed as unpriced, never counted as free.
333
+ const unreported: HeldSessionUsageReceipt = {
334
+ sessionId: usageLimitSessionId,
335
+ sourceId,
336
+ turnId: null,
337
+ amountMicros: null,
338
+ pricingSource: null,
339
+ model: model.id,
340
+ };
341
+ await writeOwedReceipt(deps.db, input, unreported).catch((error: unknown) => {
342
+ owedReceipt = unreported;
343
+ logSettlementFailure(error);
344
+ });
345
+ }
346
+ const owed = owedReceipt as HeldSessionUsageReceipt | null;
347
+ if (owed) {
348
+ // Whatever the failure class, this task's known usage is still owed.
349
+ // Retain the exact receipt for DB-only retry and fence the durable
350
+ // marker so every replica stops admitting this task's model requests
351
+ // until it lands. The provider is never called again.
352
+ const retained = pendingSettlements.retain(owed.sessionId, sourceId, () =>
353
+ writeOwedReceipt(deps.db, input, owed),
354
+ );
355
+ if (!retained) {
356
+ recordSessionUsageLimitEvent(deps.usageLimitMetrics, "single_call", "accounting_failure");
357
+ }
358
+ await fenceSessionUsageReceipt(deps.db, {
359
+ accountId: input.accountId,
360
+ workspaceId: input.workspaceId,
361
+ sessionId: owed.sessionId,
362
+ sourceId,
363
+ }).catch(() => {
364
+ // The unfilled marker still blocks once overdue.
365
+ });
366
+ }
367
+ return { model: model.id, result } satisfies ModelCallOutput;
368
+ },
369
+ };
370
+ }
371
+
372
+ async function writeOwedReceipt(
373
+ db: Database,
374
+ scope: { accountId: string; workspaceId: string },
375
+ receipt: HeldSessionUsageReceipt,
376
+ ): Promise<void> {
377
+ await settleSessionUsageReceipt(db, {
378
+ accountId: scope.accountId,
379
+ workspaceId: scope.workspaceId,
380
+ sessionId: receipt.sessionId,
381
+ sourceId: receipt.sourceId,
382
+ turnId: receipt.turnId,
383
+ amountMicros: receipt.amountMicros,
384
+ pricingSource: receipt.amountMicros === null ? null : receipt.pricingSource,
385
+ model: receipt.model,
386
+ });
387
+ }
388
+
389
+ function sessionUsageUnavailable(): ModelCallError {
390
+ return new ModelCallError({
391
+ status: 503,
392
+ type: "service_unavailable",
393
+ code: "session_usage_limit_unavailable",
394
+ message: "Usage for this task is temporarily unavailable. Try again shortly.",
395
+ });
396
+ }
397
+
398
+ /** The session of a verified live agent attempt, or null for every other caller. */
399
+ function attemptSessionId(grant: ModelCallInput["grant"]): string | null {
400
+ if (grant?.principalKind !== "agent_attempt") return null;
401
+ const sessionId = grant.metadata?.sessionId;
402
+ return typeof sessionId === "string" && sessionId.length > 0 ? sessionId : null;
403
+ }
404
+
405
+ async function requireSingleCallSessionUsageLimit(
406
+ deps: {
407
+ db: Parameters<typeof requireSessionUsageLimitAllows>[0];
408
+ usageLimitMetrics?: SessionUsageLimitMetricsSink | null;
409
+ },
410
+ input: {
411
+ accountId: string;
412
+ workspaceId: string;
413
+ sessionId: string;
414
+ runtime?: boolean;
415
+ openSourceId?: string;
416
+ },
417
+ ): Promise<void> {
418
+ try {
419
+ await requireSessionUsageLimitAllows(deps.db, input, {
420
+ sink: deps.usageLimitMetrics,
421
+ boundary: "single_call",
422
+ });
423
+ } catch (error) {
424
+ const refusal = sessionUsageLimitRefusalFromError(error);
425
+ if (refusal) {
426
+ throw new ModelCallError({
427
+ status: 402,
428
+ type: "insufficient_quota",
429
+ code: "session_usage_limit_reached",
430
+ message: refusal.message,
431
+ });
432
+ }
433
+ // Unreadable usage state is never treated as unlimited.
434
+ throw sessionUsageUnavailable();
435
+ }
436
+ }
437
+
438
+ function assertModelSupportsRequest(model: ConfiguredModel, request: ModelCallInput["request"]) {
439
+ const hasImage = request.messages.some(
440
+ (message) =>
441
+ typeof message.content !== "string" && message.content.some((part) => part.type === "image"),
442
+ );
443
+ if (hasImage && !model.capabilities.inputModalities.includes("image")) {
444
+ throw new ModelCallError({
445
+ status: 400,
446
+ type: "invalid_request_error",
447
+ code: "unsupported_content",
448
+ param: "messages",
449
+ message: `The model '${model.id}' does not accept image input.`,
450
+ });
451
+ }
452
+ if (
453
+ request.outputFormat?.type === "json_schema" &&
454
+ !model.capabilities.structuredOutput.runnable
455
+ ) {
456
+ throw new ModelCallError({
457
+ status: 400,
458
+ type: "invalid_request_error",
459
+ code: "unsupported_parameter",
460
+ param: "response_format",
461
+ message: `The model '${model.id}' does not support structured output.`,
462
+ });
463
+ }
464
+ }
465
+
466
+ /** A requested effort clamps to the model's nearest supported effort, or is dropped. */
467
+ function reasoningEffortFor(
468
+ model: ConfiguredModel,
469
+ requested: ModelCallInput["request"]["reasoningEffort"],
470
+ ): Pick<ModelCallInput["request"], "reasoningEffort"> {
471
+ if (!requested || !model.capabilities.reasoning.runnable) return {};
472
+ if (model.capabilities.reasoning.efforts.length === 0) return {};
473
+ return { reasoningEffort: clampReasoningEffortForConfiguredModel(model, requested, requested) };
474
+ }
475
+
476
+ /**
477
+ * SuperGrok runs only on the shared subscription core, whose single-call
478
+ * `completion` operation stays Codex-only (design 5.3): this API neither
479
+ * lists nor serves a SuperGrok subscription model, so a request for one is
480
+ * `model_not_found` before admission, never a misleading capacity error.
481
+ */
482
+ export function servedBySingleModelCalls(selection: WorkspaceModelSelection): boolean {
483
+ const source = selection.model.credentialSource;
484
+ return !(source.kind === "connected_subscription" && source.provider === "xai");
485
+ }
486
+
487
+ /**
488
+ * Whether the account still has included plan usage. A single call never
489
+ * spends a ChatGPT account's paid extra credits: an exhausted or unverifiable
490
+ * account is skipped before anything reaches the provider.
491
+ */
492
+ export function codexIncludedUsageAvailable(usage: CodexUsagePayload, now = Date.now()): boolean {
493
+ if (usage.status !== "ok" || usage.limitReached) return false;
494
+ const windows = [usage.fiveHour, usage.weekly].filter((window) => window !== null);
495
+ if (windows.length === 0) return false;
496
+ return windows.every(
497
+ (window) =>
498
+ Number.isFinite(window.percent) &&
499
+ (window.percent < 100 || (window.resetAt !== null && Date.parse(window.resetAt) <= now)),
500
+ );
501
+ }
502
+
503
+ /**
504
+ * A Codex single call is a sessionless operation on the shared subscription
505
+ * core, like transcription: it holds its own operation lease on a shared
506
+ * organization- or workspace-scoped connection, and every physical request is
507
+ * reserved and settled against that lease. Accounts are tried in allocation
508
+ * order only before dispatch; a dispatched request is never replayed.
509
+ */
510
+ async function withCodexOperation<T>(
511
+ deps: ModelCallServiceDeps,
512
+ settings: Settings,
513
+ input: ModelCallInput,
514
+ model: ConfiguredModel,
515
+ run: () => Promise<T>,
516
+ ): Promise<T> {
517
+ const disposition = await readCodexCutoverDisposition(
518
+ deps.db,
519
+ input.accountId,
520
+ input.workspaceId,
521
+ );
522
+ if (disposition !== "core") throw subscriptionCapacityUnavailable("Codex");
523
+ const scope: SubscriptionCoreCodexOperationScope = {
524
+ kind: "workspace",
525
+ accountId: input.accountId,
526
+ workspaceId: input.workspaceId,
527
+ subjectId: input.subjectId,
528
+ };
529
+ const candidates = (await listSubscriptionCoreCodexOperationCandidates(deps.db, scope)).filter(
530
+ (candidate) => connectionModelAllowed(candidate.allowedModelIds, model.id),
531
+ );
532
+ if (candidates.length === 0) throw subscriptionCapacityUnavailable("Codex");
533
+ const operationId = crypto.randomUUID();
534
+ const attemptId = crypto.randomUUID();
535
+ const resolveModel = buildModelResolver(codexUpstreamModelSlugs(settings));
536
+ for (const candidate of candidates) {
537
+ const ref: SubscriptionCoreCodexOperationLeaseRef = {
538
+ operationId,
539
+ attemptId,
540
+ operationKind: "completion",
541
+ connectionId: candidate.connectionId,
542
+ holderId: `completion:${input.requestId}`.slice(0, 256),
543
+ generation: 1,
544
+ };
545
+ const lease = await acquireSubscriptionCoreCodexOperationLease(deps.db, scope, ref);
546
+ if (lease.kind !== "acquired") continue;
547
+ try {
548
+ const { usage } = await fetchSubscriptionCoreCodexUsage(
549
+ deps.db,
550
+ deps.settings,
551
+ scope,
552
+ candidate.connectionId,
553
+ deps.codexFetch,
554
+ );
555
+ if (!codexIncludedUsageAvailable(usage)) continue;
556
+ const resolver = buildSubscriptionCoreCodexConnectionTokenResolver(
557
+ deps.db,
558
+ deps.settings,
559
+ scope,
560
+ candidate.connectionId,
561
+ ref,
562
+ );
563
+ let pending: { operationId: string } | null = null;
564
+ let sequence = 0;
565
+ const context: CodexRequestContext = {
566
+ clientVersion: CODEX_CLIENT_VERSION,
567
+ getToken: () => resolver.getToken(),
568
+ refresh: () => resolver.refresh(),
569
+ resolveModel,
570
+ beforeProviderDispatch: async (request) => {
571
+ if (!(await renewSubscriptionCoreCodexOperationLease(deps.db, scope, ref))) {
572
+ throw subscriptionCapacityUnavailable("Codex");
573
+ }
574
+ if (request) {
575
+ pending = await reserveSubscriptionCoreCodexOperationRequest(
576
+ deps.db,
577
+ scope,
578
+ ref,
579
+ candidate.connectionId,
580
+ request,
581
+ );
582
+ }
583
+ },
584
+ onProviderRequestSettled: async ({ outcome }) => {
585
+ const reserved = pending;
586
+ pending = null;
587
+ if (!reserved) return;
588
+ await settleSubscriptionCoreCodexOperationRequest(deps.db, scope, {
589
+ operationId: reserved.operationId,
590
+ outcome,
591
+ });
592
+ },
593
+ nextRequestId: () => `completion:${input.requestId}:${++sequence}`,
594
+ };
595
+ return await codexRequestStorage.run(context, run);
596
+ } finally {
597
+ await releaseSubscriptionCoreCodexOperationLease(deps.db, scope, ref).catch(() => false);
598
+ }
599
+ }
600
+ throw new ModelCallError({
601
+ status: 429,
602
+ type: "rate_limit_error",
603
+ code: "subscription_usage_exhausted",
604
+ message: "No Codex subscription account has included usage available right now.",
605
+ });
606
+ }
607
+
608
+ function subscriptionCapacityUnavailable(provider: string): ModelCallError {
609
+ return new ModelCallError({
610
+ status: 503,
611
+ type: "service_unavailable",
612
+ code: "subscription_unavailable",
613
+ message: `No ${provider} subscription account is available for this call.`,
614
+ });
615
+ }
616
+
617
+ function subscriptionReconnectRequired(provider: string): ModelCallError {
618
+ return new ModelCallError({
619
+ status: 503,
620
+ type: "service_unavailable",
621
+ code: "subscription_reconnect_required",
622
+ message: `Reconnect the ${provider} subscription to use this model.`,
623
+ });
624
+ }
625
+
626
+ export function isModelCallAbort(error: unknown): boolean {
627
+ return (
628
+ error instanceof Error && (error.name === "AbortError" || error.name === "APIUserAbortError")
629
+ );
630
+ }
631
+
632
+ function providerMessage(error: unknown): string {
633
+ const message = error instanceof Error ? error.message.trim() : "";
634
+ return message.length > PROVIDER_MESSAGE_MAX_LENGTH
635
+ ? `${message.slice(0, PROVIDER_MESSAGE_MAX_LENGTH)}…`
636
+ : message;
637
+ }
638
+
639
+ /** Map a provider or runtime failure to a public error; aborts pass through. */
640
+ export function publicModelCallError(error: unknown): unknown {
641
+ if (error instanceof ModelCallError || isModelCallAbort(error)) return error;
642
+ if (error instanceof SingleModelCallUnsupportedError) {
643
+ return new ModelCallError({
644
+ status: 400,
645
+ type: "invalid_request_error",
646
+ code: "unsupported_parameter",
647
+ param: error.parameter,
648
+ message: error.message,
649
+ });
650
+ }
651
+ if (error instanceof CodexReloginRequired) return subscriptionReconnectRequired("Codex");
652
+ if (error instanceof XaiSubscriptionReloginRequired) {
653
+ return subscriptionReconnectRequired("SuperGrok");
654
+ }
655
+ if (error instanceof ClaudeSubscriptionReconnectRequired) {
656
+ return subscriptionReconnectRequired("Claude");
657
+ }
658
+ if (error instanceof SingleModelCallProviderError) {
659
+ return new ModelCallError({
660
+ status: 502,
661
+ type: "api_error",
662
+ code: "provider_error",
663
+ message: providerMessage(error) || "The model request failed.",
664
+ });
665
+ }
666
+ const status = providerStatus(error);
667
+ if (status === 429) {
668
+ return new ModelCallError({
669
+ status: 429,
670
+ type: "rate_limit_error",
671
+ code: "provider_rate_limited",
672
+ message: "The model provider is rate limiting requests. Retry later.",
673
+ });
674
+ }
675
+ if (status === 400 || status === 404 || status === 413 || status === 422) {
676
+ return new ModelCallError({
677
+ status: 400,
678
+ type: "invalid_request_error",
679
+ code: "provider_rejected_request",
680
+ message: providerMessage(error) || "The model provider rejected the request.",
681
+ });
682
+ }
683
+ return new ModelCallError({
684
+ status: 502,
685
+ type: "api_error",
686
+ code: "provider_error",
687
+ message: "The model request failed.",
688
+ });
689
+ }
690
+
691
+ function providerStatus(error: unknown): number | null {
692
+ const status = (error as { status?: unknown } | null)?.status;
693
+ return typeof status === "number" ? status : null;
694
+ }