@opengeni/api-router 3.0.1 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-grant-rls.d.ts +8 -1
- package/dist/admission-trace.d.ts +8 -0
- package/dist/app.d.ts +50 -3
- package/dist/app.js +10 -1
- package/dist/artifact-catalog-cursor.d.ts +1 -0
- package/dist/attached-browser-viewer.d.ts +11 -0
- package/dist/auth/managed-auth-attempt-context.d.ts +2 -0
- package/dist/auth/managed-auth-rate-limits.d.ts +167 -0
- package/dist/auth/managed-auth-session-adapter.d.ts +9 -1
- package/dist/auth/managed-auth.d.ts +72 -5
- package/dist/auth/managed-sign-in-notifications.d.ts +4 -0
- package/dist/auth/new-signups-gate.d.ts +23 -0
- package/dist/auth/signup-funnel-metrics.d.ts +44 -0
- package/dist/azure-live.d.ts +28 -0
- package/dist/browser-action-fences.d.ts +13 -0
- package/dist/browser-controller-authority.d.ts +1 -61
- package/dist/browser-ephemeral.d.ts +5 -0
- package/dist/browser-lost-runtime-end.d.ts +24 -0
- package/dist/browser-state-authority.d.ts +1 -27
- package/dist/chunk-OGQDXVXY.js +18 -0
- package/dist/chunk-OGQDXVXY.js.map +1 -0
- package/dist/{chunk-AJ62T5QN.js → chunk-OT56OY4V.js} +80503 -39869
- package/dist/chunk-OT56OY4V.js.map +1 -0
- package/dist/claude-default-models.d.ts +19 -0
- package/dist/claude-subscription-core.d.ts +50 -0
- package/dist/claude-subscription-oauth.d.ts +36 -0
- package/dist/claude-subscription-profile.d.ts +9 -0
- package/dist/claude-subscription-usage.d.ts +6 -0
- package/dist/claude-workspace-connection.d.ts +15 -0
- package/dist/codemode.d.ts +40 -5
- package/dist/codex-realtime.d.ts +29 -3
- package/dist/codex-session-pointers.d.ts +19 -0
- package/dist/connection-ownership.d.ts +6 -3
- package/dist/controller-data-plane.d.ts +16 -0
- package/dist/credit-promotion-snapshot.d.ts +6 -0
- package/dist/editable-artifact-source-session.d.ts +3 -0
- package/dist/editable-artifact-websocket.d.ts +5 -3
- package/dist/fatal-process-boundary.d.ts +9 -1
- package/dist/github-access.d.ts +7 -1
- package/dist/github-browser-flow.d.ts +1 -1
- package/dist/http/acting-person.d.ts +36 -0
- package/dist/http/api-contract-compat.d.ts +19 -0
- package/dist/http/api-error.d.ts +50 -1
- package/dist/http/auth.d.ts +8 -1
- package/dist/http/cors.d.ts +12 -0
- package/dist/http/deprecation.d.ts +42 -0
- package/dist/http/keyed-admission.d.ts +12 -0
- package/dist/http/local-browser-boundary.d.ts +72 -0
- package/dist/http/metrics-listener.d.ts +22 -0
- package/dist/http/path-identifier.d.ts +17 -0
- package/dist/http/registered-route-label.d.ts +16 -0
- package/dist/http/rejection-telemetry.d.ts +34 -0
- package/dist/http/request-body.d.ts +27 -0
- package/dist/http/request-source.d.ts +41 -3
- package/dist/http/sse.d.ts +12 -1
- package/dist/http/unmatched-route.d.ts +18 -0
- package/dist/http/user-content.d.ts +36 -0
- package/dist/http/variable-sets-removed.d.ts +41 -0
- package/dist/http/websocket-upgrade-dispatch.d.ts +18 -0
- package/dist/index.js +1279 -108
- package/dist/index.js.map +1 -1
- package/dist/integration-connect-metrics.d.ts +35 -0
- package/dist/integration-endpoint-test.d.ts +20 -0
- package/dist/integrations/api-integrations.d.ts +2 -2
- package/dist/integrations/atlassian.d.ts +8 -3
- package/dist/integrations/fiken.d.ts +3 -1
- package/dist/integrations/github-lens-connect.d.ts +37 -66
- package/dist/integrations/google-drive.d.ts +2 -0
- package/dist/integrations/integration-commit-authority.d.ts +13 -0
- package/dist/integrations/marketplace-plugin.d.ts +43 -43
- package/dist/integrations/oauth-client.d.ts +171 -12
- package/dist/integrations/oauth-profiles.d.ts +42 -13
- package/dist/integrations/onepassword-vault-provider.d.ts +9 -0
- package/dist/integrations/slack-bot.d.ts +285 -7
- package/dist/integrations/slack-file-upload-flow.d.ts +62 -0
- package/dist/integrations/slack-interactions.d.ts +89 -10
- package/dist/integrations/slack-mrkdwn.d.ts +41 -0
- package/dist/integrations/slack-routing.d.ts +1 -1
- package/dist/integrations/slack-session-defaults.d.ts +58 -0
- package/dist/integrations/slack-task-file-upload.d.ts +36 -0
- package/dist/integrations/slack-tool-review.d.ts +5 -0
- package/dist/interaction-agent-access.d.ts +13 -8
- package/dist/interaction-agent-version.d.ts +21 -0
- package/dist/interaction-holder-heartbeat.d.ts +5 -0
- package/dist/interaction-metrics.d.ts +27 -2
- package/dist/interaction-route-stages.d.ts +25 -0
- package/dist/interaction-secrets-vault.d.ts +20 -0
- package/dist/interaction-secrets.d.ts +103 -0
- package/dist/mcp/action-catalog-types.d.ts +14 -0
- package/dist/mcp/action-catalog.gen.d.ts +2 -0
- package/dist/mcp/action-descriptions.d.ts +4 -0
- package/dist/mcp/action-schema-imports.gen.d.ts +1 -0
- package/dist/mcp/capability-account-readiness.d.ts +7 -0
- package/dist/mcp/child-read-evidence.d.ts +9 -0
- package/dist/mcp/company-profile-agent-admin.d.ts +12 -0
- package/dist/mcp/contract-input.d.ts +13 -0
- package/dist/mcp/documents.d.ts +2 -0
- package/dist/mcp/first-party-tool-permissions.d.ts +3 -606
- package/dist/mcp/notification-tools.d.ts +26 -0
- package/dist/mcp/orchestration-failure-diagnostic.d.ts +43 -0
- package/dist/mcp/scheduled-task-input.d.ts +1309 -0
- package/dist/mcp/scheduled-task-view.d.ts +217 -3
- package/dist/mcp/secret-tools.d.ts +14 -0
- package/dist/mcp/server.d.ts +108 -5
- package/dist/mcp/session-admin-access-tools.d.ts +33 -0
- package/dist/mcp/session-event-errors.d.ts +28 -0
- package/dist/mcp/session-event-view.d.ts +62 -0
- package/dist/mcp/session-view.d.ts +15 -0
- package/dist/mcp/session-wait.d.ts +18 -0
- package/dist/mcp/site-agent-clamp-tools.d.ts +38 -0
- package/dist/mcp/site-data-tools.d.ts +22 -0
- package/dist/mcp/site-publication-tools.d.ts +19 -0
- package/dist/mcp/site-sql-tools.d.ts +27 -0
- package/dist/mcp-oauth.d.ts +37 -4
- package/dist/model-calls/chat-completions.d.ts +87 -0
- package/dist/model-calls/pending-usage-settlements.d.ts +57 -0
- package/dist/model-calls/service.d.ts +36 -0
- package/dist/model-catalog.d.ts +9 -3
- package/dist/native-push-dispatch.d.ts +69 -0
- package/dist/observability.d.ts +3 -1
- package/dist/organization-mcp.d.ts +82 -0
- package/dist/prepared-mcp-actor.d.ts +77 -0
- package/dist/prepared-mcp-permissions.d.ts +8 -0
- package/dist/routes/analytics-consent.d.ts +26 -0
- package/dist/routes/api-integrations.d.ts +11 -0
- package/dist/routes/api-keys.d.ts +7 -7
- package/dist/routes/automations.d.ts +2 -0
- package/dist/routes/billing.d.ts +59 -0
- package/dist/routes/browser-sessions.d.ts +65 -2
- package/dist/routes/chat-completions.d.ts +11 -0
- package/dist/routes/claude-core-usage.d.ts +20 -0
- package/dist/routes/claude-subscription-accounts.d.ts +3 -0
- package/dist/routes/claude-subscription-oauth.d.ts +3 -0
- package/dist/routes/client-errors.d.ts +182 -0
- package/dist/routes/codex-core.d.ts +401 -0
- package/dist/routes/codex.d.ts +64 -2
- package/dist/routes/computer-sessions.d.ts +6 -1
- package/dist/routes/desktop-distribution.d.ts +32 -0
- package/dist/routes/github-browser-fonts.gen.d.ts +2 -0
- package/dist/routes/github-browser-pages.d.ts +27 -0
- package/dist/routes/inbox.d.ts +13 -0
- package/dist/routes/insights-response-cache.d.ts +10 -0
- package/dist/routes/insights-usage.d.ts +12 -0
- package/dist/routes/insights.d.ts +28 -0
- package/dist/routes/interaction-placement-message.d.ts +7 -0
- package/dist/routes/managed-sign-in-methods.d.ts +6 -0
- package/dist/routes/model-account-choice.d.ts +13 -0
- package/dist/routes/model-account-settings.d.ts +19 -0
- package/dist/routes/native-app-auth.d.ts +12 -0
- package/dist/routes/organization-integration-policy.d.ts +8 -0
- package/dist/routes/organization-integrations.d.ts +6 -0
- package/dist/routes/organization-mcp-connections.d.ts +3 -0
- package/dist/routes/organization-model-defaults.d.ts +9 -0
- package/dist/routes/organization-service-accounts.d.ts +3 -0
- package/dist/routes/personal-api-keys.d.ts +3 -0
- package/dist/routes/session-admin-access.d.ts +3 -0
- package/dist/routes/session-artifact-associations.d.ts +4 -0
- package/dist/routes/session-history-imports.d.ts +20 -0
- package/dist/routes/sessions.d.ts +38 -2
- package/dist/routes/site-data.d.ts +18 -0
- package/dist/routes/site-publishing.d.ts +5 -0
- package/dist/routes/site-runtime.d.ts +31 -0
- package/dist/routes/site-sql.d.ts +16 -0
- package/dist/routes/slack-bot-access.d.ts +3 -0
- package/dist/routes/subscription-account-pools.d.ts +21 -0
- package/dist/routes/subscription-core-http.d.ts +5 -0
- package/dist/routes/subscription-pool-access.d.ts +37 -0
- package/dist/routes/subscription-pool-core.d.ts +153 -0
- package/dist/routes/supergrok.d.ts +6 -6
- package/dist/routes/usage-allowances.d.ts +12 -0
- package/dist/routes/variable-sets-removed.d.ts +2 -0
- package/dist/routes/vault-providers.d.ts +34 -0
- package/dist/routes/vaults.d.ts +3 -0
- package/dist/routes/workspace-integrations.d.ts +35 -0
- package/dist/routes/workspace-model-providers.d.ts +4 -0
- package/dist/routes/workspaces.d.ts +11 -2
- package/dist/sandbox/agent-update.d.ts +64 -0
- package/dist/sandbox/auth-callout.d.ts +8 -0
- package/dist/sandbox/channel-a.d.ts +15 -1
- package/dist/sandbox/enrollment.d.ts +26 -4
- package/dist/sandbox/machine-audience.d.ts +29 -0
- package/dist/sandbox/machines.d.ts +15 -2
- package/dist/sandbox/metrics-ingestion.d.ts +6 -2
- package/dist/sandbox/screen-control.d.ts +85 -0
- package/dist/sandbox/viewer.d.ts +5 -1
- package/dist/sandbox-file-artifacts.d.ts +17 -1
- package/dist/scheduled-task-blockers.d.ts +39 -0
- package/dist/scheduled-task-deletion.d.ts +3 -4
- package/dist/scheduled-task-lifecycle.d.ts +14 -0
- package/dist/secret-answers.d.ts +40 -0
- package/dist/session-create-observability.d.ts +5 -0
- package/dist/session-event-view-36GO3IL7.js +528 -0
- package/dist/session-event-view-36GO3IL7.js.map +1 -0
- package/dist/signed-state-secret.d.ts +18 -0
- package/dist/site-agent-guard.d.ts +53 -0
- package/dist/site-data/operations.d.ts +103 -0
- package/dist/site-data/service.d.ts +203 -0
- package/dist/site-frame-guard.d.ts +32 -0
- package/dist/site-publishing/agent-data-tools.d.ts +84 -0
- package/dist/site-publishing/agent-model.d.ts +58 -0
- package/dist/site-publishing/agent-session.d.ts +16 -0
- package/dist/site-publishing/content-scanner.d.ts +31 -0
- package/dist/site-publishing/edge-sync.d.ts +48 -0
- package/dist/site-publishing/gateway-signature.d.ts +56 -0
- package/dist/site-publishing/limits.d.ts +63 -0
- package/dist/site-publishing/page-tool-authority.d.ts +30 -0
- package/dist/site-publishing/platform-usage.d.ts +113 -0
- package/dist/site-publishing/platform.d.ts +21 -0
- package/dist/site-publishing/readiness.d.ts +62 -0
- package/dist/site-publishing/runtime.d.ts +179 -0
- package/dist/site-publishing/service.d.ts +264 -0
- package/dist/site-publishing/session-events.d.ts +22 -0
- package/dist/site-publishing/session-views.d.ts +36 -0
- package/dist/site-publishing/viewer.d.ts +40 -0
- package/dist/site-session-origin.d.ts +31 -6
- package/dist/site-sql/format.d.ts +47 -0
- package/dist/site-sql/gateway.d.ts +50 -0
- package/dist/site-sql/service.d.ts +213 -0
- package/dist/temporal-schedule-sync.d.ts +26 -0
- package/dist/transcription/billing-refusal.d.ts +8 -0
- package/dist/transcription/normalize.d.ts +23 -0
- package/dist/transcription/providers/azure-mai.d.ts +12 -0
- package/dist/transcription/providers/azure-openai.d.ts +4 -0
- package/dist/transcription/providers/openai.d.ts +16 -0
- package/dist/transcription/providers/subscription-core.d.ts +39 -0
- package/dist/transcription/service.d.ts +10 -1
- package/dist/transcription/wav-duration.d.ts +8 -0
- package/dist/workspace-tool-gateway-attestations.d.ts +37 -0
- package/dist/workspace-tool-gateway-observability.d.ts +16 -0
- package/dist/workspace-tool-gateway-secrets.d.ts +27 -0
- package/dist/workspace-tool-gateway.d.ts +102 -6
- package/dist/workspace-tool-target-fence.d.ts +116 -0
- package/dist/workspace-tool-target.d.ts +225 -0
- package/dist/workspace-webhook-dispatch.d.ts +26 -0
- package/dist/xai-subscription-core.d.ts +60 -0
- package/package.json +25 -20
- package/src/access-grant-rls.ts +64 -14
- package/src/admission-trace.ts +14 -0
- package/src/app.ts +1684 -252
- package/src/artifact-catalog-cursor.ts +1 -0
- package/src/attached-browser-viewer.ts +26 -0
- package/src/auth/managed-auth-attempt-context.ts +9 -0
- package/src/auth/managed-auth-rate-limits.ts +252 -0
- package/src/auth/managed-auth-session-adapter.ts +64 -29
- package/src/auth/managed-auth.ts +303 -35
- package/src/auth/managed-email.ts +18 -1
- package/src/auth/managed-sign-in-notifications.ts +81 -0
- package/src/auth/new-signups-gate.ts +49 -0
- package/src/auth/organization-user-setup.ts +3 -3
- package/src/auth/signup-funnel-metrics.ts +164 -0
- package/src/azure-live.ts +103 -0
- package/src/browser-action-fences.ts +45 -0
- package/src/browser-controller-authority.ts +1 -186
- package/src/browser-ephemeral.ts +39 -0
- package/src/browser-lost-runtime-end.ts +71 -0
- package/src/browser-state-authority.ts +1 -236
- package/src/claude-default-models.ts +37 -0
- package/src/claude-subscription-core.ts +154 -0
- package/src/claude-subscription-oauth.ts +352 -0
- package/src/claude-subscription-profile.ts +73 -0
- package/src/claude-subscription-usage.ts +51 -0
- package/src/claude-workspace-connection.ts +82 -0
- package/src/codemode.ts +236 -39
- package/src/codex-realtime.ts +181 -53
- package/src/codex-session-pointers.ts +80 -0
- package/src/company-brain-okf.ts +1 -1
- package/src/connected-machine-computer-access.ts +2 -1
- package/src/connection-ownership.ts +19 -13
- package/src/controller-data-plane.ts +34 -0
- package/src/credit-promotion-snapshot.ts +36 -0
- package/src/editable-artifact-production.ts +10 -0
- package/src/editable-artifact-source-session.ts +123 -0
- package/src/editable-artifact-websocket.ts +16 -3
- package/src/fatal-process-boundary.ts +67 -3
- package/src/gateway-realtime.ts +12 -8
- package/src/github-access.ts +31 -5
- package/src/github-browser-flow.ts +1 -1
- package/src/http/acting-person.ts +105 -0
- package/src/http/api-contract-compat.ts +49 -0
- package/src/http/api-error.ts +210 -2
- package/src/http/auth.ts +68 -4
- package/src/http/cors.ts +37 -5
- package/src/http/deprecation.ts +118 -0
- package/src/http/keyed-admission.ts +29 -0
- package/src/http/local-browser-boundary.ts +343 -0
- package/src/http/metrics-listener.ts +57 -0
- package/src/http/path-identifier.ts +54 -0
- package/src/http/registered-route-label.ts +34 -0
- package/src/http/rejection-telemetry.ts +120 -0
- package/src/http/request-body.ts +127 -0
- package/src/http/request-source.ts +154 -13
- package/src/http/sse.ts +88 -28
- package/src/http/unmatched-route.ts +60 -0
- package/src/http/user-content.ts +158 -0
- package/src/http/variable-sets-removed.ts +122 -0
- package/src/http/websocket-upgrade-dispatch.ts +29 -0
- package/src/index.ts +107 -57
- package/src/integration-connect-metrics.ts +228 -0
- package/src/integration-endpoint-test.ts +291 -0
- package/src/integrations/api-integrations.ts +81 -7
- package/src/integrations/atlassian.ts +202 -83
- package/src/integrations/fiken.ts +66 -38
- package/src/integrations/github-app-connect.ts +64 -18
- package/src/integrations/github-lens-connect.ts +8 -29
- package/src/integrations/google-drive.ts +448 -152
- package/src/integrations/integration-commit-authority.ts +69 -0
- package/src/integrations/marketplace-plugin.ts +1 -1
- package/src/integrations/oauth-client.ts +733 -193
- package/src/integrations/oauth-profiles.ts +116 -45
- package/src/integrations/onepassword-vault-provider.ts +16 -0
- package/src/integrations/personal-github-repositories.ts +1 -1
- package/src/integrations/personal-github.ts +61 -35
- package/src/integrations/provider-oauth.ts +67 -85
- package/src/integrations/slack-app-home.ts +5 -5
- package/src/integrations/slack-bot.ts +893 -201
- package/src/integrations/slack-file-upload-flow.ts +147 -0
- package/src/integrations/slack-install.ts +7 -7
- package/src/integrations/slack-interactions.ts +1589 -299
- package/src/integrations/slack-mrkdwn.ts +193 -0
- package/src/integrations/slack-routing.ts +2 -2
- package/src/integrations/slack-session-defaults.ts +224 -0
- package/src/integrations/slack-task-file-upload.ts +323 -0
- package/src/integrations/slack-tool-review.ts +65 -0
- package/src/integrations/social-oauth.ts +90 -58
- package/src/interaction-agent-access.ts +40 -20
- package/src/interaction-agent-version.ts +85 -0
- package/src/interaction-holder-heartbeat.ts +24 -8
- package/src/interaction-metrics.ts +164 -2
- package/src/interaction-route-stages.ts +94 -0
- package/src/interaction-secrets-vault.ts +213 -0
- package/src/interaction-secrets.ts +426 -0
- package/src/mcp/action-catalog-types.ts +14 -0
- package/src/mcp/action-catalog.gen.ts +8014 -0
- package/src/mcp/action-descriptions.ts +299 -0
- package/src/mcp/action-schema-imports.gen.ts +304 -0
- package/src/mcp/capability-account-readiness.ts +17 -0
- package/src/mcp/child-read-evidence.ts +19 -0
- package/src/mcp/company-profile-agent-admin.ts +13 -0
- package/src/mcp/contract-input.ts +165 -0
- package/src/mcp/documents.ts +9 -2
- package/src/mcp/editable-artifacts.ts +29 -11
- package/src/mcp/files.ts +5 -1
- package/src/mcp/first-party-tool-permissions.ts +7 -285
- package/src/mcp/knowledge-entries.ts +108 -34
- package/src/mcp/notification-tools.ts +480 -0
- package/src/mcp/orchestration-failure-diagnostic.ts +43 -0
- package/src/mcp/scheduled-task-input.ts +89 -0
- package/src/mcp/scheduled-task-view.ts +63 -3
- package/src/mcp/secret-tools.ts +185 -0
- package/src/mcp/server.ts +2213 -1116
- package/src/mcp/session-admin-access-tools.ts +163 -0
- package/src/mcp/session-event-errors.ts +123 -0
- package/src/mcp/session-event-view.ts +395 -13
- package/src/mcp/session-view.ts +3 -0
- package/src/mcp/session-wait.ts +67 -7
- package/src/mcp/site-agent-clamp-tools.ts +140 -0
- package/src/mcp/site-data-tools.ts +339 -0
- package/src/mcp/site-publication-tools.ts +201 -0
- package/src/mcp/site-sql-tools.ts +427 -0
- package/src/mcp-oauth.ts +635 -45
- package/src/model-calls/chat-completions.ts +352 -0
- package/src/model-calls/pending-usage-settlements.ts +125 -0
- package/src/model-calls/service.ts +694 -0
- package/src/model-catalog.ts +68 -17
- package/src/native-push-dispatch.ts +457 -0
- package/src/observability.ts +15 -1
- package/src/organization-mcp.ts +485 -0
- package/src/prepared-mcp-actor.ts +154 -0
- package/src/prepared-mcp-permissions.ts +38 -0
- package/src/routes/analytics-consent.ts +123 -0
- package/src/routes/api-integrations.ts +268 -9
- package/src/routes/api-keys.ts +164 -25
- package/src/routes/artifact-catalog.ts +111 -0
- package/src/routes/automations.ts +163 -90
- package/src/routes/billing.ts +535 -59
- package/src/routes/browser-sessions.ts +966 -342
- package/src/routes/canonical-human-identities.ts +61 -0
- package/src/routes/capabilities.ts +112 -5
- package/src/routes/channels.ts +4 -3
- package/src/routes/chat-completions.ts +235 -0
- package/src/routes/claude-core-usage.ts +147 -0
- package/src/routes/claude-subscription-accounts.ts +233 -0
- package/src/routes/claude-subscription-oauth.ts +175 -0
- package/src/routes/client-errors.ts +394 -0
- package/src/routes/codex-core.ts +687 -0
- package/src/routes/codex.ts +1277 -1119
- package/src/routes/company-brain.ts +4 -0
- package/src/routes/computer-sessions.ts +319 -85
- package/src/routes/connect.ts +277 -175
- package/src/routes/connections.ts +690 -363
- package/src/routes/desktop-distribution.ts +217 -0
- package/src/routes/documents.ts +13 -7
- package/src/routes/editable-artifacts.ts +74 -4
- package/src/routes/enrollments.ts +110 -16
- package/src/routes/external-identity-links.ts +13 -12
- package/src/routes/files.ts +41 -16
- package/src/routes/github-browser-fonts.gen.ts +12 -0
- package/src/routes/github-browser-pages.ts +258 -0
- package/src/routes/github.ts +200 -75
- package/src/routes/inbox.ts +353 -0
- package/src/routes/insights-response-cache.ts +83 -0
- package/src/routes/insights-usage.ts +345 -0
- package/src/routes/insights.ts +103 -8
- package/src/routes/install.ts +51 -10
- package/src/routes/integration-facets.ts +70 -28
- package/src/routes/interaction-placement-message.ts +12 -0
- package/src/routes/knowledge.ts +136 -27
- package/src/routes/machines.ts +189 -135
- package/src/routes/managed-auth-session-sets.ts +43 -10
- package/src/routes/managed-onboarding.ts +39 -19
- package/src/routes/managed-sign-in-methods.ts +433 -0
- package/src/routes/memory-slack-publications.ts +3 -2
- package/src/routes/model-account-choice.ts +194 -0
- package/src/routes/model-account-settings.ts +235 -0
- package/src/routes/model-connection-access.ts +210 -48
- package/src/routes/native-app-auth.ts +296 -0
- package/src/routes/organization-integration-policy.ts +116 -0
- package/src/routes/organization-integrations.ts +326 -0
- package/src/routes/organization-mcp-connections.ts +183 -0
- package/src/routes/organization-memberships.ts +205 -19
- package/src/routes/organization-model-defaults.ts +110 -0
- package/src/routes/organization-model-providers.ts +74 -3
- package/src/routes/organization-service-accounts.ts +128 -0
- package/src/routes/organization-sessions.ts +21 -5
- package/src/routes/personal-api-keys.ts +184 -0
- package/src/routes/personal-github-git-broker.ts +2 -2
- package/src/routes/personal-github.ts +9 -4
- package/src/routes/plugins.ts +46 -7
- package/src/routes/pr-review-github.ts +105 -118
- package/src/routes/pr-review.ts +88 -82
- package/src/routes/preference-registry.ts +18 -0
- package/src/routes/rigs.ts +48 -13
- package/src/routes/scheduled-tasks.ts +347 -27
- package/src/routes/session-admin-access.ts +271 -0
- package/src/routes/session-artifact-associations.ts +164 -0
- package/src/routes/session-history-imports.ts +305 -0
- package/src/routes/sessions.ts +1682 -363
- package/src/routes/site-data.ts +340 -0
- package/src/routes/site-publishing.ts +584 -0
- package/src/routes/site-runtime.ts +1944 -0
- package/src/routes/site-sql.ts +263 -0
- package/src/routes/skill-content.ts +72 -7
- package/src/routes/skills.ts +5 -4
- package/src/routes/slack-bot-access.ts +108 -0
- package/src/routes/social.ts +27 -15
- package/src/routes/subscription-account-pools.ts +209 -0
- package/src/routes/subscription-core-http.ts +18 -0
- package/src/routes/subscription-pool-access.ts +180 -0
- package/src/routes/subscription-pool-core.ts +552 -0
- package/src/routes/supergrok.ts +174 -655
- package/src/routes/transcription-recordings.ts +71 -4
- package/src/routes/transcriptions.ts +26 -2
- package/src/routes/usage-allowances.ts +381 -0
- package/src/routes/variable-sets-removed.ts +19 -0
- package/src/routes/vault-providers.ts +782 -0
- package/src/routes/vaults.ts +421 -0
- package/src/routes/video-generation.ts +30 -12
- package/src/routes/workspace-artifacts.ts +165 -53
- package/src/routes/workspace-integrations.ts +576 -0
- package/src/routes/workspace-model-providers.ts +148 -0
- package/src/routes/workspace-state.ts +4 -0
- package/src/routes/workspaces.ts +625 -117
- package/src/sandbox/agent-update.ts +315 -0
- package/src/sandbox/auth-callout.ts +104 -21
- package/src/sandbox/channel-a.ts +165 -55
- package/src/sandbox/enrollment.ts +131 -22
- package/src/sandbox/machine-audience.ts +192 -0
- package/src/sandbox/machines.ts +75 -31
- package/src/sandbox/metrics-ingestion.ts +133 -2
- package/src/sandbox/rematerialize.ts +51 -21
- package/src/sandbox/screen-control.ts +289 -0
- package/src/sandbox/viewer.ts +33 -58
- package/src/sandbox-file-artifacts.ts +53 -27
- package/src/scheduled-task-blockers.ts +293 -0
- package/src/scheduled-task-deletion.ts +13 -3
- package/src/scheduled-task-lifecycle.ts +84 -0
- package/src/secret-answers.ts +119 -0
- package/src/session-create-observability.ts +46 -0
- package/src/session-realtime-context.ts +26 -4
- package/src/signed-state-secret.ts +58 -0
- package/src/site-agent-guard.ts +261 -0
- package/src/site-data/operations.ts +777 -0
- package/src/site-data/service.ts +1043 -0
- package/src/site-frame-guard.ts +107 -0
- package/src/site-publishing/agent-data-tools.ts +250 -0
- package/src/site-publishing/agent-model.ts +127 -0
- package/src/site-publishing/agent-session.ts +148 -0
- package/src/site-publishing/content-scanner.ts +93 -0
- package/src/site-publishing/edge-sync.ts +148 -0
- package/src/site-publishing/gateway-signature.ts +198 -0
- package/src/site-publishing/limits.ts +315 -0
- package/src/site-publishing/page-tool-authority.ts +111 -0
- package/src/site-publishing/platform-usage.ts +479 -0
- package/src/site-publishing/platform.ts +98 -0
- package/src/site-publishing/readiness.ts +330 -0
- package/src/site-publishing/runtime.ts +831 -0
- package/src/site-publishing/service.ts +1282 -0
- package/src/site-publishing/session-events.ts +262 -0
- package/src/site-publishing/session-views.ts +262 -0
- package/src/site-publishing/viewer.ts +75 -0
- package/src/site-session-origin.ts +91 -6
- package/src/site-sql/format.ts +134 -0
- package/src/site-sql/gateway.ts +168 -0
- package/src/site-sql/service.ts +1636 -0
- package/src/site-uploads.ts +27 -5
- package/src/temporal-schedule-sync.ts +74 -0
- package/src/transcription/billing-refusal.ts +14 -0
- package/src/transcription/normalize.ts +77 -0
- package/src/transcription/providers/azure-mai.ts +98 -0
- package/src/transcription/providers/azure-openai.ts +16 -7
- package/src/transcription/providers/codex-subscription.ts +190 -67
- package/src/transcription/providers/openai.ts +79 -5
- package/src/transcription/providers/subscription-core.ts +125 -0
- package/src/transcription/providers/xai-subscription.ts +81 -83
- package/src/transcription/segmenter.ts +7 -1
- package/src/transcription/service.ts +239 -10
- package/src/transcription/wav-duration.ts +39 -0
- package/src/workspace-deletion.ts +25 -1
- package/src/workspace-tool-gateway-attestations.ts +133 -0
- package/src/workspace-tool-gateway-observability.ts +64 -0
- package/src/workspace-tool-gateway-secrets.ts +104 -0
- package/src/workspace-tool-gateway.ts +921 -103
- package/src/workspace-tool-target-fence.ts +380 -0
- package/src/workspace-tool-target.ts +554 -0
- package/src/workspace-webhook-dispatch.ts +225 -0
- package/src/xai-realtime.ts +85 -81
- package/src/xai-subscription-core.ts +172 -0
- package/dist/browser-auth-broker.d.ts +0 -20
- package/dist/chunk-AJ62T5QN.js.map +0 -1
- package/dist/connection-authority-owner.d.ts +0 -59
- package/dist/routes/connection-authorities.d.ts +0 -3
- package/dist/routes/environments.d.ts +0 -5
- package/dist/routes/host-mcp-bindings.d.ts +0 -5
- package/dist/routes/host-mcp-resolvers.d.ts +0 -3
- package/dist/routes/packs.d.ts +0 -3
- package/dist/session-event-view-MU3HMNV3.js +0 -264
- package/dist/session-event-view-MU3HMNV3.js.map +0 -1
- package/dist/xai-subscription-auth.d.ts +0 -23
- package/src/browser-auth-broker.ts +0 -155
- package/src/connection-authority-owner.ts +0 -61
- package/src/routes/connection-authorities.ts +0 -139
- package/src/routes/environments.ts +0 -388
- package/src/routes/host-mcp-bindings.ts +0 -122
- package/src/routes/host-mcp-resolvers.ts +0 -41
- package/src/routes/packs.ts +0 -784
- package/src/xai-subscription-auth.ts +0 -139
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import
|
|
2
|
+
import {
|
|
3
|
+
assistantMessagePhase,
|
|
4
|
+
type SessionEvent,
|
|
5
|
+
type SessionEventType,
|
|
6
|
+
} from "@opengeni/contracts";
|
|
3
7
|
import type {
|
|
4
8
|
SessionEventSliceOptions,
|
|
5
9
|
SessionEventSlicePage,
|
|
6
10
|
} from "@opengeni/db/session-event-slices";
|
|
7
11
|
|
|
8
12
|
export const SESSION_EVENT_VIEW_MAX_BYTES = 16 * 1024;
|
|
13
|
+
/**
|
|
14
|
+
* toolName with includeOutput reads each named call's result through the exact
|
|
15
|
+
* callId path, so one page carries at most this many call/result pairs inside
|
|
16
|
+
* the same 16 KiB envelope. An omitted limit means the newest (or oldest) one.
|
|
17
|
+
*/
|
|
18
|
+
export const SESSION_EVENT_NAMED_OUTPUT_MAX_CALLS = 3;
|
|
19
|
+
const directionSchema = z.enum(["before", "after"]);
|
|
20
|
+
// A fragment continuation issued by a named-output page carries the named
|
|
21
|
+
// stream's next position, so finishing the fragment returns to that stream.
|
|
22
|
+
const namedResumeSchema = z.object({
|
|
23
|
+
toolName: z.string().min(1).max(256),
|
|
24
|
+
includeArguments: z.boolean(),
|
|
25
|
+
limit: z.number().int().min(1).max(SESSION_EVENT_NAMED_OUTPUT_MAX_CALLS),
|
|
26
|
+
direction: directionSchema,
|
|
27
|
+
after: z.number().int().nonnegative(),
|
|
28
|
+
before: z.number().int().positive().nullable(),
|
|
29
|
+
more: z.boolean(),
|
|
30
|
+
});
|
|
9
31
|
const selectionSchema = z.object({
|
|
10
32
|
sessionId: z.string().uuid(),
|
|
11
33
|
view: z.enum(["conversation", "results", "tools"]),
|
|
@@ -19,9 +41,21 @@ const selectionSchema = z.object({
|
|
|
19
41
|
"callId exceeds the encoded cursor budget",
|
|
20
42
|
)
|
|
21
43
|
.nullable(),
|
|
22
|
-
|
|
44
|
+
toolName: z
|
|
45
|
+
.string()
|
|
46
|
+
.min(1)
|
|
47
|
+
.max(256)
|
|
48
|
+
.refine(
|
|
49
|
+
(value) => Buffer.byteLength(JSON.stringify(value), "utf8") <= 512,
|
|
50
|
+
"toolName exceeds the encoded cursor budget",
|
|
51
|
+
)
|
|
52
|
+
.nullable()
|
|
53
|
+
.default(null),
|
|
54
|
+
limit: z.number().int().min(1).max(50).optional(),
|
|
55
|
+
direction: directionSchema,
|
|
23
56
|
after: z.number().int().nonnegative(),
|
|
24
57
|
before: z.number().int().positive().nullable(),
|
|
58
|
+
named: namedResumeSchema.optional(),
|
|
25
59
|
});
|
|
26
60
|
const cursorSchema = z.object({
|
|
27
61
|
v: z.union([z.literal(1), z.literal(2)]),
|
|
@@ -39,6 +73,7 @@ export type SessionEventViewInput = {
|
|
|
39
73
|
limit?: number | undefined;
|
|
40
74
|
cursor?: string | undefined;
|
|
41
75
|
callId?: string | undefined;
|
|
76
|
+
toolName?: string | undefined;
|
|
42
77
|
includeArguments?: boolean | undefined;
|
|
43
78
|
includeOutput?: boolean | undefined;
|
|
44
79
|
};
|
|
@@ -61,18 +96,108 @@ const bytes = (value: unknown) => Buffer.byteLength(JSON.stringify(value, null,
|
|
|
61
96
|
const encode = (selection: Selection, sequence: number | null = null, offset = 0, v = 2) =>
|
|
62
97
|
Buffer.from(JSON.stringify({ v, selection, sequence, offset })).toString("base64url");
|
|
63
98
|
|
|
99
|
+
const MAX_CURSOR_LENGTH = 4096;
|
|
100
|
+
// Below this many bytes an output read could not return a useful fragment.
|
|
101
|
+
const NAMED_OUTPUT_MIN_BUDGET = 2048;
|
|
102
|
+
|
|
103
|
+
const exampleCall = (args: Record<string, unknown>) =>
|
|
104
|
+
JSON.stringify(Object.fromEntries(Object.entries(args).filter(([, value]) => value != null)));
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Agents sometimes retype the opaque cursor and corrupt it. Read whatever
|
|
108
|
+
* position survives in the readable part so the refusal can name the exact
|
|
109
|
+
* cursor-free call. Recovered values are advice, never a continuation.
|
|
110
|
+
*/
|
|
111
|
+
function recoverCursorPosition(cursor: string): Record<string, unknown> | null {
|
|
112
|
+
const text = cursor.trimStart().startsWith("{")
|
|
113
|
+
? cursor
|
|
114
|
+
: Buffer.from(cursor, "base64url").toString("utf8");
|
|
115
|
+
const pick = (pattern: RegExp) => pattern.exec(text)?.[1];
|
|
116
|
+
const number = (pattern: RegExp) => {
|
|
117
|
+
const value = pick(pattern);
|
|
118
|
+
return value === undefined || value.length > 15 ? undefined : Number(value);
|
|
119
|
+
};
|
|
120
|
+
const string = (key: string) => {
|
|
121
|
+
const value = pick(new RegExp(`"${key}"\\s*:\\s*"((?:[^"\\\\]|\\\\.){1,256})"`));
|
|
122
|
+
if (value === undefined) return undefined;
|
|
123
|
+
try {
|
|
124
|
+
return JSON.parse(`"${value}"`) as string;
|
|
125
|
+
} catch {
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const view = pick(/"view"\s*:\s*"(conversation|results|tools)"/);
|
|
130
|
+
const direction = pick(/"direction"\s*:\s*"(before|after)"/) as
|
|
131
|
+
| Selection["direction"]
|
|
132
|
+
| undefined;
|
|
133
|
+
const sequence = number(/"seq[a-z]*"\s*:\s*(\d+)/i);
|
|
134
|
+
const after = number(/"after"\s*:\s*(\d+)/);
|
|
135
|
+
const before = number(/"before"\s*:\s*(\d+)/);
|
|
136
|
+
const limit = number(/"limit"\s*:\s*(\d+)/);
|
|
137
|
+
const resolvedDirection = direction ?? (before !== undefined ? "before" : undefined);
|
|
138
|
+
const position =
|
|
139
|
+
resolvedDirection === "after"
|
|
140
|
+
? sequence !== undefined
|
|
141
|
+
? { after: Math.max(0, sequence - 1) }
|
|
142
|
+
: after !== undefined
|
|
143
|
+
? { after }
|
|
144
|
+
: null
|
|
145
|
+
: resolvedDirection === "before"
|
|
146
|
+
? sequence !== undefined
|
|
147
|
+
? { before: sequence + 1 }
|
|
148
|
+
: before !== undefined
|
|
149
|
+
? { before }
|
|
150
|
+
: null
|
|
151
|
+
: null;
|
|
152
|
+
if (!position) return null;
|
|
153
|
+
return {
|
|
154
|
+
...(view ? { view } : {}),
|
|
155
|
+
...(string("toolName") ? { toolName: string("toolName") } : {}),
|
|
156
|
+
...(string("callId") ? { callId: string("callId") } : {}),
|
|
157
|
+
...(/"includeArguments"\s*:\s*true/.test(text) ? { includeArguments: true } : {}),
|
|
158
|
+
...(/"includeOutput"\s*:\s*true/.test(text) ? { includeOutput: true } : {}),
|
|
159
|
+
direction: resolvedDirection,
|
|
160
|
+
...position,
|
|
161
|
+
...(limit !== undefined && limit >= 1 && limit <= 50 ? { limit } : {}),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function invalidCursorError(input: SessionEventViewInput): Error {
|
|
166
|
+
const recovered = recoverCursorPosition(input.cursor ?? "");
|
|
167
|
+
const prefix =
|
|
168
|
+
"Invalid session_events cursor: it was not issued by session_events or was altered when copied. Pass nextCursor byte-for-byte or not at all; never retype or build one.";
|
|
169
|
+
if (recovered) {
|
|
170
|
+
return new Error(
|
|
171
|
+
`${prefix} Its readable part names a position, so continue without a cursor: ${exampleCall({
|
|
172
|
+
sessionId: input.sessionId,
|
|
173
|
+
...recovered,
|
|
174
|
+
})} (check the position against the previous page's nextBefore/nextAfter).`,
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
return new Error(
|
|
178
|
+
`${prefix} Continue without a cursor: repeat the previous call with the same view and selectors plus the last page's position, e.g. ${exampleCall(
|
|
179
|
+
{
|
|
180
|
+
sessionId: input.sessionId,
|
|
181
|
+
view: input.view,
|
|
182
|
+
direction: "before",
|
|
183
|
+
before: "<nextBefore>",
|
|
184
|
+
},
|
|
185
|
+
)} or ${exampleCall({ sessionId: input.sessionId, view: input.view, direction: "after", after: "<nextAfter>" })}.`,
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
64
189
|
/** A cursor is a bounded selector, never authority. The caller reauthorizes every read. */
|
|
65
190
|
export function resolveSessionEventView(input: SessionEventViewInput) {
|
|
66
191
|
let continuation: z.infer<typeof cursorSchema> | null = null;
|
|
67
192
|
if (input.cursor !== undefined) {
|
|
68
|
-
if (input.cursor.length >
|
|
193
|
+
if (input.cursor.length > MAX_CURSOR_LENGTH)
|
|
69
194
|
throw new Error("session_events cursor exceeds 4096 characters");
|
|
70
195
|
try {
|
|
71
196
|
continuation = cursorSchema.parse(
|
|
72
197
|
JSON.parse(Buffer.from(input.cursor, "base64url").toString()),
|
|
73
198
|
);
|
|
74
199
|
} catch {
|
|
75
|
-
throw
|
|
200
|
+
throw invalidCursorError(input);
|
|
76
201
|
}
|
|
77
202
|
const previous = continuation.selection;
|
|
78
203
|
for (const key of [
|
|
@@ -81,6 +206,7 @@ export function resolveSessionEventView(input: SessionEventViewInput) {
|
|
|
81
206
|
"includeArguments",
|
|
82
207
|
"includeOutput",
|
|
83
208
|
"callId",
|
|
209
|
+
"toolName",
|
|
84
210
|
"direction",
|
|
85
211
|
"after",
|
|
86
212
|
"before",
|
|
@@ -98,18 +224,58 @@ export function resolveSessionEventView(input: SessionEventViewInput) {
|
|
|
98
224
|
includeArguments: input.includeArguments ?? false,
|
|
99
225
|
includeOutput: input.includeOutput ?? false,
|
|
100
226
|
callId: input.callId ?? null,
|
|
227
|
+
toolName: input.toolName ?? null,
|
|
101
228
|
direction:
|
|
102
229
|
input.direction ??
|
|
103
230
|
(input.before !== undefined || input.after === undefined ? "before" : "after"),
|
|
104
231
|
after: input.after ?? 0,
|
|
105
232
|
before: input.before ?? null,
|
|
106
233
|
});
|
|
234
|
+
let notice: string | undefined;
|
|
107
235
|
if (
|
|
108
236
|
selection.view !== "tools" &&
|
|
109
|
-
(selection.callId ||
|
|
237
|
+
(selection.callId ||
|
|
238
|
+
selection.toolName ||
|
|
239
|
+
selection.includeArguments ||
|
|
240
|
+
selection.includeOutput)
|
|
110
241
|
) {
|
|
111
|
-
|
|
242
|
+
// callId and toolName name tool calls, which only view=tools returns, so
|
|
243
|
+
// the intent is unambiguous: read them there and say so.
|
|
244
|
+
if (!continuation && (selection.callId || selection.toolName)) {
|
|
245
|
+
notice = `view=${selection.view} does not return tool calls; this page is view=tools because callId/toolName select tool calls.`;
|
|
246
|
+
selection.view = "tools";
|
|
247
|
+
} else {
|
|
248
|
+
throw new Error(
|
|
249
|
+
`includeArguments/includeOutput only apply to view=tools. For a tool's result call ${exampleCall(
|
|
250
|
+
{
|
|
251
|
+
sessionId: selection.sessionId,
|
|
252
|
+
view: "tools",
|
|
253
|
+
toolName: "<exact tool name>",
|
|
254
|
+
includeOutput: true,
|
|
255
|
+
limit: 1,
|
|
256
|
+
},
|
|
257
|
+
)}; view=${selection.view} already returns complete text, so drop them: ${exampleCall({
|
|
258
|
+
sessionId: selection.sessionId,
|
|
259
|
+
view: selection.view,
|
|
260
|
+
})}.`,
|
|
261
|
+
);
|
|
262
|
+
}
|
|
112
263
|
}
|
|
264
|
+
const namedOutputs = selection.toolName !== null && selection.includeOutput;
|
|
265
|
+
// Named outputs read one exact result per call, so the page size is the
|
|
266
|
+
// number of calls and is clamped rather than refused; effectiveLimit and
|
|
267
|
+
// nextCursor report the clamp.
|
|
268
|
+
selection.limit = z
|
|
269
|
+
.number()
|
|
270
|
+
.int()
|
|
271
|
+
.min(1)
|
|
272
|
+
.max(50)
|
|
273
|
+
.transform((value) =>
|
|
274
|
+
namedOutputs ? Math.min(value, SESSION_EVENT_NAMED_OUTPUT_MAX_CALLS) : value,
|
|
275
|
+
)
|
|
276
|
+
.parse(input.limit ?? selection.limit ?? (namedOutputs ? 1 : 10));
|
|
277
|
+
if (namedOutputs && continuation && continuation.sequence !== null)
|
|
278
|
+
throw new Error("Invalid session_events cursor position");
|
|
113
279
|
if (
|
|
114
280
|
continuation &&
|
|
115
281
|
((continuation.sequence === null && continuation.offset !== 0) ||
|
|
@@ -118,7 +284,7 @@ export function resolveSessionEventView(input: SessionEventViewInput) {
|
|
|
118
284
|
(selection.before !== null && continuation.sequence >= selection.before))))
|
|
119
285
|
)
|
|
120
286
|
throw new Error("Invalid session_events cursor position");
|
|
121
|
-
return { selection, continuation };
|
|
287
|
+
return { selection, continuation, notice };
|
|
122
288
|
}
|
|
123
289
|
|
|
124
290
|
function project(event: SessionEvent, selection: Selection): Item | null {
|
|
@@ -127,8 +293,16 @@ function project(event: SessionEvent, selection: Selection): Item | null {
|
|
|
127
293
|
const p = record(event.payload);
|
|
128
294
|
const base = { sequence: event.sequence, ...(event.turnId ? { turnId: event.turnId } : {}) };
|
|
129
295
|
if (selection.view === "conversation") {
|
|
296
|
+
// Commentary stays in the conversation, labelled so a reader can tell a
|
|
297
|
+
// progress note from an answer.
|
|
298
|
+
const phase = event.type === "agent.message.completed" ? assistantMessagePhase(p) : null;
|
|
130
299
|
return typeof p.text === "string" && p.text.length > 0
|
|
131
|
-
? {
|
|
300
|
+
? {
|
|
301
|
+
...base,
|
|
302
|
+
role: event.type === "user.message" ? "user" : "assistant",
|
|
303
|
+
...(phase ? { phase } : {}),
|
|
304
|
+
text: p.text,
|
|
305
|
+
}
|
|
132
306
|
: null;
|
|
133
307
|
}
|
|
134
308
|
if (selection.view === "results") {
|
|
@@ -141,6 +315,11 @@ function project(event: SessionEvent, selection: Selection): Item | null {
|
|
|
141
315
|
text: typeof value === "string" ? value : JSON.stringify(value),
|
|
142
316
|
};
|
|
143
317
|
}
|
|
318
|
+
if (
|
|
319
|
+
selection.toolName &&
|
|
320
|
+
(event.type !== "agent.toolCall.created" || p.name !== selection.toolName)
|
|
321
|
+
)
|
|
322
|
+
return null;
|
|
144
323
|
const callId = p.callId ?? p.call_id ?? p.id;
|
|
145
324
|
if (selection.callId !== null && selection.callId !== callId) return null;
|
|
146
325
|
const output = event.type === "agent.toolCall.output";
|
|
@@ -164,8 +343,205 @@ function project(event: SessionEvent, selection: Selection): Item | null {
|
|
|
164
343
|
|
|
165
344
|
/** Read-only projection over the existing RLS/audit query. No command observations. */
|
|
166
345
|
export async function readSessionEventView(input: SessionEventViewInput, read: ReadPage) {
|
|
167
|
-
const { selection, continuation } = resolveSessionEventView(input);
|
|
168
|
-
const
|
|
346
|
+
const { selection, continuation, notice } = resolveSessionEventView(input);
|
|
347
|
+
const scanned =
|
|
348
|
+
selection.toolName !== null && selection.includeOutput
|
|
349
|
+
? await readNamedCallOutputs(selection, read)
|
|
350
|
+
: await scanSessionEventView(selection, continuation, read);
|
|
351
|
+
const page = selection.named ? returnToNamedStream(scanned, selection) : scanned;
|
|
352
|
+
return notice === undefined ? page : { ...page, notice };
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
type Continuation = ReturnType<typeof resolveSessionEventView>["continuation"];
|
|
356
|
+
type ViewPage = Awaited<ReturnType<typeof scanSessionEventView>>;
|
|
357
|
+
type NamedResume = z.infer<typeof namedResumeSchema>;
|
|
358
|
+
// An omitted structured value is final; only a text fragment continues.
|
|
359
|
+
const incompleteFragment = (item: Item) => record(item.fragment).complete === false;
|
|
360
|
+
|
|
361
|
+
const namedSelection = (selection: Selection, named: NamedResume): Selection => ({
|
|
362
|
+
sessionId: selection.sessionId,
|
|
363
|
+
view: "tools",
|
|
364
|
+
includeArguments: named.includeArguments,
|
|
365
|
+
includeOutput: true,
|
|
366
|
+
callId: null,
|
|
367
|
+
toolName: named.toolName,
|
|
368
|
+
limit: named.limit,
|
|
369
|
+
direction: named.direction,
|
|
370
|
+
after: named.after,
|
|
371
|
+
before: named.before,
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* A fragment continuation issued by a named-output page reports the named
|
|
376
|
+
* stream's position, and once the fragment is complete its nextCursor returns
|
|
377
|
+
* to that stream instead of ending the read.
|
|
378
|
+
*/
|
|
379
|
+
function returnToNamedStream(page: ViewPage, selection: Selection): ViewPage {
|
|
380
|
+
const named = selection.named!;
|
|
381
|
+
const position = {
|
|
382
|
+
view: "tools" as const,
|
|
383
|
+
effectiveLimit: named.limit,
|
|
384
|
+
direction: named.direction,
|
|
385
|
+
nextAfter: named.direction === "after" ? named.after : null,
|
|
386
|
+
nextBefore: named.direction === "before" ? named.before : null,
|
|
387
|
+
};
|
|
388
|
+
if (page.events.some(incompleteFragment)) return { ...page, ...position };
|
|
389
|
+
return {
|
|
390
|
+
...page,
|
|
391
|
+
...position,
|
|
392
|
+
hasMore: named.more,
|
|
393
|
+
nextCursor: named.more ? encode(namedSelection(selection, named)) : null,
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/** Re-issue a fragment cursor so it carries the named stream it came from. */
|
|
398
|
+
function withNamedResume(cursor: string, named: NamedResume, limit?: number): string | null {
|
|
399
|
+
const decoded = cursorSchema.parse(JSON.parse(Buffer.from(cursor, "base64url").toString()));
|
|
400
|
+
const encoded = encode(
|
|
401
|
+
{ ...decoded.selection, ...(limit === undefined ? {} : { limit }), named },
|
|
402
|
+
decoded.sequence,
|
|
403
|
+
decoded.offset,
|
|
404
|
+
decoded.v,
|
|
405
|
+
);
|
|
406
|
+
return encoded.length <= MAX_CURSOR_LENGTH ? encoded : null;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* toolName plus includeOutput: list the named calls, then read each call's
|
|
411
|
+
* result through the exact callId path. One call whose arguments or result do
|
|
412
|
+
* not fit keeps that path's lossless fragment continuation, which returns to
|
|
413
|
+
* the named stream when complete; later calls resume from a positional cursor
|
|
414
|
+
* instead of being dropped.
|
|
415
|
+
*/
|
|
416
|
+
async function readNamedCallOutputs(selection: Selection, read: ReadPage): Promise<ViewPage> {
|
|
417
|
+
const calls = await scanSessionEventView({ ...selection, includeOutput: false }, null, read);
|
|
418
|
+
const ordered = selection.direction === "before" ? [...calls.events].reverse() : calls.events;
|
|
419
|
+
const events: Item[] = [];
|
|
420
|
+
let sourceLoss = calls.sourceLoss;
|
|
421
|
+
let stop: { position: number; cursor: string | null } | null = null;
|
|
422
|
+
const envelope = (items: Item[]) => bytes({ ...calls, events: items, nextCursor: null });
|
|
423
|
+
const empty = envelope([]);
|
|
424
|
+
// The named stream continues past `sequence`, the call just returned.
|
|
425
|
+
const resumePast = (sequence: number, more: boolean): NamedResume => ({
|
|
426
|
+
toolName: selection.toolName!,
|
|
427
|
+
includeArguments: selection.includeArguments,
|
|
428
|
+
limit: selection.limit!,
|
|
429
|
+
direction: selection.direction,
|
|
430
|
+
after: selection.direction === "after" ? sequence : selection.after,
|
|
431
|
+
before: selection.direction === "before" ? sequence : selection.before,
|
|
432
|
+
more,
|
|
433
|
+
});
|
|
434
|
+
// stop.position is the first named call not yet returned (inclusive).
|
|
435
|
+
const pastCall = (call: Item) =>
|
|
436
|
+
selection.direction === "before" ? call.sequence - 1 : call.sequence + 1;
|
|
437
|
+
for (const [index, call] of ordered.entries()) {
|
|
438
|
+
const later = index + 1 < ordered.length || calls.hasMore;
|
|
439
|
+
const lookup = selectionSchema.safeParse({
|
|
440
|
+
sessionId: selection.sessionId,
|
|
441
|
+
view: "tools",
|
|
442
|
+
includeArguments: false,
|
|
443
|
+
includeOutput: true,
|
|
444
|
+
callId: typeof call.callId === "string" ? call.callId : null,
|
|
445
|
+
toolName: null,
|
|
446
|
+
limit: 1,
|
|
447
|
+
direction: "after",
|
|
448
|
+
after: call.sequence,
|
|
449
|
+
before: null,
|
|
450
|
+
});
|
|
451
|
+
const readOutput =
|
|
452
|
+
lookup.success && lookup.data.callId !== null
|
|
453
|
+
? { readOutput: { view: "tools", callId: lookup.data.callId, includeOutput: true } }
|
|
454
|
+
: {};
|
|
455
|
+
if (incompleteFragment(call)) {
|
|
456
|
+
if (index > 0) {
|
|
457
|
+
stop = { position: call.sequence, cursor: null };
|
|
458
|
+
break;
|
|
459
|
+
}
|
|
460
|
+
// Arguments larger than a page continue losslessly one call at a time
|
|
461
|
+
// and then return to the named stream; the result is one exact read.
|
|
462
|
+
events.push({ ...call, ...readOutput });
|
|
463
|
+
stop = {
|
|
464
|
+
position: pastCall(call),
|
|
465
|
+
cursor:
|
|
466
|
+
withNamedResume(calls.nextCursor!, resumePast(call.sequence, true), 1) ??
|
|
467
|
+
calls.nextCursor,
|
|
468
|
+
};
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
if (!lookup.success || lookup.data.callId === null) {
|
|
472
|
+
events.push({
|
|
473
|
+
...call,
|
|
474
|
+
outputUnavailable:
|
|
475
|
+
call.identityOmitted === true || typeof call.callId !== "string"
|
|
476
|
+
? "call_identity_omitted"
|
|
477
|
+
: "call_id_exceeds_lookup_budget",
|
|
478
|
+
});
|
|
479
|
+
continue;
|
|
480
|
+
}
|
|
481
|
+
const used = envelope([...events, call]) - empty;
|
|
482
|
+
// The result repeats the call's identity, so budget for it plus some text.
|
|
483
|
+
const { text: _arguments, ...identity } = call;
|
|
484
|
+
if (SESSION_EVENT_VIEW_MAX_BYTES - 6000 - used < NAMED_OUTPUT_MIN_BUDGET + bytes(identity)) {
|
|
485
|
+
if (index > 0) {
|
|
486
|
+
stop = { position: call.sequence, cursor: null };
|
|
487
|
+
break;
|
|
488
|
+
}
|
|
489
|
+
// Huge arguments leave no room: return the call and name the exact read.
|
|
490
|
+
events.push({ ...call, ...readOutput });
|
|
491
|
+
stop = { position: pastCall(call), cursor: null };
|
|
492
|
+
break;
|
|
493
|
+
}
|
|
494
|
+
const output = await scanSessionEventView(lookup.data, null, read, used);
|
|
495
|
+
sourceLoss ??= output.sourceLoss;
|
|
496
|
+
const result = output.events.find((item) => item.kind === "result");
|
|
497
|
+
if (!result) {
|
|
498
|
+
events.push({ ...call, outputFound: false, ...(output.hasMore ? readOutput : {}) });
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
if (incompleteFragment(result)) {
|
|
502
|
+
if (index > 0) {
|
|
503
|
+
stop = { position: call.sequence, cursor: null };
|
|
504
|
+
break;
|
|
505
|
+
}
|
|
506
|
+
// The rest of this result continues through its exact callId cursor,
|
|
507
|
+
// which returns to the named stream when the result is complete.
|
|
508
|
+
const cursor = withNamedResume(output.nextCursor!, resumePast(call.sequence, later));
|
|
509
|
+
events.push(...(cursor ? [call, result] : [{ ...call, ...readOutput }]));
|
|
510
|
+
stop = { position: pastCall(call), cursor };
|
|
511
|
+
break;
|
|
512
|
+
}
|
|
513
|
+
events.push(call, result);
|
|
514
|
+
}
|
|
515
|
+
events.sort((a, b) => a.sequence - b.sequence);
|
|
516
|
+
const position = stop
|
|
517
|
+
? selection.direction === "before"
|
|
518
|
+
? { after: selection.after, before: stop.position + 1 }
|
|
519
|
+
: { after: Math.max(0, stop.position - 1), before: selection.before }
|
|
520
|
+
: selection.direction === "before"
|
|
521
|
+
? { after: selection.after, before: calls.nextBefore }
|
|
522
|
+
: { after: calls.nextAfter ?? selection.after, before: selection.before };
|
|
523
|
+
const hasMore = stop !== null || calls.hasMore;
|
|
524
|
+
const { sourceLoss: _callsLoss, ...base } = calls;
|
|
525
|
+
return {
|
|
526
|
+
...base,
|
|
527
|
+
events,
|
|
528
|
+
nextAfter: selection.direction === "after" ? position.after : null,
|
|
529
|
+
nextBefore: selection.direction === "before" ? position.before : null,
|
|
530
|
+
hasMore,
|
|
531
|
+
nextCursor: stop?.cursor ?? (hasMore ? encode({ ...selection, ...position }) : null),
|
|
532
|
+
sourceExact: sourceLoss === undefined,
|
|
533
|
+
...(sourceLoss ? { sourceLoss } : {}),
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
async function scanSessionEventView(
|
|
538
|
+
selection: Selection,
|
|
539
|
+
continuation: Continuation,
|
|
540
|
+
read: ReadPage,
|
|
541
|
+
// Bytes a caller already holds for the same envelope (named outputs).
|
|
542
|
+
reservedBytes = 0,
|
|
543
|
+
) {
|
|
544
|
+
const limit = selection.limit!;
|
|
169
545
|
let after =
|
|
170
546
|
continuation?.sequence && selection.direction === "after"
|
|
171
547
|
? continuation.sequence - 1
|
|
@@ -182,6 +558,7 @@ export async function readSessionEventView(input: SessionEventViewInput, read: R
|
|
|
182
558
|
let legacyActive = continuation?.v === 1 && continuation.sequence !== null;
|
|
183
559
|
const page = () => ({
|
|
184
560
|
view: selection.view,
|
|
561
|
+
effectiveLimit: limit,
|
|
185
562
|
direction: selection.direction,
|
|
186
563
|
events,
|
|
187
564
|
nextAfter: selection.direction === "after" ? (edge ?? selection.after) : null,
|
|
@@ -218,7 +595,9 @@ export async function readSessionEventView(input: SessionEventViewInput, read: R
|
|
|
218
595
|
...(before === null ? {} : { before }),
|
|
219
596
|
direction: selection.direction,
|
|
220
597
|
limit: 8,
|
|
221
|
-
includeTypes: types[selection.view],
|
|
598
|
+
includeTypes: selection.toolName ? ["agent.toolCall.created"] : types[selection.view],
|
|
599
|
+
...(selection.toolName ? { toolName: selection.toolName } : {}),
|
|
600
|
+
...(selection.callId ? { callId: selection.callId } : {}),
|
|
222
601
|
payloadMode: "full",
|
|
223
602
|
excludeUnclaimedHumanPrompts: true,
|
|
224
603
|
maxBytes: 1024 * 1024,
|
|
@@ -257,7 +636,7 @@ export async function readSessionEventView(input: SessionEventViewInput, read: R
|
|
|
257
636
|
if (!slice && offset > 0 && item.text) item.text = item.text.slice(offset);
|
|
258
637
|
events.push(item);
|
|
259
638
|
// Reserve enough for the bounded cursor and fragment facts.
|
|
260
|
-
if (bytes(page()) > SESSION_EVENT_VIEW_MAX_BYTES - 4096) {
|
|
639
|
+
if (bytes(page()) > SESSION_EVENT_VIEW_MAX_BYTES - 4096 - reservedBytes) {
|
|
261
640
|
events.pop();
|
|
262
641
|
if (events.length > 0) {
|
|
263
642
|
resume(event.sequence, offset);
|
|
@@ -270,7 +649,10 @@ export async function readSessionEventView(input: SessionEventViewInput, read: R
|
|
|
270
649
|
let high = text.length;
|
|
271
650
|
while (low < high) {
|
|
272
651
|
const mid = Math.ceil((low + high) / 2);
|
|
273
|
-
if (
|
|
652
|
+
if (
|
|
653
|
+
bytes({ ...item, text: text.slice(0, mid) }) <=
|
|
654
|
+
SESSION_EVENT_VIEW_MAX_BYTES - 6000 - reservedBytes
|
|
655
|
+
)
|
|
274
656
|
low = mid;
|
|
275
657
|
else high = mid - 1;
|
|
276
658
|
}
|
package/src/mcp/session-view.ts
CHANGED
|
@@ -611,6 +611,8 @@ export function boundSessionDetailMcp(
|
|
|
611
611
|
tools: tools.value,
|
|
612
612
|
metadata: metadata.value,
|
|
613
613
|
model: modelStringProjection(session.model, 512).value,
|
|
614
|
+
reasoningEffort: session.reasoningEffort,
|
|
615
|
+
latencyMode: session.latencyMode,
|
|
614
616
|
sandboxBackend: modelStringProjection(session.sandboxBackend, 128).value,
|
|
615
617
|
sandboxOs: session.sandboxOs,
|
|
616
618
|
sandboxGroupId: session.sandboxGroupId,
|
|
@@ -646,6 +648,7 @@ export function boundSessionDetailMcp(
|
|
|
646
648
|
pinned: session.pinned,
|
|
647
649
|
pinnedAt: session.pinnedAt,
|
|
648
650
|
pinVersion: session.pinVersion,
|
|
651
|
+
...(session.retention === undefined ? {} : { retention: session.retention }),
|
|
649
652
|
...(session.treeStats === undefined ? {} : { treeStats: session.treeStats }),
|
|
650
653
|
createdAt: session.createdAt,
|
|
651
654
|
updatedAt: session.updatedAt,
|
package/src/mcp/session-wait.ts
CHANGED
|
@@ -37,6 +37,8 @@ import {
|
|
|
37
37
|
SESSION_EVENT_SEMANTIC_CLASS_TYPES,
|
|
38
38
|
SESSION_SYSTEM_UPDATE_WAKE_CLASS,
|
|
39
39
|
compactSessionEventResult,
|
|
40
|
+
isStreamedAssistantMessageCompletion,
|
|
41
|
+
turnCompletedReply,
|
|
40
42
|
type SessionSystemUpdateKind,
|
|
41
43
|
} from "@opengeni/contracts";
|
|
42
44
|
import { SESSION_EVENT_MCP_MAX_BYTES, capPayloadValue } from "./session-view";
|
|
@@ -52,6 +54,8 @@ export const SESSION_WAIT_EVENTS_PER_TARGET = 20;
|
|
|
52
54
|
* agent messages, blocking failures, goal facts, and session status/control
|
|
53
55
|
* changes. Raw deltas, tool receipts, sandbox/machine diagnostics, and PTY
|
|
54
56
|
* noise never wake a waiter; `session_events` remains the drill-down for them.
|
|
57
|
+
* The change mode further drops per-message completions: see
|
|
58
|
+
* {@link sessionWaitChangeEventMatches}.
|
|
55
59
|
*/
|
|
56
60
|
export const SESSION_WAIT_EVENT_TYPES = [
|
|
57
61
|
"turn.started",
|
|
@@ -130,6 +134,18 @@ export function sessionWaitCompletionEventMatches(event: SessionEvent): boolean
|
|
|
130
134
|
);
|
|
131
135
|
}
|
|
132
136
|
|
|
137
|
+
/**
|
|
138
|
+
* `waitFor=change` wakes on settled changes. A per-message assistant completion
|
|
139
|
+
* (commentary, or a final message the turn is about to settle) is not one: the
|
|
140
|
+
* `turn.completed` that follows carries the answer. Waking on every progress
|
|
141
|
+
* note would only buy the waiter another poll. The phase-less, id-less
|
|
142
|
+
* completion older workers publish with `turn.completed` still matches.
|
|
143
|
+
* Readers pair this with `excludeStreamedAssistantMessages` in SQL.
|
|
144
|
+
*/
|
|
145
|
+
export function sessionWaitChangeEventMatches(event: SessionEvent): boolean {
|
|
146
|
+
return !isStreamedAssistantMessageCompletion(event);
|
|
147
|
+
}
|
|
148
|
+
|
|
133
149
|
/** The self-session event that announces a newly pending machine input. */
|
|
134
150
|
export const SESSION_WAIT_OWN_PENDING_EVENT_TYPE =
|
|
135
151
|
"system.update.pending" satisfies SessionEventType;
|
|
@@ -144,6 +160,36 @@ export function ownPendingKindWakes(kind: string): boolean {
|
|
|
144
160
|
return wakeClass === undefined || wakeClass === "immediate";
|
|
145
161
|
}
|
|
146
162
|
|
|
163
|
+
function ownPendingUpdateFacts(
|
|
164
|
+
kinds: readonly string[],
|
|
165
|
+
): Pick<
|
|
166
|
+
SessionWaitResult,
|
|
167
|
+
| "ownPendingUpdates"
|
|
168
|
+
| "ownPendingUpdateKinds"
|
|
169
|
+
| "ownPendingImmediateUpdates"
|
|
170
|
+
| "ownPendingDeferredUpdateKinds"
|
|
171
|
+
> {
|
|
172
|
+
const ownKinds = [...new Set(kinds)].sort();
|
|
173
|
+
return {
|
|
174
|
+
ownPendingUpdates: kinds.length,
|
|
175
|
+
ownPendingUpdateKinds: ownKinds,
|
|
176
|
+
ownPendingImmediateUpdates: kinds.filter((kind) => ownPendingKindWakes(kind)).length,
|
|
177
|
+
ownPendingDeferredUpdateKinds: ownKinds.filter((kind) => !ownPendingKindWakes(kind)),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Re-derive the caller's own pending-input facts after the returned content
|
|
183
|
+
* consumed some of that input, keeping the same byte bound.
|
|
184
|
+
*/
|
|
185
|
+
export function withOwnPendingUpdateKinds(
|
|
186
|
+
result: SessionWaitResult,
|
|
187
|
+
kinds: readonly string[],
|
|
188
|
+
): SessionWaitResult {
|
|
189
|
+
const { truncated: _truncated, bytes: _bytes, maxBytes, ...rest } = result;
|
|
190
|
+
return boundSessionWaitResult({ ...rest, ...ownPendingUpdateFacts(kinds) }, maxBytes);
|
|
191
|
+
}
|
|
192
|
+
|
|
147
193
|
const SEMANTIC_CLASS_PRIORITY: readonly SessionEventSemanticClass[] = [
|
|
148
194
|
"terminal",
|
|
149
195
|
"failure",
|
|
@@ -164,6 +210,8 @@ export function sessionWaitSemanticClass(type: SessionEventType): SessionEventSe
|
|
|
164
210
|
export type SessionWaitTarget = { sessionId: string; afterSequence: number };
|
|
165
211
|
|
|
166
212
|
export type SessionWaitEventSummary = {
|
|
213
|
+
/** True only when every semantic result field survived all projections. */
|
|
214
|
+
contentComplete?: boolean;
|
|
167
215
|
id: string;
|
|
168
216
|
sequence: number;
|
|
169
217
|
type: SessionEventType;
|
|
@@ -349,16 +397,10 @@ export async function waitForSessionChanges(input: SessionWaitInput): Promise<Se
|
|
|
349
397
|
if (waited && read.changed.length > 0 && input.source.reauthorizeTargets) {
|
|
350
398
|
await input.source.reauthorizeTargets(read.changed.map((target) => target.sessionId));
|
|
351
399
|
}
|
|
352
|
-
const ownKinds = [...new Set(read.ownPendingUpdateKinds)].sort();
|
|
353
400
|
return boundSessionWaitResult(
|
|
354
401
|
{
|
|
355
402
|
changed: read.changed,
|
|
356
|
-
|
|
357
|
-
ownPendingUpdateKinds: ownKinds,
|
|
358
|
-
ownPendingImmediateUpdates: read.ownPendingUpdateKinds.filter((kind) =>
|
|
359
|
-
ownPendingKindWakes(kind),
|
|
360
|
-
).length,
|
|
361
|
-
ownPendingDeferredUpdateKinds: ownKinds.filter((kind) => !ownPendingKindWakes(kind)),
|
|
403
|
+
...ownPendingUpdateFacts(read.ownPendingUpdateKinds),
|
|
362
404
|
waitedMs: Math.max(0, now() - startedAt),
|
|
363
405
|
timedOut: outcome.timedOut,
|
|
364
406
|
aborted: outcome.aborted,
|
|
@@ -521,6 +563,23 @@ export function summarizeSessionWaitEvent(
|
|
|
521
563
|
} else if (typeof compact.result === "string" && compact.result !== compact.text) {
|
|
522
564
|
summary.result = clampSummaryString(compact.result, textChars);
|
|
523
565
|
}
|
|
566
|
+
// Other wait summaries may omit actionable fields (e.g. human-input
|
|
567
|
+
// questions); absence of a truncation marker is not proof of full content.
|
|
568
|
+
// Neither is the empty output of a turn that ended waiting for input while
|
|
569
|
+
// it records the reply a human's message received.
|
|
570
|
+
summary.contentComplete =
|
|
571
|
+
["turn.completed", "agent.message.completed"].includes(event.type) &&
|
|
572
|
+
turnCompletedReply(event.payload) === null &&
|
|
573
|
+
!compact.truncation.truncated &&
|
|
574
|
+
text === compact.text &&
|
|
575
|
+
JSON.stringify(failure) === JSON.stringify(compact.failure) &&
|
|
576
|
+
(compact.output === null ||
|
|
577
|
+
compact.output === compact.text ||
|
|
578
|
+
JSON.stringify(compact.output) === JSON.stringify(summary.result)) &&
|
|
579
|
+
(compact.result === null ||
|
|
580
|
+
compact.result === undefined ||
|
|
581
|
+
compact.result === compact.text ||
|
|
582
|
+
JSON.stringify(summary.result) === JSON.stringify(compact.result));
|
|
524
583
|
return summary;
|
|
525
584
|
}
|
|
526
585
|
|
|
@@ -570,6 +629,7 @@ export function boundSessionWaitResult(
|
|
|
570
629
|
...target,
|
|
571
630
|
events: target.events.map((event) => ({
|
|
572
631
|
...event,
|
|
632
|
+
contentComplete: false,
|
|
573
633
|
text: event.text === null ? null : clampSummaryString(event.text, textChars),
|
|
574
634
|
...(typeof event.result === "string"
|
|
575
635
|
? { result: clampSummaryString(event.result, textChars) }
|