@vellumai/assistant 0.7.2 → 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.
Files changed (347) hide show
  1. package/ARCHITECTURE.md +16 -1
  2. package/docs/architecture/memory.md +5 -2
  3. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +13 -4
  4. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -9
  5. package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
  6. package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
  7. package/openapi.yaml +449 -22
  8. package/package.json +1 -1
  9. package/src/__tests__/app-control-flow.test.ts +21 -11
  10. package/src/__tests__/assistant-event-hub.test.ts +48 -0
  11. package/src/__tests__/assistant-event.test.ts +0 -10
  12. package/src/__tests__/assistant-events-sse-hardening.test.ts +2 -7
  13. package/src/__tests__/assistant-feature-flags-integration.test.ts +18 -0
  14. package/src/__tests__/auto-analysis-end-to-end.test.ts +62 -1
  15. package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
  16. package/src/__tests__/call-conversation-messages.test.ts +8 -2
  17. package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
  18. package/src/__tests__/channel-readiness-service.test.ts +4 -2
  19. package/src/__tests__/config-loader-backfill.test.ts +379 -0
  20. package/src/__tests__/config-schema.test.ts +1 -0
  21. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +18 -9
  22. package/src/__tests__/config-watcher.test.ts +140 -69
  23. package/src/__tests__/context-search-agent-runner.test.ts +61 -3
  24. package/src/__tests__/context-search-conversations-source.test.ts +0 -24
  25. package/src/__tests__/context-search-fanout.test.ts +0 -1
  26. package/src/__tests__/context-search-memory-source.test.ts +3 -7
  27. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
  28. package/src/__tests__/context-search-pkb-source.test.ts +0 -1
  29. package/src/__tests__/context-search-workspace-source.test.ts +0 -1
  30. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
  31. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
  32. package/src/__tests__/conversation-agent-loop.test.ts +454 -5
  33. package/src/__tests__/conversation-error.test.ts +150 -3
  34. package/src/__tests__/conversation-process-callsite.test.ts +43 -0
  35. package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
  36. package/src/__tests__/conversation-runtime-assembly.test.ts +65 -0
  37. package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
  38. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  39. package/src/__tests__/conversation-store.test.ts +0 -18
  40. package/src/__tests__/conversation-surfaces-app-control.test.ts +15 -4
  41. package/src/__tests__/conversation-surfaces-data-persist.test.ts +404 -0
  42. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +2 -5
  43. package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
  44. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
  45. package/src/__tests__/credentials-cli.test.ts +7 -0
  46. package/src/__tests__/cu-unified-flow.test.ts +176 -10
  47. package/src/__tests__/date-context.test.ts +164 -2
  48. package/src/__tests__/disk-pressure-guard.test.ts +262 -0
  49. package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
  50. package/src/__tests__/disk-pressure-policy.test.ts +241 -0
  51. package/src/__tests__/disk-pressure-routes.test.ts +379 -0
  52. package/src/__tests__/disk-pressure-tools.test.ts +277 -0
  53. package/src/__tests__/disk-usage.test.ts +150 -0
  54. package/src/__tests__/events-client-registration.test.ts +52 -0
  55. package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
  56. package/src/__tests__/file-write-tool.test.ts +4 -10
  57. package/src/__tests__/filing-service.test.ts +3 -4
  58. package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
  59. package/src/__tests__/heartbeat-service.test.ts +260 -11
  60. package/src/__tests__/host-app-control-proxy.test.ts +195 -25
  61. package/src/__tests__/host-bash-proxy.test.ts +227 -34
  62. package/src/__tests__/host-bash-routes.test.ts +178 -13
  63. package/src/__tests__/host-cu-proxy.test.ts +210 -3
  64. package/src/__tests__/host-cu-routes-targeted.test.ts +141 -12
  65. package/src/__tests__/host-file-proxy-targeted.test.ts +48 -9
  66. package/src/__tests__/host-file-proxy.test.ts +268 -6
  67. package/src/__tests__/host-file-routes-targeted.test.ts +175 -17
  68. package/src/__tests__/host-transfer-proxy-targeted.test.ts +408 -59
  69. package/src/__tests__/host-transfer-routes-targeted.test.ts +232 -17
  70. package/src/__tests__/http-user-message-parity.test.ts +107 -1
  71. package/src/__tests__/injector-chain.test.ts +18 -6
  72. package/src/__tests__/injector-disk-pressure.test.ts +224 -0
  73. package/src/__tests__/managed-profile-guard.test.ts +18 -0
  74. package/src/__tests__/mcp-abort-signal.test.ts +130 -0
  75. package/src/__tests__/memory-admin-recall.test.ts +3 -11
  76. package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
  77. package/src/__tests__/normalize-onboarding.test.ts +180 -0
  78. package/src/__tests__/oauth-connect-routes.test.ts +316 -0
  79. package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
  80. package/src/__tests__/onboarding-persona-write.test.ts +308 -0
  81. package/src/__tests__/openai-provider.test.ts +45 -8
  82. package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
  83. package/src/__tests__/platform-callback-registration.test.ts +21 -4
  84. package/src/__tests__/platform.test.ts +2 -1
  85. package/src/__tests__/playbook-execution.test.ts +0 -43
  86. package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
  87. package/src/__tests__/prechat-onboarding-contract.test.ts +214 -27
  88. package/src/__tests__/provider-tool-name.test.ts +23 -0
  89. package/src/__tests__/relay-server.test.ts +15 -4
  90. package/src/__tests__/runtime-events-sse.test.ts +4 -8
  91. package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
  92. package/src/__tests__/secret-ingress-http.test.ts +0 -1
  93. package/src/__tests__/suggestion-routes.test.ts +46 -0
  94. package/src/__tests__/twilio-validation.test.ts +2 -2
  95. package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
  96. package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
  97. package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
  98. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +90 -0
  99. package/src/approvals/guardian-decision-primitive.ts +13 -0
  100. package/src/approvals/guardian-request-resolvers.ts +16 -17
  101. package/src/backup/snapshot-lock.ts +2 -27
  102. package/src/bundler/compiler-tools.ts +3 -2
  103. package/src/calls/call-conversation-messages.ts +46 -10
  104. package/src/cli/commands/__tests__/webhooks.test.ts +0 -4
  105. package/src/cli/commands/bash.ts +35 -108
  106. package/src/cli/commands/contacts.ts +64 -25
  107. package/src/cli/commands/credentials.ts +56 -0
  108. package/src/cli/commands/memory-v2.ts +7 -6
  109. package/src/cli/commands/oauth/__tests__/connect.test.ts +437 -1
  110. package/src/cli/commands/oauth/connect.ts +127 -1
  111. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -3
  112. package/src/cli/commands/platform/__tests__/connect.test.ts +7 -1
  113. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
  114. package/src/cli/commands/platform/__tests__/status.test.ts +103 -6
  115. package/src/cli/commands/platform/index.ts +16 -7
  116. package/src/cli/commands/status.ts +57 -0
  117. package/src/cli/program.ts +4 -2
  118. package/src/config/assistant-feature-flags.ts +13 -3
  119. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
  120. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +13 -7
  121. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
  122. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
  123. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
  124. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
  125. package/src/config/env.ts +0 -8
  126. package/src/config/feature-flag-registry.json +27 -3
  127. package/src/config/loader.ts +127 -8
  128. package/src/config/schemas/__tests__/memory-v2.test.ts +10 -5
  129. package/src/config/schemas/call-site-catalog.ts +14 -0
  130. package/src/config/schemas/channels.ts +0 -5
  131. package/src/config/schemas/heartbeat.ts +1 -1
  132. package/src/config/schemas/llm.ts +2 -0
  133. package/src/config/schemas/memory-lifecycle.ts +13 -0
  134. package/src/config/schemas/memory-v2.ts +75 -11
  135. package/src/config/schemas/platform.ts +43 -3
  136. package/src/config/schemas/services.ts +28 -0
  137. package/src/config/seed-inference-profiles.ts +230 -33
  138. package/src/contacts/contact-store.ts +0 -25
  139. package/src/daemon/__tests__/conversation-tool-setup.test.ts +86 -25
  140. package/src/daemon/assistant-attachments.ts +4 -4
  141. package/src/daemon/config-watcher.ts +85 -57
  142. package/src/daemon/conversation-agent-loop-handlers.ts +6 -0
  143. package/src/daemon/conversation-agent-loop.ts +170 -33
  144. package/src/daemon/conversation-error.ts +87 -15
  145. package/src/daemon/conversation-lifecycle.ts +1 -3
  146. package/src/daemon/conversation-process.ts +8 -0
  147. package/src/daemon/conversation-runtime-assembly.ts +26 -0
  148. package/src/daemon/conversation-store.ts +2 -2
  149. package/src/daemon/conversation-surfaces.ts +195 -15
  150. package/src/daemon/conversation-tool-setup.ts +57 -14
  151. package/src/daemon/conversation.ts +17 -22
  152. package/src/daemon/date-context.ts +71 -22
  153. package/src/daemon/disk-pressure-background-gate.ts +73 -0
  154. package/src/daemon/disk-pressure-guard.ts +343 -0
  155. package/src/daemon/disk-pressure-policy.ts +163 -0
  156. package/src/daemon/handlers/shared.ts +0 -1
  157. package/src/daemon/handlers/skills.ts +3 -4
  158. package/src/daemon/host-app-control-proxy.ts +137 -41
  159. package/src/daemon/host-bash-proxy.ts +46 -21
  160. package/src/daemon/host-cu-proxy.ts +49 -3
  161. package/src/daemon/host-file-proxy.ts +43 -7
  162. package/src/daemon/host-transfer-proxy.ts +95 -4
  163. package/src/daemon/lifecycle.ts +79 -28
  164. package/src/daemon/meet-host-supervisor.ts +4 -4
  165. package/src/daemon/meet-manifest-loader.ts +0 -1
  166. package/src/daemon/memory-v2-startup.ts +14 -4
  167. package/src/daemon/message-protocol.ts +3 -0
  168. package/src/daemon/message-types/conversations.ts +4 -0
  169. package/src/daemon/message-types/disk-pressure.ts +9 -0
  170. package/src/daemon/message-types/messages.ts +3 -0
  171. package/src/daemon/profiler-run-store.ts +5 -5
  172. package/src/daemon/tool-setup-types.ts +2 -2
  173. package/src/documents/document-store.ts +85 -0
  174. package/src/filing/filing-service.ts +30 -5
  175. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +9 -16
  176. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +36 -0
  177. package/src/heartbeat/heartbeat-run-store.ts +13 -0
  178. package/src/heartbeat/heartbeat-service.ts +205 -31
  179. package/src/home/feed-scheduler.ts +18 -0
  180. package/src/inbound/platform-callback-registration.ts +8 -15
  181. package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
  182. package/src/ipc/assistant-server.ts +56 -2
  183. package/src/ipc/gateway-client.ts +37 -3
  184. package/src/live-voice/live-voice-archive.ts +4 -4
  185. package/src/live-voice/protocol.ts +5 -7
  186. package/src/media/image-service.ts +1 -7
  187. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
  188. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +52 -22
  189. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
  190. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
  191. package/src/memory/admin.ts +5 -9
  192. package/src/memory/context-search/agent-runner.ts +19 -2
  193. package/src/memory/context-search/sources/conversations.ts +2 -11
  194. package/src/memory/context-search/sources/memory-v2.ts +5 -4
  195. package/src/memory/context-search/sources/memory.ts +0 -1
  196. package/src/memory/context-search/types.ts +0 -1
  197. package/src/memory/conversation-crud.ts +4 -12
  198. package/src/memory/db-init.ts +2 -0
  199. package/src/memory/embedding-runtime-manager.ts +119 -5
  200. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +32 -21
  201. package/src/memory/graph/conversation-graph-memory.ts +42 -54
  202. package/src/memory/graph/extraction.ts +1 -3
  203. package/src/memory/graph/graph-search.test.ts +10 -67
  204. package/src/memory/graph/graph-search.ts +1 -20
  205. package/src/memory/graph/retriever.test.ts +6 -0
  206. package/src/memory/graph/retriever.ts +6 -10
  207. package/src/memory/indexer.ts +54 -45
  208. package/src/memory/job-handlers/backfill.ts +2 -11
  209. package/src/memory/job-handlers/cleanup.ts +43 -0
  210. package/src/memory/job-handlers/embedding.ts +6 -8
  211. package/src/memory/job-handlers/summarization.ts +2 -7
  212. package/src/memory/jobs-store.ts +48 -0
  213. package/src/memory/jobs-worker.ts +81 -43
  214. package/src/memory/memory-v2-activation-log-store.ts +32 -14
  215. package/src/memory/memory-v2-concept-frequency.ts +169 -0
  216. package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
  217. package/src/memory/migrations/index.ts +1 -0
  218. package/src/memory/pkb/pkb-search.test.ts +6 -0
  219. package/src/memory/qdrant-client.ts +0 -13
  220. package/src/memory/rerank-local.ts +374 -0
  221. package/src/memory/search/semantic.ts +6 -67
  222. package/src/memory/trace-event-store.ts +1 -17
  223. package/src/memory/v2/__tests__/activation.test.ts +311 -250
  224. package/src/memory/v2/__tests__/consolidation-job.test.ts +40 -8
  225. package/src/memory/v2/__tests__/injection.test.ts +157 -167
  226. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
  227. package/src/memory/v2/__tests__/qdrant.test.ts +16 -0
  228. package/src/memory/v2/__tests__/reranker.test.ts +338 -0
  229. package/src/memory/v2/__tests__/sim.test.ts +5 -199
  230. package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
  231. package/src/memory/v2/__tests__/static-context.test.ts +76 -1
  232. package/src/memory/v2/activation.ts +149 -156
  233. package/src/memory/v2/consolidation-job.ts +62 -12
  234. package/src/memory/v2/injection.ts +47 -60
  235. package/src/memory/v2/prompts/consolidation.ts +36 -1
  236. package/src/memory/v2/qdrant.ts +99 -0
  237. package/src/memory/v2/reranker.ts +177 -0
  238. package/src/memory/v2/sim.ts +10 -84
  239. package/src/memory/v2/skill-content.ts +4 -3
  240. package/src/memory/v2/skill-store.ts +82 -59
  241. package/src/memory/v2/static-context.ts +22 -0
  242. package/src/memory/v2/types.ts +10 -10
  243. package/src/notifications/copy-composer.ts +13 -0
  244. package/src/notifications/signal.ts +4 -0
  245. package/src/oauth/AGENTS.md +3 -1
  246. package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
  247. package/src/oauth/connect-orchestrator.ts +2 -0
  248. package/src/oauth/connection-resolver.test.ts +66 -1
  249. package/src/oauth/connection-resolver.ts +55 -1
  250. package/src/oauth/oauth-connect-state.ts +77 -0
  251. package/src/oauth/seed-providers.ts +58 -1
  252. package/src/plugins/defaults/injectors.ts +35 -2
  253. package/src/plugins/defaults/memory-retrieval.ts +5 -6
  254. package/src/plugins/types.ts +7 -0
  255. package/src/proactive-artifact/aux-message-injector.ts +74 -0
  256. package/src/proactive-artifact/decision.test.ts +226 -0
  257. package/src/proactive-artifact/decision.ts +165 -0
  258. package/src/proactive-artifact/index.ts +7 -0
  259. package/src/proactive-artifact/job.test.ts +867 -0
  260. package/src/proactive-artifact/job.ts +352 -0
  261. package/src/proactive-artifact/message-copy.ts +41 -0
  262. package/src/proactive-artifact/trigger-state.test.ts +277 -0
  263. package/src/proactive-artifact/trigger-state.ts +119 -0
  264. package/src/prompts/normalize-onboarding.ts +80 -0
  265. package/src/prompts/persona-resolver.ts +101 -9
  266. package/src/prompts/system-prompt.ts +21 -7
  267. package/src/prompts/templates/BOOTSTRAP.md +13 -5
  268. package/src/providers/__tests__/retry-callsite.test.ts +222 -1
  269. package/src/providers/model-intents.ts +7 -0
  270. package/src/providers/openrouter/client.ts +8 -0
  271. package/src/providers/retry.ts +50 -0
  272. package/src/providers/types.ts +1 -0
  273. package/src/runtime/__tests__/agent-wake.test.ts +456 -3
  274. package/src/runtime/agent-wake.ts +238 -100
  275. package/src/runtime/assistant-event-hub.ts +36 -6
  276. package/src/runtime/assistant-event.ts +0 -1
  277. package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
  278. package/src/runtime/auth/route-policy.ts +14 -1
  279. package/src/runtime/auth/same-actor.ts +216 -0
  280. package/src/runtime/channel-retry-sweep.ts +65 -1
  281. package/src/runtime/guardian-reply-router.ts +10 -0
  282. package/src/runtime/local-actor-identity.ts +52 -11
  283. package/src/runtime/pending-interactions.ts +8 -0
  284. package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
  285. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +0 -5
  286. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  287. package/src/runtime/routes/client-routes.ts +20 -2
  288. package/src/runtime/routes/contact-routes.ts +0 -25
  289. package/src/runtime/routes/conversation-routes.ts +35 -26
  290. package/src/runtime/routes/debug-bash-routes.ts +163 -0
  291. package/src/runtime/routes/disk-pressure-routes.ts +121 -0
  292. package/src/runtime/routes/document-pdf-renderer.ts +6 -2
  293. package/src/runtime/routes/documents-routes.ts +2 -75
  294. package/src/runtime/routes/events-routes.ts +41 -9
  295. package/src/runtime/routes/host-bash-routes.ts +23 -3
  296. package/src/runtime/routes/host-cu-routes.ts +33 -6
  297. package/src/runtime/routes/host-file-routes.ts +32 -6
  298. package/src/runtime/routes/host-transfer-routes.ts +79 -16
  299. package/src/runtime/routes/identity-routes.ts +7 -138
  300. package/src/runtime/routes/inbound-message-handler.ts +77 -12
  301. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -0
  302. package/src/runtime/routes/index.ts +6 -0
  303. package/src/runtime/routes/memory-item-routes.test.ts +41 -15
  304. package/src/runtime/routes/memory-v2-routes.ts +33 -0
  305. package/src/runtime/routes/oauth-connect-routes.ts +153 -0
  306. package/src/runtime/verification-outbound-actions.ts +4 -4
  307. package/src/schedule/run-script.ts +37 -5
  308. package/src/schedule/scheduler.ts +20 -1
  309. package/src/security/encrypted-store.ts +2 -0
  310. package/src/security/secure-keys.ts +55 -0
  311. package/src/skills/remote-skill-policy.ts +4 -10
  312. package/src/subagent/index.ts +1 -7
  313. package/src/subagent/manager.ts +1 -15
  314. package/src/tasks/task-runner.ts +0 -1
  315. package/src/tasks/task-store.ts +0 -3
  316. package/src/tools/background-tool-registry.ts +17 -3
  317. package/src/tools/host-filesystem/edit.test.ts +151 -0
  318. package/src/tools/host-filesystem/edit.ts +43 -1
  319. package/src/tools/host-filesystem/read.test.ts +129 -0
  320. package/src/tools/host-filesystem/read.ts +43 -1
  321. package/src/tools/host-filesystem/transfer.test.ts +127 -2
  322. package/src/tools/host-filesystem/transfer.ts +56 -11
  323. package/src/tools/host-filesystem/write.test.ts +134 -0
  324. package/src/tools/host-filesystem/write.ts +43 -1
  325. package/src/tools/host-terminal/host-shell.ts +13 -6
  326. package/src/tools/mcp/mcp-tool-factory.ts +2 -1
  327. package/src/tools/memory/register.test.ts +12 -9
  328. package/src/tools/memory/register.ts +1 -2
  329. package/src/tools/provider-tool-name.ts +28 -0
  330. package/src/tools/registry.ts +30 -9
  331. package/src/tools/terminal/shell.ts +9 -1
  332. package/src/tools/tool-approval-handler.ts +31 -6
  333. package/src/tools/types.ts +24 -2
  334. package/src/tts/provider-catalog.ts +3 -5
  335. package/src/util/disk-usage.ts +138 -0
  336. package/src/util/platform.ts +21 -11
  337. package/src/util/process-liveness.ts +26 -0
  338. package/src/workspace/heartbeat-service.ts +19 -0
  339. package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
  340. package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
  341. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +72 -0
  342. package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
  343. package/src/workspace/migrations/registry.ts +8 -0
  344. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
  345. package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
  346. package/src/memory/v2/skill-qdrant.ts +0 -404
  347. package/src/signals/bash.ts +0 -198
