@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,409 @@
|
|
|
1
|
+
import { createCipheriv, createDecipheriv, createHmac, randomBytes } from "node:crypto";
|
|
2
|
+
import { canonicalPublicOrigin } from "@opengeni/config";
|
|
3
|
+
import { WebSocket as UpstreamWebSocket } from "ws";
|
|
4
|
+
import type {
|
|
5
|
+
ApiWebSocketConnection,
|
|
6
|
+
ApiWebSocketLike,
|
|
7
|
+
ApiWebSocketUpgradeServer,
|
|
8
|
+
} from "./api-websocket";
|
|
9
|
+
|
|
10
|
+
export const INTERACTION_FRAME_PROXY_PATH = "/v1/interaction/frame-proxy";
|
|
11
|
+
export const INTERACTION_FRAME_PROXY_PROTOCOL_PREFIX = "opengeni-frame-proxy.";
|
|
12
|
+
|
|
13
|
+
const TOKEN_VERSION = 1;
|
|
14
|
+
const TOKEN_IV_BYTES = 12;
|
|
15
|
+
const TOKEN_TAG_BYTES = 16;
|
|
16
|
+
const TOKEN_MAX_BYTES = 8 * 1024;
|
|
17
|
+
const TOKEN_KEY_CONTEXT = "OpenGeni interaction frame proxy v1";
|
|
18
|
+
const MAX_QUEUED_MESSAGES = 64;
|
|
19
|
+
const MAX_QUEUED_BYTES = 12 * 1024 * 1024;
|
|
20
|
+
|
|
21
|
+
type ProxyGrant = Readonly<{
|
|
22
|
+
version: 1;
|
|
23
|
+
upstreamUrl: string;
|
|
24
|
+
upstreamProtocols: readonly string[];
|
|
25
|
+
responseProtocol: string;
|
|
26
|
+
origin: string | null;
|
|
27
|
+
expiresAt: number;
|
|
28
|
+
}>;
|
|
29
|
+
|
|
30
|
+
export type InteractionFrameProxyAttachment = Readonly<{
|
|
31
|
+
url: string;
|
|
32
|
+
protocols: readonly string[];
|
|
33
|
+
}>;
|
|
34
|
+
|
|
35
|
+
/** Docker boxes cannot carry browserd's WebSocket subprotocol grant to the
|
|
36
|
+
* viewer. Unsigned OpenSandbox Channel B still uses the lifecycle proxy, so
|
|
37
|
+
* it needs the same hatch. Signed URI-mode ingress keeps native subprotocols;
|
|
38
|
+
* `openSandboxInteractionFrameProxy` is an emergency override only. */
|
|
39
|
+
export function placementUsesInteractionFrameProxy(
|
|
40
|
+
backend: string | null | undefined,
|
|
41
|
+
options?: {
|
|
42
|
+
openSandboxSignedEndpoints?: boolean;
|
|
43
|
+
openSandboxInteractionFrameProxy?: boolean;
|
|
44
|
+
},
|
|
45
|
+
): boolean {
|
|
46
|
+
if (backend === "docker") return true;
|
|
47
|
+
if (backend !== "opensandbox") return false;
|
|
48
|
+
if (typeof options?.openSandboxInteractionFrameProxy === "boolean") {
|
|
49
|
+
return options.openSandboxInteractionFrameProxy;
|
|
50
|
+
}
|
|
51
|
+
return options?.openSandboxSignedEndpoints !== true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Public origin the browser can open. TLS-terminating reverse proxies make
|
|
55
|
+
* `requestUrl` `http://127.0.0.1` / the API container; that would mint `ws://`
|
|
56
|
+
* and Chrome blocks it from an `https://` console. */
|
|
57
|
+
export function resolveInteractionFrameProxyRequestUrl(input: {
|
|
58
|
+
requestUrl: string;
|
|
59
|
+
publicBaseUrl?: string | undefined;
|
|
60
|
+
webBaseUrl?: string | undefined;
|
|
61
|
+
forwardedProto?: string | null | undefined;
|
|
62
|
+
forwardedHost?: string | null | undefined;
|
|
63
|
+
}): string {
|
|
64
|
+
const publicOrigin =
|
|
65
|
+
canonicalPublicOrigin(input.publicBaseUrl) ??
|
|
66
|
+
(input.webBaseUrl?.startsWith("https://") ? canonicalPublicOrigin(input.webBaseUrl) : null);
|
|
67
|
+
if (publicOrigin) return `${publicOrigin}/`;
|
|
68
|
+
const request = new URL(input.requestUrl);
|
|
69
|
+
const forwardedProto = firstForwardedValue(input.forwardedProto)?.toLowerCase();
|
|
70
|
+
const protocol =
|
|
71
|
+
forwardedProto === "https" ? "https:" : forwardedProto === "http" ? "http:" : request.protocol;
|
|
72
|
+
const forwardedHost = firstForwardedValue(input.forwardedHost);
|
|
73
|
+
const host = forwardedHost && isSafeForwardedHost(forwardedHost) ? forwardedHost : request.host;
|
|
74
|
+
try {
|
|
75
|
+
return new URL(`${protocol}//${host}/`).toString();
|
|
76
|
+
} catch {
|
|
77
|
+
return request.toString();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function createInteractionFrameProxyAttachment(input: {
|
|
82
|
+
requestUrl: string;
|
|
83
|
+
publicBaseUrl?: string | undefined;
|
|
84
|
+
webBaseUrl?: string | undefined;
|
|
85
|
+
forwardedProto?: string | null | undefined;
|
|
86
|
+
forwardedHost?: string | null | undefined;
|
|
87
|
+
rootSecret: string;
|
|
88
|
+
upstreamUrl: string;
|
|
89
|
+
upstreamProtocols: readonly string[];
|
|
90
|
+
origin: string | null;
|
|
91
|
+
expiresAt: string;
|
|
92
|
+
}): InteractionFrameProxyAttachment {
|
|
93
|
+
const grant = validateGrant({
|
|
94
|
+
version: TOKEN_VERSION,
|
|
95
|
+
upstreamUrl: input.upstreamUrl,
|
|
96
|
+
upstreamProtocols: input.upstreamProtocols,
|
|
97
|
+
responseProtocol: input.upstreamProtocols[0] ?? "",
|
|
98
|
+
origin: input.origin,
|
|
99
|
+
expiresAt: Date.parse(input.expiresAt),
|
|
100
|
+
});
|
|
101
|
+
const token = encryptGrant(grant, input.rootSecret);
|
|
102
|
+
const url = new URL(
|
|
103
|
+
resolveInteractionFrameProxyRequestUrl({
|
|
104
|
+
requestUrl: input.requestUrl,
|
|
105
|
+
publicBaseUrl: input.publicBaseUrl,
|
|
106
|
+
webBaseUrl: input.webBaseUrl,
|
|
107
|
+
forwardedProto: input.forwardedProto,
|
|
108
|
+
forwardedHost: input.forwardedHost,
|
|
109
|
+
}),
|
|
110
|
+
);
|
|
111
|
+
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
|
|
112
|
+
url.pathname = INTERACTION_FRAME_PROXY_PATH;
|
|
113
|
+
url.search = "";
|
|
114
|
+
url.hash = "";
|
|
115
|
+
return Object.freeze({
|
|
116
|
+
url: url.toString(),
|
|
117
|
+
protocols: Object.freeze([
|
|
118
|
+
grant.responseProtocol,
|
|
119
|
+
`${INTERACTION_FRAME_PROXY_PROTOCOL_PREFIX}${token}`,
|
|
120
|
+
]),
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export class InteractionFrameProxyTransport {
|
|
125
|
+
constructor(
|
|
126
|
+
private readonly rootSecret: string | undefined,
|
|
127
|
+
private readonly clock: () => number = Date.now,
|
|
128
|
+
) {}
|
|
129
|
+
|
|
130
|
+
handles(request: Request): boolean {
|
|
131
|
+
return new URL(request.url).pathname === INTERACTION_FRAME_PROXY_PATH;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
upgrade(request: Request, server: ApiWebSocketUpgradeServer): Response | undefined {
|
|
135
|
+
if (!this.handles(request)) return undefined;
|
|
136
|
+
if (request.method !== "GET") {
|
|
137
|
+
return new Response("Method Not Allowed", { status: 405, headers: { allow: "GET" } });
|
|
138
|
+
}
|
|
139
|
+
if (!this.rootSecret) return new Response("Service Unavailable", { status: 503 });
|
|
140
|
+
const offered = offeredProtocols(request.headers.get("sec-websocket-protocol"));
|
|
141
|
+
const proxyProtocol = offered.find((protocol) =>
|
|
142
|
+
protocol.startsWith(INTERACTION_FRAME_PROXY_PROTOCOL_PREFIX),
|
|
143
|
+
);
|
|
144
|
+
if (!proxyProtocol) return new Response("WebSocket proxy grant required", { status: 426 });
|
|
145
|
+
let grant: ProxyGrant;
|
|
146
|
+
try {
|
|
147
|
+
grant = decryptGrant(
|
|
148
|
+
proxyProtocol.slice(INTERACTION_FRAME_PROXY_PROTOCOL_PREFIX.length),
|
|
149
|
+
this.rootSecret,
|
|
150
|
+
);
|
|
151
|
+
} catch {
|
|
152
|
+
return new Response("Invalid WebSocket proxy grant", { status: 401 });
|
|
153
|
+
}
|
|
154
|
+
if (grant.expiresAt <= this.clock()) {
|
|
155
|
+
return new Response("WebSocket proxy grant expired", { status: 401 });
|
|
156
|
+
}
|
|
157
|
+
if (!offered.includes(grant.responseProtocol)) {
|
|
158
|
+
return new Response("WebSocket protocol required", { status: 426 });
|
|
159
|
+
}
|
|
160
|
+
const origin = normalizedOrigin(request.headers.get("origin"));
|
|
161
|
+
if (origin !== grant.origin) {
|
|
162
|
+
return new Response("WebSocket origin is not allowed", { status: 403 });
|
|
163
|
+
}
|
|
164
|
+
const connection = new InteractionFrameProxyConnection(grant);
|
|
165
|
+
const upgraded = server.upgrade(request, {
|
|
166
|
+
data: connection,
|
|
167
|
+
headers: { "sec-websocket-protocol": grant.responseProtocol },
|
|
168
|
+
});
|
|
169
|
+
return upgraded ? undefined : new Response("Bad Request", { status: 400 });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export class InteractionFrameProxyConnection implements ApiWebSocketConnection {
|
|
174
|
+
private socket: ApiWebSocketLike | null = null;
|
|
175
|
+
private upstream: UpstreamWebSocket | null = null;
|
|
176
|
+
private upstreamOpen = false;
|
|
177
|
+
private terminal = false;
|
|
178
|
+
private queued: Uint8Array[] = [];
|
|
179
|
+
private queuedBytes = 0;
|
|
180
|
+
|
|
181
|
+
constructor(private readonly grant: ProxyGrant) {}
|
|
182
|
+
|
|
183
|
+
attach(socket: ApiWebSocketLike): void {
|
|
184
|
+
if (this.socket || this.terminal) {
|
|
185
|
+
socket.close(4400, "invalid connection state");
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
this.socket = socket;
|
|
189
|
+
let upstream: UpstreamWebSocket;
|
|
190
|
+
try {
|
|
191
|
+
upstream = new UpstreamWebSocket(this.grant.upstreamUrl, [...this.grant.upstreamProtocols], {
|
|
192
|
+
...(this.grant.origin ? { headers: { origin: this.grant.origin } } : {}),
|
|
193
|
+
});
|
|
194
|
+
} catch {
|
|
195
|
+
this.fail(1011, "upstream unavailable");
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
this.upstream = upstream;
|
|
199
|
+
upstream.binaryType = "arraybuffer";
|
|
200
|
+
upstream.once("open", () => {
|
|
201
|
+
if (this.terminal) {
|
|
202
|
+
upstream.close(1000, "viewer closed");
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
this.upstreamOpen = true;
|
|
206
|
+
for (const message of this.queued) upstream.send(webSocketBinary(message));
|
|
207
|
+
this.queued = [];
|
|
208
|
+
this.queuedBytes = 0;
|
|
209
|
+
});
|
|
210
|
+
upstream.on("message", (data) => {
|
|
211
|
+
if (this.terminal || !this.socket) return;
|
|
212
|
+
const bytes = binaryMessage(data);
|
|
213
|
+
if (!bytes || this.socket.send(bytes, false) <= 0) {
|
|
214
|
+
this.fail(1011, "stream unavailable");
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
upstream.on("error", () => this.fail(1011, "upstream unavailable"));
|
|
218
|
+
upstream.once("close", (code, reason) => {
|
|
219
|
+
this.fail(safeCloseCode(code), boundedReason(reason.toString("utf8")));
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
receive(message: string | Uint8Array | ArrayBuffer): void {
|
|
224
|
+
if (this.terminal) return;
|
|
225
|
+
if (typeof message === "string") {
|
|
226
|
+
this.fail(4400, "binary frames required");
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const bytes =
|
|
230
|
+
message instanceof Uint8Array ? Uint8Array.from(message) : new Uint8Array(message).slice();
|
|
231
|
+
if (this.upstreamOpen && this.upstream) {
|
|
232
|
+
this.upstream.send(webSocketBinary(bytes));
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (
|
|
236
|
+
this.queued.length + 1 > MAX_QUEUED_MESSAGES ||
|
|
237
|
+
this.queuedBytes + bytes.byteLength > MAX_QUEUED_BYTES
|
|
238
|
+
) {
|
|
239
|
+
this.fail(4409, "viewer is too fast");
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
this.queued.push(bytes);
|
|
243
|
+
this.queuedBytes += bytes.byteLength;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
transportClosed(): void {
|
|
247
|
+
if (this.terminal) return;
|
|
248
|
+
this.terminal = true;
|
|
249
|
+
this.upstream?.close(1000, "viewer closed");
|
|
250
|
+
this.clear();
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
private fail(code: number, reason: string): void {
|
|
254
|
+
if (this.terminal) return;
|
|
255
|
+
this.terminal = true;
|
|
256
|
+
this.upstream?.close(code === 1000 ? 1000 : 1011, reason);
|
|
257
|
+
this.socket?.close(code, reason);
|
|
258
|
+
this.clear();
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
private clear(): void {
|
|
262
|
+
this.queued = [];
|
|
263
|
+
this.queuedBytes = 0;
|
|
264
|
+
this.socket = null;
|
|
265
|
+
this.upstream = null;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function encryptGrant(grant: ProxyGrant, rootSecret: string): string {
|
|
270
|
+
const iv = randomBytes(TOKEN_IV_BYTES);
|
|
271
|
+
const cipher = createCipheriv("aes-256-gcm", tokenKey(rootSecret), iv);
|
|
272
|
+
cipher.setAAD(Buffer.from(TOKEN_KEY_CONTEXT));
|
|
273
|
+
const ciphertext = Buffer.concat([cipher.update(JSON.stringify(grant), "utf8"), cipher.final()]);
|
|
274
|
+
const tag = cipher.getAuthTag();
|
|
275
|
+
return Buffer.concat([iv, tag, ciphertext]).toString("base64url");
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function decryptGrant(token: string, rootSecret: string): ProxyGrant {
|
|
279
|
+
const bytes = Buffer.from(token, "base64url");
|
|
280
|
+
if (
|
|
281
|
+
token.length === 0 ||
|
|
282
|
+
token.length > TOKEN_MAX_BYTES ||
|
|
283
|
+
bytes.byteLength <= TOKEN_IV_BYTES + TOKEN_TAG_BYTES
|
|
284
|
+
) {
|
|
285
|
+
throw new Error("invalid proxy grant");
|
|
286
|
+
}
|
|
287
|
+
const iv = bytes.subarray(0, TOKEN_IV_BYTES);
|
|
288
|
+
const tag = bytes.subarray(TOKEN_IV_BYTES, TOKEN_IV_BYTES + TOKEN_TAG_BYTES);
|
|
289
|
+
const ciphertext = bytes.subarray(TOKEN_IV_BYTES + TOKEN_TAG_BYTES);
|
|
290
|
+
const decipher = createDecipheriv("aes-256-gcm", tokenKey(rootSecret), iv);
|
|
291
|
+
decipher.setAAD(Buffer.from(TOKEN_KEY_CONTEXT));
|
|
292
|
+
decipher.setAuthTag(tag);
|
|
293
|
+
const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
|
|
294
|
+
return validateGrant(JSON.parse(plaintext));
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function tokenKey(rootSecret: string): Buffer {
|
|
298
|
+
if (rootSecret.length === 0) throw new Error("proxy authority is empty");
|
|
299
|
+
return createHmac("sha256", rootSecret).update(TOKEN_KEY_CONTEXT).digest();
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function validateGrant(value: unknown): ProxyGrant {
|
|
303
|
+
if (!value || typeof value !== "object") throw new Error("invalid proxy grant");
|
|
304
|
+
const grant = value as Record<string, unknown>;
|
|
305
|
+
if (grant.version !== TOKEN_VERSION) throw new Error("invalid proxy grant version");
|
|
306
|
+
const upstreamUrl = requireUpstreamUrl(grant.upstreamUrl);
|
|
307
|
+
const upstreamProtocols = requireProtocols(grant.upstreamProtocols);
|
|
308
|
+
if (
|
|
309
|
+
typeof grant.responseProtocol !== "string" ||
|
|
310
|
+
grant.responseProtocol !== upstreamProtocols[0]
|
|
311
|
+
) {
|
|
312
|
+
throw new Error("invalid proxy response protocol");
|
|
313
|
+
}
|
|
314
|
+
const origin = grant.origin === null ? null : normalizedOrigin(grant.origin);
|
|
315
|
+
if (grant.origin !== null && !origin) throw new Error("invalid proxy origin");
|
|
316
|
+
if (!Number.isSafeInteger(grant.expiresAt) || (grant.expiresAt as number) <= 0) {
|
|
317
|
+
throw new Error("invalid proxy expiry");
|
|
318
|
+
}
|
|
319
|
+
return Object.freeze({
|
|
320
|
+
version: TOKEN_VERSION,
|
|
321
|
+
upstreamUrl,
|
|
322
|
+
upstreamProtocols: Object.freeze(upstreamProtocols),
|
|
323
|
+
responseProtocol: upstreamProtocols[0]!,
|
|
324
|
+
origin,
|
|
325
|
+
expiresAt: grant.expiresAt as number,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function requireUpstreamUrl(value: unknown): string {
|
|
330
|
+
if (typeof value !== "string" || value.length === 0 || value.length > 4096) {
|
|
331
|
+
throw new Error("invalid upstream URL");
|
|
332
|
+
}
|
|
333
|
+
const url = new URL(value);
|
|
334
|
+
if (!["ws:", "wss:"].includes(url.protocol) || url.username || url.password) {
|
|
335
|
+
throw new Error("invalid upstream URL");
|
|
336
|
+
}
|
|
337
|
+
return url.toString();
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function requireProtocols(value: unknown): string[] {
|
|
341
|
+
if (!Array.isArray(value) || value.length === 0 || value.length > 4) {
|
|
342
|
+
throw new Error("invalid upstream protocols");
|
|
343
|
+
}
|
|
344
|
+
return value.map((protocol) => {
|
|
345
|
+
if (
|
|
346
|
+
typeof protocol !== "string" ||
|
|
347
|
+
protocol.length === 0 ||
|
|
348
|
+
protocol.length > 2048 ||
|
|
349
|
+
protocol.includes(",")
|
|
350
|
+
) {
|
|
351
|
+
throw new Error("invalid upstream protocol");
|
|
352
|
+
}
|
|
353
|
+
return protocol;
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function offeredProtocols(value: string | null): string[] {
|
|
358
|
+
return value
|
|
359
|
+
? value
|
|
360
|
+
.split(",")
|
|
361
|
+
.map((part) => part.trim())
|
|
362
|
+
.filter(Boolean)
|
|
363
|
+
: [];
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function normalizedOrigin(value: unknown): string | null {
|
|
367
|
+
if (typeof value !== "string" || value.length === 0 || value.length > 2048) return null;
|
|
368
|
+
try {
|
|
369
|
+
const url = new URL(value);
|
|
370
|
+
return url.pathname === "/" && !url.search && !url.hash ? url.origin : null;
|
|
371
|
+
} catch {
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function firstForwardedValue(value: string | null | undefined): string | null {
|
|
377
|
+
if (!value) return null;
|
|
378
|
+
const part = value.split(",")[0]?.trim() ?? "";
|
|
379
|
+
return part.length > 0 ? part : null;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function isSafeForwardedHost(host: string): boolean {
|
|
383
|
+
return host.length > 0 && host.length <= 253 && !/[\s/@?#\\]/.test(host);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function binaryMessage(value: unknown): Uint8Array | null {
|
|
387
|
+
if (value instanceof ArrayBuffer) return new Uint8Array(value).slice();
|
|
388
|
+
if (ArrayBuffer.isView(value)) {
|
|
389
|
+
return new Uint8Array(value.buffer, value.byteOffset, value.byteLength).slice();
|
|
390
|
+
}
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function webSocketBinary(bytes: Uint8Array): ArrayBuffer {
|
|
395
|
+
const buffer = new ArrayBuffer(bytes.byteLength);
|
|
396
|
+
new Uint8Array(buffer).set(bytes);
|
|
397
|
+
return buffer;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function safeCloseCode(code: number): number {
|
|
401
|
+
return Number.isInteger(code) && (code === 1000 || (code >= 3000 && code <= 4999)) ? code : 1011;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
function boundedReason(reason: string): string {
|
|
405
|
+
const normalized = reason.trim();
|
|
406
|
+
return normalized.length > 0 && Buffer.byteLength(normalized) <= 123
|
|
407
|
+
? normalized
|
|
408
|
+
: "upstream closed";
|
|
409
|
+
}
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
interactionOperationMetricObserver,
|
|
17
17
|
type Observability,
|
|
18
18
|
} from "@opengeni/observability";
|
|
19
|
+
import type { ComputerFrameEvidenceMismatchReason } from "@opengeni/runtime/sandbox";
|
|
19
20
|
|
|
20
21
|
type InteractionActionReceipt = BrowserActionReceipt | ComputerActionReceipt;
|
|
21
22
|
type InteractionLifecycleMutation =
|
|
@@ -32,6 +33,14 @@ const STALE_INTERACTION_ERROR_CODES = new Set([
|
|
|
32
33
|
"attempt_stale",
|
|
33
34
|
]);
|
|
34
35
|
|
|
36
|
+
const COMPUTER_FRAME_EVIDENCE_MISMATCH_REASONS = new Set<ComputerFrameEvidenceMismatchReason>([
|
|
37
|
+
"frame_session_mismatch",
|
|
38
|
+
"frame_target_mismatch",
|
|
39
|
+
"frame_controller_mismatch",
|
|
40
|
+
"frame_media_mismatch",
|
|
41
|
+
"frame_digest_mismatch",
|
|
42
|
+
]);
|
|
43
|
+
|
|
35
44
|
export function observeBrowserActionResult(
|
|
36
45
|
observability: Observability | null | undefined,
|
|
37
46
|
startedAtMs: number,
|
|
@@ -62,6 +71,27 @@ export function observeComputerActionResult(
|
|
|
62
71
|
});
|
|
63
72
|
}
|
|
64
73
|
|
|
74
|
+
export function observeComputerFrameEvidenceMismatch(
|
|
75
|
+
observability: Observability | null | undefined,
|
|
76
|
+
reason: ComputerFrameEvidenceMismatchReason,
|
|
77
|
+
): void {
|
|
78
|
+
if (!observability || !COMPUTER_FRAME_EVIDENCE_MISMATCH_REASONS.has(reason)) return;
|
|
79
|
+
try {
|
|
80
|
+
observability.incrementCounter({
|
|
81
|
+
name: "opengeni_computer_frame_evidence_mismatches_total",
|
|
82
|
+
help: "Computer frame evidence rejected at the controller-to-API boundary by bounded reason.",
|
|
83
|
+
labels: { reason },
|
|
84
|
+
});
|
|
85
|
+
} catch {
|
|
86
|
+
// Observability cannot alter the fail-closed frame boundary.
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
observability.warn("Computer frame evidence mismatch", { reason });
|
|
90
|
+
} catch {
|
|
91
|
+
// Observability cannot alter the fail-closed frame boundary.
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
65
95
|
export function observeLifecycleResult(
|
|
66
96
|
observability: Observability | null | undefined,
|
|
67
97
|
startedAtMs: number,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type ActionCatalogEntry = {
|
|
2
|
+
/** Stable name an agent calls: the SDK method ("listSessions"), else "METHOD /path". */
|
|
3
|
+
id: string;
|
|
4
|
+
method: string;
|
|
5
|
+
path: string;
|
|
6
|
+
/** Contract schema names for the JSON body and response, when known. */
|
|
7
|
+
request: string[];
|
|
8
|
+
response: string[];
|
|
9
|
+
};
|