@opengeni/api-router 3.0.1 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-grant-rls.d.ts +8 -1
- package/dist/admission-trace.d.ts +8 -0
- package/dist/app.d.ts +50 -3
- package/dist/app.js +10 -1
- package/dist/artifact-catalog-cursor.d.ts +1 -0
- package/dist/attached-browser-viewer.d.ts +11 -0
- package/dist/auth/managed-auth-attempt-context.d.ts +2 -0
- package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
- package/dist/auth/managed-auth-session-adapter.d.ts +9 -1
- package/dist/auth/managed-auth.d.ts +72 -5
- package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
- package/dist/auth/new-signups-gate.d.ts +23 -0
- package/dist/auth/signup-funnel-metrics.d.ts +44 -0
- package/dist/azure-live.d.ts +28 -0
- package/dist/browser-action-fences.d.ts +13 -0
- package/dist/browser-controller-authority.d.ts +1 -61
- package/dist/browser-ephemeral.d.ts +5 -0
- package/dist/browser-lost-runtime-end.d.ts +24 -0
- package/dist/browser-state-authority.d.ts +1 -27
- package/dist/chunk-OGQDXVXY.js +18 -0
- package/dist/chunk-OGQDXVXY.js.map +1 -0
- package/dist/{chunk-AJ62T5QN.js → chunk-OT56OY4V.js} +80503 -39869
- package/dist/chunk-OT56OY4V.js.map +1 -0
- package/dist/claude-default-models.d.ts +19 -0
- package/dist/claude-subscription-core.d.ts +50 -0
- package/dist/claude-subscription-oauth.d.ts +36 -0
- package/dist/claude-subscription-profile.d.ts +9 -0
- package/dist/claude-subscription-usage.d.ts +6 -0
- package/dist/claude-workspace-connection.d.ts +15 -0
- package/dist/codemode.d.ts +40 -5
- package/dist/codex-realtime.d.ts +29 -3
- package/dist/codex-session-pointers.d.ts +19 -0
- package/dist/connection-ownership.d.ts +6 -3
- package/dist/controller-data-plane.d.ts +16 -0
- package/dist/credit-promotion-snapshot.d.ts +6 -0
- package/dist/editable-artifact-source-session.d.ts +3 -0
- package/dist/editable-artifact-websocket.d.ts +5 -3
- package/dist/fatal-process-boundary.d.ts +9 -1
- package/dist/github-access.d.ts +7 -1
- package/dist/github-browser-flow.d.ts +1 -1
- package/dist/http/acting-person.d.ts +36 -0
- package/dist/http/api-contract-compat.d.ts +19 -0
- package/dist/http/api-error.d.ts +50 -1
- package/dist/http/auth.d.ts +8 -1
- package/dist/http/cors.d.ts +12 -0
- package/dist/http/deprecation.d.ts +42 -0
- package/dist/http/keyed-admission.d.ts +12 -0
- package/dist/http/local-browser-boundary.d.ts +72 -0
- package/dist/http/metrics-listener.d.ts +22 -0
- package/dist/http/path-identifier.d.ts +17 -0
- package/dist/http/registered-route-label.d.ts +16 -0
- package/dist/http/rejection-telemetry.d.ts +34 -0
- package/dist/http/request-body.d.ts +27 -0
- package/dist/http/request-source.d.ts +41 -3
- package/dist/http/sse.d.ts +12 -1
- package/dist/http/unmatched-route.d.ts +18 -0
- package/dist/http/user-content.d.ts +36 -0
- package/dist/http/variable-sets-removed.d.ts +41 -0
- package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
- package/dist/index.js +1279 -108
- package/dist/index.js.map +1 -1
- package/dist/integration-connect-metrics.d.ts +35 -0
- package/dist/integration-endpoint-test.d.ts +20 -0
- package/dist/integrations/api-integrations.d.ts +2 -2
- package/dist/integrations/atlassian.d.ts +8 -3
- package/dist/integrations/fiken.d.ts +3 -1
- package/dist/integrations/github-lens-connect.d.ts +37 -66
- package/dist/integrations/google-drive.d.ts +2 -0
- package/dist/integrations/integration-commit-authority.d.ts +13 -0
- package/dist/integrations/marketplace-plugin.d.ts +43 -43
- package/dist/integrations/oauth-client.d.ts +171 -12
- package/dist/integrations/oauth-profiles.d.ts +42 -13
- package/dist/integrations/onepassword-vault-provider.d.ts +9 -0
- package/dist/integrations/slack-bot.d.ts +285 -7
- package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
- package/dist/integrations/slack-interactions.d.ts +89 -10
- package/dist/integrations/slack-mrkdwn.d.ts +41 -0
- package/dist/integrations/slack-routing.d.ts +1 -1
- package/dist/integrations/slack-session-defaults.d.ts +58 -0
- package/dist/integrations/slack-task-file-upload.d.ts +36 -0
- package/dist/integrations/slack-tool-review.d.ts +5 -0
- package/dist/interaction-agent-access.d.ts +13 -8
- package/dist/interaction-agent-version.d.ts +21 -0
- package/dist/interaction-holder-heartbeat.d.ts +5 -0
- package/dist/interaction-metrics.d.ts +27 -2
- package/dist/interaction-route-stages.d.ts +25 -0
- package/dist/interaction-secrets-vault.d.ts +20 -0
- package/dist/interaction-secrets.d.ts +103 -0
- package/dist/mcp/action-catalog-types.d.ts +14 -0
- package/dist/mcp/action-catalog.gen.d.ts +2 -0
- package/dist/mcp/action-descriptions.d.ts +4 -0
- package/dist/mcp/action-schema-imports.gen.d.ts +1 -0
- package/dist/mcp/capability-account-readiness.d.ts +7 -0
- package/dist/mcp/child-read-evidence.d.ts +9 -0
- package/dist/mcp/company-profile-agent-admin.d.ts +12 -0
- package/dist/mcp/contract-input.d.ts +13 -0
- package/dist/mcp/documents.d.ts +2 -0
- package/dist/mcp/first-party-tool-permissions.d.ts +3 -606
- package/dist/mcp/notification-tools.d.ts +26 -0
- package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
- package/dist/mcp/scheduled-task-input.d.ts +1309 -0
- package/dist/mcp/scheduled-task-view.d.ts +217 -3
- package/dist/mcp/secret-tools.d.ts +14 -0
- package/dist/mcp/server.d.ts +108 -5
- package/dist/mcp/session-admin-access-tools.d.ts +33 -0
- package/dist/mcp/session-event-errors.d.ts +28 -0
- package/dist/mcp/session-event-view.d.ts +62 -0
- package/dist/mcp/session-view.d.ts +15 -0
- package/dist/mcp/session-wait.d.ts +18 -0
- package/dist/mcp/site-agent-clamp-tools.d.ts +38 -0
- package/dist/mcp/site-data-tools.d.ts +22 -0
- package/dist/mcp/site-publication-tools.d.ts +19 -0
- package/dist/mcp/site-sql-tools.d.ts +27 -0
- package/dist/mcp-oauth.d.ts +37 -4
- package/dist/model-calls/chat-completions.d.ts +87 -0
- package/dist/model-calls/pending-usage-settlements.d.ts +57 -0
- package/dist/model-calls/service.d.ts +36 -0
- package/dist/model-catalog.d.ts +9 -3
- package/dist/native-push-dispatch.d.ts +69 -0
- package/dist/observability.d.ts +3 -1
- package/dist/organization-mcp.d.ts +82 -0
- package/dist/prepared-mcp-actor.d.ts +77 -0
- package/dist/prepared-mcp-permissions.d.ts +8 -0
- package/dist/routes/analytics-consent.d.ts +26 -0
- package/dist/routes/api-integrations.d.ts +11 -0
- package/dist/routes/api-keys.d.ts +7 -7
- package/dist/routes/automations.d.ts +2 -0
- package/dist/routes/billing.d.ts +59 -0
- package/dist/routes/browser-sessions.d.ts +65 -2
- package/dist/routes/chat-completions.d.ts +11 -0
- package/dist/routes/claude-core-usage.d.ts +20 -0
- package/dist/routes/claude-subscription-accounts.d.ts +3 -0
- package/dist/routes/claude-subscription-oauth.d.ts +3 -0
- package/dist/routes/client-errors.d.ts +182 -0
- package/dist/routes/codex-core.d.ts +401 -0
- package/dist/routes/codex.d.ts +64 -2
- package/dist/routes/computer-sessions.d.ts +6 -1
- package/dist/routes/desktop-distribution.d.ts +32 -0
- package/dist/routes/github-browser-fonts.gen.d.ts +2 -0
- package/dist/routes/github-browser-pages.d.ts +27 -0
- package/dist/routes/inbox.d.ts +13 -0
- package/dist/routes/insights-response-cache.d.ts +10 -0
- package/dist/routes/insights-usage.d.ts +12 -0
- package/dist/routes/insights.d.ts +28 -0
- package/dist/routes/interaction-placement-message.d.ts +7 -0
- package/dist/routes/managed-sign-in-methods.d.ts +6 -0
- package/dist/routes/model-account-choice.d.ts +13 -0
- package/dist/routes/model-account-settings.d.ts +19 -0
- package/dist/routes/native-app-auth.d.ts +12 -0
- package/dist/routes/organization-integration-policy.d.ts +8 -0
- package/dist/routes/organization-integrations.d.ts +6 -0
- package/dist/routes/organization-mcp-connections.d.ts +3 -0
- package/dist/routes/organization-model-defaults.d.ts +9 -0
- package/dist/routes/organization-service-accounts.d.ts +3 -0
- package/dist/routes/personal-api-keys.d.ts +3 -0
- package/dist/routes/session-admin-access.d.ts +3 -0
- package/dist/routes/session-artifact-associations.d.ts +4 -0
- package/dist/routes/session-history-imports.d.ts +20 -0
- package/dist/routes/sessions.d.ts +38 -2
- package/dist/routes/site-data.d.ts +18 -0
- package/dist/routes/site-publishing.d.ts +5 -0
- package/dist/routes/site-runtime.d.ts +31 -0
- package/dist/routes/site-sql.d.ts +16 -0
- package/dist/routes/slack-bot-access.d.ts +3 -0
- package/dist/routes/subscription-account-pools.d.ts +21 -0
- package/dist/routes/subscription-core-http.d.ts +5 -0
- package/dist/routes/subscription-pool-access.d.ts +37 -0
- package/dist/routes/subscription-pool-core.d.ts +153 -0
- package/dist/routes/supergrok.d.ts +6 -6
- package/dist/routes/usage-allowances.d.ts +12 -0
- package/dist/routes/variable-sets-removed.d.ts +2 -0
- package/dist/routes/vault-providers.d.ts +34 -0
- package/dist/routes/vaults.d.ts +3 -0
- package/dist/routes/workspace-integrations.d.ts +35 -0
- package/dist/routes/workspace-model-providers.d.ts +4 -0
- package/dist/routes/workspaces.d.ts +11 -2
- package/dist/sandbox/agent-update.d.ts +64 -0
- package/dist/sandbox/auth-callout.d.ts +8 -0
- package/dist/sandbox/channel-a.d.ts +15 -1
- package/dist/sandbox/enrollment.d.ts +26 -4
- package/dist/sandbox/machine-audience.d.ts +29 -0
- package/dist/sandbox/machines.d.ts +15 -2
- package/dist/sandbox/metrics-ingestion.d.ts +6 -2
- package/dist/sandbox/screen-control.d.ts +85 -0
- package/dist/sandbox/viewer.d.ts +5 -1
- package/dist/sandbox-file-artifacts.d.ts +17 -1
- package/dist/scheduled-task-blockers.d.ts +39 -0
- package/dist/scheduled-task-deletion.d.ts +3 -4
- package/dist/scheduled-task-lifecycle.d.ts +14 -0
- package/dist/secret-answers.d.ts +40 -0
- package/dist/session-create-observability.d.ts +5 -0
- package/dist/session-event-view-36GO3IL7.js +528 -0
- package/dist/session-event-view-36GO3IL7.js.map +1 -0
- package/dist/signed-state-secret.d.ts +18 -0
- package/dist/site-agent-guard.d.ts +53 -0
- package/dist/site-data/operations.d.ts +103 -0
- package/dist/site-data/service.d.ts +203 -0
- package/dist/site-frame-guard.d.ts +32 -0
- package/dist/site-publishing/agent-data-tools.d.ts +84 -0
- package/dist/site-publishing/agent-model.d.ts +58 -0
- package/dist/site-publishing/agent-session.d.ts +16 -0
- package/dist/site-publishing/content-scanner.d.ts +31 -0
- package/dist/site-publishing/edge-sync.d.ts +48 -0
- package/dist/site-publishing/gateway-signature.d.ts +56 -0
- package/dist/site-publishing/limits.d.ts +63 -0
- package/dist/site-publishing/page-tool-authority.d.ts +30 -0
- package/dist/site-publishing/platform-usage.d.ts +113 -0
- package/dist/site-publishing/platform.d.ts +21 -0
- package/dist/site-publishing/readiness.d.ts +62 -0
- package/dist/site-publishing/runtime.d.ts +179 -0
- package/dist/site-publishing/service.d.ts +264 -0
- package/dist/site-publishing/session-events.d.ts +22 -0
- package/dist/site-publishing/session-views.d.ts +36 -0
- package/dist/site-publishing/viewer.d.ts +40 -0
- package/dist/site-session-origin.d.ts +31 -6
- package/dist/site-sql/format.d.ts +47 -0
- package/dist/site-sql/gateway.d.ts +50 -0
- package/dist/site-sql/service.d.ts +213 -0
- package/dist/temporal-schedule-sync.d.ts +26 -0
- package/dist/transcription/billing-refusal.d.ts +8 -0
- package/dist/transcription/normalize.d.ts +23 -0
- package/dist/transcription/providers/azure-mai.d.ts +12 -0
- package/dist/transcription/providers/azure-openai.d.ts +4 -0
- package/dist/transcription/providers/openai.d.ts +16 -0
- package/dist/transcription/providers/subscription-core.d.ts +39 -0
- package/dist/transcription/service.d.ts +10 -1
- package/dist/transcription/wav-duration.d.ts +8 -0
- package/dist/workspace-tool-gateway-attestations.d.ts +37 -0
- package/dist/workspace-tool-gateway-observability.d.ts +16 -0
- package/dist/workspace-tool-gateway-secrets.d.ts +27 -0
- package/dist/workspace-tool-gateway.d.ts +102 -6
- package/dist/workspace-tool-target-fence.d.ts +116 -0
- package/dist/workspace-tool-target.d.ts +225 -0
- package/dist/workspace-webhook-dispatch.d.ts +26 -0
- package/dist/xai-subscription-core.d.ts +60 -0
- package/package.json +25 -20
- package/src/access-grant-rls.ts +64 -14
- package/src/admission-trace.ts +14 -0
- package/src/app.ts +1684 -252
- package/src/artifact-catalog-cursor.ts +1 -0
- package/src/attached-browser-viewer.ts +26 -0
- package/src/auth/managed-auth-attempt-context.ts +9 -0
- package/src/auth/managed-auth-rate-limits.ts +252 -0
- package/src/auth/managed-auth-session-adapter.ts +64 -29
- package/src/auth/managed-auth.ts +303 -35
- package/src/auth/managed-email.ts +18 -1
- package/src/auth/managed-sign-in-notifications.ts +81 -0
- package/src/auth/new-signups-gate.ts +49 -0
- package/src/auth/organization-user-setup.ts +3 -3
- package/src/auth/signup-funnel-metrics.ts +164 -0
- package/src/azure-live.ts +103 -0
- package/src/browser-action-fences.ts +45 -0
- package/src/browser-controller-authority.ts +1 -186
- package/src/browser-ephemeral.ts +39 -0
- package/src/browser-lost-runtime-end.ts +71 -0
- package/src/browser-state-authority.ts +1 -236
- package/src/claude-default-models.ts +37 -0
- package/src/claude-subscription-core.ts +154 -0
- package/src/claude-subscription-oauth.ts +352 -0
- package/src/claude-subscription-profile.ts +73 -0
- package/src/claude-subscription-usage.ts +51 -0
- package/src/claude-workspace-connection.ts +82 -0
- package/src/codemode.ts +236 -39
- package/src/codex-realtime.ts +181 -53
- package/src/codex-session-pointers.ts +80 -0
- package/src/company-brain-okf.ts +1 -1
- package/src/connected-machine-computer-access.ts +2 -1
- package/src/connection-ownership.ts +19 -13
- package/src/controller-data-plane.ts +34 -0
- package/src/credit-promotion-snapshot.ts +36 -0
- package/src/editable-artifact-production.ts +10 -0
- package/src/editable-artifact-source-session.ts +123 -0
- package/src/editable-artifact-websocket.ts +16 -3
- package/src/fatal-process-boundary.ts +67 -3
- package/src/gateway-realtime.ts +12 -8
- package/src/github-access.ts +31 -5
- package/src/github-browser-flow.ts +1 -1
- package/src/http/acting-person.ts +105 -0
- package/src/http/api-contract-compat.ts +49 -0
- package/src/http/api-error.ts +210 -2
- package/src/http/auth.ts +68 -4
- package/src/http/cors.ts +37 -5
- package/src/http/deprecation.ts +118 -0
- package/src/http/keyed-admission.ts +29 -0
- package/src/http/local-browser-boundary.ts +343 -0
- package/src/http/metrics-listener.ts +57 -0
- package/src/http/path-identifier.ts +54 -0
- package/src/http/registered-route-label.ts +34 -0
- package/src/http/rejection-telemetry.ts +120 -0
- package/src/http/request-body.ts +127 -0
- package/src/http/request-source.ts +154 -13
- package/src/http/sse.ts +88 -28
- package/src/http/unmatched-route.ts +60 -0
- package/src/http/user-content.ts +158 -0
- package/src/http/variable-sets-removed.ts +122 -0
- package/src/http/websocket-upgrade-dispatch.ts +29 -0
- package/src/index.ts +107 -57
- package/src/integration-connect-metrics.ts +228 -0
- package/src/integration-endpoint-test.ts +291 -0
- package/src/integrations/api-integrations.ts +81 -7
- package/src/integrations/atlassian.ts +202 -83
- package/src/integrations/fiken.ts +66 -38
- package/src/integrations/github-app-connect.ts +64 -18
- package/src/integrations/github-lens-connect.ts +8 -29
- package/src/integrations/google-drive.ts +448 -152
- package/src/integrations/integration-commit-authority.ts +69 -0
- package/src/integrations/marketplace-plugin.ts +1 -1
- package/src/integrations/oauth-client.ts +733 -193
- package/src/integrations/oauth-profiles.ts +116 -45
- package/src/integrations/onepassword-vault-provider.ts +16 -0
- package/src/integrations/personal-github-repositories.ts +1 -1
- package/src/integrations/personal-github.ts +61 -35
- package/src/integrations/provider-oauth.ts +67 -85
- package/src/integrations/slack-app-home.ts +5 -5
- package/src/integrations/slack-bot.ts +893 -201
- package/src/integrations/slack-file-upload-flow.ts +147 -0
- package/src/integrations/slack-install.ts +7 -7
- package/src/integrations/slack-interactions.ts +1589 -299
- package/src/integrations/slack-mrkdwn.ts +193 -0
- package/src/integrations/slack-routing.ts +2 -2
- package/src/integrations/slack-session-defaults.ts +224 -0
- package/src/integrations/slack-task-file-upload.ts +323 -0
- package/src/integrations/slack-tool-review.ts +65 -0
- package/src/integrations/social-oauth.ts +90 -58
- package/src/interaction-agent-access.ts +40 -20
- package/src/interaction-agent-version.ts +85 -0
- package/src/interaction-holder-heartbeat.ts +24 -8
- package/src/interaction-metrics.ts +164 -2
- package/src/interaction-route-stages.ts +94 -0
- package/src/interaction-secrets-vault.ts +213 -0
- package/src/interaction-secrets.ts +426 -0
- package/src/mcp/action-catalog-types.ts +14 -0
- package/src/mcp/action-catalog.gen.ts +8014 -0
- package/src/mcp/action-descriptions.ts +299 -0
- package/src/mcp/action-schema-imports.gen.ts +304 -0
- package/src/mcp/capability-account-readiness.ts +17 -0
- package/src/mcp/child-read-evidence.ts +19 -0
- package/src/mcp/company-profile-agent-admin.ts +13 -0
- package/src/mcp/contract-input.ts +165 -0
- package/src/mcp/documents.ts +9 -2
- package/src/mcp/editable-artifacts.ts +29 -11
- package/src/mcp/files.ts +5 -1
- package/src/mcp/first-party-tool-permissions.ts +7 -285
- package/src/mcp/knowledge-entries.ts +108 -34
- package/src/mcp/notification-tools.ts +480 -0
- package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
- package/src/mcp/scheduled-task-input.ts +89 -0
- package/src/mcp/scheduled-task-view.ts +63 -3
- package/src/mcp/secret-tools.ts +185 -0
- package/src/mcp/server.ts +2213 -1116
- package/src/mcp/session-admin-access-tools.ts +163 -0
- package/src/mcp/session-event-errors.ts +123 -0
- package/src/mcp/session-event-view.ts +395 -13
- package/src/mcp/session-view.ts +3 -0
- package/src/mcp/session-wait.ts +67 -7
- package/src/mcp/site-agent-clamp-tools.ts +140 -0
- package/src/mcp/site-data-tools.ts +339 -0
- package/src/mcp/site-publication-tools.ts +201 -0
- package/src/mcp/site-sql-tools.ts +427 -0
- package/src/mcp-oauth.ts +635 -45
- package/src/model-calls/chat-completions.ts +352 -0
- package/src/model-calls/pending-usage-settlements.ts +125 -0
- package/src/model-calls/service.ts +694 -0
- package/src/model-catalog.ts +68 -17
- package/src/native-push-dispatch.ts +457 -0
- package/src/observability.ts +15 -1
- package/src/organization-mcp.ts +485 -0
- package/src/prepared-mcp-actor.ts +154 -0
- package/src/prepared-mcp-permissions.ts +38 -0
- package/src/routes/analytics-consent.ts +123 -0
- package/src/routes/api-integrations.ts +268 -9
- package/src/routes/api-keys.ts +164 -25
- package/src/routes/artifact-catalog.ts +111 -0
- package/src/routes/automations.ts +163 -90
- package/src/routes/billing.ts +535 -59
- package/src/routes/browser-sessions.ts +966 -342
- package/src/routes/canonical-human-identities.ts +61 -0
- package/src/routes/capabilities.ts +112 -5
- package/src/routes/channels.ts +4 -3
- package/src/routes/chat-completions.ts +235 -0
- package/src/routes/claude-core-usage.ts +147 -0
- package/src/routes/claude-subscription-accounts.ts +233 -0
- package/src/routes/claude-subscription-oauth.ts +175 -0
- package/src/routes/client-errors.ts +394 -0
- package/src/routes/codex-core.ts +687 -0
- package/src/routes/codex.ts +1277 -1119
- package/src/routes/company-brain.ts +4 -0
- package/src/routes/computer-sessions.ts +319 -85
- package/src/routes/connect.ts +277 -175
- package/src/routes/connections.ts +690 -363
- package/src/routes/desktop-distribution.ts +217 -0
- package/src/routes/documents.ts +13 -7
- package/src/routes/editable-artifacts.ts +74 -4
- package/src/routes/enrollments.ts +110 -16
- package/src/routes/external-identity-links.ts +13 -12
- package/src/routes/files.ts +41 -16
- package/src/routes/github-browser-fonts.gen.ts +12 -0
- package/src/routes/github-browser-pages.ts +258 -0
- package/src/routes/github.ts +200 -75
- package/src/routes/inbox.ts +353 -0
- package/src/routes/insights-response-cache.ts +83 -0
- package/src/routes/insights-usage.ts +345 -0
- package/src/routes/insights.ts +103 -8
- package/src/routes/install.ts +51 -10
- package/src/routes/integration-facets.ts +70 -28
- package/src/routes/interaction-placement-message.ts +12 -0
- package/src/routes/knowledge.ts +136 -27
- package/src/routes/machines.ts +189 -135
- package/src/routes/managed-auth-session-sets.ts +43 -10
- package/src/routes/managed-onboarding.ts +39 -19
- package/src/routes/managed-sign-in-methods.ts +433 -0
- package/src/routes/memory-slack-publications.ts +3 -2
- package/src/routes/model-account-choice.ts +194 -0
- package/src/routes/model-account-settings.ts +235 -0
- package/src/routes/model-connection-access.ts +210 -48
- package/src/routes/native-app-auth.ts +296 -0
- package/src/routes/organization-integration-policy.ts +116 -0
- package/src/routes/organization-integrations.ts +326 -0
- package/src/routes/organization-mcp-connections.ts +183 -0
- package/src/routes/organization-memberships.ts +205 -19
- package/src/routes/organization-model-defaults.ts +110 -0
- package/src/routes/organization-model-providers.ts +74 -3
- package/src/routes/organization-service-accounts.ts +128 -0
- package/src/routes/organization-sessions.ts +21 -5
- package/src/routes/personal-api-keys.ts +184 -0
- package/src/routes/personal-github-git-broker.ts +2 -2
- package/src/routes/personal-github.ts +9 -4
- package/src/routes/plugins.ts +46 -7
- package/src/routes/pr-review-github.ts +105 -118
- package/src/routes/pr-review.ts +88 -82
- package/src/routes/preference-registry.ts +18 -0
- package/src/routes/rigs.ts +48 -13
- package/src/routes/scheduled-tasks.ts +347 -27
- package/src/routes/session-admin-access.ts +271 -0
- package/src/routes/session-artifact-associations.ts +164 -0
- package/src/routes/session-history-imports.ts +305 -0
- package/src/routes/sessions.ts +1682 -363
- package/src/routes/site-data.ts +340 -0
- package/src/routes/site-publishing.ts +584 -0
- package/src/routes/site-runtime.ts +1944 -0
- package/src/routes/site-sql.ts +263 -0
- package/src/routes/skill-content.ts +72 -7
- package/src/routes/skills.ts +5 -4
- package/src/routes/slack-bot-access.ts +108 -0
- package/src/routes/social.ts +27 -15
- package/src/routes/subscription-account-pools.ts +209 -0
- package/src/routes/subscription-core-http.ts +18 -0
- package/src/routes/subscription-pool-access.ts +180 -0
- package/src/routes/subscription-pool-core.ts +552 -0
- package/src/routes/supergrok.ts +174 -655
- package/src/routes/transcription-recordings.ts +71 -4
- package/src/routes/transcriptions.ts +26 -2
- package/src/routes/usage-allowances.ts +381 -0
- package/src/routes/variable-sets-removed.ts +19 -0
- package/src/routes/vault-providers.ts +782 -0
- package/src/routes/vaults.ts +421 -0
- package/src/routes/video-generation.ts +30 -12
- package/src/routes/workspace-artifacts.ts +165 -53
- package/src/routes/workspace-integrations.ts +576 -0
- package/src/routes/workspace-model-providers.ts +148 -0
- package/src/routes/workspace-state.ts +4 -0
- package/src/routes/workspaces.ts +625 -117
- package/src/sandbox/agent-update.ts +315 -0
- package/src/sandbox/auth-callout.ts +104 -21
- package/src/sandbox/channel-a.ts +165 -55
- package/src/sandbox/enrollment.ts +131 -22
- package/src/sandbox/machine-audience.ts +192 -0
- package/src/sandbox/machines.ts +75 -31
- package/src/sandbox/metrics-ingestion.ts +133 -2
- package/src/sandbox/rematerialize.ts +51 -21
- package/src/sandbox/screen-control.ts +289 -0
- package/src/sandbox/viewer.ts +33 -58
- package/src/sandbox-file-artifacts.ts +53 -27
- package/src/scheduled-task-blockers.ts +293 -0
- package/src/scheduled-task-deletion.ts +13 -3
- package/src/scheduled-task-lifecycle.ts +84 -0
- package/src/secret-answers.ts +119 -0
- package/src/session-create-observability.ts +46 -0
- package/src/session-realtime-context.ts +26 -4
- package/src/signed-state-secret.ts +58 -0
- package/src/site-agent-guard.ts +261 -0
- package/src/site-data/operations.ts +777 -0
- package/src/site-data/service.ts +1043 -0
- package/src/site-frame-guard.ts +107 -0
- package/src/site-publishing/agent-data-tools.ts +250 -0
- package/src/site-publishing/agent-model.ts +127 -0
- package/src/site-publishing/agent-session.ts +148 -0
- package/src/site-publishing/content-scanner.ts +93 -0
- package/src/site-publishing/edge-sync.ts +148 -0
- package/src/site-publishing/gateway-signature.ts +198 -0
- package/src/site-publishing/limits.ts +315 -0
- package/src/site-publishing/page-tool-authority.ts +111 -0
- package/src/site-publishing/platform-usage.ts +479 -0
- package/src/site-publishing/platform.ts +98 -0
- package/src/site-publishing/readiness.ts +330 -0
- package/src/site-publishing/runtime.ts +831 -0
- package/src/site-publishing/service.ts +1282 -0
- package/src/site-publishing/session-events.ts +262 -0
- package/src/site-publishing/session-views.ts +262 -0
- package/src/site-publishing/viewer.ts +75 -0
- package/src/site-session-origin.ts +91 -6
- package/src/site-sql/format.ts +134 -0
- package/src/site-sql/gateway.ts +168 -0
- package/src/site-sql/service.ts +1636 -0
- package/src/site-uploads.ts +27 -5
- package/src/temporal-schedule-sync.ts +74 -0
- package/src/transcription/billing-refusal.ts +14 -0
- package/src/transcription/normalize.ts +77 -0
- package/src/transcription/providers/azure-mai.ts +98 -0
- package/src/transcription/providers/azure-openai.ts +16 -7
- package/src/transcription/providers/codex-subscription.ts +190 -67
- package/src/transcription/providers/openai.ts +79 -5
- package/src/transcription/providers/subscription-core.ts +125 -0
- package/src/transcription/providers/xai-subscription.ts +81 -83
- package/src/transcription/segmenter.ts +7 -1
- package/src/transcription/service.ts +239 -10
- package/src/transcription/wav-duration.ts +39 -0
- package/src/workspace-deletion.ts +25 -1
- package/src/workspace-tool-gateway-attestations.ts +133 -0
- package/src/workspace-tool-gateway-observability.ts +64 -0
- package/src/workspace-tool-gateway-secrets.ts +104 -0
- package/src/workspace-tool-gateway.ts +921 -103
- package/src/workspace-tool-target-fence.ts +380 -0
- package/src/workspace-tool-target.ts +554 -0
- package/src/workspace-webhook-dispatch.ts +225 -0
- package/src/xai-realtime.ts +85 -81
- package/src/xai-subscription-core.ts +172 -0
- package/dist/browser-auth-broker.d.ts +0 -20
- package/dist/chunk-AJ62T5QN.js.map +0 -1
- package/dist/connection-authority-owner.d.ts +0 -59
- package/dist/routes/connection-authorities.d.ts +0 -3
- package/dist/routes/environments.d.ts +0 -5
- package/dist/routes/host-mcp-bindings.d.ts +0 -5
- package/dist/routes/host-mcp-resolvers.d.ts +0 -3
- package/dist/routes/packs.d.ts +0 -3
- package/dist/session-event-view-MU3HMNV3.js +0 -264
- package/dist/session-event-view-MU3HMNV3.js.map +0 -1
- package/dist/xai-subscription-auth.d.ts +0 -23
- package/src/browser-auth-broker.ts +0 -155
- package/src/connection-authority-owner.ts +0 -61
- package/src/routes/connection-authorities.ts +0 -139
- package/src/routes/environments.ts +0 -388
- package/src/routes/host-mcp-bindings.ts +0 -122
- package/src/routes/host-mcp-resolvers.ts +0 -41
- package/src/routes/packs.ts +0 -784
- package/src/xai-subscription-auth.ts +0 -139
package/src/codemode.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { siteRequestHeaders } from "@opengeni/contracts/site-session-http";
|
|
2
1
|
import {
|
|
3
2
|
codemodeDispatchSubject,
|
|
4
3
|
decodeCodemodeDispatchAck,
|
|
@@ -14,29 +13,43 @@ import {
|
|
|
14
13
|
type CodemodeOperation,
|
|
15
14
|
} from "@opengeni/contracts";
|
|
16
15
|
import type { ApiRouteDeps } from "@opengeni/core";
|
|
17
|
-
import { hasPermission, requireSessionAuthorization } from "@opengeni/core";
|
|
16
|
+
import { hasPermission, isDeveloperSetupGrant, requireSessionAuthorization } from "@opengeni/core";
|
|
18
17
|
import {
|
|
18
|
+
CodemodeToolApprovalRequiredError,
|
|
19
19
|
getActiveSessionTurnForExecution,
|
|
20
20
|
getAttemptToolCatalog,
|
|
21
21
|
getCodemodeOperation,
|
|
22
|
+
readTurnCodemodeOperation,
|
|
22
23
|
submitCodemodeOperation,
|
|
24
|
+
type SessionTurnForExecution,
|
|
23
25
|
} from "@opengeni/db";
|
|
24
|
-
import { getSession } from "@opengeni/db";
|
|
26
|
+
import { getSession, requireWorkspace } from "@opengeni/db";
|
|
25
27
|
import {
|
|
26
28
|
allowedFirstPartyMcpToolsForSession,
|
|
29
|
+
resolveSessionFirstPartyMcpTools,
|
|
27
30
|
resolveFirstPartyDelegationSecret,
|
|
28
|
-
type
|
|
31
|
+
type FirstPartyMcpToolPolicySettings,
|
|
29
32
|
} from "@opengeni/config";
|
|
30
33
|
import {
|
|
31
34
|
DEFAULT_FIRST_PARTY_MCP_PERMISSIONS,
|
|
32
35
|
signDelegatedAccessToken,
|
|
33
|
-
|
|
36
|
+
readTurnExecutionPolicyV1,
|
|
34
37
|
OPENGENI_API_CONTRACT_HEADER,
|
|
35
38
|
OPENGENI_API_CONTRACT_REVISION,
|
|
36
39
|
type Permission,
|
|
37
40
|
type Session,
|
|
38
41
|
} from "@opengeni/contracts";
|
|
42
|
+
import {
|
|
43
|
+
SITE_FRAME_HEADER,
|
|
44
|
+
SITE_FRAME_ID_HEADER,
|
|
45
|
+
SITE_PREVIEW_FRAME,
|
|
46
|
+
siteFrameFromHeaders,
|
|
47
|
+
siteHostWorkspacePath,
|
|
48
|
+
siteRequestHeaders,
|
|
49
|
+
siteSessionPath,
|
|
50
|
+
} from "@opengeni/contracts/site-session-http";
|
|
39
51
|
import { permissionsRequiredByFirstPartyTools } from "./mcp/first-party-tool-permissions";
|
|
52
|
+
import { isPreparedMcpConnectPath, preparedMcpProxyPermissions } from "./prepared-mcp-permissions";
|
|
40
53
|
|
|
41
54
|
/** The REST authority a Codemode SDK proxy token may ever carry. */
|
|
42
55
|
export const CODEMODE_SESSION_PROXY_PERMISSION_CEILING = [
|
|
@@ -55,7 +68,7 @@ export const CODEMODE_SESSION_PROXY_PERMISSION_CEILING = [
|
|
|
55
68
|
* exactly as its MCP surface would.
|
|
56
69
|
*/
|
|
57
70
|
export function codemodeSessionProxyPermissions(
|
|
58
|
-
settings:
|
|
71
|
+
settings: FirstPartyMcpToolPolicySettings,
|
|
59
72
|
session: Pick<Session, "firstPartyMcpTools" | "firstPartyMcpPermissions">,
|
|
60
73
|
): Permission[] {
|
|
61
74
|
const sessionPermissions = session.firstPartyMcpPermissions ?? [
|
|
@@ -71,6 +84,34 @@ export function codemodeSessionProxyPermissions(
|
|
|
71
84
|
);
|
|
72
85
|
}
|
|
73
86
|
|
|
87
|
+
const FRAME_ID = /^[A-Za-z0-9_-]{1,64}$/u;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The route a Codemode SDK proxy request may take. The agent's own SDK calls
|
|
91
|
+
* keep the workspace prefix boundary under the proxy permission ceiling. A
|
|
92
|
+
* request a local Site preview forwarded from page code carries the frame
|
|
93
|
+
* marker and is held to the `SITE_OPERATIONS` allowlist; it stays marked as
|
|
94
|
+
* a preview frame (never a published Site) so the API records its origin and
|
|
95
|
+
* keeps it to the sessions it started.
|
|
96
|
+
*/
|
|
97
|
+
function codemodeProxyRoute(request: Request, path: string) {
|
|
98
|
+
const frame = siteFrameFromHeaders((name) => request.headers.get(name));
|
|
99
|
+
if (!frame) {
|
|
100
|
+
return {
|
|
101
|
+
path: (workspaceId: string) => siteHostWorkspacePath(path, workspaceId),
|
|
102
|
+
frameHeaders: null,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const frameId = frame.frameId && FRAME_ID.test(frame.frameId) ? frame.frameId : null;
|
|
106
|
+
return {
|
|
107
|
+
path: (workspaceId: string) => siteSessionPath(path, workspaceId, request.method),
|
|
108
|
+
frameHeaders: {
|
|
109
|
+
[SITE_FRAME_HEADER]: SITE_PREVIEW_FRAME,
|
|
110
|
+
...(frameId ? { [SITE_FRAME_ID_HEADER]: frameId } : {}),
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
74
115
|
/** Reuse normal REST handlers, including their resource/command authorization.
|
|
75
116
|
* The exact attempt is checked before issuing this internal-only credential. */
|
|
76
117
|
export async function codemodeSessionRequest(
|
|
@@ -78,23 +119,56 @@ export async function codemodeSessionRequest(
|
|
|
78
119
|
grant: AccessGrant,
|
|
79
120
|
request: Request,
|
|
80
121
|
path: string,
|
|
122
|
+
resolveProxySettings?: (session: Session) => FirstPartyMcpToolPolicySettings,
|
|
81
123
|
): Promise<Request> {
|
|
82
|
-
|
|
83
|
-
|
|
124
|
+
const route = codemodeProxyRoute(request, path);
|
|
125
|
+
route.path(grant.workspaceId);
|
|
126
|
+
const { authority, turn, catalog } = await requireActiveCodemodeCatalog(deps, grant);
|
|
84
127
|
const session = await getSession(deps.db, authority.workspaceId, authority.sessionId);
|
|
85
128
|
const secret = resolveFirstPartyDelegationSecret(deps.settings);
|
|
86
129
|
if (!session || !secret) throw new CodemodeAuthorityError("invalid_grant");
|
|
87
|
-
const
|
|
130
|
+
const selection = resolveSessionFirstPartyMcpTools(
|
|
131
|
+
resolveProxySettings?.(session) ?? deps.settings,
|
|
132
|
+
session,
|
|
133
|
+
(await requireWorkspace(deps.db, authority.workspaceId)).settings,
|
|
134
|
+
).filter((name) =>
|
|
135
|
+
catalog.entries.some(
|
|
136
|
+
(entry) => entry.identity.serverId === "opengeni" && entry.identity.toolName === name,
|
|
137
|
+
),
|
|
138
|
+
);
|
|
139
|
+
const permissions = codemodeSessionProxyPermissions(
|
|
140
|
+
resolveProxySettings?.(session) ?? deps.settings,
|
|
141
|
+
{ ...session, firstPartyMcpTools: selection },
|
|
142
|
+
);
|
|
143
|
+
if (isPreparedMcpConnectPath(route.path(grant.workspaceId), request.method)) {
|
|
144
|
+
if (selection.includes("custom_mcp_setup_request"))
|
|
145
|
+
permissions.push(
|
|
146
|
+
...preparedMcpProxyPermissions(
|
|
147
|
+
catalog,
|
|
148
|
+
session.firstPartyMcpPermissions ?? [...DEFAULT_FIRST_PARTY_MCP_PERMISSIONS],
|
|
149
|
+
),
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
const turnPolicy = readTurnExecutionPolicyV1(turn.metadata);
|
|
153
|
+
const initialPolicy = readTurnExecutionPolicyV1(session.metadata);
|
|
154
|
+
const restricted =
|
|
155
|
+
isDeveloperSetupGrant(grant) ||
|
|
156
|
+
(turnPolicy.kind === "valid" &&
|
|
157
|
+
turnPolicy.policy.credentialRestriction === "developer_setup") ||
|
|
158
|
+
(initialPolicy.kind === "valid" &&
|
|
159
|
+
initialPolicy.policy.credentialRestriction === "developer_setup");
|
|
88
160
|
const token = await signDelegatedAccessToken(secret, {
|
|
89
161
|
...authority,
|
|
90
162
|
permissions,
|
|
91
163
|
principalKind: "agent_attempt",
|
|
164
|
+
...(restricted ? { credentialRestriction: "developer_setup" as const } : {}),
|
|
92
165
|
exp: Math.floor(Date.now() / 1000) + 60,
|
|
93
166
|
});
|
|
94
167
|
const target = new URL(request.url);
|
|
95
|
-
const rewritten =
|
|
168
|
+
const rewritten = route.path(authority.workspaceId);
|
|
96
169
|
const url = new URL(rewritten, target.origin);
|
|
97
170
|
const headers = siteRequestHeaders(request.headers);
|
|
171
|
+
for (const [name, value] of Object.entries(route.frameHeaders ?? {})) headers.set(name, value);
|
|
98
172
|
headers.set("authorization", `Bearer ${token}`);
|
|
99
173
|
headers.set(OPENGENI_API_CONTRACT_HEADER, OPENGENI_API_CONTRACT_REVISION);
|
|
100
174
|
return new Request(url, {
|
|
@@ -206,7 +280,11 @@ export function requireMatchingCodemodeCatalog(
|
|
|
206
280
|
export async function requireActiveCodemodeCatalog(
|
|
207
281
|
deps: ApiRouteDeps,
|
|
208
282
|
grant: AccessGrant,
|
|
209
|
-
): Promise<{
|
|
283
|
+
): Promise<{
|
|
284
|
+
authority: CodemodeGrantAuthority;
|
|
285
|
+
catalog: AttemptToolCatalog;
|
|
286
|
+
turn: SessionTurnForExecution;
|
|
287
|
+
}> {
|
|
210
288
|
if (!isCodemodeGrant(grant)) throw new CodemodeAuthorityError("invalid_grant");
|
|
211
289
|
const authority = codemodeAuthorityForGrant(grant)!;
|
|
212
290
|
await requireSessionAuthorization(deps, grant, {
|
|
@@ -236,19 +314,21 @@ export async function requireActiveCodemodeCatalog(
|
|
|
236
314
|
attemptId: authority.attemptId,
|
|
237
315
|
}),
|
|
238
316
|
);
|
|
239
|
-
return { authority, catalog };
|
|
317
|
+
return { authority, catalog, turn: active };
|
|
240
318
|
}
|
|
241
319
|
|
|
242
320
|
export async function submitAndDispatchCodemodeCall(
|
|
243
321
|
deps: ApiRouteDeps,
|
|
244
322
|
grant: AccessGrant,
|
|
245
323
|
rawRequest: unknown,
|
|
324
|
+
signal?: AbortSignal,
|
|
246
325
|
): Promise<CodemodeCallSubmissionValue> {
|
|
247
|
-
const request = CodemodeCallRequest.parse(rawRequest);
|
|
326
|
+
const { durableApproval, ...request } = CodemodeCallRequest.parse(rawRequest);
|
|
248
327
|
const { authority, catalog } = await requireActiveCodemodeCatalog(deps, grant);
|
|
249
328
|
if (request.catalogDigest !== catalog.digest) throw new CodemodeCatalogStaleError();
|
|
250
329
|
const submitted = await submitCodemodeOperation(deps.db, {
|
|
251
330
|
...authority,
|
|
331
|
+
...(durableApproval ? { durableApproval: true } : {}),
|
|
252
332
|
call: {
|
|
253
333
|
...request,
|
|
254
334
|
caller: { kind: "codemode", subjectId: authority.subjectId },
|
|
@@ -261,36 +341,149 @@ export async function submitAndDispatchCodemodeCall(
|
|
|
261
341
|
? "already_running"
|
|
262
342
|
: "unavailable";
|
|
263
343
|
if (codemodeOperationNeedsDispatch(operation)) {
|
|
264
|
-
|
|
265
|
-
const reply = await deps.bus.request(
|
|
266
|
-
codemodeDispatchSubject(authority.workspaceId, authority.attemptId),
|
|
267
|
-
encodeCodemodeDispatchRequest({
|
|
268
|
-
version: 1,
|
|
269
|
-
operationId: operation.operationId,
|
|
270
|
-
catalogDigest: catalog.digest,
|
|
271
|
-
}),
|
|
272
|
-
{ timeoutMs: CODEMODE_DISPATCH_TIMEOUT_MS },
|
|
273
|
-
);
|
|
274
|
-
dispatch = decodeCodemodeDispatchAck(reply.data).status;
|
|
275
|
-
} catch {
|
|
276
|
-
dispatch = "unavailable";
|
|
277
|
-
}
|
|
278
|
-
operation = await refreshAdmittedCodemodeOperation(operation, () =>
|
|
344
|
+
const readOperation = () =>
|
|
279
345
|
getCodemodeOperation(deps.db, {
|
|
280
346
|
accountId: authority.accountId,
|
|
281
347
|
workspaceId: authority.workspaceId,
|
|
282
348
|
attemptId: authority.attemptId,
|
|
283
349
|
operationId: operation.operationId,
|
|
284
|
-
})
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
350
|
+
});
|
|
351
|
+
// Listen before dispatching so a fast settlement cannot be missed. The
|
|
352
|
+
// settlement event is committed with the operation row, so its arrival
|
|
353
|
+
// means one read returns the terminal operation.
|
|
354
|
+
const wake = codemodeSettlementWake();
|
|
355
|
+
const unsubscribe = await deps.bus
|
|
356
|
+
.subscribe(authority.workspaceId, authority.sessionId, (events) => {
|
|
357
|
+
if (events.some((event) => isCodemodeSettlementEvent(event, operation.operationId))) {
|
|
358
|
+
wake.notify();
|
|
359
|
+
}
|
|
360
|
+
})
|
|
361
|
+
.catch(() => null);
|
|
362
|
+
try {
|
|
363
|
+
try {
|
|
364
|
+
const reply = await deps.bus.request(
|
|
365
|
+
codemodeDispatchSubject(authority.workspaceId, authority.attemptId),
|
|
366
|
+
encodeCodemodeDispatchRequest({
|
|
367
|
+
version: 1,
|
|
368
|
+
operationId: operation.operationId,
|
|
369
|
+
catalogDigest: catalog.digest,
|
|
370
|
+
}),
|
|
371
|
+
{ timeoutMs: CODEMODE_DISPATCH_TIMEOUT_MS },
|
|
372
|
+
);
|
|
373
|
+
dispatch = decodeCodemodeDispatchAck(reply.data).status;
|
|
374
|
+
} catch {
|
|
375
|
+
dispatch = "unavailable";
|
|
376
|
+
}
|
|
377
|
+
operation = await refreshAdmittedCodemodeOperation(operation, readOperation);
|
|
378
|
+
// An executing call usually settles within moments. Return its result in
|
|
379
|
+
// this response so clients need no polling round; a longer call returns
|
|
380
|
+
// still running and is read as before.
|
|
381
|
+
if (
|
|
382
|
+
unsubscribe &&
|
|
383
|
+
!terminal(operation) &&
|
|
384
|
+
(dispatch === "accepted" || dispatch === "already_running")
|
|
385
|
+
) {
|
|
386
|
+
operation = await awaitCodemodeSettlement({
|
|
387
|
+
operation,
|
|
388
|
+
read: readOperation,
|
|
389
|
+
wake,
|
|
390
|
+
budgetMs: CODEMODE_SUBMIT_SETTLE_WAIT_MS,
|
|
391
|
+
fallbackReadMs: CODEMODE_SETTLE_FALLBACK_READ_MS,
|
|
392
|
+
...(signal ? { signal } : {}),
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
if (terminal(operation)) dispatch = "terminal";
|
|
396
|
+
else if (operation.state === "running" && dispatch === "unavailable") {
|
|
397
|
+
dispatch = "already_running";
|
|
398
|
+
}
|
|
399
|
+
} finally {
|
|
400
|
+
unsubscribe?.();
|
|
289
401
|
}
|
|
290
402
|
}
|
|
291
403
|
return CodemodeCallSubmission.parse({ operation, dispatch });
|
|
292
404
|
}
|
|
293
405
|
|
|
406
|
+
/**
|
|
407
|
+
* How long a submission holds its request open for the call to settle. Most
|
|
408
|
+
* tool calls finish well within it; a longer call returns still running.
|
|
409
|
+
*/
|
|
410
|
+
export const CODEMODE_SUBMIT_SETTLE_WAIT_MS = 8_000;
|
|
411
|
+
/** Safety-net read cadence if the live settlement event is missed. */
|
|
412
|
+
export const CODEMODE_SETTLE_FALLBACK_READ_MS = 400;
|
|
413
|
+
|
|
414
|
+
export function isCodemodeSettlementEvent(
|
|
415
|
+
event: { type: string; payload?: unknown },
|
|
416
|
+
operationId: string,
|
|
417
|
+
): boolean {
|
|
418
|
+
if (event.type !== "agent.toolCall.output") return false;
|
|
419
|
+
const payload = event.payload;
|
|
420
|
+
return (
|
|
421
|
+
typeof payload === "object" &&
|
|
422
|
+
payload !== null &&
|
|
423
|
+
(payload as { id?: unknown }).id === operationId
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
export type CodemodeSettlementWake = {
|
|
428
|
+
notify(): void;
|
|
429
|
+
/** Resolve on the next notification (or one already pending), a timeout or abort. */
|
|
430
|
+
wait(timeoutMs: number, signal?: AbortSignal): Promise<void>;
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
export function codemodeSettlementWake(): CodemodeSettlementWake {
|
|
434
|
+
let pending = false;
|
|
435
|
+
let release: (() => void) | null = null;
|
|
436
|
+
return {
|
|
437
|
+
notify() {
|
|
438
|
+
pending = true;
|
|
439
|
+
release?.();
|
|
440
|
+
},
|
|
441
|
+
async wait(timeoutMs, signal) {
|
|
442
|
+
if (!pending && !signal?.aborted) {
|
|
443
|
+
await new Promise<void>((resolve) => {
|
|
444
|
+
const done = () => {
|
|
445
|
+
clearTimeout(timer);
|
|
446
|
+
signal?.removeEventListener("abort", done);
|
|
447
|
+
release = null;
|
|
448
|
+
resolve();
|
|
449
|
+
};
|
|
450
|
+
const timer = setTimeout(done, Math.max(0, timeoutMs));
|
|
451
|
+
signal?.addEventListener("abort", done, { once: true });
|
|
452
|
+
release = done;
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
pending = false;
|
|
456
|
+
},
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Wait, within a budget, for an executing operation to settle. Waits only
|
|
462
|
+
* while the operation is queued or running; approval and terminal states
|
|
463
|
+
* return at once. Read failures keep the last known row.
|
|
464
|
+
*/
|
|
465
|
+
export async function awaitCodemodeSettlement(input: {
|
|
466
|
+
operation: CodemodeOperation;
|
|
467
|
+
read: () => Promise<CodemodeOperation | null>;
|
|
468
|
+
wake: CodemodeSettlementWake;
|
|
469
|
+
budgetMs: number;
|
|
470
|
+
fallbackReadMs: number;
|
|
471
|
+
signal?: AbortSignal;
|
|
472
|
+
now?: () => number;
|
|
473
|
+
}): Promise<CodemodeOperation> {
|
|
474
|
+
const now = input.now ?? (() => performance.now());
|
|
475
|
+
const deadline = now() + input.budgetMs;
|
|
476
|
+
let operation = input.operation;
|
|
477
|
+
while (operation.state === "queued" || operation.state === "running") {
|
|
478
|
+
const remaining = deadline - now();
|
|
479
|
+
if (remaining <= 0 || input.signal?.aborted) break;
|
|
480
|
+
await input.wake.wait(Math.min(input.fallbackReadMs, remaining), input.signal);
|
|
481
|
+
if (input.signal?.aborted) break;
|
|
482
|
+
operation = (await input.read().catch(() => null)) ?? operation;
|
|
483
|
+
}
|
|
484
|
+
return operation;
|
|
485
|
+
}
|
|
486
|
+
|
|
294
487
|
export function codemodeOperationNeedsDispatch(operation: CodemodeOperation): boolean {
|
|
295
488
|
return operation.state === "queued" || operation.state === "running";
|
|
296
489
|
}
|
|
@@ -299,15 +492,19 @@ export async function readCodemodeOperation(
|
|
|
299
492
|
deps: ApiRouteDeps,
|
|
300
493
|
grant: AccessGrant,
|
|
301
494
|
operationId: string,
|
|
495
|
+
options: { durableApproval?: boolean } = {},
|
|
302
496
|
): Promise<CodemodeOperation | null> {
|
|
303
|
-
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
workspaceId: authority.workspaceId,
|
|
308
|
-
attemptId: authority.attemptId,
|
|
497
|
+
const { authority } = await requireActiveCodemodeCatalog(deps, grant);
|
|
498
|
+
const operation = await readTurnCodemodeOperation(deps.db, {
|
|
499
|
+
...authority,
|
|
500
|
+
callerSubjectId: authority.subjectId,
|
|
309
501
|
operationId,
|
|
310
502
|
});
|
|
503
|
+
if (operation?.state === "waiting_for_approval" && !options.durableApproval)
|
|
504
|
+
throw new CodemodeToolApprovalRequiredError();
|
|
505
|
+
if (!operation || options.durableApproval) return operation;
|
|
506
|
+
const { durableApproval: _capability, approvalRequestId: _requestId, ...legacy } = operation;
|
|
507
|
+
return legacy;
|
|
311
508
|
}
|
|
312
509
|
|
|
313
510
|
function terminal(operation: CodemodeOperation): boolean {
|
package/src/codex-realtime.ts
CHANGED
|
@@ -13,12 +13,19 @@ import {
|
|
|
13
13
|
type CodexRealtimeCallInput,
|
|
14
14
|
} from "@opengeni/codex";
|
|
15
15
|
import {
|
|
16
|
-
|
|
16
|
+
acquireSubscriptionCoreCodexOperationLease,
|
|
17
|
+
buildSubscriptionCoreCodexConnectionTokenResolver,
|
|
18
|
+
buildSubscriptionCoreCodexOperationFetch,
|
|
19
|
+
listSubscriptionCoreCodexOperationCandidates,
|
|
20
|
+
readCodexCutoverDisposition,
|
|
21
|
+
readSubscriptionCoreSessionOwner,
|
|
22
|
+
releaseSubscriptionCoreCodexOperationLease,
|
|
23
|
+
renewSubscriptionCoreCodexOperationLease,
|
|
24
|
+
subscriptionCoreCodexPlanHasVoice,
|
|
25
|
+
type SubscriptionCoreCodexOperationLeaseRef,
|
|
26
|
+
type SubscriptionCoreCodexOperationScope,
|
|
17
27
|
getActiveSessionHistoryItems,
|
|
18
|
-
getCodexCredentialStatus,
|
|
19
28
|
getSessionRealtimeContinuityEntries,
|
|
20
|
-
getSessionCodexState,
|
|
21
|
-
listCodexAccountStatuses,
|
|
22
29
|
type Database,
|
|
23
30
|
} from "@opengeni/db";
|
|
24
31
|
import { projectSessionRealtimeInitialItems } from "./session-realtime-context";
|
|
@@ -59,6 +66,13 @@ export type CodexRealtimeBrokerDependencies = {
|
|
|
59
66
|
pinnedCredentialId: string | null;
|
|
60
67
|
activeCredentialId: string | null;
|
|
61
68
|
connectedCredentialIds: ReadonlySet<string>;
|
|
69
|
+
/**
|
|
70
|
+
* Connected credentials on a ChatGPT plan without voice (Free): the
|
|
71
|
+
* provider answers their realtime calls with 404.
|
|
72
|
+
*/
|
|
73
|
+
voicelessCredentialIds?: ReadonlySet<string>;
|
|
74
|
+
/** Connected credentials open to new allocations whose plan has voice, in pool order. */
|
|
75
|
+
voiceCredentialIds?: readonly string[];
|
|
62
76
|
}>;
|
|
63
77
|
loadInitialItems(): Promise<CodexRealtimeInitialItem[]>;
|
|
64
78
|
tokenResolver(credentialId: string): CodexTokenResolver;
|
|
@@ -104,12 +118,14 @@ The initial conversation items are authoritative context from the current sessio
|
|
|
104
118
|
|
|
105
119
|
Live context wrapped in <session_user_message> is an authoritative user message already routed to the current session. A status of queued_for_execution means it is waiting behind existing work; accepted_for_execution means it is next with no existing work ahead; accepted_for_steering means it was given priority as a change of direction, while any prior work may still be yielding. Incorporate it immediately as conversation context, but never delegate it again or treat the wrapper metadata as user-authored text.
|
|
106
120
|
|
|
107
|
-
Live context wrapped in <session_human_input_request> means current work is paused for the user's answer. Preserve the exact question meaning and options. Ask one question at a time when useful. The user may answer in the visible form or answer conversationally. If the user answers conversationally, create exactly one delegation containing the relevant question and the user's answer so the session agent can continue with complete context. If the user changes direction instead, delegate the new direction normally. Do not claim work resumed until session context confirms it.
|
|
121
|
+
Live context wrapped in <session_human_input_request> means current work is paused for the user's answer. Preserve the exact question meaning and options. Ask one question at a time when useful. The user may answer in the visible form or answer conversationally. If the user answers conversationally, create exactly one delegation containing the relevant question and the user's answer so the session agent can continue with complete context. If the user changes direction instead, delegate the new direction normally. Do not claim work resumed until session context confirms it. A secret question (a password, key or code) is answered only in the app: say "answer it in the app", never ask for the secret aloud, and never delegate a spoken secret.
|
|
108
122
|
|
|
109
123
|
Live context wrapped in <session_human_input_response> is the authoritative outcome of that pending question. An answered or skipped response came through the structured session UI and is already routed; incorporate it, never delegate it again, and acknowledge briefly only if useful. An expired or cancelled response means the question is no longer active.
|
|
110
124
|
|
|
111
125
|
Live session updates may describe work that started before this realtime conversation, work sent directly by the user, or work delegated during an earlier realtime connection. Treat those updates as part of this same session even when they have no current delegation identity.
|
|
112
126
|
|
|
127
|
+
For requests about another session, use the backend to find, select, inspect or act on it while staying in this conversation. Selecting a session alone does not authorize changing its work.
|
|
128
|
+
|
|
113
129
|
## Backend use
|
|
114
130
|
|
|
115
131
|
For actions or tasks, always use the backend. If it is unclear whether backend use would help, use it.
|
|
@@ -189,11 +205,17 @@ export async function brokerSessionCodexRealtime(
|
|
|
189
205
|
);
|
|
190
206
|
}
|
|
191
207
|
const selection = await deps.loadSelection();
|
|
192
|
-
const
|
|
208
|
+
const selected = selectCodexCredentialId({
|
|
193
209
|
sessionPinnedCredentialId: selection.pinnedCredentialId,
|
|
194
210
|
activeCredentialId: selection.activeCredentialId,
|
|
195
211
|
connectedIds: selection.connectedCredentialIds,
|
|
196
212
|
});
|
|
213
|
+
// A turn may run on a plan without voice; a call then takes another
|
|
214
|
+
// connected subscription that has it, when there is one.
|
|
215
|
+
const credentialId =
|
|
216
|
+
selected && selection.voicelessCredentialIds?.has(selected)
|
|
217
|
+
? (selection.voiceCredentialIds?.[0] ?? selected)
|
|
218
|
+
: selected;
|
|
197
219
|
if (!credentialId) {
|
|
198
220
|
throw new CodexRealtimeBrokerError(
|
|
199
221
|
"credential_unavailable",
|
|
@@ -253,59 +275,163 @@ export async function brokerSessionCodexRealtime(
|
|
|
253
275
|
}
|
|
254
276
|
}
|
|
255
277
|
|
|
256
|
-
|
|
257
|
-
export function buildSessionCodexRealtimeBroker(
|
|
278
|
+
async function loadRealtimeInitialItems(
|
|
258
279
|
db: Database,
|
|
259
|
-
settings: Settings,
|
|
260
280
|
workspaceId: string,
|
|
261
281
|
sessionId: string,
|
|
282
|
+
): Promise<CodexRealtimeInitialItem[]> {
|
|
283
|
+
const [history, continuity] = await Promise.all([
|
|
284
|
+
getActiveSessionHistoryItems(db, workspaceId, sessionId),
|
|
285
|
+
getSessionRealtimeContinuityEntries(db, workspaceId, sessionId),
|
|
286
|
+
]);
|
|
287
|
+
return projectSessionRealtimeInitialItems(history, continuity);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
async function createRealtimeCall(
|
|
291
|
+
fetchImpl: CodexFetch,
|
|
292
|
+
auth: CodexAuthHeaders,
|
|
293
|
+
callInput: CodexRealtimeCallInput,
|
|
294
|
+
options: { signal?: AbortSignal | undefined },
|
|
295
|
+
): Promise<CodexRealtimeProviderAnswer> {
|
|
296
|
+
const providerConfig = await fetchCodexRealtimeProviderConfig(auth, fetchImpl, options);
|
|
297
|
+
return await createCodexRealtimeCall(auth, callInput, fetchImpl, {
|
|
298
|
+
...options,
|
|
299
|
+
providerConfig,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Codex realtime on the shared subscription core (M3 PR 2c, EP-N05..N07):
|
|
305
|
+
* each call resolves the session's recorded owner, places one shared
|
|
306
|
+
* organization- or workspace-scoped connection (the session's explicit
|
|
307
|
+
* choice first, then the effective primary, preferring a plan with voice),
|
|
308
|
+
* and holds its own `realtime` operation lease (session-bound, no turn)
|
|
309
|
+
* through negotiation, with refresh under the per-connection lock. The chat
|
|
310
|
+
* binding is never written; the client protocol and HTTP error translation
|
|
311
|
+
* are the legacy broker's.
|
|
312
|
+
*/
|
|
313
|
+
export async function brokerSessionCoreCodexRealtime(
|
|
314
|
+
db: Database,
|
|
315
|
+
settings: Settings,
|
|
316
|
+
context: { accountId: string; workspaceId: string; sessionId: string },
|
|
317
|
+
input: Omit<CodexRealtimeBrokerInput, "sessionId">,
|
|
262
318
|
fetchImpl: CodexFetch = fetch,
|
|
263
|
-
):
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
319
|
+
): Promise<CodexRealtimeProviderAnswer> {
|
|
320
|
+
if (!settings.codexSubscriptionEnabled) {
|
|
321
|
+
throw new CodexRealtimeBrokerError(
|
|
322
|
+
"subscription_disabled",
|
|
323
|
+
"Connected Codex subscription realtime is disabled",
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
const owner = await readSubscriptionCoreSessionOwner(db, context);
|
|
327
|
+
if (!owner) {
|
|
328
|
+
throw new CodexRealtimeBrokerError(
|
|
329
|
+
"credential_unavailable",
|
|
330
|
+
"Session is unavailable for Codex realtime",
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
const scope: SubscriptionCoreCodexOperationScope = {
|
|
334
|
+
kind: "session",
|
|
335
|
+
...context,
|
|
336
|
+
sessionOwnerSubjectId: owner.ownerSubjectId,
|
|
337
|
+
};
|
|
338
|
+
const candidates = await listSubscriptionCoreCodexOperationCandidates(db, scope);
|
|
339
|
+
// A turn may run on a plan without voice; a call takes a connection that
|
|
340
|
+
// has it whenever one exists (legacy parity).
|
|
341
|
+
const ordered = [
|
|
342
|
+
...candidates.filter((candidate) => subscriptionCoreCodexPlanHasVoice(candidate.planType)),
|
|
343
|
+
...candidates.filter((candidate) => !subscriptionCoreCodexPlanHasVoice(candidate.planType)),
|
|
344
|
+
];
|
|
345
|
+
const operationId = crypto.randomUUID();
|
|
346
|
+
const attemptId = crypto.randomUUID();
|
|
347
|
+
for (const candidate of ordered) {
|
|
348
|
+
const ref: SubscriptionCoreCodexOperationLeaseRef = {
|
|
349
|
+
operationId,
|
|
350
|
+
attemptId,
|
|
351
|
+
operationKind: "realtime",
|
|
352
|
+
connectionId: candidate.connectionId,
|
|
353
|
+
holderId: `realtime:${context.sessionId}`,
|
|
354
|
+
generation: 1,
|
|
355
|
+
};
|
|
356
|
+
const lease = await acquireSubscriptionCoreCodexOperationLease(db, scope, ref);
|
|
357
|
+
if (lease.kind !== "acquired") continue;
|
|
358
|
+
try {
|
|
359
|
+
const resolver = buildSubscriptionCoreCodexConnectionTokenResolver(
|
|
360
|
+
db,
|
|
361
|
+
settings,
|
|
362
|
+
scope,
|
|
363
|
+
candidate.connectionId,
|
|
364
|
+
ref,
|
|
365
|
+
);
|
|
366
|
+
// Configuration and call creation are separate physical requests, as
|
|
367
|
+
// are both requests of the single authentication-only retry.
|
|
368
|
+
const requestFetch = buildSubscriptionCoreCodexOperationFetch(
|
|
369
|
+
db,
|
|
370
|
+
scope,
|
|
371
|
+
ref,
|
|
372
|
+
candidate.connectionId,
|
|
373
|
+
fetchImpl,
|
|
374
|
+
);
|
|
375
|
+
return await brokerSessionCodexRealtime(
|
|
376
|
+
{
|
|
377
|
+
enabled: true,
|
|
378
|
+
loadSelection: async () => ({
|
|
379
|
+
pinnedCredentialId: null,
|
|
380
|
+
activeCredentialId: candidate.connectionId,
|
|
381
|
+
connectedCredentialIds: new Set([candidate.connectionId]),
|
|
382
|
+
}),
|
|
383
|
+
loadInitialItems: () =>
|
|
384
|
+
loadRealtimeInitialItems(db, context.workspaceId, context.sessionId),
|
|
385
|
+
tokenResolver: () => resolver,
|
|
386
|
+
createCall: async (auth, callInput, options) => {
|
|
387
|
+
// Pre-dispatch fence on the exact operation lease.
|
|
388
|
+
if (!(await renewSubscriptionCoreCodexOperationLease(db, scope, ref))) {
|
|
389
|
+
throw new CodexRealtimeBrokerError(
|
|
390
|
+
"credential_unavailable",
|
|
391
|
+
"Codex subscription credential is unavailable",
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
return await createRealtimeCall(requestFetch, auth, callInput, options);
|
|
395
|
+
},
|
|
305
396
|
},
|
|
306
|
-
|
|
307
|
-
|
|
397
|
+
{ ...input, sessionId: context.sessionId },
|
|
398
|
+
);
|
|
399
|
+
} finally {
|
|
400
|
+
await releaseSubscriptionCoreCodexOperationLease(db, scope, ref).catch(() => false);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
throw new CodexRealtimeBrokerError(
|
|
404
|
+
"credential_unavailable",
|
|
405
|
+
"No connected Codex subscription is available for this session",
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/** Bind the pure broker to Opengeni's encrypted DB credential lifecycle. */
|
|
410
|
+
export function buildSessionCodexRealtimeBroker(
|
|
411
|
+
db: Database,
|
|
412
|
+
settings: Settings,
|
|
413
|
+
context: { accountId: string; workspaceId: string; sessionId: string },
|
|
414
|
+
fetchImpl: CodexFetch = fetch,
|
|
415
|
+
): (input: Omit<CodexRealtimeBrokerInput, "sessionId">) => Promise<CodexRealtimeProviderAnswer> {
|
|
416
|
+
const { accountId, workspaceId, sessionId } = context;
|
|
417
|
+
return async (input) => {
|
|
418
|
+
// The account is required: without it a disabled cutover could not fail closed.
|
|
419
|
+
const disposition = await readCodexCutoverDisposition(db, accountId, workspaceId);
|
|
420
|
+
if (disposition === "maintenance") {
|
|
421
|
+
// A disabled cutover row is maintenance: fail closed, no legacy read.
|
|
422
|
+
throw new CodexRealtimeBrokerError(
|
|
423
|
+
"subscription_disabled",
|
|
424
|
+
"Connected Codex subscription realtime is disabled",
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
return await brokerSessionCoreCodexRealtime(
|
|
428
|
+
db,
|
|
429
|
+
settings,
|
|
430
|
+
{ accountId, workspaceId, sessionId },
|
|
431
|
+
input,
|
|
432
|
+
fetchImpl,
|
|
308
433
|
);
|
|
434
|
+
};
|
|
309
435
|
}
|
|
310
436
|
|
|
311
437
|
function credentialError(error: unknown): CodexRealtimeBrokerError {
|
|
@@ -322,6 +448,8 @@ function credentialError(error: unknown): CodexRealtimeBrokerError {
|
|
|
322
448
|
}
|
|
323
449
|
|
|
324
450
|
function brokerProviderError(error: unknown): CodexRealtimeBrokerError {
|
|
451
|
+
// A core pre-dispatch fence refusal is already typed (legacy calls never raise one).
|
|
452
|
+
if (error instanceof CodexRealtimeBrokerError) return error;
|
|
325
453
|
if (!(error instanceof CodexRealtimeError)) {
|
|
326
454
|
return new CodexRealtimeBrokerError("network_error", "Codex realtime provider request failed");
|
|
327
455
|
}
|