@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
|
@@ -58,6 +58,7 @@ afterAll(() => {
|
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
import { invalidateConfigCache, loadConfig } from "../config/loader.js";
|
|
61
|
+
import { applyContextDefaultsToRawConfig } from "../runtime/routes/conversation-query-routes.js";
|
|
61
62
|
import { _setStorePath } from "../security/encrypted-store.js";
|
|
62
63
|
|
|
63
64
|
// ---------------------------------------------------------------------------
|
|
@@ -184,7 +185,7 @@ describe("platform-managed config defaults", () => {
|
|
|
184
185
|
) + "\n",
|
|
185
186
|
);
|
|
186
187
|
|
|
187
|
-
loadConfig();
|
|
188
|
+
const config = loadConfig();
|
|
188
189
|
|
|
189
190
|
const written = readConfig() as { services?: Record<string, unknown> };
|
|
190
191
|
expect(written.services).toBeDefined();
|
|
@@ -192,5 +193,287 @@ describe("platform-managed config defaults", () => {
|
|
|
192
193
|
expect(
|
|
193
194
|
(written.services!["inference"] as { mode?: string })?.mode,
|
|
194
195
|
).toBe("your-own");
|
|
196
|
+
// ...and the in-memory config must mirror the explicit user choice (the
|
|
197
|
+
// fill-defaults pass must not override an explicit "your-own").
|
|
198
|
+
expect(
|
|
199
|
+
(config.services.inference as { mode: string }).mode,
|
|
200
|
+
).toBe("your-own");
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test("IS_PLATFORM=true, config file exists without a services key → in-memory config has all managed modes", () => {
|
|
204
|
+
// Regression guard for the platform-managed boot order: by the time
|
|
205
|
+
// `loadConfig()` runs, lifecycle steps such as `seedInferenceProfiles`
|
|
206
|
+
// have already written `config.json` (with `llm.profiles` etc.), so
|
|
207
|
+
// `configFileExisted` is true even on a brand-new platform-managed
|
|
208
|
+
// assistant. Deployment-context defaults must still be applied to the
|
|
209
|
+
// in-memory config for any leaf keys that are absent from disk.
|
|
210
|
+
process.env.IS_PLATFORM = "true";
|
|
211
|
+
|
|
212
|
+
writeFileSync(
|
|
213
|
+
CONFIG_PATH,
|
|
214
|
+
JSON.stringify(
|
|
215
|
+
{
|
|
216
|
+
llm: {
|
|
217
|
+
profiles: {
|
|
218
|
+
balanced: { provider: "anthropic", model: "claude-sonnet-4.5" },
|
|
219
|
+
},
|
|
220
|
+
activeProfile: "balanced",
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
null,
|
|
224
|
+
2,
|
|
225
|
+
) + "\n",
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
const config = loadConfig();
|
|
229
|
+
|
|
230
|
+
// In-memory config has the deployment-context defaults applied for the
|
|
231
|
+
// missing service-mode fields.
|
|
232
|
+
for (const svc of MANAGED_SERVICES) {
|
|
233
|
+
expect(
|
|
234
|
+
(
|
|
235
|
+
config.services as unknown as Record<
|
|
236
|
+
string,
|
|
237
|
+
{ mode: string }
|
|
238
|
+
>
|
|
239
|
+
)[svc]!.mode,
|
|
240
|
+
).toBe("managed");
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// The on-disk file is NOT modified by the fill pass — disk reflects only
|
|
244
|
+
// what was already there. Existing-file branch never re-writes config.json.
|
|
245
|
+
const onDisk = readConfig() as Record<string, unknown>;
|
|
246
|
+
expect(onDisk["services"]).toBeUndefined();
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
test("IS_PLATFORM=true, config file exists with a partial service subtree → preserves user fields, fills missing mode", () => {
|
|
250
|
+
process.env.IS_PLATFORM = "true";
|
|
251
|
+
|
|
252
|
+
// User has an image-generation provider configured but never explicitly
|
|
253
|
+
// chose a mode for that service. The fill pass must apply
|
|
254
|
+
// `mode: "managed"` without clobbering the user-supplied provider.
|
|
255
|
+
// (The inference schema dropped per-service model/provider in
|
|
256
|
+
// migration 039 — image-generation still carries them, so it's the
|
|
257
|
+
// right schema to exercise the partial-subtree case.)
|
|
258
|
+
writeFileSync(
|
|
259
|
+
CONFIG_PATH,
|
|
260
|
+
JSON.stringify(
|
|
261
|
+
{
|
|
262
|
+
services: {
|
|
263
|
+
"image-generation": { provider: "openai" },
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
null,
|
|
267
|
+
2,
|
|
268
|
+
) + "\n",
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
const config = loadConfig();
|
|
272
|
+
|
|
273
|
+
const imageGen = (
|
|
274
|
+
config.services as unknown as Record<
|
|
275
|
+
string,
|
|
276
|
+
{ mode: string; provider?: string }
|
|
277
|
+
>
|
|
278
|
+
)["image-generation"]!;
|
|
279
|
+
expect(imageGen.mode).toBe("managed");
|
|
280
|
+
expect(imageGen.provider).toBe("openai");
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
test("IS_PLATFORM=false, config file exists without services key → in-memory config keeps schema your-own defaults", () => {
|
|
284
|
+
// Sanity guard: deployment-context defaults are a no-op when IS_PLATFORM
|
|
285
|
+
// is not enabled, regardless of whether config.json existed.
|
|
286
|
+
process.env.IS_PLATFORM = "false";
|
|
287
|
+
|
|
288
|
+
writeFileSync(
|
|
289
|
+
CONFIG_PATH,
|
|
290
|
+
JSON.stringify(
|
|
291
|
+
{
|
|
292
|
+
llm: {
|
|
293
|
+
profiles: {
|
|
294
|
+
balanced: { provider: "anthropic", model: "claude-sonnet-4.5" },
|
|
295
|
+
},
|
|
296
|
+
activeProfile: "balanced",
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
null,
|
|
300
|
+
2,
|
|
301
|
+
) + "\n",
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
const config = loadConfig();
|
|
305
|
+
|
|
306
|
+
for (const svc of MANAGED_SERVICES) {
|
|
307
|
+
expect(
|
|
308
|
+
(
|
|
309
|
+
config.services as unknown as Record<
|
|
310
|
+
string,
|
|
311
|
+
{ mode: string }
|
|
312
|
+
>
|
|
313
|
+
)[svc]!.mode,
|
|
314
|
+
).toBe("your-own");
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Regression guard for the `handleGetConfig` route handler in
|
|
321
|
+
* `assistant/src/runtime/routes/conversation-query-routes.ts`. That handler
|
|
322
|
+
* returns the raw on-disk JSON to clients (macOS, web, CLI) via
|
|
323
|
+
* `GET /v1/config`, but first layers deployment-context defaults on top
|
|
324
|
+
* via the `applyContextDefaultsToRawConfig` helper.
|
|
325
|
+
*
|
|
326
|
+
* macOS's `loadServiceModes(config:)` only updates `inferenceMode` when
|
|
327
|
+
* `services.inference.mode` is present in the response — without the fill
|
|
328
|
+
* pass, freshly-hatched platform-managed assistants would have no `services`
|
|
329
|
+
* key on disk (only `llm.profiles` from `seedInferenceProfiles`) and macOS
|
|
330
|
+
* would fall back to its `@Published` default of "your-own". The helper is
|
|
331
|
+
* also responsible for guarding against `loadRawConfig()` returning a
|
|
332
|
+
* non-object payload from a malformed-but-parseable `config.json`.
|
|
333
|
+
*/
|
|
334
|
+
describe("GET /v1/config handler — context-default fill on raw response", () => {
|
|
335
|
+
const originalIsPlatform = process.env.IS_PLATFORM;
|
|
336
|
+
|
|
337
|
+
afterEach(() => {
|
|
338
|
+
if (originalIsPlatform === undefined) {
|
|
339
|
+
delete process.env.IS_PLATFORM;
|
|
340
|
+
} else {
|
|
341
|
+
process.env.IS_PLATFORM = originalIsPlatform;
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
test("IS_PLATFORM=true, raw config has no services key → response includes managed defaults", () => {
|
|
346
|
+
process.env.IS_PLATFORM = "true";
|
|
347
|
+
|
|
348
|
+
// Mirrors the real-world fresh-hatch state: lifecycle wrote
|
|
349
|
+
// `llm.profiles` to disk, but never persisted any service modes.
|
|
350
|
+
const raw: Record<string, unknown> = {
|
|
351
|
+
llm: {
|
|
352
|
+
profiles: {
|
|
353
|
+
balanced: { provider: "anthropic", model: "claude-sonnet-4.5" },
|
|
354
|
+
},
|
|
355
|
+
activeProfile: "balanced",
|
|
356
|
+
},
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
const result = applyContextDefaultsToRawConfig(raw) as Record<
|
|
360
|
+
string,
|
|
361
|
+
unknown
|
|
362
|
+
>;
|
|
363
|
+
const services = result["services"] as Record<string, { mode: string }>;
|
|
364
|
+
expect(services).toBeDefined();
|
|
365
|
+
for (const svc of MANAGED_SERVICES) {
|
|
366
|
+
expect(services[svc]!.mode).toBe("managed");
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
test("IS_PLATFORM=true, raw config has explicit services.inference.mode='your-own' → preserved", () => {
|
|
371
|
+
process.env.IS_PLATFORM = "true";
|
|
372
|
+
|
|
373
|
+
// User has explicitly chosen "your-own" via the macOS Save flow.
|
|
374
|
+
// The patch handler persisted that to disk; the fill pass must not
|
|
375
|
+
// override an explicit user choice.
|
|
376
|
+
const raw: Record<string, unknown> = {
|
|
377
|
+
services: {
|
|
378
|
+
inference: { mode: "your-own" },
|
|
379
|
+
},
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
const result = applyContextDefaultsToRawConfig(raw) as Record<
|
|
383
|
+
string,
|
|
384
|
+
unknown
|
|
385
|
+
>;
|
|
386
|
+
const services = result["services"] as Record<string, { mode: string }>;
|
|
387
|
+
expect(services["inference"]!.mode).toBe("your-own");
|
|
388
|
+
// Other services were missing entirely → context defaults fill them in.
|
|
389
|
+
expect(services["image-generation"]!.mode).toBe("managed");
|
|
390
|
+
expect(services["web-search"]!.mode).toBe("managed");
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
test("IS_PLATFORM=false, raw config has no services key → response is unchanged", () => {
|
|
394
|
+
process.env.IS_PLATFORM = "false";
|
|
395
|
+
|
|
396
|
+
const raw: Record<string, unknown> = {
|
|
397
|
+
llm: {
|
|
398
|
+
profiles: {
|
|
399
|
+
balanced: { provider: "anthropic", model: "claude-sonnet-4.5" },
|
|
400
|
+
},
|
|
401
|
+
},
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
const result = applyContextDefaultsToRawConfig(raw) as Record<
|
|
405
|
+
string,
|
|
406
|
+
unknown
|
|
407
|
+
>;
|
|
408
|
+
expect(result["services"]).toBeUndefined();
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
test("IS_PLATFORM=true, raw config has partial services.inference subtree → preserves user fields, fills missing mode", () => {
|
|
412
|
+
process.env.IS_PLATFORM = "true";
|
|
413
|
+
|
|
414
|
+
// User set image-generation.provider but never chose a mode for any
|
|
415
|
+
// service. The fill pass adds the missing modes without clobbering
|
|
416
|
+
// the user-supplied provider.
|
|
417
|
+
const raw: Record<string, unknown> = {
|
|
418
|
+
services: {
|
|
419
|
+
"image-generation": { provider: "openai" },
|
|
420
|
+
},
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
const result = applyContextDefaultsToRawConfig(raw) as Record<
|
|
424
|
+
string,
|
|
425
|
+
unknown
|
|
426
|
+
>;
|
|
427
|
+
const services = result["services"] as Record<
|
|
428
|
+
string,
|
|
429
|
+
{ mode: string; provider?: string }
|
|
430
|
+
>;
|
|
431
|
+
expect(services["image-generation"]!.mode).toBe("managed");
|
|
432
|
+
expect(services["image-generation"]!.provider).toBe("openai");
|
|
433
|
+
// Inference, which was missing entirely, picks up the context default.
|
|
434
|
+
expect(services["inference"]!.mode).toBe("managed");
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
// -------------------------------------------------------------------------
|
|
438
|
+
// Malformed-but-parseable config.json — must not 500 the GET endpoint.
|
|
439
|
+
//
|
|
440
|
+
// `loadRawConfig()` is typed `Record<string, unknown>` but `JSON.parse`
|
|
441
|
+
// will happily return `null`, primitives, or arrays for a syntactically
|
|
442
|
+
// valid file like `null` / `42` / `[]`. The helper must return those
|
|
443
|
+
// payloads unchanged rather than throwing inside
|
|
444
|
+
// `fillContextDefaultsForMissingKeys`.
|
|
445
|
+
// -------------------------------------------------------------------------
|
|
446
|
+
|
|
447
|
+
test("IS_PLATFORM=true, raw config is null → returned unchanged (no throw)", () => {
|
|
448
|
+
process.env.IS_PLATFORM = "true";
|
|
449
|
+
expect(applyContextDefaultsToRawConfig(null)).toBe(null);
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
test("IS_PLATFORM=true, raw config is a primitive number → returned unchanged (no throw)", () => {
|
|
453
|
+
process.env.IS_PLATFORM = "true";
|
|
454
|
+
expect(applyContextDefaultsToRawConfig(42)).toBe(42);
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
test("IS_PLATFORM=true, raw config is an array → returned unchanged (no throw)", () => {
|
|
458
|
+
process.env.IS_PLATFORM = "true";
|
|
459
|
+
const raw: unknown[] = [{ foo: "bar" }];
|
|
460
|
+
const result = applyContextDefaultsToRawConfig(raw);
|
|
461
|
+
expect(result).toBe(raw);
|
|
462
|
+
// No `services` key was synthesized onto the array.
|
|
463
|
+
expect((result as { services?: unknown }).services).toBeUndefined();
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
test("IS_PLATFORM=true, raw config is a string → returned unchanged (no throw)", () => {
|
|
467
|
+
process.env.IS_PLATFORM = "true";
|
|
468
|
+
expect(applyContextDefaultsToRawConfig("not-an-object")).toBe(
|
|
469
|
+
"not-an-object",
|
|
470
|
+
);
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
test("IS_PLATFORM=false, raw config is null → returned unchanged (no throw)", () => {
|
|
474
|
+
// Sanity check: when there are no context defaults to apply, the helper
|
|
475
|
+
// also short-circuits cleanly on non-object payloads.
|
|
476
|
+
process.env.IS_PLATFORM = "false";
|
|
477
|
+
expect(applyContextDefaultsToRawConfig(null)).toBe(null);
|
|
195
478
|
});
|
|
196
479
|
});
|
|
@@ -37,6 +37,7 @@ describe("cleanupSettingsChanged", () => {
|
|
|
37
37
|
supersededItemRetentionMs: 30 * 24 * 60 * 60 * 1000,
|
|
38
38
|
conversationRetentionDays: 0,
|
|
39
39
|
llmRequestLogRetentionMs: 1 * 24 * 60 * 60 * 1000,
|
|
40
|
+
traceEventRetentionDays: 3,
|
|
40
41
|
};
|
|
41
42
|
|
|
42
43
|
test("returns false when either side is undefined", () => {
|
|
@@ -128,11 +129,9 @@ mock.module("../util/logger.js", () => ({
|
|
|
128
129
|
truncateForLog: (v: string) => v,
|
|
129
130
|
}));
|
|
130
131
|
|
|
131
|
-
// Simulate a config-cache layer: `diskConfig` is the on-disk value
|
|
132
|
-
// `cachedConfig` is
|
|
133
|
-
//
|
|
134
|
-
// a memoized value that only refreshes after explicit invalidation. Tests
|
|
135
|
-
// mutate `diskConfig` to simulate a user writing a new config.json.
|
|
132
|
+
// Simulate a config-cache layer: `diskConfig` is the on-disk value and
|
|
133
|
+
// `cachedConfig` is the in-memory value returned by getConfig() when present.
|
|
134
|
+
// Tests mutate `diskConfig` to simulate a user writing a new config.json.
|
|
136
135
|
interface TestConfig {
|
|
137
136
|
memory: {
|
|
138
137
|
enabled: boolean;
|
|
@@ -199,10 +198,6 @@ mock.module("../providers/registry.js", () => ({
|
|
|
199
198
|
initializeProviders: async () => {},
|
|
200
199
|
}));
|
|
201
200
|
|
|
202
|
-
mock.module("../signals/bash.js", () => ({
|
|
203
|
-
handleBashSignal: () => {},
|
|
204
|
-
}));
|
|
205
|
-
|
|
206
201
|
mock.module("../signals/cancel.js", () => ({
|
|
207
202
|
handleCancelSignal: () => {},
|
|
208
203
|
}));
|
|
@@ -252,6 +247,20 @@ describe("ConfigWatcher.refreshConfigFromSources cleanup throttle reset", () =>
|
|
|
252
247
|
expect(resetCleanupScheduleThrottleCalls).toBe(1);
|
|
253
248
|
});
|
|
254
249
|
|
|
250
|
+
test("resets throttle when the loader cache has already observed the disk change", async () => {
|
|
251
|
+
const watcher = new ConfigWatcher();
|
|
252
|
+
watcher.initFingerprint(diskConfig as never);
|
|
253
|
+
|
|
254
|
+
diskConfig = makeConfig({
|
|
255
|
+
llmRequestLogRetentionMs: 7 * 24 * 60 * 60 * 1000,
|
|
256
|
+
});
|
|
257
|
+
cachedConfig = null;
|
|
258
|
+
|
|
259
|
+
const changed = await watcher.refreshConfigFromSources();
|
|
260
|
+
expect(changed).toBe(true);
|
|
261
|
+
expect(resetCleanupScheduleThrottleCalls).toBe(1);
|
|
262
|
+
});
|
|
263
|
+
|
|
255
264
|
test("does NOT reset throttle when config is identical (no fingerprint change)", async () => {
|
|
256
265
|
const watcher = new ConfigWatcher();
|
|
257
266
|
watcher.initFingerprint(diskConfig as never);
|