@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,33 @@
|
|
|
1
|
+
export type ConnectedMachineComputerAccessState = {
|
|
2
|
+
hasDisplay: boolean;
|
|
3
|
+
desktopUnavailableReason: string | null;
|
|
4
|
+
allowScreenControl: boolean;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export type ConnectedMachineComputerAccessError = {
|
|
8
|
+
status: 403 | 409;
|
|
9
|
+
message: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/** Keep passive desktop viewing separate from input consent. */
|
|
13
|
+
export function connectedMachineComputerAccessError(
|
|
14
|
+
state: ConnectedMachineComputerAccessState,
|
|
15
|
+
requiresControl: boolean,
|
|
16
|
+
): ConnectedMachineComputerAccessError | null {
|
|
17
|
+
if (!state.hasDisplay) {
|
|
18
|
+
const reason = state.desktopUnavailableReason?.trim();
|
|
19
|
+
return {
|
|
20
|
+
status: 409,
|
|
21
|
+
message: reason
|
|
22
|
+
? `Connected Machine desktop is unavailable. ${reason}`
|
|
23
|
+
: "Connected Machine desktop is unavailable because this machine has no capturable display.",
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
if (requiresControl && !state.allowScreenControl) {
|
|
27
|
+
return {
|
|
28
|
+
status: 403,
|
|
29
|
+
message: "Screen control is not enabled for this Connected Machine.",
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import type { ConnectionOwnership } from "@opengeni/contracts";
|
|
2
|
+
import {
|
|
3
|
+
externalActorContinuationForAuthorization,
|
|
4
|
+
isVerifiedDelegatedHumanAuthorization,
|
|
5
|
+
type AccessGrantAuthorization,
|
|
6
|
+
} from "@opengeni/core";
|
|
7
|
+
import { HTTPException } from "hono/http-exception";
|
|
8
|
+
|
|
9
|
+
/** Signing in to a third-party provider is the person's own step in the
|
|
10
|
+
* browser; an agent acting as them through the organization MCP server is told
|
|
11
|
+
* to finish it there. */
|
|
12
|
+
export function requireProviderConsentInBrowser(access: AccessGrantAuthorization): void {
|
|
13
|
+
if (isVerifiedDelegatedHumanAuthorization(access))
|
|
14
|
+
throw new HTTPException(403, {
|
|
15
|
+
message:
|
|
16
|
+
"Signing in to a provider has to be done by the person in the Opengeni app in a browser.",
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** A verified external actor must not enter a native callback that has no
|
|
21
|
+
* corresponding key/identity reauthorization proof. Remove at an entry point
|
|
22
|
+
* only when that provider's signed continuation and commit fence are wired. */
|
|
23
|
+
export function requireLegacyOAuthActor(access: AccessGrantAuthorization): void {
|
|
24
|
+
requireProviderConsentInBrowser(access);
|
|
25
|
+
if (externalActorContinuationForAuthorization(access))
|
|
26
|
+
throw new HTTPException(422, {
|
|
27
|
+
message: "This provider does not yet support external-user OAuth continuation",
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Who may own a *personal* Connection.
|
|
33
|
+
*
|
|
34
|
+
* Connection setup defaults to a workspace-owned Connection; personal ownership
|
|
35
|
+
* is the explicit "Connect only for me" choice (AGENTS.md, "Connection
|
|
36
|
+
* ownership and executable personal authority are separate from turn
|
|
37
|
+
* initiation"). Only a managed human can own one, for two independent reasons:
|
|
38
|
+
* personal authority executes only through the immutable delegation snapshot
|
|
39
|
+
* frozen on a *human's* causal turn or scheduled task, and
|
|
40
|
+
* `bind_connection_authority` (migration 0256) can mint the `user` authority
|
|
41
|
+
* scope only for a subject holding an active organization membership. A
|
|
42
|
+
* machine-owned personal row therefore lands on the `legacy_user` compatibility
|
|
43
|
+
* lane and can never become a real organization-scoped authority.
|
|
44
|
+
*
|
|
45
|
+
* `principalKind` is the trusted, allow-listed signal: exactly `human_session`
|
|
46
|
+
* passes and every other value - including absent/unknown provenance - fails
|
|
47
|
+
* closed. The delegated-token contract forbids a `human_session` claim from
|
|
48
|
+
* carrying `serviceInitiator` or exact agent-attempt authority, so the claim
|
|
49
|
+
* cannot be combined with machine authority.
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Subject namespaces OpenGeni itself mints for machines. This is deliberately
|
|
54
|
+
* NOT an allow-list of human subjects: `docs/embedding.md` states that
|
|
55
|
+
* `subjectId` "remains opaque to OpenGeni" and that the kind must not be
|
|
56
|
+
* inferred from a subject-id prefix "because the host owns that namespace", so
|
|
57
|
+
* a trusted embedding host legitimately signs `human_session` over an opaque
|
|
58
|
+
* subject that is not `user:`-prefixed. Restricting personal ownership to
|
|
59
|
+
* `user:`/`dev` would break those hosts and would itself be the prefix-based
|
|
60
|
+
* kind inference the embedding contract forbids.
|
|
61
|
+
*
|
|
62
|
+
* The allow-list that actually decides is `principalKind === "human_session"`.
|
|
63
|
+
* This list is defence-in-depth against exactly one residual threat: a holder
|
|
64
|
+
* of the first-party delegation secret signing a human claim over an
|
|
65
|
+
* OpenGeni-minted machine subject.
|
|
66
|
+
*
|
|
67
|
+
* `connection-ownership.test.ts` asserts that every machine subject named in
|
|
68
|
+
* its list is rejected. Note what that does and does not buy: it catches a
|
|
69
|
+
* namespace being *removed* from this constant, and it documents the known
|
|
70
|
+
* machine subjects, but it is a hand-maintained list on both sides, so it
|
|
71
|
+
* cannot fail when a genuinely new machine namespace is introduced elsewhere in
|
|
72
|
+
* the repo. Adding one here is a manual step. That residual gap is acceptable
|
|
73
|
+
* only because this check is not the deciding signal anywhere: a new machine
|
|
74
|
+
* namespace still arrives with a non-`human_session` `principalKind` and is
|
|
75
|
+
* refused on that basis.
|
|
76
|
+
*
|
|
77
|
+
* It is also no longer the sole signal on any OAuth callback: a callback that
|
|
78
|
+
* persists a personal owner requires the HMAC-signed `personalOwnerVerified`
|
|
79
|
+
* state claim minted by a start path that saw the live principal.
|
|
80
|
+
*/
|
|
81
|
+
const RESERVED_MACHINE_SUBJECT_NAMESPACES = [
|
|
82
|
+
// packages/core/src/access/index.ts
|
|
83
|
+
"api_key",
|
|
84
|
+
"configured",
|
|
85
|
+
// packages/runtime/src/index.ts (signFirstPartyDelegatedBearer default)
|
|
86
|
+
"worker",
|
|
87
|
+
// packages/runtime/src/sandbox/codemode-authority.ts
|
|
88
|
+
"sandbox",
|
|
89
|
+
// apps/worker/src/activities/scheduled-tasks.ts
|
|
90
|
+
"scheduled_task",
|
|
91
|
+
// packages/db/src/session-queue-commands.ts
|
|
92
|
+
"attempt",
|
|
93
|
+
// Service principals (e.g. governed-learning activation).
|
|
94
|
+
"service",
|
|
95
|
+
] as const;
|
|
96
|
+
|
|
97
|
+
/** True only for an exact authenticated managed human. Unknown provenance fails closed. */
|
|
98
|
+
export function isPersonalConnectionOwnerPrincipal(access: AccessGrantAuthorization): boolean {
|
|
99
|
+
const { grant } = access;
|
|
100
|
+
return (
|
|
101
|
+
// Every context grant must agree on the authenticated principal and account.
|
|
102
|
+
access.contextIntegrity &&
|
|
103
|
+
access.authenticatedSubjectId === grant.subjectId &&
|
|
104
|
+
grant.principalKind === "human_session" &&
|
|
105
|
+
!grant.serviceInitiator &&
|
|
106
|
+
!grant.serviceInitiatorContext &&
|
|
107
|
+
isPersonalConnectionOwnerSubject(grant.subjectId)
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Rejects an OpenGeni-minted machine subject; see the namespace list's rationale. */
|
|
112
|
+
export function isPersonalConnectionOwnerSubject(subjectId: string): boolean {
|
|
113
|
+
const separator = subjectId.indexOf(":");
|
|
114
|
+
if (separator < 0) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
const namespace = subjectId.slice(0, separator);
|
|
118
|
+
return !RESERVED_MACHINE_SUBJECT_NAMESPACES.some((reserved) => reserved === namespace);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export const PERSONAL_CONNECTION_PRINCIPAL_MESSAGE =
|
|
122
|
+
"personal Connection ownership requires an authenticated human; API keys, configured keys, " +
|
|
123
|
+
"services, and agent attempts can create only workspace-owned Connections";
|
|
124
|
+
|
|
125
|
+
/** Personal-only connectors cannot degrade to workspace ownership, so they say so exactly. */
|
|
126
|
+
export function personalOnlyConnectionPrincipalMessage(label: string): string {
|
|
127
|
+
return (
|
|
128
|
+
`${label} connects only as a personal Connection, which requires an authenticated human; ` +
|
|
129
|
+
"API keys, configured keys, services, and agent attempts cannot own one"
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Rejects a non-human principal before a personal Connection is created.
|
|
135
|
+
* `label` names a personal-only connector, whose message must not suggest a
|
|
136
|
+
* workspace-owned alternative that its provider profile forbids.
|
|
137
|
+
*
|
|
138
|
+
* This shares that helper's core caller-integrity checks, then additionally
|
|
139
|
+
* rejects every reserved machine-subject namespace as defence-in-depth. The
|
|
140
|
+
* sibling guards a self-service authority surface where the caller claims to
|
|
141
|
+
* *be* the owner (403 "not you"), while this one rejects an ownership *value*
|
|
142
|
+
* that is unavailable to the caller (422).
|
|
143
|
+
*/
|
|
144
|
+
export function assertPersonalConnectionOwnerPrincipal(
|
|
145
|
+
access: AccessGrantAuthorization,
|
|
146
|
+
label?: string,
|
|
147
|
+
): void {
|
|
148
|
+
if (isPersonalConnectionOwnerPrincipal(access)) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
throw new HTTPException(422, {
|
|
152
|
+
message: label
|
|
153
|
+
? personalOnlyConnectionPrincipalMessage(label)
|
|
154
|
+
: PERSONAL_CONNECTION_PRINCIPAL_MESSAGE,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** The same fence expressed for a flow that resolves ownership after admission. */
|
|
159
|
+
export function assertConnectionOwnershipAllowedForPrincipal(
|
|
160
|
+
ownership: ConnectionOwnership,
|
|
161
|
+
personalOwnershipAllowed: boolean,
|
|
162
|
+
): void {
|
|
163
|
+
if (ownership === "personal" && !personalOwnershipAllowed) {
|
|
164
|
+
throw new HTTPException(422, { message: PERSONAL_CONNECTION_PRINCIPAL_MESSAGE });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* The claim a start path mints into its HMAC-signed OAuth state when it has
|
|
170
|
+
* verified the live principal may own a personal Connection.
|
|
171
|
+
*
|
|
172
|
+
* An OAuth callback carries signed state, not a live principal, so it cannot
|
|
173
|
+
* re-evaluate `principalKind`. Requiring this claim makes the callback enforce
|
|
174
|
+
* exactly what the start path decided with the full signal, instead of guessing
|
|
175
|
+
* from the subject's shape. A state minted before this claim existed simply
|
|
176
|
+
* lacks it and fails closed for personal ownership - which is precisely the
|
|
177
|
+
* in-flight rolling-deploy window these fences exist to close.
|
|
178
|
+
*/
|
|
179
|
+
export const PERSONAL_OWNER_VERIFIED_STATE_CLAIM = "personalOwnerVerified" as const;
|
|
180
|
+
|
|
181
|
+
/** True only for an explicit boolean `true` claim; absent or malformed fails closed. */
|
|
182
|
+
export function personalOwnerVerifiedInState(payload: Record<string, unknown>): boolean {
|
|
183
|
+
return payload[PERSONAL_OWNER_VERIFIED_STATE_CLAIM] === true;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Callback-side fence for every path that persists a personal owner. Requires
|
|
188
|
+
* both the signed start-time verification and a non-machine subject.
|
|
189
|
+
*/
|
|
190
|
+
export function personalOwnerStateAccepted(state: {
|
|
191
|
+
ownership: ConnectionOwnership;
|
|
192
|
+
subjectId: string;
|
|
193
|
+
personalOwnerVerified: boolean;
|
|
194
|
+
}): boolean {
|
|
195
|
+
if (state.ownership !== "personal") {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
return state.personalOwnerVerified && isPersonalConnectionOwnerSubject(state.subjectId);
|
|
199
|
+
}
|
|
@@ -1,7 +1,56 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BrowserControlRequestError,
|
|
3
3
|
BrowserControlTransportError,
|
|
4
|
+
exposedPortAllowsHostFetch,
|
|
5
|
+
exposedPortEndpointFromUrl,
|
|
6
|
+
parseOpenSandboxSignedUriPath,
|
|
7
|
+
signedEndpointNeedsRefresh,
|
|
4
8
|
} from "@opengeni/runtime/sandbox";
|
|
9
|
+
import type { InteractionPlacement } from "@opengeni/contracts";
|
|
10
|
+
import type { ChannelAOperation } from "./sandbox/channel-a";
|
|
11
|
+
|
|
12
|
+
/** Modal/Daytona/Blaxel tunnels serve browserd at `/`, so a cached
|
|
13
|
+
* controller-only session can host-fetch JSON. OpenSandbox's lifecycle proxy
|
|
14
|
+
* prefixes `/v1/sandboxes/<id>/proxy/<port>` and rewrites Authorization; JSON
|
|
15
|
+
* must stay on an exec-capable in-box curl session. OSEP-0011 signed URIs are
|
|
16
|
+
* Authorization-preserving and host-fetch like a native tunnel, but they are
|
|
17
|
+
* not durable cache keys. */
|
|
18
|
+
export function controllerCacheAllowsHostFetch(url: string): boolean {
|
|
19
|
+
try {
|
|
20
|
+
return exposedPortAllowsHostFetch(exposedPortEndpointFromUrl(url));
|
|
21
|
+
} catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function isOpenSandboxSignedControllerUrl(url: string): boolean {
|
|
27
|
+
try {
|
|
28
|
+
return parseOpenSandboxSignedUriPath(new URL(url).pathname) !== null;
|
|
29
|
+
} catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Signed Channel B URLs expire. Do not treat a lease-cached signed URI as an
|
|
35
|
+
* infinite controller endpoint. Unsigned native `/` tunnels stay cacheable. */
|
|
36
|
+
export function controllerCachedUrlIsUsable(url: string, nowMs = Date.now()): boolean {
|
|
37
|
+
if (!controllerCacheAllowsHostFetch(url)) return false;
|
|
38
|
+
if (!isOpenSandboxSignedControllerUrl(url)) return true;
|
|
39
|
+
try {
|
|
40
|
+
return !signedEndpointNeedsRefresh(new URL(url).pathname, nowMs);
|
|
41
|
+
} catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function shouldPersistControllerDataPlaneUrl(input: {
|
|
47
|
+
backend: string | null | undefined;
|
|
48
|
+
signedEndpoints: boolean;
|
|
49
|
+
url: string;
|
|
50
|
+
}): boolean {
|
|
51
|
+
if (input.backend === "opensandbox" && input.signedEndpoints) return false;
|
|
52
|
+
return controllerCachedUrlIsUsable(input.url);
|
|
53
|
+
}
|
|
5
54
|
|
|
6
55
|
/** Prefer a lease-fenced controller endpoint for the idempotent create path.
|
|
7
56
|
* Only a transport-class failure invalidates the cache and provisions once;
|
|
@@ -33,3 +82,35 @@ export function isRetryableControllerTransport(error: unknown): boolean {
|
|
|
33
82
|
(error instanceof BrowserControlRequestError && error.retryable)
|
|
34
83
|
);
|
|
35
84
|
}
|
|
85
|
+
|
|
86
|
+
/** A stopped sidecar needs provisioning on its original, fenced placement.
|
|
87
|
+
* Only reads and journaled actions may recover, once across provider retries.
|
|
88
|
+
* Revalidate controller authority before starting the sidecar. */
|
|
89
|
+
export async function withControllerTransportRecovery<T>(options: {
|
|
90
|
+
channelOperation: ChannelAOperation;
|
|
91
|
+
placementKind: InteractionPlacement["kind"];
|
|
92
|
+
recoveryState: { attempted: boolean };
|
|
93
|
+
transportAlreadyFailed: boolean;
|
|
94
|
+
use: () => Promise<T>;
|
|
95
|
+
admitRecovery: () => Promise<void>;
|
|
96
|
+
recover: () => Promise<T>;
|
|
97
|
+
}): Promise<T> {
|
|
98
|
+
if (
|
|
99
|
+
(options.channelOperation !== "browser.read" &&
|
|
100
|
+
options.channelOperation !== "browser.action") ||
|
|
101
|
+
options.placementKind !== "sandbox_group" ||
|
|
102
|
+
options.recoveryState.attempted
|
|
103
|
+
) {
|
|
104
|
+
return await options.use();
|
|
105
|
+
}
|
|
106
|
+
if (!options.transportAlreadyFailed) {
|
|
107
|
+
try {
|
|
108
|
+
return await options.use();
|
|
109
|
+
} catch (error) {
|
|
110
|
+
if (!isRetryableControllerTransport(error)) throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
options.recoveryState.attempted = true;
|
|
114
|
+
await options.admitRecovery();
|
|
115
|
+
return await options.recover();
|
|
116
|
+
}
|
|
@@ -17,6 +17,13 @@ import {
|
|
|
17
17
|
} from "@opengeni/contracts/editable-artifact-causal-frontier";
|
|
18
18
|
import { decodeEditableArtifactSerializedCommit } from "@opengeni/contracts/editable-artifact-serialized-commit";
|
|
19
19
|
import { decodeEditableArtifactMutationIntent } from "@opengeni/contracts/editable-artifacts";
|
|
20
|
+
import {
|
|
21
|
+
COMMITTED_TRANSACTION_PROTOCOL_VERSION,
|
|
22
|
+
DOCUMENT_ARTIFACT_MODEL_SCHEMA_VERSION,
|
|
23
|
+
PRESENTATION_ARTIFACT_MODEL_SCHEMA_VERSION,
|
|
24
|
+
SPREADSHEET_ARTIFACT_MODEL_SCHEMA_VERSION,
|
|
25
|
+
SPREADSHEET_COLLABORATION_SNAPSHOT_VERSION,
|
|
26
|
+
} from "@opengeni/contracts/editable-artifact-versions";
|
|
20
27
|
import {
|
|
21
28
|
MAX_EDITABLE_ARTIFACT_SNAPSHOT_BYTES,
|
|
22
29
|
causalFrontiersEqual,
|
|
@@ -39,9 +46,6 @@ import {
|
|
|
39
46
|
} from "@opengeni/core";
|
|
40
47
|
import type { BoundedObjectReadPort } from "@opengeni/storage";
|
|
41
48
|
|
|
42
|
-
const MODEL_SCHEMA_VERSION = 1;
|
|
43
|
-
const OPERATION_PROTOCOL_VERSION = 1;
|
|
44
|
-
const CRDT_STATE_VERSION = 1;
|
|
45
49
|
const SNAPSHOT_CHUNK_BYTES = 1024 * 1024;
|
|
46
50
|
|
|
47
51
|
type RuntimeFacadeModule = Readonly<{
|
|
@@ -104,7 +108,7 @@ export class NativeEditableArtifactKernelAdapter
|
|
|
104
108
|
modality: "spreadsheet" as const,
|
|
105
109
|
committedTransactionBytes,
|
|
106
110
|
kernelVersion: this.runtime.buildIdentity,
|
|
107
|
-
modelSchemaVersion:
|
|
111
|
+
modelSchemaVersion: SPREADSHEET_ARTIFACT_MODEL_SCHEMA_VERSION,
|
|
108
112
|
});
|
|
109
113
|
}
|
|
110
114
|
if (session.modality !== request.modality) {
|
|
@@ -116,7 +120,7 @@ export class NativeEditableArtifactKernelAdapter
|
|
|
116
120
|
nativeReceiptBytes,
|
|
117
121
|
resultingStateHash: editableArtifactStateHash(session.stateHash()),
|
|
118
122
|
kernelVersion: this.runtime.buildIdentity,
|
|
119
|
-
modelSchemaVersion:
|
|
123
|
+
modelSchemaVersion: modelSchemaVersionFor(request.modality),
|
|
120
124
|
});
|
|
121
125
|
} finally {
|
|
122
126
|
session.dispose();
|
|
@@ -188,7 +192,7 @@ export class NativeEditableArtifactKernelAdapter
|
|
|
188
192
|
),
|
|
189
193
|
stateHash: editableArtifactStateHash(session.stateHash()),
|
|
190
194
|
coveredHeadSequence: 0 as const,
|
|
191
|
-
modelSchemaVersion:
|
|
195
|
+
modelSchemaVersion: modelSchemaVersionFor(input.modality),
|
|
192
196
|
kernelVersion: this.runtime.buildIdentity,
|
|
193
197
|
};
|
|
194
198
|
if (session.modality === "spreadsheet") {
|
|
@@ -196,8 +200,8 @@ export class NativeEditableArtifactKernelAdapter
|
|
|
196
200
|
...common,
|
|
197
201
|
modality: "spreadsheet" as const,
|
|
198
202
|
coveredCausalFrontier: domainFrontier(session.frontier()),
|
|
199
|
-
operationProtocolVersion:
|
|
200
|
-
crdtStateVersion:
|
|
203
|
+
operationProtocolVersion: COMMITTED_TRANSACTION_PROTOCOL_VERSION,
|
|
204
|
+
crdtStateVersion: SPREADSHEET_COLLABORATION_SNAPSHOT_VERSION,
|
|
201
205
|
});
|
|
202
206
|
}
|
|
203
207
|
return Object.freeze({
|
|
@@ -239,7 +243,7 @@ export class NativeEditableArtifactKernelAdapter
|
|
|
239
243
|
),
|
|
240
244
|
stateHash: editableArtifactStateHash(session.stateHash()),
|
|
241
245
|
coveredHeadSequence: input.state.artifact.headSequence,
|
|
242
|
-
modelSchemaVersion:
|
|
246
|
+
modelSchemaVersion: modelSchemaVersionFor(input.state.modality),
|
|
243
247
|
kernelVersion: this.runtime.buildIdentity,
|
|
244
248
|
} as const;
|
|
245
249
|
if (session.modality === "spreadsheet") {
|
|
@@ -248,8 +252,8 @@ export class NativeEditableArtifactKernelAdapter
|
|
|
248
252
|
...common,
|
|
249
253
|
modality: session.modality,
|
|
250
254
|
coveredCausalFrontier: domainFrontier(session.frontier()),
|
|
251
|
-
operationProtocolVersion:
|
|
252
|
-
crdtStateVersion:
|
|
255
|
+
operationProtocolVersion: COMMITTED_TRANSACTION_PROTOCOL_VERSION,
|
|
256
|
+
crdtStateVersion: SPREADSHEET_COLLABORATION_SNAPSHOT_VERSION,
|
|
253
257
|
});
|
|
254
258
|
}
|
|
255
259
|
if (session.modality !== input.state.modality) throw new Error("Native modality mismatch");
|
|
@@ -310,12 +314,12 @@ export class NativeEditableArtifactKernelAdapter
|
|
|
310
314
|
canonicalContentHash,
|
|
311
315
|
coveredHeadSequence,
|
|
312
316
|
stateHash,
|
|
313
|
-
modelSchemaVersion:
|
|
317
|
+
modelSchemaVersion: SPREADSHEET_ARTIFACT_MODEL_SCHEMA_VERSION,
|
|
314
318
|
kernelVersion: this.runtime.buildIdentity,
|
|
315
319
|
fullCrdtStateVerified: true as const,
|
|
316
320
|
coveredCausalFrontier,
|
|
317
|
-
operationProtocolVersion:
|
|
318
|
-
crdtStateVersion:
|
|
321
|
+
operationProtocolVersion: COMMITTED_TRANSACTION_PROTOCOL_VERSION,
|
|
322
|
+
crdtStateVersion: SPREADSHEET_COLLABORATION_SNAPSHOT_VERSION,
|
|
319
323
|
...(replayedTarget ? { replayedTarget } : {}),
|
|
320
324
|
});
|
|
321
325
|
}
|
|
@@ -339,7 +343,7 @@ export class NativeEditableArtifactKernelAdapter
|
|
|
339
343
|
canonicalContentHash,
|
|
340
344
|
coveredHeadSequence,
|
|
341
345
|
stateHash,
|
|
342
|
-
modelSchemaVersion:
|
|
346
|
+
modelSchemaVersion: modelSchemaVersionFor(session.modality),
|
|
343
347
|
kernelVersion: this.runtime.buildIdentity,
|
|
344
348
|
nativeRevision,
|
|
345
349
|
...(replayedTarget ? { replayedTarget } : {}),
|
|
@@ -350,6 +354,13 @@ export class NativeEditableArtifactKernelAdapter
|
|
|
350
354
|
}
|
|
351
355
|
}
|
|
352
356
|
|
|
357
|
+
function modelSchemaVersionFor(modality: "spreadsheet" | "document" | "presentation"): 1 | 2 {
|
|
358
|
+
if (modality === "spreadsheet") return SPREADSHEET_ARTIFACT_MODEL_SCHEMA_VERSION;
|
|
359
|
+
return modality === "document"
|
|
360
|
+
? DOCUMENT_ARTIFACT_MODEL_SCHEMA_VERSION
|
|
361
|
+
: PRESENTATION_ARTIFACT_MODEL_SCHEMA_VERSION;
|
|
362
|
+
}
|
|
363
|
+
|
|
353
364
|
function assertRuntime(
|
|
354
365
|
candidate: unknown,
|
|
355
366
|
location: ConfiguredArtifactRuntimeLocation,
|
|
@@ -12,13 +12,17 @@ import {
|
|
|
12
12
|
editableArtifactReplicaId,
|
|
13
13
|
editableArtifactStateHash,
|
|
14
14
|
EditableArtifactOfficeImportError,
|
|
15
|
+
type EditableArtifactActor,
|
|
15
16
|
type EditableArtifactOfficeImportPort,
|
|
16
17
|
type EditableArtifactModality,
|
|
18
|
+
type EditableArtifactScope,
|
|
17
19
|
} from "@opengeni/core/editable-artifacts";
|
|
18
|
-
import {
|
|
20
|
+
import { requireLiveAgentAttemptAuthorization } from "@opengeni/core";
|
|
21
|
+
import { getFilesForSubject } from "@opengeni/db";
|
|
19
22
|
import {
|
|
20
23
|
MAX_BOUNDED_OBJECT_CHUNK_BYTES,
|
|
21
24
|
type BoundedImmutableObjectWritePort,
|
|
25
|
+
retryWhileMissing,
|
|
22
26
|
type ObjectStorage,
|
|
23
27
|
} from "@opengeni/storage";
|
|
24
28
|
import type { Database } from "@opengeni/db";
|
|
@@ -32,23 +36,37 @@ export type EditableArtifactOfficeImportAdapterDependencies = Readonly<{
|
|
|
32
36
|
runtime: VerifiedNativeArtifactRuntimeBinding;
|
|
33
37
|
sourceObjects: BoundedImmutableObjectWritePort;
|
|
34
38
|
snapshotObjects: BoundedImmutableObjectWritePort;
|
|
35
|
-
|
|
39
|
+
readFiles?: typeof getFilesForSubject;
|
|
40
|
+
resolveFileAuthoritySubjectId?: typeof editableArtifactFileAuthoritySubjectId;
|
|
36
41
|
prepareOffice?: typeof prepareArtifactOfficeImport;
|
|
37
42
|
}>;
|
|
38
43
|
|
|
39
44
|
/** Trusted import boundary from one ready workspace file into native sequence-zero state. */
|
|
40
45
|
export class EditableArtifactOfficeImportAdapter implements EditableArtifactOfficeImportPort {
|
|
41
|
-
private readonly
|
|
46
|
+
private readonly readFiles: typeof getFilesForSubject;
|
|
47
|
+
private readonly resolveFileAuthoritySubjectId: typeof editableArtifactFileAuthoritySubjectId;
|
|
42
48
|
|
|
43
49
|
constructor(private readonly dependencies: EditableArtifactOfficeImportAdapterDependencies) {
|
|
44
|
-
this.
|
|
50
|
+
this.readFiles = dependencies.readFiles ?? getFilesForSubject;
|
|
51
|
+
this.resolveFileAuthoritySubjectId =
|
|
52
|
+
dependencies.resolveFileAuthoritySubjectId ?? editableArtifactFileAuthoritySubjectId;
|
|
45
53
|
}
|
|
46
54
|
|
|
47
55
|
async prepare(
|
|
48
56
|
input: Parameters<EditableArtifactOfficeImportPort["prepare"]>[0],
|
|
49
57
|
): ReturnType<EditableArtifactOfficeImportPort["prepare"]> {
|
|
50
58
|
throwIfAborted(input.signal);
|
|
51
|
-
const
|
|
59
|
+
const subjectId = await this.resolveFileAuthoritySubjectId(
|
|
60
|
+
this.dependencies.db,
|
|
61
|
+
input.scope,
|
|
62
|
+
input.actor,
|
|
63
|
+
);
|
|
64
|
+
const [file] = await this.readFiles(this.dependencies.db, {
|
|
65
|
+
accountId: input.scope.accountId,
|
|
66
|
+
workspaceId: input.scope.workspaceId,
|
|
67
|
+
subjectId,
|
|
68
|
+
fileIds: [input.fileId],
|
|
69
|
+
});
|
|
52
70
|
if (!file || file.status !== "ready") {
|
|
53
71
|
throw new EditableArtifactOfficeImportError("invalid_source");
|
|
54
72
|
}
|
|
@@ -179,11 +197,23 @@ function officeFilenameMatches(filename: string, modality: EditableArtifactModal
|
|
|
179
197
|
|
|
180
198
|
async function readVerifiedWorkspaceFile(
|
|
181
199
|
storage: ObjectStorage,
|
|
182
|
-
file: NonNullable<Awaited<ReturnType<typeof
|
|
200
|
+
file: NonNullable<Awaited<ReturnType<typeof getFilesForSubject>>>[number],
|
|
183
201
|
signal?: AbortSignal,
|
|
184
202
|
): Promise<Uint8Array> {
|
|
185
203
|
throwIfAborted(signal);
|
|
186
|
-
const before = await
|
|
204
|
+
const before = await retryWhileMissing(async () => {
|
|
205
|
+
try {
|
|
206
|
+
return await storage.headFile(file);
|
|
207
|
+
} catch (error) {
|
|
208
|
+
if (typeof storage.fileExists === "function" && !(await storage.fileExists(file))) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
throw error;
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
if (!before) {
|
|
215
|
+
throw new EditableArtifactOfficeImportError("source_changed");
|
|
216
|
+
}
|
|
187
217
|
if (
|
|
188
218
|
before.ContentLength !== file.sizeBytes ||
|
|
189
219
|
before.ContentType !== file.contentType ||
|
|
@@ -198,14 +228,26 @@ async function readVerifiedWorkspaceFile(
|
|
|
198
228
|
for (let start = 0; start < file.sizeBytes; start += MAX_BOUNDED_OBJECT_CHUNK_BYTES) {
|
|
199
229
|
throwIfAborted(signal);
|
|
200
230
|
const end = Math.min(file.sizeBytes, start + MAX_BOUNDED_OBJECT_CHUNK_BYTES) - 1;
|
|
201
|
-
const chunk = await storage.getFileRange(file, { start, end });
|
|
231
|
+
const chunk = await retryWhileMissing(async () => storage.getFileRange(file, { start, end }));
|
|
202
232
|
if (!chunk || chunk.byteLength !== end - start + 1) {
|
|
203
233
|
throw new EditableArtifactOfficeImportError("source_changed");
|
|
204
234
|
}
|
|
205
235
|
bytes.set(chunk, start);
|
|
206
236
|
digest.update(chunk);
|
|
207
237
|
}
|
|
208
|
-
const after = await
|
|
238
|
+
const after = await retryWhileMissing(async () => {
|
|
239
|
+
try {
|
|
240
|
+
return await storage.headFile(file);
|
|
241
|
+
} catch (error) {
|
|
242
|
+
if (typeof storage.fileExists === "function" && !(await storage.fileExists(file))) {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
throw error;
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
if (!after) {
|
|
249
|
+
throw new EditableArtifactOfficeImportError("source_changed");
|
|
250
|
+
}
|
|
209
251
|
const sha256 = digest.digest("hex");
|
|
210
252
|
if (
|
|
211
253
|
after.ContentLength !== before.ContentLength ||
|
|
@@ -219,6 +261,32 @@ async function readVerifiedWorkspaceFile(
|
|
|
219
261
|
return bytes;
|
|
220
262
|
}
|
|
221
263
|
|
|
264
|
+
export async function editableArtifactFileAuthoritySubjectId(
|
|
265
|
+
db: Database,
|
|
266
|
+
scope: EditableArtifactScope,
|
|
267
|
+
actor: EditableArtifactActor,
|
|
268
|
+
): Promise<string | null> {
|
|
269
|
+
if (actor.kind !== "agent") return actor.subjectId;
|
|
270
|
+
const authorization = await requireLiveAgentAttemptAuthorization(
|
|
271
|
+
db,
|
|
272
|
+
{
|
|
273
|
+
accountId: scope.accountId,
|
|
274
|
+
workspaceId: scope.workspaceId,
|
|
275
|
+
subjectId: actor.subjectId,
|
|
276
|
+
permissions: [],
|
|
277
|
+
principalKind: "agent_attempt",
|
|
278
|
+
metadata: {
|
|
279
|
+
sessionId: actor.sessionId,
|
|
280
|
+
turnId: actor.turnId,
|
|
281
|
+
attemptId: actor.attemptId,
|
|
282
|
+
executionGeneration: actor.generation,
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
actor.sessionId,
|
|
286
|
+
);
|
|
287
|
+
return authorization.initiatingHumanSubjectId;
|
|
288
|
+
}
|
|
289
|
+
|
|
222
290
|
async function* byteChunks(bytes: Uint8Array): AsyncIterable<Uint8Array> {
|
|
223
291
|
for (let offset = 0; offset < bytes.byteLength; offset += MAX_BOUNDED_OBJECT_CHUNK_BYTES) {
|
|
224
292
|
yield bytes.subarray(offset, offset + MAX_BOUNDED_OBJECT_CHUNK_BYTES);
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
EditableArtifactDurableExportService,
|
|
8
8
|
EditableArtifactAgentApplication,
|
|
9
|
+
EDITABLE_ARTIFACT_EXPORT_FORMATS,
|
|
9
10
|
EDITABLE_ARTIFACT_EXPORT_MAX_DOWNLOAD_BYTES,
|
|
10
11
|
EditableArtifactCompactionPipeline,
|
|
11
12
|
EditableArtifactGenesisPipeline,
|
|
@@ -30,7 +31,6 @@ import {
|
|
|
30
31
|
type EditableArtifactMaterializationProfilePort,
|
|
31
32
|
} from "@opengeni/core/editable-artifacts";
|
|
32
33
|
import {
|
|
33
|
-
EDITABLE_ARTIFACT_LIVE_PROTOCOL_VERSION,
|
|
34
34
|
EditableArtifactApplication,
|
|
35
35
|
EditableArtifactCompatibilityError,
|
|
36
36
|
EditableArtifactLiveServer,
|
|
@@ -41,12 +41,14 @@ import {
|
|
|
41
41
|
type EditableArtifactLiveAuthorizationInvalidationPort,
|
|
42
42
|
type EditableArtifactLiveCompatibilityPort,
|
|
43
43
|
} from "@opengeni/core/editable-artifact-live";
|
|
44
|
+
import { currentEditableArtifactCompatibility } from "@opengeni/contracts/editable-artifacts";
|
|
44
45
|
import {
|
|
45
46
|
PostgresEditableArtifactLiveReadStore,
|
|
46
47
|
PostgresEditableArtifactLiveTicketStore,
|
|
47
48
|
PostgresEditableArtifactStore,
|
|
48
49
|
listEditableArtifactIdsForSession,
|
|
49
50
|
touchEditableArtifactSessionLink,
|
|
51
|
+
recordNativeDocumentInspection,
|
|
50
52
|
dbSql,
|
|
51
53
|
withRlsContext,
|
|
52
54
|
type Database,
|
|
@@ -167,6 +169,11 @@ export async function createStandaloneEditableArtifactApplication(input: {
|
|
|
167
169
|
await touchEditableArtifactSessionLink(input.db, scope, sessionId, artifactId),
|
|
168
170
|
} satisfies EditableArtifactAgentAssociationPort),
|
|
169
171
|
inspector: kernel,
|
|
172
|
+
recordInspection: async (inspection) => {
|
|
173
|
+
if (inspection.actor.kind !== "agent")
|
|
174
|
+
throw new Error("Inspection proof requires an agent attempt");
|
|
175
|
+
return recordNativeDocumentInspection(input.db, { ...inspection, actor: inspection.actor });
|
|
176
|
+
},
|
|
170
177
|
officeImports,
|
|
171
178
|
workspaceFiles: new EditableArtifactWorkspaceFileAdapter({
|
|
172
179
|
db: input.db,
|
|
@@ -194,10 +201,14 @@ export async function createStandaloneEditableArtifactApplication(input: {
|
|
|
194
201
|
assertCompatible(
|
|
195
202
|
request: Parameters<EditableArtifactLiveCompatibilityPort["assertCompatible"]>[0],
|
|
196
203
|
) {
|
|
204
|
+
const current = currentEditableArtifactCompatibility(request.artifact.modality);
|
|
197
205
|
if (
|
|
198
|
-
request.
|
|
199
|
-
request.
|
|
200
|
-
request.
|
|
206
|
+
request.modality !== request.artifact.modality ||
|
|
207
|
+
request.liveProtocolVersion !== current.liveProtocolVersion ||
|
|
208
|
+
request.modelSchemaVersion !== current.modelSchemaVersion ||
|
|
209
|
+
request.snapshotVersion !== current.snapshotVersion ||
|
|
210
|
+
request.commandProtocolVersion !== current.commandProtocolVersion ||
|
|
211
|
+
request.committedTransactionProtocolVersion !== current.committedTransactionProtocolVersion
|
|
201
212
|
) {
|
|
202
213
|
throw new EditableArtifactCompatibilityError();
|
|
203
214
|
}
|
|
@@ -334,23 +345,28 @@ class RandomEditableArtifactDurableExportIds implements EditableArtifactDurableE
|
|
|
334
345
|
function materializationProfiles(
|
|
335
346
|
capabilities: EditableArtifactNativeMaterializerCapabilities,
|
|
336
347
|
): EditableArtifactMaterializationProfilePort {
|
|
348
|
+
const spreadsheetCompatibility = currentEditableArtifactCompatibility("spreadsheet");
|
|
337
349
|
if (
|
|
338
350
|
capabilities.protocol !== "OGAMC001" ||
|
|
339
351
|
capabilities.runtimeKind !== "native" ||
|
|
340
352
|
capabilities.maxOutputBytes !== EDITABLE_ARTIFACT_EXPORT_MAX_DOWNLOAD_BYTES ||
|
|
341
353
|
capabilities.codecVersions["opengeni.xlsx"] === undefined ||
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
354
|
+
capabilities.supportedModelSchemaVersions[0] !== spreadsheetCompatibility.modelSchemaVersion ||
|
|
355
|
+
capabilities.supportedOperationProtocolVersions[0] !==
|
|
356
|
+
spreadsheetCompatibility.committedTransactionProtocolVersion ||
|
|
357
|
+
capabilities.supportedSnapshotProtocolVersions[0] !== spreadsheetCompatibility.snapshotVersion
|
|
345
358
|
) {
|
|
346
359
|
throw new Error("Verified artifact materializer profile is incompatible");
|
|
347
360
|
}
|
|
348
361
|
const codecVersion = capabilities.codecVersions["opengeni.xlsx"];
|
|
349
362
|
return Object.freeze({
|
|
363
|
+
supportedFormats: EDITABLE_ARTIFACT_EXPORT_FORMATS,
|
|
350
364
|
async resolve(input: Parameters<EditableArtifactMaterializationProfilePort["resolve"]>[0]) {
|
|
365
|
+
// EDITABLE_ARTIFACT_EXPORT_FORMATS is what agents are told exists.
|
|
351
366
|
if (
|
|
352
367
|
input.modality !== "spreadsheet" ||
|
|
353
368
|
input.format !== "xlsx" ||
|
|
369
|
+
!EDITABLE_ARTIFACT_EXPORT_FORMATS[input.modality].includes(input.format) ||
|
|
354
370
|
Object.keys(input.options).length !== 0
|
|
355
371
|
) {
|
|
356
372
|
return null;
|