@vellumai/assistant 0.10.1 → 0.10.2-dev.202606241651.2d2b40d
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/docs/workspace-tools.md +42 -33
- package/eslint-rules/cli-no-daemon-internals.js +6 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts +91 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +31 -0
- package/node_modules/@vellumai/gateway-client/src/guardian-delivery-contract.ts +48 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +14 -0
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +17 -0
- package/openapi.yaml +74 -1
- package/package.json +1 -1
- package/scripts/test.sh +36 -15
- package/src/__tests__/actor-token-service.test.ts +36 -14
- package/src/__tests__/agent-loop-override-profile.test.ts +1 -0
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +2 -0
- package/src/__tests__/annotate-activity-metadata.test.ts +2 -0
- package/src/__tests__/annotate-risk-options.test.ts +2 -0
- package/src/__tests__/approval-cascade.test.ts +2 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +2 -0
- package/src/__tests__/btw-routes.test.ts +2 -0
- package/src/__tests__/build-persisted-content.test.ts +2 -0
- package/src/__tests__/call-controller.test.ts +19 -0
- package/src/__tests__/channel-guardian.test.ts +94 -58
- package/src/__tests__/channel-reply-delivery.test.ts +2 -0
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/compaction.benchmark.test.ts +2 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +2 -0
- package/src/__tests__/compactor-low-watermark-cut.test.ts +2 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +2 -0
- package/src/__tests__/compactor-summary-call-truncation.test.ts +2 -0
- package/src/__tests__/compactor-web-search-strip.test.ts +2 -0
- package/src/__tests__/computer-use-tools.test.ts +13 -0
- package/src/__tests__/config-loader-backfill.test.ts +5 -1
- package/src/__tests__/config-schema.test.ts +1 -0
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +31 -29
- package/src/__tests__/contacts-relay-reads.test.ts +13 -15
- package/src/__tests__/conversation-abort-tool-results.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop.test.ts +7 -0
- package/src/__tests__/conversation-analysis-routes.test.ts +2 -0
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +2 -0
- package/src/__tests__/conversation-confirmation-signals.test.ts +2 -0
- package/src/__tests__/conversation-history-web-search.test.ts +2 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +2 -0
- package/src/__tests__/conversation-load-history-stripped.test.ts +2 -0
- package/src/__tests__/conversation-pairing.test.ts +2 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +2 -0
- package/src/__tests__/conversation-process-callsite.test.ts +2 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -0
- package/src/__tests__/conversation-queue.test.ts +91 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +14 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +14 -0
- package/src/__tests__/conversation-slash-queue.test.ts +2 -0
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -0
- package/src/__tests__/conversation-speed-override.test.ts +2 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +65 -0
- package/src/__tests__/conversation-title-service.test.ts +2 -0
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +47 -0
- package/src/__tests__/conversation-usage.test.ts +2 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +2 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +2 -0
- package/src/__tests__/credential-security-invariants.test.ts +0 -1
- package/src/__tests__/db-migration-rollback.test.ts +205 -171
- package/src/__tests__/db-test-helpers.ts +5 -4
- package/src/__tests__/deterministic-verification-control-plane.test.ts +4 -2
- package/src/__tests__/disk-pressure-guard.test.ts +41 -0
- package/src/__tests__/dm-persistence.test.ts +2 -0
- package/src/__tests__/emit-signal-routing-intent.test.ts +10 -5
- package/src/__tests__/events-dev-bypass-actor.test.ts +7 -1
- package/src/__tests__/filing-service.test.ts +2 -0
- package/src/__tests__/guardian-binding-drift-heal.test.ts +75 -10
- package/src/__tests__/guardian-dispatch.test.ts +95 -1
- package/src/__tests__/guardian-outbound-http.test.ts +13 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +2 -0
- package/src/__tests__/heartbeat-service.test.ts +2 -0
- package/src/__tests__/helpers/channel-test-adapter.ts +1 -7
- package/src/__tests__/host-app-control-routes.test.ts +24 -30
- package/src/__tests__/host-bash-routes.test.ts +31 -41
- package/src/__tests__/host-browser-routes.test.ts +26 -32
- package/src/__tests__/host-cu-proxy.test.ts +299 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +25 -33
- package/src/__tests__/host-file-routes-targeted.test.ts +40 -52
- package/src/__tests__/host-transfer-routes-targeted.test.ts +31 -43
- package/src/__tests__/http-user-message-parity.test.ts +167 -8
- package/src/__tests__/inbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/invite-redemption-service.test.ts +43 -0
- package/src/__tests__/llm-context-normalization.test.ts +105 -0
- package/src/__tests__/llm-usage-store.test.ts +25 -0
- package/src/__tests__/media-stream-server-integration.test.ts +127 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +2 -0
- package/src/__tests__/messaging-send-tool.test.ts +2 -0
- package/src/__tests__/migration-import-from-url.test.ts +2 -2
- package/src/__tests__/native-web-search.test.ts +2 -0
- package/src/__tests__/non-member-access-request.test.ts +189 -17
- package/src/__tests__/notification-broadcaster.test.ts +4 -0
- package/src/__tests__/notification-decision-recipient-context.test.ts +33 -32
- package/src/__tests__/notification-deep-link.test.ts +6 -0
- package/src/__tests__/notification-guardian-path.test.ts +19 -0
- package/src/__tests__/outbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/pending-interactions-resolved-event.test.ts +7 -4
- package/src/__tests__/persistence-secret-redaction.test.ts +2 -0
- package/src/__tests__/plugin-bootstrap.test.ts +3 -73
- package/src/__tests__/plugin-route-contribution.test.ts +4 -17
- package/src/__tests__/plugin-tool-contribution.test.ts +3 -18
- package/src/__tests__/plugin-types.test.ts +0 -2
- package/src/__tests__/process-message-background-slack.test.ts +2 -0
- package/src/__tests__/process-message-display-content.test.ts +2 -0
- package/src/__tests__/provider-usage-tracking.test.ts +39 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +2 -0
- package/src/__tests__/registry.test.ts +3 -0
- package/src/__tests__/relay-server.test.ts +694 -25
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
- package/src/__tests__/secret-ingress-http.test.ts +14 -0
- package/src/__tests__/send-endpoint-busy.test.ts +30 -8
- package/src/__tests__/skills.test.ts +44 -0
- package/src/__tests__/slack-inbound-verification.test.ts +47 -2
- package/src/__tests__/sse-actor-principal-guardian-source.test.ts +102 -0
- package/src/__tests__/steer-on-enqueue-question.test.ts +181 -0
- package/src/__tests__/stt-hints.test.ts +44 -13
- package/src/__tests__/subagent-detail.test.ts +27 -0
- package/src/__tests__/subagent-disposal.test.ts +65 -0
- package/src/__tests__/subagent-notify-parent.test.ts +2 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +2 -0
- package/src/__tests__/subagent-tools.test.ts +2 -0
- package/src/__tests__/suggestion-routes.test.ts +2 -0
- package/src/__tests__/title-generate-hook.test.ts +2 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -0
- package/src/__tests__/tool-executor.test.ts +16 -11
- package/src/__tests__/tool-preview-lifecycle.test.ts +2 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +2 -0
- package/src/__tests__/tool-start-timestamp.test.ts +2 -0
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +10 -10
- package/src/__tests__/twilio-routes.test.ts +96 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -0
- package/src/__tests__/web-search-backend-failure.test.ts +2 -0
- package/src/__tests__/workspace-tool-loader.test.ts +195 -2
- package/src/agent/loop-exclusive-tool.test.ts +150 -0
- package/src/agent/loop.ts +56 -0
- package/src/api/constants/sse-replay.ts +41 -0
- package/src/api/index.ts +6 -0
- package/src/api/responses/llm-request-log-entry.ts +25 -0
- package/src/api/responses/subagent-detail.ts +17 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +262 -4
- package/src/calls/call-domain.ts +3 -3
- package/src/calls/guardian-dispatch.ts +10 -8
- package/src/calls/inbound-trust-reader.ts +17 -1
- package/src/calls/media-stream-server.ts +21 -0
- package/src/calls/relay-server.ts +167 -50
- package/src/calls/relay-setup-router.ts +37 -7
- package/src/calls/relay-verification.ts +4 -4
- package/src/calls/stt-hints.ts +9 -12
- package/src/calls/twilio-routes.ts +14 -4
- package/src/cli/commands/__tests__/cache.test.ts +8 -1
- package/src/cli/commands/cache.ts +194 -181
- package/src/cli/commands/db/__tests__/repair.test.ts +6 -5
- package/src/cli/commands/db/status.ts +37 -1
- package/src/cli/commands/mcp.ts +252 -218
- package/src/cli/commands/memory/__tests__/worker.test.ts +302 -0
- package/src/cli/commands/memory/index.ts +2 -0
- package/src/cli/commands/memory/worker.ts +175 -0
- package/src/cli/commands/plugins.ts +75 -3
- package/src/cli/lib/__tests__/install-from-github.test.ts +102 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +160 -1
- package/src/cli/lib/list-installed-plugins.ts +179 -1
- package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +143 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +6 -1
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +27 -17
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +13 -3
- package/src/config/feature-flag-registry.json +0 -8
- package/src/config/loader.ts +36 -5
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/memory-lifecycle.ts +12 -0
- package/src/config/schemas/memory-v3.ts +7 -0
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/timeouts.ts +8 -0
- package/src/config/seed-inference-profiles.ts +14 -5
- package/src/config/skills.ts +27 -5
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +312 -0
- package/src/contacts/contacts-write.ts +3 -0
- package/src/contacts/guardian-delivery-reader.ts +223 -0
- package/src/daemon/conversation-agent-loop.ts +9 -0
- package/src/daemon/conversation-process.ts +39 -17
- package/src/daemon/conversation-surfaces.ts +8 -0
- package/src/daemon/conversation-tool-setup.ts +49 -16
- package/src/daemon/conversation.ts +21 -2
- package/src/daemon/disk-pressure-guard.ts +12 -2
- package/src/daemon/event-loop-watchdog.ts +28 -1
- package/src/daemon/external-plugins-bootstrap.ts +4 -34
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +25 -0
- package/src/daemon/handlers/__tests__/config-channels.test.ts +225 -0
- package/src/daemon/handlers/config-a2a.ts +6 -14
- package/src/daemon/handlers/config-channels.ts +78 -22
- package/src/daemon/handlers/conversations.ts +77 -0
- package/src/daemon/host-cu-proxy.ts +102 -11
- package/src/daemon/lifecycle.ts +4 -0
- package/src/daemon/memory-v2-startup.test.ts +72 -0
- package/src/daemon/memory-v2-startup.ts +87 -19
- package/src/daemon/server.ts +0 -4
- package/src/daemon/shutdown-handlers.ts +20 -0
- package/src/daemon/tool-setup-types.ts +9 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +1 -1
- package/src/ipc/assistant-server.ts +2 -2
- package/src/memory/__tests__/301-create-watchdog-events.test.ts +110 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
- package/src/memory/__tests__/prompt-override.test.ts +192 -0
- package/src/memory/__tests__/watchdog-events-store.test.ts +161 -0
- package/src/memory/conversation-crud.ts +38 -0
- package/src/memory/db-connection.ts +22 -3
- package/src/memory/db-init.ts +36 -502
- package/src/memory/db-singleton.ts +6 -4
- package/src/memory/jobs-worker.ts +58 -0
- package/src/memory/llm-usage-store.ts +48 -20
- package/src/memory/memory-retrospective-job.ts +9 -8
- package/src/memory/migrations/014-backfill-inbox-thread-state.ts +13 -3
- package/src/memory/migrations/136-drop-assistant-id-columns.ts +52 -27
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +130 -56
- package/src/memory/migrations/300-add-processing-started-at.ts +30 -0
- package/src/memory/migrations/301-create-watchdog-events.ts +45 -0
- package/src/memory/migrations/__tests__/014-backfill-inbox-thread-state.test.ts +108 -0
- package/src/memory/migrations/__tests__/136-drop-assistant-id-columns.test.ts +82 -0
- package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +224 -0
- package/src/memory/migrations/__tests__/run-migrations.test.ts +2 -2
- package/src/memory/migrations/run-migrations.ts +90 -6
- package/src/memory/migrations/schema-introspection.ts +14 -0
- package/src/memory/migrations/validate-migration-state.ts +101 -66
- package/src/memory/prompt-override.ts +129 -0
- package/src/memory/schema/conversations.ts +9 -0
- package/src/memory/schema/infrastructure.ts +20 -0
- package/src/memory/steps.ts +573 -0
- package/src/memory/v2/__tests__/cli-command-store.test.ts +25 -0
- package/src/memory/v2/__tests__/skill-store.test.ts +80 -0
- package/src/memory/v2/cli-command-store.ts +75 -38
- package/src/memory/v2/prompts/consolidation.ts +13 -82
- package/src/memory/v2/prompts/router.ts +21 -93
- package/src/memory/v2/skill-store.ts +68 -31
- package/src/memory/watchdog-events-store.ts +87 -0
- package/src/memory/worker-control.ts +118 -0
- package/src/memory/worker-process.ts +72 -0
- package/src/notifications/__tests__/broadcaster.test.ts +16 -8
- package/src/notifications/__tests__/connected-channels.test.ts +114 -0
- package/src/notifications/__tests__/decision-engine.test.ts +78 -9
- package/src/notifications/__tests__/destination-resolver.test.ts +256 -0
- package/src/notifications/broadcaster.ts +8 -1
- package/src/notifications/decision-engine.ts +15 -7
- package/src/notifications/destination-resolver.ts +68 -24
- package/src/notifications/emit-signal.ts +39 -14
- package/src/onboarding/checkin-event.test.ts +220 -0
- package/src/onboarding/checkin-event.ts +321 -0
- package/src/onboarding/schedule-checkin.ts +190 -0
- package/src/permissions/question-prompter.test.ts +1 -1
- package/src/permissions/question-prompter.ts +7 -4
- package/src/plugin-api/index.ts +6 -6
- package/src/plugin-api/types.ts +3 -5
- package/src/plugin-api/vision-support.test.ts +28 -4
- package/src/plugin-api/vision-support.ts +66 -31
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +161 -0
- package/src/plugins/defaults/advisor/__tests__/context-pack-gating.test.ts +106 -0
- package/src/plugins/defaults/advisor/__tests__/context-pack.test.ts +60 -0
- package/src/plugins/defaults/advisor/consult.ts +110 -6
- package/src/plugins/defaults/advisor/context-pack.ts +288 -0
- package/src/plugins/defaults/advisor/steering.ts +14 -2
- package/src/plugins/defaults/advisor/tools/advisor.ts +32 -5
- package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +47 -7
- package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +10 -11
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +12 -20
- package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +42 -11
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +11 -2
- package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +146 -0
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +29 -1
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +8 -1
- package/src/plugins/mtime-cache.ts +7 -2
- package/src/plugins/types.ts +0 -2
- package/src/providers/anthropic/client.ts +5 -0
- package/src/providers/call-site-routing.ts +4 -0
- package/src/providers/model-catalog.ts +16 -0
- package/src/providers/openai/responses-provider.ts +5 -0
- package/src/providers/openrouter/client.ts +5 -0
- package/src/providers/provider-send-message.ts +4 -0
- package/src/providers/ratelimit.ts +4 -0
- package/src/providers/retry.ts +4 -0
- package/src/providers/types.ts +9 -0
- package/src/providers/usage-tracking.ts +4 -0
- package/src/runtime/__tests__/channel-verification-service.test.ts +133 -0
- package/src/runtime/__tests__/guardian-vellum-migration.test.ts +181 -0
- package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +66 -0
- package/src/runtime/__tests__/local-principal-trust.test.ts +164 -0
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +335 -3
- package/src/runtime/access-request-helper.ts +19 -39
- package/src/runtime/actor-trust-resolver.ts +2 -2
- package/src/runtime/anchored-guardian.test.ts +156 -0
- package/src/runtime/anchored-guardian.ts +135 -0
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/assistant-stream-state.ts +9 -2
- package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +99 -0
- package/src/runtime/auth/require-bound-guardian.ts +21 -11
- package/src/runtime/channel-verification-service.ts +56 -31
- package/src/runtime/confirmation-request-guardian-bridge.ts +3 -3
- package/src/runtime/guardian-vellum-migration.ts +66 -7
- package/src/runtime/invite-redemption-service.ts +50 -18
- package/src/runtime/local-actor-identity.ts +76 -11
- package/src/runtime/local-principal-trust.ts +52 -0
- package/src/runtime/pending-interactions.ts +11 -1
- package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +56 -5
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/contact-routes.test.ts +212 -0
- package/src/runtime/routes/__tests__/global-search-routes.test.ts +93 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +215 -1
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/channel-verification-routes.ts +3 -3
- package/src/runtime/routes/contact-routes.ts +8 -32
- package/src/runtime/routes/conversation-cli-routes.ts +4 -5
- package/src/runtime/routes/conversation-list-routes.ts +4 -7
- package/src/runtime/routes/conversation-routes.ts +74 -81
- package/src/runtime/routes/events-routes.ts +2 -2
- package/src/runtime/routes/global-search-routes.ts +3 -1
- package/src/runtime/routes/guardian-action-routes.ts +4 -5
- package/src/runtime/routes/host-app-control-routes.ts +5 -4
- package/src/runtime/routes/host-bash-routes.ts +5 -4
- package/src/runtime/routes/host-browser-routes.ts +9 -11
- package/src/runtime/routes/host-cu-routes.ts +5 -4
- package/src/runtime/routes/host-file-routes.ts +5 -4
- package/src/runtime/routes/host-transfer-routes.ts +6 -6
- package/src/runtime/routes/http-adapter.ts +1 -1
- package/src/runtime/routes/identity-routes.ts +3 -2
- package/src/runtime/routes/inbound-message-handler.ts +5 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +97 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +61 -49
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +16 -4
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +21 -8
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -3
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/llm-context-normalization.ts +71 -0
- package/src/runtime/routes/mcp-auth-routes.ts +38 -15
- package/src/runtime/routes/migration-rollback-routes.ts +4 -3
- package/src/runtime/routes/migration-routes.ts +4 -1
- package/src/runtime/routes/onboarding-checkin-routes.ts +86 -0
- package/src/runtime/routes/subagents-routes.ts +5 -0
- package/src/runtime/routes/surface-action-routes.ts +51 -55
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +1 -0
- package/src/runtime/services/conversation-serializer.ts +7 -9
- package/src/runtime/tool-grant-request-helper.ts +3 -3
- package/src/runtime/trust-verdict-consumer.ts +85 -9
- package/src/runtime/verification-outbound-actions.ts +18 -18
- package/src/signals/user-message.ts +16 -0
- package/src/subagent/manager.ts +9 -0
- package/src/telemetry/types.ts +34 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -2
- package/src/telemetry/usage-telemetry-reporter.ts +87 -3
- package/src/tools/ask-question/ask-question-tool.test.ts +29 -0
- package/src/tools/ask-question/ask-question-tool.ts +13 -0
- package/src/tools/computer-use/definitions.ts +8 -2
- package/src/tools/executor.ts +4 -4
- package/src/tools/registry.ts +18 -0
- package/src/tools/tool-approval-handler.ts +1 -1
- package/src/tools/tool-defaults.ts +9 -2
- package/src/tools/types.ts +17 -2
- package/src/tools/workspace-tools/loader.ts +348 -244
- package/src/util/platform.ts +5 -0
- package/src/util/telemetry-db-path.ts +24 -0
- package/src/workspace/migrations/017-seed-persona-dirs.ts +3 -34
- package/src/workspace/migrations/019-scope-journal-to-guardian.ts +3 -24
- package/src/__tests__/workspace-tools-watcher-flag.test.ts +0 -70
- package/src/daemon/workspace-tools-watcher.ts +0 -328
- package/src/memory/migrations/registry.ts +0 -573
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
import { v4 as uuid } from "uuid";
|
|
10
10
|
import { z } from "zod";
|
|
11
11
|
|
|
12
|
-
import { findConversation } from "../../daemon/conversation-registry.js";
|
|
13
12
|
import { clearAllConversations as clearAllActive } from "../../daemon/handlers/conversations.js";
|
|
14
13
|
import { formatJson, formatMarkdown } from "../../export/formatter.js";
|
|
15
14
|
import { ipcCall as ipcCallGateway } from "../../ipc/gateway-client.js";
|
|
15
|
+
import { isConversationProcessing } from "../../memory/conversation-crud.js";
|
|
16
16
|
import {
|
|
17
17
|
addMessage,
|
|
18
18
|
createConversation,
|
|
@@ -53,10 +53,9 @@ function handleListCli({ body = {} }: RouteHandlerArgs) {
|
|
|
53
53
|
id: c.id,
|
|
54
54
|
title: c.title,
|
|
55
55
|
updatedAt: c.updatedAt,
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
isProcessing: findConversation(c.id)?.isProcessing() ?? false,
|
|
56
|
+
// Checks in-memory flag first (hot path), falls back to the
|
|
57
|
+
// persisted `processing_started_at` column for cold conversations.
|
|
58
|
+
isProcessing: isConversationProcessing(c.id),
|
|
60
59
|
})),
|
|
61
60
|
};
|
|
62
61
|
}
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
|
|
13
|
-
import { findConversation } from "../../daemon/conversation-registry.js";
|
|
14
13
|
import {
|
|
15
14
|
type Confidence,
|
|
16
15
|
getAttentionStateByConversationIds,
|
|
@@ -18,6 +17,7 @@ import {
|
|
|
18
17
|
recordConversationSeenSignal,
|
|
19
18
|
type SignalType,
|
|
20
19
|
} from "../../memory/conversation-attention-store.js";
|
|
20
|
+
import { isConversationProcessing } from "../../memory/conversation-crud.js";
|
|
21
21
|
import {
|
|
22
22
|
type ConversationRow,
|
|
23
23
|
getDisplayMetaForConversations,
|
|
@@ -270,12 +270,9 @@ function handleListConversations({ queryParams = {} }: RouteHandlerArgs) {
|
|
|
270
270
|
attentionState: attentionStates.get(conversation.id),
|
|
271
271
|
displayMeta: displayMeta.get(conversation.id),
|
|
272
272
|
parentCache,
|
|
273
|
-
//
|
|
274
|
-
//
|
|
275
|
-
|
|
276
|
-
// mid-turn since the agent loop only runs on resident convs.
|
|
277
|
-
isProcessing:
|
|
278
|
-
findConversation(conversation.id)?.isProcessing() ?? false,
|
|
273
|
+
// Checks in-memory flag first (hot path), falls back to the
|
|
274
|
+
// persisted `processing_started_at` column for cold conversations.
|
|
275
|
+
isProcessing: isConversationProcessing(conversation.id),
|
|
279
276
|
}),
|
|
280
277
|
),
|
|
281
278
|
nextOffset,
|
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
getCannedFirstGreeting,
|
|
51
51
|
isWakeUpGreeting,
|
|
52
52
|
} from "../../daemon/first-greeting.js";
|
|
53
|
+
import { supersedePendingInteractionsOnEnqueue } from "../../daemon/handlers/conversations.js";
|
|
53
54
|
import {
|
|
54
55
|
collectAttachmentRefs,
|
|
55
56
|
type HistoryAttachmentRef,
|
|
@@ -67,6 +68,7 @@ import type {
|
|
|
67
68
|
HostProxyTransportMetadata,
|
|
68
69
|
NonHostProxyTransportMetadata,
|
|
69
70
|
} from "../../daemon/message-types/conversations.js";
|
|
71
|
+
import type { TrustContext } from "../../daemon/trust-context.js";
|
|
70
72
|
import { HeartbeatService } from "../../heartbeat/heartbeat-service.js";
|
|
71
73
|
import {
|
|
72
74
|
writeOnboardingSidecar,
|
|
@@ -120,30 +122,27 @@ import {
|
|
|
120
122
|
} from "../../util/platform.js";
|
|
121
123
|
import { silentlyWithLog } from "../../util/silently.js";
|
|
122
124
|
import { assistantEventHub, broadcastMessage } from "../assistant-event-hub.js";
|
|
123
|
-
import { DAEMON_INTERNAL_ASSISTANT_ID } from "../assistant-scope.js";
|
|
124
125
|
import { getPersistedSeq } from "../assistant-stream-state.js";
|
|
125
126
|
import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
|
|
126
127
|
import {
|
|
127
128
|
type GuardianPendingScope,
|
|
128
129
|
routeGuardianReply,
|
|
129
130
|
} from "../guardian-reply-router.js";
|
|
130
|
-
import {
|
|
131
|
+
import { reResolveTrustOnResetDrift } from "../guardian-vellum-migration.js";
|
|
131
132
|
import type {
|
|
132
133
|
ApprovalConversationGenerator,
|
|
133
134
|
RuntimeAttachmentMetadata,
|
|
134
135
|
RuntimeMessagePayload,
|
|
135
136
|
SendMessageDeps,
|
|
136
137
|
} from "../http-types.js";
|
|
137
|
-
import {
|
|
138
|
+
import { findLocalGuardianPrincipalId } from "../local-actor-identity.js";
|
|
139
|
+
import { resolveLocalPrincipalTrustContext } from "../local-principal-trust.js";
|
|
138
140
|
import * as pendingInteractions from "../pending-interactions.js";
|
|
139
141
|
import {
|
|
140
142
|
publishConversationListAndMetadataChanged,
|
|
141
143
|
publishConversationMessagesChanged,
|
|
142
144
|
} from "../sync/resource-sync-events.js";
|
|
143
|
-
import {
|
|
144
|
-
resolveTrustContext,
|
|
145
|
-
withSourceChannel,
|
|
146
|
-
} from "../trust-context-resolver.js";
|
|
145
|
+
import { withSourceChannel } from "../trust-context-resolver.js";
|
|
147
146
|
import {
|
|
148
147
|
BadRequestError,
|
|
149
148
|
InternalError,
|
|
@@ -946,25 +945,28 @@ export function handleListMessages({
|
|
|
946
945
|
.filter((block) => block.type !== "text" || block.text.length > 0);
|
|
947
946
|
}
|
|
948
947
|
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
948
|
+
// Ensure every hydrated attachment has a corresponding content block.
|
|
949
|
+
// renderHistoryContent inlines attachment blocks only when it has
|
|
950
|
+
// file-block refs with matching DB rows; directives (assistant-authored
|
|
951
|
+
// <vellum-attachment/> tags) don't leave a file block after stripping,
|
|
952
|
+
// so their attachments end up in the flat `attachments` array but not in
|
|
953
|
+
// `contentBlocks`. Append any that are missing so the canonical
|
|
954
|
+
// projection is complete.
|
|
955
|
+
const existingAttachmentIds = new Set(
|
|
956
|
+
contentBlocks
|
|
957
|
+
.filter(
|
|
958
|
+
(b): b is Extract<ConversationContentBlock, { type: "attachment" }> =>
|
|
959
|
+
b.type === "attachment",
|
|
960
|
+
)
|
|
961
|
+
.map((b) => b.attachment.id),
|
|
962
|
+
);
|
|
963
|
+
for (const att of msgAttachments) {
|
|
964
|
+
if (!existingAttachmentIds.has(att.id)) {
|
|
965
|
+
contentBlocks.push({ type: "attachment", attachment: att });
|
|
966
|
+
}
|
|
964
967
|
}
|
|
965
|
-
}
|
|
966
968
|
|
|
967
|
-
|
|
969
|
+
const alignedContentOrder = aligned.rewriteContentOrder(contentOrder);
|
|
968
970
|
|
|
969
971
|
// Use sentAt (actual event time) for the display timestamp when available,
|
|
970
972
|
// falling back to createdAt (persistence time). Clients use this display
|
|
@@ -1440,56 +1442,65 @@ export async function handleSendMessage(
|
|
|
1440
1442
|
conversation.setOnboardingContext(body.onboarding!);
|
|
1441
1443
|
}
|
|
1442
1444
|
|
|
1443
|
-
// Resolve guardian context from the AuthContext's actorPrincipalId
|
|
1444
|
-
//
|
|
1445
|
-
// the same trust resolution pipeline that channel ingress uses.
|
|
1445
|
+
// Resolve guardian context from the AuthContext's actorPrincipalId via the
|
|
1446
|
+
// gateway guardian binding: a vellum principal is the guardian or nobody.
|
|
1446
1447
|
if (actorPrincipalId) {
|
|
1447
1448
|
// Dev bypass (HTTP auth disabled): the synthetic "dev-bypass" principal
|
|
1448
|
-
// won't match any guardian binding. Resolve
|
|
1449
|
-
//
|
|
1449
|
+
// won't match any guardian binding. Resolve the real guardian principal and
|
|
1450
|
+
// map that through, failing closed to unknown on an empty gateway.
|
|
1450
1451
|
if (isHttpAuthDisabled() && actorPrincipalId === "dev-bypass") {
|
|
1451
|
-
|
|
1452
|
+
const guardianPrincipalId = await findLocalGuardianPrincipalId();
|
|
1453
|
+
let trustCtx: TrustContext = guardianPrincipalId
|
|
1454
|
+
? withSourceChannel(
|
|
1455
|
+
sourceChannel,
|
|
1456
|
+
await resolveLocalPrincipalTrustContext({
|
|
1457
|
+
actorPrincipalId: guardianPrincipalId,
|
|
1458
|
+
sourceChannel: "vellum",
|
|
1459
|
+
conversationExternalId: "local",
|
|
1460
|
+
}),
|
|
1461
|
+
)
|
|
1462
|
+
: { trustClass: "unknown", sourceChannel };
|
|
1463
|
+
if (guardianPrincipalId && trustCtx.trustClass === "unknown") {
|
|
1464
|
+
const healed = await reResolveTrustOnResetDrift(
|
|
1465
|
+
guardianPrincipalId,
|
|
1466
|
+
sourceChannel,
|
|
1467
|
+
);
|
|
1468
|
+
if (healed) trustCtx = healed;
|
|
1469
|
+
}
|
|
1470
|
+
conversation.setTrustContext(trustCtx);
|
|
1452
1471
|
} else {
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1472
|
+
let trustCtx = withSourceChannel(
|
|
1473
|
+
sourceChannel,
|
|
1474
|
+
await resolveLocalPrincipalTrustContext({
|
|
1475
|
+
actorPrincipalId,
|
|
1476
|
+
sourceChannel: "vellum",
|
|
1477
|
+
conversationExternalId: "local",
|
|
1478
|
+
}),
|
|
1479
|
+
);
|
|
1460
1480
|
if (trustCtx.trustClass === "unknown") {
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
trustCtx = resolveTrustContext({
|
|
1468
|
-
assistantId,
|
|
1469
|
-
sourceChannel: "vellum",
|
|
1470
|
-
conversationExternalId: "local",
|
|
1471
|
-
actorExternalId: actorPrincipalId,
|
|
1472
|
-
});
|
|
1481
|
+
const healed = await reResolveTrustOnResetDrift(
|
|
1482
|
+
actorPrincipalId,
|
|
1483
|
+
sourceChannel,
|
|
1484
|
+
);
|
|
1485
|
+
if (healed && healed.trustClass !== "unknown") {
|
|
1486
|
+
trustCtx = healed;
|
|
1473
1487
|
log.info(
|
|
1474
|
-
{
|
|
1475
|
-
|
|
1476
|
-
trustClass: trustCtx.trustClass,
|
|
1477
|
-
},
|
|
1478
|
-
"Trust re-resolved after guardian binding drift heal",
|
|
1488
|
+
{ actorPrincipalId, trustClass: trustCtx.trustClass },
|
|
1489
|
+
"Trust re-resolved from local mirror after gateway returned unknown",
|
|
1479
1490
|
);
|
|
1480
1491
|
} else {
|
|
1481
1492
|
log.warn(
|
|
1482
1493
|
{
|
|
1483
|
-
actorPrincipalId
|
|
1494
|
+
actorPrincipalId,
|
|
1484
1495
|
sourceChannel,
|
|
1485
|
-
trustClass:
|
|
1486
|
-
principalType
|
|
1496
|
+
trustClass: "unknown",
|
|
1497
|
+
principalType,
|
|
1487
1498
|
},
|
|
1488
1499
|
"JWT-verified actor resolved to unknown trust class — possible guardian binding drift (e.g. DB reset without re-bootstrap)",
|
|
1489
1500
|
);
|
|
1490
1501
|
}
|
|
1491
1502
|
}
|
|
1492
|
-
conversation.setTrustContext(
|
|
1503
|
+
conversation.setTrustContext(trustCtx);
|
|
1493
1504
|
}
|
|
1494
1505
|
} else {
|
|
1495
1506
|
// Service principals (svc_gateway) or tokens without an actor ID
|
|
@@ -1814,29 +1825,11 @@ export async function handleSendMessage(
|
|
|
1814
1825
|
// the client showing "Failed to send" for a message the daemon will
|
|
1815
1826
|
// process from the queue.
|
|
1816
1827
|
try {
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
)) {
|
|
1823
|
-
if (interaction.kind === "confirmation") {
|
|
1824
|
-
conversation.emitConfirmationStateChanged({
|
|
1825
|
-
conversationId: mapping.conversationId,
|
|
1826
|
-
requestId: interaction.requestId,
|
|
1827
|
-
state: "denied" as const,
|
|
1828
|
-
source: "auto_deny" as const,
|
|
1829
|
-
});
|
|
1830
|
-
// Sync canonical guardian request status so stale "pending" DB
|
|
1831
|
-
// records don't get matched by later guardian reply routing.
|
|
1832
|
-
resolveCanonicalGuardianRequest(interaction.requestId, "pending", {
|
|
1833
|
-
status: "denied",
|
|
1834
|
-
});
|
|
1835
|
-
}
|
|
1836
|
-
}
|
|
1837
|
-
conversation.denyAllPendingConfirmations();
|
|
1838
|
-
pendingInteractions.removeByConversation(mapping.conversationId);
|
|
1839
|
-
}
|
|
1828
|
+
// Supersede interactions left pending by the in-flight turn: auto-deny
|
|
1829
|
+
// confirmations (with canonical/client sync) and steer to the enqueued
|
|
1830
|
+
// message if an ask_question is parked. Centralized so the CLI signal
|
|
1831
|
+
// path (signals/user-message.ts) gets identical handling.
|
|
1832
|
+
supersedePendingInteractionsOnEnqueue(mapping.conversationId, requestId);
|
|
1840
1833
|
|
|
1841
1834
|
// Expire any orphaned canonical requests that survived without a
|
|
1842
1835
|
// matching in-memory pending interaction (e.g. prompter timeouts).
|
|
@@ -43,7 +43,7 @@ import type { ReplaySubscriber } from "../assistant-stream-state.js";
|
|
|
43
43
|
import { getReplayWindow } from "../assistant-stream-state.js";
|
|
44
44
|
import { ACTOR_PRINCIPALS, GATEWAY_PRINCIPALS } from "../auth/route-policy.js";
|
|
45
45
|
import { DEFAULT_HEARTBEAT_INTERVAL_MS } from "../client-health.js";
|
|
46
|
-
import {
|
|
46
|
+
import { resolveActorPrincipalIdForLocalGuardianSync } from "../local-actor-identity.js";
|
|
47
47
|
import {
|
|
48
48
|
BadRequestError,
|
|
49
49
|
NotFoundError,
|
|
@@ -311,7 +311,7 @@ export function handleSubscribeAssistantEvents(
|
|
|
311
311
|
// bearer token's AuthContext. May be absent for legacy / service-token
|
|
312
312
|
// connections that have no principal. See `resolveActorPrincipalId` for the
|
|
313
313
|
// dev-bypass translation rationale.
|
|
314
|
-
const actorPrincipalId =
|
|
314
|
+
const actorPrincipalId = resolveActorPrincipalIdForLocalGuardianSync(
|
|
315
315
|
rawActorPrincipalId?.trim() || undefined,
|
|
316
316
|
);
|
|
317
317
|
|
|
@@ -263,7 +263,9 @@ async function handleGlobalSearch({
|
|
|
263
263
|
id: c.id,
|
|
264
264
|
displayName: c.displayName,
|
|
265
265
|
notes: c.notes,
|
|
266
|
-
|
|
266
|
+
// Daemon-native search has no gateway-relayed read; recency orders on
|
|
267
|
+
// contacts.updatedAt, not the channel-derived lastInteraction column.
|
|
268
|
+
lastInteraction: c.updatedAt,
|
|
267
269
|
}));
|
|
268
270
|
}
|
|
269
271
|
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
import { z } from "zod";
|
|
15
15
|
|
|
16
16
|
import { isHttpAuthDisabled } from "../../config/env.js";
|
|
17
|
-
import { findGuardianForChannel } from "../../contacts/contact-store.js";
|
|
18
17
|
import {
|
|
19
18
|
type CanonicalGuardianRequest,
|
|
20
19
|
listPendingRequestsByConversationScope,
|
|
@@ -23,6 +22,7 @@ import { ACTOR_PRINCIPALS } from "../auth/route-policy.js";
|
|
|
23
22
|
import { processGuardianDecision } from "../guardian-action-service.js";
|
|
24
23
|
import type { GuardianDecisionPrompt } from "../guardian-decision-types.js";
|
|
25
24
|
import { buildOneTimeDecisionActions } from "../guardian-decision-types.js";
|
|
25
|
+
import { findLocalGuardianPrincipalId } from "../local-actor-identity.js";
|
|
26
26
|
import { BadRequestError, NotFoundError } from "./errors.js";
|
|
27
27
|
import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
28
28
|
|
|
@@ -73,16 +73,15 @@ async function handleGuardianActionDecision({
|
|
|
73
73
|
// Resolve the actor's guardian principal ID. The HTTP adapter injects it
|
|
74
74
|
// from the AuthContext via the x-vellum-actor-principal-id header.
|
|
75
75
|
// For dev bypass (HTTP auth disabled) the synthetic "dev-bypass" principal
|
|
76
|
-
// won't match the real guardian binding, so
|
|
77
|
-
//
|
|
76
|
+
// won't match the real guardian binding, so resolve the local guardian
|
|
77
|
+
// principal to avoid identity_mismatch.
|
|
78
78
|
let guardianPrincipalId: string | undefined =
|
|
79
79
|
headers["x-vellum-actor-principal-id"] ?? undefined;
|
|
80
80
|
if (
|
|
81
81
|
isHttpAuthDisabled() &&
|
|
82
82
|
headers["x-vellum-actor-principal-id"] === "dev-bypass"
|
|
83
83
|
) {
|
|
84
|
-
|
|
85
|
-
guardianPrincipalId = binding?.contact.principalId ?? undefined;
|
|
84
|
+
guardianPrincipalId = (await findLocalGuardianPrincipalId()) ?? undefined;
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
const result = await processGuardianDecision({
|
|
@@ -39,7 +39,7 @@ const VALID_STATES: ReadonlySet<HostAppControlState> = new Set([
|
|
|
39
39
|
// POST /v1/host-app-control-result
|
|
40
40
|
// ---------------------------------------------------------------------------
|
|
41
41
|
|
|
42
|
-
function handleHostAppControlResult({ body, headers }: RouteHandlerArgs) {
|
|
42
|
+
async function handleHostAppControlResult({ body, headers }: RouteHandlerArgs) {
|
|
43
43
|
if (!body || typeof body !== "object") {
|
|
44
44
|
throw new BadRequestError("Request body is required");
|
|
45
45
|
}
|
|
@@ -95,9 +95,10 @@ function handleHostAppControlResult({ body, headers }: RouteHandlerArgs) {
|
|
|
95
95
|
`Client "${submittingClientId}" is not the target for this request (expected "${peeked.targetClientId}"). The targeted client must submit the result.`,
|
|
96
96
|
);
|
|
97
97
|
}
|
|
98
|
-
const submittingActorPrincipalId =
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
const submittingActorPrincipalId =
|
|
99
|
+
await resolveActorPrincipalIdForLocalGuardian(
|
|
100
|
+
headerMap["x-vellum-actor-principal-id"]?.trim() || undefined,
|
|
101
|
+
);
|
|
101
102
|
enforceSameActorOrThrow({
|
|
102
103
|
sourceActorPrincipalId: submittingActorPrincipalId,
|
|
103
104
|
targetActorPrincipalId: peeked.targetActorPrincipalId,
|
|
@@ -26,7 +26,7 @@ import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
|
26
26
|
// POST /v1/host-bash-result
|
|
27
27
|
// ---------------------------------------------------------------------------
|
|
28
28
|
|
|
29
|
-
function handleHostBashResult({ body, headers }: RouteHandlerArgs) {
|
|
29
|
+
async function handleHostBashResult({ body, headers }: RouteHandlerArgs) {
|
|
30
30
|
if (!body || typeof body !== "object") {
|
|
31
31
|
throw new BadRequestError("Request body is required");
|
|
32
32
|
}
|
|
@@ -45,9 +45,10 @@ function handleHostBashResult({ body, headers }: RouteHandlerArgs) {
|
|
|
45
45
|
|
|
46
46
|
const submittingClientId =
|
|
47
47
|
headers?.["x-vellum-client-id"]?.trim() || undefined;
|
|
48
|
-
const submittingActorPrincipalId =
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
const submittingActorPrincipalId =
|
|
49
|
+
await resolveActorPrincipalIdForLocalGuardian(
|
|
50
|
+
headers?.["x-vellum-actor-principal-id"]?.trim() || undefined,
|
|
51
|
+
);
|
|
51
52
|
|
|
52
53
|
const peeked = pendingInteractions.get(requestId);
|
|
53
54
|
if (!peeked) {
|
|
@@ -61,14 +61,14 @@ export type HostBrowserResultResolution =
|
|
|
61
61
|
* already authenticated the caller (the HTTP route uses
|
|
62
62
|
* `requireBoundGuardian`).
|
|
63
63
|
*/
|
|
64
|
-
export function resolveHostBrowserResultByRequestId(
|
|
64
|
+
export async function resolveHostBrowserResultByRequestId(
|
|
65
65
|
frame: {
|
|
66
66
|
requestId?: unknown;
|
|
67
67
|
content?: unknown;
|
|
68
68
|
isError?: unknown;
|
|
69
69
|
},
|
|
70
70
|
headers?: Record<string, string | undefined>,
|
|
71
|
-
): HostBrowserResultResolution {
|
|
71
|
+
): Promise<HostBrowserResultResolution> {
|
|
72
72
|
const { requestId, content, isError } = frame;
|
|
73
73
|
|
|
74
74
|
if (!requestId || typeof requestId !== "string") {
|
|
@@ -127,9 +127,10 @@ export function resolveHostBrowserResultByRequestId(
|
|
|
127
127
|
// stream. This prevents a different authenticated user with knowledge of
|
|
128
128
|
// both the requestId and target clientId from submitting a result on
|
|
129
129
|
// behalf of the targeted client.
|
|
130
|
-
const submittingActorPrincipalId =
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
const submittingActorPrincipalId =
|
|
131
|
+
await resolveActorPrincipalIdForLocalGuardian(
|
|
132
|
+
headerMap["x-vellum-actor-principal-id"]?.trim() || undefined,
|
|
133
|
+
);
|
|
133
134
|
try {
|
|
134
135
|
enforceSameActorOrThrow({
|
|
135
136
|
sourceActorPrincipalId: submittingActorPrincipalId,
|
|
@@ -260,12 +261,12 @@ export function resolveHostBrowserSessionInvalidated(frame: {
|
|
|
260
261
|
// POST /v1/host-browser-result
|
|
261
262
|
// ---------------------------------------------------------------------------
|
|
262
263
|
|
|
263
|
-
function handleHostBrowserResult({ body, headers }: RouteHandlerArgs) {
|
|
264
|
+
async function handleHostBrowserResult({ body, headers }: RouteHandlerArgs) {
|
|
264
265
|
if (!body || typeof body !== "object") {
|
|
265
266
|
throw new BadRequestError("Request body is required");
|
|
266
267
|
}
|
|
267
268
|
|
|
268
|
-
const resolution = resolveHostBrowserResultByRequestId(
|
|
269
|
+
const resolution = await resolveHostBrowserResultByRequestId(
|
|
269
270
|
body,
|
|
270
271
|
headers as Record<string, string | undefined> | undefined,
|
|
271
272
|
);
|
|
@@ -399,10 +400,7 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
399
400
|
"Marks the target as invalidated in the runtime-side browser session registry.",
|
|
400
401
|
tags: ["host"],
|
|
401
402
|
requestBody: z.object({
|
|
402
|
-
targetId: z
|
|
403
|
-
.string()
|
|
404
|
-
.optional()
|
|
405
|
-
.describe("CDP target that was detached"),
|
|
403
|
+
targetId: z.string().optional().describe("CDP target that was detached"),
|
|
406
404
|
reason: z.string().optional().describe("Detach reason"),
|
|
407
405
|
clientId: z
|
|
408
406
|
.string()
|
|
@@ -26,7 +26,7 @@ import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
|
26
26
|
// POST /v1/host-cu-result
|
|
27
27
|
// ---------------------------------------------------------------------------
|
|
28
28
|
|
|
29
|
-
function handleHostCuResult({ body, headers }: RouteHandlerArgs) {
|
|
29
|
+
async function handleHostCuResult({ body, headers }: RouteHandlerArgs) {
|
|
30
30
|
if (!body || typeof body !== "object") {
|
|
31
31
|
throw new BadRequestError("Request body is required");
|
|
32
32
|
}
|
|
@@ -95,9 +95,10 @@ function handleHostCuResult({ body, headers }: RouteHandlerArgs) {
|
|
|
95
95
|
// stream. This prevents a different authenticated user with knowledge of
|
|
96
96
|
// both the requestId and target clientId from submitting a result on
|
|
97
97
|
// behalf of the targeted client.
|
|
98
|
-
const submittingActorPrincipalId =
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
const submittingActorPrincipalId =
|
|
99
|
+
await resolveActorPrincipalIdForLocalGuardian(
|
|
100
|
+
headerMap["x-vellum-actor-principal-id"]?.trim() || undefined,
|
|
101
|
+
);
|
|
101
102
|
enforceSameActorOrThrow({
|
|
102
103
|
sourceActorPrincipalId: submittingActorPrincipalId,
|
|
103
104
|
targetActorPrincipalId: peeked.targetActorPrincipalId,
|
|
@@ -26,7 +26,7 @@ import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
|
26
26
|
// POST /v1/host-file-result
|
|
27
27
|
// ---------------------------------------------------------------------------
|
|
28
28
|
|
|
29
|
-
function handleHostFileResult({ body, headers }: RouteHandlerArgs) {
|
|
29
|
+
async function handleHostFileResult({ body, headers }: RouteHandlerArgs) {
|
|
30
30
|
if (!body || typeof body !== "object") {
|
|
31
31
|
throw new BadRequestError("Request body is required");
|
|
32
32
|
}
|
|
@@ -76,9 +76,10 @@ function handleHostFileResult({ body, headers }: RouteHandlerArgs) {
|
|
|
76
76
|
// match the actor that opened the target client's SSE stream. This blocks
|
|
77
77
|
// cross-user submissions even if a different user somehow obtains the
|
|
78
78
|
// target client id.
|
|
79
|
-
const submittingActorPrincipalId =
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
const submittingActorPrincipalId =
|
|
80
|
+
await resolveActorPrincipalIdForLocalGuardian(
|
|
81
|
+
headerMap["x-vellum-actor-principal-id"]?.trim() || undefined,
|
|
82
|
+
);
|
|
82
83
|
enforceSameActorOrThrow({
|
|
83
84
|
sourceActorPrincipalId: submittingActorPrincipalId,
|
|
84
85
|
targetActorPrincipalId: peeked.targetActorPrincipalId,
|
|
@@ -39,10 +39,10 @@ function findProxyByTransferId(transferId: string) {
|
|
|
39
39
|
// GET /v1/transfers/:transferId/content
|
|
40
40
|
// ---------------------------------------------------------------------------
|
|
41
41
|
|
|
42
|
-
function handleTransferContentGet({
|
|
42
|
+
async function handleTransferContentGet({
|
|
43
43
|
pathParams = {},
|
|
44
44
|
headers = {},
|
|
45
|
-
}: RouteHandlerArgs): Uint8Array {
|
|
45
|
+
}: RouteHandlerArgs): Promise<Uint8Array> {
|
|
46
46
|
const transferId = pathParams.transferId;
|
|
47
47
|
if (!transferId) {
|
|
48
48
|
throw new BadRequestError("transferId path parameter is required");
|
|
@@ -72,7 +72,7 @@ function handleTransferContentGet({
|
|
|
72
72
|
// the value persisted at registration time so a brief reconnect does
|
|
73
73
|
// not 403 a legitimate fetch.
|
|
74
74
|
enforceSameActorOrThrow({
|
|
75
|
-
sourceActorPrincipalId: resolveActorPrincipalIdForLocalGuardian(
|
|
75
|
+
sourceActorPrincipalId: await resolveActorPrincipalIdForLocalGuardian(
|
|
76
76
|
headerMap["x-vellum-actor-principal-id"]?.trim() || undefined,
|
|
77
77
|
),
|
|
78
78
|
targetActorPrincipalId:
|
|
@@ -151,7 +151,7 @@ async function handleTransferContentPut({
|
|
|
151
151
|
);
|
|
152
152
|
|
|
153
153
|
enforceSameActorOrThrow({
|
|
154
|
-
sourceActorPrincipalId: resolveActorPrincipalIdForLocalGuardian(
|
|
154
|
+
sourceActorPrincipalId: await resolveActorPrincipalIdForLocalGuardian(
|
|
155
155
|
headerMap["x-vellum-actor-principal-id"]?.trim() || undefined,
|
|
156
156
|
),
|
|
157
157
|
targetActorPrincipalId:
|
|
@@ -181,7 +181,7 @@ async function handleTransferContentPut({
|
|
|
181
181
|
// POST /v1/host-transfer-result
|
|
182
182
|
// ---------------------------------------------------------------------------
|
|
183
183
|
|
|
184
|
-
function handleTransferResult({ body, headers }: RouteHandlerArgs) {
|
|
184
|
+
async function handleTransferResult({ body, headers }: RouteHandlerArgs) {
|
|
185
185
|
if (!body || typeof body !== "object") {
|
|
186
186
|
throw new BadRequestError("Request body is required");
|
|
187
187
|
}
|
|
@@ -222,7 +222,7 @@ function handleTransferResult({ body, headers }: RouteHandlerArgs) {
|
|
|
222
222
|
);
|
|
223
223
|
|
|
224
224
|
enforceSameActorOrThrow({
|
|
225
|
-
sourceActorPrincipalId: resolveActorPrincipalIdForLocalGuardian(
|
|
225
|
+
sourceActorPrincipalId: await resolveActorPrincipalIdForLocalGuardian(
|
|
226
226
|
headerMap["x-vellum-actor-principal-id"]?.trim() || undefined,
|
|
227
227
|
),
|
|
228
228
|
targetActorPrincipalId: peeked.targetActorPrincipalId,
|
|
@@ -51,7 +51,7 @@ export function routeDefinitionsToHTTPRoutes(
|
|
|
51
51
|
handler: async ({ req, url, params, authContext }) => {
|
|
52
52
|
try {
|
|
53
53
|
if (r.requireGuardian) {
|
|
54
|
-
const guardianError = requireBoundGuardian(authContext);
|
|
54
|
+
const guardianError = await requireBoundGuardian(authContext);
|
|
55
55
|
if (guardianError) return guardianError;
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -10,7 +10,8 @@ import { z } from "zod";
|
|
|
10
10
|
import { getCpuLimit, getIsPlatform } from "../../config/env-registry.js";
|
|
11
11
|
import { parseIdentityFields } from "../../daemon/handlers/identity.js";
|
|
12
12
|
import { getProfilerRuntimeStatus } from "../../daemon/profiler-run-store.js";
|
|
13
|
-
import {
|
|
13
|
+
import { getMaxRollbackVersion } from "../../memory/migrations/run-migrations.js";
|
|
14
|
+
import { migrationSteps } from "../../memory/steps.js";
|
|
14
15
|
import { getCesClient } from "../../security/secure-keys.js";
|
|
15
16
|
import {
|
|
16
17
|
getDiskUsageInfo,
|
|
@@ -335,7 +336,7 @@ function getDetailedHealth() {
|
|
|
335
336
|
memory: getMemoryInfo(),
|
|
336
337
|
cpu: getCpuInfo(),
|
|
337
338
|
migrations: {
|
|
338
|
-
dbVersion:
|
|
339
|
+
dbVersion: getMaxRollbackVersion(migrationSteps),
|
|
339
340
|
lastWorkspaceMigrationId:
|
|
340
341
|
getLastWorkspaceMigrationId(WORKSPACE_MIGRATIONS),
|
|
341
342
|
},
|
|
@@ -680,7 +680,7 @@ export async function handleChannelInbound({
|
|
|
680
680
|
canonicalAssistantId,
|
|
681
681
|
assistantId,
|
|
682
682
|
content,
|
|
683
|
-
channelId: resolvedMember?.
|
|
683
|
+
channelId: resolvedMember?.channelId,
|
|
684
684
|
});
|
|
685
685
|
}
|
|
686
686
|
|
|
@@ -761,7 +761,7 @@ export async function handleChannelInbound({
|
|
|
761
761
|
: enforceAdmissionPolicy({
|
|
762
762
|
sourceChannel,
|
|
763
763
|
trustClass: trustCtx.trustClass,
|
|
764
|
-
memberStatus: resolvedMember?.
|
|
764
|
+
memberStatus: resolvedMember?.status,
|
|
765
765
|
policy: admissionPolicyFromGateway,
|
|
766
766
|
});
|
|
767
767
|
if (!admissionResult.admitted) {
|
|
@@ -801,7 +801,7 @@ export async function handleChannelInbound({
|
|
|
801
801
|
// guardian sees "previously pending" etc.
|
|
802
802
|
let guardianNotified = false;
|
|
803
803
|
try {
|
|
804
|
-
const accessResult = notifyGuardianOfAccessRequest({
|
|
804
|
+
const accessResult = await notifyGuardianOfAccessRequest({
|
|
805
805
|
canonicalAssistantId,
|
|
806
806
|
sourceChannel,
|
|
807
807
|
conversationExternalId,
|
|
@@ -811,7 +811,7 @@ export async function handleChannelInbound({
|
|
|
811
811
|
...(resolvedMember
|
|
812
812
|
? {
|
|
813
813
|
previousMemberStatus: channelStatusToMemberStatus(
|
|
814
|
-
resolvedMember.
|
|
814
|
+
resolvedMember.status,
|
|
815
815
|
),
|
|
816
816
|
}
|
|
817
817
|
: {}),
|
|
@@ -935,7 +935,7 @@ export async function handleChannelInbound({
|
|
|
935
935
|
}
|
|
936
936
|
|
|
937
937
|
// ── Ingress escalation ──
|
|
938
|
-
const escalationResponse = handleEscalationIntercept({
|
|
938
|
+
const escalationResponse = await handleEscalationIntercept({
|
|
939
939
|
resolvedMember,
|
|
940
940
|
canonicalAssistantId,
|
|
941
941
|
sourceChannel,
|