@@ -0,0 +1,146 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+
4
+ import type { WorkspaceMigration } from "./types.js";
5
+
6
+ /**
7
+ * Seed a cheap, bounded default for the `heartbeatAgent` LLM call site.
8
+ *
9
+ * Heartbeats are default-on and now run frequently, so they should not inherit
10
+ * the workspace's active chat profile. The default managed profile is Sonnet
11
+ * with high effort and thinking enabled, which is appropriate for interactive
12
+ * chat but too expensive for a periodic background triage pass.
13
+ *
14
+ * Preserve user-owned model selection. If `heartbeatAgent` already has a
15
+ * `profile`, `provider`, or `model`, this migration leaves the entry unchanged
16
+ * so call-site leaves do not silently override the selected profile/model.
17
+ * Speed-only legacy entries from migration 038 are treated as defaultable.
18
+ */
19
+ export const seedHeartbeatCallsiteCostDefaultMigration: WorkspaceMigration = {
20
+ id: "066-seed-heartbeat-callsite-cost-default",
21
+ description:
22
+ "Seed cost-optimized defaults for the heartbeatAgent LLM call site",
23
+ run(workspaceDir: string): void {
24
+ if (process.env.VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH) return;
25
+
26
+ const configPath = join(workspaceDir, "config.json");
27
+ const configExisted = existsSync(configPath);
28
+
29
+ let config: Record<string, unknown> = {};
30
+ if (configExisted) {
31
+ try {
32
+ const raw = JSON.parse(readFileSync(configPath, "utf-8"));
33
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
34
+ config = raw as Record<string, unknown>;
35
+ } catch {
36
+ return;
37
+ }
38
+ }
39
+
40
+ const llm = readObject(config.llm) ?? {};
41
+ const defaultBlock = readObject(llm.default);
42
+ const provider = readString(defaultBlock?.provider) ?? "anthropic";
43
+ const cheapModel = resolveCheapModel(provider);
44
+ if (cheapModel === undefined) return;
45
+
46
+ const callSites = readObject(llm.callSites) ?? {};
47
+ const existing = readObject(callSites.heartbeatAgent) ?? {};
48
+ if (hasExplicitModelSelection(existing)) return;
49
+
50
+ const seeded: Record<string, unknown> = { ...existing };
51
+ let changed = false;
52
+
53
+ const profiles = readObject(llm.profiles) ?? {};
54
+ const costProfile = readObject(profiles["cost-optimized"]);
55
+ if (readString(costProfile?.provider) === provider) {
56
+ seeded.profile = "cost-optimized";
57
+ } else {
58
+ seeded.provider = provider;
59
+ seeded.model = cheapModel;
60
+ }
61
+ changed = true;
62
+
63
+ changed = seedMissingLeaf(seeded, "maxTokens", 2048) || changed;
64
+ changed = seedMissingLeaf(seeded, "effort", "low") || changed;
65
+ changed = seedMissingLeaf(seeded, "temperature", 0) || changed;
66
+
67
+ const thinking = readObject(seeded.thinking) ?? {};
68
+ const seededThinking = { ...thinking };
69
+ const enabledChanged = seedMissingLeaf(seededThinking, "enabled", false);
70
+ const streamThinkingChanged = seedMissingLeaf(
71
+ seededThinking,
72
+ "streamThinking",
73
+ false,
74
+ );
75
+ const thinkingChanged = enabledChanged || streamThinkingChanged;
76
+ if (thinkingChanged || readObject(seeded.thinking) === null) {
77
+ seeded.thinking = seededThinking;
78
+ changed = true;
79
+ }
80
+
81
+ const contextWindow = readObject(seeded.contextWindow) ?? {};
82
+ const seededContextWindow = { ...contextWindow };
83
+ const contextChanged = seedMissingLeaf(
84
+ seededContextWindow,
85
+ "maxInputTokens",
86
+ 16_000,
87
+ );
88
+ if (contextChanged || readObject(seeded.contextWindow) === null) {
89
+ seeded.contextWindow = seededContextWindow;
90
+ changed = true;
91
+ }
92
+
93
+ if (!changed) return;
94
+
95
+ callSites.heartbeatAgent = seeded;
96
+ llm.callSites = callSites;
97
+ config.llm = llm;
98
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
99
+ },
100
+ down(_workspaceDir: string): void {
101
+ // Forward-only: removing the seeded default would make frequent
102
+ // heartbeats inherit the user's potentially expensive chat profile again.
103
+ },
104
+ };
105
+
106
+ // ---------------------------------------------------------------------------
107
+ // Helpers — self-contained per workspace migrations AGENTS.md
108
+ // ---------------------------------------------------------------------------
109
+
110
+ const CHEAP_MODELS_BY_PROVIDER: Record<string, string> = {
111
+ anthropic: "claude-haiku-4-5-20251001",
112
+ openai: "gpt-5.4-nano",
113
+ gemini: "gemini-3-flash",
114
+ ollama: "llama3.2",
115
+ fireworks: "accounts/fireworks/models/kimi-k2p5",
116
+ openrouter: "anthropic/claude-haiku-4.5",
117
+ };
118
+
119
+ function resolveCheapModel(provider: string): string | undefined {
120
+ return CHEAP_MODELS_BY_PROVIDER[provider];
121
+ }
122
+
123
+ function hasExplicitModelSelection(value: Record<string, unknown>): boolean {
124
+ return "profile" in value || "provider" in value || "model" in value;
125
+ }
126
+
127
+ function seedMissingLeaf(
128
+ target: Record<string, unknown>,
129
+ key: string,
130
+ value: unknown,
131
+ ): boolean {
132
+ if (key in target) return false;
133
+ target[key] = value;
134
+ return true;
135
+ }
136
+
137
+ function readObject(value: unknown): Record<string, unknown> | null {
138
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
139
+ return null;
140
+ }
141
+ return value as Record<string, unknown>;
142
+ }
143
+
144
+ function readString(value: unknown): string | undefined {
145
+ return typeof value === "string" && value.length > 0 ? value : undefined;
146
+ }
@@ -0,0 +1,72 @@
1
+ import {
2
+ appendFileSync,
3
+ existsSync,
4
+ readFileSync,
5
+ writeFileSync,
6
+ } from "node:fs";
7
+ import { join } from "node:path";
8
+
9
+ import { getLogger } from "../../util/logger.js";
10
+ import type { WorkspaceMigration } from "./types.js";
11
+
12
+ const log = getLogger(
13
+ "workspace-migration-067-release-notes-safe-storage-limits",
14
+ );
15
+
16
+ const MIGRATION_ID = "067-release-notes-safe-storage-limits";
17
+ const MARKER = `<!-- release-note-id:${MIGRATION_ID} -->`;
18
+
19
+ const RELEASE_NOTE = `${MARKER}
20
+ ## Safe storage limits
21
+
22
+ A new storage protection mode is available behind the safe-storage-limits
23
+ rollout flag. When enabled, the assistant watches workspace disk usage and
24
+ enters cleanup mode if the volume reaches the critical 95% threshold.
25
+
26
+ In cleanup mode, background processes pause and remote messages, including
27
+ trusted-contact messages, are blocked until the guardian frees enough space or
28
+ explicitly overrides the lock. The macOS app now shows a storage cleanup banner
29
+ that must be acknowledged before cleanup chat continues, then keeps a status
30
+ banner visible while cleanup mode is active.
31
+ `;
32
+
33
+ export const releaseNotesSafeStorageLimitsMigration: WorkspaceMigration = {
34
+ id: MIGRATION_ID,
35
+ description: "Append release notes for safe storage limits to UPDATES.md",
36
+
37
+ run(workspaceDir: string): void {
38
+ const updatesPath = join(workspaceDir, "UPDATES.md");
39
+
40
+ try {
41
+ if (existsSync(updatesPath)) {
42
+ const existing = readFileSync(updatesPath, "utf-8");
43
+ if (existing.includes(MARKER)) {
44
+ return;
45
+ }
46
+ const needsLeadingNewline = !existing.endsWith("\n\n");
47
+ const prefix = existing.endsWith("\n") ? "\n" : "\n\n";
48
+ appendFileSync(
49
+ updatesPath,
50
+ needsLeadingNewline ? `${prefix}${RELEASE_NOTE}` : RELEASE_NOTE,
51
+ "utf-8",
52
+ );
53
+ } else {
54
+ writeFileSync(updatesPath, RELEASE_NOTE, "utf-8");
55
+ }
56
+ log.info(
57
+ { path: updatesPath },
58
+ "Appended safe storage limits release note",
59
+ );
60
+ } catch (err) {
61
+ log.warn(
62
+ { err, path: updatesPath },
63
+ "Failed to append safe storage limits release note to UPDATES.md",
64
+ );
65
+ }
66
+ },
67
+
68
+ down(_workspaceDir: string): void {
69
+ // Forward-only: UPDATES.md is a user-facing bulletin the assistant
70
+ // processes and deletes on its own.
71
+ },
72
+ };
@@ -0,0 +1,65 @@
1
+ import {
2
+ appendFileSync,
3
+ existsSync,
4
+ readFileSync,
5
+ writeFileSync,
6
+ } from "node:fs";
7
+ import { join } from "node:path";
8
+
9
+ import { getLogger } from "../../util/logger.js";
10
+ import type { WorkspaceMigration } from "./types.js";
11
+
12
+ const log = getLogger("workspace-migration-068-release-notes-local-timezone");
13
+
14
+ const MIGRATION_ID = "068-release-notes-local-timezone";
15
+ const MARKER = `<!-- release-note-id:${MIGRATION_ID} -->`;
16
+
17
+ const RELEASE_NOTE = `${MARKER}
18
+ ## Local timezone grounding
19
+
20
+ The assistant now grounds \`current_time\` in your local timezone across clients,
21
+ instead of falling back to UTC when the client can report the device timezone.
22
+
23
+ Manual timezone overrides still win when configured, and the assistant can help
24
+ update a stale override after you confirm that your device timezone should be
25
+ used going forward.
26
+ `;
27
+
28
+ export const releaseNotesLocalTimezoneMigration: WorkspaceMigration = {
29
+ id: MIGRATION_ID,
30
+ description:
31
+ "Append release notes for local timezone grounding to UPDATES.md",
32
+
33
+ run(workspaceDir: string): void {
34
+ const updatesPath = join(workspaceDir, "UPDATES.md");
35
+
36
+ try {
37
+ if (existsSync(updatesPath)) {
38
+ const existing = readFileSync(updatesPath, "utf-8");
39
+ if (existing.includes(MARKER)) {
40
+ return;
41
+ }
42
+ const needsLeadingNewline = !existing.endsWith("\n\n");
43
+ const prefix = existing.endsWith("\n") ? "\n" : "\n\n";
44
+ appendFileSync(
45
+ updatesPath,
46
+ needsLeadingNewline ? `${prefix}${RELEASE_NOTE}` : RELEASE_NOTE,
47
+ "utf-8",
48
+ );
49
+ } else {
50
+ writeFileSync(updatesPath, RELEASE_NOTE, "utf-8");
51
+ }
52
+ log.info({ path: updatesPath }, "Appended local timezone release note");
53
+ } catch (err) {
54
+ log.warn(
55
+ { err, path: updatesPath },
56
+ "Failed to append local timezone release note to UPDATES.md",
57
+ );
58
+ }
59
+ },
60
+
61
+ down(_workspaceDir: string): void {
62
+ // Forward-only: UPDATES.md is a user-facing bulletin the assistant
63
+ // processes and deletes on its own.
64
+ },
65
+ };
@@ -62,6 +62,10 @@ import { moveBackupKeyToWorkspaceMigration } from "./061-move-backup-key-to-work
62
62
  import { dropMemoryV2EdgesJsonMigration } from "./062-drop-memory-v2-edges-json.js";
