@vellumai/assistant 0.12.3-staging.1 → 0.12.3-staging.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/ARCHITECTURE.md +43 -29
- package/Dockerfile +63 -0
- package/docs/architecture/security.md +10 -5
- package/docs/architecture/turn-actor.md +2 -0
- package/docs/desktop-browser-cli.md +45 -4
- package/docs/live-voice-task-outcomes.md +100 -0
- package/docs/mode-sessions.md +183 -0
- package/docs/voice-input-diagnostics.md +58 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +2 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +2 -1
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +20 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +4 -1
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +38 -7
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +5 -6
- package/node_modules/@vellumai/service-contracts/package.json +2 -1
- package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/integration-categories.ts +36 -0
- package/node_modules/@vellumai/slack-text/src/index.ts +4 -8
- package/openapi.yaml +665 -14
- package/package.json +1 -1
- package/scripts/smoke-desktop-browser-cli.ts +10 -26
- package/scripts/smoke-desktop-window-theme.ts +2 -3
- package/src/__tests__/agent-loop-output-hooks.test.ts +150 -1
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +87 -19
- package/src/__tests__/annotate-activity-metadata.test.ts +3 -1
- package/src/__tests__/annotate-risk-options.test.ts +2 -0
- package/src/__tests__/answered-question-persistence.test.ts +2 -0
- package/src/__tests__/anthropic-gateway-shared.test.ts +22 -0
- package/src/__tests__/approval-message-composer.test.ts +1 -118
- package/src/__tests__/approval-routes-http.test.ts +3 -0
- package/src/__tests__/assistant-event-hub-connection-history.test.ts +111 -0
- package/src/__tests__/assistant-event-hub-targeted.test.ts +50 -0
- package/src/__tests__/assistant-event-targeting.test.ts +186 -0
- package/src/__tests__/assistant-stream-state.test.ts +29 -9
- package/src/__tests__/browser-fill-credential.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +4 -1
- package/src/__tests__/build-persisted-content.test.ts +1 -1
- package/src/__tests__/call-conversation-messages.test.ts +5 -0
- package/src/__tests__/call-recovery.test.ts +7 -2
- package/src/__tests__/call-routes-http.test.ts +12 -0
- package/src/__tests__/call-store.test.ts +7 -2
- package/src/__tests__/channel-retry-sweep.test.ts +9 -0
- package/src/__tests__/chat-reveal-guard-priming.test.ts +2 -0
- package/src/__tests__/checker.test.ts +11 -3
- package/src/__tests__/client-os-metadata-persistence.test.ts +35 -1
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +0 -25
- package/src/__tests__/computer-use-tools.test.ts +1 -233
- package/src/__tests__/config-model-image-provider.test.ts +39 -0
- package/src/__tests__/config-schema.test.ts +16 -0
- package/src/__tests__/config-watcher.test.ts +24 -0
- package/src/__tests__/context-search-agent-runner.test.ts +260 -1
- package/src/__tests__/context-search-fanout.test.ts +1 -1
- package/src/__tests__/context-search-types.test.ts +7 -7
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +8 -2
- package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop.test.ts +546 -16
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +53 -1
- package/src/__tests__/conversation-evictor.test.ts +62 -37
- package/src/__tests__/conversation-history-boundary-repair-failure.test.ts +174 -0
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +2 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +2 -0
- package/src/__tests__/conversation-retry-route.test.ts +22 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +2 -0
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +2 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +10 -0
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +2 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +29 -0
- package/src/__tests__/conversation-surface-snapshots.test.ts +543 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +151 -0
- package/src/__tests__/conversation-surfaces-point-at-budget.test.ts +63 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +23 -0
- package/src/__tests__/conversation-undo.test.ts +61 -0
- package/src/__tests__/credential-execution-client.test.ts +6 -6
- package/src/__tests__/credential-prompt-route.test.ts +35 -3
- package/src/__tests__/cu-unified-flow.test.ts +82 -1
- package/src/__tests__/db-mode-sessions-migration.test.ts +175 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +2 -0
- package/src/__tests__/dm-backfill.test.ts +91 -1
- package/src/__tests__/document-create-route.test.ts +88 -0
- package/src/__tests__/document-sync-tags.test.ts +27 -0
- package/src/__tests__/emit-signal-routing-intent.test.ts +142 -2
- package/src/__tests__/events-tail-route.test.ts +25 -0
- package/src/__tests__/evict-conversations-for-reload.test.ts +57 -8
- package/src/__tests__/guardian-action-sweep.test.ts +16 -0
- package/src/__tests__/guardian-dispatch.test.ts +13 -0
- package/src/__tests__/headless-browser-interactions.test.ts +64 -20
- package/src/__tests__/heartbeat-service.test.ts +2 -59
- package/src/__tests__/helpers/mock-conversation.ts +21 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +2 -0
- package/src/__tests__/helpers/verification-sessions-ipc-sim.ts +5 -0
- package/src/__tests__/host-cu-proxy.test.ts +46 -2
- package/src/__tests__/http-user-message-parity.test.ts +2 -0
- package/src/__tests__/image-credentials.test.ts +49 -0
- package/src/__tests__/image-service-dispatcher.test.ts +45 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +1 -1
- package/src/__tests__/interrupt-on-send.test.ts +57 -43
- package/src/__tests__/interrupt-turn-note.test.ts +5 -6
- package/src/__tests__/llm-catalog-parity.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +49 -1
- package/src/__tests__/message-provenance-contact-id.test.ts +69 -0
- package/src/__tests__/migration-export-to-gcs.test.ts +142 -0
- package/src/__tests__/mode-session-history.test.ts +245 -0
- package/src/__tests__/mode-session-recovery.test.ts +222 -0
- package/src/__tests__/mode-session-wire.test.ts +141 -0
- package/src/__tests__/notification-guardian-path.test.ts +7 -0
- package/src/__tests__/notification-telegram-adapter.test.ts +2 -2
- package/src/__tests__/notification-vellum-adapter.test.ts +34 -0
- package/src/__tests__/oauth-provider-serializer.test.ts +12 -0
- package/src/__tests__/oauth-providers-routes.test.ts +1 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +2 -0
- package/src/__tests__/plugin-api-provider.test.ts +5 -0
- package/src/__tests__/plugin-api-resolve-credential.test.ts +97 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +9 -0
- package/src/__tests__/process-message-display-content.test.ts +56 -0
- package/src/__tests__/reaction-persistence.test.ts +5 -0
- package/src/__tests__/request-secret-standalone-channel-gate.test.ts +25 -9
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +1 -1
- package/src/__tests__/scripted-turn-metadata-persistence.test.ts +73 -0
- package/src/__tests__/secret-ingress-http.test.ts +2 -0
- package/src/__tests__/secure-keys.test.ts +43 -1
- package/src/__tests__/send-endpoint-busy.test.ts +163 -1
- package/src/__tests__/server-history-render.test.ts +91 -1
- package/src/__tests__/settings-routes.test.ts +50 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +32 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +1 -2
- package/src/__tests__/subagent-manager-notify.test.ts +1 -2
- package/src/__tests__/subagent-notify-parent.test.ts +146 -39
- package/src/__tests__/subagent-notify-stale-rebuild.test.ts +2 -4
- package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +2 -0
- package/src/__tests__/thread-backfill.test.ts +53 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +2 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +3 -1
- package/src/__tests__/tool-start-timestamp.test.ts +2 -0
- package/src/__tests__/twilio-routes.test.ts +1 -0
- package/src/__tests__/web-search-backend-failure.test.ts +1 -1
- package/src/activation/progress-store.test.ts +12 -7
- package/src/agent/loop.ts +99 -41
- package/src/api/events/assistant-turn-start.ts +3 -0
- package/src/api/events/generation-handoff.ts +2 -0
- package/src/api/events/message-complete.ts +2 -0
- package/src/api/events/notification-conversation-created.ts +14 -16
- package/src/api/events/notification-intent.ts +4 -2
- package/src/api/events/tool-result.ts +85 -0
- package/src/api/events/tool-use-start.ts +3 -0
- package/src/api/events/user-message-echo.ts +3 -0
- package/src/api/index.ts +31 -6
- package/src/api/mode-session.test.ts +131 -0
- package/src/api/mode-session.ts +148 -0
- package/src/api/remember-tool.ts +15 -0
- package/src/api/responses/conversation-message.ts +6 -0
- package/src/approvals/AGENTS.md +4 -2
- package/src/browser/__tests__/operations.test.ts +29 -0
- package/src/browser/operation-meta.ts +2 -1
- package/src/browser/operations.ts +29 -0
- package/src/browser/virtual-desktop-target.ts +2 -8
- package/src/bundler/bundle-signer.ts +1 -3
- package/src/calls/__tests__/barge-in-guard.test.ts +3 -0
- package/src/calls/__tests__/call-controller.test.ts +94 -0
- package/src/calls/__tests__/call-funnel-telemetry.test.ts +204 -0
- package/src/calls/__tests__/voice-control-protocol.test.ts +15 -0
- package/src/calls/__tests__/voice-escalation-judge.test.ts +209 -0
- package/src/calls/__tests__/voice-leg-coordinator.test.ts +168 -0
- package/src/{live-voice/__tests__/live-voice-metrics.test.ts → calls/__tests__/voice-metrics.test.ts} +32 -38
- package/src/calls/__tests__/voice-session-bridge.test.ts +576 -122
- package/src/calls/barge-in-guard.ts +5 -0
- package/src/calls/call-controller.ts +196 -1
- package/src/calls/call-domain.ts +4 -0
- package/src/calls/call-store.ts +87 -2
- package/src/calls/guardian-action-sweep.ts +22 -8
- package/src/calls/media-stream-audio-transcode.ts +1 -3
- package/src/calls/typesafe-noul.ts +156 -0
- package/src/calls/voice-control-protocol.ts +6 -0
- package/src/calls/voice-escalation-judge.ts +145 -0
- package/src/calls/voice-escalation-target.ts +10 -0
- package/src/calls/voice-leg-coordinator.ts +121 -3
- package/src/{live-voice/live-voice-metrics.ts → calls/voice-metrics.ts} +94 -87
- package/src/calls/voice-session-bridge.ts +256 -112
- package/src/calls/voice-triage-escalate.ts +7 -0
- package/src/cli/__tests__/roadmap-cli.test.ts +4 -41
- package/src/cli/commands/__tests__/notifications.test.ts +35 -10
- package/src/cli/commands/browser.help.ts +4 -5
- package/src/cli/commands/browser.ts +0 -1
- package/src/cli/commands/clients.help.ts +46 -0
- package/src/cli/commands/clients.ts +116 -0
- package/src/cli/commands/credentials.help.ts +6 -1
- package/src/cli/commands/notifications.help.ts +16 -2
- package/src/cli/commands/notifications.ts +30 -8
- package/src/cli/commands/roadmap.help.ts +18 -21
- package/src/cli/commands/roadmap.ts +4 -21
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +5 -2
- package/src/cli/lib/bundled-marketplace.json +84 -34
- package/src/cli/lib/plugin-marketplace.ts +8 -0
- package/src/cli/lib/publish-plugin.ts +1 -2
- package/src/config/__tests__/default-provider.test.ts +3 -1
- package/src/config/__tests__/memory-retrospective-schema.test.ts +14 -1
- package/src/config/bundled-skills/computer-use/SKILL.md +1 -1
- package/src/config/bundled-skills/computer-use/TOOLS.json +89 -1
- package/src/config/bundled-skills/image-studio/SKILL.md +17 -2
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +7 -11
- package/src/config/bundled-skills/sequences/TOOLS.json +1 -5
- package/src/config/call-site-defaults.ts +9 -0
- package/src/config/feature-flag-registry.json +16 -0
- package/src/config/profile-text-generation.test.ts +2 -2
- package/src/config/schemas/__tests__/tools.test.ts +31 -0
- package/src/config/schemas/call-site-catalog.ts +14 -0
- package/src/config/schemas/channels.ts +0 -18
- package/src/config/schemas/llm.ts +3 -1
- package/src/config/schemas/mcp.ts +2 -1
- package/src/config/schemas/memory-retrospective.ts +11 -2
- package/src/config/schemas/services.ts +15 -6
- package/src/config/schemas/tools.ts +10 -0
- package/src/config/session-groups-gate.ts +21 -0
- package/src/config/skills.ts +2 -6
- package/src/conversations/__tests__/message-consolidation.test.ts +149 -0
- package/src/conversations/message-consolidation.ts +102 -5
- package/src/credential-execution/ces-connect.test.ts +69 -0
- package/src/credential-execution/ces-connect.ts +115 -0
- package/src/credential-execution/ces-runtime.ts +55 -93
- package/src/credential-execution/executable-discovery.ts +1 -11
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +10 -1
- package/src/daemon/__tests__/inference-profile-notification.test.ts +2 -0
- package/src/daemon/browser-mode-session.test.ts +402 -0
- package/src/daemon/browser-mode-session.ts +186 -0
- package/src/daemon/computer-use-mode-session.test.ts +210 -0
- package/src/daemon/computer-use-mode-session.ts +105 -0
- package/src/daemon/config-watcher.ts +10 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +58 -10
- package/src/daemon/conversation-agent-loop.ts +219 -25
- package/src/daemon/conversation-evictor.ts +5 -24
- package/src/daemon/conversation-history.ts +10 -0
- package/src/daemon/conversation-interrupt-repair.ts +4 -43
- package/src/daemon/conversation-interrupt.ts +7 -11
- package/src/daemon/conversation-messaging.ts +58 -5
- package/src/daemon/conversation-mode-session.test.ts +1667 -0
- package/src/daemon/conversation-mode-session.ts +1008 -0
- package/src/daemon/conversation-process.ts +5 -0
- package/src/daemon/conversation-runtime-assembly.ts +10 -20
- package/src/daemon/conversation-skill-tools.ts +1 -0
- package/src/daemon/conversation-store.ts +4 -4
- package/src/daemon/conversation-surface-snapshots.ts +135 -0
- package/src/daemon/conversation-surfaces.ts +113 -5
- package/src/daemon/conversation-tool-setup.ts +8 -3
- package/src/daemon/conversation.ts +143 -41
- package/src/daemon/handlers/config-model.ts +7 -5
- package/src/daemon/handlers/shared.ts +55 -16
- package/src/daemon/host-cu-proxy.ts +51 -22
- package/src/daemon/lifecycle.ts +30 -13
- package/src/daemon/message-protocol.ts +0 -1
- package/src/daemon/message-provenance.ts +28 -4
- package/src/daemon/mode-session-startup-recovery.ts +23 -0
- package/src/daemon/mode-session-tracking.ts +54 -0
- package/src/daemon/process-message.ts +13 -4
- package/src/daemon/virtual-desktop-context.ts +21 -0
- package/src/desktop/__tests__/fake-desktop.ts +1 -0
- package/src/desktop/desktop-accessibility-script.ts +88 -0
- package/src/desktop/desktop-accessibility.test.ts +160 -0
- package/src/desktop/desktop-accessibility.ts +169 -0
- package/src/desktop/desktop-automation-lease.test.ts +76 -68
- package/src/desktop/desktop-automation-lease.ts +41 -50
- package/src/desktop/desktop-browser-endpoint.ts +4 -0
- package/src/desktop/desktop-computer-use-routing.test.ts +330 -0
- package/src/desktop/desktop-computer-use.test.ts +449 -0
- package/src/desktop/desktop-computer-use.ts +502 -0
- package/src/desktop/desktop-dependencies.ts +47 -293
- package/src/desktop/desktop-display.ts +2 -2
- package/src/desktop/desktop-panel-config.test.ts +13 -3
- package/src/desktop/desktop-panel-config.ts +109 -15
- package/src/desktop/desktop-session-manager.test.ts +69 -21
- package/src/desktop/desktop-session-manager.ts +76 -22
- package/src/desktop/desktop-stream-bridge.test.ts +11 -122
- package/src/desktop/desktop-stream-bridge.ts +6 -8
- package/src/desktop/desktop-window-theme.ts +5 -25
- package/src/desktop/virtual-desktop-feature.ts +52 -2
- package/src/desktop/virtual-desktop-platform.test.ts +5 -9
- package/src/documents/document-store.ts +23 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +22 -26
- package/src/heartbeat/heartbeat-service.ts +5 -33
- package/src/ipc/__tests__/browser-ipc.test.ts +215 -6
- package/src/ipc/assistant-server.ts +2 -0
- package/src/ipc/routes/__tests__/channel-reply-ipc-routes.test.ts +111 -0
- package/src/ipc/routes/channel-reply-ipc-routes.ts +73 -0
- package/src/live-voice/__tests__/continuation-judge.test.ts +151 -0
- package/src/live-voice/__tests__/live-activity-reporter.test.ts +154 -15
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +743 -31
- package/src/live-voice/__tests__/live-voice-look-follow-up.test.ts +191 -10
- package/src/live-voice/__tests__/live-voice-session-groups-gate.test.ts +87 -0
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +5 -1
- package/src/live-voice/__tests__/live-voice-sight-frame-echo.test.ts +41 -0
- package/src/live-voice/__tests__/live-voice-sight-frame.test.ts +1017 -9
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +224 -1
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +101 -0
- package/src/live-voice/__tests__/live-voice-tts.test.ts +44 -0
- package/src/live-voice/__tests__/live-voice-vad.test.ts +939 -75
- package/src/live-voice/__tests__/microphone-idle-gate.test.ts +87 -0
- package/src/live-voice/__tests__/session-controls.test.ts +23 -0
- package/src/live-voice/__tests__/task-outcomes.test.ts +117 -0
- package/src/live-voice/__tests__/voice-input-diagnostics.test.ts +117 -0
- package/src/live-voice/camera-mode-session.test.ts +265 -0
- package/src/live-voice/camera-mode-session.ts +277 -0
- package/src/live-voice/continuation-judge.ts +123 -0
- package/src/live-voice/live-activity-reporter.ts +115 -6
- package/src/live-voice/live-voice-manager.ts +36 -1
- package/src/live-voice/live-voice-photo.ts +88 -7
- package/src/live-voice/live-voice-session-manager.ts +15 -0
- package/src/live-voice/live-voice-session.ts +1443 -747
- package/src/live-voice/live-voice-tts.ts +22 -4
- package/src/live-voice/microphone-idle-gate.ts +56 -0
- package/src/live-voice/protocol.ts +171 -4
- package/src/live-voice/session-controls.ts +11 -3
- package/src/live-voice/task-outcomes.ts +131 -0
- package/src/live-voice/voice-input-diagnostics.ts +117 -0
- package/src/mcp/__tests__/manager-tool-caps.test.ts +63 -18
- package/src/mcp/__tests__/tool-caps.test.ts +28 -1
- package/src/mcp/manager.ts +3 -0
- package/src/mcp/tool-caps.ts +12 -4
- package/src/media/__tests__/image-models.test.ts +58 -0
- package/src/media/image-credentials.ts +5 -0
- package/src/media/image-models.ts +52 -0
- package/src/media/image-service.ts +8 -0
- package/src/media/openrouter-image-service.test.ts +133 -0
- package/src/media/openrouter-image-service.ts +153 -0
- package/src/media/types.ts +1 -1
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +65 -11
- package/src/messaging/providers/discord/send.ts +4 -17
- package/src/messaging/providers/discord/transport.ts +2 -2
- package/src/messaging/providers/outlook/client.ts +16 -22
- package/src/messaging/providers/telegram-bot/send.test.ts +236 -1
- package/src/messaging/providers/telegram-bot/send.ts +10 -7
- package/src/messaging/providers/telegram-bot/transport.ts +3 -10
- package/src/messaging/providers/whatsapp/send.test.ts +169 -4
- package/src/monitoring/__tests__/control.test.ts +17 -5
- package/src/monitoring/control.ts +15 -5
- package/src/notifications/AGENTS.md +1 -1
- package/src/notifications/README.md +83 -99
- package/src/notifications/__tests__/broadcaster.test.ts +1 -1
- package/src/notifications/__tests__/channel-allowlist.test.ts +39 -0
- package/src/notifications/__tests__/copy-composer.test.ts +1 -1
- package/src/notifications/__tests__/decision-engine.test.ts +79 -2
- package/src/notifications/__tests__/deterministic-checks.test.ts +10 -10
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +93 -4
- package/src/notifications/__tests__/notification-utils.test.ts +18 -0
- package/src/notifications/adapters/macos.ts +37 -46
- package/src/notifications/broadcaster.ts +5 -6
- package/src/notifications/channel-allowlist.ts +44 -0
- package/src/notifications/copy-composer.ts +0 -23
- package/src/notifications/decision-engine.ts +24 -14
- package/src/notifications/deterministic-checks.ts +1 -1
- package/src/notifications/emit-signal.ts +123 -37
- package/src/notifications/home-feed-side-effect.ts +9 -7
- package/src/notifications/notification-utils.ts +19 -0
- package/src/notifications/signal.ts +4 -19
- package/src/notifications/types.ts +15 -0
- package/src/oauth/connection-resolver.ts +1 -2
- package/src/oauth/oauth-store.ts +1 -3
- package/src/oauth/provider-serializer.ts +7 -0
- package/src/oauth/seed-providers.ts +30 -0
- package/src/onboarding/onboarding-events-store.ts +99 -12
- package/src/persistence/__tests__/client-connection-events-store.test.ts +322 -0
- package/src/persistence/client-connection-events-store.ts +377 -0
- package/src/persistence/conversation-crud.ts +55 -6
- package/src/persistence/conversation-mode-sessions.test.ts +424 -0
- package/src/persistence/conversation-mode-sessions.ts +460 -0
- package/src/persistence/conversation-queries.ts +6 -19
- package/src/persistence/llm-usage-store.ts +3 -9
- package/src/persistence/message-metadata.ts +25 -0
- package/src/persistence/migrations/381-create-conversation-mode-sessions.ts +41 -0
- package/src/persistence/migrations/382-create-client-connection-events.ts +40 -0
- package/src/persistence/migrations/__tests__/382-create-client-connection-events.test.ts +56 -0
- package/src/persistence/schema/conversations.ts +67 -0
- package/src/persistence/schema/infrastructure.ts +29 -0
- package/src/persistence/steps.ts +17 -0
- package/src/plugin-api/__tests__/plugin-name-env.test.ts +249 -0
- package/src/plugin-api/effective-context-window.ts +33 -0
- package/src/plugin-api/index.ts +24 -5
- package/src/plugin-api/plugin-name-env.ts +125 -0
- package/src/plugin-api/resolve-credential.ts +79 -20
- package/src/plugin-api/vision-support.test.ts +22 -0
- package/src/plugin-api/vision-support.ts +17 -5
- package/src/plugins/__tests__/active-plugin-env.test.ts +136 -0
- package/src/plugins/active-plugin-env.ts +51 -0
- package/src/plugins/defaults/index.ts +24 -0
- package/src/plugins/defaults/memory/__tests__/archive-removal-framing.test.ts +64 -0
- package/src/plugins/defaults/memory/__tests__/worker-control.test.ts +19 -6
- package/src/plugins/defaults/memory/context-search/agent-protocol.ts +9 -12
- package/src/plugins/defaults/memory/context-search/agent-runner.ts +78 -22
- package/src/plugins/defaults/memory/context-search/format.ts +51 -7
- package/src/plugins/defaults/memory/context-search/limits.ts +10 -12
- package/src/plugins/defaults/memory/context-search/recall-input.ts +38 -0
- package/src/plugins/defaults/memory/context-search/search.ts +8 -14
- package/src/plugins/defaults/memory/context-search/sources/conversations.ts +1 -0
- package/src/plugins/defaults/memory/context-search/types.ts +1 -11
- package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +11 -4
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +12 -21
- package/src/plugins/defaults/memory/graph/tools.ts +35 -64
- package/src/plugins/defaults/memory/src/memory-eval-routes.ts +2 -3
- package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +5 -0
- package/src/plugins/defaults/memory/src/memory-item-routes.ts +2 -1
- package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +2 -2
- package/src/plugins/defaults/memory/tools.test.ts +124 -9
- package/src/plugins/defaults/memory/tools.ts +38 -11
- package/src/plugins/defaults/memory/v3/__tests__/pool-log-store.test.ts +165 -27
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +626 -27
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +46 -27
- package/src/plugins/defaults/memory/v3/orchestrate.ts +78 -38
- package/src/plugins/defaults/memory/v3/pool-log-store.ts +65 -79
- package/src/plugins/defaults/memory/v3/pool-select.test.ts +14 -5
- package/src/plugins/defaults/memory/v3/pool-select.ts +683 -44
- package/src/plugins/defaults/memory/worker-control.ts +15 -5
- package/src/plugins/defaults/task-progress/__tests__/registration.test.ts +70 -0
- package/src/plugins/defaults/task-progress/__tests__/task-progress-context.test.ts +380 -0
- package/src/plugins/defaults/task-progress/hooks/post-compact.ts +19 -0
- package/src/plugins/defaults/task-progress/hooks/user-prompt-submit.ts +24 -0
- package/src/plugins/defaults/task-progress/package.json +14 -0
- package/src/plugins/defaults/task-progress/src/apply-task-progress-context.ts +93 -0
- package/src/plugins/defaults/task-progress/src/format-task-progress-context.ts +67 -0
- package/src/providers/__tests__/context-overflow-error.test.ts +10 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +18 -0
- package/src/providers/anthropic/client.ts +10 -1
- package/src/providers/anthropic-gateway-shared.ts +6 -0
- package/src/providers/fetch-provider-catalog.ts +11 -0
- package/src/providers/gemini/client.ts +25 -8
- package/src/providers/inference/adapter-factory.ts +1 -1
- package/src/providers/jev/client.test.ts +10 -0
- package/src/providers/jev/client.ts +20 -4
- package/src/providers/model-catalog.ts +4 -3
- package/src/providers/openai/__tests__/chat-completions-extra-body.test.ts +94 -1
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +106 -1
- package/src/providers/openai/__tests__/chat-template-flatten.test.ts +24 -0
- package/src/providers/openai/__tests__/google-thought-signature.test.ts +1 -2
- package/src/providers/openai/chat-completions-provider.ts +100 -29
- package/src/providers/openai/google-thought-signature.ts +0 -6
- package/src/providers/openai/responses-provider.ts +23 -1
- package/src/providers/ratelimit.ts +1 -3
- package/src/providers/search-provider-catalog.ts +24 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +24 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +7 -1
- package/src/providers/speech-to-text/__tests__/vellum-managed-realtime.test.ts +50 -1
- package/src/providers/speech-to-text/deepgram-flux-frames.ts +11 -0
- package/src/providers/speech-to-text/vellum-managed-flux-realtime.ts +13 -0
- package/src/providers/types.ts +5 -0
- package/src/routes/control.ts +7 -5
- package/src/runtime/AGENTS.md +4 -2
- package/src/runtime/actor-trust-resolver.ts +3 -3
- package/src/runtime/agent-wake.ts +1 -1
- package/src/runtime/approval-message-composer.ts +3 -69
- package/src/runtime/assistant-event-hub.ts +73 -75
- package/src/runtime/assistant-event-publish-options.ts +7 -0
- package/src/runtime/assistant-event-targeting.ts +79 -0
- package/src/runtime/assistant-stream-state.ts +13 -100
- package/src/runtime/background-job-runner.ts +5 -5
- package/src/runtime/channel-retry-sweep.ts +1 -0
- package/src/runtime/guardian-action-message-composer.ts +8 -161
- package/src/runtime/guardian-reply-router.ts +28 -32
- package/src/runtime/http-types.ts +6 -0
- package/src/runtime/message-composer-types.ts +3 -61
- package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +67 -1
- package/src/runtime/migrations/vbundle-builder.ts +24 -1
- package/src/runtime/migrations/vbundle-import-analyzer.ts +13 -4
- package/src/runtime/migrations/vbundle-import-policy.ts +10 -0
- package/src/runtime/migrations/vbundle-importer.ts +4 -1
- package/src/runtime/migrations/vbundle-streaming-importer.ts +4 -1
- package/src/runtime/migrations/vbundle-validator.ts +1 -0
- package/src/runtime/pending-interactions-mode-session.test.ts +62 -0
- package/src/runtime/pending-interactions.ts +29 -0
- package/src/runtime/routes/__tests__/client-history-routes.test.ts +104 -0
- package/src/runtime/routes/__tests__/image-generation-routes.test.ts +97 -0
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/roadmap-routes.test.ts +29 -6
- package/src/runtime/routes/browser-context.ts +31 -11
- package/src/runtime/routes/browser-routes.ts +43 -4
- package/src/runtime/routes/btw-routes.ts +9 -4
- package/src/runtime/routes/client-routes.ts +108 -0
- package/src/runtime/routes/conversation-management-routes.ts +4 -1
- package/src/runtime/routes/conversation-routes.ts +113 -27
- package/src/runtime/routes/credential-prompt-routes.ts +4 -3
- package/src/runtime/routes/credential-routes.ts +1 -2
- package/src/runtime/routes/desktop-setup-routes.test.ts +9 -18
- package/src/runtime/routes/desktop-setup-routes.ts +4 -6
- package/src/runtime/routes/documents-routes.ts +51 -0
- package/src/runtime/routes/email-routes.ts +3 -7
- package/src/runtime/routes/events-routes.ts +75 -54
- package/src/runtime/routes/identity-routes.ts +1 -5
- package/src/runtime/routes/image-generation-routes.ts +8 -14
- package/src/runtime/routes/inbound-message-handler.ts +35 -38
- package/src/runtime/routes/inbound-stages/backfill-sender-provenance.test.ts +168 -0
- package/src/runtime/routes/inbound-stages/backfill-sender-provenance.ts +96 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +38 -9
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +2 -5
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +2 -0
- package/src/runtime/routes/llm-context-normalization.ts +1 -7
- package/src/runtime/routes/migration-routes.ts +73 -2
- package/src/runtime/routes/notification-routes.ts +10 -0
- package/src/runtime/routes/oauth-providers.ts +7 -0
- package/src/runtime/routes/plugins-routes.ts +6 -0
- package/src/runtime/routes/roadmap-routes.ts +47 -8
- package/src/runtime/routes/secret-routes.ts +1 -1
- package/src/runtime/routes/settings-routes.ts +10 -4
- package/src/runtime/routes/watcher-routes.ts +1 -3
- package/src/runtime/trust-class.test.ts +7 -6
- package/src/runtime/trust-class.ts +9 -17
- package/src/schedule/__tests__/worker-control.test.ts +36 -5
- package/src/schedule/worker-control.ts +15 -5
- package/src/security/secure-keys.ts +53 -103
- package/src/skills/clawhub.ts +3 -8
- package/src/skills/managed-store.ts +1 -5
- package/src/stt/types.ts +4 -0
- package/src/subagent/notify.ts +54 -34
- package/src/subagent/parent-notification.ts +6 -0
- package/src/telemetry/__tests__/phone-call-funnel.test.ts +72 -0
- package/src/telemetry/phone-call-funnel.ts +144 -0
- package/src/tools/__tests__/tool-schema-root-combinator-guard.test.ts +81 -0
- package/src/tools/ask-question/ask-question-tool.ts +6 -4
- package/src/tools/browser/browser-execution.ts +22 -59
- package/src/tools/browser/cdp-client/__tests__/cdp-dom-helpers.test.ts +561 -39
- package/src/tools/browser/cdp-client/cdp-dom-helpers.ts +435 -39
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +1 -8
- package/src/tools/client-os.ts +15 -0
- package/src/tools/computer-use/skill-proxy-bridge.ts +1 -1
- package/src/tools/computer-use/target.ts +42 -0
- package/src/tools/document/document-tool.ts +13 -18
- package/src/tools/execution-target.ts +14 -16
- package/src/tools/host-terminal/host-shell.ts +4 -1
- package/src/tools/network/__tests__/web-fetch-tinyfish.test.ts +250 -0
- package/src/tools/network/__tests__/web-search.test.ts +203 -0
- package/src/tools/network/web-fetch.ts +274 -7
- package/src/tools/network/web-search.ts +468 -6
- package/src/tools/permission-checker.ts +3 -3
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/skills/load.ts +2 -1
- package/src/tools/skills/sandbox-runner.ts +11 -2
- package/src/tools/skills/skill-script-runner.ts +7 -0
- package/src/tools/skills/skill-tool-factory.ts +15 -1
- package/src/tools/terminal/__tests__/safe-env.test.ts +11 -0
- package/src/tools/terminal/safe-env.ts +4 -0
- package/src/tools/terminal/shell.ts +2 -0
- package/src/tools/tool-approval-handler.ts +5 -1
- package/src/tools/tool-types.ts +3 -3
- package/src/tools/types.ts +8 -2
- package/src/util/__tests__/worker-process-command.test.ts +5 -4
- package/src/util/abort-reasons.ts +18 -26
- package/src/util/canonicalize-identity.test.ts +21 -0
- package/src/util/canonicalize-identity.ts +16 -0
- package/src/util/errors.ts +13 -3
- package/src/util/provider-error-patterns.ts +3 -0
- package/src/util/worker-process.ts +77 -35
- package/src/workspace/migrations/157-add-desktop-files-launcher.ts +94 -0
- package/src/workspace/migrations/__tests__/156-extract-workspace-mcp-json.test.ts +4 -10
- package/src/workspace/migrations/__tests__/157-add-desktop-files-launcher.test.ts +113 -0
- package/src/workspace/migrations/registry.ts +2 -0
- package/src/__tests__/computer-use-window-schema.test.ts +0 -24
- package/src/api/events/heartbeat-alert.ts +0 -20
- package/src/daemon/message-types/web-activity.ts +0 -65
- package/src/desktop/desktop-dependencies.test.ts +0 -131
- package/src/tools/computer-use/definitions.ts +0 -607
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provenance for backfilled Slack rows, resolved per sender.
|
|
3
|
+
*
|
|
4
|
+
* A backfilled row was written by someone other than the live inbound actor,
|
|
5
|
+
* so the live turn's trust context says nothing about it. Each sender is
|
|
6
|
+
* classified by the same gateway verdict live ingress uses
|
|
7
|
+
* (`resolve_inbound_trust`), so a backfilled row and a live row from the same
|
|
8
|
+
* person carry the same trust class and contact id. The verdict answers for
|
|
9
|
+
* the contact list at import time, which is when the row is written.
|
|
10
|
+
*
|
|
11
|
+
* When the verdict is unreadable or unusable, the row falls back to the
|
|
12
|
+
* guardian-address comparison, carries no contact id, and is marked
|
|
13
|
+
* `provenanceLookupFailed` so it stays distinguishable from a stranger.
|
|
14
|
+
*
|
|
15
|
+
* A read goes through `readInboundTrust`, so it also refreshes the
|
|
16
|
+
* member-verdict cache for that sender, as a live inbound read does.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { readInboundTrust } from "../../../calls/inbound-trust-reader.js";
|
|
20
|
+
import type { ActorAuthorProvenance } from "../../../daemon/message-provenance.js";
|
|
21
|
+
import type { Message as ProviderMessage } from "../../../messaging/provider-types.js";
|
|
22
|
+
import { inboundIdentitiesMatch } from "../../../util/canonicalize-identity.js";
|
|
23
|
+
import type { TrustClass } from "../../trust-class.js";
|
|
24
|
+
import {
|
|
25
|
+
verdictMemberFromVerdict,
|
|
26
|
+
verdictUsability,
|
|
27
|
+
} from "../../trust-verdict-consumer.js";
|
|
28
|
+
|
|
29
|
+
export interface BackfilledSenderProvenance extends ActorAuthorProvenance {
|
|
30
|
+
provenanceTrustClass: TrustClass;
|
|
31
|
+
/** The lookup ran and returned no usable verdict; see `messageMetadataSchema`. */
|
|
32
|
+
provenanceLookupFailed?: true;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Resolves a backfilled message's sender provenance. One resolver serves one
|
|
37
|
+
* backfill pass and reads the gateway at most once per distinct sender.
|
|
38
|
+
*/
|
|
39
|
+
export type BackfilledSenderProvenanceResolver = (
|
|
40
|
+
senderId: string | undefined,
|
|
41
|
+
) => Promise<BackfilledSenderProvenance>;
|
|
42
|
+
|
|
43
|
+
export function createBackfilledSenderProvenanceResolver(
|
|
44
|
+
guardianExternalUserId: string | undefined,
|
|
45
|
+
messages: readonly ProviderMessage[],
|
|
46
|
+
): BackfilledSenderProvenanceResolver {
|
|
47
|
+
const bySender = new Map<string, Promise<BackfilledSenderProvenance>>();
|
|
48
|
+
const resolve: BackfilledSenderProvenanceResolver = (senderId) => {
|
|
49
|
+
const trimmed = senderId?.trim();
|
|
50
|
+
if (!trimmed) {
|
|
51
|
+
return Promise.resolve({ provenanceTrustClass: "unknown" });
|
|
52
|
+
}
|
|
53
|
+
let pending = bySender.get(trimmed);
|
|
54
|
+
if (!pending) {
|
|
55
|
+
pending = resolveSenderProvenance(trimmed, guardianExternalUserId);
|
|
56
|
+
bySender.set(trimmed, pending);
|
|
57
|
+
}
|
|
58
|
+
return pending;
|
|
59
|
+
};
|
|
60
|
+
// Every sender's read starts now, so the pass waits on the slowest read
|
|
61
|
+
// rather than their sum. Bots included: a third-party bot's post is a user
|
|
62
|
+
// row, and singling out this assistant's own posts needs an async lookup.
|
|
63
|
+
// A read reports failure as a result, never a rejection.
|
|
64
|
+
for (const message of messages) {
|
|
65
|
+
void resolve(message.sender?.id);
|
|
66
|
+
}
|
|
67
|
+
return resolve;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function resolveSenderProvenance(
|
|
71
|
+
senderId: string,
|
|
72
|
+
guardianExternalUserId: string | undefined,
|
|
73
|
+
): Promise<BackfilledSenderProvenance> {
|
|
74
|
+
const read = await readInboundTrust({
|
|
75
|
+
channelType: "slack",
|
|
76
|
+
actorExternalId: senderId,
|
|
77
|
+
});
|
|
78
|
+
if (read.ok) {
|
|
79
|
+
const usability = verdictUsability(read.verdict);
|
|
80
|
+
if (usability.usable) {
|
|
81
|
+
const member = verdictMemberFromVerdict(usability.verdict);
|
|
82
|
+
return {
|
|
83
|
+
provenanceTrustClass: usability.verdict.trustClass,
|
|
84
|
+
...(member ? { provenanceContactId: member.contactId } : {}),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
provenanceTrustClass:
|
|
90
|
+
guardianExternalUserId !== undefined &&
|
|
91
|
+
inboundIdentitiesMatch("slack", senderId, guardianExternalUserId)
|
|
92
|
+
? "guardian"
|
|
93
|
+
: "unknown",
|
|
94
|
+
provenanceLookupFailed: true,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
@@ -173,10 +173,10 @@ import {
|
|
|
173
173
|
} from "../../../daemon/conversation-registry.js";
|
|
174
174
|
import type { TrustContext } from "../../../daemon/trust-context-types.js";
|
|
175
175
|
import type { MessageProcessor } from "../../http-types.js";
|
|
176
|
+
import { hasDeliverableAssistantText } from "../../no-response.js";
|
|
176
177
|
import {
|
|
177
178
|
isBoundGuardianActor,
|
|
178
179
|
processChannelMessageInBackground,
|
|
179
|
-
shouldShowActivityForText,
|
|
180
180
|
shouldShowActivityImmediately,
|
|
181
181
|
} from "./background-dispatch.js";
|
|
182
182
|
import { __resetChannelTurnAdmissionForTests } from "./channel-turn-admission.js";
|
|
@@ -260,6 +260,35 @@ describe("processChannelMessageInBackground — reply delivery", () => {
|
|
|
260
260
|
const flush = (): Promise<void> =>
|
|
261
261
|
new Promise((resolve) => setTimeout(resolve, 10));
|
|
262
262
|
|
|
263
|
+
test("names the inbound sender as the persisted message's author", async () => {
|
|
264
|
+
let capturedAuthor: TrustContext | undefined;
|
|
265
|
+
const processMessage: MessageProcessor = async (
|
|
266
|
+
_conversationId,
|
|
267
|
+
_content,
|
|
268
|
+
options,
|
|
269
|
+
) => {
|
|
270
|
+
capturedAuthor = options?.author;
|
|
271
|
+
return { messageId: "user-msg-author" };
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
processChannelMessageInBackground({
|
|
275
|
+
processMessage,
|
|
276
|
+
conversationId: "conv-author",
|
|
277
|
+
eventId: "evt-author",
|
|
278
|
+
content: "the export endpoint needs a scoped token",
|
|
279
|
+
sourceChannel: "slack",
|
|
280
|
+
sourceInterface: "slack",
|
|
281
|
+
externalChatId: "C-AUTHOR",
|
|
282
|
+
trustCtx,
|
|
283
|
+
metadataHints: [],
|
|
284
|
+
replyCallbackUrl: "https://example.test/deliver/slack?channel=C-AUTHOR",
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
await flush();
|
|
288
|
+
|
|
289
|
+
expect(capturedAuthor).toBe(trustCtx);
|
|
290
|
+
});
|
|
291
|
+
|
|
263
292
|
test("records callback delivery failures without failing processing", async () => {
|
|
264
293
|
const conversationId = "conv-delivery-failure";
|
|
265
294
|
const channelId = "C-DELIVERY-FAILURE";
|
|
@@ -1070,14 +1099,14 @@ describe("channel activity timing", () => {
|
|
|
1070
1099
|
});
|
|
1071
1100
|
|
|
1072
1101
|
test("recognizes only deliverable text as a reason to show activity", () => {
|
|
1073
|
-
expect(
|
|
1074
|
-
expect(
|
|
1075
|
-
expect(
|
|
1076
|
-
expect(
|
|
1077
|
-
expect(
|
|
1078
|
-
expect(
|
|
1079
|
-
expect(
|
|
1080
|
-
expect(
|
|
1102
|
+
expect(hasDeliverableAssistantText("")).toBe(false);
|
|
1103
|
+
expect(hasDeliverableAssistantText(" ")).toBe(false);
|
|
1104
|
+
expect(hasDeliverableAssistantText("<")).toBe(false);
|
|
1105
|
+
expect(hasDeliverableAssistantText("<no_response")).toBe(false);
|
|
1106
|
+
expect(hasDeliverableAssistantText("<no_response/>")).toBe(false);
|
|
1107
|
+
expect(hasDeliverableAssistantText(" <no_response /> ")).toBe(false);
|
|
1108
|
+
expect(hasDeliverableAssistantText("Real response.")).toBe(true);
|
|
1109
|
+
expect(hasDeliverableAssistantText("<no_response/>\nReal response.")).toBe(
|
|
1081
1110
|
true,
|
|
1082
1111
|
);
|
|
1083
1112
|
});
|
|
@@ -286,6 +286,7 @@ export function processChannelMessageInBackground(
|
|
|
286
286
|
},
|
|
287
287
|
assistantId,
|
|
288
288
|
trustContext: trustCtx,
|
|
289
|
+
author: trustCtx,
|
|
289
290
|
isInteractive: resolveRoutingState(trustCtx).promptWaitingAllowed,
|
|
290
291
|
...(displayContent !== undefined ? { displayContent } : {}),
|
|
291
292
|
...(cmdIntent ? { commandIntent: cmdIntent } : {}),
|
|
@@ -452,10 +453,6 @@ type ChannelActivityController = {
|
|
|
452
453
|
stop: () => void;
|
|
453
454
|
};
|
|
454
455
|
|
|
455
|
-
export function shouldShowActivityForText(text: string): boolean {
|
|
456
|
-
return hasDeliverableAssistantText(text);
|
|
457
|
-
}
|
|
458
|
-
|
|
459
456
|
/**
|
|
460
457
|
* Room shapes with one other participant, in each channel's own word for it.
|
|
461
458
|
*
|
|
@@ -613,7 +610,7 @@ function startChannelActivity(params: {
|
|
|
613
610
|
return;
|
|
614
611
|
}
|
|
615
612
|
observedAssistantText += msg.text;
|
|
616
|
-
if (
|
|
613
|
+
if (hasDeliverableAssistantText(observedAssistantText)) {
|
|
617
614
|
show();
|
|
618
615
|
}
|
|
619
616
|
},
|
|
@@ -35,6 +35,7 @@ import { createApprovalCopyGenerator } from "../../../daemon/approval-generators
|
|
|
35
35
|
import { findConversation } from "../../../daemon/conversation-registry.js";
|
|
36
36
|
import { getDiskPressureStatus } from "../../../daemon/disk-pressure-guard.js";
|
|
37
37
|
import { classifyDiskPressureTurnPolicy } from "../../../daemon/disk-pressure-policy.js";
|
|
38
|
+
import { actorAuthorProvenance } from "../../../daemon/message-provenance.js";
|
|
38
39
|
import { processMessage } from "../../../daemon/process-message.js";
|
|
39
40
|
import { renderReactionHistoryText } from "../../../daemon/reaction-history-render.js";
|
|
40
41
|
import type { TrustContext } from "../../../daemon/trust-context-types.js";
|
|
@@ -544,6 +545,7 @@ async function persistReactionAsMessage(params: {
|
|
|
544
545
|
{
|
|
545
546
|
metadata: {
|
|
546
547
|
...provenanceFromTrustContext(params.trustCtx),
|
|
548
|
+
...actorAuthorProvenance(params.trustCtx),
|
|
547
549
|
...buildReactionRowEnvelope(facts),
|
|
548
550
|
},
|
|
549
551
|
skipIndexing: true,
|
|
@@ -1025,7 +1025,7 @@ function anthropicMessageSections(
|
|
|
1025
1025
|
toolName: asString(block.name) ?? asString(block.tool_use_id),
|
|
1026
1026
|
data:
|
|
1027
1027
|
type === "web_search_tool_result"
|
|
1028
|
-
?
|
|
1028
|
+
? sanitizeAnthropicStructuredValue(block)
|
|
1029
1029
|
: undefined,
|
|
1030
1030
|
text: collectAnthropicToolResultText(block),
|
|
1031
1031
|
});
|
|
@@ -1397,12 +1397,6 @@ function collectAnthropicToolResultText(
|
|
|
1397
1397
|
return collectAnthropicText(block.content);
|
|
1398
1398
|
}
|
|
1399
1399
|
|
|
1400
|
-
function sanitizeAnthropicWebSearchToolResultData(
|
|
1401
|
-
block: Record<string, unknown>,
|
|
1402
|
-
): unknown {
|
|
1403
|
-
return sanitizeAnthropicStructuredValue(block);
|
|
1404
|
-
}
|
|
1405
|
-
|
|
1406
1400
|
function sanitizeAnthropicStructuredValue(value: unknown): unknown {
|
|
1407
1401
|
if (Array.isArray(value)) {
|
|
1408
1402
|
return value.map((entry) => sanitizeAnthropicStructuredValue(entry));
|
|
@@ -20,11 +20,13 @@ import { createReadStream } from "node:fs";
|
|
|
20
20
|
import { hostname } from "node:os";
|
|
21
21
|
import { PassThrough, Readable } from "node:stream";
|
|
22
22
|
|
|
23
|
+
import { GatewayDebugExportIpcResponseSchema } from "@vellumai/gateway-client/gateway-ipc-contracts";
|
|
23
24
|
import { z } from "zod";
|
|
24
25
|
|
|
25
26
|
import { invalidateConfigCache } from "../../config/loader.js";
|
|
26
27
|
import { resolvePlatformAssistantId } from "../../config/platform-identity.js";
|
|
27
28
|
import { getAssistantName } from "../../daemon/identity-helpers.js";
|
|
29
|
+
import { ipcCallPersistent } from "../../ipc/gateway-client.js";
|
|
28
30
|
import { runAsyncSqlite } from "../../persistence/db-async-query.js";
|
|
29
31
|
import {
|
|
30
32
|
getDb,
|
|
@@ -470,8 +472,40 @@ const EXPORT_TO_GCS_PUT_TIMEOUT_MS = 60 * 60 * 1000;
|
|
|
470
472
|
const MigrationExportToGcsBody = z.object({
|
|
471
473
|
upload_url: z.string().url(),
|
|
472
474
|
description: z.string().optional(),
|
|
475
|
+
/**
|
|
476
|
+
* `debug`: a bundle for Vellum staff to inspect. Adds the gateway's
|
|
477
|
+
* database and recent logs under `gateway/`. `migration` is the default.
|
|
478
|
+
*/
|
|
479
|
+
profile: z.enum(["migration", "debug"]).default("migration"),
|
|
473
480
|
});
|
|
474
481
|
|
|
482
|
+
/** Archive path of the gateway's contribution to a debug bundle. */
|
|
483
|
+
export const GATEWAY_DEBUG_EXPORT_PATH = "gateway/export.tar.gz";
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Ask the gateway for its debug archive over the local socket. The daemon
|
|
487
|
+
* cannot read the gateway's files itself: in local mode they sit in the
|
|
488
|
+
* protected directory beside the encryption keys, and in Docker on a volume
|
|
489
|
+
* the daemon does not mount.
|
|
490
|
+
*/
|
|
491
|
+
async function collectGatewayDebugExport(): Promise<{
|
|
492
|
+
archivePath: string;
|
|
493
|
+
data: Uint8Array;
|
|
494
|
+
}> {
|
|
495
|
+
const raw = await ipcCallPersistent(
|
|
496
|
+
"gateway_debug_export",
|
|
497
|
+
{},
|
|
498
|
+
GATEWAY_DEBUG_EXPORT_TIMEOUT_MS,
|
|
499
|
+
);
|
|
500
|
+
const parsed = GatewayDebugExportIpcResponseSchema.parse(raw);
|
|
501
|
+
return {
|
|
502
|
+
archivePath: GATEWAY_DEBUG_EXPORT_PATH,
|
|
503
|
+
data: new Uint8Array(Buffer.from(parsed.archive_base64, "base64")),
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const GATEWAY_DEBUG_EXPORT_TIMEOUT_MS = 120_000;
|
|
508
|
+
|
|
475
509
|
/**
|
|
476
510
|
* Collected credentials plus warning markers if the credential store was
|
|
477
511
|
* unreachable. The caller surfaces the warning in logs; production callers
|
|
@@ -559,9 +593,10 @@ export async function handleMigrationExportToGcs({ body }: RouteHandlerArgs) {
|
|
|
559
593
|
const parsed = MigrationExportToGcsBody.safeParse(body);
|
|
560
594
|
if (!parsed.success) {
|
|
561
595
|
throw new BadRequestError(
|
|
562
|
-
"Request body must be { upload_url: string, description?: string } with a valid URL",
|
|
596
|
+
"Request body must be { upload_url: string, description?: string, profile?: 'migration' | 'debug' } with a valid URL",
|
|
563
597
|
);
|
|
564
598
|
}
|
|
599
|
+
const isDebugProfile = parsed.data.profile === "debug";
|
|
565
600
|
|
|
566
601
|
// ── 2. Validate the upload URL. Never log `parsed.data.upload_url`.
|
|
567
602
|
const validated = validateGcsSignedUrl(
|
|
@@ -608,8 +643,11 @@ export async function handleMigrationExportToGcs({ body }: RouteHandlerArgs) {
|
|
|
608
643
|
// "managed"), and teleport clients re-provision platform identity after
|
|
609
644
|
// a platform→local import — so redact instead of emitting a bundle the
|
|
610
645
|
// importer is guaranteed to reject.
|
|
646
|
+
//
|
|
647
|
+
// A debug bundle goes to Vellum staff, so it never carries credentials
|
|
648
|
+
// either, whatever the deployment mode.
|
|
611
649
|
let collected: CollectedCredentials;
|
|
612
|
-
if (manifestInputs.origin.mode === "managed") {
|
|
650
|
+
if (manifestInputs.origin.mode === "managed" || isDebugProfile) {
|
|
613
651
|
collected = {
|
|
614
652
|
credentials: [],
|
|
615
653
|
unreachable: false,
|
|
@@ -632,17 +670,44 @@ export async function handleMigrationExportToGcs({ body }: RouteHandlerArgs) {
|
|
|
632
670
|
collected.perAccountUnreachable,
|
|
633
671
|
);
|
|
634
672
|
|
|
673
|
+
if (isDebugProfile) {
|
|
674
|
+
manifestInputs = {
|
|
675
|
+
...manifestInputs,
|
|
676
|
+
exportOptions: { ...manifestInputs.exportOptions, include_gateway: true },
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
|
|
635
680
|
// ── 4. Enqueue the job. The runner captures the collected credentials.
|
|
636
681
|
let job;
|
|
637
682
|
try {
|
|
638
683
|
job = migrationJobs.startJob("export", async () => {
|
|
639
684
|
let cleanup: (() => Promise<void>) | undefined;
|
|
640
685
|
try {
|
|
686
|
+
// The gateway snapshot can take a while on a large database, so it
|
|
687
|
+
// runs inside the job (after the export slot is held) rather than
|
|
688
|
+
// before the 202. A debug bundle without the gateway's data is not
|
|
689
|
+
// what staff asked for, so a failure fails the job and nothing is
|
|
690
|
+
// uploaded.
|
|
691
|
+
let extraFiles: Array<{ archivePath: string; data: Uint8Array }> = [];
|
|
692
|
+
if (isDebugProfile) {
|
|
693
|
+
try {
|
|
694
|
+
extraFiles = [await collectGatewayDebugExport()];
|
|
695
|
+
} catch (err) {
|
|
696
|
+
log.error({ err }, "Failed to collect the gateway's debug export");
|
|
697
|
+
const wrapped = new Error(
|
|
698
|
+
"The gateway did not provide its debug export; the bundle was not sent.",
|
|
699
|
+
);
|
|
700
|
+
(wrapped as { code?: string }).code = "gateway_debug_export_failed";
|
|
701
|
+
throw wrapped;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
641
705
|
const result = await streamExportVBundle({
|
|
642
706
|
workspaceDir: getWorkspaceDir(),
|
|
643
707
|
...manifestInputs,
|
|
644
708
|
secretsRedacted,
|
|
645
709
|
credentials: collected.credentials,
|
|
710
|
+
extraFiles,
|
|
646
711
|
checkpoint: checkpointDbsForExport,
|
|
647
712
|
});
|
|
648
713
|
|
|
@@ -2402,6 +2467,12 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
2402
2467
|
.string()
|
|
2403
2468
|
.optional()
|
|
2404
2469
|
.describe("Human-readable export description."),
|
|
2470
|
+
profile: z
|
|
2471
|
+
.enum(["migration", "debug"])
|
|
2472
|
+
.optional()
|
|
2473
|
+
.describe(
|
|
2474
|
+
"Export profile. 'migration' (default) builds a teleport bundle. 'debug' builds a bundle for Vellum staff to open on a debug clone: no credentials, plus the gateway's database and logs under gateway/.",
|
|
2475
|
+
),
|
|
2405
2476
|
}),
|
|
2406
2477
|
responseStatus: "202",
|
|
2407
2478
|
responseBody: z.object({
|
|
@@ -14,6 +14,10 @@ import {
|
|
|
14
14
|
NotificationSourceChannelSchema,
|
|
15
15
|
RoutingIntentSchema,
|
|
16
16
|
} from "../../notifications/signal.js";
|
|
17
|
+
import {
|
|
18
|
+
NotificationDeliveryResultSchema,
|
|
19
|
+
NotificationReceiptClassSchema,
|
|
20
|
+
} from "../../notifications/types.js";
|
|
17
21
|
import { UrgencySchema } from "../../notifications/urgency.js";
|
|
18
22
|
import { getDb } from "../../persistence/db-connection.js";
|
|
19
23
|
import { notificationDeliveries } from "../../persistence/schema/index.js";
|
|
@@ -78,6 +82,9 @@ const EmitSignalResponse = z.object({
|
|
|
78
82
|
dispatched: z.boolean(),
|
|
79
83
|
deduplicated: z.boolean(),
|
|
80
84
|
reason: z.string(),
|
|
85
|
+
selectedChannels: z.array(z.string()),
|
|
86
|
+
deliveryResults: z.array(NotificationDeliveryResultSchema),
|
|
87
|
+
receiptClass: NotificationReceiptClassSchema,
|
|
81
88
|
});
|
|
82
89
|
|
|
83
90
|
async function handleEmitSignal({ body = {} }: RouteHandlerArgs) {
|
|
@@ -94,6 +101,9 @@ async function handleEmitSignal({ body = {} }: RouteHandlerArgs) {
|
|
|
94
101
|
dispatched: result.dispatched,
|
|
95
102
|
deduplicated: result.deduplicated,
|
|
96
103
|
reason: result.reason,
|
|
104
|
+
selectedChannels: result.selectedChannels,
|
|
105
|
+
deliveryResults: result.deliveryResults,
|
|
106
|
+
receiptClass: result.receiptClass,
|
|
97
107
|
};
|
|
98
108
|
}
|
|
99
109
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* the standard runtime auth middleware.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { INTEGRATION_CATEGORIES } from "@vellumai/service-contracts/integration-categories";
|
|
9
10
|
import { z } from "zod";
|
|
10
11
|
|
|
11
12
|
import { loadConfig } from "../../config/loader.js";
|
|
@@ -401,6 +402,12 @@ export const oauthProviderSummarySchema = z.object({
|
|
|
401
402
|
supports_managed_mode: z.boolean(),
|
|
402
403
|
managed_service_is_paid: z.boolean(),
|
|
403
404
|
feature_flag: z.string().nullable(),
|
|
405
|
+
category: z
|
|
406
|
+
.enum(INTEGRATION_CATEGORIES)
|
|
407
|
+
.nullable()
|
|
408
|
+
.describe(
|
|
409
|
+
"Where the integrations catalog files the provider; null for a provider without a seed entry.",
|
|
410
|
+
),
|
|
404
411
|
tenant_host: z
|
|
405
412
|
.object({
|
|
406
413
|
pattern: z.string(),
|
|
@@ -226,6 +226,12 @@ const mcpPluginIntegrationSchema = z.object({
|
|
|
226
226
|
}),
|
|
227
227
|
logo: z.string(),
|
|
228
228
|
oauthProvider: z.string().optional(),
|
|
229
|
+
category: z
|
|
230
|
+
.string()
|
|
231
|
+
.optional()
|
|
232
|
+
.describe(
|
|
233
|
+
"Where the integrations catalog files the entry: a slug from the shared integration-category vocabulary, passed through as the catalog declares it.",
|
|
234
|
+
),
|
|
229
235
|
});
|
|
230
236
|
|
|
231
237
|
const pluginSearchMatchSchema = z.object({
|
|
@@ -379,16 +379,55 @@ const createRequestSchema = z.object({
|
|
|
379
379
|
tags: z.array(z.string()).optional().describe("Tag slugs"),
|
|
380
380
|
});
|
|
381
381
|
|
|
382
|
+
/** Item fields the roadmap service reserves for staff on an update. */
|
|
383
|
+
const STAFF_ONLY_UPDATE_FIELDS = new Set(["status", "tags"]);
|
|
384
|
+
|
|
385
|
+
function listFields(fields: string[]): string {
|
|
386
|
+
return `${fields.join(", ")} ${fields.length === 1 ? "is" : "are"}`;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Why an update carrying fields other than title and description is refused.
|
|
391
|
+
* A staff-only field and an unknown one need different remedies, so each is
|
|
392
|
+
* named for what it is.
|
|
393
|
+
*/
|
|
394
|
+
function unsupportedUpdateFieldsMessage(keys: string[]): string {
|
|
395
|
+
const staffOnly = keys.filter((k) => STAFF_ONLY_UPDATE_FIELDS.has(k));
|
|
396
|
+
const unknown = keys.filter((k) => !STAFF_ONLY_UPDATE_FIELDS.has(k));
|
|
397
|
+
const reasons = [
|
|
398
|
+
...(staffOnly.length > 0
|
|
399
|
+
? [`${listFields(staffOnly)} set by Vellum staff`]
|
|
400
|
+
: []),
|
|
401
|
+
...(unknown.length > 0
|
|
402
|
+
? [`${listFields(unknown)} not a roadmap update field`]
|
|
403
|
+
: []),
|
|
404
|
+
];
|
|
405
|
+
return `An assistant can change only an item's title and description; ${reasons.join("; ")}.`;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Only the fields the roadmap service lets this assistant change. An
|
|
410
|
+
* assistant is always the author tier there, never staff, and an author may
|
|
411
|
+
* edit only an open item's title and description; status and tags are staff
|
|
412
|
+
* triage and answer 403. Strict, so a caller that sends anything else learns
|
|
413
|
+
* why here instead of from the upstream refusal.
|
|
414
|
+
*/
|
|
382
415
|
const updateRequestSchema = z
|
|
383
|
-
.
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
416
|
+
.strictObject(
|
|
417
|
+
{
|
|
418
|
+
title: z.string().optional(),
|
|
419
|
+
description: z.string().optional(),
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
error: (issue) =>
|
|
423
|
+
issue.code === "unrecognized_keys"
|
|
424
|
+
? unsupportedUpdateFieldsMessage(issue.keys)
|
|
425
|
+
: undefined,
|
|
426
|
+
},
|
|
427
|
+
)
|
|
389
428
|
.refine(
|
|
390
429
|
(patch) => Object.values(patch).some((v) => v !== undefined),
|
|
391
|
-
"At least one of title
|
|
430
|
+
"At least one of title or description is required.",
|
|
392
431
|
);
|
|
393
432
|
|
|
394
433
|
type RoadmapItem = z.infer<typeof itemSchema>;
|
|
@@ -684,7 +723,7 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
684
723
|
},
|
|
685
724
|
summary: "Update a roadmap item",
|
|
686
725
|
description:
|
|
687
|
-
"Updates a roadmap item
|
|
726
|
+
"Updates the title or description of a roadmap item this assistant filed, while the item is still open. Status and tags are set by Vellum staff.",
|
|
688
727
|
tags: ["roadmap"],
|
|
689
728
|
pathParams: SLUG_PARAM,
|
|
690
729
|
requestBody: updateRequestSchema,
|
|
@@ -303,7 +303,7 @@ async function handleAddSecret({ body }: RouteHandlerArgs) {
|
|
|
303
303
|
);
|
|
304
304
|
return { success: false, error: validation.reason };
|
|
305
305
|
}
|
|
306
|
-
} else if (name === "
|
|
306
|
+
} else if (name === "typesafe") {
|
|
307
307
|
const validation = await validateJevApiKey(value);
|
|
308
308
|
if (!validation.valid) {
|
|
309
309
|
log.warn(
|
|
@@ -662,10 +662,16 @@ async function handleToolPermissionSimulate({ body = {} }: RouteHandlerArgs) {
|
|
|
662
662
|
const manifestOverride = resolveManifestOverride(toolName);
|
|
663
663
|
// Permission Simulator path: registered tool wins, then explicit
|
|
664
664
|
// manifest override, then the standard inference rules.
|
|
665
|
-
const
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
665
|
+
const tool = getTool(toolName);
|
|
666
|
+
const executionTarget = resolveExecutionTarget(
|
|
667
|
+
{
|
|
668
|
+
name: toolName,
|
|
669
|
+
executionTarget:
|
|
670
|
+
tool?.executionTarget ?? manifestOverride?.execution_target,
|
|
671
|
+
getExecutionTarget: tool?.getExecutionTarget,
|
|
672
|
+
},
|
|
673
|
+
input,
|
|
674
|
+
);
|
|
669
675
|
const executionContext =
|
|
670
676
|
isInteractive === false ? "headless" : "conversation";
|
|
671
677
|
const policyContext = { executionTarget, executionContext } as const;
|
|
@@ -86,7 +86,7 @@ function handleWatcherCreate({ body = {} }: RouteHandlerArgs) {
|
|
|
86
86
|
const credentialService =
|
|
87
87
|
credentialServiceOverride ?? provider.requiredCredentialService;
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
return createWatcher({
|
|
90
90
|
name,
|
|
91
91
|
providerId,
|
|
92
92
|
actionPrompt,
|
|
@@ -94,8 +94,6 @@ function handleWatcherCreate({ body = {} }: RouteHandlerArgs) {
|
|
|
94
94
|
pollIntervalMs,
|
|
95
95
|
configJson: config ? JSON.stringify(config) : null,
|
|
96
96
|
});
|
|
97
|
-
|
|
98
|
-
return watcher;
|
|
99
97
|
}
|
|
100
98
|
|
|
101
99
|
function handleWatcherList({ body = {} }: RouteHandlerArgs) {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { afterEach, describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
+
import { TRUST_CLASS_VALUES } from "@vellumai/gateway-client";
|
|
4
|
+
|
|
3
5
|
import { resolveCapabilities } from "./capabilities.js";
|
|
4
6
|
import {
|
|
5
7
|
derivePersonaTrustFlags,
|
|
6
8
|
isContactTrustClass,
|
|
7
9
|
type PersonaTrustFlags,
|
|
8
|
-
trustClassSchema,
|
|
9
10
|
} from "./trust-class.js";
|
|
10
11
|
|
|
11
12
|
describe("isContactTrustClass", () => {
|
|
@@ -27,7 +28,7 @@ describe("isContactTrustClass", () => {
|
|
|
27
28
|
test("agrees with derivePersonaTrustFlags for every trust class", () => {
|
|
28
29
|
// The predicate and the persona flags encode the same grouping; pin them
|
|
29
30
|
// together so neither can drift without failing here.
|
|
30
|
-
for (const trustClass of
|
|
31
|
+
for (const trustClass of TRUST_CLASS_VALUES) {
|
|
31
32
|
expect(isContactTrustClass(trustClass)).toBe(
|
|
32
33
|
derivePersonaTrustFlags(trustClass).isTrustedContact,
|
|
33
34
|
);
|
|
@@ -46,7 +47,7 @@ describe("derivePersonaTrustFlags", () => {
|
|
|
46
47
|
});
|
|
47
48
|
|
|
48
49
|
test("trusted_contact and unverified_contact derive identical contact flags", () => {
|
|
49
|
-
// The admission-only equivalence documented
|
|
50
|
+
// The admission-only equivalence documented in trust-class.ts: the two
|
|
50
51
|
// classes must never drift apart at the persona layer.
|
|
51
52
|
const expected: PersonaTrustFlags = {
|
|
52
53
|
trustClass: "trusted_contact",
|
|
@@ -82,9 +83,9 @@ describe("derivePersonaTrustFlags", () => {
|
|
|
82
83
|
});
|
|
83
84
|
|
|
84
85
|
test("exactly one flag is true for every trust class", () => {
|
|
85
|
-
// Iterates the
|
|
86
|
+
// Iterates the canonical class list so a newly added class is covered
|
|
86
87
|
// (the helper itself won't compile until the new class gets a case).
|
|
87
|
-
for (const trustClass of
|
|
88
|
+
for (const trustClass of TRUST_CLASS_VALUES) {
|
|
88
89
|
const flags = derivePersonaTrustFlags(trustClass);
|
|
89
90
|
const trueCount = [
|
|
90
91
|
flags.isGuardian,
|
|
@@ -128,7 +129,7 @@ describe("derivePersonaTrustFlags", () => {
|
|
|
128
129
|
isTrustedContact: "social-engineering-defense",
|
|
129
130
|
isStranger: "stranger-warning",
|
|
130
131
|
};
|
|
131
|
-
for (const trustClass of
|
|
132
|
+
for (const trustClass of TRUST_CLASS_VALUES) {
|
|
132
133
|
const flags = derivePersonaTrustFlags(trustClass);
|
|
133
134
|
const guidance = resolveCapabilities(trustClass).promptTrustGuidance;
|
|
134
135
|
for (const [flag, expected] of Object.entries(guidanceByFlag)) {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* persistence schema can share one definition without a circular import.
|
|
2
|
+
* The daemon's reading of an inbound actor's trust class. The vocabulary
|
|
3
|
+
* itself ({@link TrustClass}, `TrustClassSchema`) belongs to the gateway,
|
|
4
|
+
* which classifies every actor; it lives in `@vellumai/gateway-client`
|
|
5
|
+
* (`trust-verdict-contract.ts`) and is re-exported here, never redeclared.
|
|
6
|
+
* This module holds what the daemon derives from a class:
|
|
8
7
|
*
|
|
9
8
|
* - `'guardian'`: The sender matches the active guardian binding for this
|
|
10
9
|
* (assistant, channel). Guardians have full control-plane access and
|
|
@@ -21,21 +20,14 @@
|
|
|
21
20
|
* actors are fail-closed with no escalation path.
|
|
22
21
|
*/
|
|
23
22
|
|
|
24
|
-
import {
|
|
25
|
-
|
|
26
|
-
export const trustClassSchema = z.enum([
|
|
27
|
-
"guardian",
|
|
28
|
-
"trusted_contact",
|
|
29
|
-
"unverified_contact",
|
|
30
|
-
"unknown",
|
|
31
|
-
]);
|
|
23
|
+
import type { TrustClass } from "@vellumai/gateway-client";
|
|
32
24
|
|
|
33
|
-
export type TrustClass
|
|
25
|
+
export type { TrustClass };
|
|
34
26
|
|
|
35
27
|
/**
|
|
36
28
|
* Whether a trust class names a known non-guardian contact — the
|
|
37
29
|
* `trusted_contact` / `unverified_contact` pair whose admission-only
|
|
38
|
-
* equivalence is documented
|
|
30
|
+
* equivalence is documented in this module's header.
|
|
39
31
|
*
|
|
40
32
|
* Accepts a raw string (not just `TrustClass`) because several call sites
|
|
41
33
|
* classify trust classes read back from persisted turn metadata, which may
|
|
@@ -75,7 +67,7 @@ export interface PersonaTrustFlags {
|
|
|
75
67
|
* needs the opposite default — fail closed, so a turn that never resolved an
|
|
76
68
|
* actor still renders the guardrail rather than a guardian exemption.
|
|
77
69
|
* - `unverified_contact` derives identically to `trusted_contact`, making the
|
|
78
|
-
* admission-only equivalence documented
|
|
70
|
+
* admission-only equivalence documented in this module's header
|
|
79
71
|
* executable in one place.
|
|
80
72
|
* - The switch is exhaustive with no default: adding a `TrustClass` member is a
|
|
81
73
|
* compile error here, forcing a deliberate persona decision for the new
|