@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
|
@@ -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 {
|
|
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
|
-
|
|
112
|
-
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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 ?
|
|
300
|
+
...(deps.observability ? observabilityEventBusOptions(deps.observability) : {}),
|
|
218
301
|
},
|
|
219
302
|
);
|
|
220
|
-
deps.observability?.info?.("
|
|
303
|
+
deps.observability?.info?.("Opengeni NATS auth-callout responder started", {
|
|
221
304
|
subject: AUTH_CALLOUT_SUBJECT,
|
|
222
305
|
});
|
|
223
306
|
return connection;
|