@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,315 @@
1
+ // One exact-process agent update request, shared by the dashboard's "Update
2
+ // now" route and the automatic updater that keeps every live Connected Machine
3
+ // on its channel's promoted build without a click.
4
+
5
+ import type { Settings } from "@opengeni/config";
6
+ import { ControlRequest, ErrorCode } from "@opengeni/agent-proto";
7
+ import {
8
+ advanceEnrollmentAgentUpdate,
9
+ beginEnrollmentAgentUpdate,
10
+ countLiveConnectedMachineBrowsers,
11
+ type Database,
12
+ type EnrollmentRecord,
13
+ } from "@opengeni/db";
14
+ import type { EventBus } from "@opengeni/events";
15
+ import type { Observability } from "@opengeni/observability";
16
+ import { NatsControlRpc, subjectFor } from "@opengeni/runtime/sandbox";
17
+ import {
18
+ ACTIVE_UPDATE_STATUSES,
19
+ compareAgentVersions,
20
+ machineUpdateBlockedReason,
21
+ promotedAgentVersion,
22
+ } from "./machines";
23
+
24
+ export type AgentUpdateDeps = {
25
+ db: Database;
26
+ bus?: EventBus | null;
27
+ settings: Settings;
28
+ };
29
+
30
+ export type AgentUpdateRequestResult =
31
+ | { kind: "accepted"; operationId: string; targetVersion: string }
32
+ | { kind: "refused"; status: 409 | 422 | 502; message: string };
33
+
34
+ /** Reserve one exact-generation operation, ask the authoritative runner to
35
+ * apply the promoted release, then let progress events + the successor Hello
36
+ * drive the durable state to completion. `live` must be the enrollment's
37
+ * current live connection. */
38
+ export async function requestAgentUpdate(
39
+ deps: AgentUpdateDeps,
40
+ live: EnrollmentRecord,
41
+ input: { releaseBaseUrl: string },
42
+ ): Promise<AgentUpdateRequestResult> {
43
+ const { db, bus, settings } = deps;
44
+ if (!live.connectionInstanceId || !live.agentVersion) {
45
+ return refused(409, "machine has no authoritative live agent build");
46
+ }
47
+ const blockedReason = machineUpdateBlockedReason(live.os, live.agentVersion);
48
+ if (blockedReason) return refused(422, blockedReason);
49
+ const channel = live.agentUpdateChannel ?? "stable";
50
+ const targetVersion = promotedAgentVersion(settings, channel);
51
+ const reusableRequest =
52
+ live.agentUpdate?.status === "requested" &&
53
+ live.agentUpdate.targetVersion === targetVersion &&
54
+ live.agentUpdate.connectionInstanceId === live.connectionInstanceId &&
55
+ live.agentUpdate.connectionGeneration === live.connectionGeneration
56
+ ? live.agentUpdate
57
+ : null;
58
+ // Whatever happened to an earlier attempt, a machine already running the
59
+ // promoted build has nothing to install.
60
+ if (!reusableRequest && live.agentVersion === targetVersion) {
61
+ return refused(409, "machine already runs the promoted version");
62
+ }
63
+ const operationId = reusableRequest?.operationId ?? crypto.randomUUID();
64
+ const fence = {
65
+ accountId: live.accountId,
66
+ workspaceId: live.workspaceId,
67
+ enrollmentId: live.id,
68
+ connectionInstanceId: live.connectionInstanceId,
69
+ connectionGeneration: live.connectionGeneration,
70
+ operationId,
71
+ };
72
+ if (!reusableRequest) {
73
+ const reserved = await beginEnrollmentAgentUpdate(db, { ...fence, targetVersion });
74
+ if (!reserved) return refused(409, "machine update state changed; refresh and retry");
75
+ }
76
+
77
+ const rpc = new NatsControlRpc(async () => bus?.getRequestConnection() ?? null);
78
+ const request: ControlRequest = {
79
+ requestId: operationId,
80
+ // The subject already selects the exact authoritative process instance.
81
+ // `epoch` is the sandbox lease epoch, not the enrollment connection
82
+ // generation, so this process-scoped operation intentionally leaves it 0.
83
+ epoch: 0,
84
+ resourcePolicy: undefined,
85
+ op: {
86
+ $case: "agentUpdateApply",
87
+ agentUpdateApply: {
88
+ operationId,
89
+ targetVersion,
90
+ channel,
91
+ expectedCurrentVersion: live.agentVersion,
92
+ expectedCurrentSha256: live.agentBinarySha256 ?? "",
93
+ releaseBaseUrl: input.releaseBaseUrl.replace(/\/+$/, ""),
94
+ },
95
+ },
96
+ };
97
+ const subject = subjectFor(live.workspaceId, live.id, live.connectionInstanceId);
98
+ let response = await rpc.request(subject, request, { timeoutMs: 10_000 });
99
+ // The operation id is idempotent. One retry heals an ambiguous lost reply;
100
+ // the agent returns the same acceptance and never starts a second update.
101
+ if (response.error?.code === ErrorCode.ERROR_CODE_TIMEOUT) {
102
+ response = await rpc.request(subject, request, { timeoutMs: 10_000 });
103
+ }
104
+ if (response.error) {
105
+ // A second timeout remains ambiguous: progress/Hello may still prove the
106
+ // operation. Keep it requested rather than racing a false terminal failure.
107
+ if (response.error.code !== ErrorCode.ERROR_CODE_TIMEOUT) {
108
+ await advanceEnrollmentAgentUpdate(db, {
109
+ ...fence,
110
+ status: "failed",
111
+ errorCode:
112
+ response.error.detail.failure_code ??
113
+ (response.error.code === ErrorCode.ERROR_CODE_AGENT_OFFLINE
114
+ ? "agent_offline"
115
+ : "update_dispatch_rejected"),
116
+ retryable: response.error.retryable,
117
+ rolledBack: false,
118
+ });
119
+ return refused(response.error.retryable ? 409 : 422, response.error.message);
120
+ }
121
+ } else if (
122
+ response.result?.$case !== "agentUpdateApply" ||
123
+ !response.result.agentUpdateApply.accepted
124
+ ) {
125
+ await advanceEnrollmentAgentUpdate(db, {
126
+ ...fence,
127
+ status: "failed",
128
+ errorCode: "invalid_agent_response",
129
+ retryable: true,
130
+ rolledBack: false,
131
+ });
132
+ return refused(502, "agent returned an invalid update response");
133
+ } else {
134
+ await advanceEnrollmentAgentUpdate(db, { ...fence, status: "accepted" });
135
+ }
136
+ return { kind: "accepted", operationId, targetVersion };
137
+ }
138
+
139
+ function refused(status: 409 | 422 | 502, message: string): AgentUpdateRequestResult {
140
+ return { kind: "refused", status, message };
141
+ }
142
+
143
+ /** First agent release whose restart detaches from its managed browsers so
144
+ * the successor adopts them with their tabs and page state. An older agent
145
+ * closes every managed browser while it shuts down for an update. */
146
+ export const BROWSER_PRESERVING_AGENT_VERSION = "0.1.58";
147
+
148
+ /** Recorded when the automatic updater leaves an older agent alone because
149
+ * updating it would close managed browsers. A `update_busy_*` code, so it
150
+ * reads and retries as a postponement rather than a failure. */
151
+ export const UPDATE_POSTPONED_FOR_BROWSERS = "update_busy_browsers";
152
+
153
+ /** Whether updating this agent would close browsers it manages. */
154
+ export async function agentUpdateWouldCloseBrowsers(
155
+ db: Database,
156
+ enrollment: EnrollmentRecord,
157
+ ): Promise<boolean> {
158
+ const order = enrollment.agentVersion
159
+ ? compareAgentVersions(enrollment.agentVersion, BROWSER_PRESERVING_AGENT_VERSION)
160
+ : null;
161
+ if (order !== null && order >= 0) return false;
162
+ const live = await countLiveConnectedMachineBrowsers(db, {
163
+ accountId: enrollment.accountId,
164
+ workspaceId: enrollment.workspaceId,
165
+ enrollmentId: enrollment.id,
166
+ });
167
+ return live > 0;
168
+ }
169
+
170
+ /** Record a postponed automatic update on the machine without asking its
171
+ * agent, so the machine shows why it stays on its current build and the
172
+ * busy backoff decides when to look again. */
173
+ async function postponeAgentUpdate(
174
+ db: Database,
175
+ live: EnrollmentRecord,
176
+ targetVersion: string,
177
+ errorCode: string,
178
+ ): Promise<boolean> {
179
+ if (!live.connectionInstanceId) return false;
180
+ const fence = {
181
+ accountId: live.accountId,
182
+ workspaceId: live.workspaceId,
183
+ enrollmentId: live.id,
184
+ connectionInstanceId: live.connectionInstanceId,
185
+ connectionGeneration: live.connectionGeneration,
186
+ operationId: crypto.randomUUID(),
187
+ };
188
+ const reserved = await beginEnrollmentAgentUpdate(db, { ...fence, targetVersion });
189
+ if (!reserved) return false;
190
+ await advanceEnrollmentAgentUpdate(db, {
191
+ ...fence,
192
+ status: "failed",
193
+ errorCode,
194
+ retryable: true,
195
+ rolledBack: false,
196
+ });
197
+ return true;
198
+ }
199
+
200
+ /** How long the automatic updater leaves a machine alone after an attempt. */
201
+ export const AUTOMATIC_AGENT_UPDATE_RETRY_MS = {
202
+ /** A machine postponed because it was busy (running work, or managed
203
+ * browsers an older agent would close) is looked at again soon: the check
204
+ * is instant and interrupts nothing. */
205
+ busy: 10 * 60_000,
206
+ /** A request the runner never answered is re-sent under the same operation. */
207
+ unanswered: 10 * 60_000,
208
+ /** Other retryable failures (download, verification, a replaced process). */
209
+ retryable: 60 * 60_000,
210
+ } as const;
211
+
212
+ /** Whether a live machine should be asked now to move to `targetVersion`.
213
+ * Pure: decided from the enrollment the heartbeat already read. Only upgrades
214
+ * are automatic; moving a machine to an older promoted build stays an explicit
215
+ * per-machine request. A non-retryable failure waits for a newer promotion. */
216
+ export function automaticAgentUpdateDue(
217
+ enrollment: EnrollmentRecord,
218
+ targetVersion: string,
219
+ now: number,
220
+ ): boolean {
221
+ if (!enrollment.connectionInstanceId || !enrollment.agentVersion) return false;
222
+ if (machineUpdateBlockedReason(enrollment.os, enrollment.agentVersion)) return false;
223
+ const order = compareAgentVersions(enrollment.agentVersion, targetVersion);
224
+ if (order === null || order >= 0) return false;
225
+ const update = enrollment.agentUpdate;
226
+ if (!update) return true;
227
+ const updatedAt = Date.parse(update.updatedAt);
228
+ const age = Number.isFinite(updatedAt) ? now - updatedAt : Number.POSITIVE_INFINITY;
229
+ if (ACTIVE_UPDATE_STATUSES.has(update.status)) {
230
+ // Past "requested", the runner owns the operation (including waiting for
231
+ // idle). A replaced runner turns it into a retryable failure on its Hello.
232
+ return (
233
+ update.status === "requested" &&
234
+ update.targetVersion === targetVersion &&
235
+ update.connectionInstanceId === enrollment.connectionInstanceId &&
236
+ age >= AUTOMATIC_AGENT_UPDATE_RETRY_MS.unanswered
237
+ );
238
+ }
239
+ if (update.status === "succeeded" || update.targetVersion !== targetVersion) return true;
240
+ if (update.errorCode?.startsWith("update_busy")) {
241
+ return age >= AUTOMATIC_AGENT_UPDATE_RETRY_MS.busy;
242
+ }
243
+ return update.retryable && age >= AUTOMATIC_AGENT_UPDATE_RETRY_MS.retryable;
244
+ }
245
+
246
+ export type AutomaticAgentUpdater = {
247
+ /** Consider one live machine, typically from the enrollment its heartbeat
248
+ * just read and renewed. Never blocks the caller. */
249
+ consider(enrollment: EnrollmentRecord): void;
250
+ };
251
+
252
+ /** Keep live machines on their promoted build. Returns null when the
253
+ * deployment turned automatic updates off or has no public base URL for the
254
+ * agent to fetch the release manifest from. Concurrent API replicas are safe:
255
+ * reserving an operation is an atomic conditional write. */
256
+ export function createAutomaticAgentUpdater(
257
+ deps: AgentUpdateDeps & { observability?: Observability; now?: () => number },
258
+ ): AutomaticAgentUpdater | null {
259
+ const { settings, observability } = deps;
260
+ if (!settings.agentAutoUpdate || !settings.publicBaseUrl) return null;
261
+ const releaseBaseUrl = settings.publicBaseUrl;
262
+ const now = deps.now ?? Date.now;
263
+ const inFlight = new Set<string>();
264
+ return {
265
+ consider(enrollment) {
266
+ const targetVersion = promotedAgentVersion(settings, enrollment.agentUpdateChannel);
267
+ if (inFlight.has(enrollment.id)) return;
268
+ if (!automaticAgentUpdateDue(enrollment, targetVersion, now())) return;
269
+ inFlight.add(enrollment.id);
270
+ const fields = {
271
+ workspaceId: enrollment.workspaceId,
272
+ enrollmentId: enrollment.id,
273
+ installedVersion: enrollment.agentVersion,
274
+ targetVersion,
275
+ };
276
+ void (async () => {
277
+ // An explicit "Update now" may still close them; an automatic update
278
+ // never does.
279
+ if (await agentUpdateWouldCloseBrowsers(deps.db, enrollment)) {
280
+ if (
281
+ await postponeAgentUpdate(
282
+ deps.db,
283
+ enrollment,
284
+ targetVersion,
285
+ UPDATE_POSTPONED_FOR_BROWSERS,
286
+ )
287
+ ) {
288
+ observability?.info?.(
289
+ "Postponed an automatic Connected Machine agent update: the installed agent would close its open managed browsers",
290
+ fields,
291
+ );
292
+ }
293
+ return;
294
+ }
295
+ const result = await requestAgentUpdate(deps, enrollment, { releaseBaseUrl });
296
+ if (result.kind === "accepted") {
297
+ observability?.info?.("Requested an automatic Connected Machine agent update", fields);
298
+ } else if (result.status !== 409) {
299
+ observability?.warn?.("An automatic Connected Machine agent update was refused", {
300
+ ...fields,
301
+ message: result.message,
302
+ });
303
+ }
304
+ })()
305
+ .catch((error: unknown) => {
306
+ observability?.warn?.("Failed to request an automatic Connected Machine agent update", {
307
+ workspaceId: enrollment.workspaceId,
308
+ enrollmentId: enrollment.id,
309
+ error: error instanceof Error ? error.message : String(error),
310
+ });
311
+ })
312
+ .finally(() => inFlight.delete(enrollment.id));
313
+ },
314
+ };
315
+ }
@@ -28,6 +28,8 @@
28
28
  // on its callout timeout). The bearer's `exp` caps the minted credential's life so a
