@vellumai/assistant 0.7.2 → 0.8.0
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 +45 -29
- package/Dockerfile +1 -0
- package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
- package/bun.lock +3 -0
- package/docs/architecture/memory.md +5 -2
- package/knip.json +1 -0
- package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +13 -4
- package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
- package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
- package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
- package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -9
- package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
- package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
- package/openapi.yaml +470 -25
- package/package.json +3 -1
- package/src/__tests__/annotate-risk-options.test.ts +291 -0
- package/src/__tests__/app-control-flow.test.ts +21 -11
- package/src/__tests__/approval-cascade.test.ts +8 -16
- package/src/__tests__/approval-routes-http.test.ts +6 -0
- package/src/__tests__/assistant-event-hub.test.ts +48 -0
- package/src/__tests__/assistant-event.test.ts +0 -10
- package/src/__tests__/assistant-events-sse-hardening.test.ts +2 -7
- package/src/__tests__/assistant-feature-flags-integration.test.ts +18 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +48 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
- package/src/__tests__/call-constants.test.ts +10 -1
- package/src/__tests__/call-controller.test.ts +127 -0
- package/src/__tests__/call-conversation-messages.test.ts +8 -2
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
- package/src/__tests__/channel-readiness-service.test.ts +4 -2
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +58 -28
- package/src/__tests__/config-loader-backfill.test.ts +379 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +284 -1
- package/src/__tests__/config-schema.test.ts +1 -0
- package/src/__tests__/config-watcher-cleanup-throttle.test.ts +18 -9
- package/src/__tests__/config-watcher.test.ts +140 -69
- 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 +6 -33
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
- package/src/__tests__/context-search-pkb-source.test.ts +12 -7
- package/src/__tests__/context-search-workspace-source.test.ts +0 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop.test.ts +457 -8
- package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
- package/src/__tests__/conversation-error.test.ts +150 -3
- package/src/__tests__/conversation-init.benchmark.test.ts +1 -1
- package/src/__tests__/conversation-process-callsite.test.ts +38 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +74 -0
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -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 +170 -9
- package/src/__tests__/conversation-surfaces-app-control.test.ts +15 -4
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +476 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +61 -5
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
- package/src/__tests__/credentials-cli.test.ts +7 -0
- package/src/__tests__/cu-unified-flow.test.ts +176 -10
- package/src/__tests__/date-context.test.ts +164 -2
- 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__/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 +2 -20
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -26
- package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
- package/src/__tests__/heartbeat-service.test.ts +260 -11
- package/src/__tests__/host-app-control-proxy.test.ts +195 -25
- package/src/__tests__/host-bash-proxy.test.ts +227 -34
- package/src/__tests__/host-bash-routes.test.ts +178 -13
- package/src/__tests__/host-cu-proxy.test.ts +210 -3
- package/src/__tests__/host-cu-routes-targeted.test.ts +141 -12
- package/src/__tests__/host-file-proxy-targeted.test.ts +48 -9
- package/src/__tests__/host-file-proxy.test.ts +268 -6
- package/src/__tests__/host-file-routes-targeted.test.ts +175 -17
- package/src/__tests__/host-transfer-proxy-targeted.test.ts +408 -59
- package/src/__tests__/host-transfer-routes-targeted.test.ts +232 -17
- package/src/__tests__/http-user-message-parity.test.ts +107 -1
- package/src/__tests__/injector-chain.test.ts +36 -16
- package/src/__tests__/injector-disk-pressure.test.ts +224 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +154 -67
- package/src/__tests__/managed-profile-guard.test.ts +18 -0
- package/src/__tests__/mcp-abort-signal.test.ts +130 -0
- package/src/__tests__/memory-admin-recall.test.ts +3 -11
- package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
- package/src/__tests__/normalize-onboarding.test.ts +180 -0
- package/src/__tests__/notification-decision-fallback.test.ts +91 -0
- package/src/__tests__/notification-decision-strategy.test.ts +22 -0
- package/src/__tests__/oauth-cli.test.ts +121 -0
- package/src/__tests__/oauth-connect-routes.test.ts +316 -0
- package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
- 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__/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 -27
- package/src/__tests__/provider-tool-name.test.ts +23 -0
- package/src/__tests__/relay-server.test.ts +60 -5
- package/src/__tests__/runtime-events-sse.test.ts +4 -8
- package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
- package/src/__tests__/secret-ingress-http.test.ts +0 -1
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
- package/src/__tests__/secret-response-routing.test.ts +7 -5
- package/src/__tests__/server-history-render.test.ts +82 -0
- package/src/__tests__/skill-include-graph.test.ts +31 -0
- package/src/__tests__/skill-load-tool.test.ts +44 -16
- package/src/__tests__/skills.test.ts +39 -0
- package/src/__tests__/suggestion-routes.test.ts +46 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
- package/src/__tests__/tool-executor.test.ts +155 -0
- package/src/__tests__/twilio-validation.test.ts +2 -2
- package/src/__tests__/voice-session-bridge.test.ts +3 -0
- 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-069-seed-onboarding-threads.test.ts +120 -0
- package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
- package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +78 -0
- package/src/agent/loop.ts +11 -0
- package/src/approvals/guardian-request-resolvers.ts +3 -32
- package/src/backup/snapshot-lock.ts +2 -27
- package/src/bundler/compiler-tools.ts +3 -2
- package/src/calls/call-constants.ts +5 -8
- package/src/calls/call-controller.ts +130 -67
- package/src/calls/call-conversation-messages.ts +46 -10
- package/src/calls/relay-server.ts +7 -1
- package/src/calls/voice-session-bridge.ts +1 -1
- package/src/cli/commands/__tests__/webhooks.test.ts +0 -4
- package/src/cli/commands/bash.ts +35 -108
- package/src/cli/commands/contacts.ts +64 -25
- package/src/cli/commands/credentials.ts +56 -0
- package/src/cli/commands/memory-v2.ts +11 -10
- package/src/cli/commands/oauth/__tests__/connect.test.ts +401 -219
- package/src/cli/commands/oauth/connect.ts +124 -40
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -3
- package/src/cli/commands/platform/__tests__/connect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +103 -6
- package/src/cli/commands/platform/index.ts +16 -7
- package/src/cli/commands/status.ts +57 -0
- package/src/cli/program.ts +4 -2
- package/src/config/assistant-feature-flags.ts +13 -3
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +13 -7
- 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/env.ts +0 -8
- package/src/config/feature-flag-registry.json +13 -5
- package/src/config/loader.ts +199 -27
- package/src/config/schemas/__tests__/memory-v2.test.ts +10 -5
- package/src/config/schemas/call-site-catalog.ts +14 -0
- package/src/config/schemas/channels.ts +0 -5
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +2 -0
- package/src/config/schemas/memory-lifecycle.ts +13 -0
- package/src/config/schemas/memory-v2.ts +76 -12
- package/src/config/schemas/platform.ts +43 -3
- package/src/config/schemas/services.ts +28 -0
- package/src/config/seed-inference-profiles.ts +230 -33
- package/src/contacts/contact-store.ts +0 -25
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +32 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +86 -25
- package/src/daemon/assistant-attachments.ts +4 -4
- package/src/daemon/config-watcher.ts +85 -57
- package/src/daemon/conversation-agent-loop-handlers.ts +38 -0
- package/src/daemon/conversation-agent-loop.ts +183 -43
- package/src/daemon/conversation-error.ts +87 -15
- package/src/daemon/conversation-lifecycle.ts +22 -10
- package/src/daemon/conversation-process.ts +8 -0
- package/src/daemon/conversation-runtime-assembly.ts +26 -0
- package/src/daemon/conversation-store.ts +2 -2
- package/src/daemon/conversation-surfaces.ts +211 -29
- package/src/daemon/conversation-tool-setup.ts +66 -19
- package/src/daemon/conversation.ts +18 -23
- 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/handlers/shared.ts +26 -1
- package/src/daemon/handlers/skills.ts +3 -4
- package/src/daemon/host-app-control-proxy.ts +137 -41
- package/src/daemon/host-bash-proxy.ts +47 -22
- package/src/daemon/host-browser-proxy.ts +1 -1
- package/src/daemon/host-cu-proxy.ts +50 -4
- package/src/daemon/host-file-proxy.ts +44 -8
- package/src/daemon/host-transfer-proxy.ts +97 -6
- package/src/daemon/lifecycle.ts +167 -101
- 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 +66 -15
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/conversations.ts +4 -0
- package/src/daemon/message-types/disk-pressure.ts +9 -0
- package/src/daemon/message-types/messages.ts +22 -1
- package/src/daemon/profiler-run-store.ts +5 -5
- package/src/daemon/tool-setup-types.ts +2 -2
- package/src/documents/document-store.ts +119 -0
- package/src/filing/filing-service.ts +29 -5
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +9 -16
- package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +36 -0
- package/src/heartbeat/heartbeat-run-store.ts +13 -0
- package/src/heartbeat/heartbeat-service.ts +205 -31
- package/src/home/feed-scheduler.ts +18 -0
- package/src/inbound/platform-callback-registration.ts +8 -15
- package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
- package/src/ipc/assistant-server.ts +149 -38
- package/src/ipc/gateway-client.ts +37 -3
- package/src/ipc/skill-server.ts +99 -42
- package/src/live-voice/live-voice-archive.ts +4 -4
- package/src/live-voice/protocol.ts +5 -7
- 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-worker-v2-schedule.test.ts +34 -51
- 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/admin.ts +5 -9
- package/src/memory/context-search/agent-runner.ts +19 -2
- package/src/memory/context-search/sources/conversations.ts +2 -11
- package/src/memory/context-search/sources/memory-v2.ts +1 -16
- package/src/memory/context-search/sources/memory.ts +2 -3
- package/src/memory/context-search/sources/pkb.ts +2 -3
- package/src/memory/context-search/types.ts +0 -1
- package/src/memory/conversation-crud.ts +4 -12
- package/src/memory/db-init.ts +2 -0
- package/src/memory/embedding-runtime-manager.ts +119 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +136 -82
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
- package/src/memory/graph/conversation-graph-memory.ts +72 -61
- package/src/memory/graph/extraction.ts +1 -3
- package/src/memory/graph/graph-search.test.ts +11 -67
- package/src/memory/graph/graph-search.ts +4 -24
- package/src/memory/graph/retriever.test.ts +12 -1
- package/src/memory/graph/retriever.ts +10 -15
- package/src/memory/graph/tool-handlers.ts +3 -4
- package/src/memory/graph/tools.ts +4 -4
- package/src/memory/indexer.ts +53 -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 +116 -0
- package/src/memory/jobs/embed-concept-page.ts +223 -87
- package/src/memory/jobs-store.ts +48 -0
- package/src/memory/jobs-worker.ts +85 -43
- package/src/memory/memory-v2-activation-log-store.ts +32 -14
- package/src/memory/memory-v2-concept-frequency.ts +169 -0
- package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/pkb/pkb-search.test.ts +7 -0
- package/src/memory/pkb/pkb-search.ts +4 -5
- package/src/memory/qdrant-client.ts +3 -13
- package/src/memory/rerank-local.ts +374 -0
- package/src/memory/search/semantic.ts +10 -72
- package/src/memory/trace-event-store.ts +1 -17
- package/src/memory/v2/__tests__/activation.test.ts +346 -255
- package/src/memory/v2/__tests__/consolidation-job.test.ts +61 -40
- package/src/memory/v2/__tests__/injection.test.ts +297 -190
- package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
- package/src/memory/v2/__tests__/qdrant.test.ts +326 -9
- package/src/memory/v2/__tests__/reranker.test.ts +338 -0
- package/src/memory/v2/__tests__/sim.test.ts +113 -196
- package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
- package/src/memory/v2/__tests__/static-context.test.ts +77 -14
- package/src/memory/v2/__tests__/sweep-job.test.ts +19 -33
- package/src/memory/v2/activation.ts +149 -156
- package/src/memory/v2/consolidation-job.ts +69 -20
- package/src/memory/v2/injection.ts +75 -68
- package/src/memory/v2/page-store.ts +39 -0
- package/src/memory/v2/prompts/consolidation.ts +41 -1
- package/src/memory/v2/qdrant.ts +306 -46
- package/src/memory/v2/reranker.ts +177 -0
- package/src/memory/v2/sim.ts +77 -110
- package/src/memory/v2/skill-content.ts +4 -3
- package/src/memory/v2/skill-store.ts +82 -59
- package/src/memory/v2/static-context.ts +26 -8
- package/src/memory/v2/sweep-job.ts +5 -6
- package/src/memory/v2/types.ts +17 -10
- package/src/notifications/copy-composer.ts +47 -0
- package/src/notifications/decision-engine.ts +46 -0
- 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 +2 -0
- package/src/oauth/connection-resolver.test.ts +66 -1
- package/src/oauth/connection-resolver.ts +55 -1
- package/src/oauth/oauth-connect-state.ts +77 -0
- package/src/oauth/seed-providers.ts +58 -1
- package/src/permissions/gateway-threshold-reader.ts +116 -8
- package/src/permissions/prompter.ts +86 -96
- package/src/permissions/secret-prompter.ts +31 -31
- package/src/plugins/defaults/injectors.ts +36 -4
- 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 +914 -0
- package/src/proactive-artifact/job.ts +366 -0
- package/src/proactive-artifact/message-copy.ts +58 -0
- package/src/proactive-artifact/trigger-state.test.ts +277 -0
- package/src/proactive-artifact/trigger-state.ts +119 -0
- package/src/prompts/normalize-onboarding.ts +80 -0
- package/src/prompts/persona-resolver.ts +101 -9
- package/src/prompts/system-prompt.ts +21 -7
- package/src/prompts/templates/BOOTSTRAP.md +13 -5
- package/src/prompts/templates/SOUL.md +13 -28
- 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/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 +36 -6
- package/src/runtime/assistant-event.ts +0 -1
- package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
- package/src/runtime/auth/route-policy.ts +15 -1
- package/src/runtime/auth/same-actor.ts +216 -0
- package/src/runtime/channel-approvals.ts +3 -2
- package/src/runtime/channel-retry-sweep.ts +65 -1
- package/src/runtime/local-actor-identity.ts +52 -11
- package/src/runtime/pending-interactions.ts +27 -15
- package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +0 -5
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
- package/src/runtime/routes/approval-routes.ts +7 -3
- package/src/runtime/routes/client-routes.ts +20 -2
- package/src/runtime/routes/consolidation-routes.ts +8 -9
- package/src/runtime/routes/contact-routes.ts +0 -25
- package/src/runtime/routes/conversation-query-routes.ts +44 -1
- package/src/runtime/routes/conversation-routes.ts +35 -26
- package/src/runtime/routes/debug-bash-routes.ts +165 -0
- package/src/runtime/routes/disk-pressure-routes.ts +121 -0
- package/src/runtime/routes/document-pdf-renderer.ts +6 -2
- package/src/runtime/routes/documents-routes.ts +2 -75
- package/src/runtime/routes/events-routes.ts +41 -9
- package/src/runtime/routes/filing-routes.ts +2 -3
- package/src/runtime/routes/host-bash-routes.ts +23 -3
- package/src/runtime/routes/host-cu-routes.ts +33 -6
- package/src/runtime/routes/host-file-routes.ts +32 -6
- package/src/runtime/routes/host-transfer-routes.ts +79 -16
- package/src/runtime/routes/identity-routes.ts +7 -138
- package/src/runtime/routes/inbound-message-handler.ts +77 -12
- package/src/runtime/routes/index.ts +6 -0
- package/src/runtime/routes/memory-item-routes.test.ts +37 -17
- package/src/runtime/routes/memory-item-routes.ts +5 -6
- package/src/runtime/routes/memory-v2-routes.ts +136 -17
- package/src/runtime/routes/oauth-connect-routes.ts +153 -0
- package/src/runtime/verification-outbound-actions.ts +4 -4
- package/src/schedule/run-script.ts +37 -5
- package/src/schedule/scheduler.ts +20 -1
- package/src/security/encrypted-store.ts +2 -0
- package/src/security/secure-keys.ts +55 -0
- package/src/skills/include-graph.ts +35 -13
- package/src/skills/remote-skill-policy.ts +4 -10
- 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/tools/background-tool-registry.ts +17 -3
- package/src/tools/document/document-tool.ts +20 -0
- package/src/tools/executor.ts +18 -2
- package/src/tools/host-filesystem/edit.test.ts +151 -0
- package/src/tools/host-filesystem/edit.ts +43 -1
- package/src/tools/host-filesystem/read.test.ts +129 -0
- package/src/tools/host-filesystem/read.ts +43 -1
- package/src/tools/host-filesystem/transfer.test.ts +127 -2
- package/src/tools/host-filesystem/transfer.ts +56 -11
- package/src/tools/host-filesystem/write.test.ts +134 -0
- package/src/tools/host-filesystem/write.ts +43 -1
- package/src/tools/host-terminal/host-shell.ts +13 -6
- package/src/tools/mcp/mcp-tool-factory.ts +2 -1
- package/src/tools/memory/register.test.ts +14 -9
- package/src/tools/memory/register.ts +1 -2
- package/src/tools/permission-checker.ts +15 -0
- package/src/tools/provider-tool-name.ts +28 -0
- package/src/tools/registry.ts +30 -9
- package/src/tools/skills/load.ts +24 -20
- package/src/tools/terminal/shell.ts +9 -1
- package/src/tools/tool-approval-handler.ts +31 -6
- package/src/tools/tool-name-aliases.ts +19 -0
- package/src/tools/types.ts +43 -3
- package/src/tts/provider-catalog.ts +3 -5
- 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/heartbeat-service.ts +19 -0
- 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 +14 -0
- package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +28 -0
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
- package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
- package/src/workspace/migrations/registry.ts +14 -0
- package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
- package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
- package/src/memory/v2/skill-qdrant.ts +0 -404
- package/src/signals/bash.ts +0 -198
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
assistantEventHub,
|
|
24
24
|
broadcastMessage,
|
|
25
25
|
} from "../runtime/assistant-event-hub.js";
|
|
26
|
+
import { enforceSameActorOrErrorResult } from "../runtime/auth/same-actor.js";
|
|
26
27
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
27
28
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
28
29
|
import { AssistantError, ErrorCode } from "../util/errors.js";
|
|
@@ -121,6 +122,16 @@ export class HostCuProxy {
|
|
|
121
122
|
// Request / resolve lifecycle
|
|
122
123
|
// ---------------------------------------------------------------------------
|
|
123
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Send a CU request to the connected desktop client.
|
|
127
|
+
*
|
|
128
|
+
* When `targetClientId` is supplied, the proxy validates that the target
|
|
129
|
+
* exists and advertises the `host_cu` capability, mirroring HostFileProxy's
|
|
130
|
+
* resolver-side checks so that the proxy is safe to call as a standalone
|
|
131
|
+
* API. It additionally enforces that the caller (`sourceActorPrincipalId`)
|
|
132
|
+
* and the target client share the same actor principal — cross-user
|
|
133
|
+
* targeted dispatch is rejected.
|
|
134
|
+
*/
|
|
124
135
|
request(
|
|
125
136
|
toolName: string,
|
|
126
137
|
input: Record<string, unknown>,
|
|
@@ -129,6 +140,7 @@ export class HostCuProxy {
|
|
|
129
140
|
reasoning?: string,
|
|
130
141
|
signal?: AbortSignal,
|
|
131
142
|
targetClientId?: string,
|
|
143
|
+
sourceActorPrincipalId?: string,
|
|
132
144
|
): Promise<ToolExecutionResult> {
|
|
133
145
|
if (signal?.aborted) {
|
|
134
146
|
return Promise.resolve({
|
|
@@ -144,6 +156,38 @@ export class HostCuProxy {
|
|
|
144
156
|
});
|
|
145
157
|
}
|
|
146
158
|
|
|
159
|
+
// Existence + capability validation for explicit targets. Mirrors
|
|
160
|
+
// HostFileProxy's resolver-side guard so that the proxy is safe even
|
|
161
|
+
// when called outside the conversation-surfaces dispatch (which has
|
|
162
|
+
// its own validation layer).
|
|
163
|
+
if (targetClientId != null) {
|
|
164
|
+
const client = assistantEventHub.getClientById(targetClientId);
|
|
165
|
+
if (!client) {
|
|
166
|
+
return Promise.resolve({
|
|
167
|
+
content: `No connected client with id '${targetClientId}' supports host_cu. Run \`assistant clients list --capability host_cu\` to see available clients.`,
|
|
168
|
+
isError: true,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
if (!client.capabilities.includes("host_cu")) {
|
|
172
|
+
return Promise.resolve({
|
|
173
|
+
content: `Client '${targetClientId}' does not support host_cu. Run \`assistant clients list --capability host_cu\` to see available clients.`,
|
|
174
|
+
isError: true,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Same-user enforcement: targeted CU dispatch must be owned by the
|
|
179
|
+
// same actor on both sides. This is the authoritative gate — the
|
|
180
|
+
// dispatch layer (conversation-surfaces.ts) skips its own check
|
|
181
|
+
// and relies on the proxy.
|
|
182
|
+
const rejection = enforceSameActorOrErrorResult({
|
|
183
|
+
hub: assistantEventHub,
|
|
184
|
+
sourceActorPrincipalId,
|
|
185
|
+
targetClientId,
|
|
186
|
+
op: "host_cu",
|
|
187
|
+
});
|
|
188
|
+
if (rejection) return Promise.resolve(rejection);
|
|
189
|
+
}
|
|
190
|
+
|
|
147
191
|
const requestId = uuid();
|
|
148
192
|
|
|
149
193
|
return new Promise<ToolExecutionResult>((resolve, reject) => {
|
|
@@ -170,9 +214,7 @@ export class HostCuProxy {
|
|
|
170
214
|
type: "host_cu_cancel",
|
|
171
215
|
requestId,
|
|
172
216
|
conversationId,
|
|
173
|
-
...(targetClientId != null
|
|
174
|
-
? { targetClientId }
|
|
175
|
-
: {}),
|
|
217
|
+
...(targetClientId != null ? { targetClientId } : {}),
|
|
176
218
|
},
|
|
177
219
|
conversationId,
|
|
178
220
|
{ targetClientId },
|
|
@@ -193,7 +235,11 @@ export class HostCuProxy {
|
|
|
193
235
|
conversationId,
|
|
194
236
|
kind: "host_cu",
|
|
195
237
|
targetClientId,
|
|
196
|
-
|
|
238
|
+
targetActorPrincipalId:
|
|
239
|
+
targetClientId != null
|
|
240
|
+
? assistantEventHub.getActorPrincipalIdForClient(targetClientId)
|
|
241
|
+
: undefined,
|
|
242
|
+
rpcResolve: resolve as (v: unknown) => void,
|
|
197
243
|
rpcReject: reject,
|
|
198
244
|
timer,
|
|
199
245
|
detachAbort,
|
|
@@ -4,6 +4,11 @@ import {
|
|
|
4
4
|
assistantEventHub,
|
|
5
5
|
broadcastMessage,
|
|
6
6
|
} from "../runtime/assistant-event-hub.js";
|
|
7
|
+
import {
|
|
8
|
+
ambiguousSameUserError,
|
|
9
|
+
enforceSameActorOrErrorResult,
|
|
10
|
+
pickSameUserAutoResolve,
|
|
11
|
+
} from "../runtime/auth/same-actor.js";
|
|
7
12
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
8
13
|
import { readImageBase64 } from "../tools/shared/filesystem/image-read.js";
|
|
9
14
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
@@ -68,15 +73,18 @@ export class HostFileProxy {
|
|
|
68
73
|
conversationId: string,
|
|
69
74
|
signal?: AbortSignal,
|
|
70
75
|
targetClientId?: string,
|
|
76
|
+
sourceActorPrincipalId?: string,
|
|
71
77
|
): Promise<ToolExecutionResult> {
|
|
72
78
|
if (signal?.aborted) {
|
|
73
79
|
return Promise.resolve({ content: "Aborted", isError: true });
|
|
74
80
|
}
|
|
75
81
|
|
|
76
|
-
// Resolve targetClientId: explicit → validate; single
|
|
77
|
-
// Callers may embed targetClientId in
|
|
78
|
-
// the
|
|
79
|
-
|
|
82
|
+
// Resolve targetClientId: explicit → validate; single same-user
|
|
83
|
+
// capable client → auto-resolve. Callers may embed targetClientId in
|
|
84
|
+
// the input object (tool handlers) or pass it as the 4th parameter
|
|
85
|
+
// (legacy). Prefer the explicit param; fall back to input field.
|
|
86
|
+
let resolvedTargetClientId: string | undefined =
|
|
87
|
+
targetClientId ?? input.targetClientId;
|
|
80
88
|
if (resolvedTargetClientId != null) {
|
|
81
89
|
const client = assistantEventHub.getClientById(resolvedTargetClientId);
|
|
82
90
|
if (!client) {
|
|
@@ -92,10 +100,32 @@ export class HostFileProxy {
|
|
|
92
100
|
});
|
|
93
101
|
}
|
|
94
102
|
} else {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
103
|
+
// Auto-resolve to the unique same-user client. Reject ambiguous
|
|
104
|
+
// (multi-machine) cases so a single targeted-style request cannot
|
|
105
|
+
// fan out across the user's machines.
|
|
106
|
+
const resolved = pickSameUserAutoResolve({
|
|
107
|
+
hub: assistantEventHub,
|
|
108
|
+
capability: "host_file",
|
|
109
|
+
sourceActorPrincipalId,
|
|
110
|
+
});
|
|
111
|
+
if (resolved.kind === "ambiguous") {
|
|
112
|
+
return Promise.resolve(ambiguousSameUserError("host_file"));
|
|
98
113
|
}
|
|
114
|
+
resolvedTargetClientId =
|
|
115
|
+
resolved.kind === "match" ? resolved.clientId : undefined;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Same-user check: targeted host_file requests must be bound to the same
|
|
119
|
+
// authenticated user identity that opened the target client's SSE stream.
|
|
120
|
+
// Prevents cross-user routing through actor token mis-targeting.
|
|
121
|
+
if (resolvedTargetClientId != null) {
|
|
122
|
+
const rejection = enforceSameActorOrErrorResult({
|
|
123
|
+
hub: assistantEventHub,
|
|
124
|
+
sourceActorPrincipalId,
|
|
125
|
+
targetClientId: resolvedTargetClientId,
|
|
126
|
+
op: "host_file",
|
|
127
|
+
});
|
|
128
|
+
if (rejection) return Promise.resolve(rejection);
|
|
99
129
|
}
|
|
100
130
|
|
|
101
131
|
const requestId = uuid();
|
|
@@ -150,7 +180,13 @@ export class HostFileProxy {
|
|
|
150
180
|
conversationId,
|
|
151
181
|
kind: "host_file",
|
|
152
182
|
targetClientId: resolvedTargetClientId,
|
|
153
|
-
|
|
183
|
+
targetActorPrincipalId:
|
|
184
|
+
resolvedTargetClientId != null
|
|
185
|
+
? assistantEventHub.getActorPrincipalIdForClient(
|
|
186
|
+
resolvedTargetClientId,
|
|
187
|
+
)
|
|
188
|
+
: undefined,
|
|
189
|
+
rpcResolve: resolve as (v: unknown) => void,
|
|
154
190
|
rpcReject: reject,
|
|
155
191
|
timer,
|
|
156
192
|
detachAbort,
|
|
@@ -9,6 +9,11 @@ import {
|
|
|
9
9
|
assistantEventHub,
|
|
10
10
|
broadcastMessage,
|
|
11
11
|
} from "../runtime/assistant-event-hub.js";
|
|
12
|
+
import {
|
|
13
|
+
ambiguousSameUserError,
|
|
14
|
+
enforceSameActorOrErrorResult,
|
|
15
|
+
pickSameUserAutoResolve,
|
|
16
|
+
} from "../runtime/auth/same-actor.js";
|
|
12
17
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
13
18
|
import type { ToolExecutionResult } from "../tools/types.js";
|
|
14
19
|
import { AssistantError, ErrorCode } from "../util/errors.js";
|
|
@@ -31,6 +36,13 @@ interface TransferEntry {
|
|
|
31
36
|
sha256?: string;
|
|
32
37
|
fileBuffer?: Buffer;
|
|
33
38
|
targetClientId?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Snapshot of `targetClientId`'s `actorPrincipalId` taken at registration
|
|
41
|
+
* time. Persisted so the GET/PUT content routes compare against a stable
|
|
42
|
+
* value rather than the live hub — the target client's SSE subscription
|
|
43
|
+
* may briefly disconnect between dispatch and content fetch/upload.
|
|
44
|
+
*/
|
|
45
|
+
targetActorPrincipalId?: string;
|
|
34
46
|
}
|
|
35
47
|
|
|
36
48
|
/**
|
|
@@ -124,6 +136,8 @@ export class HostTransferProxy {
|
|
|
124
136
|
targetClientId?: string;
|
|
125
137
|
},
|
|
126
138
|
signal?: AbortSignal,
|
|
139
|
+
// Principal ID of the actor on whose behalf this request is initiated.
|
|
140
|
+
sourceActorPrincipalId?: string,
|
|
127
141
|
): Promise<ToolExecutionResult> {
|
|
128
142
|
if (signal?.aborted) {
|
|
129
143
|
return Promise.resolve({ content: "Aborted", isError: true });
|
|
@@ -145,8 +159,29 @@ export class HostTransferProxy {
|
|
|
145
159
|
});
|
|
146
160
|
}
|
|
147
161
|
} else {
|
|
148
|
-
|
|
149
|
-
|
|
162
|
+
// Auto-resolve to the unique same-user client; reject ambiguous
|
|
163
|
+
// (multi-machine) cases so a single targeted-style transfer cannot
|
|
164
|
+
// fan out across the user's machines.
|
|
165
|
+
const resolved = pickSameUserAutoResolve({
|
|
166
|
+
hub: assistantEventHub,
|
|
167
|
+
capability: "host_file",
|
|
168
|
+
sourceActorPrincipalId,
|
|
169
|
+
});
|
|
170
|
+
if (resolved.kind === "ambiguous") {
|
|
171
|
+
return Promise.resolve(ambiguousSameUserError("host_file"));
|
|
172
|
+
}
|
|
173
|
+
resolvedTargetClientId =
|
|
174
|
+
resolved.kind === "match" ? resolved.clientId : undefined;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (resolvedTargetClientId != null) {
|
|
178
|
+
const rejection = enforceSameActorOrErrorResult({
|
|
179
|
+
hub: assistantEventHub,
|
|
180
|
+
sourceActorPrincipalId,
|
|
181
|
+
targetClientId: resolvedTargetClientId,
|
|
182
|
+
op: "host_transfer",
|
|
183
|
+
});
|
|
184
|
+
if (rejection != null) return Promise.resolve(rejection);
|
|
150
185
|
}
|
|
151
186
|
|
|
152
187
|
const requestId = uuid();
|
|
@@ -220,13 +255,25 @@ export class HostTransferProxy {
|
|
|
220
255
|
sha256,
|
|
221
256
|
fileBuffer,
|
|
222
257
|
targetClientId: resolvedTargetClientId,
|
|
258
|
+
targetActorPrincipalId:
|
|
259
|
+
resolvedTargetClientId != null
|
|
260
|
+
? assistantEventHub.getActorPrincipalIdForClient(
|
|
261
|
+
resolvedTargetClientId,
|
|
262
|
+
)
|
|
263
|
+
: undefined,
|
|
223
264
|
});
|
|
224
265
|
|
|
225
266
|
pendingInteractions.register(requestId, {
|
|
226
267
|
conversationId: input.conversationId,
|
|
227
268
|
kind: "host_transfer",
|
|
228
269
|
targetClientId: resolvedTargetClientId,
|
|
229
|
-
|
|
270
|
+
targetActorPrincipalId:
|
|
271
|
+
resolvedTargetClientId != null
|
|
272
|
+
? assistantEventHub.getActorPrincipalIdForClient(
|
|
273
|
+
resolvedTargetClientId,
|
|
274
|
+
)
|
|
275
|
+
: undefined,
|
|
276
|
+
rpcResolve: resolve as (v: unknown) => void,
|
|
230
277
|
rpcReject: reject,
|
|
231
278
|
timer,
|
|
232
279
|
detachAbort,
|
|
@@ -291,6 +338,8 @@ export class HostTransferProxy {
|
|
|
291
338
|
targetClientId?: string;
|
|
292
339
|
},
|
|
293
340
|
signal?: AbortSignal,
|
|
341
|
+
// Principal ID of the actor on whose behalf this request is initiated.
|
|
342
|
+
sourceActorPrincipalId?: string,
|
|
294
343
|
): Promise<ToolExecutionResult> {
|
|
295
344
|
if (signal?.aborted) {
|
|
296
345
|
return Promise.resolve({ content: "Aborted", isError: true });
|
|
@@ -312,8 +361,29 @@ export class HostTransferProxy {
|
|
|
312
361
|
});
|
|
313
362
|
}
|
|
314
363
|
} else {
|
|
315
|
-
|
|
316
|
-
|
|
364
|
+
// Auto-resolve to the unique same-user client; reject ambiguous
|
|
365
|
+
// (multi-machine) cases so a single targeted-style transfer cannot
|
|
366
|
+
// fan out across the user's machines.
|
|
367
|
+
const resolved = pickSameUserAutoResolve({
|
|
368
|
+
hub: assistantEventHub,
|
|
369
|
+
capability: "host_file",
|
|
370
|
+
sourceActorPrincipalId,
|
|
371
|
+
});
|
|
372
|
+
if (resolved.kind === "ambiguous") {
|
|
373
|
+
return Promise.resolve(ambiguousSameUserError("host_file"));
|
|
374
|
+
}
|
|
375
|
+
resolvedTargetClientId =
|
|
376
|
+
resolved.kind === "match" ? resolved.clientId : undefined;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (resolvedTargetClientId != null) {
|
|
380
|
+
const rejection = enforceSameActorOrErrorResult({
|
|
381
|
+
hub: assistantEventHub,
|
|
382
|
+
sourceActorPrincipalId,
|
|
383
|
+
targetClientId: resolvedTargetClientId,
|
|
384
|
+
op: "host_transfer",
|
|
385
|
+
});
|
|
386
|
+
if (rejection != null) return Promise.resolve(rejection);
|
|
317
387
|
}
|
|
318
388
|
|
|
319
389
|
const requestId = uuid();
|
|
@@ -374,13 +444,25 @@ export class HostTransferProxy {
|
|
|
374
444
|
filePath: input.destPath,
|
|
375
445
|
overwrite: input.overwrite,
|
|
376
446
|
targetClientId: resolvedTargetClientId,
|
|
447
|
+
targetActorPrincipalId:
|
|
448
|
+
resolvedTargetClientId != null
|
|
449
|
+
? assistantEventHub.getActorPrincipalIdForClient(
|
|
450
|
+
resolvedTargetClientId,
|
|
451
|
+
)
|
|
452
|
+
: undefined,
|
|
377
453
|
});
|
|
378
454
|
|
|
379
455
|
pendingInteractions.register(requestId, {
|
|
380
456
|
conversationId: input.conversationId,
|
|
381
457
|
kind: "host_transfer",
|
|
382
458
|
targetClientId: resolvedTargetClientId,
|
|
383
|
-
|
|
459
|
+
targetActorPrincipalId:
|
|
460
|
+
resolvedTargetClientId != null
|
|
461
|
+
? assistantEventHub.getActorPrincipalIdForClient(
|
|
462
|
+
resolvedTargetClientId,
|
|
463
|
+
)
|
|
464
|
+
: undefined,
|
|
465
|
+
rpcResolve: resolve as (v: unknown) => void,
|
|
384
466
|
rpcReject: reject,
|
|
385
467
|
timer,
|
|
386
468
|
detachAbort,
|
|
@@ -623,6 +705,15 @@ export class HostTransferProxy {
|
|
|
623
705
|
return this.transfers.get(transferId)?.targetClientId ?? null;
|
|
624
706
|
}
|
|
625
707
|
|
|
708
|
+
/**
|
|
709
|
+
* Look up the persisted `targetActorPrincipalId` for a given transferId
|
|
710
|
+
* without consuming the entry. Routes call this for the same-actor
|
|
711
|
+
* binding check so it's stable across brief SSE reconnects.
|
|
712
|
+
*/
|
|
713
|
+
getTargetActorPrincipalIdForTransfer(transferId: string): string | undefined {
|
|
714
|
+
return this.transfers.get(transferId)?.targetActorPrincipalId;
|
|
715
|
+
}
|
|
716
|
+
|
|
626
717
|
dispose(): void {
|
|
627
718
|
for (const entry of pendingInteractions.getByKind("host_transfer")) {
|
|
628
719
|
const transferId = entry.metadata?.transferId as string | undefined;
|