@opengeni/api-router 3.0.1 → 3.0.2-canary.38894290271001
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-AJ62T5QN.js → chunk-GBUJ2DYZ.js} +80507 -39878
- package/dist/chunk-GBUJ2DYZ.js.map +1 -0
- package/dist/chunk-OGQDXVXY.js +18 -0
- package/dist/chunk-OGQDXVXY.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 +150 -49
- 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
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
// Reaching the person who owns a session. A notification is a session event:
|
|
2
|
+
// it stays in the timeline, reaches webhook subscribers, opens an item in the
|
|
3
|
+
// person's inbox and, when new, alerts their phones. Posting the same key again
|
|
4
|
+
// updates that item in place without a new alert. Agents can withdraw their own
|
|
5
|
+
// notifications and, as the person allows, tidy others' or look after the whole
|
|
6
|
+
// inbox (see, snooze and dismiss any item) — but never answer a question or
|
|
7
|
+
// decide an approval on the person's behalf.
|
|
8
|
+
//
|
|
9
|
+
// An agent can also notify another member of its workspace, when that member
|
|
10
|
+
// allows other people's agents to (per workspace, off by default). It shows
|
|
11
|
+
// them who it came from: the person the session works for.
|
|
12
|
+
import {
|
|
13
|
+
NOTIFICATION_BODY_MAX_CHARS,
|
|
14
|
+
NOTIFICATION_FACT_LABEL_MAX_CHARS,
|
|
15
|
+
NOTIFICATION_FACT_VALUE_MAX_CHARS,
|
|
16
|
+
NOTIFICATION_FACTS_MAX,
|
|
17
|
+
NOTIFICATION_LINK_LABEL_MAX_CHARS,
|
|
18
|
+
NOTIFICATION_SUBTITLE_MAX_CHARS,
|
|
19
|
+
NOTIFICATION_TITLE_MAX_CHARS,
|
|
20
|
+
NotificationKey,
|
|
21
|
+
SessionNotificationPostedPayload,
|
|
22
|
+
SessionNotificationWithdrawnPayload,
|
|
23
|
+
type AccessGrant,
|
|
24
|
+
} from "@opengeni/contracts";
|
|
25
|
+
import type { ApiRouteDeps } from "@opengeni/core";
|
|
26
|
+
import {
|
|
27
|
+
dismissInboxNotification,
|
|
28
|
+
getInboxTidyPolicy,
|
|
29
|
+
getManagedUserByEmail,
|
|
30
|
+
getManagedUserProfilesByIds,
|
|
31
|
+
getMemberNotificationsAllowed,
|
|
32
|
+
getSession,
|
|
33
|
+
getSessionInboxRecipient,
|
|
34
|
+
getSessionTitles,
|
|
35
|
+
listInboxItems,
|
|
36
|
+
listWorkspaceMembers,
|
|
37
|
+
updateInboxItemAttention,
|
|
38
|
+
type InboxItemRow,
|
|
39
|
+
} from "@opengeni/db";
|
|
40
|
+
import { appendAndPublishEvents, appendAndPublishTurnEventsFenced } from "@opengeni/events";
|
|
41
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
42
|
+
import * as z from "zod/v4";
|
|
43
|
+
|
|
44
|
+
type JsonResult = (value: unknown) => {
|
|
45
|
+
content: { type: "text"; text: string }[];
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
type AttemptClaims = {
|
|
49
|
+
callerTurnId: string;
|
|
50
|
+
callerExecutionGeneration: number;
|
|
51
|
+
callerAttemptId: string;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export type RegisterNotificationToolsInput = {
|
|
55
|
+
server: McpServer;
|
|
56
|
+
deps: ApiRouteDeps;
|
|
57
|
+
grant: AccessGrant;
|
|
58
|
+
sessionId: string;
|
|
59
|
+
authorize: () => Promise<void>;
|
|
60
|
+
/** The calling attempt; notifications are fenced to it. */
|
|
61
|
+
attempt: () => AttemptClaims;
|
|
62
|
+
json: JsonResult;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/** Questions, approvals and paused goals wait on the person; replies and notes don't. */
|
|
66
|
+
function needsPerson(item: InboxItemRow): boolean {
|
|
67
|
+
return item.kind === "question" || item.kind === "approval" || item.kind === "goal_paused";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** The person a session works for (its owner, else who started it), or null when no person does. */
|
|
71
|
+
async function sessionOwner(
|
|
72
|
+
deps: ApiRouteDeps,
|
|
73
|
+
workspaceId: string,
|
|
74
|
+
sessionId: string,
|
|
75
|
+
): Promise<{ subjectId: string; parentSessionId: string | null } | null> {
|
|
76
|
+
return await getSessionInboxRecipient(deps.db, workspaceId, sessionId);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Whether `ancestorId` is `sessionId` or one of the sessions above it (bounded). */
|
|
80
|
+
async function isSelfOrAncestor(
|
|
81
|
+
deps: ApiRouteDeps,
|
|
82
|
+
workspaceId: string,
|
|
83
|
+
ancestorId: string,
|
|
84
|
+
sessionId: string,
|
|
85
|
+
): Promise<boolean> {
|
|
86
|
+
let current: string | null = sessionId;
|
|
87
|
+
for (let depth = 0; current && depth < 12; depth += 1) {
|
|
88
|
+
if (current === ancestorId) return true;
|
|
89
|
+
current = (await getSession(deps.db, workspaceId, current))?.parentSessionId ?? null;
|
|
90
|
+
}
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
type Member = { subjectId: string; label: string };
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The workspace member a `recipient` names: their subject id, their email or
|
|
98
|
+
* their member name (case-insensitive). Null when it names nobody in the
|
|
99
|
+
* workspace, or more than one person.
|
|
100
|
+
*/
|
|
101
|
+
async function resolveMember(
|
|
102
|
+
deps: ApiRouteDeps,
|
|
103
|
+
workspaceId: string,
|
|
104
|
+
recipient: string,
|
|
105
|
+
): Promise<Member | null> {
|
|
106
|
+
const members = await listWorkspaceMembers(deps.db, workspaceId);
|
|
107
|
+
const wanted = recipient.trim();
|
|
108
|
+
const lowered = wanted.toLowerCase();
|
|
109
|
+
const toMember = (member: (typeof members)[number]): Member => ({
|
|
110
|
+
subjectId: member.subjectId,
|
|
111
|
+
label: member.subjectLabel?.trim() || member.subjectId,
|
|
112
|
+
});
|
|
113
|
+
const byId = members.find((member) => member.subjectId === wanted);
|
|
114
|
+
if (byId) return toMember(byId);
|
|
115
|
+
if (wanted.includes("@")) {
|
|
116
|
+
const userId = await getManagedUserByEmail(deps.db, wanted).catch(() => null);
|
|
117
|
+
const byEmail = userId
|
|
118
|
+
? members.find((member) => member.subjectId === `user:${userId}`)
|
|
119
|
+
: members.find((member) => member.subjectLabel?.trim().toLowerCase() === lowered);
|
|
120
|
+
if (byEmail) return toMember(byEmail);
|
|
121
|
+
}
|
|
122
|
+
const byName = members.filter((member) => member.subjectLabel?.trim().toLowerCase() === lowered);
|
|
123
|
+
return byName.length === 1 ? toMember(byName[0]!) : null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** How a person is named to other members: their member name, else their profile. */
|
|
127
|
+
async function personLabel(
|
|
128
|
+
deps: ApiRouteDeps,
|
|
129
|
+
workspaceId: string,
|
|
130
|
+
subjectId: string,
|
|
131
|
+
): Promise<string> {
|
|
132
|
+
const member = (await listWorkspaceMembers(deps.db, workspaceId)).find(
|
|
133
|
+
(each) => each.subjectId === subjectId,
|
|
134
|
+
);
|
|
135
|
+
const named = member?.subjectLabel?.trim();
|
|
136
|
+
if (named) return named.slice(0, 200);
|
|
137
|
+
if (subjectId.startsWith("user:")) {
|
|
138
|
+
const [profile] = await getManagedUserProfilesByIds(deps.db, [subjectId.slice(5)]).catch(
|
|
139
|
+
() => [],
|
|
140
|
+
);
|
|
141
|
+
const fromProfile = profile?.name?.trim() || profile?.email?.trim();
|
|
142
|
+
if (fromProfile) return fromProfile.slice(0, 200);
|
|
143
|
+
}
|
|
144
|
+
return "A teammate";
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function registerNotificationTools(input: RegisterNotificationToolsInput): void {
|
|
148
|
+
const { server, deps, grant, sessionId, authorize, attempt, json } = input;
|
|
149
|
+
|
|
150
|
+
const appendOwn = async (events: Array<{ type: string; payload: unknown }>) => {
|
|
151
|
+
const claims = attempt();
|
|
152
|
+
const appended = await appendAndPublishTurnEventsFenced(
|
|
153
|
+
deps.db,
|
|
154
|
+
deps.bus,
|
|
155
|
+
grant.workspaceId,
|
|
156
|
+
sessionId,
|
|
157
|
+
claims.callerTurnId,
|
|
158
|
+
claims.callerExecutionGeneration,
|
|
159
|
+
claims.callerAttemptId,
|
|
160
|
+
events as Parameters<typeof appendAndPublishTurnEventsFenced>[7],
|
|
161
|
+
);
|
|
162
|
+
if (!appended.accepted) {
|
|
163
|
+
throw new Error("The calling turn was replaced before the notification committed.");
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
server.registerTool(
|
|
168
|
+
"notify_user",
|
|
169
|
+
{
|
|
170
|
+
description: [
|
|
171
|
+
"Notify the person who owns this session: it goes to their inbox and, when new, to their phone. It always links back to this point in this session, so never add a link to the session yourself.",
|
|
172
|
+
"Use it sparingly, for something they would want to know while away: a long task finished, a result is ready, or you are blocked on them. Questions and approvals already reach them; don't duplicate those.",
|
|
173
|
+
"Write it like a good phone notification. title: what happened, a few words ('Release 2.4 is live'). subtitle (optional): what it's about ('Billing service'). message (optional): one or two short sentences or up to four '- ' bullets; **bold**, `code` and [links](https://…) render in the inbox and become plain text on the lock screen. facts (optional): up to four short label/value pairs for the numbers that matter ('Tests' / '412 passed'). link (optional): one https place outside the session worth opening, such as a pull request or dashboard. Keep secrets out.",
|
|
174
|
+
"Give each notification a stable key: posting the same key again updates it in place without a new alert (for progress such as '7 of 10 done'). urgency time_sensitive breaks through Focus on their phone; use it only for what cannot wait. Withdraw it with notification_withdraw when it no longer applies.",
|
|
175
|
+
"recipient (optional): notify another member of this workspace instead, by their email or name. They see who it came from (the person this session works for). It only reaches people who allow other members' agents to notify them; otherwise you get an error saying so. Don't retry then: tell the person you work for.",
|
|
176
|
+
].join(" "),
|
|
177
|
+
inputSchema: {
|
|
178
|
+
title: z.string().trim().min(1).max(NOTIFICATION_TITLE_MAX_CHARS),
|
|
179
|
+
subtitle: z.string().trim().max(NOTIFICATION_SUBTITLE_MAX_CHARS).optional(),
|
|
180
|
+
message: z.string().trim().max(NOTIFICATION_BODY_MAX_CHARS).default(""),
|
|
181
|
+
facts: z
|
|
182
|
+
.array(
|
|
183
|
+
z.object({
|
|
184
|
+
label: z.string().trim().min(1).max(NOTIFICATION_FACT_LABEL_MAX_CHARS),
|
|
185
|
+
value: z.string().trim().min(1).max(NOTIFICATION_FACT_VALUE_MAX_CHARS),
|
|
186
|
+
}),
|
|
187
|
+
)
|
|
188
|
+
.max(NOTIFICATION_FACTS_MAX)
|
|
189
|
+
.optional(),
|
|
190
|
+
link: z
|
|
191
|
+
.object({
|
|
192
|
+
url: z.string().trim().max(2000).describe("An https URL outside this session."),
|
|
193
|
+
label: z.string().trim().min(1).max(NOTIFICATION_LINK_LABEL_MAX_CHARS),
|
|
194
|
+
})
|
|
195
|
+
.optional(),
|
|
196
|
+
key: z
|
|
197
|
+
.string()
|
|
198
|
+
.max(120)
|
|
199
|
+
.optional()
|
|
200
|
+
.describe("Stable id for this notification, e.g. 'migration' or 'report-ready'."),
|
|
201
|
+
urgency: z.enum(["normal", "time_sensitive"]).default("normal"),
|
|
202
|
+
recipient: z
|
|
203
|
+
.string()
|
|
204
|
+
.trim()
|
|
205
|
+
.min(1)
|
|
206
|
+
.max(320)
|
|
207
|
+
.optional()
|
|
208
|
+
.describe(
|
|
209
|
+
"Another workspace member to notify, by email or name. Omit to notify the person you work for.",
|
|
210
|
+
),
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
async ({ title, subtitle, message, facts, link, key, urgency, recipient }) => {
|
|
214
|
+
await authorize();
|
|
215
|
+
const resolvedKey = NotificationKey.parse(key ?? `n-${crypto.randomUUID().slice(0, 8)}`);
|
|
216
|
+
const owner = await sessionOwner(deps, grant.workspaceId, sessionId);
|
|
217
|
+
let member: Member | null = null;
|
|
218
|
+
if (recipient) {
|
|
219
|
+
// Only a session that works for a person can speak for them to others.
|
|
220
|
+
if (!owner) {
|
|
221
|
+
throw new Error(
|
|
222
|
+
"This session works for no person, so it cannot notify other members of the workspace.",
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
member = await resolveMember(deps, grant.workspaceId, recipient);
|
|
226
|
+
if (!member) {
|
|
227
|
+
throw new Error(
|
|
228
|
+
`${recipient} is not a member of this workspace (or the name matches more than one member). Use their email.`,
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
if (member.subjectId === owner.subjectId) {
|
|
232
|
+
member = null;
|
|
233
|
+
} else if (
|
|
234
|
+
!(await getMemberNotificationsAllowed(deps.db, {
|
|
235
|
+
workspaceId: grant.workspaceId,
|
|
236
|
+
subjectId: member.subjectId,
|
|
237
|
+
}))
|
|
238
|
+
) {
|
|
239
|
+
throw new Error(
|
|
240
|
+
`${member.label} hasn't allowed other people's agents to notify them in this workspace. They can turn it on in their inbox settings; until then, tell the person you work for instead.`,
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const target = member?.subjectId ?? owner?.subjectId ?? null;
|
|
245
|
+
const existing = target
|
|
246
|
+
? (
|
|
247
|
+
await listInboxItems(deps.db, {
|
|
248
|
+
accountId: grant.accountId,
|
|
249
|
+
subjectId: target,
|
|
250
|
+
})
|
|
251
|
+
).find(
|
|
252
|
+
(item) =>
|
|
253
|
+
item.sessionId === sessionId &&
|
|
254
|
+
item.kind === "notification" &&
|
|
255
|
+
item.sourceKey === resolvedKey,
|
|
256
|
+
)
|
|
257
|
+
: undefined;
|
|
258
|
+
const parsed = SessionNotificationPostedPayload.safeParse({
|
|
259
|
+
key: resolvedKey,
|
|
260
|
+
title,
|
|
261
|
+
...(subtitle ? { subtitle } : {}),
|
|
262
|
+
body: message,
|
|
263
|
+
...(facts && facts.length > 0 ? { facts } : {}),
|
|
264
|
+
...(link ? { link } : {}),
|
|
265
|
+
urgency,
|
|
266
|
+
replaced: Boolean(existing),
|
|
267
|
+
...(member && owner
|
|
268
|
+
? {
|
|
269
|
+
recipientSubjectId: member.subjectId,
|
|
270
|
+
sender: {
|
|
271
|
+
subjectId: owner.subjectId,
|
|
272
|
+
label: await personLabel(deps, grant.workspaceId, owner.subjectId),
|
|
273
|
+
},
|
|
274
|
+
}
|
|
275
|
+
: {}),
|
|
276
|
+
// Recorded on the event so integrations can deliver it themselves.
|
|
277
|
+
...(target === null ? { undeliveredReason: "no_human_recipient" as const } : {}),
|
|
278
|
+
});
|
|
279
|
+
if (!parsed.success) {
|
|
280
|
+
const issue = parsed.error.issues[0];
|
|
281
|
+
throw new Error(
|
|
282
|
+
`Invalid notification${issue ? ` (${issue.path.join(".") || "input"}): ${issue.message}` : ""}`,
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
const payload = parsed.data;
|
|
286
|
+
await appendOwn([{ type: "session.notification.posted", payload }]);
|
|
287
|
+
return json({
|
|
288
|
+
ok: true,
|
|
289
|
+
key: resolvedKey,
|
|
290
|
+
// No person owns this session (a key or service started it): nobody is notified.
|
|
291
|
+
delivered: target !== null,
|
|
292
|
+
...(target === null ? { undeliveredReason: "no_human_recipient" } : {}),
|
|
293
|
+
...(member ? { recipient: member.label } : {}),
|
|
294
|
+
updatedInPlace: Boolean(existing),
|
|
295
|
+
});
|
|
296
|
+
},
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
server.registerTool(
|
|
300
|
+
"notification_withdraw",
|
|
301
|
+
{
|
|
302
|
+
description:
|
|
303
|
+
"Withdraw a notification this session posted (by its key) once it no longer applies, for example when you are no longer blocked. It leaves the inbox and phone of everyone it reached; pass recipient to withdraw only the copy sent to that member.",
|
|
304
|
+
inputSchema: {
|
|
305
|
+
key: z.string().min(1).max(120),
|
|
306
|
+
recipient: z.string().trim().min(1).max(320).optional(),
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
async ({ key, recipient }) => {
|
|
310
|
+
await authorize();
|
|
311
|
+
let recipientSubjectId: string | undefined;
|
|
312
|
+
if (recipient) {
|
|
313
|
+
const member = await resolveMember(deps, grant.workspaceId, recipient);
|
|
314
|
+
// Someone who has since left can still have their copy withdrawn by id.
|
|
315
|
+
recipientSubjectId = member?.subjectId ?? recipient;
|
|
316
|
+
}
|
|
317
|
+
const payload = SessionNotificationWithdrawnPayload.parse({
|
|
318
|
+
key: NotificationKey.parse(key),
|
|
319
|
+
...(recipientSubjectId ? { recipientSubjectId } : {}),
|
|
320
|
+
});
|
|
321
|
+
await appendOwn([{ type: "session.notification.withdrawn", payload }]);
|
|
322
|
+
return json({ ok: true, key: payload.key });
|
|
323
|
+
},
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
server.registerTool(
|
|
327
|
+
"inbox_tidy",
|
|
328
|
+
{
|
|
329
|
+
description:
|
|
330
|
+
"See and look after the inbox of the person this session works for. Lists the open items you may manage: by default the agent notifications from this session and sessions under it; every session's notifications when the person lets any agent tidy; and, when the person gives agents full access, every open item (questions, approvals, paused goals, replies and notifications) with its session, so you can keep them up to date. Pass dismissItemIds to dismiss items that are done, stale or duplicated, snooze to hide items until a time, and unsnoozeItemIds to bring snoozed ones back. Dismissing a question or approval only clears it from the inbox; its session still waits. Never answer a question or decide an approval for the person: tell them, and they settle it.",
|
|
331
|
+
inputSchema: {
|
|
332
|
+
dismissItemIds: z.array(z.string().uuid()).max(50).default([]),
|
|
333
|
+
snooze: z
|
|
334
|
+
.array(
|
|
335
|
+
z.object({
|
|
336
|
+
itemId: z.string().uuid(),
|
|
337
|
+
until: z
|
|
338
|
+
.string()
|
|
339
|
+
.datetime({ offset: true })
|
|
340
|
+
.describe("ISO time to hide the item until"),
|
|
341
|
+
}),
|
|
342
|
+
)
|
|
343
|
+
.max(50)
|
|
344
|
+
.default([]),
|
|
345
|
+
unsnoozeItemIds: z.array(z.string().uuid()).max(50).default([]),
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
async ({ dismissItemIds, snooze, unsnoozeItemIds }) => {
|
|
349
|
+
await authorize();
|
|
350
|
+
const owner = await sessionOwner(deps, grant.workspaceId, sessionId);
|
|
351
|
+
if (!owner) {
|
|
352
|
+
return json({ ok: true, items: [], dismissed: [], snoozed: [], unsnoozed: [] });
|
|
353
|
+
}
|
|
354
|
+
const scope = { accountId: grant.accountId, subjectId: owner.subjectId };
|
|
355
|
+
const policy = await getInboxTidyPolicy(deps.db, scope);
|
|
356
|
+
const fullAccess = policy === "full_access";
|
|
357
|
+
const allowed = async (item: InboxItemRow): Promise<boolean> => {
|
|
358
|
+
if (fullAccess) return true;
|
|
359
|
+
if (item.kind !== "notification") return false;
|
|
360
|
+
if (policy === "any_agent") return true;
|
|
361
|
+
return (
|
|
362
|
+
item.workspaceId === grant.workspaceId &&
|
|
363
|
+
(await isSelfOrAncestor(deps, grant.workspaceId, sessionId, item.sessionId))
|
|
364
|
+
);
|
|
365
|
+
};
|
|
366
|
+
const items = await listInboxItems(deps.db, scope);
|
|
367
|
+
const manageable: InboxItemRow[] = [];
|
|
368
|
+
for (const item of items) if (await allowed(item)) manageable.push(item);
|
|
369
|
+
const find = (itemId: string) => manageable.find((candidate) => candidate.id === itemId);
|
|
370
|
+
const dismissed: string[] = [];
|
|
371
|
+
for (const itemId of dismissItemIds) {
|
|
372
|
+
const item = find(itemId);
|
|
373
|
+
if (!item) continue;
|
|
374
|
+
if (item.kind !== "notification") {
|
|
375
|
+
// Clears it from the inbox only; the question or approval stays open in its session.
|
|
376
|
+
if (await updateInboxItemAttention(deps.db, { itemId, ...scope, dismissed: true })) {
|
|
377
|
+
dismissed.push(itemId);
|
|
378
|
+
}
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
if (await dismissInboxNotification(deps.db, { itemId, ...scope })) {
|
|
382
|
+
dismissed.push(itemId);
|
|
383
|
+
// Record the tidy on the posting session, so its timeline and hosts see it.
|
|
384
|
+
await appendAndPublishEvents(deps.db, deps.bus, item.workspaceId, item.sessionId, [
|
|
385
|
+
{
|
|
386
|
+
type: "session.notification.withdrawn",
|
|
387
|
+
payload: SessionNotificationWithdrawnPayload.parse({
|
|
388
|
+
key: item.sourceKey,
|
|
389
|
+
...(item.sessionId === sessionId ? {} : { bySessionId: sessionId }),
|
|
390
|
+
// Only this person's copy: the same key may also have reached others.
|
|
391
|
+
recipientSubjectId: owner.subjectId,
|
|
392
|
+
}),
|
|
393
|
+
},
|
|
394
|
+
] as Parameters<typeof appendAndPublishEvents>[4]);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
const snoozed: Array<{ itemId: string; until: string }> = [];
|
|
398
|
+
for (const { itemId, until } of snooze) {
|
|
399
|
+
if (dismissed.includes(itemId) || !find(itemId)) continue;
|
|
400
|
+
const at = new Date(until);
|
|
401
|
+
if (Number.isNaN(at.getTime()) || at.getTime() <= Date.now()) {
|
|
402
|
+
throw new Error(`Snooze time for ${itemId} must be in the future`);
|
|
403
|
+
}
|
|
404
|
+
const iso = at.toISOString();
|
|
405
|
+
if (await updateInboxItemAttention(deps.db, { itemId, ...scope, snoozedUntil: iso })) {
|
|
406
|
+
snoozed.push({ itemId, until: iso });
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
const unsnoozed: string[] = [];
|
|
410
|
+
for (const itemId of unsnoozeItemIds) {
|
|
411
|
+
const item = find(itemId);
|
|
412
|
+
if (!item || dismissed.includes(itemId) || item.snoozedUntil === null) continue;
|
|
413
|
+
if (await updateInboxItemAttention(deps.db, { itemId, ...scope, snoozedUntil: null })) {
|
|
414
|
+
unsnoozed.push(itemId);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
const remaining = manageable.filter((item) => !dismissed.includes(item.id));
|
|
418
|
+
const snoozeOf = (item: InboxItemRow): string | null => {
|
|
419
|
+
if (unsnoozed.includes(item.id)) return null;
|
|
420
|
+
return snoozed.find((each) => each.itemId === item.id)?.until ?? item.snoozedUntil;
|
|
421
|
+
};
|
|
422
|
+
if (!fullAccess) {
|
|
423
|
+
return json({
|
|
424
|
+
ok: true,
|
|
425
|
+
policy,
|
|
426
|
+
dismissed,
|
|
427
|
+
snoozed,
|
|
428
|
+
unsnoozed,
|
|
429
|
+
notifications: remaining.map((item) => ({
|
|
430
|
+
itemId: item.id,
|
|
431
|
+
sessionId: item.sessionId,
|
|
432
|
+
title: item.title,
|
|
433
|
+
message: item.body,
|
|
434
|
+
snoozedUntil: snoozeOf(item),
|
|
435
|
+
updatedAt: item.updatedAt,
|
|
436
|
+
})),
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
const titles = new Map<string, string | null>();
|
|
440
|
+
const byWorkspace = new Map<string, string[]>();
|
|
441
|
+
for (const item of remaining) {
|
|
442
|
+
byWorkspace.set(item.workspaceId, [
|
|
443
|
+
...(byWorkspace.get(item.workspaceId) ?? []),
|
|
444
|
+
item.sessionId,
|
|
445
|
+
]);
|
|
446
|
+
}
|
|
447
|
+
for (const [workspaceId, sessionIds] of byWorkspace) {
|
|
448
|
+
const found = await getSessionTitles(deps.db, workspaceId, [...new Set(sessionIds)]);
|
|
449
|
+
for (const [id, title] of found) titles.set(id, title);
|
|
450
|
+
}
|
|
451
|
+
return json({
|
|
452
|
+
ok: true,
|
|
453
|
+
policy,
|
|
454
|
+
dismissed,
|
|
455
|
+
snoozed,
|
|
456
|
+
unsnoozed,
|
|
457
|
+
// Needs-you items first, then replies and notes; newest first within each.
|
|
458
|
+
items: [
|
|
459
|
+
...remaining.filter((item) => needsPerson(item)),
|
|
460
|
+
...remaining.filter((item) => !needsPerson(item)),
|
|
461
|
+
].map((item) => ({
|
|
462
|
+
itemId: item.id,
|
|
463
|
+
kind: item.kind,
|
|
464
|
+
needsPerson: needsPerson(item),
|
|
465
|
+
sessionId: item.sessionId,
|
|
466
|
+
sessionTitle: titles.get(item.sessionId) ?? null,
|
|
467
|
+
title: item.title,
|
|
468
|
+
...(item.subtitle ? { subtitle: item.subtitle } : {}),
|
|
469
|
+
message: item.body,
|
|
470
|
+
...(item.facts.length > 0 ? { facts: item.facts } : {}),
|
|
471
|
+
...(item.choices.length > 0 ? { choices: item.choices.map((each) => each.label) } : {}),
|
|
472
|
+
urgency: item.urgency,
|
|
473
|
+
unread: item.unread,
|
|
474
|
+
snoozedUntil: snoozeOf(item),
|
|
475
|
+
updatedAt: item.updatedAt,
|
|
476
|
+
})),
|
|
477
|
+
});
|
|
478
|
+
},
|
|
479
|
+
);
|
|
480
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ApiRouteDeps } from "@opengeni/core";
|
|
2
|
+
import { failureDiagnostic, type FailureDiagnosticInput } from "@opengeni/observability";
|
|
3
|
+
|
|
4
|
+
type OrchestrationTool = "session_create" | "session_send_message" | "session_steer";
|
|
5
|
+
type CallerAttempt = {
|
|
6
|
+
sessionId: string;
|
|
7
|
+
turnId: string;
|
|
8
|
+
attemptId: string;
|
|
9
|
+
executionGeneration: number;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/** Caller identity comes only from the signed grant, never tool arguments. */
|
|
13
|
+
export function orchestrationFailureDiagnostic(
|
|
14
|
+
deps: Pick<ApiRouteDeps, "settings" | "observability">,
|
|
15
|
+
tool: OrchestrationTool,
|
|
16
|
+
error: unknown,
|
|
17
|
+
caller: CallerAttempt | null,
|
|
18
|
+
) {
|
|
19
|
+
const input: FailureDiagnosticInput = {
|
|
20
|
+
code: "mcp_orchestration_failed",
|
|
21
|
+
stage: `mcp.${tool}`,
|
|
22
|
+
retryDecision: "unknown",
|
|
23
|
+
error,
|
|
24
|
+
...(caller ?? {}),
|
|
25
|
+
};
|
|
26
|
+
const diagnostic = failureDiagnostic(input, deps.settings.deploymentRevision);
|
|
27
|
+
let diagnosticExport: "disabled" | "queued" | "unavailable" = "disabled";
|
|
28
|
+
if (deps.settings.observabilityDiagnosticsEndpoint) {
|
|
29
|
+
diagnosticExport = "unavailable";
|
|
30
|
+
try {
|
|
31
|
+
const id = deps.observability?.recordFailureDiagnostic({
|
|
32
|
+
...input,
|
|
33
|
+
diagnosticId: diagnostic.diagnosticId,
|
|
34
|
+
});
|
|
35
|
+
if (id === diagnostic.diagnosticId) diagnosticExport = "queued";
|
|
36
|
+
} catch {
|
|
37
|
+
// Evidence export cannot change the original error or replay the operation.
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Self-contained safe facts survive the ordinary failed-tool receipt even when
|
|
41
|
+
// the optional protected sink is disabled. Queued is not proof of delivery.
|
|
42
|
+
return { diagnostic, diagnosticExport };
|
|
43
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CreateScheduledTaskRequest,
|
|
3
|
+
ScheduledTaskAgentConfigInput,
|
|
4
|
+
ScheduledTaskRunMode,
|
|
5
|
+
} from "@opengeni/contracts";
|
|
6
|
+
import { z } from "zod/v4";
|
|
7
|
+
|
|
8
|
+
/** The calling session is supplied by the signed grant, never by model text. */
|
|
9
|
+
export function resolveScheduledTaskCreateInput(
|
|
10
|
+
input: Record<string, unknown>,
|
|
11
|
+
sessionId: string | null,
|
|
12
|
+
) {
|
|
13
|
+
const runMode =
|
|
14
|
+
input.runMode ?? (input.targetSessionId || sessionId ? "existing_session" : undefined);
|
|
15
|
+
const targetSessionId =
|
|
16
|
+
input.targetSessionId ?? (runMode === "existing_session" ? sessionId : undefined);
|
|
17
|
+
if (!runMode)
|
|
18
|
+
throw new Error(
|
|
19
|
+
"Choose an existing chat or explicitly select reusable_session or new_session_per_run for a separate agent",
|
|
20
|
+
);
|
|
21
|
+
if (runMode === "existing_session" && !targetSessionId)
|
|
22
|
+
throw new Error("Choose the chat that should receive scheduled messages");
|
|
23
|
+
return CreateScheduledTaskRequest.parse({
|
|
24
|
+
...input,
|
|
25
|
+
runMode,
|
|
26
|
+
...(targetSessionId ? { targetSessionId } : {}),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function scheduledTaskCreateToolInput() {
|
|
31
|
+
return (
|
|
32
|
+
z
|
|
33
|
+
.object({
|
|
34
|
+
...CreateScheduledTaskRequest.options[1].out.shape,
|
|
35
|
+
runMode: ScheduledTaskRunMode.optional().describe(
|
|
36
|
+
"Omit to schedule a message in this chat. Choose reusable_session or new_session_per_run only when the user requests a separate agent.",
|
|
37
|
+
),
|
|
38
|
+
targetSessionId: z
|
|
39
|
+
.string()
|
|
40
|
+
.uuid()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe(
|
|
43
|
+
"Destination chat. Omitted existing-session destinations use the calling chat.",
|
|
44
|
+
),
|
|
45
|
+
prompt: ScheduledTaskAgentConfigInput.shape.prompt
|
|
46
|
+
.optional()
|
|
47
|
+
.describe(
|
|
48
|
+
"Message to send to an existing chat at each occurrence. The chat supplies its model, tools and machine.",
|
|
49
|
+
),
|
|
50
|
+
agentConfig: z
|
|
51
|
+
.object(ScheduledTaskAgentConfigInput.shape)
|
|
52
|
+
.omit({ slackBotChannelId: true, toolPolicy: true })
|
|
53
|
+
.strict()
|
|
54
|
+
.optional()
|
|
55
|
+
.describe(
|
|
56
|
+
"Creation settings for a separate scheduled agent. For an existing chat, supply prompt instead.",
|
|
57
|
+
),
|
|
58
|
+
})
|
|
59
|
+
// Only a person pins connector accounts; agents never do.
|
|
60
|
+
// Variable Sets were removed (RM-1); agents choose vaults via vaultPolicy.
|
|
61
|
+
.omit({
|
|
62
|
+
agentLearning: true,
|
|
63
|
+
connectionAuthorities: true,
|
|
64
|
+
pinnedAccounts: true,
|
|
65
|
+
pinnedAccountsRequired: true,
|
|
66
|
+
variableSetId: true,
|
|
67
|
+
environmentId: true,
|
|
68
|
+
})
|
|
69
|
+
.strict()
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Validate the original call, before projection defaults can add fields from
|
|
74
|
+
// the separate-agent branch to the existing-chat message branch.
|
|
75
|
+
export function scheduledTaskCreateToolValidation(sessionId: string | null) {
|
|
76
|
+
return z.record(z.string(), z.unknown()).superRefine((input, context) => {
|
|
77
|
+
try {
|
|
78
|
+
resolveScheduledTaskCreateInput(input, sessionId);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
if (error instanceof z.ZodError)
|
|
81
|
+
for (const issue of error.issues) context.addIssue({ ...issue });
|
|
82
|
+
else
|
|
83
|
+
context.addIssue({
|
|
84
|
+
code: "custom",
|
|
85
|
+
message: error instanceof Error ? error.message : "Invalid schedule destination",
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|