@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
@@ -1,4 +1,11 @@
1
- import { describe, expect, it } from "bun:test";
1
+ import { beforeEach, describe, expect, it, mock } from "bun:test";
2
+
3
+ let providerRoutingSources: Record<string, "user-key" | "managed-proxy"> = {};
4
+
5
+ mock.module("../providers/registry.js", () => ({
6
+ getProviderRoutingSource: (provider: string) =>
7
+ providerRoutingSources[provider],
8
+ }));
2
9
 
3
10
  import type { ErrorContext } from "../daemon/conversation-error.js";
4
11
  import {
@@ -63,6 +70,10 @@ describe("isUserCancellation", () => {
63
70
  describe("classifyConversationError", () => {
64
71
  const baseCtx: ErrorContext = { phase: "agent_loop" };
65
72
 
73
+ beforeEach(() => {
74
+ providerRoutingSources = {};
75
+ });
76
+
66
77
  describe("network errors", () => {
67
78
  const cases = [
68
79
  "ECONNREFUSED",
@@ -105,6 +116,52 @@ describe("classifyConversationError", () => {
105
116
  expect(result.errorCategory).toBe("rate_limit");
106
117
  });
107
118
  }
119
+
120
+ it("classifies managed-proxy daily quota responses as MANAGED_USAGE_LIMIT", () => {
121
+ const err = new ProviderError(
122
+ 'Anthropic API error (429): 429 {"code":"daily_quota_exceeded","detail":"You\'ve reached your usage limit for today. You\'ve made 1000 requests, but your current plan allows 1000 per day.","provider":"anthropic"}',
123
+ "anthropic",
124
+ 429,
125
+ );
126
+
127
+ const result = classifyConversationError(err, baseCtx);
128
+
129
+ expect(result.code).toBe("MANAGED_USAGE_LIMIT");
130
+ expect(result.retryable).toBe(true);
131
+ expect(result.userMessage).toContain("Vellum managed inference");
132
+ expect(result.userMessage).toContain("not an AI provider outage");
133
+ expect(result.errorCategory).toBe("managed_usage_limit");
134
+ });
135
+
136
+ it("classifies managed-proxy routed 429s as MANAGED_USAGE_LIMIT", () => {
137
+ providerRoutingSources.anthropic = "managed-proxy";
138
+ const err = new ProviderError(
139
+ "Anthropic API error (429): Too many requests",
140
+ "anthropic",
141
+ 429,
142
+ );
143
+
144
+ const result = classifyConversationError(err, baseCtx);
145
+
146
+ expect(result.code).toBe("MANAGED_USAGE_LIMIT");
147
+ expect(result.userMessage).toContain("Vellum managed inference");
148
+ expect(result.errorCategory).toBe("managed_usage_limit");
149
+ });
150
+
151
+ it("keeps provider copy for direct provider 429s", () => {
152
+ providerRoutingSources.anthropic = "user-key";
153
+ const err = new ProviderError(
154
+ "Anthropic API error (429): Too many requests",
155
+ "anthropic",
156
+ 429,
157
+ );
158
+
159
+ const result = classifyConversationError(err, baseCtx);
160
+
161
+ expect(result.code).toBe("PROVIDER_RATE_LIMIT");
162
+ expect(result.userMessage).toContain("AI provider");
163
+ expect(result.errorCategory).toBe("rate_limit");
164
+ });
108
165
  });
109
166
 
110
167
  describe("provider overloaded errors", () => {
@@ -509,11 +566,11 @@ describe("classifyConversationError", () => {
509
566
  expect(result.errorCategory).toBe("provider_not_configured");
510
567
  });
511
568
 
512
- it("classifies ProviderError with 402 as credits_exhausted (non-retryable)", () => {
569
+ it("classifies direct ProviderError with 402 as provider_billing (non-retryable)", () => {
513
570
  const err = new ProviderError("Payment Required", "anthropic", 402);
514
571
  const result = classifyConversationError(err, baseCtx);
515
572
  expect(result.code).toBe("PROVIDER_BILLING");
516
- expect(result.errorCategory).toBe("credits_exhausted");
573
+ expect(result.errorCategory).toBe("provider_billing");
517
574
  expect(result.retryable).toBe(false);
518
575
  });
519
576
 
@@ -560,6 +617,96 @@ describe("classifyConversationError", () => {
560
617
  });
561
618
  });
562
619
 
620
+ describe("OpenRouter billing classification", () => {
621
+ it("keeps managed-proxy OpenRouter 402 responses as credits_exhausted", () => {
622
+ providerRoutingSources.openrouter = "managed-proxy";
623
+ const err = new ProviderError(
624
+ "OpenRouter API error (402): Payment Required",
625
+ "openrouter",
626
+ 402,
627
+ );
628
+
629
+ const result = classifyConversationError(err, baseCtx);
630
+
631
+ expect(result.code).toBe("PROVIDER_BILLING");
632
+ expect(result.errorCategory).toBe("credits_exhausted");
633
+ expect(result.retryable).toBe(false);
634
+ expect(result.userMessage).toContain("Add funds");
635
+ expect(result.userMessage).toContain("assistant");
636
+ });
637
+
638
+ it("classifies direct Anthropic, OpenAI, and OpenRouter 402 responses as provider_billing", () => {
639
+ providerRoutingSources.anthropic = "user-key";
640
+ providerRoutingSources.openai = "user-key";
641
+ providerRoutingSources.openrouter = "user-key";
642
+
643
+ for (const provider of ["anthropic", "openai", "openrouter"]) {
644
+ const err = new ProviderError(
645
+ `${provider} API error (402): Payment Required`,
646
+ provider,
647
+ 402,
648
+ );
649
+
650
+ const result = classifyConversationError(err, baseCtx);
651
+
652
+ expect(result.code).toBe("PROVIDER_BILLING");
653
+ expect(result.errorCategory).toBe("provider_billing");
654
+ expect(result.retryable).toBe(false);
655
+ expect(result.userMessage).toContain("provider");
656
+ expect(result.userMessage).toContain("Settings");
657
+ }
658
+ });
659
+
660
+ it("classifies OpenRouter 400 credit-limit messages as provider_billing", () => {
661
+ const cases = [
662
+ "OpenRouter API error (400): This request requires more credits",
663
+ "OpenRouter API error (400): You can only afford 1000 tokens",
664
+ ];
665
+
666
+ for (const message of cases) {
667
+ const err = new ProviderError(message, "openrouter", 400);
668
+
669
+ const result = classifyConversationError(err, baseCtx);
670
+
671
+ expect(result.code).toBe("PROVIDER_BILLING");
672
+ expect(result.errorCategory).toBe("provider_billing");
673
+ expect(result.retryable).toBe(false);
674
+ }
675
+ });
676
+
677
+ it("classifies managed-proxy OpenRouter insufficient_balance bodies as credits_exhausted", () => {
678
+ providerRoutingSources.openrouter = "managed-proxy";
679
+ const err = new ProviderError(
680
+ 'OpenRouter API error (402): {"code":"insufficient_balance","detail":"Managed balance exhausted"}',
681
+ "openrouter",
682
+ 402,
683
+ );
684
+
685
+ const result = classifyConversationError(err, baseCtx);
686
+
687
+ expect(result.code).toBe("PROVIDER_BILLING");
688
+ expect(result.errorCategory).toBe("credits_exhausted");
689
+ expect(result.retryable).toBe(false);
690
+ });
691
+
692
+ it("classifies direct OpenRouter insufficient_balance bodies as provider_billing", () => {
693
+ providerRoutingSources.openrouter = "user-key";
694
+ const err = new ProviderError(
695
+ 'OpenRouter API error (402): {"code":"insufficient_balance","detail":"Provider account balance exhausted"}',
696
+ "openrouter",
697
+ 402,
698
+ );
699
+
700
+ const result = classifyConversationError(err, baseCtx);
701
+
702
+ expect(result.code).toBe("PROVIDER_BILLING");
703
+ expect(result.errorCategory).toBe("provider_billing");
704
+ expect(result.retryable).toBe(false);
705
+ expect(result.userMessage).toContain("provider");
706
+ expect(result.userMessage).toContain("Settings");
707
+ });
708
+ });
709
+
563
710
  describe("debug detail truncation", () => {
564
711
  it("truncates debugDetails longer than 4000 chars", () => {
565
712
  const longMsg = "x".repeat(5000);
@@ -12,8 +12,14 @@
12
12
  */
13
13
  import { describe, expect, mock, test } from "bun:test";
14
14
 
15
+ import { _setOverridesForTesting } from "../config/assistant-feature-flags.js";
15
16
  import type { Message, ProviderResponse } from "../providers/types.js";
16
17
 
18
+ // This test exercises v1 conversation routing. The `memory-v2-enabled` flag
19
+ // (registry default `true`) flips memory routing to v2 — disable it here so
20
+ // the v1 paths under test stay active.
21
+ _setOverridesForTesting({ "memory-v2-enabled": false });
22
+
17
23
  // Use an object wrapper so TypeScript doesn't narrow the captured type to
18
24
  // `undefined` based on the initial assignment in the test setup.
19
25
  const captured: {
@@ -382,4 +388,41 @@ describe("processMessage callSite threading", () => {
382
388
  expect(captured.resolvedMaxTokens).toBe(1234);
383
389
  expect(captured.resolvedHasMaxTokens).toBe(true);
384
390
  });
391
+
392
+ test("applies clientTimezone in the create and reuse transport metadata path", async () => {
393
+ mockConversation = {
394
+ id: "conv-store-client-timezone",
395
+ contextSummary: null,
396
+ contextCompactedMessageCount: 0,
397
+ totalInputTokens: 0,
398
+ totalOutputTokens: 0,
399
+ totalEstimatedCost: 0,
400
+ };
401
+ mockDbMessages = [];
402
+ clearCaptured();
403
+ clearAllActiveConversations();
404
+
405
+ const conversation = await getOrCreateConversation(
406
+ "conv-store-client-timezone",
407
+ {
408
+ transport: {
409
+ channelId: "vellum",
410
+ interfaceId: "macos",
411
+ clientTimezone: "america/new_york",
412
+ },
413
+ },
414
+ );
415
+
416
+ expect(conversation.clientTimezone).toBe("America/New_York");
417
+
418
+ await getOrCreateConversation("conv-store-client-timezone", {
419
+ transport: {
420
+ channelId: "vellum",
421
+ interfaceId: "ios",
422
+ clientTimezone: "europe/london",
423
+ },
424
+ });
425
+
426
+ expect(conversation.clientTimezone).toBe("Europe/London");
427
+ });
385
428
  });
@@ -1,11 +1,17 @@
1
1
  import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  import type { AgentEvent } from "../agent/loop.js";
4
+ import { _setOverridesForTesting } from "../config/assistant-feature-flags.js";
4
5
  import type { UserMessageAttachment } from "../daemon/message-protocol.js";
5
6
  import { resetPluginRegistryAndRegisterDefaults } from "../plugins/defaults/index.js";
6
7
  import type { Message, ProviderResponse } from "../providers/types.js";
7
8
  import { ProviderError } from "../util/errors.js";
8
9
 
10
+ // This test exercises v1 conversation routing. The `memory-v2-enabled` flag
11
+ // (registry default `true`) flips memory routing to v2 — disable it here so
12
+ // the v1 paths under test stay active.
13
+ _setOverridesForTesting({ "memory-v2-enabled": false });
14
+
9
15
  mock.module("../util/logger.js", () => ({
10
16
  getLogger: () =>
11
17
  new Proxy({} as Record<string, unknown>, { get: () => () => {} }),
@@ -1,5 +1,12 @@
1
1
  import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
+ import { _setOverridesForTesting } from "../config/assistant-feature-flags.js";
4
+
5
+ // This test exercises v1 conversation routing. The `memory-v2-enabled` flag
6
+ // (registry default `true`) flips memory routing to v2 — disable it here so
7
+ // the v1 paths under test stay active.
8
+ _setOverridesForTesting({ "memory-v2-enabled": false });
9
+
3
10
  // PKB search is mocked so the reminder-hints tests can assert behavior
4
11
  // without standing up Qdrant. The mock returns whatever is staged in
5
12
  // `pkbSearchResults` / `pkbSearchThrows` for the enclosing test.
@@ -1430,6 +1437,64 @@ describe("buildUnifiedTurnContextBlock", () => {
1430
1437
  expect(text).toContain("time_since_last_message: yesterday");
1431
1438
  expect(text).toContain("canonical_actor_identity: user-1");
1432
1439
  });
1440
+
1441
+ test("timezone mismatch: omits extra lines when there is no manual override", () => {
1442
+ const text = buildUnifiedTurnContextBlock({
1443
+ timestamp: "2026-04-02 (Thursday) 08:00:00 -04:00 (America/New_York)",
1444
+ clientTimezone: "America/New_York",
1445
+ detectedTimezone: "America/New_York",
1446
+ });
1447
+
1448
+ expect(text).toContain(
1449
+ "current_time: 2026-04-02 (Thursday) 08:00:00 -04:00 (America/New_York)",
1450
+ );
1451
+ expect(text).not.toContain("configured_user_timezone:");
1452
+ expect(text).not.toContain("client_device_timezone:");
1453
+ expect(text).not.toContain("timezone_update_available:");
1454
+ });
1455
+
1456
+ test("timezone mismatch: omits extra lines when configured and client timezone match", () => {
1457
+ const text = buildUnifiedTurnContextBlock({
1458
+ timestamp: "2026-04-02 (Thursday) 08:00:00 -04:00 (America/New_York)",
1459
+ configuredUserTimezone: "America/New_York",
1460
+ clientTimezone: "America/New_York",
1461
+ detectedTimezone: "America/New_York",
1462
+ });
1463
+
1464
+ expect(text).not.toContain("configured_user_timezone:");
1465
+ expect(text).not.toContain("client_device_timezone:");
1466
+ expect(text).not.toContain("timezone_update_available:");
1467
+ });
1468
+
1469
+ test("timezone mismatch: emits configured and client device timezone when they differ", () => {
1470
+ const text = buildUnifiedTurnContextBlock({
1471
+ timestamp: "2026-04-02 (Thursday) 08:00:00 -04:00 (America/New_York)",
1472
+ configuredUserTimezone: "America/New_York",
1473
+ clientTimezone: "America/Los_Angeles",
1474
+ detectedTimezone: "America/Los_Angeles",
1475
+ });
1476
+
1477
+ expect(text).toContain("configured_user_timezone: America/New_York");
1478
+ expect(text).toContain("client_device_timezone: America/Los_Angeles");
1479
+ });
1480
+
1481
+ test("timezone mismatch: emits CLI affordance only in mismatch case", () => {
1482
+ const mismatchText = buildUnifiedTurnContextBlock({
1483
+ timestamp: "2026-04-02 (Thursday) 08:00:00 -04:00 (America/New_York)",
1484
+ configuredUserTimezone: "America/New_York",
1485
+ clientTimezone: "America/Los_Angeles",
1486
+ });
1487
+ const matchingText = buildUnifiedTurnContextBlock({
1488
+ timestamp: "2026-04-02 (Thursday) 08:00:00 -04:00 (America/New_York)",
1489
+ configuredUserTimezone: "America/New_York",
1490
+ clientTimezone: "America/New_York",
1491
+ });
1492
+
1493
+ expect(mismatchText).toContain(
1494
+ 'timezone_update_available: after explicit user confirmation, persist client_device_timezone with `assistant config set ui.userTimezone "America/Los_Angeles"`',
1495
+ );
1496
+ expect(matchingText).not.toContain("timezone_update_available:");
1497
+ });
1433
1498
  });
1434
1499
 
1435
1500
  // ---------------------------------------------------------------------------
@@ -5,9 +5,15 @@ import type {
5
5
  CheckpointDecision,
6
6
  CheckpointInfo,
7
7
  } from "../agent/loop.js";
8
+ import { _setOverridesForTesting } from "../config/assistant-feature-flags.js";
8
9
  import type { ServerMessage } from "../daemon/message-protocol.js";
9
10
  import type { Message, ProviderResponse } from "../providers/types.js";
10
11
 
12
+ // This test exercises v1 conversation routing. The `memory-v2-enabled` flag
13
+ // (registry default `true`) flips memory routing to v2 — disable it here so
14
+ // the v1 paths under test stay active.
15
+ _setOverridesForTesting({ "memory-v2-enabled": false });
16
+
11
17
  // ---------------------------------------------------------------------------
12
18
  // Mocks — must precede the Conversation import so Bun applies them at load time.
13
19
  // ---------------------------------------------------------------------------
@@ -294,7 +294,6 @@ describe("per-conversation speed override", () => {
294
294
  4096,
295
295
  makeSendToClient(),
296
296
  "/tmp",
297
- undefined, // memoryPolicy
298
297
  undefined, // sharedCesClient
299
298
  "standard", // speedOverride
300
299
  );
@@ -315,7 +314,6 @@ describe("per-conversation speed override", () => {
315
314
  4096,
316
315
  makeSendToClient(),
317
316
  "/tmp",
318
- undefined, // memoryPolicy
319
317
  undefined, // sharedCesClient
320
318
  // no speedOverride — should fall back to global config "fast"
321
319
  );
@@ -335,7 +333,6 @@ describe("per-conversation speed override", () => {
335
333
  4096,
336
334
  makeSendToClient(),
337
335
  "/tmp",
338
- undefined, // memoryPolicy
339
336
  undefined, // sharedCesClient
340
337
  "fast", // speedOverride
341
338
  );
@@ -19,7 +19,6 @@ import {
19
19
  createConversation,
20
20
  deleteLastExchange,
21
21
  getConversation,
22
- getConversationMemoryScopeId,
23
22
  getMessages,
24
23
  } from "../memory/conversation-crud.js";
25
24
  import { isLastUserMessageToolResult } from "../memory/conversation-queries.js";
@@ -454,23 +453,6 @@ describe("createConversation with conversation type option", () => {
454
453
  });
455
454
  });
456
455
 
457
- describe("conversation metadata read helpers", () => {
458
- beforeEach(() => {
459
- const db = getDb();
460
- db.run(`DELETE FROM messages`);
461
- db.run(`DELETE FROM conversations`);
462
- });
463
-
464
- test("getConversationMemoryScopeId returns default for standard conversation", () => {
465
- const conv = createConversation("test");
466
- expect(getConversationMemoryScopeId(conv.id)).toBe("default");
467
- });
468
-
469
- test("getConversationMemoryScopeId returns default for missing conversation", () => {
470
- expect(getConversationMemoryScopeId("nonexistent-id")).toBe("default");
471
- });
472
- });
473
-
474
456
  // ---------------------------------------------------------------------------
475
457
  // Baseline: attachment reuse across conversations
476
458
  // ---------------------------------------------------------------------------
@@ -33,8 +33,11 @@ mock.module("../runtime/pending-interactions.js", () => ({
33
33
 
34
34
  const { surfaceProxyResolver } =
35
35
  await import("../daemon/conversation-surfaces.js");
36
- const { HostAppControlProxy, _resetActiveAppControlConversationId } =
37
- await import("../daemon/host-app-control-proxy.js");
36
+ const {
37
+ HostAppControlProxy,
38
+ _resetActiveAppControlSession,
39
+ _setActiveAppControlSession,
40
+ } = await import("../daemon/host-app-control-proxy.js");
38
41
  type SurfaceConversationContext =
39
42
  import("../daemon/conversation-surfaces.js").SurfaceConversationContext;
40
43
 
@@ -83,11 +86,11 @@ describe("surfaceProxyResolver — app-control tool routing", () => {
83
86
  beforeEach(() => {
84
87
  sentMessages.length = 0;
85
88
  mockHasClient = true;
86
- _resetActiveAppControlConversationId();
89
+ _resetActiveAppControlSession();
87
90
  });
88
91
 
89
92
  afterEach(() => {
90
- _resetActiveAppControlConversationId();
93
+ _resetActiveAppControlSession();
91
94
  });
92
95
 
93
96
  // -------------------------------------------------------------------------
@@ -148,6 +151,10 @@ describe("surfaceProxyResolver — app-control tool routing", () => {
148
151
  test("app_control_observe routes through proxy and returns observation", async () => {
149
152
  const proxy = new HostAppControlProxy("conv-1");
150
153
  const ctx = buildMockContext(proxy, "conv-1");
154
+ _setActiveAppControlSession({
155
+ conversationId: "conv-1",
156
+ app: "com.example.editor",
157
+ });
151
158
 
152
159
  const resultPromise = surfaceProxyResolver(ctx, "app_control_observe", {
153
160
  tool: "observe",
@@ -254,6 +261,10 @@ describe("surfaceProxyResolver — app-control tool routing", () => {
254
261
  test("injects `tool` derived from toolName when the agent input omits it", async () => {
255
262
  const proxy = new HostAppControlProxy("conv-1");
256
263
  const ctx = buildMockContext(proxy, "conv-1");
264
+ _setActiveAppControlSession({
265
+ conversationId: "conv-1",
266
+ app: "com.example.editor",
267
+ });
257
268
 
258
269
  // Agent inputs do not carry the discriminator — the resolver has to
259
270
  // synthesize it from `toolName` ("app_control_observe" → "observe")