63
63
  import { releaseNotesDynamicModelContextMigration } from "./063-release-notes-dynamic-model-context.js";
64
64
  import { unwindMainAgentOpusSeedMigration } from "./064-unwind-main-agent-opus-seed.js";
65
+ import { bumpStaleHeartbeatIntervalMigration } from "./065-bump-stale-heartbeat-interval.js";
66
+ import { seedHeartbeatCallsiteCostDefaultMigration } from "./066-seed-heartbeat-callsite-cost-default.js";
67
+ import { releaseNotesSafeStorageLimitsMigration } from "./067-release-notes-safe-storage-limits.js";
68
+ import { releaseNotesLocalTimezoneMigration } from "./068-release-notes-local-timezone.js";
65
69
  import { migrateToWorkspaceVolumeMigration } from "./migrate-to-workspace-volume.js";
66
70
  import type { WorkspaceMigration } from "./types.js";
67
71
 
@@ -135,4 +139,8 @@ export const WORKSPACE_MIGRATIONS: WorkspaceMigration[] = [
135
139
  dropMemoryV2EdgesJsonMigration,
136
140
  releaseNotesDynamicModelContextMigration,
137
141
  unwindMainAgentOpusSeedMigration,
142
+ bumpStaleHeartbeatIntervalMigration,
143
+ seedHeartbeatCallsiteCostDefaultMigration,
144
+ releaseNotesSafeStorageLimitsMigration,
145
+ releaseNotesLocalTimezoneMigration,
138
146
  ];
