@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
@@ -50,6 +50,10 @@ let lastCreateOptions: Record<string, unknown> | null = null;
50
50
  let lastConstructorOptions: Record<string, unknown> | null = null;
51
51
  let shouldThrow: Error | null = null;
52
52
 
53
+ function userMsg(text: string): Message {
54
+ return { role: "user", content: [{ type: "text", text }] };
55
+ }
56
+
53
57
  // Simulate OpenAI.APIError
54
58
  class FakeAPIError extends Error {
55
59
  status: number;
@@ -1294,10 +1298,6 @@ describe("effort config passthrough", () => {
1294
1298
  // ---------------------------------------------------------------------------
1295
1299
 
1296
1300
  describe("OpenRouterProvider reasoning", () => {
1297
- function userMsg(text: string): Message {
1298
- return { role: "user", content: [{ type: "text", text }] };
1299
- }
1300
-
1301
1301
  beforeEach(() => {
1302
1302
  fakeChunks = [textChunk("OK"), usageChunk(10, 2)];
1303
1303
  lastCreateParams = null;
@@ -1367,6 +1367,47 @@ describe("OpenRouterProvider reasoning", () => {
1367
1367
  });
1368
1368
  });
1369
1369
 
1370
+ describe("OpenRouterProvider Anthropic-compatible errors", () => {
1371
+ test("retags Anthropic ProviderError instances as OpenRouter errors", async () => {
1372
+ const provider = new OpenRouterProvider("or-key", "anthropic/claude-4.5");
1373
+ const abortReason = createAbortReason(
1374
+ "user_cancel",
1375
+ "openrouter-provider-test",
1376
+ );
1377
+ const cause = new Error("upstream cause");
1378
+ const innerError = new ProviderError(
1379
+ "Anthropic API error (402): Payment Required",
1380
+ "anthropic",
1381
+ 402,
1382
+ { cause, retryAfterMs: 1250, abortReason },
1383
+ );
1384
+
1385
+ (
1386
+ provider as unknown as {
1387
+ anthropicInner: {
1388
+ sendMessage: OpenRouterProvider["sendMessage"];
1389
+ };
1390
+ }
1391
+ ).anthropicInner = {
1392
+ sendMessage: async () => {
1393
+ throw innerError;
1394
+ },
1395
+ };
1396
+
1397
+ try {
1398
+ await provider.sendMessage([userMsg("hi")]);
1399
+ throw new Error("expected sendMessage to throw");
1400
+ } catch (error) {
1401
+ expect(error).toBeInstanceOf(ProviderError);
1402
+ expect((error as ProviderError).provider).toBe("openrouter");
1403
+ expect((error as ProviderError).statusCode).toBe(402);
1404
+ expect((error as ProviderError).retryAfterMs).toBe(1250);
1405
+ expect((error as ProviderError).abortReason).toBe(abortReason);
1406
+ expect((error as Error).cause).toBe(cause);
1407
+ }
1408
+ });
1409
+ });
1410
+
1370
1411
  // ---------------------------------------------------------------------------
1371
1412
  // Reasoning effort → OpenAI reasoning_effort mapping
1372
1413
  // ---------------------------------------------------------------------------
@@ -1374,10 +1415,6 @@ describe("OpenRouterProvider reasoning", () => {
1374
1415
  describe("OpenAIProvider reasoning_effort", () => {
1375
1416
  let provider: OpenAIProvider;
1376
1417
 
1377
- function userMsg(text: string): Message {
1378
- return { role: "user", content: [{ type: "text", text }] };
1379
- }
1380
-
1381
1418
  beforeEach(() => {
1382
1419
  fakeChunks = [textChunk("OK"), usageChunk(10, 2)];
1383
1420
  lastCreateParams = null;
@@ -27,6 +27,31 @@ mock.module("../util/logger.js", () => ({
27
27
 
28
28
  let writeRelationshipStateCalled = false;
29
29
  let sidecarPayload: unknown = null;
30
+ let writeOnboardingSectionPayload: unknown = null;
31
+
32
+ mock.module("../prompts/normalize-onboarding.js", () => ({
33
+ normalizeOnboardingContext: (ctx: unknown) => ctx,
34
+ }));
35
+
36
+ mock.module("../prompts/persona-resolver.js", () => ({
37
+ writeOnboardingSection: (payload: unknown) => {
38
+ writeOnboardingSectionPayload = payload;
39
+ },
40
+ resolveGuardianPersonaPath: () => join(TEST_DIR, "users", "guardian.md"),
41
+ resolveGuardianPersona: () => null,
42
+ resolveGuardianPersonaStrict: () => null,
43
+ resolveUserPersona: () => null,
44
+ resolveChannelPersona: () => null,
45
+ resolvePersonaContext: () => ({
46
+ userPersona: null,
47
+ userSlug: null,
48
+ channelPersona: null,
49
+ }),
50
+ resolveUserSlug: () => null,
51
+ ensureGuardianPersonaFile: () => {},
52
+ isGuardianPersonaCustomized: () => false,
53
+ GUARDIAN_PERSONA_TEMPLATE: "",
54
+ }));
30
55
 
31
56
  mock.module("../home/relationship-state-writer.js", () => ({
32
57
  RELATIONSHIP_STATE_FILENAME: "relationship-state.json",
@@ -59,13 +84,12 @@ describe("persistOnboardingArtifacts", () => {
59
84
  mkdirSync(TEST_DIR, { recursive: true });
60
85
  writeRelationshipStateCalled = false;
61
86
  sidecarPayload = null;
87
+ writeOnboardingSectionPayload = null;
62
88
  });
63
89
 
64
90
  afterEach(() => {
65
- for (const name of ["IDENTITY.md", "USER.md"]) {
66
- const p = workspacePath(name);
67
- if (existsSync(p)) rmSync(p, { force: true });
68
- }
91
+ const p = workspacePath("IDENTITY.md");
92
+ if (existsSync(p)) rmSync(p, { force: true });
69
93
  });
70
94
 
71
95
  test("seeds IDENTITY.md with assistant name when file does not exist", () => {
@@ -80,19 +104,7 @@ describe("persistOnboardingArtifacts", () => {
80
104
  expect(content).toBe("# Identity\n\n- **Name:** Nova\n");
81
105
  });
82
106
 
83
- test("seeds USER.md with user name when file does not exist", () => {
84
- persistOnboardingArtifacts({
85
- tools: ["slack"],
86
- tasks: ["email"],
87
- tone: "balanced",
88
- userName: "Alex",
89
- });
90
-
91
- const content = readFileSync(workspacePath("USER.md"), "utf-8");
92
- expect(content).toBe("# User\n\n- **Name:** Alex\n");
93
- });
94
-
95
- test("seeds both IDENTITY.md and USER.md when both names are provided", () => {
107
+ test("seeds IDENTITY.md when both names are provided", () => {
96
108
  persistOnboardingArtifacts({
97
109
  tools: [],
98
110
  tasks: [],
@@ -104,9 +116,6 @@ describe("persistOnboardingArtifacts", () => {
104
116
  expect(readFileSync(workspacePath("IDENTITY.md"), "utf-8")).toBe(
105
117
  "# Identity\n\n- **Name:** Pax\n",
106
118
  );
107
- expect(readFileSync(workspacePath("USER.md"), "utf-8")).toBe(
108
- "# User\n\n- **Name:** Alex\n",
109
- );
110
119
  });
111
120
 
112
121
  test("updates Name field in existing IDENTITY.md template", () => {
@@ -128,23 +137,6 @@ describe("persistOnboardingArtifacts", () => {
128
137
  );
129
138
  });
130
139
 
131
- test("updates Name field in existing USER.md template", () => {
132
- writeFileSync(
133
- workspacePath("USER.md"),
134
- "# User\n\n- **Name:** _(not yet chosen)_\n",
135
- );
136
-
137
- persistOnboardingArtifacts({
138
- tools: [],
139
- tasks: [],
140
- tone: "casual",
141
- userName: "NewUser",
142
- });
143
-
144
- const content = readFileSync(workspacePath("USER.md"), "utf-8");
145
- expect(content).toBe("# User\n\n- **Name:** NewUser\n");
146
- });
147
-
148
140
  test("updates old-format Name field in existing IDENTITY.md", () => {
149
141
  writeFileSync(
150
142
  workspacePath("IDENTITY.md"),
@@ -190,17 +182,6 @@ describe("persistOnboardingArtifacts", () => {
190
182
  expect(existsSync(workspacePath("IDENTITY.md"))).toBe(false);
191
183
  });
192
184
 
193
- test("skips USER.md when userName is missing", () => {
194
- persistOnboardingArtifacts({
195
- tools: ["notion"],
196
- tasks: ["project-management"],
197
- tone: "balanced",
198
- assistantName: "Nova",
199
- });
200
-
201
- expect(existsSync(workspacePath("USER.md"))).toBe(false);
202
- });
203
-
204
185
  test("skips IDENTITY.md when assistantName is whitespace-only", () => {
205
186
  persistOnboardingArtifacts({
206
187
  tools: [],
@@ -212,32 +193,17 @@ describe("persistOnboardingArtifacts", () => {
212
193
  expect(existsSync(workspacePath("IDENTITY.md"))).toBe(false);
213
194
  });
214
195
 
215
- test("skips USER.md when userName is whitespace-only", () => {
216
- persistOnboardingArtifacts({
217
- tools: [],
218
- tasks: [],
219
- tone: "balanced",
220
- userName: " ",
221
- });
222
-
223
- expect(existsSync(workspacePath("USER.md"))).toBe(false);
224
- });
225
-
226
- test("trims whitespace from names before writing", () => {
196
+ test("trims whitespace from assistantName before writing", () => {
227
197
  persistOnboardingArtifacts({
228
198
  tools: [],
229
199
  tasks: [],
230
200
  tone: "balanced",
231
- userName: " Alex ",
232
201
  assistantName: " Nova ",
233
202
  });
234
203
 
235
204
  expect(readFileSync(workspacePath("IDENTITY.md"), "utf-8")).toBe(
236
205
  "# Identity\n\n- **Name:** Nova\n",
237
206
  );
238
- expect(readFileSync(workspacePath("USER.md"), "utf-8")).toBe(
239
- "# User\n\n- **Name:** Alex\n",
240
- );
241
207
  });
242
208
 
243
209
  test("passes onboarding payload to writeOnboardingSidecar", () => {
@@ -263,4 +229,18 @@ describe("persistOnboardingArtifacts", () => {
263
229
 
264
230
  expect(writeRelationshipStateCalled).toBe(true);
265
231
  });
232
+
233
+ test("calls writeOnboardingSection with normalized data", () => {
234
+ const payload = {
235
+ tools: ["slack", "linear"],
236
+ tasks: ["code-building", "writing"],
237
+ tone: "professional",
238
+ userName: "Alex",
239
+ assistantName: "Nova",
240
+ };
241
+
242
+ persistOnboardingArtifacts(payload);
243
+
244
+ expect(writeOnboardingSectionPayload).toEqual(payload);
245
+ });
266
246
  });
@@ -5,7 +5,6 @@ import { credentialKey } from "../security/credential-key.js";
5
5
  let mockIsPlatform = true;
6
6
  let mockPlatformBaseUrl = "";
7
7
  let mockPlatformAssistantId = "";
8
- let mockPlatformInternalApiKey = "";
9
8
  let mockSecureKeys: Record<string, string> = {};
10
9
 
11
10
  mock.module("../config/env-registry.js", () => ({
@@ -15,7 +14,6 @@ mock.module("../config/env-registry.js", () => ({
15
14
  mock.module("../config/env.js", () => ({
16
15
  getPlatformBaseUrl: () => mockPlatformBaseUrl,
17
16
  getPlatformAssistantId: () => mockPlatformAssistantId,
18
- getPlatformInternalApiKey: () => mockPlatformInternalApiKey,
19
17
  }));
20
18
 
21
19
  mock.module("../security/secure-keys.js", () => ({
@@ -32,6 +30,7 @@ mock.module("../util/logger.js", () => ({
32
30
  }));
33
31
 
34
32
  const originalFetch = globalThis.fetch;
33
+ const originalEnvCredential = process.env.ASSISTANT_API_KEY;
35
34
 
36
35
  const { registerCallbackRoute, resolvePlatformCallbackRegistrationContext } =
37
36
  await import("../inbound/platform-callback-registration.js");
@@ -41,13 +40,18 @@ describe("platform callback registration", () => {
41
40
  mockIsPlatform = true;
42
41
  mockPlatformBaseUrl = "";
43
42
  mockPlatformAssistantId = "";
44
- mockPlatformInternalApiKey = "";
45
43
  mockSecureKeys = {};
44
+ delete process.env.ASSISTANT_API_KEY;
46
45
  globalThis.fetch = originalFetch;
47
46
  });
48
47
 
49
48
  afterEach(() => {
50
49
  globalThis.fetch = originalFetch;
50
+ if (originalEnvCredential === undefined) {
51
+ delete process.env.ASSISTANT_API_KEY;
52
+ } else {
53
+ process.env.ASSISTANT_API_KEY = originalEnvCredential;
54
+ }
51
55
  });
52
56
 
53
57
  test("resolves managed callback context from stored credentials", async () => {
@@ -64,7 +68,6 @@ describe("platform callback registration", () => {
64
68
  expect(context.isPlatform).toBe(true);
65
69
  expect(context.platformBaseUrl).toBe("https://platform.example.com");
66
70
  expect(context.assistantId).toBe("11111111-2222-4333-8444-555555555555");
67
- expect(context.hasInternalApiKey).toBe(false);
68
71
  expect(context.hasAssistantApiKey).toBe(true);
69
72
  expect(context.authHeader).toBe("Api-Key ast-managed-key");
70
73
  });
@@ -88,6 +91,20 @@ describe("platform callback registration", () => {
88
91
  expect(context.authHeader).toBe("Api-Key ast-self-hosted-key");
89
92
  });
90
93
 
94
+ test("uses ASSISTANT_API_KEY env fallback when stored credential is missing", async () => {
95
+ process.env.ASSISTANT_API_KEY = "env-key";
96
+ mockPlatformBaseUrl = "https://platform.example.com";
97
+ mockPlatformAssistantId = "33333333-4444-4555-8666-777777777777";
98
+
99
+ const context = await resolvePlatformCallbackRegistrationContext();
100
+
101
+ expect(context.enabled).toBe(true);
102
+ expect(context.platformBaseUrl).toBe("https://platform.example.com");
103
+ expect(context.assistantId).toBe("33333333-4444-4555-8666-777777777777");
104
+ expect(context.hasAssistantApiKey).toBe(true);
105
+ expect(context.authHeader).toBe("Api-Key env-key");
106
+ });
107
+
91
108
  test("registerCallbackRoute falls back to assistant API key auth", async () => {
92
109
  mockSecureKeys[credentialKey("vellum", "platform_base_url")] =
93
110
  "https://platform.example.com";
@@ -19,6 +19,7 @@ import {
19
19
  getWorkspacePromptPath,
20
20
  getWorkspaceSkillsDir,
21
21
  getXdgVellumConfigDirName,
22
+ vellumRoot,
22
23
  } from "../util/platform.js";
23
24
 
24
25
  const originalWorkspaceDir = process.env.VELLUM_WORKSPACE_DIR;
@@ -99,7 +100,7 @@ describe("path characterization", () => {
99
100
  ensureDataDir();
100
101
 
101
102
  // Root-level dirs (ensureDataDir always creates these)
102
- const root = join(homedir(), ".vellum");
103
+ const root = vellumRoot();
103
104
  expect(existsSync(root)).toBe(true);
104
105
 
105
106
  // Workspace dirs (in our temp location)
@@ -411,28 +411,6 @@ describe("compilePlaybooks", () => {
411
411
  describe("playbook tool edge cases", () => {
412
412
  beforeEach(clearPlaybooks);
413
413
 
414
- test("create uses memoryScopeId from context when present", async () => {
415
- const scopedCtx: ToolContext = { ...ctx, memoryScopeId: "custom-scope" };
416
- const result = await executePlaybookCreate(
417
- {
418
- trigger: "scoped trigger",
419
- action: "scoped action",
420
- },
421
- scopedCtx,
422
- );
423
-
424
- expect(result.isError).toBe(false);
425
- expect(result.content).toContain("Playbook created successfully");
426
-
427
- // Verify it's invisible to default scope
428
- const defaultList = await executePlaybookList({}, ctx);
429
- expect(defaultList.content).toContain("No playbooks found");
430
-
431
- // Visible to custom scope
432
- const scopedList = await executePlaybookList({}, scopedCtx);
433
- expect(scopedList.content).toContain("scoped trigger");
434
- });
435
-
436
414
  test("update detects collision with another playbook", async () => {
437
415
  const _r1 = await executePlaybookCreate(
438
416
  { trigger: "trigger A", action: "action A" },
@@ -587,25 +565,4 @@ describe("playbook tool edge cases", () => {
587
565
  expect(result.content).toContain("Found 1 playbook");
588
566
  expect(result.content).toContain("**a**");
589
567
  });
590
-
591
- test("delete is scoped and does not affect other scopes", async () => {
592
- const scopedCtx: ToolContext = { ...ctx, memoryScopeId: "scope-A" };
593
- const createResult = await executePlaybookCreate(
594
- { trigger: "x", action: "y" },
595
- scopedCtx,
596
- );
597
- const id = createResult.content.match(/ID: (\S+)/)![1];
598
-
599
- // Try to delete from default scope
600
- const deleteResult = await executePlaybookDelete({ playbook_id: id }, ctx);
601
- expect(deleteResult.isError).toBe(true);
602
- expect(deleteResult.content).toContain("not found");
603
-
604
- // Delete from correct scope succeeds
605
- const correctDelete = await executePlaybookDelete(
606
- { playbook_id: id },
607
- scopedCtx,
608
- );
609
- expect(correctDelete.isError).toBe(false);
610
- });
611
568
  });
@@ -236,6 +236,53 @@ describe("registerPluginTools / unregisterPluginTools helpers", () => {
236
236
  expect(retrieved?.ownerPluginId).toBe("my-plugin");
237
237
  });
238
238
 
239
+ test("registerPluginTools exposes provider-safe aliases for unsafe plugin tool names", async () => {
240
+ const execute = mock(
241
+ async (
242
+ _input: Record<string, unknown>,
243
+ _context: ToolContext,
244
+ ): Promise<ToolExecutionResult> => ({ content: "ok", isError: false }),
245
+ );
246
+ const accepted = registerPluginTools("stripe-plugin", [
247
+ makeFakeTool("Stripe Link CLI", { execute }),
248
+ ]);
249
+
250
+ expect(accepted).toHaveLength(1);
251
+ const alias = accepted[0]!.name;
252
+ expect(alias).toMatch(/^[a-zA-Z0-9_-]{1,64}$/);
253
+ expect(alias.startsWith("Stripe_Link_CLI__")).toBe(true);
254
+ expect(getTool(alias)).toBeDefined();
255
+ expect(accepted[0]!.getDefinition().name).toBe(alias);
256
+
257
+ await accepted[0]!.execute(
258
+ {},
259
+ {
260
+ workingDir: "/tmp",
261
+ conversationId: "conv-1",
262
+ trustClass: "guardian",
263
+ },
264
+ );
265
+
266
+ expect(execute).toHaveBeenCalledTimes(1);
267
+ });
268
+
269
+ test("registerPluginTools keeps edge-whitespace tool names distinct", () => {
270
+ const accepted = registerPluginTools("deploy-plugin", [
271
+ makeFakeTool("deploy"),
272
+ makeFakeTool(" deploy "),
273
+ ]);
274
+
275
+ expect(accepted).toHaveLength(2);
276
+ const aliases = accepted.map((tool) => tool.name);
277
+ expect(new Set(aliases).size).toBe(2);
278
+ expect(aliases).toContain("deploy");
279
+
280
+ const paddedAlias = aliases.find((name) => name !== "deploy");
281
+ expect(paddedAlias).toMatch(/^deploy__[a-f0-9]{12}$/);
282
+ expect(getTool("deploy")).toBeDefined();
283
+ expect(getTool(paddedAlias!)).toBeDefined();
284
+ });
285
+
239
286
  test("registerPluginTools overwrites any pre-existing ownership metadata", () => {
240
287
  // A plugin author could (maliciously or mistakenly) hand in a tool
241
288
  // pre-tagged with another skill's or plugin's ID. The helper must