29
29
  // revoked/expired enrollment cannot outlive its bearer.
30
30
 
31
+ import { createHash } from "node:crypto";
32
+ import { createLogThrottle, type LogThrottle } from "@opengeni/observability";
31
33
  import {
32
34
  resolveEnrollmentSigningSecret,
33
35
  type NatsCalloutConfig,
@@ -45,7 +47,7 @@ import {
45
47
  type ResponderConnection,
46
48
  } from "@opengeni/events";
47
49
  import type { Observability } from "@opengeni/observability";
48
- import { observabilityEventLogger } from "../observability";
50
+ import { observabilityEventBusOptions } from "../observability";
49
51
  import { AGENT_CONNECTION_LEASE_MS } from "./connection-authority";
50
52
 
51
53
  /** The NATS subject nats-server publishes authorization requests on (ADR-26). */
@@ -57,6 +59,73 @@ export interface AuthCalloutDeps {
57
59
  settings: Settings;
58
60
  callout: NatsCalloutConfig;
59
61
  observability?: Observability;
62
+ /** Bounds repeated denial warnings; defaults to one process-wide throttle. */
63
+ denialWarningThrottle?: LogThrottle;
64
+ }
65
+
66
+ /** A stale or revoked machine re-dials on its reconnect backoff forever, so an
67
+ * unthrottled denial warning repeats every few seconds per machine. Log each
68
+ * distinct machine's first denial, then at most once per interval with the
69
+ * count of denials it hid. The denial decision itself is never throttled. */
70
+ export const AUTH_CALLOUT_DENIAL_WARNING_INTERVAL_MS = 60_000;
71
+ const processDenialWarningThrottle = createLogThrottle({
72
+ intervalMs: AUTH_CALLOUT_DENIAL_WARNING_INTERVAL_MS,
73
+ maxKeys: 1_024,
74
+ });
75
+
76
+ /** Closed denial vocabulary. The public log projection drops identifiers, so
77
+ * `reason` is what tells an operator which throttle key a count belongs to. */
78
+ type AuthCalloutDenialReason = "invalid_bearer" | "inactive_enrollment" | "duplicate_runner";
79
+
80
+ function warnDenial(
81
+ deps: AuthCalloutDeps,
82
+ key: string,
83
+ reason: AuthCalloutDenialReason,
84
+ message: string,
85
+ attributes: Record<string, string | number> = {},
86
+ ): void {
87
+ const admission = (deps.denialWarningThrottle ?? processDenialWarningThrottle).admit(key);
88
+ if (!admission) return;
89
+ deps.observability?.warn?.(message, {
90
+ ...attributes,
91
+ reason,
92
+ ...(admission.suppressedCount > 0 ? { suppressedCount: admission.suppressedCount } : {}),
93
+ });
94
+ }
95
+
96
+ /** Closed reasons a Connected Machine agent's NATS connect is refused. */
97
+ type MachineConnectDenialReason =
98
+ | "undecodable"
99
+ | "missing_bearer"
100
+ | "plane_disabled"
101
+ | "invalid_bearer"
102
+ | "inactive_enrollment"
103
+ | "identity_mismatch"
104
+ | "generation_mismatch"
105
+ | "invalid_instance"
106
+ | "duplicate_runner";
107
+
108
+ /** Count every machine connect decision; identifiers never become labels. */
109
+ function recordMachineConnect(
110
+ deps: AuthCalloutDeps,
111
+ outcome: "granted" | "denied",
112
+ reason: MachineConnectDenialReason | "none",
113
+ ): void {
114
+ try {
115
+ deps.observability?.incrementCounter({
116
+ name: "opengeni_machine_connect_total",
117
+ help: "Connected Machine agent NATS connect decisions (auth callout) by outcome and closed denial reason.",
118
+ labels: { outcome, reason },
119
+ });
120
+ } catch {
121
+ // Telemetry never changes the signed connect decision.
122
+ }
123
+ }
124
+
125
+ /** A process-local dedupe key for a rejected bearer. The digest is never
126
+ * logged, and the bearer value never leaves this function. */
127
+ function rejectedBearerKey(bearer: string): string {
128
+ return `invalid-bearer:${createHash("sha256").update(bearer).digest("hex").slice(0, 32)}`;
60
129
  }
61
130
 
62
131
  /**
@@ -78,10 +147,12 @@ export async function handleAuthorizationRequest(
78
147
  // is nothing to scope a response to. Leave it for the server's timeout by
79
148
  // throwing (the transport leaves it unanswered, fail-closed).
80
149
  deps.observability?.warn?.("auth-callout: undecodable authorization request", {});
150
+ recordMachineConnect(deps, "denied", "undecodable");
81
151
  throw new Error("undecodable authorization request");
82
152
  }
83
153
 
84
- const deny = (reason: string): Uint8Array => {
154
+ const deny = (code: MachineConnectDenialReason, reason: string): Uint8Array => {
155
+ recordMachineConnect(deps, "denied", code);
85
156
  // A SIGNED denial: the server reads `nats.error` and refuses the connection.
86
157
  const response = mintAuthResponse({
87
158
  userPublicKey: decoded.userNkey,
@@ -94,7 +165,7 @@ export async function handleAuthorizationRequest(
94
165
 
95
166
  const bearer = decoded.authToken;
96
167
  if (!bearer) {
97
- return deny("missing enrollment bearer");
168
+ return deny("missing_bearer", "missing enrollment bearer");
98
169
  }
99
170
 
100
171
  const secret = resolveEnrollmentSigningSecret(deps.settings);
@@ -102,25 +173,33 @@ export async function handleAuthorizationRequest(
102
173
  // The credential plane is off for this deployment — deny rather than mint an
103
174
  // unscoped credential. (The responder should not even be running in this case,
104
175
  // but fail-closed regardless.)
105
- return deny("enrollment credential plane disabled");
176
+ return deny("plane_disabled", "enrollment credential plane disabled");
106
177
  }
107
178
 
108
179
  const claims = await verifyEnrollmentBearer(secret, bearer);
109
180
  if (!claims) {
110
181
  // Invalid signature / malformed / expired bearer. NEVER log the bearer value.
111
- deps.observability?.warn?.("auth-callout: rejected an invalid enrollment bearer", {});
112
- return deny("invalid or expired enrollment bearer");
182
+ warnDenial(
183
+ deps,
184
+ rejectedBearerKey(bearer),
185
+ "invalid_bearer",
186
+ "auth-callout: rejected an invalid enrollment bearer",
187
+ );
188
+ return deny("invalid_bearer", "invalid or expired enrollment bearer");
113
189
  }
114
190
 
115
191
  // Confirm the enrollment is still ACTIVE — a revoked machine is denied even with a
116
192
  // still-unexpired bearer (the revoke path flips status; this re-checks at connect).
117
193
  const enrollment = await getEnrollment(deps.db, claims.workspaceId, claims.enrollmentId);
118
194
  if (!enrollment || enrollment.status !== "active") {
119
- deps.observability?.warn?.("auth-callout: denied a revoked or unknown enrollment", {
120
- workspaceId: claims.workspaceId,
121
- agentId: claims.agentId,
122
- });
123
- return deny("enrollment is not active");
195
+ warnDenial(
196
+ deps,
197
+ `inactive:${claims.workspaceId}:${claims.agentId}`,
198
+ "inactive_enrollment",
199
+ "auth-callout: denied a revoked or unknown enrollment",
200
+ { workspaceId: claims.workspaceId, agentId: claims.agentId },
201
+ );
202
+ return deny("inactive_enrollment", "enrollment is not active");
124
203
  }
125
204
 
126
205
  // Belt-and-braces: the bearer's agentId/enrollmentId must match the row we found.
@@ -133,15 +212,15 @@ export async function handleAuthorizationRequest(
133
212
  claims.agentId !== claims.enrollmentId ||
134
213
  claims.subjectPrefix !== `agent.${claims.workspaceId}.${claims.agentId}`
135
214
  ) {
136
- return deny("enrollment identity mismatch");
215
+ return deny("identity_mismatch", "enrollment identity mismatch");
137
216
  }
138
217
  if (enrollment.credentialGeneration !== claims.credentialGeneration) {
139
- return deny("enrollment credential generation mismatch");
218
+ return deny("generation_mismatch", "enrollment credential generation mismatch");
140
219
  }
141
220
 
142
221
  const connectionInstanceId = parseAgentConnectionName(decoded.name);
143
222
  if (!connectionInstanceId) {
144
- return deny("missing or invalid agent connection instance");
223
+ return deny("invalid_instance", "missing or invalid agent connection instance");
145
224
  }
146
225
  const claim = await claimEnrollmentConnection(deps.db, {
147
226
  workspaceId: claims.workspaceId,
@@ -151,11 +230,14 @@ export async function handleAuthorizationRequest(
151
230
  leaseMs: AGENT_CONNECTION_LEASE_MS,
152
231
  });
153
232
  if (!claim.claimed) {
154
- deps.observability?.warn?.("auth-callout: denied a duplicate live runner", {
155
- workspaceId: claims.workspaceId,
156
- agentId: claims.agentId,
157
- });
158
- return deny("another runner instance currently owns this enrollment");
233
+ warnDenial(
234
+ deps,
235
+ `duplicate:${claims.workspaceId}:${claims.agentId}`,
236
+ "duplicate_runner",
237
+ "auth-callout: denied a duplicate live runner",
238
+ { workspaceId: claims.workspaceId, agentId: claims.agentId },
239
+ );
240
+ return deny("duplicate_runner", "another runner instance currently owns this enrollment");
159
241
  }
160
242
 
161
243
  // GRANT: the operational subject includes the exact claimed process instance.
@@ -187,6 +269,7 @@ export async function handleAuthorizationRequest(
187
269
  accountSeed: deps.callout.accountSeed,
188
270
  userJwt,
189
271
  });
272
+ recordMachineConnect(deps, "granted", "none");
190
273
  deps.observability?.info?.("auth-callout: granted a workspace-scoped NATS credential", {
191
274
  workspaceId: claims.workspaceId,
192
275
  agentId: claims.agentId,
@@ -214,10 +297,10 @@ export async function startAuthCalloutResponder(
214
297
  (bytes) => handleAuthorizationRequest(deps, bytes),
215
298
  {
216
299
  name: "opengeni-auth-callout",
217
- ...(deps.observability ? { logger: observabilityEventLogger(deps.observability) } : {}),
300
+ ...(deps.observability ? observabilityEventBusOptions(deps.observability) : {}),
218
301
  },
219
302
  );
220
- deps.observability?.info?.("OpenGeni NATS auth-callout responder started", {
303
+ deps.observability?.info?.("Opengeni NATS auth-callout responder started", {
221
304
  subject: AUTH_CALLOUT_SUBJECT,
222
305
  });
223
306
  return connection;