@vellumai/assistant 0.7.1 → 0.7.3
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 +48 -50
- package/Dockerfile +1 -0
- package/README.md +1 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +9 -3
- package/bun.lock +26 -26
- package/docs/architecture/memory.md +5 -2
- package/docs/architecture/security.md +20 -0
- package/docs/plugins.md +7 -9
- package/knip.json +1 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +52 -5
- package/node_modules/@vellumai/gateway-client/src/types.ts +11 -0
- package/node_modules/@vellumai/service-contracts/package.json +2 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/contracts.test.ts +4 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +107 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +5 -1
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +24 -0
- package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +84 -0
- package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
- package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
- package/node_modules/@vellumai/twilio-client/bun.lock +24 -0
- package/node_modules/@vellumai/twilio-client/package.json +18 -0
- package/node_modules/@vellumai/twilio-client/src/__tests__/twilio-client.test.ts +128 -0
- package/node_modules/@vellumai/twilio-client/src/index.ts +179 -0
- package/node_modules/@vellumai/twilio-client/tsconfig.json +20 -0
- package/openapi.yaml +1020 -40
- package/package.json +6 -3
- package/src/__tests__/app-builder-tool-scripts.test.ts +3 -3
- package/src/__tests__/app-bundler.test.ts +170 -1
- package/src/__tests__/app-control-flow.test.ts +384 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +98 -0
- package/src/__tests__/app-control-tool-schemas.test.ts +621 -0
- package/src/__tests__/app-executors.test.ts +30 -43
- package/src/__tests__/approval-routes-http.test.ts +23 -6
- package/src/__tests__/assistant-event-hub-machine-name.test.ts +146 -0
- package/src/__tests__/assistant-event-hub-targeted.test.ts +257 -0
- package/src/__tests__/assistant-event-hub.test.ts +157 -2
- package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -7
- package/src/__tests__/auto-analysis-end-to-end.test.ts +62 -1
- package/src/__tests__/background-shell-host-bash.test.ts +14 -15
- package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +44 -0
- package/src/__tests__/btw-routes.test.ts +13 -4
- package/src/__tests__/call-controller.test.ts +49 -1
- package/src/__tests__/call-conversation-messages.test.ts +8 -2
- package/src/__tests__/call-domain.test.ts +0 -2
- package/src/__tests__/call-routes-http.test.ts +0 -2
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
- package/src/__tests__/channel-readiness-service.test.ts +62 -2
- package/src/__tests__/checker.test.ts +3 -4
- package/src/__tests__/config-loader-backfill.test.ts +461 -147
- package/src/__tests__/config-loader-platform-defaults.test.ts +196 -0
- package/src/__tests__/config-schema-cmd.test.ts +0 -1
- package/src/__tests__/config-schema.test.ts +1 -0
- package/src/__tests__/config-set-platform-guard.test.ts +48 -4
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +20 -11
- package/src/__tests__/config-watcher.test.ts +142 -71
- package/src/__tests__/context-search-agent-runner.test.ts +61 -3
- package/src/__tests__/context-search-conversations-source.test.ts +0 -24
- package/src/__tests__/context-search-fanout.test.ts +0 -1
- package/src/__tests__/context-search-memory-source.test.ts +3 -7
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -1
- package/src/__tests__/context-search-workspace-source.test.ts +0 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
- package/src/__tests__/conversation-agent-loop.test.ts +454 -5
- package/src/__tests__/conversation-app-control-instantiation.test.ts +392 -0
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +237 -0
- package/src/__tests__/conversation-error.test.ts +150 -3
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-lifecycle.test.ts +36 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +283 -0
- package/src/__tests__/conversation-process-callsite.test.ts +43 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +6 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +120 -72
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +65 -0
- package/src/__tests__/conversation-slash-commands.test.ts +0 -4
- package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
- package/src/__tests__/conversation-speed-override.test.ts +0 -3
- package/src/__tests__/conversation-store.test.ts +0 -18
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +202 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +328 -0
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +404 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +2 -5
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +5 -12
- package/src/__tests__/credential-execution-managed-contract.test.ts +3 -131
- package/src/__tests__/credentials-cli.test.ts +12 -12
- package/src/__tests__/cu-unified-flow.test.ts +351 -23
- package/src/__tests__/daemon-credential-client.test.ts +101 -19
- package/src/__tests__/date-context.test.ts +164 -2
- package/src/__tests__/db-schedule-syntax-migration.test.ts +2 -0
- package/src/__tests__/disk-pressure-guard.test.ts +262 -0
- package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
- package/src/__tests__/disk-pressure-policy.test.ts +241 -0
- package/src/__tests__/disk-pressure-routes.test.ts +379 -0
- package/src/__tests__/disk-pressure-tools.test.ts +277 -0
- package/src/__tests__/disk-usage.test.ts +150 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/events-client-registration.test.ts +52 -0
- package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
- package/src/__tests__/file-write-tool.test.ts +4 -10
- package/src/__tests__/filing-service.test.ts +3 -4
- package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -2
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -2
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
- package/src/__tests__/heartbeat-service.test.ts +968 -2
- package/src/__tests__/helpers/call-route-handler.ts +7 -1
- package/src/__tests__/host-app-control-proxy.test.ts +772 -0
- package/src/__tests__/host-app-control-routes.test.ts +263 -0
- package/src/__tests__/host-bash-proxy.test.ts +439 -47
- package/src/__tests__/host-bash-routes.test.ts +459 -0
- package/src/__tests__/host-browser-proxy.test.ts +24 -22
- package/src/__tests__/host-browser-routes.test.ts +39 -13
- package/src/__tests__/host-cu-proxy.test.ts +248 -52
- package/src/__tests__/host-cu-routes-targeted.test.ts +429 -0
- package/src/__tests__/host-file-edit-tool.test.ts +47 -1
- package/src/__tests__/host-file-proxy-targeted.test.ts +378 -0
- package/src/__tests__/host-file-proxy.test.ts +301 -45
- package/src/__tests__/host-file-read-tool.test.ts +17 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +420 -0
- package/src/__tests__/host-file-write-tool.test.ts +42 -1
- package/src/__tests__/host-proxy-base.test.ts +312 -0
- package/src/__tests__/host-shell-tool.test.ts +22 -4
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +932 -0
- package/src/__tests__/host-transfer-proxy.test.ts +121 -22
- package/src/__tests__/host-transfer-routes-targeted.test.ts +662 -0
- package/src/__tests__/http-user-message-parity.test.ts +108 -1
- package/src/__tests__/identity-intro-cache.test.ts +29 -0
- package/src/__tests__/identity-routes.test.ts +103 -1
- package/src/__tests__/init-feature-flag-overrides.test.ts +26 -3
- package/src/__tests__/injector-chain.test.ts +18 -6
- package/src/__tests__/injector-disk-pressure.test.ts +224 -0
- package/src/__tests__/inline-command-runner.test.ts +0 -1
- package/src/__tests__/inline-skill-load-permissions.test.ts +5 -11
- package/src/__tests__/integration-status.test.ts +85 -5
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +95 -5
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +17 -0
- package/src/__tests__/managed-profile-guard.test.ts +18 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +0 -1
- package/src/__tests__/mcp-abort-signal.test.ts +130 -0
- package/src/__tests__/mcp-auth-routes.test.ts +197 -0
- package/src/__tests__/mcp-cli.test.ts +338 -2
- package/src/__tests__/memory-admin-recall.test.ts +3 -11
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +188 -0
- package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
- package/src/__tests__/migration-import-commit-http.test.ts +108 -2
- package/src/__tests__/mock-gateway-ipc.ts +1 -0
- package/src/__tests__/normalize-onboarding.test.ts +180 -0
- package/src/__tests__/oauth-cli.test.ts +0 -2
- package/src/__tests__/oauth-connect-routes.test.ts +316 -0
- package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
- package/src/__tests__/oauth2-gateway-transport.test.ts +0 -1
- package/src/__tests__/onboarding-persona-write.test.ts +308 -0
- package/src/__tests__/openai-provider.test.ts +45 -8
- package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
- package/src/__tests__/persistence-secret-redaction.test.ts +299 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +5 -9
- package/src/__tests__/platform-callback-registration.test.ts +21 -4
- package/src/__tests__/platform.test.ts +2 -1
- package/src/__tests__/playbook-execution.test.ts +0 -43
- package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
- package/src/__tests__/prechat-onboarding-contract.test.ts +214 -25
- package/src/__tests__/process-message-background-slack.test.ts +2 -0
- package/src/__tests__/provider-commit-message-generator.test.ts +0 -1
- package/src/__tests__/provider-tool-name.test.ts +23 -0
- package/src/__tests__/public-ingress-urls.test.ts +97 -0
- package/src/__tests__/relay-server.test.ts +15 -4
- package/src/__tests__/require-fresh-approval.test.ts +0 -1
- package/src/__tests__/retry-backoff.test.ts +87 -0
- package/src/__tests__/runtime-events-sse.test.ts +2 -2
- package/src/__tests__/sanitize-config-for-transfer.test.ts +24 -2
- package/src/__tests__/schedule-retry.test.ts +715 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
- package/src/__tests__/script-proxy-mitm-handler.test.ts +1 -1
- package/src/__tests__/secret-ingress-http.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +3 -0
- package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -1
- package/src/__tests__/skill-feature-flags.test.ts +43 -41
- package/src/__tests__/skill-load-feature-flag.test.ts +13 -14
- package/src/__tests__/skill-load-inline-command.test.ts +0 -51
- package/src/__tests__/skill-load-inline-includes.test.ts +0 -43
- package/src/__tests__/skill-projection.benchmark.test.ts +0 -1
- package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -1
- package/src/__tests__/slack-channel-config.test.ts +9 -14
- package/src/__tests__/suggestion-routes.test.ts +46 -0
- package/src/__tests__/system-prompt-ask-mode.test.ts +0 -1
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/telegram-config.test.ts +0 -1
- package/src/__tests__/test-preload.ts +8 -0
- package/src/__tests__/tool-approval-handler.test.ts +3 -4
- package/src/__tests__/tool-audit-listener.test.ts +48 -0
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -1
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/twilio-config.test.ts +3 -16
- package/src/__tests__/twilio-routes.test.ts +3 -5
- package/src/__tests__/twilio-validation.test.ts +93 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -4
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -4
- package/src/__tests__/voice-ingress-preflight.test.ts +19 -0
- package/src/__tests__/workspace-migration-006-services-config.test.ts +3 -2
- package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
- package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
- package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -5
- package/src/__tests__/workspace-migration-down-functions.test.ts +8 -8
- package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +90 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +10 -6
- package/src/approvals/guardian-decision-primitive.ts +13 -0
- package/src/approvals/guardian-request-resolvers.ts +16 -17
- package/src/backup/__tests__/paths.test.ts +0 -22
- package/src/backup/__tests__/restore.test.ts +51 -151
- package/src/backup/paths.ts +2 -18
- package/src/backup/restore.ts +107 -231
- package/src/backup/snapshot-lock.ts +2 -27
- package/src/bundler/app-bundler.ts +51 -3
- package/src/bundler/compiler-tools.ts +3 -2
- package/src/calls/call-conversation-messages.ts +46 -10
- package/src/calls/relay-server.ts +4 -44
- package/src/calls/twilio-config.ts +2 -17
- package/src/calls/twilio-rest.ts +33 -105
- package/src/calls/twilio-routes.ts +11 -12
- package/src/channels/types.ts +8 -7
- package/src/cli/commands/__tests__/backup.test.ts +6 -277
- package/src/cli/commands/__tests__/gateway.test.ts +288 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +4 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +0 -5
- package/src/cli/commands/backup.ts +6 -331
- package/src/cli/commands/bash.ts +35 -108
- package/src/cli/commands/clients.ts +36 -37
- package/src/cli/commands/contacts.ts +137 -25
- package/src/cli/commands/conversations.ts +2 -5
- package/src/cli/commands/credentials.ts +71 -7
- package/src/cli/commands/domain.ts +66 -15
- package/src/cli/commands/gateway.ts +183 -0
- package/src/cli/commands/keys.ts +9 -6
- package/src/cli/commands/mcp.ts +116 -156
- package/src/cli/commands/memory-v2.ts +303 -7
- package/src/cli/commands/oauth/__tests__/connect.test.ts +437 -1
- package/src/cli/commands/oauth/connect.ts +127 -1
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -4
- package/src/cli/commands/platform/__tests__/connect.test.ts +7 -3
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -3
- package/src/cli/commands/platform/__tests__/status.test.ts +116 -21
- package/src/cli/commands/platform/disconnect.ts +5 -4
- package/src/cli/commands/platform/index.ts +16 -25
- package/src/cli/commands/status.ts +57 -0
- package/src/cli/lib/daemon-credential-client.ts +110 -28
- package/src/cli/program.ts +6 -2
- package/src/config/assistant-feature-flags.ts +79 -12
- package/src/config/bundled-skills/acp/SKILL.md +6 -0
- package/src/config/bundled-skills/acp/TOOLS.json +1 -22
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -109
- package/src/config/bundled-skills/app-builder/TOOLS.json +1 -28
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -10
- package/src/config/bundled-skills/app-control/SKILL.md +75 -0
- package/src/config/bundled-skills/app-control/TOOLS.json +299 -0
- package/src/config/bundled-skills/app-control/tools/app-control-click.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-combo.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-drag.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-observe.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-press.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-sequence.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-start.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-stop.ts +12 -0
- package/src/config/bundled-skills/app-control/tools/app-control-type.ts +12 -0
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +67 -43
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -16
- package/src/config/bundled-skills/document/TOOLS.json +0 -8
- package/src/config/bundled-skills/followups/TOOLS.json +0 -12
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/TOOLS.json +0 -4
- package/src/config/bundled-skills/media-processing/TOOLS.json +0 -24
- package/src/config/bundled-skills/messaging/TOOLS.json +0 -40
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
- package/src/config/bundled-skills/phone-calls/TOOLS.json +0 -12
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +25 -4
- package/src/config/bundled-skills/playbooks/TOOLS.json +0 -16
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +14 -14
- package/src/config/bundled-skills/sequences/TOOLS.json +0 -36
- package/src/config/bundled-skills/settings/SKILL.md +4 -0
- package/src/config/bundled-skills/settings/TOOLS.json +0 -12
- package/src/config/bundled-skills/skill-management/SKILL.md +6 -0
- package/src/config/bundled-skills/skill-management/TOOLS.json +0 -8
- package/src/config/bundled-skills/subagent/SKILL.md +6 -2
- package/src/config/bundled-skills/subagent/TOOLS.json +0 -20
- package/src/config/bundled-skills/transcribe/SKILL.md +4 -0
- package/src/config/bundled-skills/transcribe/TOOLS.json +0 -4
- package/src/config/bundled-tool-registry.ts +21 -0
- package/src/config/env-registry.ts +0 -2
- package/src/config/env.ts +19 -20
- package/src/config/feature-flag-registry.json +47 -135
- package/src/config/loader.ts +197 -104
- package/src/config/sanitize-for-transfer.ts +2 -0
- package/src/config/schemas/__tests__/memory-lifecycle.test.ts +80 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +17 -9
- package/src/config/schemas/call-site-catalog.ts +14 -0
- package/src/config/schemas/calls.ts +0 -9
- package/src/config/schemas/channels.ts +0 -5
- package/src/config/schemas/heartbeat.ts +64 -1
- package/src/config/schemas/ingress.ts +10 -6
- package/src/config/schemas/llm.ts +7 -10
- package/src/config/schemas/memory-lifecycle.ts +90 -24
- package/src/config/schemas/memory-v2.ts +121 -13
- package/src/config/schemas/platform.ts +49 -3
- package/src/config/schemas/services.ts +29 -15
- package/src/config/schemas/skills.ts +0 -6
- package/src/config/seed-inference-profiles.ts +230 -33
- package/src/contacts/contact-store.ts +0 -55
- package/src/contacts/contacts-write.ts +0 -27
- package/src/context/window-manager.ts +1 -2
- package/src/credential-execution/feature-gates.ts +10 -10
- package/src/credential-execution/process-manager.ts +12 -41
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +187 -5
- package/src/daemon/assistant-attachments.ts +4 -4
- package/src/daemon/bootstrap-turn-cleanup.ts +45 -0
- package/src/daemon/config-watcher.ts +89 -60
- package/src/daemon/conversation-agent-loop-handlers.ts +27 -3
- package/src/daemon/conversation-agent-loop.ts +202 -61
- package/src/daemon/conversation-error.ts +87 -15
- package/src/daemon/conversation-lifecycle.ts +9 -4
- package/src/daemon/conversation-process.ts +24 -11
- package/src/daemon/conversation-runtime-assembly.ts +28 -2
- package/src/daemon/conversation-store.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +305 -4
- package/src/daemon/conversation-tool-setup.ts +66 -62
- package/src/daemon/conversation.ts +38 -24
- package/src/daemon/date-context.ts +71 -22
- package/src/daemon/disk-pressure-background-gate.ts +73 -0
- package/src/daemon/disk-pressure-guard.ts +343 -0
- package/src/daemon/disk-pressure-policy.ts +163 -0
- package/src/daemon/doordash-steps.ts +1 -1
- package/src/daemon/handlers/shared.ts +4 -2
- package/src/daemon/handlers/skills.ts +3 -4
- package/src/daemon/host-app-control-proxy.ts +389 -0
- package/src/daemon/host-bash-proxy.ts +117 -82
- package/src/daemon/host-browser-proxy.ts +67 -82
- package/src/daemon/host-cu-proxy.ts +127 -86
- package/src/daemon/host-file-proxy.ts +129 -69
- package/src/daemon/host-proxy-base.ts +294 -0
- package/src/daemon/host-proxy-preactivation.ts +82 -0
- package/src/daemon/host-transfer-proxy.ts +338 -129
- package/src/daemon/lifecycle.ts +194 -145
- package/src/daemon/meet-host-supervisor.ts +4 -4
- package/src/daemon/meet-manifest-loader.ts +0 -1
- package/src/daemon/memory-v2-startup.ts +14 -4
- package/src/daemon/message-protocol.ts +6 -8
- package/src/daemon/message-types/contacts.ts +23 -1
- package/src/daemon/message-types/conversations.ts +15 -8
- package/src/daemon/message-types/disk-pressure.ts +9 -0
- package/src/daemon/message-types/host-app-control.ts +150 -0
- package/src/daemon/message-types/host-bash.ts +4 -0
- package/src/daemon/message-types/host-cu.ts +2 -0
- package/src/daemon/message-types/host-file.ts +4 -0
- package/src/daemon/message-types/host-transfer.ts +3 -0
- package/src/daemon/message-types/messages.ts +3 -0
- package/src/daemon/message-types/schedules.ts +8 -3
- package/src/daemon/message-types/skills.ts +2 -2
- package/src/daemon/process-message.ts +18 -1
- package/src/daemon/profiler-run-store.ts +5 -5
- package/src/daemon/shutdown-handlers.ts +0 -3
- package/src/daemon/tool-setup-types.ts +51 -0
- package/src/daemon/tool-side-effects.ts +1 -1
- package/src/documents/document-store.ts +85 -0
- package/src/events/tool-audit-listener.ts +2 -1
- package/src/filing/filing-service.ts +30 -5
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +24 -23
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +252 -0
- package/src/heartbeat/heartbeat-run-store.ts +249 -0
- package/src/heartbeat/heartbeat-service.ts +459 -54
- package/src/home/__tests__/post-connect-feed.test.ts +99 -0
- package/src/home/__tests__/relationship-state-writer.test.ts +11 -9
- package/src/home/__tests__/suggested-prompts.test.ts +89 -0
- package/src/home/feed-scheduler.ts +18 -0
- package/src/home/post-connect-feed.ts +68 -0
- package/src/home/relationship-state-writer.ts +17 -92
- package/src/home/suggested-prompts.ts +46 -10
- package/src/inbound/platform-callback-registration.ts +8 -15
- package/src/inbound/public-ingress-urls.ts +32 -34
- package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
- package/src/ipc/__tests__/route-error-envelope.test.ts +80 -0
- package/src/ipc/assistant-server.ts +70 -3
- package/src/ipc/cli-client.ts +32 -1
- package/src/ipc/gateway-client.ts +37 -3
- package/src/live-voice/live-voice-archive.ts +4 -4
- package/src/live-voice/live-voice-metrics.ts +10 -10
- package/src/live-voice/protocol.ts +5 -7
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +304 -0
- package/src/mcp/mcp-auth-orchestrator.ts +213 -0
- package/src/mcp/mcp-auth-state.ts +133 -0
- package/src/mcp/mcp-oauth-provider.ts +19 -0
- package/src/media/image-service.ts +1 -7
- package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +24 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +52 -22
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
- package/src/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
- package/src/memory/__tests__/sparse-tokenize.test.ts +66 -0
- package/src/memory/admin.ts +5 -9
- package/src/memory/anisotropy.test.ts +247 -0
- package/src/memory/anisotropy.ts +443 -0
- package/src/memory/auto-analysis-constants.ts +17 -0
- package/src/memory/auto-analysis-guard.ts +5 -15
- package/src/memory/canonical-guardian-store.ts +7 -7
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +122 -0
- package/src/memory/context-search/agent-protocol.ts +6 -6
- package/src/memory/context-search/agent-runner.ts +51 -9
- package/src/memory/context-search/sources/conversations.ts +2 -11
- package/src/memory/context-search/sources/memory-v2.ts +22 -9
- package/src/memory/context-search/sources/memory.ts +0 -1
- package/src/memory/context-search/types.ts +0 -1
- package/src/memory/conversation-crud.ts +5 -13
- package/src/memory/conversation-key-store.ts +2 -15
- package/src/memory/db-init.ts +6 -0
- package/src/memory/embedding-backend.ts +9 -21
- package/src/memory/embedding-runtime-manager.ts +119 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +81 -25
- package/src/memory/graph/conversation-graph-memory.ts +43 -78
- package/src/memory/graph/extraction.ts +1 -3
- package/src/memory/graph/graph-search.test.ts +10 -67
- package/src/memory/graph/graph-search.ts +9 -20
- package/src/memory/graph/retriever.test.ts +6 -0
- package/src/memory/graph/retriever.ts +34 -10
- package/src/memory/graph/tools.ts +1 -1
- package/src/memory/indexer.ts +54 -45
- package/src/memory/job-handlers/backfill.ts +2 -11
- package/src/memory/job-handlers/cleanup.ts +43 -0
- package/src/memory/job-handlers/embedding.ts +6 -8
- package/src/memory/job-handlers/summarization.ts +2 -7
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +8 -2
- package/src/memory/jobs/embed-concept-page.ts +28 -2
- package/src/memory/jobs/embed-pkb-file.test.ts +2 -2
- package/src/memory/jobs-store.ts +114 -22
- package/src/memory/jobs-worker.ts +193 -106
- package/src/memory/memory-v2-activation-log-store.ts +33 -15
- package/src/memory/memory-v2-concept-frequency.ts +169 -0
- package/src/memory/migrations/237-heartbeat-runs.ts +45 -0
- package/src/memory/migrations/238-schedule-retry-policy.ts +20 -0
- package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/pkb/pkb-search.test.ts +6 -0
- package/src/memory/pkb/pkb-search.ts +7 -0
- package/src/memory/qdrant-client.ts +49 -32
- package/src/memory/rerank-local.ts +374 -0
- package/src/memory/schema/infrastructure.ts +15 -0
- package/src/memory/search/semantic.ts +13 -67
- package/src/memory/sparse-tokenize.ts +49 -0
- package/src/memory/trace-event-store.ts +1 -17
- package/src/memory/v2/__tests__/activation.test.ts +387 -344
- package/src/memory/v2/__tests__/consolidation-job.test.ts +40 -8
- package/src/memory/v2/__tests__/injection.test.ts +181 -169
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
- package/src/memory/v2/__tests__/qdrant.test.ts +16 -0
- package/src/memory/v2/__tests__/reranker.test.ts +338 -0
- package/src/memory/v2/__tests__/sim.test.ts +154 -188
- package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
- package/src/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
- package/src/memory/v2/__tests__/static-context.test.ts +76 -2
- package/src/memory/v2/activation.ts +213 -239
- package/src/memory/v2/consolidation-job.ts +65 -17
- package/src/memory/v2/constants.ts +7 -0
- package/src/memory/v2/injection.ts +123 -103
- package/src/memory/v2/prompts/consolidation.ts +348 -92
- package/src/memory/v2/qdrant.ts +198 -1
- package/src/memory/v2/reranker.ts +177 -0
- package/src/memory/v2/sim.ts +113 -77
- package/src/memory/v2/skill-content.ts +4 -3
- package/src/memory/v2/skill-store.ts +91 -53
- package/src/memory/v2/sparse-bm25.ts +245 -0
- package/src/memory/v2/static-context.ts +28 -5
- package/src/memory/v2/types.ts +10 -10
- package/src/messaging/providers/gmail/types.ts +0 -49
- package/src/messaging/providers/slack/adapter.ts +1 -31
- package/src/messaging/providers/slack/types.ts +0 -32
- package/src/notifications/README.md +10 -10
- package/src/notifications/broadcaster.ts +1 -1
- package/src/notifications/copy-composer.ts +13 -0
- package/src/notifications/guardian-question-mode.ts +5 -5
- package/src/notifications/signal.ts +4 -0
- package/src/oauth/AGENTS.md +3 -1
- package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
- package/src/oauth/connect-orchestrator.ts +6 -0
- package/src/oauth/connection-resolver.test.ts +66 -1
- package/src/oauth/connection-resolver.ts +55 -1
- package/src/oauth/credential-token-resolver.ts +1 -3
- package/src/oauth/manual-token-connection.ts +0 -4
- package/src/oauth/oauth-connect-state.ts +77 -0
- package/src/oauth/seed-providers.ts +58 -1
- package/src/outbound-proxy/index.ts +1 -37
- package/src/outbound-proxy/logging.ts +1 -1
- package/src/outbound-proxy/policy.ts +6 -5
- package/src/outbound-proxy/router.ts +2 -1
- package/src/permissions/approval-policy.test.ts +6 -275
- package/src/permissions/approval-policy.ts +0 -51
- package/src/permissions/checker.test.ts +0 -1
- package/src/permissions/checker.ts +3 -17
- package/src/permissions/gateway-threshold-reader.ts +2 -0
- package/src/permissions/prompter.ts +34 -1
- package/src/permissions/secret-prompter.ts +6 -2
- package/src/plugins/defaults/injectors.ts +35 -2
- package/src/plugins/defaults/memory-retrieval.ts +5 -6
- package/src/plugins/types.ts +7 -0
- package/src/proactive-artifact/aux-message-injector.ts +74 -0
- package/src/proactive-artifact/decision.test.ts +226 -0
- package/src/proactive-artifact/decision.ts +165 -0
- package/src/proactive-artifact/index.ts +7 -0
- package/src/proactive-artifact/job.test.ts +867 -0
- package/src/proactive-artifact/job.ts +352 -0
- package/src/proactive-artifact/message-copy.ts +41 -0
- package/src/proactive-artifact/trigger-state.test.ts +277 -0
- package/src/proactive-artifact/trigger-state.ts +119 -0
- package/src/prompts/bootstrap-cleanup.ts +27 -0
- package/src/prompts/normalize-onboarding.ts +80 -0
- package/src/prompts/persona-resolver.ts +101 -9
- package/src/prompts/system-prompt.ts +23 -24
- package/src/prompts/templates/BOOTSTRAP.md +13 -5
- package/src/prompts/templates/SOUL.md +13 -1
- package/src/providers/__tests__/retry-callsite.test.ts +222 -1
- package/src/providers/model-intents.ts +7 -0
- package/src/providers/openrouter/client.ts +8 -0
- package/src/providers/retry.ts +50 -0
- package/src/providers/speech-to-text/provider-catalog.ts +7 -8
- package/src/providers/types.ts +1 -0
- package/src/runtime/__tests__/agent-wake.test.ts +456 -3
- package/src/runtime/agent-wake.ts +238 -100
- package/src/runtime/assistant-event-hub.ts +151 -99
- package/src/runtime/auth/__tests__/middleware.test.ts +11 -56
- package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
- package/src/runtime/auth/middleware.ts +0 -96
- package/src/runtime/auth/route-policy.ts +32 -0
- package/src/runtime/auth/same-actor.ts +216 -0
- package/src/runtime/btw-sidechain.ts +2 -3
- package/src/runtime/channel-invite-transport.ts +2 -48
- package/src/runtime/channel-invite-transports/email.ts +1 -1
- package/src/runtime/channel-invite-transports/slack.ts +1 -1
- package/src/runtime/channel-invite-transports/telegram.ts +1 -1
- package/src/runtime/channel-invite-transports/voice.ts +1 -1
- package/src/runtime/channel-invite-transports/whatsapp.ts +1 -1
- package/src/runtime/channel-invite-types.ts +54 -0
- package/src/runtime/channel-readiness-service.ts +32 -13
- package/src/runtime/channel-retry-sweep.ts +65 -1
- package/src/runtime/guardian-reply-router.ts +10 -0
- package/src/runtime/http-server.ts +3 -329
- package/src/runtime/http-types.ts +0 -5
- package/src/runtime/local-actor-identity.ts +52 -11
- package/src/runtime/migrations/__tests__/vbundle-import-parity.test.ts +413 -0
- package/src/runtime/migrations/__tests__/vbundle-import-policy.test.ts +260 -0
- package/src/runtime/migrations/__tests__/vbundle-import-version-compat.test.ts +189 -0
- package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +153 -1
- package/src/runtime/migrations/__tests__/vbundle-symlink-importer.test.ts +451 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming-importer.test.ts +0 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-streaming.test.ts +515 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-tar.test.ts +437 -0
- package/src/runtime/migrations/__tests__/vbundle-symlink-walker.test.ts +319 -0
- package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +51 -1
- package/src/runtime/migrations/migration-transport.ts +7 -7
- package/src/runtime/migrations/vbundle-builder.ts +327 -60
- package/src/runtime/migrations/vbundle-import-analyzer.ts +4 -4
- package/src/runtime/migrations/vbundle-import-policy.ts +172 -0
- package/src/runtime/migrations/vbundle-importer.ts +245 -68
- package/src/runtime/migrations/vbundle-streaming-importer.ts +326 -35
- package/src/runtime/migrations/vbundle-streaming-validator.ts +157 -4
- package/src/runtime/migrations/vbundle-tar-stream.ts +15 -6
- package/src/runtime/migrations/vbundle-validator.ts +114 -0
- package/src/runtime/pending-interactions.ts +43 -9
- package/src/runtime/routes/__tests__/backup-routes.test.ts +22 -150
- package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -5
- package/src/runtime/routes/__tests__/gateway-log-routes.test.ts +242 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +112 -0
- package/src/runtime/routes/approval-interception-types.ts +13 -0
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +1 -1
- package/src/runtime/routes/backup-routes.ts +15 -38
- package/src/runtime/routes/btw-routes.ts +14 -37
- package/src/runtime/routes/client-routes.ts +21 -2
- package/src/runtime/routes/contact-prompt-routes.ts +183 -0
- package/src/runtime/routes/contact-routes.ts +0 -25
- package/src/runtime/routes/conversation-query-routes.ts +36 -1
- package/src/runtime/routes/conversation-routes.ts +65 -39
- package/src/runtime/routes/debug-bash-routes.ts +163 -0
- package/src/runtime/routes/disk-pressure-routes.ts +121 -0
- package/src/runtime/routes/document-pdf-renderer.ts +169 -0
- package/src/runtime/routes/documents-routes.ts +32 -75
- package/src/runtime/routes/errors.ts +19 -4
- package/src/runtime/routes/events-routes.ts +38 -0
- package/src/runtime/routes/gateway-log-routes.ts +79 -0
- package/src/runtime/routes/guardian-approval-interception.ts +2 -8
- package/src/runtime/routes/heartbeat-routes.ts +103 -38
- package/src/runtime/routes/host-app-control-routes.ts +134 -0
- package/src/runtime/routes/host-bash-routes.ts +56 -6
- package/src/runtime/routes/host-browser-routes.ts +108 -13
- package/src/runtime/routes/host-cu-routes.ts +66 -9
- package/src/runtime/routes/host-file-routes.ts +54 -5
- package/src/runtime/routes/host-transfer-routes.ts +122 -19
- package/src/runtime/routes/http-adapter.ts +1 -0
- package/src/runtime/routes/identity-intro-cache.ts +30 -0
- package/src/runtime/routes/identity-routes.ts +21 -180
- package/src/runtime/routes/inbound-message-handler.ts +78 -21
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -7
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +0 -8
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -0
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +0 -20
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +5 -13
- package/src/runtime/routes/index.ts +14 -0
- package/src/runtime/routes/mcp-auth-routes.ts +132 -0
- package/src/runtime/routes/memory-item-routes.test.ts +41 -15
- package/src/runtime/routes/memory-item-routes.ts +10 -12
- package/src/runtime/routes/memory-v2-routes.ts +474 -1
- package/src/runtime/routes/migration-routes.ts +96 -0
- package/src/runtime/routes/oauth-connect-routes.ts +153 -0
- package/src/runtime/routes/schedule-routes.ts +7 -0
- package/src/runtime/verification-outbound-actions.ts +4 -4
- package/src/runtime/verification-templates.ts +4 -7
- package/src/schedule/integration-status.ts +66 -2
- package/src/schedule/recurrence-engine.ts +4 -1
- package/src/schedule/retry-backoff.ts +18 -0
- package/src/schedule/retry-policy.ts +82 -0
- package/src/schedule/run-script.ts +37 -5
- package/src/schedule/schedule-recovery.ts +64 -0
- package/src/schedule/schedule-store.ts +106 -2
- package/src/schedule/scheduler-types.ts +25 -0
- package/src/schedule/scheduler.ts +83 -39
- package/src/security/encrypted-store.ts +2 -0
- package/src/security/oauth-callback-registry.ts +8 -0
- package/src/security/secure-keys.ts +55 -0
- package/src/sequence/analytics.ts +5 -5
- package/src/sequence/engine.ts +1 -1
- package/src/skills/catalog-files.ts +2 -8
- package/src/skills/include-graph.ts +5 -5
- package/src/skills/remote-skill-policy.ts +10 -16
- package/src/skills/skill-file-provider.ts +1 -1
- package/src/skills/skill-file-types.ts +13 -0
- package/src/skills/skillssh-audit-types.ts +28 -0
- package/src/skills/skillssh-registry.ts +8 -21
- package/src/subagent/index.ts +1 -7
- package/src/subagent/manager.ts +1 -15
- package/src/tasks/task-runner.ts +0 -1
- package/src/tasks/task-store.ts +0 -3
- package/src/telemetry/types.ts +2 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +21 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/app-control/skill-proxy-bridge.ts +28 -0
- package/src/tools/apps/executors.ts +56 -69
- package/src/tools/background-tool-registry.ts +17 -3
- package/src/tools/browser/__tests__/browser-status.test.ts +21 -18
- package/src/tools/browser/browser-execution.ts +2 -2
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +55 -4
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +12 -6
- package/src/tools/browser/cdp-client/factory.ts +23 -24
- package/src/tools/browser/cdp-client/index.ts +1 -14
- package/src/tools/computer-use/definitions.ts +42 -20
- package/src/tools/executor.ts +2 -0
- package/src/tools/host-filesystem/edit.test.ts +151 -0
- package/src/tools/host-filesystem/edit.ts +68 -0
- package/src/tools/host-filesystem/read.test.ts +129 -0
- package/src/tools/host-filesystem/read.ts +68 -0
- package/src/tools/host-filesystem/transfer.test.ts +127 -2
- package/src/tools/host-filesystem/transfer.ts +78 -3
- package/src/tools/host-filesystem/write.test.ts +134 -0
- package/src/tools/host-filesystem/write.ts +68 -0
- package/src/tools/host-terminal/host-shell.ts +66 -1
- package/src/tools/mcp/mcp-tool-factory.ts +2 -1
- package/src/tools/memory/register.test.ts +12 -9
- package/src/tools/memory/register.ts +1 -2
- package/src/tools/provider-tool-name.ts +28 -0
- package/src/tools/registry.ts +30 -9
- package/src/tools/schedule/create.ts +6 -0
- package/src/tools/schedule/list.ts +2 -0
- package/src/tools/schedule/update.ts +10 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +2 -0
- package/src/tools/shared/filesystem/path-policy.ts +25 -1
- package/src/tools/skills/load.ts +0 -32
- package/src/tools/terminal/shell.ts +9 -1
- package/src/tools/tool-approval-handler.ts +32 -11
- package/src/tools/types.ts +28 -2
- package/src/tts/provider-catalog.ts +3 -5
- package/src/usage/pricing.ts +1 -1
- package/src/util/disk-usage.ts +138 -0
- package/src/util/platform.ts +21 -11
- package/src/util/process-liveness.ts +26 -0
- package/src/workspace/hatched-date.ts +86 -0
- package/src/workspace/heartbeat-service.ts +19 -0
- package/src/workspace/migrations/003-seed-device-id.ts +1 -1
- package/src/workspace/migrations/006-services-config.ts +8 -5
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +3 -9
- package/src/workspace/migrations/021-move-signals-to-workspace.ts +4 -10
- package/src/workspace/migrations/022-move-hooks-to-workspace.ts +4 -10
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +4 -11
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +3 -10
- package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +3 -2
- package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +2 -1
- package/src/workspace/migrations/059-move-pid-to-workspace.ts +3 -8
- package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +3 -8
- package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
- package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
- package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +72 -0
- package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
- package/src/workspace/migrations/AGENTS.md +1 -1
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +4 -10
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/migrations/utils.ts +21 -0
- package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
- package/src/__tests__/host-browser-e2e-cloud.test.ts +0 -443
- package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +0 -226
- package/src/__tests__/host-browser-ws-events-e2e.test.ts +0 -427
- package/src/__tests__/twilio-rest.test.ts +0 -34
- package/src/backup/__tests__/backup-key.test.ts +0 -152
- package/src/backup/__tests__/backup-worker.test.ts +0 -782
- package/src/backup/__tests__/offsite-writer.test.ts +0 -641
- package/src/backup/__tests__/stream-crypt.test.ts +0 -228
- package/src/backup/backup-key.ts +0 -137
- package/src/backup/backup-worker.ts +0 -472
- package/src/backup/offsite-writer.ts +0 -222
- package/src/backup/stream-crypt.ts +0 -263
- package/src/daemon/message-types/pairing.ts +0 -58
- package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
- package/src/memory/v2/skill-qdrant.ts +0 -395
- package/src/outbound-proxy/config.ts +0 -20
- package/src/outbound-proxy/health.ts +0 -18
- package/src/outbound-proxy/types.ts +0 -150
- package/src/runtime/capability-tokens.ts +0 -190
- package/src/signals/bash.ts +0 -198
- package/src/signals/mcp-reload.ts +0 -18
|
@@ -7,9 +7,11 @@ import {
|
|
|
7
7
|
parseChannelId,
|
|
8
8
|
parseInterfaceId,
|
|
9
9
|
} from "../channels/types.js";
|
|
10
|
+
import { getDiskPressureStatus } from "../daemon/disk-pressure-guard.js";
|
|
11
|
+
import { classifyDiskPressureTurnPolicy } from "../daemon/disk-pressure-policy.js";
|
|
10
12
|
import type { TrustContext } from "../daemon/trust-context.js";
|
|
11
13
|
import { updateDeliveredSegmentCount } from "../memory/delivery-channels.js";
|
|
12
|
-
import { linkMessage } from "../memory/delivery-crud.js";
|
|
14
|
+
import { clearPayload, linkMessage } from "../memory/delivery-crud.js";
|
|
13
15
|
import {
|
|
14
16
|
getRetryableEvents,
|
|
15
17
|
markProcessed,
|
|
@@ -18,10 +20,13 @@ import {
|
|
|
18
20
|
} from "../memory/delivery-status.js";
|
|
19
21
|
import { getLogger } from "../util/logger.js";
|
|
20
22
|
import { deliverReplyViaCallback } from "./channel-reply-delivery.js";
|
|
23
|
+
import { deliverChannelReply } from "./gateway-client.js";
|
|
21
24
|
import type { MessageProcessor } from "./http-types.js";
|
|
22
25
|
import { resolveRoutingStateFromRuntime } from "./trust-context-resolver.js";
|
|
23
26
|
|
|
24
27
|
const log = getLogger("runtime-http");
|
|
28
|
+
const DISK_PRESSURE_REMOTE_BLOCK_REPLY =
|
|
29
|
+
"Storage is critically low, so remote messages are ignored until the guardian frees enough space. Please try again later.";
|
|
25
30
|
|
|
26
31
|
function parseTrustRuntimeContext(value: unknown): TrustContext | undefined {
|
|
27
32
|
if (!value || typeof value !== "object") return undefined;
|
|
@@ -163,6 +168,65 @@ export async function sweepFailedEvents(
|
|
|
163
168
|
trustClass: "unknown",
|
|
164
169
|
};
|
|
165
170
|
|
|
171
|
+
const diskPressureDecision = classifyDiskPressureTurnPolicy(
|
|
172
|
+
getDiskPressureStatus(),
|
|
173
|
+
{
|
|
174
|
+
sourceChannel,
|
|
175
|
+
sourceInterface,
|
|
176
|
+
trustContext: {
|
|
177
|
+
sourceChannel: trustContext.sourceChannel,
|
|
178
|
+
trustClass: trustContext.trustClass,
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
);
|
|
182
|
+
if (diskPressureDecision.action === "block") {
|
|
183
|
+
clearPayload(event.id);
|
|
184
|
+
markProcessed(event.id);
|
|
185
|
+
log.info(
|
|
186
|
+
{
|
|
187
|
+
eventId: event.id,
|
|
188
|
+
conversationId: event.conversationId,
|
|
189
|
+
reason: diskPressureDecision.reason,
|
|
190
|
+
trustClass: trustContext.trustClass,
|
|
191
|
+
},
|
|
192
|
+
"Skipped channel retry during disk pressure cleanup mode",
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
const replyCallbackUrl =
|
|
196
|
+
typeof payload.replyCallbackUrl === "string"
|
|
197
|
+
? payload.replyCallbackUrl
|
|
198
|
+
: undefined;
|
|
199
|
+
const externalChatId =
|
|
200
|
+
typeof payload.externalChatId === "string"
|
|
201
|
+
? payload.externalChatId
|
|
202
|
+
: undefined;
|
|
203
|
+
if (replyCallbackUrl && externalChatId) {
|
|
204
|
+
const requesterExternalUserId =
|
|
205
|
+
trustContext.requesterExternalUserId ??
|
|
206
|
+
(typeof payload.senderExternalUserId === "string"
|
|
207
|
+
? payload.senderExternalUserId
|
|
208
|
+
: undefined);
|
|
209
|
+
const replyPayload: Parameters<typeof deliverChannelReply>[1] = {
|
|
210
|
+
chatId: externalChatId,
|
|
211
|
+
text: DISK_PRESSURE_REMOTE_BLOCK_REPLY,
|
|
212
|
+
assistantId,
|
|
213
|
+
};
|
|
214
|
+
if (sourceChannel === "slack" && requesterExternalUserId) {
|
|
215
|
+
replyPayload.ephemeral = true;
|
|
216
|
+
replyPayload.user = requesterExternalUserId;
|
|
217
|
+
}
|
|
218
|
+
try {
|
|
219
|
+
await deliverChannelReply(replyCallbackUrl, replyPayload);
|
|
220
|
+
} catch (err) {
|
|
221
|
+
log.warn(
|
|
222
|
+
{ err, eventId: event.id, conversationId: event.conversationId },
|
|
223
|
+
"Failed to deliver disk pressure retry block reply",
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
|
|
166
230
|
const metadataHintsRaw = sourceMetadata?.hints;
|
|
167
231
|
const metadataHints = Array.isArray(metadataHintsRaw)
|
|
168
232
|
? metadataHintsRaw.filter(
|
|
@@ -99,6 +99,13 @@ export interface GuardianReplyResult {
|
|
|
99
99
|
requestId?: string;
|
|
100
100
|
/** Detailed result from the canonical decision primitive (when a decision was attempted). */
|
|
101
101
|
canonicalResult?: CanonicalDecisionResult;
|
|
102
|
+
/** When a voice access request was approved, the contact that should be activated. */
|
|
103
|
+
activatedContact?: {
|
|
104
|
+
sourceChannel: string;
|
|
105
|
+
externalUserId: string;
|
|
106
|
+
externalChatId?: string;
|
|
107
|
+
displayName?: string;
|
|
108
|
+
};
|
|
102
109
|
/**
|
|
103
110
|
* When true, the caller should skip legacy approval interception for this
|
|
104
111
|
* message. Set by the invite handoff bypass so that "open invite flow"
|
|
@@ -686,6 +693,9 @@ async function applyDecision(
|
|
|
686
693
|
...(canonicalResult.resolverReplyText
|
|
687
694
|
? { replyText: canonicalResult.resolverReplyText }
|
|
688
695
|
: {}),
|
|
696
|
+
...(canonicalResult.activatedContact
|
|
697
|
+
? { activatedContact: canonicalResult.activatedContact }
|
|
698
|
+
: {}),
|
|
689
699
|
requestId,
|
|
690
700
|
canonicalResult,
|
|
691
701
|
};
|
|
@@ -45,18 +45,12 @@ import {
|
|
|
45
45
|
SttStreamSession,
|
|
46
46
|
} from "../stt/stt-stream-session.js";
|
|
47
47
|
import { getLogger } from "../util/logger.js";
|
|
48
|
-
|
|
49
|
-
import {
|
|
50
|
-
authenticateHostBrowserResultRequest,
|
|
51
|
-
authenticateRequest,
|
|
52
|
-
} from "./auth/middleware.js";
|
|
48
|
+
import { authenticateRequest } from "./auth/middleware.js";
|
|
53
49
|
import { parseSub } from "./auth/subject.js";
|
|
54
50
|
import { verifyToken } from "./auth/token-service.js";
|
|
55
|
-
import { verifyHostBrowserCapability } from "./capability-tokens.js";
|
|
56
51
|
import { sweepFailedEvents } from "./channel-retry-sweep.js";
|
|
57
52
|
import { httpError, type HttpErrorCode } from "./http-errors.js";
|
|
58
53
|
import { HttpRouter } from "./http-router.js";
|
|
59
|
-
// Middleware
|
|
60
54
|
import {
|
|
61
55
|
extractBearerToken,
|
|
62
56
|
isLoopbackHost,
|
|
@@ -91,29 +85,12 @@ import {
|
|
|
91
85
|
stopGuardianExpirySweep,
|
|
92
86
|
} from "./routes/channel-guardian-routes.js";
|
|
93
87
|
import { RouteError } from "./routes/errors.js";
|
|
94
|
-
import {
|
|
95
|
-
resolveHostBrowserEvent,
|
|
96
|
-
resolveHostBrowserResultByRequestId,
|
|
97
|
-
resolveHostBrowserSessionInvalidated,
|
|
98
|
-
} from "./routes/host-browser-routes.js";
|
|
99
88
|
import { handleHealth, handleReadyz } from "./routes/identity-routes.js";
|
|
100
89
|
import { matchSkillRoute } from "./skill-route-registry.js";
|
|
101
90
|
|
|
102
91
|
// Re-export for consumers
|
|
103
92
|
export { isPrivateAddress } from "./middleware/auth.js";
|
|
104
93
|
|
|
105
|
-
// Re-export shared types so existing consumers don't need to update imports
|
|
106
|
-
export type {
|
|
107
|
-
ApprovalConversationGenerator,
|
|
108
|
-
ApprovalCopyGenerator,
|
|
109
|
-
GuardianActionCopyGenerator,
|
|
110
|
-
GuardianFollowUpConversationGenerator,
|
|
111
|
-
MessageProcessor,
|
|
112
|
-
RuntimeAttachmentMetadata,
|
|
113
|
-
RuntimeHttpServerOptions,
|
|
114
|
-
RuntimeMessageConversationOptions,
|
|
115
|
-
} from "./http-types.js";
|
|
116
|
-
|
|
117
94
|
import type {
|
|
118
95
|
ApprovalConversationGenerator,
|
|
119
96
|
ApprovalCopyGenerator,
|
|
@@ -130,38 +107,10 @@ const DEFAULT_HOSTNAME = "127.0.0.1";
|
|
|
130
107
|
/** Global hard cap on request body size (512 MB — accommodates large .vbundle backup imports). */
|
|
131
108
|
const MAX_REQUEST_BODY_BYTES = 512 * 1024 * 1024;
|
|
132
109
|
|
|
133
|
-
/**
|
|
134
|
-
* WebSocket data attached to `/v1/browser-relay` connections. The route
|
|
135
|
-
* is used exclusively by the chrome-extension CDP proxy — outbound
|
|
136
|
-
* `host_browser_request` frames are pushed through the assistant event
|
|
137
|
-
* hub, and inbound `host_browser_result` frames are dispatched through
|
|
138
|
-
* `resolveHostBrowserResultByRequestId`. The extension may also submit
|
|
139
|
-
* results via `POST /v1/host-browser-result` (both transports resolve
|
|
140
|
-
* through the same core function).
|
|
141
|
-
*/
|
|
142
|
-
interface BrowserRelayWebSocketData {
|
|
143
|
-
wsType: "browser-relay";
|
|
144
|
-
connectionId: string;
|
|
145
|
-
/**
|
|
146
|
-
* Guardian identity derived from the JWT claims at WebSocket upgrade
|
|
147
|
-
* time. Undefined when HTTP auth is disabled (dev bypass) or when the
|
|
148
|
-
* token's sub cannot be parsed into an actor principal.
|
|
149
|
-
*/
|
|
150
|
-
guardianId?: string;
|
|
151
|
-
/**
|
|
152
|
-
* Stable per-extension-install identifier supplied by the client on
|
|
153
|
-
* the WebSocket handshake (via the `clientInstanceId` query param or
|
|
154
|
-
* the `x-client-instance-id` header). Allows multiple parallel installs
|
|
155
|
-
* for the same guardian (e.g. two Chrome profiles, two desktops) to
|
|
156
|
-
* coexist. Undefined on older extension builds.
|
|
157
|
-
*/
|
|
158
|
-
clientInstanceId?: string;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
110
|
/**
|
|
162
111
|
* WebSocket data attached to `/v1/calls/media-stream` connections.
|
|
163
112
|
* The `wsType` discriminator routes frames to the media-stream call
|
|
164
|
-
* session instead of the ConversationRelay
|
|
113
|
+
* session instead of the ConversationRelay handlers.
|
|
165
114
|
*/
|
|
166
115
|
interface MediaStreamWebSocketData {
|
|
167
116
|
wsType: "media-stream";
|
|
@@ -241,7 +190,6 @@ export class RuntimeHttpServer {
|
|
|
241
190
|
async start(): Promise<void> {
|
|
242
191
|
type AllWebSocketData =
|
|
243
192
|
| RelayWebSocketData
|
|
244
|
-
| BrowserRelayWebSocketData
|
|
245
193
|
| MediaStreamWebSocketData
|
|
246
194
|
| SttStreamWebSocketData
|
|
247
195
|
| LiveVoiceWebSocketData;
|
|
@@ -362,125 +310,6 @@ export class RuntimeHttpServer {
|
|
|
362
310
|
typeof message === "string"
|
|
363
311
|
? message
|
|
364
312
|
: new TextDecoder().decode(message);
|
|
365
|
-
if ("wsType" in data && data.wsType === "browser-relay") {
|
|
366
|
-
// Inbound frames on `/v1/browser-relay` carry one of:
|
|
367
|
-
// - `host_browser_result` — paired response to an outbound
|
|
368
|
-
// `host_browser_request` (see PR2).
|
|
369
|
-
// - `host_browser_event` — unsolicited CDP event forwarded
|
|
370
|
-
// from the extension's `chrome.debugger.onEvent`
|
|
371
|
-
// subscription (PR10).
|
|
372
|
-
// - `host_browser_session_invalidated` — detach
|
|
373
|
-
// notification forwarded from the extension's
|
|
374
|
-
// `chrome.debugger.onDetach` subscription (PR10).
|
|
375
|
-
//
|
|
376
|
-
// Every supported frame type delegates into a shared
|
|
377
|
-
// resolver exported from `host-browser-routes.ts` so the
|
|
378
|
-
// validation and resolution semantics stay in lockstep
|
|
379
|
-
// with the HTTP path. Malformed or unsupported frames are
|
|
380
|
-
// logged at debug and swallowed — we never throw out of a
|
|
381
|
-
// WebSocket `message` handler because an uncaught
|
|
382
|
-
// exception would tear down the whole socket for an
|
|
383
|
-
// attacker-controlled payload.
|
|
384
|
-
let parsed: unknown;
|
|
385
|
-
try {
|
|
386
|
-
parsed = JSON.parse(raw);
|
|
387
|
-
} catch (err) {
|
|
388
|
-
log.debug(
|
|
389
|
-
{
|
|
390
|
-
connectionId: data.connectionId,
|
|
391
|
-
error: err instanceof Error ? err.message : String(err),
|
|
392
|
-
},
|
|
393
|
-
"browser-relay: dropped non-JSON inbound frame",
|
|
394
|
-
);
|
|
395
|
-
return;
|
|
396
|
-
}
|
|
397
|
-
if (!parsed || typeof parsed !== "object") {
|
|
398
|
-
log.debug(
|
|
399
|
-
{ connectionId: data.connectionId },
|
|
400
|
-
"browser-relay: dropped non-object inbound frame",
|
|
401
|
-
);
|
|
402
|
-
return;
|
|
403
|
-
}
|
|
404
|
-
const frame = parsed as Record<string, unknown>;
|
|
405
|
-
switch (frame.type) {
|
|
406
|
-
case "host_browser_result": {
|
|
407
|
-
const resolution = resolveHostBrowserResultByRequestId({
|
|
408
|
-
requestId: frame.requestId,
|
|
409
|
-
content: frame.content,
|
|
410
|
-
isError: frame.isError,
|
|
411
|
-
});
|
|
412
|
-
if (!resolution.ok) {
|
|
413
|
-
log.warn(
|
|
414
|
-
{
|
|
415
|
-
connectionId: data.connectionId,
|
|
416
|
-
requestId:
|
|
417
|
-
typeof frame.requestId === "string"
|
|
418
|
-
? frame.requestId
|
|
419
|
-
: undefined,
|
|
420
|
-
code: resolution.code,
|
|
421
|
-
message: resolution.message,
|
|
422
|
-
},
|
|
423
|
-
"browser-relay: host_browser_result frame rejected",
|
|
424
|
-
);
|
|
425
|
-
}
|
|
426
|
-
return;
|
|
427
|
-
}
|
|
428
|
-
case "host_browser_event": {
|
|
429
|
-
const resolution = resolveHostBrowserEvent({
|
|
430
|
-
method: frame.method,
|
|
431
|
-
params: frame.params,
|
|
432
|
-
cdpSessionId: frame.cdpSessionId,
|
|
433
|
-
});
|
|
434
|
-
if (!resolution.ok) {
|
|
435
|
-
log.warn(
|
|
436
|
-
{
|
|
437
|
-
connectionId: data.connectionId,
|
|
438
|
-
method:
|
|
439
|
-
typeof frame.method === "string"
|
|
440
|
-
? frame.method
|
|
441
|
-
: undefined,
|
|
442
|
-
code: resolution.code,
|
|
443
|
-
message: resolution.message,
|
|
444
|
-
},
|
|
445
|
-
"browser-relay: host_browser_event frame rejected",
|
|
446
|
-
);
|
|
447
|
-
}
|
|
448
|
-
return;
|
|
449
|
-
}
|
|
450
|
-
case "host_browser_session_invalidated": {
|
|
451
|
-
const resolution = resolveHostBrowserSessionInvalidated({
|
|
452
|
-
targetId: frame.targetId,
|
|
453
|
-
reason: frame.reason,
|
|
454
|
-
});
|
|
455
|
-
if (!resolution.ok) {
|
|
456
|
-
log.warn(
|
|
457
|
-
{
|
|
458
|
-
connectionId: data.connectionId,
|
|
459
|
-
targetId:
|
|
460
|
-
typeof frame.targetId === "string"
|
|
461
|
-
? frame.targetId
|
|
462
|
-
: undefined,
|
|
463
|
-
code: resolution.code,
|
|
464
|
-
message: resolution.message,
|
|
465
|
-
},
|
|
466
|
-
"browser-relay: host_browser_session_invalidated frame rejected",
|
|
467
|
-
);
|
|
468
|
-
}
|
|
469
|
-
return;
|
|
470
|
-
}
|
|
471
|
-
case "keepalive": {
|
|
472
|
-
// Extension keepalive — acknowledged, no action needed.
|
|
473
|
-
return;
|
|
474
|
-
}
|
|
475
|
-
default: {
|
|
476
|
-
log.debug(
|
|
477
|
-
{ connectionId: data.connectionId, type: frame.type },
|
|
478
|
-
"browser-relay: dropped unsupported inbound frame type",
|
|
479
|
-
);
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
313
|
if ("wsType" in data && data.wsType === "media-stream") {
|
|
485
314
|
const msData = data as MediaStreamWebSocketData;
|
|
486
315
|
msData.session?.handleMessage(raw);
|
|
@@ -728,13 +557,6 @@ export class RuntimeHttpServer {
|
|
|
728
557
|
return handleReadyz();
|
|
729
558
|
}
|
|
730
559
|
|
|
731
|
-
// WebSocket upgrade for the Chrome extension browser relay.
|
|
732
|
-
if (
|
|
733
|
-
path === "/v1/browser-relay" &&
|
|
734
|
-
req.headers.get("upgrade")?.toLowerCase() === "websocket"
|
|
735
|
-
) {
|
|
736
|
-
return this.handleBrowserRelayUpgrade(req, server);
|
|
737
|
-
}
|
|
738
560
|
|
|
739
561
|
// WebSocket upgrade for ConversationRelay — before auth check because
|
|
740
562
|
// Twilio WebSocket connections don't use bearer tokens.
|
|
@@ -823,19 +645,7 @@ export class RuntimeHttpServer {
|
|
|
823
645
|
|
|
824
646
|
// JWT bearer authentication — replaces the old shared-secret comparison.
|
|
825
647
|
// authenticateRequest handles dev bypass (DISABLE_HTTP_AUTH) internally.
|
|
826
|
-
|
|
827
|
-
// Special-case: /v1/host-browser-result POST accepts either a
|
|
828
|
-
// daemon-minted JWT (legacy/cloud) or a host_browser capability
|
|
829
|
-
// token (self-hosted chrome extension). The chrome extension's
|
|
830
|
-
// HTTP fallback (`postHostBrowserResult`) hands over the same
|
|
831
|
-
// capability token it presented to `/v1/browser-relay`, so the
|
|
832
|
-
// POST route must understand both auth shapes. Every other route
|
|
833
|
-
// keeps the JWT-only flow via `authenticateRequest`.
|
|
834
|
-
const normalizedPath = path.endsWith("/") ? path.slice(0, -1) : path;
|
|
835
|
-
const authResult =
|
|
836
|
-
normalizedPath === "/v1/host-browser-result" && req.method === "POST"
|
|
837
|
-
? await authenticateHostBrowserResultRequest(req)
|
|
838
|
-
: authenticateRequest(req);
|
|
648
|
+
const authResult = authenticateRequest(req);
|
|
839
649
|
if (!authResult.ok) {
|
|
840
650
|
return authResult.response;
|
|
841
651
|
}
|
|
@@ -917,142 +727,6 @@ export class RuntimeHttpServer {
|
|
|
917
727
|
return routerResponse ?? httpError("NOT_FOUND", "Not found", 404);
|
|
918
728
|
}
|
|
919
729
|
|
|
920
|
-
private async handleBrowserRelayUpgrade(
|
|
921
|
-
req: Request,
|
|
922
|
-
server: ReturnType<typeof Bun.serve>,
|
|
923
|
-
): Promise<Response> {
|
|
924
|
-
if (
|
|
925
|
-
!isLoopbackHost(new URL(req.url).hostname) &&
|
|
926
|
-
!isPrivateNetworkPeer(server, req)
|
|
927
|
-
) {
|
|
928
|
-
return httpError(
|
|
929
|
-
"FORBIDDEN",
|
|
930
|
-
"Browser relay only accepts connections from localhost",
|
|
931
|
-
403,
|
|
932
|
-
);
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
// When auth is enabled we accept two different kinds of token on the
|
|
936
|
-
// `/v1/browser-relay` handshake:
|
|
937
|
-
//
|
|
938
|
-
// 1. **Capability token** — a signed `host_browser_command`
|
|
939
|
-
// capability minted by the gateway and handed to the chrome
|
|
940
|
-
// extension by the native-messaging pair flow
|
|
941
|
-
// (`/v1/browser-extension-pair`). This is the preferred,
|
|
942
|
-
// self-hosted default: the extension never has to touch a
|
|
943
|
-
// gateway JWT.
|
|
944
|
-
// 2. **JWT** (audience `vellum-daemon`) — the legacy path used by
|
|
945
|
-
// the gateway-proxied cloud flow and by any compatibility
|
|
946
|
-
// callers that still hold a daemon-bound JWT. In that case we
|
|
947
|
-
// parse the JWT `sub` to extract the actor principal id and
|
|
948
|
-
// fall back to the explicit `x-guardian-id` / `guardianId`
|
|
949
|
-
// query param for service-token paths (see below).
|
|
950
|
-
//
|
|
951
|
-
// When auth is disabled (dev bypass), guardianId remains undefined
|
|
952
|
-
// and the registration is skipped — host_browser_request routing
|
|
953
|
-
// requires an authenticated guardian.
|
|
954
|
-
//
|
|
955
|
-
// Gateway path: when the WebSocket upgrade is proxied through the
|
|
956
|
-
// gateway, the upstream token minted by `mintServiceToken()` has
|
|
957
|
-
// `sub=svc:gateway:self` with no actor principal id. The gateway
|
|
958
|
-
// parses the downstream edge token's `actorPrincipalId` and forwards
|
|
959
|
-
// it as an explicit `guardianId` query parameter (and/or header) so
|
|
960
|
-
// we can register the connection under the real guardian. Missing
|
|
961
|
-
// guardian context on this path is rejected (fail closed).
|
|
962
|
-
// Read the client-supplied stable instance id off the handshake.
|
|
963
|
-
// The extension generates this on first run and persists it in
|
|
964
|
-
// chrome.storage so it survives service-worker restarts and
|
|
965
|
-
// browser restarts. The header form is preferred so gateway
|
|
966
|
-
// forwarding and proxy logs don't surface instance ids in the
|
|
967
|
-
// URL, but we also accept a query param for fetch-based clients
|
|
968
|
-
// that can't mutate headers. An empty string is treated as absent
|
|
969
|
-
// so sparse clients don't end up all sharing the same legacy key.
|
|
970
|
-
const rawInstanceHeader = req.headers.get("x-client-instance-id")?.trim();
|
|
971
|
-
const rawInstanceQuery = new URL(req.url).searchParams
|
|
972
|
-
.get("clientInstanceId")
|
|
973
|
-
?.trim();
|
|
974
|
-
const clientInstanceId =
|
|
975
|
-
(rawInstanceHeader ?? "") || (rawInstanceQuery ?? "") || undefined;
|
|
976
|
-
|
|
977
|
-
let guardianId: string | undefined;
|
|
978
|
-
if (!isHttpAuthDisabled()) {
|
|
979
|
-
const wsUrl = new URL(req.url);
|
|
980
|
-
const token = wsUrl.searchParams.get("token");
|
|
981
|
-
if (!token) {
|
|
982
|
-
return httpError("UNAUTHORIZED", "Unauthorized", 401);
|
|
983
|
-
}
|
|
984
|
-
// 1) Capability-token path (self-hosted default). The chrome
|
|
985
|
-
// extension presents the token it received from the native
|
|
986
|
-
// messaging pair flow. We derive `guardianId` from the
|
|
987
|
-
// capability claims directly — the claims are HMAC-signed by
|
|
988
|
-
// the same daemon so there is no cross-tenant risk.
|
|
989
|
-
const capabilityClaims = await verifyHostBrowserCapability(token);
|
|
990
|
-
if (capabilityClaims) {
|
|
991
|
-
guardianId = capabilityClaims.guardianId;
|
|
992
|
-
} else {
|
|
993
|
-
// 2) JWT compatibility path (gateway / legacy). Fall back to the
|
|
994
|
-
// existing verifyToken+parseSub flow so cloud callers and any
|
|
995
|
-
// old self-hosted clients still holding a daemon JWT
|
|
996
|
-
// continue to work during the cutover.
|
|
997
|
-
const jwtResult = verifyToken(token, "vellum-daemon");
|
|
998
|
-
if (!jwtResult.ok) {
|
|
999
|
-
return httpError("UNAUTHORIZED", "Unauthorized", 401);
|
|
1000
|
-
}
|
|
1001
|
-
const subResult = parseSub(jwtResult.claims.sub);
|
|
1002
|
-
if (subResult.ok && subResult.actorPrincipalId) {
|
|
1003
|
-
// Direct actor principal — this is the loopback / desktop path.
|
|
1004
|
-
guardianId = subResult.actorPrincipalId;
|
|
1005
|
-
} else {
|
|
1006
|
-
// Service-token path (gateway-forwarded). The gateway must plumb
|
|
1007
|
-
// the resolved actor principal as an explicit `x-guardian-id`
|
|
1008
|
-
// header or `guardianId` query param. Header takes precedence
|
|
1009
|
-
// because headers are easier for the gateway to forward without
|
|
1010
|
-
// rewriting the URL.
|
|
1011
|
-
const headerGuardianId =
|
|
1012
|
-
req.headers.get("x-guardian-id")?.trim() ?? "";
|
|
1013
|
-
const queryGuardianId =
|
|
1014
|
-
wsUrl.searchParams.get("guardianId")?.trim() ?? "";
|
|
1015
|
-
const fallbackGuardianId = headerGuardianId || queryGuardianId;
|
|
1016
|
-
if (fallbackGuardianId) {
|
|
1017
|
-
guardianId = fallbackGuardianId;
|
|
1018
|
-
} else {
|
|
1019
|
-
// Fail closed: a service-token relay upgrade without a
|
|
1020
|
-
// guardian context cannot be routed safely.
|
|
1021
|
-
log.warn(
|
|
1022
|
-
{
|
|
1023
|
-
principalType: subResult.ok
|
|
1024
|
-
? subResult.principalType
|
|
1025
|
-
: "unknown",
|
|
1026
|
-
sub: jwtResult.claims.sub,
|
|
1027
|
-
},
|
|
1028
|
-
"Browser relay upgrade denied: missing guardian context on service-token path",
|
|
1029
|
-
);
|
|
1030
|
-
return httpError(
|
|
1031
|
-
"UNAUTHORIZED",
|
|
1032
|
-
"Browser relay requires guardian context",
|
|
1033
|
-
401,
|
|
1034
|
-
);
|
|
1035
|
-
}
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
}
|
|
1039
|
-
|
|
1040
|
-
const connectionId = crypto.randomUUID();
|
|
1041
|
-
const upgraded = server.upgrade(req, {
|
|
1042
|
-
data: {
|
|
1043
|
-
wsType: "browser-relay",
|
|
1044
|
-
connectionId,
|
|
1045
|
-
guardianId,
|
|
1046
|
-
clientInstanceId,
|
|
1047
|
-
} satisfies BrowserRelayWebSocketData,
|
|
1048
|
-
});
|
|
1049
|
-
if (!upgraded) {
|
|
1050
|
-
return new Response("WebSocket upgrade failed", { status: 500 });
|
|
1051
|
-
}
|
|
1052
|
-
// Bun's WebSocket upgrade consumes the request — no Response is sent.
|
|
1053
|
-
return undefined!;
|
|
1054
|
-
}
|
|
1055
|
-
|
|
1056
730
|
private verifyGatewayServiceToken(req: Request): Response | null {
|
|
1057
731
|
if (isHttpAuthDisabled()) return null;
|
|
1058
732
|
|
|
@@ -21,13 +21,8 @@ import type {
|
|
|
21
21
|
|
|
22
22
|
export type {
|
|
23
23
|
ApprovalCopyGenerator,
|
|
24
|
-
ApprovalMessageContext,
|
|
25
|
-
ApprovalMessageScenario,
|
|
26
24
|
ComposeApprovalMessageGenerativeOptions,
|
|
27
|
-
ComposeGuardianActionMessageOptions,
|
|
28
25
|
GuardianActionCopyGenerator,
|
|
29
|
-
GuardianActionMessageContext,
|
|
30
|
-
GuardianActionMessageScenario,
|
|
31
26
|
} from "./message-composer-types.js";
|
|
32
27
|
import type { TrustContext } from "../daemon/trust-context.js";
|
|
33
28
|
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type { ChannelId } from "../channels/types.js";
|
|
15
|
+
import { isHttpAuthDisabled } from "../config/env.js";
|
|
15
16
|
import { findGuardianForChannel } from "../contacts/contact-store.js";
|
|
16
17
|
import type { TrustContext } from "../daemon/trust-context.js";
|
|
17
18
|
import { getLogger } from "../util/logger.js";
|
|
@@ -43,6 +44,52 @@ export function buildLocalAuthContext(conversationId: string): AuthContext {
|
|
|
43
44
|
};
|
|
44
45
|
}
|
|
45
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Look up the local vellum guardian's principalId from the contacts table.
|
|
49
|
+
*
|
|
50
|
+
* Returns `undefined` when no vellum guardian binding exists (e.g. fresh
|
|
51
|
+
* install before bootstrap). Callers should treat that case as
|
|
52
|
+
* "not yet available" and either fall back or proceed without a principalId.
|
|
53
|
+
*/
|
|
54
|
+
export function findLocalGuardianPrincipalId(): string | undefined {
|
|
55
|
+
return findGuardianForChannel("vellum")?.contact.principalId ?? undefined;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Translate the synthetic dev-bypass actor principal to the real local
|
|
60
|
+
* guardian's principalId when running in `DISABLE_HTTP_AUTH=true` mode.
|
|
61
|
+
*
|
|
62
|
+
* The dev-bypass `AuthContext` (`runtime/auth/middleware.ts`) injects
|
|
63
|
+
* `"dev-bypass"` as the actor principal id for every request, but tool-side
|
|
64
|
+
* trust resolution (`resolveLocalTrustContext`) and SSE registration both
|
|
65
|
+
* carry the real local guardian principalId. Without this translation, every
|
|
66
|
+
* targeted host_bash/host_file/host_cu/host_transfer result POST mismatches
|
|
67
|
+
* the same-user check and is rejected with 403, and conversation/surface/
|
|
68
|
+
* guardian-action routes resolve trust against the wrong principal.
|
|
69
|
+
*
|
|
70
|
+
* Returns the input unchanged when:
|
|
71
|
+
* - HTTP auth is enabled (production / non-dev-bypass deployments), OR
|
|
72
|
+
* - the input is not literally `"dev-bypass"` (e.g. service tokens).
|
|
73
|
+
*
|
|
74
|
+
* Returns the local guardian principalId when both gates are true. Returns
|
|
75
|
+
* `undefined` when dev-bypass is set but no guardian binding has been created
|
|
76
|
+
* yet (e.g. fresh install before bootstrap); callers must treat this the
|
|
77
|
+
* same as a missing principal.
|
|
78
|
+
*/
|
|
79
|
+
export function resolveActorPrincipalIdForLocalGuardian(
|
|
80
|
+
rawHeader: string | undefined,
|
|
81
|
+
): string | undefined {
|
|
82
|
+
if (rawHeader !== "dev-bypass" || !isHttpAuthDisabled()) return rawHeader;
|
|
83
|
+
|
|
84
|
+
const guardianPrincipalId = findLocalGuardianPrincipalId();
|
|
85
|
+
if (guardianPrincipalId) return guardianPrincipalId;
|
|
86
|
+
|
|
87
|
+
log.warn(
|
|
88
|
+
"dev-bypass actor principal received but no vellum guardian binding found; returning undefined",
|
|
89
|
+
);
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
|
|
46
93
|
/**
|
|
47
94
|
* Resolve the guardian runtime context for a local connection.
|
|
48
95
|
*
|
|
@@ -60,10 +107,8 @@ export function resolveLocalTrustContext(
|
|
|
60
107
|
): TrustContext {
|
|
61
108
|
const assistantId = DAEMON_INTERNAL_ASSISTANT_ID;
|
|
62
109
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (guardianResult && guardianResult.contact.principalId) {
|
|
66
|
-
const guardianPrincipalId = guardianResult.contact.principalId;
|
|
110
|
+
const guardianPrincipalId = findLocalGuardianPrincipalId();
|
|
111
|
+
if (guardianPrincipalId) {
|
|
67
112
|
const trustCtx = resolveTrustContext({
|
|
68
113
|
assistantId,
|
|
69
114
|
sourceChannel: "vellum",
|
|
@@ -97,13 +142,9 @@ export function resolveLocalTrustContext(
|
|
|
97
142
|
export function resolveLocalAuthContext(conversationId: string): AuthContext {
|
|
98
143
|
const authContext = buildLocalAuthContext(conversationId);
|
|
99
144
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return {
|
|
104
|
-
...authContext,
|
|
105
|
-
actorPrincipalId: guardianResult.contact.principalId,
|
|
106
|
-
};
|
|
145
|
+
const guardianPrincipalId = findLocalGuardianPrincipalId();
|
|
146
|
+
if (guardianPrincipalId) {
|
|
147
|
+
return { ...authContext, actorPrincipalId: guardianPrincipalId };
|
|
107
148
|
}
|
|
108
149
|
|
|
109
150
|
log.warn(
|