@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.
- package/dist/access-grant-rls.d.ts +8 -1
- package/dist/admission-trace.d.ts +8 -0
- package/dist/app.d.ts +50 -3
- package/dist/app.js +10 -1
- package/dist/artifact-catalog-cursor.d.ts +1 -0
- package/dist/attached-browser-viewer.d.ts +11 -0
- package/dist/auth/managed-auth-attempt-context.d.ts +2 -0
- package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
- package/dist/auth/managed-auth-session-adapter.d.ts +9 -1
- package/dist/auth/managed-auth.d.ts +72 -5
- package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
- package/dist/auth/new-signups-gate.d.ts +23 -0
- package/dist/auth/signup-funnel-metrics.d.ts +44 -0
- package/dist/azure-live.d.ts +28 -0
- package/dist/browser-action-fences.d.ts +13 -0
- package/dist/browser-controller-authority.d.ts +1 -61
- package/dist/browser-ephemeral.d.ts +5 -0
- package/dist/browser-lost-runtime-end.d.ts +24 -0
- package/dist/browser-state-authority.d.ts +1 -27
- package/dist/chunk-OGQDXVXY.js +18 -0
- package/dist/chunk-OGQDXVXY.js.map +1 -0
- package/dist/{chunk-AJ62T5QN.js → chunk-OT56OY4V.js} +80503 -39869
- package/dist/chunk-OT56OY4V.js.map +1 -0
- package/dist/claude-default-models.d.ts +19 -0
- package/dist/claude-subscription-core.d.ts +50 -0
- package/dist/claude-subscription-oauth.d.ts +36 -0
- package/dist/claude-subscription-profile.d.ts +9 -0
- package/dist/claude-subscription-usage.d.ts +6 -0
- package/dist/claude-workspace-connection.d.ts +15 -0
- package/dist/codemode.d.ts +40 -5
- package/dist/codex-realtime.d.ts +29 -3
- package/dist/codex-session-pointers.d.ts +19 -0
- package/dist/connection-ownership.d.ts +6 -3
- package/dist/controller-data-plane.d.ts +16 -0
- package/dist/credit-promotion-snapshot.d.ts +6 -0
- package/dist/editable-artifact-source-session.d.ts +3 -0
- package/dist/editable-artifact-websocket.d.ts +5 -3
- package/dist/fatal-process-boundary.d.ts +9 -1
- package/dist/github-access.d.ts +7 -1
- package/dist/github-browser-flow.d.ts +1 -1
- package/dist/http/acting-person.d.ts +36 -0
- package/dist/http/api-contract-compat.d.ts +19 -0
- package/dist/http/api-error.d.ts +50 -1
- package/dist/http/auth.d.ts +8 -1
- package/dist/http/cors.d.ts +12 -0
- package/dist/http/deprecation.d.ts +42 -0
- package/dist/http/keyed-admission.d.ts +12 -0
- package/dist/http/local-browser-boundary.d.ts +72 -0
- package/dist/http/metrics-listener.d.ts +22 -0
- package/dist/http/path-identifier.d.ts +17 -0
- package/dist/http/registered-route-label.d.ts +16 -0
- package/dist/http/rejection-telemetry.d.ts +34 -0
- package/dist/http/request-body.d.ts +27 -0
- package/dist/http/request-source.d.ts +41 -3
- package/dist/http/sse.d.ts +12 -1
- package/dist/http/unmatched-route.d.ts +18 -0
- package/dist/http/user-content.d.ts +36 -0
- package/dist/http/variable-sets-removed.d.ts +41 -0
- package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
- package/dist/index.js +1279 -108
- package/dist/index.js.map +1 -1
- package/dist/integration-connect-metrics.d.ts +35 -0
- package/dist/integration-endpoint-test.d.ts +20 -0
- package/dist/integrations/api-integrations.d.ts +2 -2
- package/dist/integrations/atlassian.d.ts +8 -3
- package/dist/integrations/fiken.d.ts +3 -1
- package/dist/integrations/github-lens-connect.d.ts +37 -66
- package/dist/integrations/google-drive.d.ts +2 -0
- package/dist/integrations/integration-commit-authority.d.ts +13 -0
- package/dist/integrations/marketplace-plugin.d.ts +43 -43
- package/dist/integrations/oauth-client.d.ts +171 -12
- package/dist/integrations/oauth-profiles.d.ts +42 -13
- package/dist/integrations/onepassword-vault-provider.d.ts +9 -0
- package/dist/integrations/slack-bot.d.ts +285 -7
- package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
- package/dist/integrations/slack-interactions.d.ts +89 -10
- package/dist/integrations/slack-mrkdwn.d.ts +41 -0
- package/dist/integrations/slack-routing.d.ts +1 -1
- package/dist/integrations/slack-session-defaults.d.ts +58 -0
- package/dist/integrations/slack-task-file-upload.d.ts +36 -0
- package/dist/integrations/slack-tool-review.d.ts +5 -0
- package/dist/interaction-agent-access.d.ts +13 -8
- package/dist/interaction-agent-version.d.ts +21 -0
- package/dist/interaction-holder-heartbeat.d.ts +5 -0
- package/dist/interaction-metrics.d.ts +27 -2
- package/dist/interaction-route-stages.d.ts +25 -0
- package/dist/interaction-secrets-vault.d.ts +20 -0
- package/dist/interaction-secrets.d.ts +103 -0
- package/dist/mcp/action-catalog-types.d.ts +14 -0
- package/dist/mcp/action-catalog.gen.d.ts +2 -0
- package/dist/mcp/action-descriptions.d.ts +4 -0
- package/dist/mcp/action-schema-imports.gen.d.ts +1 -0
- package/dist/mcp/capability-account-readiness.d.ts +7 -0
- package/dist/mcp/child-read-evidence.d.ts +9 -0
- package/dist/mcp/company-profile-agent-admin.d.ts +12 -0
- package/dist/mcp/contract-input.d.ts +13 -0
- package/dist/mcp/documents.d.ts +2 -0
- package/dist/mcp/first-party-tool-permissions.d.ts +3 -606
- package/dist/mcp/notification-tools.d.ts +26 -0
- package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
- package/dist/mcp/scheduled-task-input.d.ts +1309 -0
- package/dist/mcp/scheduled-task-view.d.ts +217 -3
- package/dist/mcp/secret-tools.d.ts +14 -0
- package/dist/mcp/server.d.ts +108 -5
- package/dist/mcp/session-admin-access-tools.d.ts +33 -0
- package/dist/mcp/session-event-errors.d.ts +28 -0
- package/dist/mcp/session-event-view.d.ts +62 -0
- package/dist/mcp/session-view.d.ts +15 -0
- package/dist/mcp/session-wait.d.ts +18 -0
- package/dist/mcp/site-agent-clamp-tools.d.ts +38 -0
- package/dist/mcp/site-data-tools.d.ts +22 -0
- package/dist/mcp/site-publication-tools.d.ts +19 -0
- package/dist/mcp/site-sql-tools.d.ts +27 -0
- package/dist/mcp-oauth.d.ts +37 -4
- package/dist/model-calls/chat-completions.d.ts +87 -0
- package/dist/model-calls/pending-usage-settlements.d.ts +57 -0
- package/dist/model-calls/service.d.ts +36 -0
- package/dist/model-catalog.d.ts +9 -3
- package/dist/native-push-dispatch.d.ts +69 -0
- package/dist/observability.d.ts +3 -1
- package/dist/organization-mcp.d.ts +82 -0
- package/dist/prepared-mcp-actor.d.ts +77 -0
- package/dist/prepared-mcp-permissions.d.ts +8 -0
- package/dist/routes/analytics-consent.d.ts +26 -0
- package/dist/routes/api-integrations.d.ts +11 -0
- package/dist/routes/api-keys.d.ts +7 -7
- package/dist/routes/automations.d.ts +2 -0
- package/dist/routes/billing.d.ts +59 -0
- package/dist/routes/browser-sessions.d.ts +65 -2
- package/dist/routes/chat-completions.d.ts +11 -0
- package/dist/routes/claude-core-usage.d.ts +20 -0
- package/dist/routes/claude-subscription-accounts.d.ts +3 -0
- package/dist/routes/claude-subscription-oauth.d.ts +3 -0
- package/dist/routes/client-errors.d.ts +182 -0
- package/dist/routes/codex-core.d.ts +401 -0
- package/dist/routes/codex.d.ts +64 -2
- package/dist/routes/computer-sessions.d.ts +6 -1
- package/dist/routes/desktop-distribution.d.ts +32 -0
- package/dist/routes/github-browser-fonts.gen.d.ts +2 -0
- package/dist/routes/github-browser-pages.d.ts +27 -0
- package/dist/routes/inbox.d.ts +13 -0
- package/dist/routes/insights-response-cache.d.ts +10 -0
- package/dist/routes/insights-usage.d.ts +12 -0
- package/dist/routes/insights.d.ts +28 -0
- package/dist/routes/interaction-placement-message.d.ts +7 -0
- package/dist/routes/managed-sign-in-methods.d.ts +6 -0
- package/dist/routes/model-account-choice.d.ts +13 -0
- package/dist/routes/model-account-settings.d.ts +19 -0
- package/dist/routes/native-app-auth.d.ts +12 -0
- package/dist/routes/organization-integration-policy.d.ts +8 -0
- package/dist/routes/organization-integrations.d.ts +6 -0
- package/dist/routes/organization-mcp-connections.d.ts +3 -0
- package/dist/routes/organization-model-defaults.d.ts +9 -0
- package/dist/routes/organization-service-accounts.d.ts +3 -0
- package/dist/routes/personal-api-keys.d.ts +3 -0
- package/dist/routes/session-admin-access.d.ts +3 -0
- package/dist/routes/session-artifact-associations.d.ts +4 -0
- package/dist/routes/session-history-imports.d.ts +20 -0
- package/dist/routes/sessions.d.ts +38 -2
- package/dist/routes/site-data.d.ts +18 -0
- package/dist/routes/site-publishing.d.ts +5 -0
- package/dist/routes/site-runtime.d.ts +31 -0
- package/dist/routes/site-sql.d.ts +16 -0
- package/dist/routes/slack-bot-access.d.ts +3 -0
- package/dist/routes/subscription-account-pools.d.ts +21 -0
- package/dist/routes/subscription-core-http.d.ts +5 -0
- package/dist/routes/subscription-pool-access.d.ts +37 -0
- package/dist/routes/subscription-pool-core.d.ts +153 -0
- package/dist/routes/supergrok.d.ts +6 -6
- package/dist/routes/usage-allowances.d.ts +12 -0
- package/dist/routes/variable-sets-removed.d.ts +2 -0
- package/dist/routes/vault-providers.d.ts +34 -0
- package/dist/routes/vaults.d.ts +3 -0
- package/dist/routes/workspace-integrations.d.ts +35 -0
- package/dist/routes/workspace-model-providers.d.ts +4 -0
- package/dist/routes/workspaces.d.ts +11 -2
- package/dist/sandbox/agent-update.d.ts +64 -0
- package/dist/sandbox/auth-callout.d.ts +8 -0
- package/dist/sandbox/channel-a.d.ts +15 -1
- package/dist/sandbox/enrollment.d.ts +26 -4
- package/dist/sandbox/machine-audience.d.ts +29 -0
- package/dist/sandbox/machines.d.ts +15 -2
- package/dist/sandbox/metrics-ingestion.d.ts +6 -2
- package/dist/sandbox/screen-control.d.ts +85 -0
- package/dist/sandbox/viewer.d.ts +5 -1
- package/dist/sandbox-file-artifacts.d.ts +17 -1
- package/dist/scheduled-task-blockers.d.ts +39 -0
- package/dist/scheduled-task-deletion.d.ts +3 -4
- package/dist/scheduled-task-lifecycle.d.ts +14 -0
- package/dist/secret-answers.d.ts +40 -0
- package/dist/session-create-observability.d.ts +5 -0
- package/dist/session-event-view-36GO3IL7.js +528 -0
- package/dist/session-event-view-36GO3IL7.js.map +1 -0
- package/dist/signed-state-secret.d.ts +18 -0
- package/dist/site-agent-guard.d.ts +53 -0
- package/dist/site-data/operations.d.ts +103 -0
- package/dist/site-data/service.d.ts +203 -0
- package/dist/site-frame-guard.d.ts +32 -0
- package/dist/site-publishing/agent-data-tools.d.ts +84 -0
- package/dist/site-publishing/agent-model.d.ts +58 -0
- package/dist/site-publishing/agent-session.d.ts +16 -0
- package/dist/site-publishing/content-scanner.d.ts +31 -0
- package/dist/site-publishing/edge-sync.d.ts +48 -0
- package/dist/site-publishing/gateway-signature.d.ts +56 -0
- package/dist/site-publishing/limits.d.ts +63 -0
- package/dist/site-publishing/page-tool-authority.d.ts +30 -0
- package/dist/site-publishing/platform-usage.d.ts +113 -0
- package/dist/site-publishing/platform.d.ts +21 -0
- package/dist/site-publishing/readiness.d.ts +62 -0
- package/dist/site-publishing/runtime.d.ts +179 -0
- package/dist/site-publishing/service.d.ts +264 -0
- package/dist/site-publishing/session-events.d.ts +22 -0
- package/dist/site-publishing/session-views.d.ts +36 -0
- package/dist/site-publishing/viewer.d.ts +40 -0
- package/dist/site-session-origin.d.ts +31 -6
- package/dist/site-sql/format.d.ts +47 -0
- package/dist/site-sql/gateway.d.ts +50 -0
- package/dist/site-sql/service.d.ts +213 -0
- package/dist/temporal-schedule-sync.d.ts +26 -0
- package/dist/transcription/billing-refusal.d.ts +8 -0
- package/dist/transcription/normalize.d.ts +23 -0
- package/dist/transcription/providers/azure-mai.d.ts +12 -0
- package/dist/transcription/providers/azure-openai.d.ts +4 -0
- package/dist/transcription/providers/openai.d.ts +16 -0
- package/dist/transcription/providers/subscription-core.d.ts +39 -0
- package/dist/transcription/service.d.ts +10 -1
- package/dist/transcription/wav-duration.d.ts +8 -0
- package/dist/workspace-tool-gateway-attestations.d.ts +37 -0
- package/dist/workspace-tool-gateway-observability.d.ts +16 -0
- package/dist/workspace-tool-gateway-secrets.d.ts +27 -0
- package/dist/workspace-tool-gateway.d.ts +102 -6
- package/dist/workspace-tool-target-fence.d.ts +116 -0
- package/dist/workspace-tool-target.d.ts +225 -0
- package/dist/workspace-webhook-dispatch.d.ts +26 -0
- package/dist/xai-subscription-core.d.ts +60 -0
- package/package.json +25 -20
- package/src/access-grant-rls.ts +64 -14
- package/src/admission-trace.ts +14 -0
- package/src/app.ts +1684 -252
- package/src/artifact-catalog-cursor.ts +1 -0
- package/src/attached-browser-viewer.ts +26 -0
- package/src/auth/managed-auth-attempt-context.ts +9 -0
- package/src/auth/managed-auth-rate-limits.ts +252 -0
- package/src/auth/managed-auth-session-adapter.ts +64 -29
- package/src/auth/managed-auth.ts +303 -35
- package/src/auth/managed-email.ts +18 -1
- package/src/auth/managed-sign-in-notifications.ts +81 -0
- package/src/auth/new-signups-gate.ts +49 -0
- package/src/auth/organization-user-setup.ts +3 -3
- package/src/auth/signup-funnel-metrics.ts +164 -0
- package/src/azure-live.ts +103 -0
- package/src/browser-action-fences.ts +45 -0
- package/src/browser-controller-authority.ts +1 -186
- package/src/browser-ephemeral.ts +39 -0
- package/src/browser-lost-runtime-end.ts +71 -0
- package/src/browser-state-authority.ts +1 -236
- package/src/claude-default-models.ts +37 -0
- package/src/claude-subscription-core.ts +154 -0
- package/src/claude-subscription-oauth.ts +352 -0
- package/src/claude-subscription-profile.ts +73 -0
- package/src/claude-subscription-usage.ts +51 -0
- package/src/claude-workspace-connection.ts +82 -0
- package/src/codemode.ts +236 -39
- package/src/codex-realtime.ts +181 -53
- package/src/codex-session-pointers.ts +80 -0
- package/src/company-brain-okf.ts +1 -1
- package/src/connected-machine-computer-access.ts +2 -1
- package/src/connection-ownership.ts +19 -13
- package/src/controller-data-plane.ts +34 -0
- package/src/credit-promotion-snapshot.ts +36 -0
- package/src/editable-artifact-production.ts +10 -0
- package/src/editable-artifact-source-session.ts +123 -0
- package/src/editable-artifact-websocket.ts +16 -3
- package/src/fatal-process-boundary.ts +67 -3
- package/src/gateway-realtime.ts +12 -8
- package/src/github-access.ts +31 -5
- package/src/github-browser-flow.ts +1 -1
- package/src/http/acting-person.ts +105 -0
- package/src/http/api-contract-compat.ts +49 -0
- package/src/http/api-error.ts +210 -2
- package/src/http/auth.ts +68 -4
- package/src/http/cors.ts +37 -5
- package/src/http/deprecation.ts +118 -0
- package/src/http/keyed-admission.ts +29 -0
- package/src/http/local-browser-boundary.ts +343 -0
- package/src/http/metrics-listener.ts +57 -0
- package/src/http/path-identifier.ts +54 -0
- package/src/http/registered-route-label.ts +34 -0
- package/src/http/rejection-telemetry.ts +120 -0
- package/src/http/request-body.ts +127 -0
- package/src/http/request-source.ts +154 -13
- package/src/http/sse.ts +88 -28
- package/src/http/unmatched-route.ts +60 -0
- package/src/http/user-content.ts +158 -0
- package/src/http/variable-sets-removed.ts +122 -0
- package/src/http/websocket-upgrade-dispatch.ts +29 -0
- package/src/index.ts +107 -57
- package/src/integration-connect-metrics.ts +228 -0
- package/src/integration-endpoint-test.ts +291 -0
- package/src/integrations/api-integrations.ts +81 -7
- package/src/integrations/atlassian.ts +202 -83
- package/src/integrations/fiken.ts +66 -38
- package/src/integrations/github-app-connect.ts +64 -18
- package/src/integrations/github-lens-connect.ts +8 -29
- package/src/integrations/google-drive.ts +448 -152
- package/src/integrations/integration-commit-authority.ts +69 -0
- package/src/integrations/marketplace-plugin.ts +1 -1
- package/src/integrations/oauth-client.ts +733 -193
- package/src/integrations/oauth-profiles.ts +116 -45
- package/src/integrations/onepassword-vault-provider.ts +16 -0
- package/src/integrations/personal-github-repositories.ts +1 -1
- package/src/integrations/personal-github.ts +61 -35
- package/src/integrations/provider-oauth.ts +67 -85
- package/src/integrations/slack-app-home.ts +5 -5
- package/src/integrations/slack-bot.ts +893 -201
- package/src/integrations/slack-file-upload-flow.ts +147 -0
- package/src/integrations/slack-install.ts +7 -7
- package/src/integrations/slack-interactions.ts +1589 -299
- package/src/integrations/slack-mrkdwn.ts +193 -0
- package/src/integrations/slack-routing.ts +2 -2
- package/src/integrations/slack-session-defaults.ts +224 -0
- package/src/integrations/slack-task-file-upload.ts +323 -0
- package/src/integrations/slack-tool-review.ts +65 -0
- package/src/integrations/social-oauth.ts +90 -58
- package/src/interaction-agent-access.ts +40 -20
- package/src/interaction-agent-version.ts +85 -0
- package/src/interaction-holder-heartbeat.ts +24 -8
- package/src/interaction-metrics.ts +164 -2
- package/src/interaction-route-stages.ts +94 -0
- package/src/interaction-secrets-vault.ts +213 -0
- package/src/interaction-secrets.ts +426 -0
- package/src/mcp/action-catalog-types.ts +14 -0
- package/src/mcp/action-catalog.gen.ts +8014 -0
- package/src/mcp/action-descriptions.ts +299 -0
- package/src/mcp/action-schema-imports.gen.ts +304 -0
- package/src/mcp/capability-account-readiness.ts +17 -0
- package/src/mcp/child-read-evidence.ts +19 -0
- package/src/mcp/company-profile-agent-admin.ts +13 -0
- package/src/mcp/contract-input.ts +165 -0
- package/src/mcp/documents.ts +9 -2
- package/src/mcp/editable-artifacts.ts +29 -11
- package/src/mcp/files.ts +5 -1
- package/src/mcp/first-party-tool-permissions.ts +7 -285
- package/src/mcp/knowledge-entries.ts +108 -34
- package/src/mcp/notification-tools.ts +480 -0
- package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
- package/src/mcp/scheduled-task-input.ts +89 -0
- package/src/mcp/scheduled-task-view.ts +63 -3
- package/src/mcp/secret-tools.ts +185 -0
- package/src/mcp/server.ts +2213 -1116
- package/src/mcp/session-admin-access-tools.ts +163 -0
- package/src/mcp/session-event-errors.ts +123 -0
- package/src/mcp/session-event-view.ts +395 -13
- package/src/mcp/session-view.ts +3 -0
- package/src/mcp/session-wait.ts +67 -7
- package/src/mcp/site-agent-clamp-tools.ts +140 -0
- package/src/mcp/site-data-tools.ts +339 -0
- package/src/mcp/site-publication-tools.ts +201 -0
- package/src/mcp/site-sql-tools.ts +427 -0
- package/src/mcp-oauth.ts +635 -45
- package/src/model-calls/chat-completions.ts +352 -0
- package/src/model-calls/pending-usage-settlements.ts +125 -0
- package/src/model-calls/service.ts +694 -0
- package/src/model-catalog.ts +68 -17
- package/src/native-push-dispatch.ts +457 -0
- package/src/observability.ts +15 -1
- package/src/organization-mcp.ts +485 -0
- package/src/prepared-mcp-actor.ts +154 -0
- package/src/prepared-mcp-permissions.ts +38 -0
- package/src/routes/analytics-consent.ts +123 -0
- package/src/routes/api-integrations.ts +268 -9
- package/src/routes/api-keys.ts +164 -25
- package/src/routes/artifact-catalog.ts +111 -0
- package/src/routes/automations.ts +163 -90
- package/src/routes/billing.ts +535 -59
- package/src/routes/browser-sessions.ts +966 -342
- package/src/routes/canonical-human-identities.ts +61 -0
- package/src/routes/capabilities.ts +112 -5
- package/src/routes/channels.ts +4 -3
- package/src/routes/chat-completions.ts +235 -0
- package/src/routes/claude-core-usage.ts +147 -0
- package/src/routes/claude-subscription-accounts.ts +233 -0
- package/src/routes/claude-subscription-oauth.ts +175 -0
- package/src/routes/client-errors.ts +394 -0
- package/src/routes/codex-core.ts +687 -0
- package/src/routes/codex.ts +1277 -1119
- package/src/routes/company-brain.ts +4 -0
- package/src/routes/computer-sessions.ts +319 -85
- package/src/routes/connect.ts +277 -175
- package/src/routes/connections.ts +690 -363
- package/src/routes/desktop-distribution.ts +217 -0
- package/src/routes/documents.ts +13 -7
- package/src/routes/editable-artifacts.ts +74 -4
- package/src/routes/enrollments.ts +110 -16
- package/src/routes/external-identity-links.ts +13 -12
- package/src/routes/files.ts +41 -16
- package/src/routes/github-browser-fonts.gen.ts +12 -0
- package/src/routes/github-browser-pages.ts +258 -0
- package/src/routes/github.ts +200 -75
- package/src/routes/inbox.ts +353 -0
- package/src/routes/insights-response-cache.ts +83 -0
- package/src/routes/insights-usage.ts +345 -0
- package/src/routes/insights.ts +103 -8
- package/src/routes/install.ts +51 -10
- package/src/routes/integration-facets.ts +70 -28
- package/src/routes/interaction-placement-message.ts +12 -0
- package/src/routes/knowledge.ts +136 -27
- package/src/routes/machines.ts +189 -135
- package/src/routes/managed-auth-session-sets.ts +43 -10
- package/src/routes/managed-onboarding.ts +39 -19
- package/src/routes/managed-sign-in-methods.ts +433 -0
- package/src/routes/memory-slack-publications.ts +3 -2
- package/src/routes/model-account-choice.ts +194 -0
- package/src/routes/model-account-settings.ts +235 -0
- package/src/routes/model-connection-access.ts +210 -48
- package/src/routes/native-app-auth.ts +296 -0
- package/src/routes/organization-integration-policy.ts +116 -0
- package/src/routes/organization-integrations.ts +326 -0
- package/src/routes/organization-mcp-connections.ts +183 -0
- package/src/routes/organization-memberships.ts +205 -19
- package/src/routes/organization-model-defaults.ts +110 -0
- package/src/routes/organization-model-providers.ts +74 -3
- package/src/routes/organization-service-accounts.ts +128 -0
- package/src/routes/organization-sessions.ts +21 -5
- package/src/routes/personal-api-keys.ts +184 -0
- package/src/routes/personal-github-git-broker.ts +2 -2
- package/src/routes/personal-github.ts +9 -4
- package/src/routes/plugins.ts +46 -7
- package/src/routes/pr-review-github.ts +105 -118
- package/src/routes/pr-review.ts +88 -82
- package/src/routes/preference-registry.ts +18 -0
- package/src/routes/rigs.ts +48 -13
- package/src/routes/scheduled-tasks.ts +347 -27
- package/src/routes/session-admin-access.ts +271 -0
- package/src/routes/session-artifact-associations.ts +164 -0
- package/src/routes/session-history-imports.ts +305 -0
- package/src/routes/sessions.ts +1682 -363
- package/src/routes/site-data.ts +340 -0
- package/src/routes/site-publishing.ts +584 -0
- package/src/routes/site-runtime.ts +1944 -0
- package/src/routes/site-sql.ts +263 -0
- package/src/routes/skill-content.ts +72 -7
- package/src/routes/skills.ts +5 -4
- package/src/routes/slack-bot-access.ts +108 -0
- package/src/routes/social.ts +27 -15
- package/src/routes/subscription-account-pools.ts +209 -0
- package/src/routes/subscription-core-http.ts +18 -0
- package/src/routes/subscription-pool-access.ts +180 -0
- package/src/routes/subscription-pool-core.ts +552 -0
- package/src/routes/supergrok.ts +174 -655
- package/src/routes/transcription-recordings.ts +71 -4
- package/src/routes/transcriptions.ts +26 -2
- package/src/routes/usage-allowances.ts +381 -0
- package/src/routes/variable-sets-removed.ts +19 -0
- package/src/routes/vault-providers.ts +782 -0
- package/src/routes/vaults.ts +421 -0
- package/src/routes/video-generation.ts +30 -12
- package/src/routes/workspace-artifacts.ts +165 -53
- package/src/routes/workspace-integrations.ts +576 -0
- package/src/routes/workspace-model-providers.ts +148 -0
- package/src/routes/workspace-state.ts +4 -0
- package/src/routes/workspaces.ts +625 -117
- package/src/sandbox/agent-update.ts +315 -0
- package/src/sandbox/auth-callout.ts +104 -21
- package/src/sandbox/channel-a.ts +165 -55
- package/src/sandbox/enrollment.ts +131 -22
- package/src/sandbox/machine-audience.ts +192 -0
- package/src/sandbox/machines.ts +75 -31
- package/src/sandbox/metrics-ingestion.ts +133 -2
- package/src/sandbox/rematerialize.ts +51 -21
- package/src/sandbox/screen-control.ts +289 -0
- package/src/sandbox/viewer.ts +33 -58
- package/src/sandbox-file-artifacts.ts +53 -27
- package/src/scheduled-task-blockers.ts +293 -0
- package/src/scheduled-task-deletion.ts +13 -3
- package/src/scheduled-task-lifecycle.ts +84 -0
- package/src/secret-answers.ts +119 -0
- package/src/session-create-observability.ts +46 -0
- package/src/session-realtime-context.ts +26 -4
- package/src/signed-state-secret.ts +58 -0
- package/src/site-agent-guard.ts +261 -0
- package/src/site-data/operations.ts +777 -0
- package/src/site-data/service.ts +1043 -0
- package/src/site-frame-guard.ts +107 -0
- package/src/site-publishing/agent-data-tools.ts +250 -0
- package/src/site-publishing/agent-model.ts +127 -0
- package/src/site-publishing/agent-session.ts +148 -0
- package/src/site-publishing/content-scanner.ts +93 -0
- package/src/site-publishing/edge-sync.ts +148 -0
- package/src/site-publishing/gateway-signature.ts +198 -0
- package/src/site-publishing/limits.ts +315 -0
- package/src/site-publishing/page-tool-authority.ts +111 -0
- package/src/site-publishing/platform-usage.ts +479 -0
- package/src/site-publishing/platform.ts +98 -0
- package/src/site-publishing/readiness.ts +330 -0
- package/src/site-publishing/runtime.ts +831 -0
- package/src/site-publishing/service.ts +1282 -0
- package/src/site-publishing/session-events.ts +262 -0
- package/src/site-publishing/session-views.ts +262 -0
- package/src/site-publishing/viewer.ts +75 -0
- package/src/site-session-origin.ts +91 -6
- package/src/site-sql/format.ts +134 -0
- package/src/site-sql/gateway.ts +168 -0
- package/src/site-sql/service.ts +1636 -0
- package/src/site-uploads.ts +27 -5
- package/src/temporal-schedule-sync.ts +74 -0
- package/src/transcription/billing-refusal.ts +14 -0
- package/src/transcription/normalize.ts +77 -0
- package/src/transcription/providers/azure-mai.ts +98 -0
- package/src/transcription/providers/azure-openai.ts +16 -7
- package/src/transcription/providers/codex-subscription.ts +190 -67
- package/src/transcription/providers/openai.ts +79 -5
- package/src/transcription/providers/subscription-core.ts +125 -0
- package/src/transcription/providers/xai-subscription.ts +81 -83
- package/src/transcription/segmenter.ts +7 -1
- package/src/transcription/service.ts +239 -10
- package/src/transcription/wav-duration.ts +39 -0
- package/src/workspace-deletion.ts +25 -1
- package/src/workspace-tool-gateway-attestations.ts +133 -0
- package/src/workspace-tool-gateway-observability.ts +64 -0
- package/src/workspace-tool-gateway-secrets.ts +104 -0
- package/src/workspace-tool-gateway.ts +921 -103
- package/src/workspace-tool-target-fence.ts +380 -0
- package/src/workspace-tool-target.ts +554 -0
- package/src/workspace-webhook-dispatch.ts +225 -0
- package/src/xai-realtime.ts +85 -81
- package/src/xai-subscription-core.ts +172 -0
- package/dist/browser-auth-broker.d.ts +0 -20
- package/dist/chunk-AJ62T5QN.js.map +0 -1
- package/dist/connection-authority-owner.d.ts +0 -59
- package/dist/routes/connection-authorities.d.ts +0 -3
- package/dist/routes/environments.d.ts +0 -5
- package/dist/routes/host-mcp-bindings.d.ts +0 -5
- package/dist/routes/host-mcp-resolvers.d.ts +0 -3
- package/dist/routes/packs.d.ts +0 -3
- package/dist/session-event-view-MU3HMNV3.js +0 -264
- package/dist/session-event-view-MU3HMNV3.js.map +0 -1
- package/dist/xai-subscription-auth.d.ts +0 -23
- package/src/browser-auth-broker.ts +0 -155
- package/src/connection-authority-owner.ts +0 -61
- package/src/routes/connection-authorities.ts +0 -139
- package/src/routes/environments.ts +0 -388
- package/src/routes/host-mcp-bindings.ts +0 -122
- package/src/routes/host-mcp-resolvers.ts +0 -41
- package/src/routes/packs.ts +0 -784
- package/src/xai-subscription-auth.ts +0 -139
package/src/routes/supergrok.ts
CHANGED
|
@@ -1,69 +1,55 @@
|
|
|
1
|
+
import { registerSubscriptionAccountPoolRoutes } from "./subscription-account-pools";
|
|
2
|
+
import {
|
|
3
|
+
coreConnectRefused,
|
|
4
|
+
deliverPoolCoreWake,
|
|
5
|
+
requireSubscriptionCoreRoute,
|
|
6
|
+
type SubscriptionPoolCore,
|
|
7
|
+
} from "./subscription-pool-core";
|
|
8
|
+
import {
|
|
9
|
+
managedCookieHuman,
|
|
10
|
+
requireSameOriginBrowserMutation,
|
|
11
|
+
requireSubscriptionScopeMutation,
|
|
12
|
+
} from "./subscription-pool-access";
|
|
13
|
+
export { managedCookieHuman } from "./subscription-pool-access";
|
|
1
14
|
import { requireOrganizationCodexHuman } from "./codex";
|
|
2
15
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
16
|
+
connectSubscriptionCoreXaiConnection,
|
|
17
|
+
getSubscriptionCoreXaiOrganizationProjection,
|
|
18
|
+
getSubscriptionCoreXaiWorkspaceProjection,
|
|
19
|
+
SUBSCRIPTION_CORE_XAI,
|
|
20
|
+
encryptEnvironmentValue,
|
|
21
|
+
decryptEnvironmentValue,
|
|
22
|
+
type XaiSubscriptionAccountMetadata,
|
|
7
23
|
} from "@opengeni/db";
|
|
8
24
|
import {
|
|
9
25
|
configuredModels,
|
|
10
26
|
environmentsEncryptionKeyBytes,
|
|
11
27
|
withXaiSubscriptionCatalogProvider,
|
|
12
28
|
} from "@opengeni/config";
|
|
13
|
-
import {
|
|
14
|
-
WORKSPACE_XAI_PROVIDER_ACCOUNT_AUTHORITY_SNAPSHOT_V1,
|
|
15
|
-
type XaiProviderAccountAuthoritySnapshotV1,
|
|
16
|
-
} from "@opengeni/contracts";
|
|
17
|
-
import {
|
|
18
|
-
disconnectXaiSubscriptionCredentialAndRepick,
|
|
19
|
-
ensureXaiRotationSettings,
|
|
20
|
-
getXaiRotationSettings,
|
|
21
|
-
getXaiSubscriptionAccountAuthoritySnapshot,
|
|
22
|
-
listXaiSubscriptionAccountsMetadata,
|
|
23
|
-
materializeXaiCredentialForRun,
|
|
24
|
-
refreshXaiSubscriptionCredentialSerialized,
|
|
25
|
-
renameXaiSubscriptionAccount,
|
|
26
|
-
resolveXaiProviderAccountAuthoritySnapshotForAcceptance,
|
|
27
|
-
setActiveXaiCredential,
|
|
28
|
-
setInitialActiveXaiCredential,
|
|
29
|
-
updateXaiAllocatorEligibility,
|
|
30
|
-
updateXaiRotationSettings,
|
|
31
|
-
upsertXaiSubscriptionCredential,
|
|
32
|
-
wakeXaiCapacityWaiters,
|
|
33
|
-
encryptEnvironmentValue,
|
|
34
|
-
decryptEnvironmentValue,
|
|
35
|
-
getWorkspaceGrant,
|
|
36
|
-
type XaiSubscriptionAccountMetadata,
|
|
37
|
-
} from "@opengeni/db";
|
|
29
|
+
import { SubscriptionConnectPollRequest, SupergrokConnectStartRequest } from "@opengeni/contracts";
|
|
38
30
|
import { createSignedState, readSignedState } from "@opengeni/github";
|
|
39
31
|
import {
|
|
40
|
-
getManagedSession,
|
|
41
32
|
requireAccessGrant,
|
|
42
33
|
requireAccessGrantAuthorization,
|
|
43
34
|
externalActorContinuationForAuthorization,
|
|
44
35
|
type ApiRouteDeps,
|
|
45
36
|
} from "@opengeni/core";
|
|
46
37
|
import {
|
|
47
|
-
XAI_CLIENT_VERSION,
|
|
48
38
|
XaiSubscriptionError,
|
|
49
|
-
fetchXaiSubscriptionModels,
|
|
50
39
|
pollXaiDeviceCode,
|
|
51
|
-
refreshXaiToken,
|
|
52
40
|
requestXaiDeviceCode,
|
|
53
41
|
xaiAccessTokenExpiry,
|
|
54
42
|
xaiIdentityFromDeviceTokens,
|
|
55
43
|
type XaiFetch,
|
|
56
|
-
type XaiProxyAuthContext,
|
|
57
44
|
} from "@opengeni/xai-subscription";
|
|
58
45
|
import type { Context, Hono } from "hono";
|
|
59
46
|
import { HTTPException } from "hono/http-exception";
|
|
60
|
-
import * as z from "zod/v4";
|
|
61
47
|
import { projectClientModel } from "../model-catalog";
|
|
48
|
+
import { readXaiCoreStatus } from "../xai-subscription-core";
|
|
62
49
|
import { ExternalActorContinuation } from "@opengeni/contracts/external-identities";
|
|
63
50
|
import { requireConnectOwnerAuthority } from "../integrations/connect-authority";
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
type ManagedCookieHuman = { subjectId: string };
|
|
51
|
+
import { databaseUnavailableHttpError } from "../http/api-error";
|
|
52
|
+
import { requirePrivateSubscriptionHuman } from "./subscription-pool-access";
|
|
67
53
|
|
|
68
54
|
type SuperGrokConnectState = {
|
|
69
55
|
externalContinuationEncrypted?: string;
|
|
@@ -76,59 +62,20 @@ type SuperGrokConnectState = {
|
|
|
76
62
|
iat: number;
|
|
77
63
|
};
|
|
78
64
|
|
|
79
|
-
const connectStartBody =
|
|
80
|
-
scope: z.enum(["workspace", "user"]).default("workspace"),
|
|
81
|
-
});
|
|
82
|
-
const connectPollBody = z.object({ state: z.string().min(1).max(16_384) });
|
|
83
|
-
const allocatorBody = z.object({
|
|
84
|
-
enabled: z.boolean(),
|
|
85
|
-
expectedVersion: z.number().int().positive(),
|
|
86
|
-
});
|
|
87
|
-
const settingsBody = z.object({ rotationEnabled: z.boolean() });
|
|
88
|
-
const renameBody = z.object({ label: z.string().trim().max(200).nullable() });
|
|
89
|
-
|
|
90
|
-
export async function managedCookieHuman(
|
|
91
|
-
c: Context,
|
|
92
|
-
deps: ApiRouteDeps,
|
|
93
|
-
): Promise<ManagedCookieHuman | null> {
|
|
94
|
-
if (
|
|
95
|
-
deps.settings.productAccessMode !== "managed" ||
|
|
96
|
-
!deps.managedAuth ||
|
|
97
|
-
!c.req.header("cookie") ||
|
|
98
|
-
c.req.header("authorization")
|
|
99
|
-
) {
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
const session = await getManagedSession(c, deps.managedAuth, {
|
|
103
|
-
db: deps.db,
|
|
104
|
-
sessionAdapter: deps.managedAuthSessionAdapter,
|
|
105
|
-
sessionSetMode: deps.settings.managedAuthSessionSetMode,
|
|
106
|
-
});
|
|
107
|
-
return session?.user?.id ? { subjectId: `user:${session.user.id}` } : null;
|
|
108
|
-
}
|
|
65
|
+
const connectStartBody = SupergrokConnectStartRequest;
|
|
109
66
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
throw new HTTPException(403, {
|
|
123
|
-
message: "same-origin browser request required",
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
if (c.req.header("sec-fetch-site")?.toLowerCase() !== "same-origin") {
|
|
127
|
-
throw new HTTPException(403, {
|
|
128
|
-
message: "same-origin fetch metadata required",
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
}
|
|
67
|
+
/**
|
|
68
|
+
* SuperGrok on the shared subscription core (provider id `xai`), its only
|
|
69
|
+
* runtime: the legacy pool runtime was deleted after the SuperGrok cutover.
|
|
70
|
+
*/
|
|
71
|
+
const SUPERGROK_CORE: SubscriptionPoolCore = {
|
|
72
|
+
binding: SUBSCRIPTION_CORE_XAI,
|
|
73
|
+
workspaceProjection: getSubscriptionCoreXaiWorkspaceProjection,
|
|
74
|
+
organizationProjection: getSubscriptionCoreXaiOrganizationProjection,
|
|
75
|
+
};
|
|
76
|
+
const supergrokRoute = (deps: ApiRouteDeps, accountId: () => Promise<string>) =>
|
|
77
|
+
requireSubscriptionCoreRoute(deps, "xai", "SuperGrok", accountId);
|
|
78
|
+
const connectPollBody = SubscriptionConnectPollRequest;
|
|
132
79
|
|
|
133
80
|
function requireEnabled(deps: ApiRouteDeps): void {
|
|
134
81
|
if (!deps.settings.supergrokSubscriptionEnabled) {
|
|
@@ -138,100 +85,43 @@ function requireEnabled(deps: ApiRouteDeps): void {
|
|
|
138
85
|
}
|
|
139
86
|
}
|
|
140
87
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if (c.req.header("authorization")) {
|
|
147
|
-
const authorization = await requireAccessGrantAuthorization(
|
|
148
|
-
c,
|
|
149
|
-
deps,
|
|
150
|
-
workspaceId,
|
|
151
|
-
"connections:write",
|
|
152
|
-
);
|
|
153
|
-
const external = externalActorContinuationForAuthorization(authorization);
|
|
154
|
-
if (
|
|
155
|
-
external &&
|
|
156
|
-
authorization.contextIntegrity &&
|
|
157
|
-
external.actor.effectiveSubjectId === authorization.grant.subjectId
|
|
158
|
-
) {
|
|
159
|
-
// The existing xAI user-pool domain requires an ordinary workspace
|
|
160
|
-
// membership, not just the synthetic Personal-workspace owner grant.
|
|
161
|
-
if (!(await getWorkspaceGrant(deps.db, authorization.grant.subjectId, workspaceId)))
|
|
162
|
-
throw new HTTPException(409, {
|
|
163
|
-
message: "Private SuperGrok accounts require membership in an ordinary workspace",
|
|
164
|
-
});
|
|
165
|
-
return { accountId: authorization.grant.accountId, subjectId: authorization.grant.subjectId };
|
|
166
|
-
}
|
|
167
|
-
throw new HTTPException(403, {
|
|
168
|
-
message: "Private SuperGrok accounts require a verified owning user",
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
const human = await managedCookieHuman(c, deps);
|
|
172
|
-
if (!human) {
|
|
173
|
-
throw new HTTPException(401, {
|
|
174
|
-
message: "managed browser session required",
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
const grant = await requireAccessGrant(c, deps, workspaceId, "connections:write");
|
|
178
|
-
if (grant.subjectId !== human.subjectId) {
|
|
179
|
-
throw new HTTPException(403, {
|
|
180
|
-
message: "managed browser identity mismatch",
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
if (!(await getWorkspaceGrant(deps.db, grant.subjectId, workspaceId)))
|
|
184
|
-
throw new HTTPException(409, {
|
|
185
|
-
message: "Private SuperGrok accounts require membership in an ordinary workspace",
|
|
186
|
-
});
|
|
187
|
-
return { accountId: grant.accountId, subjectId: grant.subjectId };
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
export async function requireScopeMutation(
|
|
88
|
+
/**
|
|
89
|
+
* The legacy scope check; on the shared core a private (`user`) account is
|
|
90
|
+
* managed only from its owner's Personal workspace.
|
|
91
|
+
*/
|
|
92
|
+
export const requireScopeMutation = (
|
|
191
93
|
c: Context,
|
|
192
94
|
deps: ApiRouteDeps,
|
|
193
95
|
workspaceId: string,
|
|
194
96
|
scope: "workspace" | "user" | "organization",
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
// bearers remain rejected by requirePrivateHuman; native CSRF is unchanged.
|
|
201
|
-
if (!c.req.header("authorization")) requireSameOriginBrowserMutation(c, deps);
|
|
202
|
-
return await requirePrivateHuman(c, deps, workspaceId);
|
|
203
|
-
}
|
|
204
|
-
const grant = await requireAccessGrant(c, deps, workspaceId, "workspace:admin");
|
|
205
|
-
return { accountId: grant.accountId, subjectId: grant.subjectId };
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
async function resolveReadAuthority(
|
|
209
|
-
c: Context,
|
|
210
|
-
deps: ApiRouteDeps,
|
|
211
|
-
workspaceId: string,
|
|
212
|
-
): Promise<{
|
|
213
|
-
accountId: string;
|
|
214
|
-
subjectId: string;
|
|
215
|
-
snapshot: XaiAuthoritySnapshot;
|
|
216
|
-
}> {
|
|
217
|
-
const grant = await requireAccessGrant(c, deps, workspaceId, "workspace:read");
|
|
218
|
-
const snapshot = await resolveXaiProviderAccountAuthoritySnapshotForAcceptance(deps.db, {
|
|
97
|
+
runtime: "legacy" | "core" = "legacy",
|
|
98
|
+
) =>
|
|
99
|
+
requireSubscriptionScopeMutation(
|
|
100
|
+
c,
|
|
101
|
+
deps,
|
|
219
102
|
workspaceId,
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
103
|
+
scope,
|
|
104
|
+
"SuperGrok",
|
|
105
|
+
runtime === "core" ? "personal_workspace" : "ordinary_workspace",
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* The runtime serving a workspace route. With the receipt the switch row is
|
|
110
|
+
* read for the caller's organization, which a workspace grant names first,
|
|
111
|
+
* so an unauthenticated caller learns nothing about it.
|
|
112
|
+
*/
|
|
113
|
+
const workspaceRuntime = (c: Context, deps: ApiRouteDeps, workspaceId: string) =>
|
|
114
|
+
supergrokRoute(
|
|
115
|
+
deps,
|
|
116
|
+
async () => (await requireAccessGrant(c, deps, workspaceId, "workspace:read")).accountId,
|
|
117
|
+
);
|
|
233
118
|
|
|
234
119
|
function xaiHttpError(error: unknown, fallback: string): HTTPException {
|
|
120
|
+
// A connect poll can lose its database connection after provider login or
|
|
121
|
+
// persistence. Preserve retryability and unknown mutation outcome instead
|
|
122
|
+
// of misclassifying the outage as a provider 502.
|
|
123
|
+
const databaseError = databaseUnavailableHttpError(error, "POST");
|
|
124
|
+
if (databaseError) return databaseError;
|
|
235
125
|
if (error instanceof HTTPException) return error;
|
|
236
126
|
if (error instanceof XaiSubscriptionError) {
|
|
237
127
|
const status =
|
|
@@ -271,119 +161,62 @@ function accountJson(row: XaiSubscriptionAccountMetadata, activeCredentialId: st
|
|
|
271
161
|
};
|
|
272
162
|
}
|
|
273
163
|
|
|
274
|
-
|
|
164
|
+
/**
|
|
165
|
+
* Persist a finished SuperGrok device sign-in on the shared core: a personal
|
|
166
|
+
* connection for a `user` scope (only in the person's Personal workspace),
|
|
167
|
+
* else a shared one through the neutral writer. Returns the connection id.
|
|
168
|
+
*/
|
|
169
|
+
async function coreSuperGrokConnected(
|
|
170
|
+
c: Context,
|
|
275
171
|
deps: ApiRouteDeps,
|
|
276
172
|
input: {
|
|
277
173
|
accountId: string;
|
|
278
|
-
workspaceId: string;
|
|
174
|
+
workspaceId: string | null;
|
|
279
175
|
subjectId: string;
|
|
280
|
-
|
|
281
|
-
|
|
176
|
+
personal?: boolean;
|
|
177
|
+
encryptionKey: Uint8Array;
|
|
178
|
+
tokens: { accessToken: string; refreshToken?: string | null; expiresInSeconds: number };
|
|
179
|
+
identity: ReturnType<typeof xaiIdentityFromDeviceTokens>;
|
|
282
180
|
},
|
|
283
|
-
): Promise<{
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
let credential = await materializeXaiCredentialForRun(deps.db, {
|
|
294
|
-
...input,
|
|
295
|
-
encryptionKey,
|
|
296
|
-
});
|
|
297
|
-
const tokenSnapshot = () => {
|
|
298
|
-
if (!credential.secret.accessToken || !credential.providerAccountId) {
|
|
299
|
-
throw new XaiSubscriptionError(
|
|
300
|
-
"relogin_required",
|
|
301
|
-
"The SuperGrok connection is missing an access token or verified identity",
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
return {
|
|
305
|
-
accessToken: credential.secret.accessToken,
|
|
306
|
-
userId: credential.providerAccountId,
|
|
307
|
-
};
|
|
308
|
-
};
|
|
309
|
-
return {
|
|
310
|
-
account: credential,
|
|
311
|
-
context: {
|
|
312
|
-
clientVersion: XAI_CLIENT_VERSION,
|
|
313
|
-
getToken: async () => tokenSnapshot(),
|
|
314
|
-
refresh: async () => {
|
|
315
|
-
const observedAccessToken = credential.secret.accessToken;
|
|
316
|
-
const observedRefreshToken = credential.secret.refreshToken;
|
|
317
|
-
if (!observedRefreshToken) {
|
|
318
|
-
throw new XaiSubscriptionError(
|
|
319
|
-
"relogin_required",
|
|
320
|
-
"The SuperGrok connection cannot be refreshed",
|
|
321
|
-
);
|
|
322
|
-
}
|
|
323
|
-
const result = await refreshXaiSubscriptionCredentialSerialized(deps.db, {
|
|
324
|
-
accountId: input.accountId,
|
|
325
|
-
workspaceId: input.workspaceId,
|
|
326
|
-
subjectId: input.subjectId,
|
|
327
|
-
credentialId: input.credentialId,
|
|
328
|
-
authoritySnapshot: input.authoritySnapshot,
|
|
329
|
-
encryptionKey,
|
|
330
|
-
observedAccessToken,
|
|
331
|
-
observedRefreshToken,
|
|
332
|
-
refresh: async (current) => {
|
|
333
|
-
const refreshToken = current.secret.refreshToken;
|
|
334
|
-
if (!refreshToken) {
|
|
335
|
-
throw new XaiSubscriptionError(
|
|
336
|
-
"relogin_required",
|
|
337
|
-
"The SuperGrok connection cannot be refreshed",
|
|
338
|
-
);
|
|
339
|
-
}
|
|
340
|
-
const tokens = await refreshXaiToken(refreshToken, {
|
|
341
|
-
fetch: (deps.xaiFetch ?? fetch) as XaiFetch,
|
|
342
|
-
});
|
|
343
|
-
return {
|
|
344
|
-
secret: {
|
|
345
|
-
version: 1,
|
|
346
|
-
accessToken: tokens.accessToken,
|
|
347
|
-
refreshToken: tokens.refreshToken,
|
|
348
|
-
},
|
|
349
|
-
expiresAt:
|
|
350
|
-
xaiAccessTokenExpiry(tokens.accessToken) ??
|
|
351
|
-
new Date(Date.now() + tokens.expiresInSeconds * 1_000),
|
|
352
|
-
};
|
|
353
|
-
},
|
|
354
|
-
});
|
|
355
|
-
credential = result.credential;
|
|
356
|
-
return tokenSnapshot();
|
|
357
|
-
},
|
|
181
|
+
): Promise<string> {
|
|
182
|
+
const result = await connectSubscriptionCoreXaiConnection(deps.db, {
|
|
183
|
+
accountId: input.accountId,
|
|
184
|
+
workspaceId: input.workspaceId,
|
|
185
|
+
subjectId: input.subjectId,
|
|
186
|
+
...(input.personal ? { personal: true } : {}),
|
|
187
|
+
encryptionKey: input.encryptionKey,
|
|
188
|
+
tokens: {
|
|
189
|
+
accessToken: input.tokens.accessToken,
|
|
190
|
+
refreshToken: input.tokens.refreshToken || null,
|
|
358
191
|
},
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
credentialId: string,
|
|
367
|
-
): Promise<{
|
|
368
|
-
accountId: string;
|
|
369
|
-
subjectId: string;
|
|
370
|
-
snapshot: XaiAuthoritySnapshot;
|
|
371
|
-
}> {
|
|
372
|
-
const readGrant = await requireAccessGrant(c, deps, workspaceId, "workspace:read");
|
|
373
|
-
const snapshot = await getXaiSubscriptionAccountAuthoritySnapshot(deps.db, {
|
|
374
|
-
workspaceId,
|
|
375
|
-
subjectId: readGrant.subjectId,
|
|
376
|
-
credentialId,
|
|
192
|
+
identitySubject: input.identity.subject,
|
|
193
|
+
accountEmail: input.identity.email,
|
|
194
|
+
label: input.identity.name ?? input.identity.email ?? input.identity.subject,
|
|
195
|
+
expiresAt:
|
|
196
|
+
xaiAccessTokenExpiry(input.tokens.accessToken) ??
|
|
197
|
+
new Date(Date.now() + input.tokens.expiresInSeconds * 1_000),
|
|
198
|
+
connectedBySubjectId: (await managedCookieHuman(c, deps))?.subjectId ?? null,
|
|
377
199
|
});
|
|
378
|
-
if (
|
|
379
|
-
|
|
380
|
-
|
|
200
|
+
if (result.kind === "refused")
|
|
201
|
+
throw coreConnectRefused(result.reason, "SuperGrok", input.personal === true);
|
|
202
|
+
await deliverPoolCoreWake(deps, SUPERGROK_CORE, result.wake);
|
|
203
|
+
return result.id;
|
|
381
204
|
}
|
|
382
205
|
|
|
383
206
|
export function registerSuperGrokRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
207
|
+
registerSubscriptionAccountPoolRoutes(app, deps, {
|
|
208
|
+
provider: "xai",
|
|
209
|
+
route: "supergrok",
|
|
210
|
+
displayName: "SuperGrok",
|
|
211
|
+
enabled: () => deps.settings.supergrokSubscriptionEnabled,
|
|
212
|
+
accountJson,
|
|
213
|
+
core: SUPERGROK_CORE,
|
|
214
|
+
});
|
|
384
215
|
const { db } = deps;
|
|
385
216
|
|
|
386
217
|
const organizationPath = "/v1/organizations/:organizationId/supergrok";
|
|
218
|
+
// Device sign-in (start/poll) accepts an agent acting as an admin: the agent
|
|
219
|
+
// relays the short code, and the person still approves at xAI themselves.
|
|
387
220
|
const organizationActor = async (c: Context, mutation = false) => {
|
|
388
221
|
requireEnabled(deps);
|
|
389
222
|
if (mutation) requireSameOriginBrowserMutation(c, deps);
|
|
@@ -391,24 +224,10 @@ export function registerSuperGrokRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
391
224
|
const human = await requireOrganizationCodexHuman(c, deps, organizationId);
|
|
392
225
|
return { organizationId, actorSubjectId: human.subjectId };
|
|
393
226
|
};
|
|
394
|
-
app.get(`${organizationPath}/accounts`, async (c) => {
|
|
395
|
-
const actor = await organizationActor(c);
|
|
396
|
-
const { accounts, rotation } = await listOrganizationXaiSubscriptions(db, actor);
|
|
397
|
-
const activeAccountId = rotation?.activeCredentialId ?? null;
|
|
398
|
-
return c.json({
|
|
399
|
-
accounts: accounts.map((account) => accountJson(account, activeAccountId)),
|
|
400
|
-
activeAccountId,
|
|
401
|
-
source: "organization",
|
|
402
|
-
organizationId: actor.organizationId,
|
|
403
|
-
settings: {
|
|
404
|
-
rotationEnabled: rotation?.rotationEnabled ?? false,
|
|
405
|
-
rotationStrategy: "sharded",
|
|
406
|
-
activeCredentialId: activeAccountId,
|
|
407
|
-
},
|
|
408
|
-
});
|
|
409
|
-
});
|
|
410
227
|
app.post(`${organizationPath}/connect/start`, async (c) => {
|
|
411
228
|
const actor = await organizationActor(c, true);
|
|
229
|
+
// A sign-in that could not be saved is never started (maintenance fails closed).
|
|
230
|
+
await supergrokRoute(deps, async () => actor.organizationId);
|
|
412
231
|
try {
|
|
413
232
|
const start = await requestXaiDeviceCode({ fetch: (deps.xaiFetch ?? fetch) as XaiFetch });
|
|
414
233
|
const expiresAt = Math.floor(Date.now() / 1000) + start.expiresInSeconds;
|
|
@@ -429,6 +248,7 @@ export function registerSuperGrokRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
429
248
|
});
|
|
430
249
|
app.post(`${organizationPath}/connect/poll`, async (c) => {
|
|
431
250
|
const actor = await organizationActor(c, true);
|
|
251
|
+
await supergrokRoute(deps, async () => actor.organizationId);
|
|
432
252
|
const parsed = connectPollBody.safeParse(await c.req.json().catch(() => null));
|
|
433
253
|
if (!parsed.success) throw new HTTPException(400, { message: "SuperGrok state is required" });
|
|
434
254
|
const state = readSignedState(parsed.data.state, deps.githubStateSecret) as {
|
|
@@ -459,94 +279,38 @@ export function registerSuperGrokRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
459
279
|
const encryptionKey = environmentsEncryptionKeyBytes(deps.settings);
|
|
460
280
|
if (!encryptionKey)
|
|
461
281
|
throw new HTTPException(500, { message: "Connection encryption is not configured" });
|
|
462
|
-
const
|
|
463
|
-
|
|
282
|
+
const id = await coreSuperGrokConnected(c, deps, {
|
|
283
|
+
accountId: actor.organizationId,
|
|
284
|
+
workspaceId: null,
|
|
285
|
+
subjectId: actor.actorSubjectId,
|
|
464
286
|
encryptionKey,
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
label: identity.name ?? identity.email ?? identity.subject,
|
|
472
|
-
accountEmail: identity.email,
|
|
473
|
-
expiresAt:
|
|
474
|
-
xaiAccessTokenExpiry(poll.tokens.accessToken) ??
|
|
475
|
-
new Date(Date.now() + poll.tokens.expiresInSeconds * 1000),
|
|
287
|
+
tokens: poll.tokens,
|
|
288
|
+
identity,
|
|
289
|
+
});
|
|
290
|
+
const { activeCredentialId } = await getSubscriptionCoreXaiOrganizationProjection(db, {
|
|
291
|
+
organizationId: actor.organizationId,
|
|
292
|
+
subjectId: actor.actorSubjectId,
|
|
476
293
|
});
|
|
477
294
|
return c.json({
|
|
478
295
|
status: "connected",
|
|
479
|
-
accountId:
|
|
296
|
+
accountId: id,
|
|
480
297
|
scope: "organization",
|
|
481
|
-
isActive:
|
|
298
|
+
isActive: activeCredentialId === id,
|
|
482
299
|
email: identity.email,
|
|
483
300
|
});
|
|
484
301
|
} catch (error) {
|
|
485
302
|
throw xaiHttpError(error, "SuperGrok device login failed");
|
|
486
303
|
}
|
|
487
304
|
});
|
|
488
|
-
app.patch(`${organizationPath}/settings`, async (c) => {
|
|
489
|
-
const actor = await organizationActor(c, true);
|
|
490
|
-
const parsed = settingsBody.safeParse(await c.req.json().catch(() => null));
|
|
491
|
-
if (!parsed.success) throw new HTTPException(400, { message: "rotationEnabled is required" });
|
|
492
|
-
const rotation = await updateOrganizationXaiRotation(db, { ...actor, ...parsed.data });
|
|
493
|
-
return c.json({
|
|
494
|
-
rotationEnabled: rotation.rotationEnabled,
|
|
495
|
-
rotationStrategy: "sharded",
|
|
496
|
-
activeCredentialId: rotation.activeCredentialId,
|
|
497
|
-
});
|
|
498
|
-
});
|
|
499
|
-
const updateOrganizationAccount = async (
|
|
500
|
-
c: Context,
|
|
501
|
-
changes: Omit<
|
|
502
|
-
Parameters<typeof updateOrganizationXaiSubscription>[1],
|
|
503
|
-
"organizationId" | "actorSubjectId" | "credentialId"
|
|
504
|
-
>,
|
|
505
|
-
) => {
|
|
506
|
-
const actor = await organizationActor(c, true);
|
|
507
|
-
try {
|
|
508
|
-
const result = await updateOrganizationXaiSubscription(db, {
|
|
509
|
-
...actor,
|
|
510
|
-
credentialId: c.req.param("accountId")!,
|
|
511
|
-
...changes,
|
|
512
|
-
});
|
|
513
|
-
if (!result) throw new HTTPException(404, { message: "SuperGrok account not found" });
|
|
514
|
-
return c.json(result);
|
|
515
|
-
} catch (error) {
|
|
516
|
-
if (error instanceof HTTPException) throw error;
|
|
517
|
-
throw new HTTPException(409, {
|
|
518
|
-
message:
|
|
519
|
-
error instanceof Error ? error.message : "SuperGrok subscription could not be updated",
|
|
520
|
-
});
|
|
521
|
-
}
|
|
522
|
-
};
|
|
523
|
-
app.post(`${organizationPath}/accounts/:accountId/activate`, (c) =>
|
|
524
|
-
updateOrganizationAccount(c, { activate: true }),
|
|
525
|
-
);
|
|
526
|
-
app.delete(`${organizationPath}/accounts/:accountId`, (c) =>
|
|
527
|
-
updateOrganizationAccount(c, { disconnect: true }),
|
|
528
|
-
);
|
|
529
|
-
app.patch(`${organizationPath}/accounts/:accountId`, async (c) => {
|
|
530
|
-
const parsed = renameBody.safeParse(await c.req.json().catch(() => null));
|
|
531
|
-
if (!parsed.success) throw new HTTPException(400, { message: "label is invalid" });
|
|
532
|
-
return updateOrganizationAccount(c, { label: parsed.data.label || null });
|
|
533
|
-
});
|
|
534
|
-
app.patch(`${organizationPath}/accounts/:accountId/allocator`, async (c) => {
|
|
535
|
-
const parsed = allocatorBody.safeParse(await c.req.json().catch(() => null));
|
|
536
|
-
if (!parsed.success)
|
|
537
|
-
throw new HTTPException(400, { message: "enabled and expectedVersion are required" });
|
|
538
|
-
return updateOrganizationAccount(c, {
|
|
539
|
-
allocatorEnabled: parsed.data.enabled,
|
|
540
|
-
expectedAllocatorVersion: parsed.data.expectedVersion,
|
|
541
|
-
});
|
|
542
|
-
});
|
|
543
|
-
|
|
544
305
|
app.post("/v1/workspaces/:workspaceId/supergrok/connect/start", async (c) => {
|
|
545
306
|
requireEnabled(deps);
|
|
546
307
|
const workspaceId = c.req.param("workspaceId");
|
|
547
308
|
const parsed = connectStartBody.safeParse(await c.req.json().catch(() => ({})));
|
|
548
309
|
if (!parsed.success) throw new HTTPException(400, { message: "invalid SuperGrok scope" });
|
|
549
|
-
|
|
310
|
+
// On the core a private account is connected only from the person's own
|
|
311
|
+
// Personal workspace: refused here, before the xAI sign-in, elsewhere.
|
|
312
|
+
const runtime = await workspaceRuntime(c, deps, workspaceId);
|
|
313
|
+
const authority = await requireScopeMutation(c, deps, workspaceId, parsed.data.scope, runtime);
|
|
550
314
|
const authorization = await requireAccessGrantAuthorization(
|
|
551
315
|
c,
|
|
552
316
|
deps,
|
|
@@ -613,7 +377,8 @@ export function registerSuperGrokRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
613
377
|
message: "SuperGrok connect state is invalid or expired",
|
|
614
378
|
});
|
|
615
379
|
}
|
|
616
|
-
const
|
|
380
|
+
const runtime = await workspaceRuntime(c, deps, workspaceId);
|
|
381
|
+
const authority = await requireScopeMutation(c, deps, workspaceId, state.scope, runtime);
|
|
617
382
|
if (authority.subjectId !== state.subjectId) {
|
|
618
383
|
throw new HTTPException(403, {
|
|
619
384
|
message: "SuperGrok connect identity changed",
|
|
@@ -660,7 +425,7 @@ export function registerSuperGrokRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
660
425
|
const identity = xaiIdentityFromDeviceTokens(poll.tokens);
|
|
661
426
|
phase = "credential_persist";
|
|
662
427
|
await requireOrigin();
|
|
663
|
-
const liveAuthority = await requireScopeMutation(c, deps, workspaceId, state.scope);
|
|
428
|
+
const liveAuthority = await requireScopeMutation(c, deps, workspaceId, state.scope, runtime);
|
|
664
429
|
if (
|
|
665
430
|
liveAuthority.accountId !== authority.accountId ||
|
|
666
431
|
liveAuthority.subjectId !== authority.subjectId
|
|
@@ -672,51 +437,25 @@ export function registerSuperGrokRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
672
437
|
message: "OPENGENI_ENVIRONMENTS_ENCRYPTION_KEY is not configured",
|
|
673
438
|
});
|
|
674
439
|
}
|
|
675
|
-
const
|
|
440
|
+
const id = await coreSuperGrokConnected(c, deps, {
|
|
676
441
|
accountId: authority.accountId,
|
|
677
442
|
workspaceId,
|
|
678
443
|
subjectId: authority.subjectId,
|
|
679
|
-
|
|
444
|
+
personal: state.scope === "user",
|
|
680
445
|
encryptionKey,
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
accessToken: poll.tokens.accessToken,
|
|
684
|
-
refreshToken: poll.tokens.refreshToken,
|
|
685
|
-
},
|
|
686
|
-
providerAccountId: identity.subject,
|
|
687
|
-
label: identity.name ?? identity.email ?? identity.subject,
|
|
688
|
-
accountEmail: identity.email,
|
|
689
|
-
expiresAt:
|
|
690
|
-
xaiAccessTokenExpiry(poll.tokens.accessToken) ??
|
|
691
|
-
new Date(Date.now() + poll.tokens.expiresInSeconds * 1_000),
|
|
446
|
+
tokens: poll.tokens,
|
|
447
|
+
identity,
|
|
692
448
|
});
|
|
693
|
-
const
|
|
449
|
+
const { activeCredentialId } = await getSubscriptionCoreXaiWorkspaceProjection(deps.db, {
|
|
694
450
|
accountId: authority.accountId,
|
|
695
451
|
workspaceId,
|
|
696
|
-
|
|
697
|
-
authoritySnapshot: upserted.authoritySnapshot,
|
|
698
|
-
});
|
|
699
|
-
let isActive = rotation.activeCredentialId === upserted.account.id;
|
|
700
|
-
if (!isActive && rotation.activeCredentialId === null) {
|
|
701
|
-
isActive = await setInitialActiveXaiCredential(deps.db, {
|
|
702
|
-
accountId: authority.accountId,
|
|
703
|
-
workspaceId,
|
|
704
|
-
subjectId: authority.subjectId,
|
|
705
|
-
authoritySnapshot: upserted.authoritySnapshot,
|
|
706
|
-
credentialId: upserted.account.id,
|
|
707
|
-
});
|
|
708
|
-
}
|
|
709
|
-
await wakeXaiCapacityWaiters(deps.db, {
|
|
710
|
-
workspaceId,
|
|
711
|
-
subjectId: authority.subjectId,
|
|
712
|
-
authoritySnapshot: upserted.authoritySnapshot,
|
|
713
|
-
reason: "xai_credential_connected",
|
|
452
|
+
viewerSubjectId: authority.subjectId,
|
|
714
453
|
});
|
|
715
454
|
return c.json({
|
|
716
455
|
status: "connected" as const,
|
|
717
|
-
accountId:
|
|
456
|
+
accountId: id,
|
|
718
457
|
scope: state.scope,
|
|
719
|
-
isActive,
|
|
458
|
+
isActive: activeCredentialId === id,
|
|
720
459
|
email: identity.email,
|
|
721
460
|
});
|
|
722
461
|
} catch (error) {
|
|
@@ -742,265 +481,45 @@ export function registerSuperGrokRoutes(app: Hono, deps: ApiRouteDeps): void {
|
|
|
742
481
|
}
|
|
743
482
|
});
|
|
744
483
|
|
|
745
|
-
app.get("/v1/workspaces/:workspaceId/supergrok/accounts", async (c) => {
|
|
746
|
-
requireEnabled(deps);
|
|
747
|
-
const workspaceId = c.req.param("workspaceId");
|
|
748
|
-
const authority = await resolveReadAuthority(c, deps, workspaceId);
|
|
749
|
-
const [accounts, settings] = await Promise.all([
|
|
750
|
-
listXaiSubscriptionAccountsMetadata(deps.db, {
|
|
751
|
-
workspaceId,
|
|
752
|
-
subjectId: authority.subjectId,
|
|
753
|
-
}),
|
|
754
|
-
getXaiRotationSettings(deps.db, {
|
|
755
|
-
workspaceId,
|
|
756
|
-
subjectId: authority.subjectId,
|
|
757
|
-
authoritySnapshot: authority.snapshot,
|
|
758
|
-
}),
|
|
759
|
-
]);
|
|
760
|
-
const activeCredentialId = settings?.activeCredentialId ?? null;
|
|
761
|
-
return c.json({
|
|
762
|
-
source: authority.snapshot.scope,
|
|
763
|
-
organizationId: authority.accountId,
|
|
764
|
-
accounts: accounts
|
|
765
|
-
.filter((account) =>
|
|
766
|
-
authority.snapshot.scope === "organization"
|
|
767
|
-
? account.scope === "organization"
|
|
768
|
-
: account.scope !== "organization",
|
|
769
|
-
)
|
|
770
|
-
.map((account) => accountJson(account, activeCredentialId)),
|
|
771
|
-
activeAccountId: activeCredentialId,
|
|
772
|
-
settings: {
|
|
773
|
-
rotationEnabled: settings?.rotationEnabled ?? true,
|
|
774
|
-
rotationStrategy: "sharded" as const,
|
|
775
|
-
activeCredentialId,
|
|
776
|
-
},
|
|
777
|
-
});
|
|
778
|
-
});
|
|
779
|
-
|
|
780
484
|
app.get("/v1/workspaces/:workspaceId/supergrok/status", async (c) => {
|
|
781
485
|
requireEnabled(deps);
|
|
782
486
|
const workspaceId = c.req.param("workspaceId");
|
|
783
|
-
const
|
|
784
|
-
const
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
return c.json({
|
|
798
|
-
connected: accounts.length > 0,
|
|
799
|
-
valid: false,
|
|
800
|
-
accountCount: accounts.length,
|
|
801
|
-
});
|
|
802
|
-
}
|
|
803
|
-
let valid = false;
|
|
804
|
-
try {
|
|
805
|
-
const auth = await materializedAuthContext(deps, {
|
|
806
|
-
accountId: authority.accountId,
|
|
487
|
+
const grant = await requireAccessGrant(c, deps, workspaceId, "workspace:read");
|
|
488
|
+
const supergrokModels = async () =>
|
|
489
|
+
configuredModels(
|
|
490
|
+
withXaiSubscriptionCatalogProvider((await deps.resolveCatalogSettings()).settings),
|
|
491
|
+
)
|
|
492
|
+
.filter(
|
|
493
|
+
(model) =>
|
|
494
|
+
model.credentialSource.kind === "connected_subscription" &&
|
|
495
|
+
model.credentialSource.provider === "xai",
|
|
496
|
+
)
|
|
497
|
+
.map(projectClientModel);
|
|
498
|
+
return c.json(
|
|
499
|
+
await readXaiCoreStatus(deps, {
|
|
500
|
+
accountId: grant.accountId,
|
|
807
501
|
workspaceId,
|
|
808
|
-
subjectId:
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
502
|
+
subjectId: grant.subjectId,
|
|
503
|
+
models: supergrokModels,
|
|
504
|
+
// Only the verified owner in their Personal workspace may make a
|
|
505
|
+
// live personal-account usage request; other viewers get stored status.
|
|
506
|
+
ownerVerified: async () => {
|
|
507
|
+
try {
|
|
508
|
+
const owner = await requirePrivateSubscriptionHuman(
|
|
509
|
+
c,
|
|
510
|
+
deps,
|
|
511
|
+
workspaceId,
|
|
512
|
+
"SuperGrok",
|
|
513
|
+
"personal_workspace",
|
|
514
|
+
);
|
|
515
|
+
return owner.accountId === grant.accountId && owner.subjectId === grant.subjectId;
|
|
516
|
+
} catch (error) {
|
|
517
|
+
if (error instanceof HTTPException) return false;
|
|
518
|
+
throw error;
|
|
519
|
+
}
|
|
520
|
+
},
|
|
814
521
|
...(deps.xaiFetch ? { fetch: deps.xaiFetch } : {}),
|
|
815
|
-
})
|
|
816
|
-
valid = true;
|
|
817
|
-
} catch {
|
|
818
|
-
valid = false;
|
|
819
|
-
}
|
|
820
|
-
const catalogSettings = valid ? (await deps.resolveCatalogSettings()).settings : null;
|
|
821
|
-
const catalog = catalogSettings
|
|
822
|
-
? configuredModels(withXaiSubscriptionCatalogProvider(catalogSettings))
|
|
823
|
-
.filter(
|
|
824
|
-
(model) =>
|
|
825
|
-
model.credentialSource.kind === "connected_subscription" &&
|
|
826
|
-
model.credentialSource.provider === "xai",
|
|
827
|
-
)
|
|
828
|
-
.map(projectClientModel)
|
|
829
|
-
: [];
|
|
830
|
-
return c.json({
|
|
831
|
-
connected: true,
|
|
832
|
-
valid,
|
|
833
|
-
accountCount: accounts.length,
|
|
834
|
-
models: catalog,
|
|
835
|
-
activeAccount: {
|
|
836
|
-
id: active.id,
|
|
837
|
-
label: active.label,
|
|
838
|
-
subject: active.providerAccountId,
|
|
839
|
-
scope: active.scope,
|
|
840
|
-
},
|
|
841
|
-
});
|
|
842
|
-
});
|
|
843
|
-
|
|
844
|
-
app.post("/v1/workspaces/:workspaceId/supergrok/accounts/:accountId/activate", async (c) => {
|
|
845
|
-
requireEnabled(deps);
|
|
846
|
-
const workspaceId = c.req.param("workspaceId");
|
|
847
|
-
const credentialId = c.req.param("accountId");
|
|
848
|
-
const authority = await authorityForAccountMutation(c, deps, workspaceId, credentialId);
|
|
849
|
-
const activated = await setActiveXaiCredential(deps.db, {
|
|
850
|
-
accountId: authority.accountId,
|
|
851
|
-
workspaceId,
|
|
852
|
-
subjectId: authority.subjectId,
|
|
853
|
-
authoritySnapshot: authority.snapshot,
|
|
854
|
-
credentialId,
|
|
855
|
-
});
|
|
856
|
-
if (!activated)
|
|
857
|
-
throw new HTTPException(409, {
|
|
858
|
-
message: "SuperGrok account requires relogin",
|
|
859
|
-
});
|
|
860
|
-
await wakeXaiCapacityWaiters(deps.db, {
|
|
861
|
-
workspaceId,
|
|
862
|
-
subjectId: authority.subjectId,
|
|
863
|
-
authoritySnapshot: authority.snapshot,
|
|
864
|
-
reason: "xai_active_credential_changed",
|
|
865
|
-
});
|
|
866
|
-
return c.json({ activated: true, accountId: credentialId });
|
|
867
|
-
});
|
|
868
|
-
|
|
869
|
-
app.patch("/v1/workspaces/:workspaceId/supergrok/settings", async (c) => {
|
|
870
|
-
requireEnabled(deps);
|
|
871
|
-
const workspaceId = c.req.param("workspaceId");
|
|
872
|
-
const parsed = settingsBody.safeParse(await c.req.json().catch(() => null));
|
|
873
|
-
if (!parsed.success) throw new HTTPException(400, { message: "rotationEnabled is required" });
|
|
874
|
-
const readAuthority = await resolveReadAuthority(c, deps, workspaceId);
|
|
875
|
-
const authority = await requireScopeMutation(
|
|
876
|
-
c,
|
|
877
|
-
deps,
|
|
878
|
-
workspaceId,
|
|
879
|
-
readAuthority.snapshot.scope,
|
|
522
|
+
}),
|
|
880
523
|
);
|
|
881
|
-
const current = await ensureXaiRotationSettings(deps.db, {
|
|
882
|
-
accountId: authority.accountId,
|
|
883
|
-
workspaceId,
|
|
884
|
-
subjectId: authority.subjectId,
|
|
885
|
-
authoritySnapshot: readAuthority.snapshot,
|
|
886
|
-
});
|
|
887
|
-
const updated = await updateXaiRotationSettings(deps.db, {
|
|
888
|
-
workspaceId,
|
|
889
|
-
subjectId: authority.subjectId,
|
|
890
|
-
authoritySnapshot: readAuthority.snapshot,
|
|
891
|
-
expectedVersion: current.version,
|
|
892
|
-
rotationEnabled: parsed.data.rotationEnabled,
|
|
893
|
-
}).catch(() => null);
|
|
894
|
-
if (!updated) throw new HTTPException(409, { message: "SuperGrok settings changed" });
|
|
895
|
-
await wakeXaiCapacityWaiters(deps.db, {
|
|
896
|
-
workspaceId,
|
|
897
|
-
subjectId: authority.subjectId,
|
|
898
|
-
authoritySnapshot: readAuthority.snapshot,
|
|
899
|
-
reason: "xai_rotation_settings_changed",
|
|
900
|
-
});
|
|
901
|
-
return c.json({
|
|
902
|
-
rotationEnabled: updated.rotationEnabled,
|
|
903
|
-
rotationStrategy: "sharded" as const,
|
|
904
|
-
activeCredentialId: updated.activeCredentialId,
|
|
905
|
-
});
|
|
906
|
-
});
|
|
907
|
-
|
|
908
|
-
app.patch("/v1/workspaces/:workspaceId/supergrok/accounts/:accountId/allocator", async (c) => {
|
|
909
|
-
requireEnabled(deps);
|
|
910
|
-
const workspaceId = c.req.param("workspaceId");
|
|
911
|
-
const credentialId = c.req.param("accountId");
|
|
912
|
-
const authority = await authorityForAccountMutation(c, deps, workspaceId, credentialId);
|
|
913
|
-
const parsed = allocatorBody.safeParse(await c.req.json().catch(() => null));
|
|
914
|
-
if (!parsed.success) {
|
|
915
|
-
throw new HTTPException(400, {
|
|
916
|
-
message: "enabled and expectedVersion are required",
|
|
917
|
-
});
|
|
918
|
-
}
|
|
919
|
-
const result = await updateXaiAllocatorEligibility(deps.db, {
|
|
920
|
-
workspaceId,
|
|
921
|
-
subjectId: authority.subjectId,
|
|
922
|
-
credentialId,
|
|
923
|
-
enabled: parsed.data.enabled,
|
|
924
|
-
expectedVersion: parsed.data.expectedVersion,
|
|
925
|
-
});
|
|
926
|
-
if (result.kind === "not_found") {
|
|
927
|
-
throw new HTTPException(404, {
|
|
928
|
-
message: "SuperGrok account not found",
|
|
929
|
-
});
|
|
930
|
-
}
|
|
931
|
-
const response = {
|
|
932
|
-
allocatorEnabled: result.allocatorEnabled,
|
|
933
|
-
allocatorVersion: result.allocatorVersion,
|
|
934
|
-
allocatorUpdatedAt: result.allocatorUpdatedAt?.toISOString() ?? null,
|
|
935
|
-
changed: result.kind === "updated",
|
|
936
|
-
};
|
|
937
|
-
if (result.kind === "updated") {
|
|
938
|
-
await wakeXaiCapacityWaiters(deps.db, {
|
|
939
|
-
workspaceId,
|
|
940
|
-
subjectId: authority.subjectId,
|
|
941
|
-
authoritySnapshot: authority.snapshot,
|
|
942
|
-
reason: "xai_allocator_eligibility_changed",
|
|
943
|
-
});
|
|
944
|
-
}
|
|
945
|
-
return result.kind === "conflict" ? c.json(response, 409) : c.json(response);
|
|
946
|
-
});
|
|
947
|
-
|
|
948
|
-
app.patch("/v1/workspaces/:workspaceId/supergrok/accounts/:accountId", async (c) => {
|
|
949
|
-
requireEnabled(deps);
|
|
950
|
-
const workspaceId = c.req.param("workspaceId");
|
|
951
|
-
const credentialId = c.req.param("accountId");
|
|
952
|
-
const authority = await authorityForAccountMutation(c, deps, workspaceId, credentialId);
|
|
953
|
-
const parsed = renameBody.safeParse(await c.req.json().catch(() => null));
|
|
954
|
-
if (!parsed.success) throw new HTTPException(400, { message: "label is invalid" });
|
|
955
|
-
const account = await renameXaiSubscriptionAccount(deps.db, {
|
|
956
|
-
workspaceId,
|
|
957
|
-
subjectId: authority.subjectId,
|
|
958
|
-
credentialId,
|
|
959
|
-
label: parsed.data.label || null,
|
|
960
|
-
});
|
|
961
|
-
if (!account)
|
|
962
|
-
throw new HTTPException(404, {
|
|
963
|
-
message: "SuperGrok account not found",
|
|
964
|
-
});
|
|
965
|
-
const settings = await getXaiRotationSettings(deps.db, {
|
|
966
|
-
workspaceId,
|
|
967
|
-
subjectId: authority.subjectId,
|
|
968
|
-
authoritySnapshot: authority.snapshot,
|
|
969
|
-
});
|
|
970
|
-
return c.json(accountJson(account, settings?.activeCredentialId ?? null));
|
|
971
|
-
});
|
|
972
|
-
|
|
973
|
-
app.delete("/v1/workspaces/:workspaceId/supergrok/accounts/:accountId", async (c) => {
|
|
974
|
-
requireEnabled(deps);
|
|
975
|
-
const workspaceId = c.req.param("workspaceId");
|
|
976
|
-
const credentialId = c.req.param("accountId");
|
|
977
|
-
const authority = await authorityForAccountMutation(c, deps, workspaceId, credentialId);
|
|
978
|
-
if (authority.snapshot.scope === "user") {
|
|
979
|
-
await wakeXaiCapacityWaiters(deps.db, {
|
|
980
|
-
workspaceId,
|
|
981
|
-
subjectId: authority.subjectId,
|
|
982
|
-
authoritySnapshot: authority.snapshot,
|
|
983
|
-
reason: "xai_credential_disconnecting",
|
|
984
|
-
});
|
|
985
|
-
}
|
|
986
|
-
const result = await disconnectXaiSubscriptionCredentialAndRepick(deps.db, {
|
|
987
|
-
accountId: authority.accountId,
|
|
988
|
-
workspaceId,
|
|
989
|
-
subjectId: authority.subjectId,
|
|
990
|
-
credentialId,
|
|
991
|
-
authoritySnapshot: authority.snapshot,
|
|
992
|
-
});
|
|
993
|
-
if (result.disconnected && authority.snapshot.scope === "workspace") {
|
|
994
|
-
await wakeXaiCapacityWaiters(deps.db, {
|
|
995
|
-
workspaceId,
|
|
996
|
-
subjectId: authority.subjectId,
|
|
997
|
-
authoritySnapshot: WORKSPACE_XAI_PROVIDER_ACCOUNT_AUTHORITY_SNAPSHOT_V1,
|
|
998
|
-
reason: "xai_credential_disconnected",
|
|
999
|
-
});
|
|
1000
|
-
}
|
|
1001
|
-
return c.json({
|
|
1002
|
-
disconnected: result.disconnected,
|
|
1003
|
-
newActiveId: result.newActiveCredentialId,
|
|
1004
|
-
});
|
|
1005
524
|
});
|
|
1006
525
|
}
|