@@ -1,167 +0,0 @@
1
- /**
2
- * Tests that createToolExecutor propagates memoryScopeId from the session's
3
- * memory policy into the ToolContext passed to the underlying executor.
4
- */
5
-
6
- import { describe, expect, mock, test } from "bun:test";
7
-
8
- import type { ToolSetupContext } from "../daemon/conversation-tool-setup.js";
9
- import type { SurfaceData, SurfaceType } from "../daemon/message-protocol.js";
10
- import type { PermissionPrompter } from "../permissions/prompter.js";
11
- import type { SecretPrompter } from "../permissions/secret-prompter.js";
12
- import type { ToolExecutor } from "../tools/executor.js";
13
- import type { ToolContext, ToolExecutionResult } from "../tools/types.js";
14
-
15
- // ---------------------------------------------------------------------------
16
- // Mocks — must be set up before importing the module under test
17
- // ---------------------------------------------------------------------------
18
-
19
- mock.module("../daemon/conversation-surfaces.js", () => ({
20
- refreshSurfacesForApp: mock(() => {}),
21
- surfaceProxyResolver: mock(() =>
22
- Promise.resolve({ content: "", isError: false }),
23
- ),
24
- }));
25
-
26
- mock.module("../services/published-app-updater.js", () => ({
27
- updatePublishedAppDeployment: mock(() => Promise.resolve()),
28
- }));
29
-
30
- mock.module("../tools/browser/browser-screencast.js", () => ({
31
- registerConversationSender: mock(() => {}),
32
- }));
33
-
34
- // ---------------------------------------------------------------------------
35
- // Import after mocks
36
- // ---------------------------------------------------------------------------
37
-
38
- import { createToolExecutor } from "../daemon/conversation-tool-setup.js";
39
-
40
- // ---------------------------------------------------------------------------
41
- // Helpers
42
- // ---------------------------------------------------------------------------
43
-
44
- function makeCtx(overrides: Partial<ToolSetupContext> = {}): ToolSetupContext {
45
- return {
46
- conversationId: "conv-scope",
47
- currentRequestId: "req-1",
48
- workingDir: "/tmp/test",
49
- abortController: null,
50
- traceEmitter: { emit: () => {} },
51
- sendToClient: mock(() => {}),
52
- pendingSurfaceActions: new Map(),
53
- lastSurfaceAction: new Map(),
54
- surfaceState: new Map<
55
- string,
56
- { surfaceType: SurfaceType; data: SurfaceData; title?: string }
57
- >(),
58
- surfaceUndoStacks: new Map(),
59
- accumulatedSurfaceState: new Map(),
60
- surfaceActionRequestIds: new Set<string>(),
61
- currentTurnSurfaces: [],
62
- isProcessing: () => false,
63
- enqueueMessage: () => ({ queued: false, requestId: "r" }),
64
- getQueueDepth: () => 0,
65
- processMessage: async () => "",
66
- withSurface: async <T>(_id: string, fn: () => T | Promise<T>) => fn(),
67
- memoryPolicy: { scopeId: "default" },
68
- ...overrides,
69
- };
70
- }
71
-
72
- /** Executor spy that captures the ToolContext passed to execute(). */
73
- function makeCapturingExecutor(
74
- result: ToolExecutionResult = { content: "ok", isError: false },
75
- ) {
76
- let captured: ToolContext | undefined;
77
- return {
78
- executor: {
79
- execute: mock(
80
- async (
81
- _name: string,
82
- _input: Record<string, unknown>,
83
- ctx: ToolContext,
84
- ) => {
85
- captured = ctx;
86
- return result;
87
- },
88
- ),
89
- },
90
- getCaptured: () => captured,
91
- };
92
- }
93
-
94
- const noopPrompter = {
95
- prompt: mock(async () => ({ decision: "allow" as const })),
96
- } as unknown as PermissionPrompter;
97
- const noopSecretPrompter = {
98
- prompt: mock(async () => ({ cancelled: true })),
99
- } as unknown as SecretPrompter;
100
- const noopLifecycleHandler = mock(() => {});
101
-
102
- // ---------------------------------------------------------------------------
103
- // Tests
104
- // ---------------------------------------------------------------------------
105
-
106
- describe("session-tool-setup memoryScopeId propagation", () => {
107
- test("passes default memoryScopeId to executor context", async () => {
108
- const ctx = makeCtx({
109
- memoryPolicy: { scopeId: "default" },
110
- });
111
- const { executor, getCaptured } = makeCapturingExecutor();
112
-
113
- const toolFn = createToolExecutor(
114
- executor as unknown as ToolExecutor,
115
- noopPrompter,
116
- noopSecretPrompter,
117
- ctx,
118
- noopLifecycleHandler,
119
- );
120
-
121
- await toolFn("some_tool", { key: "value" });
122
-
123
- expect(getCaptured()).toBeDefined();
124
- expect(getCaptured()!.memoryScopeId).toBe("default");
125
- });
126
-
127
- test("passes custom memoryScopeId from session memory policy", async () => {
128
- const ctx = makeCtx({
129
- memoryPolicy: { scopeId: "custom-scope-abc" },
130
- });
131
- const { executor, getCaptured } = makeCapturingExecutor();
132
-
133
- const toolFn = createToolExecutor(
134
- executor as unknown as ToolExecutor,
135
- noopPrompter,
136
- noopSecretPrompter,
137
- ctx,
138
- noopLifecycleHandler,
139
- );
140
-
141
- await toolFn("memory_write", { content: "test" });
142
-
143
- expect(getCaptured()!.memoryScopeId).toBe("custom-scope-abc");
144
- });
145
-
146
- test("reads memoryScopeId at call time, not construction time", async () => {
147
- const ctx = makeCtx({
148
- memoryPolicy: { scopeId: "initial" },
149
- });
150
- const { executor, getCaptured } = makeCapturingExecutor();
151
-
152
- const toolFn = createToolExecutor(
153
- executor as unknown as ToolExecutor,
154
- noopPrompter,
155
- noopSecretPrompter,
156
- ctx,
157
- noopLifecycleHandler,
158
- );
159
-
160
- // Mutate the memory policy after construction
161
- ctx.memoryPolicy = { scopeId: "updated-scope" };
162
-
163
- await toolFn("some_tool", {});
164
-
165
- expect(getCaptured()!.memoryScopeId).toBe("updated-scope");
166
- });
167
- });