@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
|
@@ -1,16 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
resolveVoiceInputProviderRegistry,
|
|
3
|
+
voiceInputCreditBillingActive,
|
|
4
|
+
type Settings,
|
|
5
|
+
} from "@opengeni/config";
|
|
2
6
|
import { VOICE_INPUT_ACCEPTED_MIME_TYPES } from "@opengeni/contracts";
|
|
7
|
+
import { voiceTranscriptionSettlementKeys } from "@opengeni/db";
|
|
3
8
|
import {
|
|
9
|
+
createVoiceInputBilling,
|
|
4
10
|
filenameForMimeType,
|
|
5
11
|
isAcceptedMimeType,
|
|
6
12
|
normalizeMimeType,
|
|
7
13
|
TRANSCRIPTION_PROVIDER_REQUEST_TIMEOUT_MILLISECONDS,
|
|
8
14
|
type TranscriptionAvailabilityContext,
|
|
15
|
+
type TranscriptionBilling,
|
|
16
|
+
type TranscriptionBillingContext,
|
|
9
17
|
type TranscriptionProvider,
|
|
10
18
|
type TranscriptionService,
|
|
11
19
|
TranscriptionServiceError,
|
|
12
20
|
} from "@opengeni/core";
|
|
13
21
|
import type { Database } from "@opengeni/db";
|
|
22
|
+
import { createFfmpegAudioNormalizer, type TranscriptionAudioNormalizer } from "./normalize";
|
|
23
|
+
import { createMaiTranscriptionProvider } from "./providers/azure-mai";
|
|
14
24
|
import { createAzureOpenAiTranscriptionProvider } from "./providers/azure-openai";
|
|
15
25
|
import { createCodexSubscriptionTranscriptionProvider } from "./providers/codex-subscription";
|
|
16
26
|
import { createOpenAiTranscriptionProvider } from "./providers/openai";
|
|
@@ -26,6 +36,14 @@ export function createTranscriptionService(input: {
|
|
|
26
36
|
providerRequestTimeoutMilliseconds?: number;
|
|
27
37
|
/** Test seam for evaluating persisted absolute deadlines after delayed setup. */
|
|
28
38
|
now?: () => Date;
|
|
39
|
+
/** Credit admission/settlement for deployment-funded providers. */
|
|
40
|
+
billing?: TranscriptionBilling;
|
|
41
|
+
/** Test seam: trusted one-shot decode + duration (defaults to ffmpeg). */
|
|
42
|
+
normalizeAudio?: TranscriptionAudioNormalizer;
|
|
43
|
+
/** Loud operator log for settlement failures after provider success. */
|
|
44
|
+
log?: (message: string, attributes: Record<string, string | number | boolean>) => void;
|
|
45
|
+
/** In-process settlement retry pacing after an inline failure. */
|
|
46
|
+
settlementRetryDelaysMilliseconds?: readonly number[];
|
|
29
47
|
}): TranscriptionService {
|
|
30
48
|
const providers: TranscriptionProvider[] = resolveVoiceInputProviderRegistry(input.settings).map(
|
|
31
49
|
(config) => {
|
|
@@ -35,6 +53,12 @@ export function createTranscriptionService(input: {
|
|
|
35
53
|
...config,
|
|
36
54
|
...(input.fetch ? { fetch: input.fetch } : {}),
|
|
37
55
|
});
|
|
56
|
+
case "azure-mai":
|
|
57
|
+
return createMaiTranscriptionProvider({
|
|
58
|
+
...config,
|
|
59
|
+
ffmpegPath: input.settings.voiceInputFfmpegPath,
|
|
60
|
+
...(input.fetch ? { fetch: input.fetch } : {}),
|
|
61
|
+
});
|
|
38
62
|
case "azure-openai":
|
|
39
63
|
return createAzureOpenAiTranscriptionProvider({
|
|
40
64
|
...config,
|
|
@@ -66,16 +90,119 @@ export function createTranscriptionService(input: {
|
|
|
66
90
|
const providerRequestTimeoutMilliseconds =
|
|
67
91
|
input.providerRequestTimeoutMilliseconds ?? TRANSCRIPTION_PROVIDER_REQUEST_TIMEOUT_MILLISECONDS;
|
|
68
92
|
const now = input.now ?? (() => new Date());
|
|
93
|
+
const log =
|
|
94
|
+
input.log ??
|
|
95
|
+
((message: string, attributes: Record<string, string | number | boolean>) => {
|
|
96
|
+
console.error(message, attributes);
|
|
97
|
+
});
|
|
98
|
+
const billing =
|
|
99
|
+
input.billing ??
|
|
100
|
+
createVoiceInputBilling({
|
|
101
|
+
db: input.db,
|
|
102
|
+
settings: input.settings,
|
|
103
|
+
onReconcileError: (error, scope) => {
|
|
104
|
+
log("Voice input charge reconciliation failed", {
|
|
105
|
+
...scope,
|
|
106
|
+
errorClass: error instanceof Error ? error.name : "UnknownError",
|
|
107
|
+
error: boundedErrorMessage(error),
|
|
108
|
+
});
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
let normalizer: TranscriptionAudioNormalizer | undefined = input.normalizeAudio;
|
|
112
|
+
const normalizeAudio: TranscriptionAudioNormalizer = (request) => {
|
|
113
|
+
normalizer ??= createFfmpegAudioNormalizer({ ffmpegPath: input.settings.voiceInputFfmpegPath });
|
|
114
|
+
return normalizer(request);
|
|
115
|
+
};
|
|
116
|
+
const retryDelays = input.settlementRetryDelaysMilliseconds ?? [2_000, 15_000, 60_000];
|
|
117
|
+
type Settlement = Parameters<TranscriptionBilling["settle"]>[0];
|
|
118
|
+
/**
|
|
119
|
+
* Post-use settlement never fails the request: the provider already returned
|
|
120
|
+
* text the user is waiting for. A failure is logged with the exact
|
|
121
|
+
* idempotency keys and retried in-process; if the receipt committed but the
|
|
122
|
+
* debit did not, the next admission in the workspace reconciles it.
|
|
123
|
+
*/
|
|
124
|
+
const settleWithoutFailing = async (settlement: Settlement): Promise<number> => {
|
|
125
|
+
try {
|
|
126
|
+
return (await billing.settle(settlement)).creditCostMicros;
|
|
127
|
+
} catch (error) {
|
|
128
|
+
reportUnsettled(settlement, error, 0, retryDelays.length > 0 && !deterministic(error));
|
|
129
|
+
if (!deterministic(error)) scheduleSettlementRetry(settlement, 0);
|
|
130
|
+
return 0;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
const deterministic = (error: unknown) => error instanceof TranscriptionServiceError;
|
|
134
|
+
const scheduleSettlementRetry = (settlement: Settlement, attempt: number) => {
|
|
135
|
+
const delay = retryDelays[attempt];
|
|
136
|
+
if (delay === undefined) return;
|
|
137
|
+
const timer = setTimeout(() => {
|
|
138
|
+
void billing.settle(settlement).then(
|
|
139
|
+
() => {
|
|
140
|
+
log("Voice input charge settled on retry", {
|
|
141
|
+
...settlementAttributes(settlement),
|
|
142
|
+
attempt: attempt + 1,
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
(error: unknown) => {
|
|
146
|
+
const more = attempt + 1 < retryDelays.length;
|
|
147
|
+
reportUnsettled(settlement, error, attempt + 1, more);
|
|
148
|
+
if (more) scheduleSettlementRetry(settlement, attempt + 1);
|
|
149
|
+
},
|
|
150
|
+
);
|
|
151
|
+
}, delay);
|
|
152
|
+
(timer as ReturnType<typeof setTimeout> & { unref?: () => void }).unref?.();
|
|
153
|
+
};
|
|
154
|
+
const reportUnsettled = (
|
|
155
|
+
settlement: Settlement,
|
|
156
|
+
error: unknown,
|
|
157
|
+
attempt: number,
|
|
158
|
+
willRetry: boolean,
|
|
159
|
+
) => {
|
|
160
|
+
log(
|
|
161
|
+
willRetry
|
|
162
|
+
? "Voice input charge is unsettled after provider success; retrying"
|
|
163
|
+
: "Voice input charge is UNSETTLED after provider success; manual reconciliation needed unless its usage receipt committed",
|
|
164
|
+
{
|
|
165
|
+
...settlementAttributes(settlement),
|
|
166
|
+
attempt,
|
|
167
|
+
willRetry,
|
|
168
|
+
errorClass: error instanceof Error ? error.name : "UnknownError",
|
|
169
|
+
error: boundedErrorMessage(error),
|
|
170
|
+
},
|
|
171
|
+
);
|
|
172
|
+
};
|
|
173
|
+
const creditBillingActive = voiceInputCreditBillingActive(input.settings);
|
|
174
|
+
/** Deployment-funded calls are charged; the workspace's own subscriptions never are. */
|
|
175
|
+
const chargeable = (provider: TranscriptionProvider) =>
|
|
176
|
+
creditBillingActive && provider.deploymentFunded !== undefined;
|
|
69
177
|
return {
|
|
70
178
|
limits: () => limits,
|
|
71
179
|
async available(context) {
|
|
72
|
-
return (
|
|
73
|
-
|
|
180
|
+
return Boolean(
|
|
181
|
+
await firstAvailable(orderedProviders(providers, context ?? {}), context ?? {}),
|
|
182
|
+
);
|
|
183
|
+
},
|
|
184
|
+
async availableProviderIds(context) {
|
|
185
|
+
// Every ready provider, for the workspace provider picker. One failing
|
|
186
|
+
// probe means that provider is not ready; it never fails the caller.
|
|
187
|
+
const available = await Promise.all(
|
|
188
|
+
providers.map(async (provider) => {
|
|
189
|
+
try {
|
|
190
|
+
return (await provider.available(context)) ? provider.id : null;
|
|
191
|
+
} catch {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
}),
|
|
74
195
|
);
|
|
196
|
+
return available.filter((id): id is string => id !== null);
|
|
75
197
|
},
|
|
76
198
|
async selectProvider(context) {
|
|
77
199
|
return (await firstAvailable(orderedProviders(providers, context), context))?.id ?? null;
|
|
78
200
|
},
|
|
201
|
+
async admit({ providerId, accountId, workspaceId, attribution }) {
|
|
202
|
+
const provider = providers.find((candidate) => candidate.id === providerId);
|
|
203
|
+
if (!provider || !chargeable(provider)) return;
|
|
204
|
+
await billing.admit({ accountId, workspaceId, attribution });
|
|
205
|
+
},
|
|
79
206
|
async transcribe(request) {
|
|
80
207
|
const mimeType = normalizeMimeType(request.mimeType);
|
|
81
208
|
if (!isAcceptedMimeType(mimeType, limits.acceptedMimeTypes)) {
|
|
@@ -120,6 +247,65 @@ export function createTranscriptionService(input: {
|
|
|
120
247
|
message: "Transcription provider does not support bounded requests.",
|
|
121
248
|
});
|
|
122
249
|
}
|
|
250
|
+
if (chargeable(provider)) {
|
|
251
|
+
// Fail closed: a deployment-paid call is never sent without a price
|
|
252
|
+
// and a trusted settlement identity.
|
|
253
|
+
if (!provider.deploymentFunded?.pricing || !request.billing) {
|
|
254
|
+
throw new TranscriptionServiceError({
|
|
255
|
+
code: "unavailable",
|
|
256
|
+
message: "Transcription billing is not configured.",
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
try {
|
|
260
|
+
await billing.admit({
|
|
261
|
+
accountId: request.accountId,
|
|
262
|
+
workspaceId: request.workspaceId,
|
|
263
|
+
attribution: request.billing.attribution,
|
|
264
|
+
});
|
|
265
|
+
} catch (error) {
|
|
266
|
+
// Nothing was sent yet: a fallback-safe refusal (Opengeni credits
|
|
267
|
+
// turned off here) lets the next provider, such as a connected
|
|
268
|
+
// subscription, serve the request.
|
|
269
|
+
if (
|
|
270
|
+
error instanceof TranscriptionServiceError &&
|
|
271
|
+
error.fallbackSafe &&
|
|
272
|
+
!request.providerId &&
|
|
273
|
+
request.fallbackEnabled !== false &&
|
|
274
|
+
!request.signal?.aborted
|
|
275
|
+
) {
|
|
276
|
+
const excludedProviders = [...(request.excludedProviders ?? []), provider.id];
|
|
277
|
+
if (
|
|
278
|
+
await firstAvailable(
|
|
279
|
+
orderedProviders(providers, { ...request, excludedProviders }),
|
|
280
|
+
request,
|
|
281
|
+
)
|
|
282
|
+
) {
|
|
283
|
+
return await this.transcribe({ ...request, excludedProviders });
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
throw error;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
let audio = request.audio;
|
|
290
|
+
let providerMimeType = mimeType;
|
|
291
|
+
let billingContext: TranscriptionBillingContext | undefined = request.billing;
|
|
292
|
+
let audioSeconds = request.durationSeconds ?? 0;
|
|
293
|
+
if (chargeable(provider) && billingContext?.trustedDurationSeconds === undefined) {
|
|
294
|
+
// A deployment-paid one-shot upload is decoded by the server first, so
|
|
295
|
+
// the call always carries a duration the server measured from bytes it
|
|
296
|
+
// produced. That bills any usage shape we cannot price, and bounds
|
|
297
|
+
// what is sent upstream to the configured maximum recording length.
|
|
298
|
+
const normalized = await normalizeAudio({
|
|
299
|
+
audio,
|
|
300
|
+
mimeType,
|
|
301
|
+
maxDurationSeconds: limits.maxDurationSeconds,
|
|
302
|
+
...(request.signal ? { signal: request.signal } : {}),
|
|
303
|
+
});
|
|
304
|
+
audio = normalized.bytes;
|
|
305
|
+
providerMimeType = "audio/wav";
|
|
306
|
+
audioSeconds = normalized.durationSeconds;
|
|
307
|
+
billingContext = { ...billingContext!, trustedDurationSeconds: normalized.durationSeconds };
|
|
308
|
+
}
|
|
123
309
|
const startedAt = performance.now();
|
|
124
310
|
const remainingMilliseconds = request.providerDeadlineAt
|
|
125
311
|
? remainingTranscriptionProviderRequestMilliseconds(request.providerDeadlineAt, now())
|
|
@@ -135,12 +321,12 @@ export function createTranscriptionService(input: {
|
|
|
135
321
|
});
|
|
136
322
|
}
|
|
137
323
|
const deadline = createProviderRequestDeadline(request.signal, remainingMilliseconds);
|
|
138
|
-
let result:
|
|
324
|
+
let result: Awaited<ReturnType<TranscriptionProvider["transcribe"]>>;
|
|
139
325
|
try {
|
|
140
326
|
result = await provider.transcribe({
|
|
141
|
-
audio
|
|
142
|
-
mimeType,
|
|
143
|
-
filename: filenameForMimeType(
|
|
327
|
+
audio,
|
|
328
|
+
mimeType: providerMimeType,
|
|
329
|
+
filename: filenameForMimeType(providerMimeType),
|
|
144
330
|
workspaceId: request.workspaceId,
|
|
145
331
|
accountId: request.accountId,
|
|
146
332
|
subjectId: request.subjectId,
|
|
@@ -183,11 +369,30 @@ export function createTranscriptionService(input: {
|
|
|
183
369
|
} finally {
|
|
184
370
|
deadline.dispose();
|
|
185
371
|
}
|
|
372
|
+
const latencyMs = Math.round(performance.now() - startedAt);
|
|
373
|
+
let creditCostMicros = 0;
|
|
374
|
+
const settle = async () => {
|
|
375
|
+
if (chargeable(provider) && provider.deploymentFunded?.pricing && billingContext) {
|
|
376
|
+
creditCostMicros = await settleWithoutFailing({
|
|
377
|
+
accountId: request.accountId,
|
|
378
|
+
workspaceId: request.workspaceId,
|
|
379
|
+
providerId: provider.id,
|
|
380
|
+
model: provider.deploymentFunded.model,
|
|
381
|
+
pricing: provider.deploymentFunded.pricing,
|
|
382
|
+
usage: result.usage ?? null,
|
|
383
|
+
billing: billingContext,
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
if (!request.deferBillingSettlement) await settle();
|
|
186
388
|
return {
|
|
187
|
-
|
|
389
|
+
text: result.text,
|
|
390
|
+
languages: result.languages,
|
|
188
391
|
providerId: provider.id,
|
|
189
|
-
audioSeconds
|
|
190
|
-
latencyMs
|
|
392
|
+
audioSeconds,
|
|
393
|
+
latencyMs,
|
|
394
|
+
creditCostMicros,
|
|
395
|
+
...(request.deferBillingSettlement ? { settleBilling: settle } : {}),
|
|
191
396
|
};
|
|
192
397
|
},
|
|
193
398
|
};
|
|
@@ -272,3 +477,27 @@ async function exactAvailable(
|
|
|
272
477
|
const provider = providers.find((candidate) => candidate.id === providerId);
|
|
273
478
|
return provider && (await provider.available(context)) ? provider : null;
|
|
274
479
|
}
|
|
480
|
+
|
|
481
|
+
function settlementAttributes(settlement: {
|
|
482
|
+
accountId: string;
|
|
483
|
+
workspaceId: string;
|
|
484
|
+
providerId: string;
|
|
485
|
+
billing: TranscriptionBillingContext;
|
|
486
|
+
}): Record<string, string> {
|
|
487
|
+
const keys = voiceTranscriptionSettlementKeys({
|
|
488
|
+
workspaceId: settlement.workspaceId,
|
|
489
|
+
sourceId: settlement.billing.sourceId,
|
|
490
|
+
});
|
|
491
|
+
return {
|
|
492
|
+
accountId: settlement.accountId,
|
|
493
|
+
workspaceId: settlement.workspaceId,
|
|
494
|
+
providerId: settlement.providerId,
|
|
495
|
+
sourceId: settlement.billing.sourceId,
|
|
496
|
+
usageIdempotencyKey: keys.usageIdempotencyKey,
|
|
497
|
+
debitIdempotencyKey: keys.debitIdempotencyKey,
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
function boundedErrorMessage(error: unknown): string {
|
|
502
|
+
return (error instanceof Error ? error.message : String(error)).slice(0, 500);
|
|
503
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Duration of a PCM RIFF/WAVE buffer the server itself produced (resumable
|
|
3
|
+
* provider segments are ffmpeg-normalized WAV). Used only as the trusted
|
|
4
|
+
* billing fallback when a provider reports no usage; never applied to
|
|
5
|
+
* client-uploaded bytes. Returns null for anything that is not a well-formed
|
|
6
|
+
* WAV with a positive byte rate.
|
|
7
|
+
*/
|
|
8
|
+
export function wavDurationSeconds(bytes: Uint8Array): number | null {
|
|
9
|
+
if (bytes.byteLength < 12) return null;
|
|
10
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
11
|
+
if (ascii(bytes, 0) !== "RIFF" || ascii(bytes, 8) !== "WAVE") return null;
|
|
12
|
+
let offset = 12;
|
|
13
|
+
let byteRate: number | null = null;
|
|
14
|
+
while (offset + 8 <= bytes.byteLength) {
|
|
15
|
+
const id = ascii(bytes, offset);
|
|
16
|
+
const size = view.getUint32(offset + 4, true);
|
|
17
|
+
const body = offset + 8;
|
|
18
|
+
if (id === "fmt " && body + 12 <= bytes.byteLength) {
|
|
19
|
+
byteRate = view.getUint32(body + 8, true);
|
|
20
|
+
} else if (id === "data") {
|
|
21
|
+
if (!byteRate) return null;
|
|
22
|
+
// Streamed WAV writes a placeholder size; the actual payload is the rest.
|
|
23
|
+
const available = bytes.byteLength - body;
|
|
24
|
+
const dataBytes = size === 0 || size === 0xffffffff ? available : Math.min(size, available);
|
|
25
|
+
return dataBytes / byteRate;
|
|
26
|
+
}
|
|
27
|
+
offset = body + size + (size % 2);
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function ascii(bytes: Uint8Array, offset: number): string {
|
|
33
|
+
return String.fromCharCode(
|
|
34
|
+
bytes[offset] ?? 0,
|
|
35
|
+
bytes[offset + 1] ?? 0,
|
|
36
|
+
bytes[offset + 2] ?? 0,
|
|
37
|
+
bytes[offset + 3] ?? 0,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
deleteWorkspaceIfQuiescent,
|
|
3
|
+
nestedPostgresSqlState,
|
|
4
|
+
safeDatabaseErrorFacts,
|
|
5
|
+
} from "@opengeni/db";
|
|
2
6
|
import type { ApiRouteDeps } from "@opengeni/core";
|
|
3
7
|
import { HTTPException } from "hono/http-exception";
|
|
4
8
|
|
|
9
|
+
import { dropSiteSqlDatabases, siteSqlSitesOfWorkspace } from "./site-sql/service";
|
|
5
10
|
import { processTemporalScheduleCleanupClaims } from "./temporal-schedule-cleanup";
|
|
6
11
|
import { workspaceDeleteObserver } from "./workspace-delete-observability";
|
|
7
12
|
|
|
@@ -14,6 +19,9 @@ export async function deleteWorkspaceForRequest(
|
|
|
14
19
|
},
|
|
15
20
|
): Promise<void> {
|
|
16
21
|
const observer = workspaceDeleteObserver(deps.observability, input);
|
|
22
|
+
// Site SQL rows in Postgres cascade with the workspace; the Durable Objects
|
|
23
|
+
// holding the data do not, so note them first and drop them after.
|
|
24
|
+
const siteSqlSites = await siteSqlSitesOfWorkspace(deps, input);
|
|
17
25
|
let deleted;
|
|
18
26
|
try {
|
|
19
27
|
deleted = await deleteWorkspaceIfQuiescent(deps.db, {
|
|
@@ -28,6 +36,21 @@ export async function deleteWorkspaceForRequest(
|
|
|
28
36
|
if (state === "P0002") {
|
|
29
37
|
throw new HTTPException(404, { message: "workspace not found" });
|
|
30
38
|
}
|
|
39
|
+
if (state === "23503") {
|
|
40
|
+
// Retention and linked-record FKs are intentional deletion boundaries.
|
|
41
|
+
// The failed transaction has rolled back: do not erase history, retry
|
|
42
|
+
// the cascade, or dispatch any external schedule cleanup.
|
|
43
|
+
// Editable documents, spreadsheets, and presentations keep immutable
|
|
44
|
+
// version history that only the organization retention lifecycle may
|
|
45
|
+
// erase, so name that cause without exposing the constraint itself.
|
|
46
|
+
const constraint = safeDatabaseErrorFacts(error).constraint ?? "";
|
|
47
|
+
const retainedRecords = constraint.startsWith("editable_artifact")
|
|
48
|
+
? "the workspace's editable documents, spreadsheets, or presentations, whose version history is retained"
|
|
49
|
+
: "retained or linked records";
|
|
50
|
+
throw new HTTPException(409, {
|
|
51
|
+
message: `workspace deletion is blocked by ${retainedRecords}; keep the workspace, revoke access, and disable scheduled work instead`,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
31
54
|
throw error;
|
|
32
55
|
}
|
|
33
56
|
|
|
@@ -61,4 +84,5 @@ export async function deleteWorkspaceForRequest(
|
|
|
61
84
|
},
|
|
62
85
|
deleted.temporalScheduleCleanups,
|
|
63
86
|
);
|
|
87
|
+
await dropSiteSqlDatabases(deps, siteSqlSites, { workspaceId: input.workspaceId });
|
|
64
88
|
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { ToolGatewayCatalog, ToolGatewayIdentity } from "@opengeni/contracts";
|
|
2
|
+
import { digestCanonicalJson } from "@opengeni/tool-gateway";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Content-free memory of complete workspace tool catalogs this API process
|
|
6
|
+
* produced for one exact caller scope.
|
|
7
|
+
*
|
|
8
|
+
* A complete catalog digest covers every enabled connector, so verifying a
|
|
9
|
+
* call's `catalogDigest` used to require connecting and listing every
|
|
10
|
+
* connector again. The attestation remembers, per complete digest, only the
|
|
11
|
+
* canonical digest of each entry. A later call can then prepare just its
|
|
12
|
+
* target connector live and prove that the entry it is about to execute is
|
|
13
|
+
* byte-for-byte the entry its caller saw in that complete catalog.
|
|
14
|
+
*
|
|
15
|
+
* It never stores credentials, prepared gateways, connections, schemas,
|
|
16
|
+
* arguments, or results, and grants no authority: every call still resolves
|
|
17
|
+
* live caller, account, connection, policy, and Site authority. A miss,
|
|
18
|
+
* expiry, or entry mismatch falls back to complete preparation and the exact
|
|
19
|
+
* historical stale-catalog contract.
|
|
20
|
+
*/
|
|
21
|
+
export type WorkspaceToolGatewayCatalogAttestations = {
|
|
22
|
+
record(scope: string, catalog: Pick<ToolGatewayCatalog, "digest" | "entries">): void;
|
|
23
|
+
/** The attested entry digest, or `undefined` when the catalog is unknown or expired. */
|
|
24
|
+
entryDigest(
|
|
25
|
+
scope: string,
|
|
26
|
+
catalogDigest: string,
|
|
27
|
+
identity: ToolGatewayIdentity,
|
|
28
|
+
): string | undefined;
|
|
29
|
+
/** Entry digests currently retained (bounded by `maxEntries`). */
|
|
30
|
+
readonly retainedEntries: number;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type WorkspaceToolGatewayCatalogAttestationOptions = {
|
|
34
|
+
/** Fixed lifetime from complete preparation; use never extends it. */
|
|
35
|
+
ttlMs?: number;
|
|
36
|
+
maxScopes?: number;
|
|
37
|
+
maxCatalogsPerScope?: number;
|
|
38
|
+
/** Global bound on retained entry digests across all scopes and catalogs. */
|
|
39
|
+
maxEntries?: number;
|
|
40
|
+
now?: () => number;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const WORKSPACE_TOOL_GATEWAY_ATTESTATION_TTL_MS = 10 * 60_000;
|
|
44
|
+
const DEFAULT_MAX_SCOPES = 512;
|
|
45
|
+
const DEFAULT_MAX_CATALOGS_PER_SCOPE = 4;
|
|
46
|
+
// About 250k entries * a few hundred bytes: on the order of 100 MiB per API
|
|
47
|
+
// process in the worst case, typically far less.
|
|
48
|
+
const DEFAULT_MAX_ENTRIES = 250_000;
|
|
49
|
+
|
|
50
|
+
type AttestedCatalog = { expiresAt: number; entries: ReadonlyMap<string, string> };
|
|
51
|
+
|
|
52
|
+
export function createWorkspaceToolGatewayCatalogAttestations(
|
|
53
|
+
options: WorkspaceToolGatewayCatalogAttestationOptions = {},
|
|
54
|
+
): WorkspaceToolGatewayCatalogAttestations {
|
|
55
|
+
const ttlMs = options.ttlMs ?? WORKSPACE_TOOL_GATEWAY_ATTESTATION_TTL_MS;
|
|
56
|
+
const maxScopes = options.maxScopes ?? DEFAULT_MAX_SCOPES;
|
|
57
|
+
const maxCatalogsPerScope = options.maxCatalogsPerScope ?? DEFAULT_MAX_CATALOGS_PER_SCOPE;
|
|
58
|
+
const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
59
|
+
const now = options.now ?? Date.now;
|
|
60
|
+
// Map insertion order is the eviction order (least recently recorded first).
|
|
61
|
+
const scopes = new Map<string, Map<string, AttestedCatalog>>();
|
|
62
|
+
let retainedEntries = 0;
|
|
63
|
+
const drop = (scope: string, catalogs: Map<string, AttestedCatalog>, digest: string) => {
|
|
64
|
+
const attested = catalogs.get(digest);
|
|
65
|
+
if (!attested) return;
|
|
66
|
+
retainedEntries -= attested.entries.size;
|
|
67
|
+
catalogs.delete(digest);
|
|
68
|
+
if (catalogs.size === 0) scopes.delete(scope);
|
|
69
|
+
};
|
|
70
|
+
const dropOldest = (): boolean => {
|
|
71
|
+
const oldest = scopes.entries().next().value;
|
|
72
|
+
if (!oldest) return false;
|
|
73
|
+
drop(oldest[0], oldest[1], oldest[1].keys().next().value!);
|
|
74
|
+
return true;
|
|
75
|
+
};
|
|
76
|
+
const overBudget = (): boolean => scopes.size > maxScopes || retainedEntries > maxEntries;
|
|
77
|
+
return {
|
|
78
|
+
record(scope, catalog) {
|
|
79
|
+
const at = now();
|
|
80
|
+
for (const [candidateScope, catalogs] of [...scopes]) {
|
|
81
|
+
for (const [digest, attested] of [...catalogs]) {
|
|
82
|
+
if (attested.expiresAt <= at) drop(candidateScope, catalogs, digest);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// A catalog larger than the whole budget is simply not attested; its
|
|
86
|
+
// calls keep using complete preparation.
|
|
87
|
+
if (catalog.entries.length > maxEntries) return;
|
|
88
|
+
const entries = new Map<string, string>();
|
|
89
|
+
for (const entry of catalog.entries) {
|
|
90
|
+
entries.set(
|
|
91
|
+
workspaceToolGatewayIdentityKey(entry.identity),
|
|
92
|
+
digestWorkspaceToolGatewayCatalogEntry(entry),
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
const existing = scopes.get(scope);
|
|
96
|
+
if (existing) drop(scope, existing, catalog.digest);
|
|
97
|
+
const catalogs = scopes.get(scope) ?? new Map<string, AttestedCatalog>();
|
|
98
|
+
scopes.delete(scope);
|
|
99
|
+
catalogs.set(catalog.digest, { expiresAt: at + ttlMs, entries });
|
|
100
|
+
retainedEntries += entries.size;
|
|
101
|
+
while (catalogs.size > maxCatalogsPerScope) {
|
|
102
|
+
const oldestDigest = catalogs.keys().next().value!;
|
|
103
|
+
retainedEntries -= catalogs.get(oldestDigest)!.entries.size;
|
|
104
|
+
catalogs.delete(oldestDigest);
|
|
105
|
+
}
|
|
106
|
+
scopes.set(scope, catalogs);
|
|
107
|
+
while (overBudget()) {
|
|
108
|
+
if (!dropOldest()) break;
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
entryDigest(scope, catalogDigest, identity) {
|
|
112
|
+
const catalogs = scopes.get(scope);
|
|
113
|
+
const attested = catalogs?.get(catalogDigest);
|
|
114
|
+
if (!catalogs || !attested) return undefined;
|
|
115
|
+
if (attested.expiresAt <= now()) {
|
|
116
|
+
drop(scope, catalogs, catalogDigest);
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
return attested.entries.get(workspaceToolGatewayIdentityKey(identity));
|
|
120
|
+
},
|
|
121
|
+
get retainedEntries() {
|
|
122
|
+
return retainedEntries;
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function digestWorkspaceToolGatewayCatalogEntry(entry: unknown): string {
|
|
128
|
+
return digestCanonicalJson(entry);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function workspaceToolGatewayIdentityKey(identity: ToolGatewayIdentity): string {
|
|
132
|
+
return JSON.stringify([identity.serverId, identity.toolName]);
|
|
133
|
+
}
|
|
@@ -15,6 +15,70 @@ export type WorkspaceToolGatewayOutcome =
|
|
|
15
15
|
|
|
16
16
|
const DURATION_BUCKETS = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60];
|
|
17
17
|
|
|
18
|
+
export function recordWorkspaceToolTargetOperation(
|
|
19
|
+
observability: Observability | null | undefined,
|
|
20
|
+
input: {
|
|
21
|
+
operation: "resolve" | "invoke" | "target-approvals" | "manifest";
|
|
22
|
+
outcome: "ok" | "failed";
|
|
23
|
+
durationSeconds: number;
|
|
24
|
+
},
|
|
25
|
+
): void {
|
|
26
|
+
try {
|
|
27
|
+
const labels = { operation: input.operation, outcome: input.outcome };
|
|
28
|
+
observability?.incrementCounter({
|
|
29
|
+
name: "opengeni_tool_target_operations_total",
|
|
30
|
+
help: "Targeted workspace tool requests; never full-catalog fallback.",
|
|
31
|
+
labels,
|
|
32
|
+
});
|
|
33
|
+
observability?.observeHistogram({
|
|
34
|
+
name: "opengeni_tool_target_duration_seconds",
|
|
35
|
+
help: "Total targeted request time including metadata, provider preparation and execution.",
|
|
36
|
+
labels,
|
|
37
|
+
buckets: DURATION_BUCKETS,
|
|
38
|
+
value: Math.max(0, input.durationSeconds),
|
|
39
|
+
});
|
|
40
|
+
} catch {
|
|
41
|
+
/* Observation never changes execution. */
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Bounded preparation telemetry: how long the request spent constructing,
|
|
47
|
+
* credentialing, connecting, and listing connectors before any execution, and
|
|
48
|
+
* whether a call used target-only preparation through a catalog attestation.
|
|
49
|
+
*/
|
|
50
|
+
export function recordWorkspaceToolGatewayPreparation(
|
|
51
|
+
observability: Observability | null | undefined,
|
|
52
|
+
input: {
|
|
53
|
+
operation: "catalog" | "call";
|
|
54
|
+
scope: "complete" | "target";
|
|
55
|
+
attestation: "hit" | "miss" | "mismatch" | "bypass" | "record";
|
|
56
|
+
durationSeconds: number;
|
|
57
|
+
},
|
|
58
|
+
): void {
|
|
59
|
+
try {
|
|
60
|
+
const labels = {
|
|
61
|
+
operation: input.operation,
|
|
62
|
+
scope: input.scope,
|
|
63
|
+
attestation: input.attestation,
|
|
64
|
+
};
|
|
65
|
+
observability?.incrementCounter({
|
|
66
|
+
name: "opengeni_tool_gateway_preparations_total",
|
|
67
|
+
help: "Workspace tool gateway HTTP preparations by bounded operation, scope, and catalog attestation outcome.",
|
|
68
|
+
labels,
|
|
69
|
+
});
|
|
70
|
+
observability?.observeHistogram({
|
|
71
|
+
name: "opengeni_tool_gateway_preparation_duration_seconds",
|
|
72
|
+
help: "Workspace tool gateway HTTP preparation wall time in seconds, before execution.",
|
|
73
|
+
labels,
|
|
74
|
+
buckets: DURATION_BUCKETS,
|
|
75
|
+
value: Math.max(0, input.durationSeconds),
|
|
76
|
+
});
|
|
77
|
+
} catch {
|
|
78
|
+
// Telemetry must never change gateway execution truth.
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
18
82
|
/**
|
|
19
83
|
* Low-cardinality gateway telemetry shared by HTTP/SDK/Site and aggregate MCP
|
|
20
84
|
* adapters. Tool names, workspace/subject ids, arguments, results, credentials,
|