@opengeni/api-router 0.30.1 → 1.0.0
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 +3 -0
- package/dist/admission-trace.d.ts +8 -0
- package/dist/api-websocket.d.ts +18 -0
- package/dist/app.d.ts +50 -2
- package/dist/app.js +12 -1
- package/dist/artifact-catalog-cursor.d.ts +27 -0
- package/dist/auth/managed-auth-attempt-context.d.ts +10 -0
- package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
- package/dist/auth/managed-auth-session-adapter.d.ts +6 -0
- package/dist/auth/managed-auth.d.ts +102 -3
- package/dist/auth/managed-email.d.ts +29 -0
- package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
- package/dist/auth/new-signups-gate.d.ts +23 -0
- package/dist/auth/organization-user-setup.d.ts +80 -0
- package/dist/auth/signup-funnel-metrics.d.ts +44 -0
- package/dist/browser-controller-authority.d.ts +1 -61
- package/dist/browser-ephemeral.d.ts +5 -0
- package/dist/browser-state-authority.d.ts +1 -27
- package/dist/chunk-6TZ5LG3O.js +123948 -0
- package/dist/chunk-6TZ5LG3O.js.map +1 -0
- package/dist/chunk-OGQDXVXY.js +18 -0
- package/dist/chunk-OGQDXVXY.js.map +1 -0
- package/dist/claude-subscription-account-conflicts.d.ts +1 -0
- package/dist/claude-subscription-account-usage.d.ts +39 -0
- package/dist/claude-subscription-oauth.d.ts +25 -0
- package/dist/claude-subscription-profile.d.ts +9 -0
- package/dist/claude-subscription-usage.d.ts +44 -0
- package/dist/claude-workspace-connection.d.ts +15 -0
- package/dist/codemode.d.ts +32 -1
- package/dist/company-brain-okf.d.ts +24 -0
- package/dist/connected-machine-computer-access.d.ts +11 -0
- package/dist/connection-ownership.d.ts +54 -0
- package/dist/controller-data-plane.d.ts +32 -0
- package/dist/editable-artifact-office-import.d.ts +7 -4
- package/dist/editable-artifact-source-session.d.ts +3 -0
- package/dist/editable-artifact-websocket.d.ts +10 -18
- package/dist/editable-artifact-workspace-files.d.ts +1 -1
- package/dist/fatal-process-boundary.d.ts +25 -0
- package/dist/github-access.d.ts +31 -2
- package/dist/http/acting-person.d.ts +24 -0
- package/dist/http/api-contract-compat.d.ts +19 -0
- package/dist/http/api-error.d.ts +27 -1
- package/dist/http/cors.d.ts +17 -0
- package/dist/http/deprecation.d.ts +42 -0
- package/dist/http/interaction-control-error.d.ts +13 -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/request-body.d.ts +27 -0
- package/dist/http/request-source.d.ts +52 -0
- package/dist/http/sse.d.ts +17 -6
- package/dist/http/unmatched-route.d.ts +18 -0
- package/dist/http/user-content.d.ts +36 -0
- package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
- package/dist/index.d.ts +10 -3
- package/dist/index.js +1129 -166
- package/dist/index.js.map +1 -1
- package/dist/integration-endpoint-test.d.ts +20 -0
- package/dist/integrations/api-integrations.d.ts +2 -2
- package/dist/integrations/atlassian.d.ts +29 -3
- package/dist/integrations/connect-authority.d.ts +1 -0
- package/dist/integrations/connect-callback-return.d.ts +6 -0
- package/dist/integrations/fiken.d.ts +16 -2
- package/dist/integrations/github-app-connect.d.ts +47 -0
- package/dist/integrations/github-installation-proof.d.ts +3 -0
- package/dist/integrations/github-lens-connect.d.ts +116 -0
- package/dist/integrations/github-skill-source.d.ts +1 -5
- package/dist/integrations/google-drive.d.ts +25 -0
- package/dist/integrations/integration-commit-authority.d.ts +13 -0
- package/dist/integrations/marketplace-plugin.d.ts +2691 -0
- package/dist/integrations/oauth-client.d.ts +178 -18
- package/dist/integrations/oauth-profiles.d.ts +222 -0
- package/dist/integrations/oauth-return-path.d.ts +1 -0
- package/dist/integrations/personal-github-repositories.d.ts +84 -0
- package/dist/integrations/personal-github.d.ts +42 -0
- package/dist/integrations/pr-review-provider.d.ts +22 -0
- package/dist/integrations/provider-oauth.d.ts +19 -1
- package/dist/integrations/slack-app-home.d.ts +24 -0
- package/dist/integrations/slack-bot.d.ts +367 -12
- package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
- package/dist/integrations/slack-install.d.ts +20 -0
- package/dist/integrations/slack-interactions.d.ts +113 -10
- package/dist/integrations/slack-mrkdwn.d.ts +41 -0
- package/dist/integrations/slack-routing.d.ts +120 -0
- package/dist/integrations/slack-session-defaults.d.ts +58 -0
- package/dist/integrations/slack-task-file-upload.d.ts +36 -0
- package/dist/integrations/social-oauth.d.ts +7 -0
- package/dist/interaction-agent-access.d.ts +15 -0
- package/dist/interaction-frame-proxy.d.ts +68 -0
- package/dist/interaction-metrics.d.ts +2 -0
- package/dist/mcp/action-catalog-types.d.ts +9 -0
- package/dist/mcp/action-catalog.gen.d.ts +2 -0
- package/dist/mcp/capability-account-readiness.d.ts +7 -0
- package/dist/mcp/child-read-evidence.d.ts +9 -0
- package/dist/mcp/command-read.d.ts +24 -0
- package/dist/mcp/company-profile-agent-admin.d.ts +44 -0
- package/dist/mcp/contract-input.d.ts +11 -0
- package/dist/mcp/documents.d.ts +7 -5
- package/dist/mcp/files.d.ts +2 -2
- package/dist/mcp/first-party-tool-permissions.d.ts +650 -0
- package/dist/mcp/knowledge-entries.d.ts +5 -0
- package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
- package/dist/mcp/receipts.d.ts +9 -0
- package/dist/mcp/request-abort.d.ts +19 -0
- package/dist/mcp/scheduled-task-input.d.ts +1189 -0
- package/dist/mcp/scheduled-task-view.d.ts +22 -4
- package/dist/mcp/server.d.ts +255 -3
- package/dist/mcp/session-event-view.d.ts +94 -0
- package/dist/mcp/session-view.d.ts +66 -2
- package/dist/mcp/session-wait.d.ts +174 -0
- package/dist/mcp-oauth.d.ts +52 -0
- package/dist/model-catalog.d.ts +11 -31
- package/dist/observability.d.ts +3 -1
- package/dist/organization-mcp.d.ts +52 -0
- package/dist/organization-recovery-notifications.d.ts +41 -0
- package/dist/routes/analytics-consent.d.ts +26 -0
- package/dist/routes/api-integrations.d.ts +25 -0
- package/dist/routes/api-keys.d.ts +17 -0
- package/dist/routes/artifact-catalog.d.ts +6 -0
- package/dist/routes/automations.d.ts +19 -0
- package/dist/routes/billing.d.ts +49 -0
- package/dist/routes/browser-sessions.d.ts +71 -3
- 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 +146 -0
- package/dist/routes/codex.d.ts +76 -2
- package/dist/routes/company-brain.d.ts +3 -0
- package/dist/routes/company-profile.d.ts +2 -1
- package/dist/routes/computer-sessions.d.ts +14 -0
- package/dist/routes/connect.d.ts +5 -0
- package/dist/routes/editable-artifacts.d.ts +2 -0
- package/dist/routes/external-identity-links.d.ts +6 -0
- package/dist/routes/feedback.d.ts +3 -0
- package/dist/routes/files.d.ts +4 -0
- package/dist/routes/github-browser-pages.d.ts +12 -0
- package/dist/routes/github.d.ts +2 -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 +30 -1
- package/dist/routes/knowledge.d.ts +3 -0
- package/dist/routes/managed-auth-session-sets.d.ts +26 -0
- package/dist/routes/managed-onboarding.d.ts +29 -0
- package/dist/routes/managed-sign-in-methods.d.ts +6 -0
- package/dist/routes/model-connection-access.d.ts +3 -0
- package/dist/routes/organization-integration-policy.d.ts +3 -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-providers.d.ts +3 -0
- package/dist/routes/organization-recovery.d.ts +19 -0
- package/dist/routes/organization-service-accounts.d.ts +3 -0
- package/dist/routes/organization-sessions.d.ts +26 -0
- package/dist/routes/personal-github-git-broker.d.ts +29 -0
- package/dist/routes/personal-github.d.ts +3 -0
- package/dist/routes/pr-review-github.d.ts +3 -0
- package/dist/routes/pr-review.d.ts +3 -0
- package/dist/routes/session-artifact-associations.d.ts +4 -0
- package/dist/routes/session-history-imports.d.ts +9 -0
- package/dist/routes/sessions.d.ts +44 -6
- package/dist/routes/skill-content.d.ts +4 -0
- package/dist/routes/skill-install-authority.d.ts +6 -0
- package/dist/routes/subscription-account-pools.d.ts +34 -0
- package/dist/routes/subscription-pool-access.d.ts +16 -0
- package/dist/routes/supergrok.d.ts +6 -1
- package/dist/routes/usage-allowances.d.ts +12 -0
- package/dist/routes/user-resource-authorities.d.ts +3 -0
- package/dist/routes/workspace-artifacts.d.ts +2 -1
- package/dist/routes/workspace-capture.d.ts +10 -2
- package/dist/routes/workspace-integrations.d.ts +35 -0
- package/dist/routes/workspace-learning.d.ts +3 -0
- package/dist/routes/workspace-model-providers.d.ts +4 -0
- package/dist/routes/workspaces.d.ts +29 -0
- package/dist/sandbox/auth-callout.d.ts +8 -0
- package/dist/sandbox/channel-a.d.ts +19 -1
- package/dist/sandbox/connection-authority.d.ts +3 -0
- package/dist/sandbox/enrollment.d.ts +9 -1
- package/dist/sandbox/machines.d.ts +5 -2
- package/dist/sandbox/metrics-ingestion.d.ts +28 -20
- package/dist/sandbox/rematerialize.d.ts +2 -0
- package/dist/sandbox/session-attach-variable-sets.d.ts +30 -0
- package/dist/sandbox/viewer.d.ts +26 -1
- package/dist/sandbox-file-artifacts.d.ts +50 -0
- package/dist/scheduled-task-deletion.d.ts +13 -0
- package/dist/session-create-observability.d.ts +5 -0
- package/dist/session-event-view-MPS2OZD3.js +292 -0
- package/dist/session-event-view-MPS2OZD3.js.map +1 -0
- package/dist/site-session-origin.d.ts +13 -0
- package/dist/site-uploads.d.ts +41 -0
- package/dist/slack-reaction-files.d.ts +1 -1
- package/dist/temporal-schedule-cleanup.d.ts +1 -0
- package/dist/temporal-schedule-sync.d.ts +26 -0
- package/dist/transcription/providers/xai-subscription.d.ts +1 -0
- package/dist/transcription/service.d.ts +2 -1
- package/dist/work-discovery-observability.d.ts +33 -0
- package/dist/workspace-artifact-content.d.ts +28 -0
- package/dist/workspace-artifact-provenance.d.ts +7 -0
- package/dist/workspace-delete-observability.d.ts +10 -0
- package/dist/workspace-deletion.d.ts +6 -0
- package/dist/workspace-state-projection.d.ts +3 -5
- package/dist/workspace-tool-gateway-observability.d.ts +17 -0
- package/dist/workspace-tool-gateway.d.ts +123 -0
- package/dist/workspace-webhook-dispatch.d.ts +26 -0
- package/package.json +23 -19
- package/src/access-grant-rls.ts +75 -0
- package/src/admission-trace.ts +14 -0
- package/src/api-websocket.ts +23 -0
- package/src/app.ts +1974 -256
- package/src/artifact-catalog-cursor.ts +60 -0
- package/src/auth/managed-auth-attempt-context.ts +70 -0
- package/src/auth/managed-auth-rate-limits.ts +252 -0
- package/src/auth/managed-auth-session-adapter.ts +222 -0
- package/src/auth/managed-auth.ts +536 -60
- package/src/auth/managed-email.ts +174 -0
- 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 +307 -0
- package/src/auth/signup-funnel-metrics.ts +164 -0
- package/src/browser-controller-authority.ts +1 -186
- package/src/browser-ephemeral.ts +39 -0
- package/src/browser-state-authority.ts +1 -236
- package/src/claude-subscription-account-conflicts.ts +12 -0
- package/src/claude-subscription-account-usage.ts +48 -0
- package/src/claude-subscription-oauth.ts +362 -0
- package/src/claude-subscription-profile.ts +73 -0
- package/src/claude-subscription-usage.ts +97 -0
- package/src/claude-workspace-connection.ts +82 -0
- package/src/codemode.ts +194 -30
- package/src/codex-realtime.ts +8 -2
- package/src/company-brain-okf.ts +340 -0
- package/src/connected-machine-computer-access.ts +33 -0
- package/src/connection-ownership.ts +199 -0
- package/src/controller-data-plane.ts +81 -0
- package/src/editable-artifact-native-kernel.ts +26 -15
- package/src/editable-artifact-office-import.ts +77 -9
- package/src/editable-artifact-production.ts +23 -7
- package/src/editable-artifact-source-session.ts +123 -0
- package/src/editable-artifact-websocket.ts +27 -21
- package/src/editable-artifact-workspace-files.ts +31 -6
- package/src/fatal-process-boundary.ts +246 -0
- package/src/gateway-realtime.ts +1 -1
- package/src/github-access.ts +147 -5
- package/src/http/acting-person.ts +71 -0
- package/src/http/api-contract-compat.ts +49 -0
- package/src/http/api-error.ts +115 -1
- package/src/http/auth.ts +48 -0
- package/src/http/cors.ts +67 -0
- package/src/http/deprecation.ts +118 -0
- package/src/http/interaction-control-error.ts +164 -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/request-body.ts +127 -0
- package/src/http/request-source.ts +178 -0
- package/src/http/sse.ts +486 -132
- package/src/http/unmatched-route.ts +60 -0
- package/src/http/user-content.ts +158 -0
- package/src/http/websocket-upgrade-dispatch.ts +29 -0
- package/src/index.ts +157 -52
- package/src/integration-endpoint-test.ts +291 -0
- package/src/integrations/api-integrations.ts +98 -11
- package/src/integrations/atlassian.ts +474 -136
- package/src/integrations/connect-authority.ts +2 -0
- package/src/integrations/connect-callback-return.ts +86 -0
- package/src/integrations/fiken.ts +354 -64
- package/src/integrations/github-app-connect.ts +435 -0
- package/src/integrations/github-installation-proof.ts +60 -0
- package/src/integrations/github-lens-connect.ts +76 -0
- package/src/integrations/github-skill-source.ts +2 -142
- package/src/integrations/google-drive.ts +820 -222
- package/src/integrations/integration-commit-authority.ts +69 -0
- package/src/integrations/marketplace-plugin.ts +48 -0
- package/src/integrations/oauth-client.ts +1356 -459
- package/src/integrations/oauth-profiles.ts +537 -0
- package/src/integrations/oauth-return-path.ts +18 -0
- package/src/integrations/personal-github-repositories.ts +674 -0
- package/src/integrations/personal-github.ts +825 -0
- package/src/integrations/pr-review-provider.ts +246 -0
- package/src/integrations/provider-oauth.ts +250 -22
- package/src/integrations/slack-app-home.ts +300 -0
- package/src/integrations/slack-bot.ts +963 -239
- package/src/integrations/slack-file-upload-flow.ts +147 -0
- package/src/integrations/slack-install.ts +83 -0
- package/src/integrations/slack-interactions.ts +3170 -474
- package/src/integrations/slack-mrkdwn.ts +193 -0
- package/src/integrations/slack-routing.ts +337 -0
- package/src/integrations/slack-session-defaults.ts +224 -0
- package/src/integrations/slack-task-file-upload.ts +323 -0
- package/src/integrations/social-oauth.ts +213 -15
- package/src/interaction-agent-access.ts +48 -0
- package/src/interaction-frame-proxy.ts +409 -0
- package/src/interaction-metrics.ts +30 -0
- package/src/mcp/action-catalog-types.ts +9 -0
- package/src/mcp/action-catalog.gen.ts +6696 -0
- package/src/mcp/capability-account-readiness.ts +17 -0
- package/src/mcp/child-read-evidence.ts +19 -0
- package/src/mcp/command-read.ts +109 -0
- package/src/mcp/company-profile-agent-admin.ts +198 -0
- package/src/mcp/contract-input.ts +141 -0
- package/src/mcp/documents.ts +65 -377
- package/src/mcp/editable-artifacts.ts +12 -6
- package/src/mcp/files.ts +80 -38
- package/src/mcp/first-party-tool-permissions.ts +305 -0
- package/src/mcp/knowledge-entries.ts +322 -0
- package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
- package/src/mcp/receipts.ts +34 -0
- package/src/mcp/request-abort.ts +44 -0
- package/src/mcp/scheduled-task-input.ts +76 -0
- package/src/mcp/scheduled-task-view.ts +44 -3
- package/src/mcp/server.ts +3030 -1267
- package/src/mcp/session-event-view.ts +383 -0
- package/src/mcp/session-view.ts +84 -3
- package/src/mcp/session-wait.ts +665 -0
- package/src/mcp-oauth.ts +1123 -0
- package/src/model-catalog.ts +91 -333
- package/src/observability.ts +15 -1
- package/src/organization-mcp.ts +397 -0
- package/src/organization-recovery-notifications.ts +103 -0
- package/src/routes/analytics-consent.ts +123 -0
- package/src/routes/api-integrations.ts +364 -74
- package/src/routes/api-keys.ts +336 -10
- package/src/routes/artifact-catalog.ts +279 -0
- package/src/routes/automations.ts +768 -0
- package/src/routes/billing.ts +461 -46
- package/src/routes/browser-sessions.ts +839 -131
- package/src/routes/canonical-human-identities.ts +90 -14
- package/src/routes/capabilities.ts +107 -6
- package/src/routes/channels.ts +20 -3
- package/src/routes/claude-subscription-accounts.ts +334 -0
- package/src/routes/claude-subscription-oauth.ts +142 -0
- package/src/routes/client-errors.ts +362 -0
- package/src/routes/codex.ts +833 -116
- package/src/routes/company-brain.ts +322 -0
- package/src/routes/company-profile.ts +65 -1
- package/src/routes/computer-sessions.ts +557 -106
- package/src/routes/connect.ts +1938 -0
- package/src/routes/connections.ts +1040 -349
- package/src/routes/documents.ts +488 -287
- package/src/routes/editable-artifacts.ts +79 -9
- package/src/routes/enrollments.ts +135 -39
- package/src/routes/environments.ts +154 -58
- package/src/routes/external-identity-links.ts +201 -0
- package/src/routes/feedback.ts +113 -0
- package/src/routes/files.ts +337 -39
- package/src/routes/github-browser-pages.ts +162 -0
- package/src/routes/github.ts +446 -144
- package/src/routes/insights-response-cache.ts +83 -0
- package/src/routes/insights-usage.ts +345 -0
- package/src/routes/insights.ts +153 -19
- package/src/routes/install.ts +133 -38
- package/src/routes/integration-facets.ts +107 -33
- package/src/routes/interaction-resources.ts +30 -3
- package/src/routes/knowledge.ts +488 -0
- package/src/routes/machines.ts +313 -15
- package/src/routes/managed-auth-session-sets.ts +1218 -0
- package/src/routes/managed-onboarding.ts +337 -0
- package/src/routes/managed-sign-in-methods.ts +433 -0
- package/src/routes/memory-slack-publications.ts +3 -2
- package/src/routes/model-connection-access.ts +208 -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 +178 -0
- package/src/routes/organization-memberships.ts +1019 -27
- package/src/routes/organization-model-providers.ts +293 -0
- package/src/routes/organization-recovery.ts +325 -0
- package/src/routes/organization-service-accounts.ts +128 -0
- package/src/routes/organization-sessions.ts +350 -0
- package/src/routes/personal-github-git-broker.ts +785 -0
- package/src/routes/personal-github.ts +370 -0
- package/src/routes/plugins.ts +251 -22
- package/src/routes/pr-review-github.ts +881 -0
- package/src/routes/pr-review.ts +622 -0
- package/src/routes/preference-registry.ts +12 -93
- package/src/routes/rigs.ts +167 -50
- package/src/routes/scheduled-tasks.ts +346 -41
- package/src/routes/session-artifact-associations.ts +87 -0
- package/src/routes/session-history-imports.ts +280 -0
- package/src/routes/sessions.ts +2306 -264
- package/src/routes/skill-content.ts +297 -0
- package/src/routes/skill-install-authority.ts +64 -0
- package/src/routes/skills.ts +62 -9
- package/src/routes/social.ts +46 -18
- package/src/routes/subscription-account-pools.ts +436 -0
- package/src/routes/subscription-pool-access.ts +126 -0
- package/src/routes/supergrok.ts +219 -303
- package/src/routes/transcription-recordings.ts +38 -3
- package/src/routes/transcriptions.ts +4 -0
- package/src/routes/usage-allowances.ts +378 -0
- package/src/routes/user-resource-authorities.ts +138 -0
- package/src/routes/video-generation.ts +14 -10
- package/src/routes/workspace-artifacts.ts +275 -69
- package/src/routes/workspace-capture.ts +21 -0
- package/src/routes/workspace-integrations.ts +576 -0
- package/src/routes/workspace-learning.ts +159 -0
- package/src/routes/workspace-model-providers.ts +148 -0
- package/src/routes/workspace-state.ts +38 -25
- package/src/routes/workspaces.ts +1004 -127
- package/src/sandbox/auth-callout.ts +96 -19
- package/src/sandbox/channel-a.ts +323 -24
- package/src/sandbox/connection-authority.ts +3 -0
- package/src/sandbox/enrollment.ts +81 -6
- package/src/sandbox/machines.ts +218 -76
- package/src/sandbox/metrics-ingestion.ts +411 -62
- package/src/sandbox/rematerialize.ts +121 -19
- package/src/sandbox/session-attach-variable-sets.ts +131 -0
- package/src/sandbox/viewer.ts +280 -25
- package/src/sandbox-file-artifacts.ts +413 -0
- package/src/scheduled-task-deletion.ts +138 -0
- package/src/session-create-observability.ts +46 -0
- package/src/session-realtime-context.ts +6 -3
- package/src/site-session-origin.ts +48 -0
- package/src/site-uploads.ts +224 -0
- package/src/slack-reaction-files.ts +16 -5
- package/src/temporal-schedule-cleanup.ts +13 -0
- package/src/temporal-schedule-sync.ts +74 -0
- package/src/transcription/providers/codex-subscription.ts +2 -0
- package/src/transcription/providers/openai.ts +1 -0
- package/src/transcription/providers/xai-subscription.ts +49 -3
- package/src/transcription/segmenter.ts +8 -2
- package/src/transcription/service.ts +43 -6
- package/src/work-discovery-observability.ts +121 -0
- package/src/workspace-artifact-content.ts +144 -0
- package/src/workspace-artifact-provenance.ts +104 -0
- package/src/workspace-delete-observability.ts +75 -0
- package/src/workspace-deletion.ts +73 -0
- package/src/workspace-state-projection.ts +18 -148
- package/src/workspace-tool-gateway-observability.ts +100 -0
- package/src/workspace-tool-gateway.ts +870 -0
- package/src/workspace-webhook-dispatch.ts +190 -0
- package/src/xai-subscription-auth.ts +9 -2
- package/dist/chunk-2PQMSRCB.js +0 -49759
- package/dist/chunk-2PQMSRCB.js.map +0 -1
- package/dist/routes/packs.d.ts +0 -3
- package/src/routes/packs.ts +0 -729
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hasPermission,
|
|
3
|
+
requireExternalContinuationAuthority,
|
|
4
|
+
requireSessionAuthorization,
|
|
5
|
+
type ApiRouteDeps,
|
|
6
|
+
type OpenEditableArtifactLiveInput,
|
|
7
|
+
} from "@opengeni/core";
|
|
8
|
+
import {
|
|
9
|
+
findActiveWorkspaceApiKeyById,
|
|
10
|
+
getSession,
|
|
11
|
+
getWorkspaceGrant,
|
|
12
|
+
hasEditableArtifactSessionLink,
|
|
13
|
+
lockExternalWorkspaceMembershipLifecycle,
|
|
14
|
+
withRlsContext,
|
|
15
|
+
} from "@opengeni/db";
|
|
16
|
+
import { withAccessGrantSessionRlsContext } from "./access-grant-rls";
|
|
17
|
+
import { sql } from "drizzle-orm";
|
|
18
|
+
|
|
19
|
+
/** Supplied by the API adapter, so mounted hosts use their canonical live port. */
|
|
20
|
+
export function editableArtifactSourceSessionAuthorizer(
|
|
21
|
+
deps: ApiRouteDeps,
|
|
22
|
+
): NonNullable<OpenEditableArtifactLiveInput["authorizeSourceSession"]> {
|
|
23
|
+
return async (ticket, permission, transaction, signal) => {
|
|
24
|
+
signal?.throwIfAborted();
|
|
25
|
+
const authority = ticket.sourceSessionAuthority;
|
|
26
|
+
if (!authority) return true;
|
|
27
|
+
const { grant } = authority;
|
|
28
|
+
const required = permission === "edit" ? "artifacts:publish" : "artifacts:read";
|
|
29
|
+
if (
|
|
30
|
+
!hasPermission(grant.permissions, required) ||
|
|
31
|
+
!hasPermission(grant.permissions, "sessions:read")
|
|
32
|
+
) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
// An external audit shape without the verified continuation is not authority.
|
|
36
|
+
if (grant.metadata?.externalActor && !authority.externalContinuation) return false;
|
|
37
|
+
try {
|
|
38
|
+
const scopedDeps = transaction ? { ...deps, db: transaction } : deps;
|
|
39
|
+
// Source-bound stores invoke us before their tenancy/aggregate locks.
|
|
40
|
+
// Match lifecycle writers' organization -> tenancy -> session prefix.
|
|
41
|
+
if (transaction) {
|
|
42
|
+
await lockExternalWorkspaceMembershipLifecycle(transaction, ticket.scope.accountId);
|
|
43
|
+
signal?.throwIfAborted();
|
|
44
|
+
// Tenancy writers acquire this fence before source session rows.
|
|
45
|
+
await transaction.execute(sql`select pg_advisory_xact_lock_shared(
|
|
46
|
+
hashtextextended(${`session-tenancy:${ticket.scope.workspaceId}`}, 0))`);
|
|
47
|
+
signal?.throwIfAborted();
|
|
48
|
+
}
|
|
49
|
+
return await withAccessGrantSessionRlsContext(scopedDeps, grant, async () => {
|
|
50
|
+
return await withRlsContext(scopedDeps.db, ticket.scope, async (tx) => {
|
|
51
|
+
if (authority.externalContinuation) {
|
|
52
|
+
await requireExternalContinuationAuthority(
|
|
53
|
+
tx,
|
|
54
|
+
authority.externalContinuation,
|
|
55
|
+
{ ...ticket.scope, subjectId: grant.subjectId },
|
|
56
|
+
["sessions:read", required],
|
|
57
|
+
);
|
|
58
|
+
signal?.throwIfAborted();
|
|
59
|
+
} else if (transaction) {
|
|
60
|
+
// The authenticated ticket grant is a ceiling, not proof that
|
|
61
|
+
// source-read permission still exists at the commit boundary.
|
|
62
|
+
const actor = ticket.actor;
|
|
63
|
+
if (
|
|
64
|
+
actor.kind === "human" ||
|
|
65
|
+
(actor.kind === "service" && actor.service === "configured_key")
|
|
66
|
+
) {
|
|
67
|
+
await tx.execute(sql`select subject_id from workspace_memberships
|
|
68
|
+
where account_id = ${ticket.scope.accountId}::uuid
|
|
69
|
+
and workspace_id = ${ticket.scope.workspaceId}::uuid
|
|
70
|
+
and subject_id = ${grant.subjectId} for share`);
|
|
71
|
+
const live = await getWorkspaceGrant(tx, grant.subjectId, ticket.scope.workspaceId);
|
|
72
|
+
if (!live || !hasPermission(live.permissions, "sessions:read")) return false;
|
|
73
|
+
} else if (actor.kind === "service" && actor.service === "api_key") {
|
|
74
|
+
await tx.execute(sql`select id from api_keys
|
|
75
|
+
where account_id = ${ticket.scope.accountId}::uuid
|
|
76
|
+
and id::text = ${grant.subjectId.slice("api_key:".length)}
|
|
77
|
+
for share`);
|
|
78
|
+
const live = await findActiveWorkspaceApiKeyById(tx, {
|
|
79
|
+
...ticket.scope,
|
|
80
|
+
apiKeyId: grant.subjectId.slice("api_key:".length),
|
|
81
|
+
});
|
|
82
|
+
if (!live || !hasPermission(live.permissions, "sessions:read")) return false;
|
|
83
|
+
} else if (actor.kind === "agent") {
|
|
84
|
+
const live = await getSession(tx, ticket.scope.workspaceId, actor.sessionId);
|
|
85
|
+
if (
|
|
86
|
+
!live ||
|
|
87
|
+
(live.firstPartyMcpPermissions !== null &&
|
|
88
|
+
!hasPermission(live.firstPartyMcpPermissions, "sessions:read"))
|
|
89
|
+
) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
signal?.throwIfAborted();
|
|
96
|
+
}
|
|
97
|
+
// Locks protect visibility and removal of the exact association
|
|
98
|
+
// until the enclosing mutation transaction commits.
|
|
99
|
+
const linked = await hasEditableArtifactSessionLink(
|
|
100
|
+
tx,
|
|
101
|
+
ticket.scope,
|
|
102
|
+
authority.sessionId,
|
|
103
|
+
ticket.artifactId,
|
|
104
|
+
{ lockForCommit: transaction !== undefined },
|
|
105
|
+
);
|
|
106
|
+
signal?.throwIfAborted();
|
|
107
|
+
if (!linked) return false;
|
|
108
|
+
await requireSessionAuthorization({ ...scopedDeps, db: tx }, grant, {
|
|
109
|
+
sessionId: authority.sessionId,
|
|
110
|
+
operation: "session.read",
|
|
111
|
+
surface: "http",
|
|
112
|
+
});
|
|
113
|
+
signal?.throwIfAborted();
|
|
114
|
+
return true;
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
} catch {
|
|
118
|
+
// Denial or an unavailable authority must stop data/writes, never fall
|
|
119
|
+
// back to artifact-only scope. The live loop closes denied readers.
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -8,32 +8,24 @@ import {
|
|
|
8
8
|
type EditableArtifactLiveServerFrame,
|
|
9
9
|
type EditableArtifactLiveSession,
|
|
10
10
|
type EditableArtifactLiveSinkPort,
|
|
11
|
+
type OpenEditableArtifactLiveInput,
|
|
11
12
|
} from "@opengeni/core";
|
|
13
|
+
import type {
|
|
14
|
+
ApiWebSocketConnection,
|
|
15
|
+
ApiWebSocketLike,
|
|
16
|
+
ApiWebSocketUpgradeServer,
|
|
17
|
+
} from "./api-websocket";
|
|
12
18
|
|
|
13
19
|
export const EDITABLE_ARTIFACT_LIVE_WEBSOCKET_PATH = "/v1/editable-artifacts/live";
|
|
14
|
-
export const EDITABLE_ARTIFACT_LIVE_WEBSOCKET_PROTOCOL = "opengeni-artifact-
|
|
20
|
+
export const EDITABLE_ARTIFACT_LIVE_WEBSOCKET_PROTOCOL = "opengeni-artifact-v2";
|
|
15
21
|
export const EDITABLE_ARTIFACT_LIVE_WEBSOCKET_MAX_MESSAGE_BYTES = 8 * 1024 * 1024 + 64 * 1024;
|
|
16
22
|
|
|
17
23
|
const MAX_QUEUED_MESSAGES = 64;
|
|
18
24
|
const MAX_QUEUED_BYTES = 12 * 1024 * 1024;
|
|
19
25
|
|
|
20
|
-
export type EditableArtifactWebSocketLike =
|
|
21
|
-
data: EditableArtifactWebSocketConnection;
|
|
22
|
-
send(data: Uint8Array, compress?: boolean): number;
|
|
23
|
-
close(code?: number, reason?: string): void;
|
|
24
|
-
readonly bufferedAmount?: number;
|
|
25
|
-
getBufferedAmount?(): number;
|
|
26
|
-
}>;
|
|
26
|
+
export type EditableArtifactWebSocketLike = ApiWebSocketLike;
|
|
27
27
|
|
|
28
|
-
export type EditableArtifactWebSocketUpgradeServer =
|
|
29
|
-
upgrade(
|
|
30
|
-
request: Request,
|
|
31
|
-
options: Readonly<{
|
|
32
|
-
data: EditableArtifactWebSocketConnection;
|
|
33
|
-
headers: HeadersInit;
|
|
34
|
-
}>,
|
|
35
|
-
): boolean;
|
|
36
|
-
}>;
|
|
28
|
+
export type EditableArtifactWebSocketUpgradeServer = ApiWebSocketUpgradeServer;
|
|
37
29
|
|
|
38
30
|
export type EditableArtifactWebSocketHandler = Readonly<{
|
|
39
31
|
open(socket: EditableArtifactWebSocketLike): void;
|
|
@@ -44,7 +36,10 @@ export type EditableArtifactWebSocketHandler = Readonly<{
|
|
|
44
36
|
export class EditableArtifactWebSocketTransport {
|
|
45
37
|
readonly websocket: EditableArtifactWebSocketHandler;
|
|
46
38
|
|
|
47
|
-
constructor(
|
|
39
|
+
constructor(
|
|
40
|
+
private readonly application: EditableArtifactApplicationPort | undefined,
|
|
41
|
+
private readonly authorizeSourceSession?: OpenEditableArtifactLiveInput["authorizeSourceSession"],
|
|
42
|
+
) {
|
|
48
43
|
this.websocket = Object.freeze({
|
|
49
44
|
open: (socket) => socket.data.attach(socket),
|
|
50
45
|
message: (socket, message) => socket.data.receive(message),
|
|
@@ -69,7 +64,10 @@ export class EditableArtifactWebSocketTransport {
|
|
|
69
64
|
if (!offeredProtocol(request.headers.get("sec-websocket-protocol"))) {
|
|
70
65
|
return new Response("WebSocket protocol required", { status: 426 });
|
|
71
66
|
}
|
|
72
|
-
const connection = new EditableArtifactWebSocketConnection(
|
|
67
|
+
const connection = new EditableArtifactWebSocketConnection(
|
|
68
|
+
this.application,
|
|
69
|
+
this.authorizeSourceSession,
|
|
70
|
+
);
|
|
73
71
|
const upgraded = server.upgrade(request, {
|
|
74
72
|
data: connection,
|
|
75
73
|
headers: {
|
|
@@ -81,7 +79,9 @@ export class EditableArtifactWebSocketTransport {
|
|
|
81
79
|
}
|
|
82
80
|
|
|
83
81
|
/** One socket, one consumed ticket, one stream epoch. */
|
|
84
|
-
export class EditableArtifactWebSocketConnection
|
|
82
|
+
export class EditableArtifactWebSocketConnection
|
|
83
|
+
implements EditableArtifactLiveSinkPort, ApiWebSocketConnection
|
|
84
|
+
{
|
|
85
85
|
private socket: EditableArtifactWebSocketLike | null = null;
|
|
86
86
|
private session: EditableArtifactLiveSession | null = null;
|
|
87
87
|
private work: Promise<void> = Promise.resolve();
|
|
@@ -89,7 +89,10 @@ export class EditableArtifactWebSocketConnection implements EditableArtifactLive
|
|
|
89
89
|
private queuedBytes = 0;
|
|
90
90
|
private terminal = false;
|
|
91
91
|
|
|
92
|
-
constructor(
|
|
92
|
+
constructor(
|
|
93
|
+
private readonly application: EditableArtifactApplicationPort,
|
|
94
|
+
private readonly authorizeSourceSession?: OpenEditableArtifactLiveInput["authorizeSourceSession"],
|
|
95
|
+
) {}
|
|
93
96
|
|
|
94
97
|
attach(socket: EditableArtifactWebSocketLike): void {
|
|
95
98
|
if (this.socket || this.terminal) {
|
|
@@ -184,6 +187,9 @@ export class EditableArtifactWebSocketConnection implements EditableArtifactLive
|
|
|
184
187
|
protocolVersion: frame.protocolVersion,
|
|
185
188
|
resume: frame.resume,
|
|
186
189
|
sink: this,
|
|
190
|
+
...(this.authorizeSourceSession
|
|
191
|
+
? { authorizeSourceSession: this.authorizeSourceSession }
|
|
192
|
+
: {}),
|
|
187
193
|
});
|
|
188
194
|
if (this.terminal) {
|
|
189
195
|
await session.close("transport_error");
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
type EditableArtifactDurableExportService,
|
|
6
6
|
} from "@opengeni/core/editable-artifacts";
|
|
7
7
|
import { completeFileUpload, prepareGeneratedWorkspaceFile, type Database } from "@opengeni/db";
|
|
8
|
-
import type
|
|
8
|
+
import { retryWhileMissing, type ObjectHead, type ObjectStorage } from "@opengeni/storage";
|
|
9
9
|
|
|
10
10
|
const UPLOAD_INTENT_TTL_MS = 60 * 60_000;
|
|
11
11
|
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u;
|
|
@@ -81,7 +81,7 @@ export class EditableArtifactWorkspaceFileAdapter implements EditableArtifactAge
|
|
|
81
81
|
if (existing) {
|
|
82
82
|
assertStoredExport(existing, download.byteSize, download.mimeType, sha256);
|
|
83
83
|
} else {
|
|
84
|
-
await storage.putObjectStreamIfAbsent({
|
|
84
|
+
const created = await storage.putObjectStreamIfAbsent({
|
|
85
85
|
key: objectKey,
|
|
86
86
|
contentType: download.mimeType,
|
|
87
87
|
chunks: download.chunks(input.signal ? { signal: input.signal } : {}),
|
|
@@ -89,18 +89,28 @@ export class EditableArtifactWorkspaceFileAdapter implements EditableArtifactAge
|
|
|
89
89
|
sha256,
|
|
90
90
|
...(input.signal ? { signal: input.signal } : {}),
|
|
91
91
|
});
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
if (!created) {
|
|
93
|
+
await assertVisibleExport(
|
|
94
|
+
storage,
|
|
95
|
+
objectKey,
|
|
96
|
+
download.byteSize,
|
|
97
|
+
download.mimeType,
|
|
98
|
+
sha256,
|
|
99
|
+
input.signal,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
94
102
|
}
|
|
95
103
|
await download.assertUnchanged(input.signal);
|
|
96
104
|
throwIfAborted(input.signal);
|
|
97
105
|
file = await this.completeFile(this.dependencies.db, input.scope.workspaceId, uploadId);
|
|
98
106
|
} else {
|
|
99
|
-
|
|
100
|
-
|
|
107
|
+
await assertVisibleExport(
|
|
108
|
+
storage,
|
|
109
|
+
objectKey,
|
|
101
110
|
download.byteSize,
|
|
102
111
|
download.mimeType,
|
|
103
112
|
sha256,
|
|
113
|
+
input.signal,
|
|
104
114
|
);
|
|
105
115
|
await download.assertUnchanged(input.signal);
|
|
106
116
|
}
|
|
@@ -133,6 +143,21 @@ export class EditableArtifactWorkspaceFileAdapter implements EditableArtifactAge
|
|
|
133
143
|
}
|
|
134
144
|
}
|
|
135
145
|
|
|
146
|
+
async function assertVisibleExport(
|
|
147
|
+
storage: ObjectStorage,
|
|
148
|
+
objectKey: string,
|
|
149
|
+
byteSize: number,
|
|
150
|
+
contentType: string,
|
|
151
|
+
sha256: string,
|
|
152
|
+
signal?: AbortSignal,
|
|
153
|
+
): Promise<void> {
|
|
154
|
+
const head = await retryWhileMissing(
|
|
155
|
+
async () => await storage.headObject!(objectKey),
|
|
156
|
+
signal ? { signal } : {},
|
|
157
|
+
);
|
|
158
|
+
assertStoredExport(head, byteSize, contentType, sha256);
|
|
159
|
+
}
|
|
160
|
+
|
|
136
161
|
function assertStoredExport(
|
|
137
162
|
head: ObjectHead | null,
|
|
138
163
|
byteSize: number,
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import type { Attributes, Observability, Span } from "@opengeni/observability";
|
|
3
|
+
|
|
4
|
+
export type ApiFatalEvent = "startup_failure" | "unhandled_rejection" | "uncaught_exception";
|
|
5
|
+
export type ApiFatalPhase = "startup" | "running";
|
|
6
|
+
export type ApiFatalReasonKind =
|
|
7
|
+
| "bigint"
|
|
8
|
+
| "boolean"
|
|
9
|
+
| "error"
|
|
10
|
+
| "function"
|
|
11
|
+
| "null"
|
|
12
|
+
| "number"
|
|
13
|
+
| "object"
|
|
14
|
+
| "string"
|
|
15
|
+
| "symbol"
|
|
16
|
+
| "undefined";
|
|
17
|
+
|
|
18
|
+
type ApiFatalObservability = Pick<Observability, "error" | "flush" | "startSpan"> &
|
|
19
|
+
Partial<Pick<Observability, "recordFailureDiagnostic">>;
|
|
20
|
+
|
|
21
|
+
type ApiFatalProcess = {
|
|
22
|
+
on: (
|
|
23
|
+
event: "unhandledRejection" | "uncaughtException",
|
|
24
|
+
listener: (reason: unknown) => void,
|
|
25
|
+
) => void;
|
|
26
|
+
off: (
|
|
27
|
+
event: "unhandledRejection" | "uncaughtException",
|
|
28
|
+
listener: (reason: unknown) => void,
|
|
29
|
+
) => void;
|
|
30
|
+
exit: (code: number) => void;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type ApiFatalProcessBoundaryOptions = {
|
|
34
|
+
process?: ApiFatalProcess;
|
|
35
|
+
observability?: ApiFatalObservability;
|
|
36
|
+
flushTimeoutMs?: number;
|
|
37
|
+
correlationId?: () => string;
|
|
38
|
+
fallbackLog?: (message: string) => void;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type ApiFatalProcessBoundary = {
|
|
42
|
+
attachObservability: (observability: ApiFatalObservability) => void;
|
|
43
|
+
markRunning: () => void;
|
|
44
|
+
reportStartupFailure: (reason: unknown) => Promise<void>;
|
|
45
|
+
dispose: () => void;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const API_FATAL_FLUSH_TIMEOUT_MS = 1_000;
|
|
49
|
+
const API_FATAL_CORRELATION_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
50
|
+
|
|
51
|
+
const FATAL_ERROR_CODES = {
|
|
52
|
+
startup_failure: "api_startup_failed",
|
|
53
|
+
unhandled_rejection: "api_unhandled_rejection",
|
|
54
|
+
uncaught_exception: "api_uncaught_exception",
|
|
55
|
+
} as const;
|
|
56
|
+
|
|
57
|
+
export function installApiFatalProcessBoundary(
|
|
58
|
+
options: ApiFatalProcessBoundaryOptions = {},
|
|
59
|
+
): ApiFatalProcessBoundary {
|
|
60
|
+
const runtimeProcess = options.process ?? defaultProcessBoundary();
|
|
61
|
+
const flushTimeoutMs = options.flushTimeoutMs ?? API_FATAL_FLUSH_TIMEOUT_MS;
|
|
62
|
+
const correlationId = options.correlationId ?? (() => `api-fatal.${randomUUID()}`);
|
|
63
|
+
const fallbackLog = options.fallbackLog ?? ((message: string) => console.error(message));
|
|
64
|
+
let observability = options.observability;
|
|
65
|
+
let phase: ApiFatalPhase = "startup";
|
|
66
|
+
let reporting = false;
|
|
67
|
+
|
|
68
|
+
const report = async (event: ApiFatalEvent, reason: unknown): Promise<void> => {
|
|
69
|
+
if (reporting) return;
|
|
70
|
+
reporting = true;
|
|
71
|
+
|
|
72
|
+
const diagnostic = apiFatalDiagnostic(event, phase, reason, correlationId);
|
|
73
|
+
let message = apiFatalMessage(diagnostic);
|
|
74
|
+
const activeObservability = observability;
|
|
75
|
+
try {
|
|
76
|
+
if (activeObservability) {
|
|
77
|
+
try {
|
|
78
|
+
const diagnosticId = activeObservability.recordFailureDiagnostic?.({
|
|
79
|
+
code: FATAL_ERROR_CODES[event],
|
|
80
|
+
stage: phase,
|
|
81
|
+
retryDecision: "not_retryable",
|
|
82
|
+
error: reason,
|
|
83
|
+
});
|
|
84
|
+
if (diagnosticId) {
|
|
85
|
+
diagnostic.correlationId = diagnosticId;
|
|
86
|
+
message = apiFatalMessage(diagnostic);
|
|
87
|
+
}
|
|
88
|
+
} catch {
|
|
89
|
+
// Never replace the required fatal exit with an observer failure.
|
|
90
|
+
}
|
|
91
|
+
let logged = false;
|
|
92
|
+
try {
|
|
93
|
+
activeObservability.error(message, diagnostic);
|
|
94
|
+
logged = true;
|
|
95
|
+
} catch {
|
|
96
|
+
// The fatal boundary must still report and terminate if logging is unhealthy.
|
|
97
|
+
}
|
|
98
|
+
if (!logged) {
|
|
99
|
+
safeFallbackLog(fallbackLog, message);
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
const span: Span = activeObservability.startSpan("api.process.fatal", diagnostic);
|
|
103
|
+
span.end({ error: true });
|
|
104
|
+
} catch {
|
|
105
|
+
// The synchronous log remains authoritative when span creation fails.
|
|
106
|
+
}
|
|
107
|
+
await flushWithin(activeObservability, flushTimeoutMs);
|
|
108
|
+
} else {
|
|
109
|
+
safeFallbackLog(fallbackLog, message);
|
|
110
|
+
}
|
|
111
|
+
} finally {
|
|
112
|
+
runtimeProcess.exit(1);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const onUnhandledRejection = (reason: unknown): void => {
|
|
117
|
+
void report("unhandled_rejection", reason);
|
|
118
|
+
};
|
|
119
|
+
const onUncaughtException = (reason: unknown): void => {
|
|
120
|
+
void report("uncaught_exception", reason);
|
|
121
|
+
};
|
|
122
|
+
runtimeProcess.on("unhandledRejection", onUnhandledRejection);
|
|
123
|
+
runtimeProcess.on("uncaughtException", onUncaughtException);
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
attachObservability: (value) => {
|
|
127
|
+
observability = value;
|
|
128
|
+
},
|
|
129
|
+
markRunning: () => {
|
|
130
|
+
phase = "running";
|
|
131
|
+
},
|
|
132
|
+
reportStartupFailure: async (reason) => {
|
|
133
|
+
await report("startup_failure", reason);
|
|
134
|
+
},
|
|
135
|
+
dispose: () => {
|
|
136
|
+
runtimeProcess.off("unhandledRejection", onUnhandledRejection);
|
|
137
|
+
runtimeProcess.off("uncaughtException", onUncaughtException);
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function apiFatalDiagnostic(
|
|
143
|
+
event: ApiFatalEvent,
|
|
144
|
+
phase: ApiFatalPhase,
|
|
145
|
+
reason: unknown,
|
|
146
|
+
correlationId: () => string,
|
|
147
|
+
): Attributes & {
|
|
148
|
+
errorClass: "ApiFatalOperationError";
|
|
149
|
+
errorCode: (typeof FATAL_ERROR_CODES)[ApiFatalEvent];
|
|
150
|
+
origin: "api";
|
|
151
|
+
phase: ApiFatalPhase;
|
|
152
|
+
reasonKind: ApiFatalReasonKind;
|
|
153
|
+
correlationId: string;
|
|
154
|
+
} {
|
|
155
|
+
let safeCorrelationId = "api-fatal.fallback";
|
|
156
|
+
try {
|
|
157
|
+
const candidate = correlationId();
|
|
158
|
+
if (API_FATAL_CORRELATION_ID_PATTERN.test(candidate)) {
|
|
159
|
+
safeCorrelationId = candidate;
|
|
160
|
+
}
|
|
161
|
+
} catch {
|
|
162
|
+
// A fixed valid fallback preserves the fatal report and nonzero exit.
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
errorClass: "ApiFatalOperationError",
|
|
166
|
+
errorCode: FATAL_ERROR_CODES[event],
|
|
167
|
+
origin: "api",
|
|
168
|
+
phase,
|
|
169
|
+
reasonKind: apiFatalReasonKind(reason),
|
|
170
|
+
correlationId: safeCorrelationId,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function apiFatalReasonKind(reason: unknown): ApiFatalReasonKind {
|
|
175
|
+
if (reason === null) return "null";
|
|
176
|
+
const kind = typeof reason;
|
|
177
|
+
if (kind !== "object") return kind;
|
|
178
|
+
try {
|
|
179
|
+
return reason instanceof Error ? "error" : "object";
|
|
180
|
+
} catch {
|
|
181
|
+
return "object";
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function apiFatalMessage(diagnostic: ReturnType<typeof apiFatalDiagnostic>): string {
|
|
186
|
+
return (
|
|
187
|
+
`OpenGeni API fatal process failure (${diagnostic.errorCode}; ` +
|
|
188
|
+
`phase=${diagnostic.phase}; reason_kind=${diagnostic.reasonKind}; ` +
|
|
189
|
+
`correlation_id=${diagnostic.correlationId})`
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
async function flushWithin(
|
|
194
|
+
observability: Pick<Observability, "flush">,
|
|
195
|
+
timeoutMs: number,
|
|
196
|
+
): Promise<void> {
|
|
197
|
+
let flush: Promise<void>;
|
|
198
|
+
try {
|
|
199
|
+
flush = Promise.resolve(observability.flush()).catch(() => undefined);
|
|
200
|
+
} catch {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) return;
|
|
204
|
+
|
|
205
|
+
let timeout: ReturnType<typeof setTimeout> | undefined;
|
|
206
|
+
try {
|
|
207
|
+
await Promise.race([
|
|
208
|
+
flush,
|
|
209
|
+
new Promise<void>((resolve) => {
|
|
210
|
+
timeout = setTimeout(resolve, timeoutMs);
|
|
211
|
+
}),
|
|
212
|
+
]);
|
|
213
|
+
} finally {
|
|
214
|
+
if (timeout !== undefined) clearTimeout(timeout);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function safeFallbackLog(fallbackLog: (message: string) => void, message: string): void {
|
|
219
|
+
try {
|
|
220
|
+
fallbackLog(message);
|
|
221
|
+
} catch {
|
|
222
|
+
// Process termination remains mandatory even when every diagnostic sink fails.
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function defaultProcessBoundary(): ApiFatalProcess {
|
|
227
|
+
return {
|
|
228
|
+
on: (event, listener) => {
|
|
229
|
+
if (event === "unhandledRejection") {
|
|
230
|
+
process.on("unhandledRejection", listener);
|
|
231
|
+
} else {
|
|
232
|
+
process.on("uncaughtException", listener);
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
off: (event, listener) => {
|
|
236
|
+
if (event === "unhandledRejection") {
|
|
237
|
+
process.off("unhandledRejection", listener);
|
|
238
|
+
} else {
|
|
239
|
+
process.off("uncaughtException", listener);
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
exit: (code) => {
|
|
243
|
+
process.exit(code);
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
}
|
package/src/gateway-realtime.ts
CHANGED
|
@@ -62,7 +62,7 @@ export async function createGatewayRealtimeConnectionSecret(input: {
|
|
|
62
62
|
throw new GatewayRealtimeBrokerError(
|
|
63
63
|
"credential_unavailable",
|
|
64
64
|
resolved.source === "managed"
|
|
65
|
-
? "
|
|
65
|
+
? "Opengeni Gateway voice is not configured"
|
|
66
66
|
: "The workspace AI Gateway connection is unavailable",
|
|
67
67
|
);
|
|
68
68
|
}
|