@vellumai/assistant 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (424) hide show
  1. package/ARCHITECTURE.md +45 -29
  2. package/Dockerfile +1 -0
  3. package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
  4. package/bun.lock +3 -0
  5. package/docs/architecture/memory.md +5 -2
  6. package/knip.json +1 -0
  7. package/node_modules/@vellumai/gateway-client/src/ipc-client.ts +13 -4
  8. package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
  9. package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
  10. package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
  11. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
  12. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
  13. package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
  14. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -9
  15. package/node_modules/@vellumai/slack-text/src/index.test.ts +18 -35
  16. package/node_modules/@vellumai/slack-text/src/index.ts +2 -48
  17. package/openapi.yaml +470 -25
  18. package/package.json +3 -1
  19. package/src/__tests__/annotate-risk-options.test.ts +291 -0
  20. package/src/__tests__/app-control-flow.test.ts +21 -11
  21. package/src/__tests__/approval-cascade.test.ts +8 -16
  22. package/src/__tests__/approval-routes-http.test.ts +6 -0
  23. package/src/__tests__/assistant-event-hub.test.ts +48 -0
  24. package/src/__tests__/assistant-event.test.ts +0 -10
  25. package/src/__tests__/assistant-events-sse-hardening.test.ts +2 -7
  26. package/src/__tests__/assistant-feature-flags-integration.test.ts +18 -0
  27. package/src/__tests__/auto-analysis-end-to-end.test.ts +48 -0
  28. package/src/__tests__/background-workers-disk-pressure.test.ts +268 -0
  29. package/src/__tests__/call-constants.test.ts +10 -1
  30. package/src/__tests__/call-controller.test.ts +127 -0
  31. package/src/__tests__/call-conversation-messages.test.ts +8 -2
  32. package/src/__tests__/channel-inbound-disk-pressure.test.ts +537 -0
  33. package/src/__tests__/channel-readiness-service.test.ts +4 -2
  34. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +58 -28
  35. package/src/__tests__/config-loader-backfill.test.ts +379 -0
  36. package/src/__tests__/config-loader-platform-defaults.test.ts +284 -1
  37. package/src/__tests__/config-schema.test.ts +1 -0
  38. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +18 -9
  39. package/src/__tests__/config-watcher.test.ts +140 -69
  40. package/src/__tests__/context-search-agent-runner.test.ts +61 -3
  41. package/src/__tests__/context-search-conversations-source.test.ts +0 -24
  42. package/src/__tests__/context-search-fanout.test.ts +0 -1
  43. package/src/__tests__/context-search-memory-source.test.ts +6 -33
  44. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -2
  45. package/src/__tests__/context-search-pkb-source.test.ts +12 -7
  46. package/src/__tests__/context-search-workspace-source.test.ts +0 -1
  47. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -0
  48. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +223 -0
  49. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
  50. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -1
  51. package/src/__tests__/conversation-agent-loop.test.ts +457 -8
  52. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
  53. package/src/__tests__/conversation-error.test.ts +150 -3
  54. package/src/__tests__/conversation-init.benchmark.test.ts +1 -1
  55. package/src/__tests__/conversation-process-callsite.test.ts +38 -0
  56. package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -0
  57. package/src/__tests__/conversation-runtime-assembly.test.ts +74 -0
  58. package/src/__tests__/conversation-slash-unknown.test.ts +1 -0
  59. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  60. package/src/__tests__/conversation-store.test.ts +0 -18
  61. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
  62. package/src/__tests__/conversation-surfaces-app-control.test.ts +15 -4
  63. package/src/__tests__/conversation-surfaces-data-persist.test.ts +476 -0
  64. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +61 -5
  65. package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
  66. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
  67. package/src/__tests__/credentials-cli.test.ts +7 -0
  68. package/src/__tests__/cu-unified-flow.test.ts +176 -10
  69. package/src/__tests__/date-context.test.ts +164 -2
  70. package/src/__tests__/disk-pressure-guard.test.ts +262 -0
  71. package/src/__tests__/disk-pressure-lifecycle.test.ts +168 -0
  72. package/src/__tests__/disk-pressure-policy.test.ts +241 -0
  73. package/src/__tests__/disk-pressure-routes.test.ts +379 -0
  74. package/src/__tests__/disk-pressure-tools.test.ts +277 -0
  75. package/src/__tests__/disk-usage.test.ts +150 -0
  76. package/src/__tests__/events-client-registration.test.ts +52 -0
  77. package/src/__tests__/events-dev-bypass-actor.test.ts +162 -0
  78. package/src/__tests__/file-write-tool.test.ts +4 -10
  79. package/src/__tests__/filing-service.test.ts +2 -20
  80. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -26
  81. package/src/__tests__/heartbeat-disk-pressure.test.ts +183 -0
  82. package/src/__tests__/heartbeat-service.test.ts +260 -11
  83. package/src/__tests__/host-app-control-proxy.test.ts +195 -25
  84. package/src/__tests__/host-bash-proxy.test.ts +227 -34
  85. package/src/__tests__/host-bash-routes.test.ts +178 -13
  86. package/src/__tests__/host-cu-proxy.test.ts +210 -3
  87. package/src/__tests__/host-cu-routes-targeted.test.ts +141 -12
  88. package/src/__tests__/host-file-proxy-targeted.test.ts +48 -9
  89. package/src/__tests__/host-file-proxy.test.ts +268 -6
  90. package/src/__tests__/host-file-routes-targeted.test.ts +175 -17
  91. package/src/__tests__/host-transfer-proxy-targeted.test.ts +408 -59
  92. package/src/__tests__/host-transfer-routes-targeted.test.ts +232 -17
  93. package/src/__tests__/http-user-message-parity.test.ts +107 -1
  94. package/src/__tests__/injector-chain.test.ts +36 -16
  95. package/src/__tests__/injector-disk-pressure.test.ts +224 -0
  96. package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
  97. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +154 -67
  98. package/src/__tests__/managed-profile-guard.test.ts +18 -0
  99. package/src/__tests__/mcp-abort-signal.test.ts +130 -0
  100. package/src/__tests__/memory-admin-recall.test.ts +3 -11
  101. package/src/__tests__/memory-retrieval-pipeline.test.ts +22 -1
  102. package/src/__tests__/normalize-onboarding.test.ts +180 -0
  103. package/src/__tests__/notification-decision-fallback.test.ts +91 -0
  104. package/src/__tests__/notification-decision-strategy.test.ts +22 -0
  105. package/src/__tests__/oauth-cli.test.ts +121 -0
  106. package/src/__tests__/oauth-connect-routes.test.ts +316 -0
  107. package/src/__tests__/oauth-provider-seed-logos.test.ts +24 -2
  108. package/src/__tests__/onboarding-persona-write.test.ts +308 -0
  109. package/src/__tests__/openai-provider.test.ts +45 -8
  110. package/src/__tests__/persist-onboarding-artifacts.test.ts +44 -64
  111. package/src/__tests__/platform-callback-registration.test.ts +21 -4
  112. package/src/__tests__/platform.test.ts +2 -1
  113. package/src/__tests__/playbook-execution.test.ts +0 -43
  114. package/src/__tests__/plugin-tool-contribution.test.ts +47 -0
  115. package/src/__tests__/prechat-onboarding-contract.test.ts +214 -27
  116. package/src/__tests__/provider-tool-name.test.ts +23 -0
  117. package/src/__tests__/relay-server.test.ts +60 -5
  118. package/src/__tests__/runtime-events-sse.test.ts +4 -8
  119. package/src/__tests__/scheduler-disk-pressure.test.ts +148 -0
  120. package/src/__tests__/secret-ingress-http.test.ts +0 -1
  121. package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
  122. package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
  123. package/src/__tests__/secret-response-routing.test.ts +7 -5
  124. package/src/__tests__/server-history-render.test.ts +82 -0
  125. package/src/__tests__/skill-include-graph.test.ts +31 -0
  126. package/src/__tests__/skill-load-tool.test.ts +44 -16
  127. package/src/__tests__/skills.test.ts +39 -0
  128. package/src/__tests__/suggestion-routes.test.ts +46 -0
  129. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
  130. package/src/__tests__/tool-executor.test.ts +155 -0
  131. package/src/__tests__/twilio-validation.test.ts +2 -2
  132. package/src/__tests__/voice-session-bridge.test.ts +3 -0
  133. package/src/__tests__/workspace-migration-065-bump-stale-heartbeat-interval.test.ts +122 -0
  134. package/src/__tests__/workspace-migration-066-seed-heartbeat-callsite-cost-default.test.ts +285 -0
  135. package/src/__tests__/workspace-migration-068-release-notes-local-timezone.test.ts +90 -0
  136. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +120 -0
  137. package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
  138. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +78 -0
  139. package/src/agent/loop.ts +11 -0
  140. package/src/approvals/guardian-request-resolvers.ts +3 -32
  141. package/src/backup/snapshot-lock.ts +2 -27
  142. package/src/bundler/compiler-tools.ts +3 -2
  143. package/src/calls/call-constants.ts +5 -8
  144. package/src/calls/call-controller.ts +130 -67
  145. package/src/calls/call-conversation-messages.ts +46 -10
  146. package/src/calls/relay-server.ts +7 -1
  147. package/src/calls/voice-session-bridge.ts +1 -1
  148. package/src/cli/commands/__tests__/webhooks.test.ts +0 -4
  149. package/src/cli/commands/bash.ts +35 -108
  150. package/src/cli/commands/contacts.ts +64 -25
  151. package/src/cli/commands/credentials.ts +56 -0
  152. package/src/cli/commands/memory-v2.ts +11 -10
  153. package/src/cli/commands/oauth/__tests__/connect.test.ts +401 -219
  154. package/src/cli/commands/oauth/connect.ts +124 -40
  155. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -3
  156. package/src/cli/commands/platform/__tests__/connect.test.ts +7 -1
  157. package/src/cli/commands/platform/__tests__/disconnect.test.ts +7 -1
  158. package/src/cli/commands/platform/__tests__/status.test.ts +103 -6
  159. package/src/cli/commands/platform/index.ts +16 -7
  160. package/src/cli/commands/status.ts +57 -0
  161. package/src/cli/program.ts +4 -2
  162. package/src/config/assistant-feature-flags.ts +13 -3
  163. package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
  164. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -3
  165. package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +13 -7
  166. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +2 -2
  167. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +2 -2
  168. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
  169. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +2 -2
  170. package/src/config/env.ts +0 -8
  171. package/src/config/feature-flag-registry.json +13 -5
  172. package/src/config/loader.ts +199 -27
  173. package/src/config/schemas/__tests__/memory-v2.test.ts +10 -5
  174. package/src/config/schemas/call-site-catalog.ts +14 -0
  175. package/src/config/schemas/channels.ts +0 -5
  176. package/src/config/schemas/heartbeat.ts +1 -1
  177. package/src/config/schemas/llm.ts +2 -0
  178. package/src/config/schemas/memory-lifecycle.ts +13 -0
  179. package/src/config/schemas/memory-v2.ts +76 -12
  180. package/src/config/schemas/platform.ts +43 -3
  181. package/src/config/schemas/services.ts +28 -0
  182. package/src/config/seed-inference-profiles.ts +230 -33
  183. package/src/contacts/contact-store.ts +0 -25
  184. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +32 -0
  185. package/src/daemon/__tests__/conversation-tool-setup.test.ts +86 -25
  186. package/src/daemon/assistant-attachments.ts +4 -4
  187. package/src/daemon/config-watcher.ts +85 -57
  188. package/src/daemon/conversation-agent-loop-handlers.ts +38 -0
  189. package/src/daemon/conversation-agent-loop.ts +183 -43
  190. package/src/daemon/conversation-error.ts +87 -15
  191. package/src/daemon/conversation-lifecycle.ts +22 -10
  192. package/src/daemon/conversation-process.ts +8 -0
  193. package/src/daemon/conversation-runtime-assembly.ts +26 -0
  194. package/src/daemon/conversation-store.ts +2 -2
  195. package/src/daemon/conversation-surfaces.ts +211 -29
  196. package/src/daemon/conversation-tool-setup.ts +66 -19
  197. package/src/daemon/conversation.ts +18 -23
  198. package/src/daemon/date-context.ts +71 -22
  199. package/src/daemon/disk-pressure-background-gate.ts +73 -0
  200. package/src/daemon/disk-pressure-guard.ts +343 -0
  201. package/src/daemon/disk-pressure-policy.ts +163 -0
  202. package/src/daemon/handlers/shared.ts +26 -1
  203. package/src/daemon/handlers/skills.ts +3 -4
  204. package/src/daemon/host-app-control-proxy.ts +137 -41
  205. package/src/daemon/host-bash-proxy.ts +47 -22
  206. package/src/daemon/host-browser-proxy.ts +1 -1
  207. package/src/daemon/host-cu-proxy.ts +50 -4
  208. package/src/daemon/host-file-proxy.ts +44 -8
  209. package/src/daemon/host-transfer-proxy.ts +97 -6
  210. package/src/daemon/lifecycle.ts +167 -101
  211. package/src/daemon/meet-host-supervisor.ts +4 -4
  212. package/src/daemon/meet-manifest-loader.ts +0 -1
  213. package/src/daemon/memory-v2-startup.ts +66 -15
  214. package/src/daemon/message-protocol.ts +3 -0
  215. package/src/daemon/message-types/conversations.ts +4 -0
  216. package/src/daemon/message-types/disk-pressure.ts +9 -0
  217. package/src/daemon/message-types/messages.ts +22 -1
  218. package/src/daemon/profiler-run-store.ts +5 -5
  219. package/src/daemon/tool-setup-types.ts +2 -2
  220. package/src/documents/document-store.ts +119 -0
  221. package/src/filing/filing-service.ts +29 -5
  222. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +9 -16
  223. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +36 -0
  224. package/src/heartbeat/heartbeat-run-store.ts +13 -0
  225. package/src/heartbeat/heartbeat-service.ts +205 -31
  226. package/src/home/feed-scheduler.ts +18 -0
  227. package/src/inbound/platform-callback-registration.ts +8 -15
  228. package/src/ipc/__tests__/clients-list-ipc.test.ts +169 -0
  229. package/src/ipc/assistant-server.ts +149 -38
  230. package/src/ipc/gateway-client.ts +37 -3
  231. package/src/ipc/skill-server.ts +99 -42
  232. package/src/live-voice/live-voice-archive.ts +4 -4
  233. package/src/live-voice/protocol.ts +5 -7
  234. package/src/media/image-service.ts +1 -7
  235. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +21 -13
  236. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +34 -51
  237. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -6
  238. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +272 -0
  239. package/src/memory/admin.ts +5 -9
  240. package/src/memory/context-search/agent-runner.ts +19 -2
  241. package/src/memory/context-search/sources/conversations.ts +2 -11
  242. package/src/memory/context-search/sources/memory-v2.ts +1 -16
  243. package/src/memory/context-search/sources/memory.ts +2 -3
  244. package/src/memory/context-search/sources/pkb.ts +2 -3
  245. package/src/memory/context-search/types.ts +0 -1
  246. package/src/memory/conversation-crud.ts +4 -12
  247. package/src/memory/db-init.ts +2 -0
  248. package/src/memory/embedding-runtime-manager.ts +119 -5
  249. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +136 -82
  250. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
  251. package/src/memory/graph/conversation-graph-memory.ts +72 -61
  252. package/src/memory/graph/extraction.ts +1 -3
  253. package/src/memory/graph/graph-search.test.ts +11 -67
  254. package/src/memory/graph/graph-search.ts +4 -24
  255. package/src/memory/graph/retriever.test.ts +12 -1
  256. package/src/memory/graph/retriever.ts +10 -15
  257. package/src/memory/graph/tool-handlers.ts +3 -4
  258. package/src/memory/graph/tools.ts +4 -4
  259. package/src/memory/indexer.ts +53 -45
  260. package/src/memory/job-handlers/backfill.ts +2 -11
  261. package/src/memory/job-handlers/cleanup.ts +43 -0
  262. package/src/memory/job-handlers/embedding.ts +6 -8
  263. package/src/memory/job-handlers/summarization.ts +2 -7
  264. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +116 -0
  265. package/src/memory/jobs/embed-concept-page.ts +223 -87
  266. package/src/memory/jobs-store.ts +48 -0
  267. package/src/memory/jobs-worker.ts +85 -43
  268. package/src/memory/memory-v2-activation-log-store.ts +32 -14
  269. package/src/memory/memory-v2-concept-frequency.ts +169 -0
  270. package/src/memory/migrations/239-trace-events-created-at-index.ts +18 -0
  271. package/src/memory/migrations/index.ts +1 -0
  272. package/src/memory/pkb/pkb-search.test.ts +7 -0
  273. package/src/memory/pkb/pkb-search.ts +4 -5
  274. package/src/memory/qdrant-client.ts +3 -13
  275. package/src/memory/rerank-local.ts +374 -0
  276. package/src/memory/search/semantic.ts +10 -72
  277. package/src/memory/trace-event-store.ts +1 -17
  278. package/src/memory/v2/__tests__/activation.test.ts +346 -255
  279. package/src/memory/v2/__tests__/consolidation-job.test.ts +61 -40
  280. package/src/memory/v2/__tests__/injection.test.ts +297 -190
  281. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +61 -2
  282. package/src/memory/v2/__tests__/qdrant.test.ts +326 -9
  283. package/src/memory/v2/__tests__/reranker.test.ts +338 -0
  284. package/src/memory/v2/__tests__/sim.test.ts +113 -196
  285. package/src/memory/v2/__tests__/skill-store.test.ts +71 -65
  286. package/src/memory/v2/__tests__/static-context.test.ts +77 -14
  287. package/src/memory/v2/__tests__/sweep-job.test.ts +19 -33
  288. package/src/memory/v2/activation.ts +149 -156
  289. package/src/memory/v2/consolidation-job.ts +69 -20
  290. package/src/memory/v2/injection.ts +75 -68
  291. package/src/memory/v2/page-store.ts +39 -0
  292. package/src/memory/v2/prompts/consolidation.ts +41 -1
  293. package/src/memory/v2/qdrant.ts +306 -46
  294. package/src/memory/v2/reranker.ts +177 -0
  295. package/src/memory/v2/sim.ts +77 -110
  296. package/src/memory/v2/skill-content.ts +4 -3
  297. package/src/memory/v2/skill-store.ts +82 -59
  298. package/src/memory/v2/static-context.ts +26 -8
  299. package/src/memory/v2/sweep-job.ts +5 -6
  300. package/src/memory/v2/types.ts +17 -10
  301. package/src/notifications/copy-composer.ts +47 -0
  302. package/src/notifications/decision-engine.ts +46 -0
  303. package/src/notifications/signal.ts +4 -0
  304. package/src/oauth/AGENTS.md +3 -1
  305. package/src/oauth/__tests__/oauth-connect-state.test.ts +137 -0
  306. package/src/oauth/connect-orchestrator.ts +2 -0
  307. package/src/oauth/connection-resolver.test.ts +66 -1
  308. package/src/oauth/connection-resolver.ts +55 -1
  309. package/src/oauth/oauth-connect-state.ts +77 -0
  310. package/src/oauth/seed-providers.ts +58 -1
  311. package/src/permissions/gateway-threshold-reader.ts +116 -8
  312. package/src/permissions/prompter.ts +86 -96
  313. package/src/permissions/secret-prompter.ts +31 -31
  314. package/src/plugins/defaults/injectors.ts +36 -4
  315. package/src/plugins/defaults/memory-retrieval.ts +5 -6
  316. package/src/plugins/types.ts +7 -0
  317. package/src/proactive-artifact/aux-message-injector.ts +74 -0
  318. package/src/proactive-artifact/decision.test.ts +226 -0
  319. package/src/proactive-artifact/decision.ts +165 -0
  320. package/src/proactive-artifact/index.ts +7 -0
  321. package/src/proactive-artifact/job.test.ts +914 -0
  322. package/src/proactive-artifact/job.ts +366 -0
  323. package/src/proactive-artifact/message-copy.ts +58 -0
  324. package/src/proactive-artifact/trigger-state.test.ts +277 -0
  325. package/src/proactive-artifact/trigger-state.ts +119 -0
  326. package/src/prompts/normalize-onboarding.ts +80 -0
  327. package/src/prompts/persona-resolver.ts +101 -9
  328. package/src/prompts/system-prompt.ts +21 -7
  329. package/src/prompts/templates/BOOTSTRAP.md +13 -5
  330. package/src/prompts/templates/SOUL.md +13 -28
  331. package/src/providers/__tests__/retry-callsite.test.ts +222 -1
  332. package/src/providers/model-intents.ts +7 -0
  333. package/src/providers/openrouter/client.ts +8 -0
  334. package/src/providers/retry.ts +50 -0
  335. package/src/providers/types.ts +1 -0
  336. package/src/runtime/__tests__/agent-wake.test.ts +456 -3
  337. package/src/runtime/agent-wake.ts +238 -100
  338. package/src/runtime/assistant-event-hub.ts +36 -6
  339. package/src/runtime/assistant-event.ts +0 -1
  340. package/src/runtime/auth/__tests__/route-policy.test.ts +64 -0
  341. package/src/runtime/auth/route-policy.ts +15 -1
  342. package/src/runtime/auth/same-actor.ts +216 -0
  343. package/src/runtime/channel-approvals.ts +3 -2
  344. package/src/runtime/channel-retry-sweep.ts +65 -1
  345. package/src/runtime/local-actor-identity.ts +52 -11
  346. package/src/runtime/pending-interactions.ts +27 -15
  347. package/src/runtime/routes/__tests__/client-routes.test.ts +155 -0
  348. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +0 -5
  349. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  350. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
  351. package/src/runtime/routes/approval-routes.ts +7 -3
  352. package/src/runtime/routes/client-routes.ts +20 -2
  353. package/src/runtime/routes/consolidation-routes.ts +8 -9
  354. package/src/runtime/routes/contact-routes.ts +0 -25
  355. package/src/runtime/routes/conversation-query-routes.ts +44 -1
  356. package/src/runtime/routes/conversation-routes.ts +35 -26
  357. package/src/runtime/routes/debug-bash-routes.ts +165 -0
  358. package/src/runtime/routes/disk-pressure-routes.ts +121 -0
  359. package/src/runtime/routes/document-pdf-renderer.ts +6 -2
  360. package/src/runtime/routes/documents-routes.ts +2 -75
  361. package/src/runtime/routes/events-routes.ts +41 -9
  362. package/src/runtime/routes/filing-routes.ts +2 -3
  363. package/src/runtime/routes/host-bash-routes.ts +23 -3
  364. package/src/runtime/routes/host-cu-routes.ts +33 -6
  365. package/src/runtime/routes/host-file-routes.ts +32 -6
  366. package/src/runtime/routes/host-transfer-routes.ts +79 -16
  367. package/src/runtime/routes/identity-routes.ts +7 -138
  368. package/src/runtime/routes/inbound-message-handler.ts +77 -12
  369. package/src/runtime/routes/index.ts +6 -0
  370. package/src/runtime/routes/memory-item-routes.test.ts +37 -17
  371. package/src/runtime/routes/memory-item-routes.ts +5 -6
  372. package/src/runtime/routes/memory-v2-routes.ts +136 -17
  373. package/src/runtime/routes/oauth-connect-routes.ts +153 -0
  374. package/src/runtime/verification-outbound-actions.ts +4 -4
  375. package/src/schedule/run-script.ts +37 -5
  376. package/src/schedule/scheduler.ts +20 -1
  377. package/src/security/encrypted-store.ts +2 -0
  378. package/src/security/secure-keys.ts +55 -0
  379. package/src/skills/include-graph.ts +35 -13
  380. package/src/skills/remote-skill-policy.ts +4 -10
  381. package/src/subagent/index.ts +1 -7
  382. package/src/subagent/manager.ts +1 -15
  383. package/src/tasks/task-runner.ts +0 -1
  384. package/src/tasks/task-store.ts +0 -3
  385. package/src/tools/background-tool-registry.ts +17 -3
  386. package/src/tools/document/document-tool.ts +20 -0
  387. package/src/tools/executor.ts +18 -2
  388. package/src/tools/host-filesystem/edit.test.ts +151 -0
  389. package/src/tools/host-filesystem/edit.ts +43 -1
  390. package/src/tools/host-filesystem/read.test.ts +129 -0
  391. package/src/tools/host-filesystem/read.ts +43 -1
  392. package/src/tools/host-filesystem/transfer.test.ts +127 -2
  393. package/src/tools/host-filesystem/transfer.ts +56 -11
  394. package/src/tools/host-filesystem/write.test.ts +134 -0
  395. package/src/tools/host-filesystem/write.ts +43 -1
  396. package/src/tools/host-terminal/host-shell.ts +13 -6
  397. package/src/tools/mcp/mcp-tool-factory.ts +2 -1
  398. package/src/tools/memory/register.test.ts +14 -9
  399. package/src/tools/memory/register.ts +1 -2
  400. package/src/tools/permission-checker.ts +15 -0
  401. package/src/tools/provider-tool-name.ts +28 -0
  402. package/src/tools/registry.ts +30 -9
  403. package/src/tools/skills/load.ts +24 -20
  404. package/src/tools/terminal/shell.ts +9 -1
  405. package/src/tools/tool-approval-handler.ts +31 -6
  406. package/src/tools/tool-name-aliases.ts +19 -0
  407. package/src/tools/types.ts +43 -3
  408. package/src/tts/provider-catalog.ts +3 -5
  409. package/src/util/disk-usage.ts +138 -0
  410. package/src/util/platform.ts +21 -11
  411. package/src/util/process-liveness.ts +26 -0
  412. package/src/workspace/heartbeat-service.ts +19 -0
  413. package/src/workspace/migrations/065-bump-stale-heartbeat-interval.ts +60 -0
  414. package/src/workspace/migrations/066-seed-heartbeat-callsite-cost-default.ts +146 -0
  415. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +14 -0
  416. package/src/workspace/migrations/068-release-notes-local-timezone.ts +65 -0
  417. package/src/workspace/migrations/069-seed-onboarding-threads.ts +28 -0
  418. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
  419. package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
  420. package/src/workspace/migrations/registry.ts +14 -0
  421. package/src/__tests__/conversation-tool-setup-memory-scope.test.ts +0 -167
  422. package/src/memory/v2/__tests__/skill-qdrant.test.ts +0 -657
  423. package/src/memory/v2/skill-qdrant.ts +0 -404
  424. package/src/signals/bash.ts +0 -198
@@ -12,20 +12,37 @@ export interface MemoryV2ConceptRowRecord {
12
12
  simUser: number;
13
13
  simAssistant: number;
14
14
  simNow: number;
15
+ /**
16
+ * Cross-encoder rerank delta in raw rerank space (`alpha · r_norm_u`)
17
+ * for the user channel. Zero when rerank is disabled or the slug fell
18
+ * outside the unified top-K-by-pre-rerank-A_o window. Applied
19
+ * additively to A_o weighted by `c_user` — `simUser` itself is the
20
+ * raw fused score and never carries the boost. Stored as a JSON field,
21
+ * so older log rows pre-date this addition and decode with `undefined`;
22
+ * readers should fall back to 0.
23
+ */
24
+ simUserRerankBoost: number;
25
+ /**
26
+ * Cross-encoder rerank delta for the assistant channel. Same semantics
27
+ * as `simUserRerankBoost`, weighted by `c_assistant` when applied to
28
+ * A_o. The NOW channel intentionally bypasses rerank, so there is no
29
+ * `simNowRerankBoost`.
30
+ */
31
+ simAssistantRerankBoost: number;
32
+ /**
33
+ * True when rerank ran and this slug landed in the unified
34
+ * top-K-by-pre-rerank-A_o pool. Distinguishes "cross-encoder evaluated
35
+ * this and chose 0" from "rerank skipped this slug" so the inspector
36
+ * can keep the rerank rows visible at `+0.000` instead of silently
37
+ * dropping them. Older log rows pre-date this field and decode with
38
+ * `undefined`; readers should fall back to `false`.
39
+ */
40
+ inRerankPool: boolean;
15
41
  spreadContribution: number;
16
42
  source: "prior_state" | "ann_top50" | "both";
17
43
  status: "in_context" | "injected" | "not_injected" | "page_missing";
18
44
  }
19
45
 
20
- export interface MemoryV2SkillRowRecord {
21
- id: string;
22
- activation: number;
23
- simUser: number;
24
- simAssistant: number;
25
- simNow: number;
26
- status: "injected" | "not_injected";
27
- }
28
-
29
46
  export interface MemoryV2ConfigSnapshot {
30
47
  d: number;
31
48
  c_user: number;
@@ -34,7 +51,6 @@ export interface MemoryV2ConfigSnapshot {
34
51
  k: number;
35
52
  hops: number;
36
53
  top_k: number;
37
- top_k_skills: number;
38
54
  epsilon: number;
39
55
  }
40
56
 
@@ -43,7 +59,6 @@ export interface RecordMemoryV2ActivationLogParams {
43
59
  turn: number;
44
60
  mode: "context-load" | "per-turn";
45
61
  concepts: MemoryV2ConceptRowRecord[];
46
- skills: MemoryV2SkillRowRecord[];
47
62
  config: MemoryV2ConfigSnapshot;
48
63
  }
49
64
 
@@ -51,6 +66,11 @@ export function recordMemoryV2ActivationLog(
51
66
  params: RecordMemoryV2ActivationLogParams,
52
67
  ): void {
53
68
  const db = getDb();
69
+ // Skills now live as concept rows under `slug: "skills/<id>"`, so the
70
+ // separate `skills_json` column is always written empty. The column itself
71
+ // remains in the schema for backwards-compat with prior log rows; the
72
+ // reader drops it. A future migration can DROP the column once those rows
73
+ // age out of relevance.
54
74
  db.insert(memoryV2ActivationLogs)
55
75
  .values({
56
76
  id: uuid(),
@@ -59,7 +79,7 @@ export function recordMemoryV2ActivationLog(
59
79
  turn: params.turn,
60
80
  mode: params.mode,
61
81
  conceptsJson: JSON.stringify(params.concepts),
62
- skillsJson: JSON.stringify(params.skills),
82
+ skillsJson: "[]",
63
83
  configJson: JSON.stringify(params.config),
64
84
  createdAt: Date.now(),
65
85
  })
@@ -87,7 +107,6 @@ export interface MemoryV2ActivationLog {
87
107
  turn: number;
88
108
  mode: "context-load" | "per-turn";
89
109
  concepts: MemoryV2ConceptRowRecord[];
90
- skills: MemoryV2SkillRowRecord[];
91
110
  config: MemoryV2ConfigSnapshot;
92
111
  }
93
112
 
@@ -109,7 +128,6 @@ export function getMemoryV2ActivationLogByMessageIds(
109
128
  turn: row.turn,
110
129
  mode: row.mode as "context-load" | "per-turn",
111
130
  concepts: JSON.parse(row.conceptsJson) as MemoryV2ConceptRowRecord[],
112
- skills: JSON.parse(row.skillsJson) as MemoryV2SkillRowRecord[],
113
131
  config: JSON.parse(row.configJson) as MemoryV2ConfigSnapshot,
114
132
  };
115
133
  }
@@ -0,0 +1,169 @@
1
+ import type { MemoryV2ConceptRowRecord } from "./memory-v2-activation-log-store.js";
2
+ import { rawAll, rawGet } from "./raw-query.js";
3
+ import { listPages } from "./v2/page-store.js";
4
+
5
+ type ConceptStatus = MemoryV2ConceptRowRecord["status"];
6
+
7
+ export type ConceptFrequencyCounts = Record<ConceptStatus, number>;
8
+
9
+ export interface ConceptFrequencyRow {
10
+ slug: string;
11
+ counts: ConceptFrequencyCounts;
12
+ totalEvaluations: number;
13
+ lastInjectedAt: number | null;
14
+ /** Whether the slug currently has a markdown page on disk. */
15
+ onDisk: boolean;
16
+ }
17
+
18
+ export interface ConceptFrequencyResponse {
19
+ filters: {
20
+ conversationId: string | null;
21
+ sinceMs: number | null;
22
+ };
23
+ totals: {
24
+ /** Activation log rows scanned (turns of evaluation in the window). */
25
+ logCount: number;
26
+ /** Sum of per-row concept evaluations across all log rows in the window. */
27
+ conceptOccurrences: number;
28
+ };
29
+ /** Per-slug aggregates, sorted by `totalEvaluations` desc, then slug asc. */
30
+ concepts: ConceptFrequencyRow[];
31
+ /**
32
+ * Slugs present on disk that never appeared in any activation log row in
33
+ * the window — i.e. retrieval never even scored them as a candidate.
34
+ */
35
+ neverEvaluatedSlugs: string[];
36
+ }
37
+
38
+ export interface GetConceptFrequencyFilters {
39
+ conversationId?: string;
40
+ sinceMs?: number;
41
+ }
42
+
43
+ interface AggRow {
44
+ slug: string | null;
45
+ status: ConceptStatus | string | null;
46
+ count: number;
47
+ last_seen: number;
48
+ }
49
+
50
+ const ZERO_COUNTS: ConceptFrequencyCounts = {
51
+ injected: 0,
52
+ in_context: 0,
53
+ not_injected: 0,
54
+ page_missing: 0,
55
+ };
56
+
57
+ interface CountRow {
58
+ count: number;
59
+ }
60
+
61
+ export async function getConceptFrequencySummary(
62
+ workspaceDir: string,
63
+ filters: GetConceptFrequencyFilters = {},
64
+ ): Promise<ConceptFrequencyResponse> {
65
+ const conversationId = filters.conversationId ?? null;
66
+ const sinceMs = filters.sinceMs ?? null;
67
+
68
+ // Kick off the on-disk page walk in parallel with the (synchronous) SQL
69
+ // queries below — listPages does fs.readdir, rawAll/rawGet are sync.
70
+ const onDiskSlugsPromise = listPages(workspaceDir);
71
+
72
+ const aggRows = rawAll<AggRow>(
73
+ `SELECT
74
+ json_extract(c.value, '$.slug') AS slug,
75
+ json_extract(c.value, '$.status') AS status,
76
+ COUNT(*) AS count,
77
+ MAX(l.created_at) AS last_seen
78
+ FROM memory_v2_activation_logs l, json_each(l.concepts_json) c
79
+ WHERE (? IS NULL OR l.conversation_id = ?)
80
+ AND (? IS NULL OR l.created_at >= ?)
81
+ GROUP BY slug, status`,
82
+ conversationId,
83
+ conversationId,
84
+ sinceMs,
85
+ sinceMs,
86
+ );
87
+
88
+ const logCountRow = rawGet<CountRow>(
89
+ `SELECT COUNT(*) AS count
90
+ FROM memory_v2_activation_logs
91
+ WHERE (? IS NULL OR conversation_id = ?)
92
+ AND (? IS NULL OR created_at >= ?)`,
93
+ conversationId,
94
+ conversationId,
95
+ sinceMs,
96
+ sinceMs,
97
+ );
98
+
99
+ const bySlug = new Map<string, ConceptFrequencyRow>();
100
+ let conceptOccurrences = 0;
101
+
102
+ for (const row of aggRows) {
103
+ if (!row.slug) continue;
104
+ let entry = bySlug.get(row.slug);
105
+ if (!entry) {
106
+ entry = {
107
+ slug: row.slug,
108
+ counts: { ...ZERO_COUNTS },
109
+ totalEvaluations: 0,
110
+ lastInjectedAt: null,
111
+ onDisk: false,
112
+ };
113
+ bySlug.set(row.slug, entry);
114
+ }
115
+
116
+ switch (row.status) {
117
+ case "injected":
118
+ entry.counts.injected += row.count;
119
+ entry.lastInjectedAt =
120
+ entry.lastInjectedAt === null
121
+ ? row.last_seen
122
+ : Math.max(entry.lastInjectedAt, row.last_seen);
123
+ break;
124
+ case "in_context":
125
+ entry.counts.in_context += row.count;
126
+ break;
127
+ case "not_injected":
128
+ entry.counts.not_injected += row.count;
129
+ break;
130
+ case "page_missing":
131
+ entry.counts.page_missing += row.count;
132
+ break;
133
+ default:
134
+ // Forward-compat: unknown status values are ignored, not summed into
135
+ // totalEvaluations. The activation pipeline produces a closed enum.
136
+ continue;
137
+ }
138
+ entry.totalEvaluations += row.count;
139
+ conceptOccurrences += row.count;
140
+ }
141
+
142
+ const onDiskSlugs = new Set(await onDiskSlugsPromise);
143
+ for (const entry of bySlug.values()) {
144
+ entry.onDisk = onDiskSlugs.has(entry.slug);
145
+ }
146
+
147
+ const neverEvaluatedSlugs: string[] = [];
148
+ for (const slug of onDiskSlugs) {
149
+ if (!bySlug.has(slug)) neverEvaluatedSlugs.push(slug);
150
+ }
151
+ neverEvaluatedSlugs.sort();
152
+
153
+ const concepts = [...bySlug.values()].sort((a, b) => {
154
+ if (b.totalEvaluations !== a.totalEvaluations) {
155
+ return b.totalEvaluations - a.totalEvaluations;
156
+ }
157
+ return a.slug.localeCompare(b.slug);
158
+ });
159
+
160
+ return {
161
+ filters: { conversationId, sinceMs },
162
+ totals: {
163
+ logCount: logCountRow?.count ?? 0,
164
+ conceptOccurrences,
165
+ },
166
+ concepts,
167
+ neverEvaluatedSlugs,
168
+ };
169
+ }
@@ -0,0 +1,18 @@
1
+ import type { DrizzleDb } from "../db-connection.js";
2
+ import { getSqliteFrom } from "../db-connection.js";
3
+ import { withCrashRecovery } from "./validate-migration-state.js";
4
+
5
+ const CHECKPOINT_KEY = "migration_trace_events_created_at_index_v1";
6
+
7
+ /**
8
+ * Add an index on `trace_events.created_at` so the periodic prune job
9
+ * can locate expired rows without a full table scan.
10
+ */
11
+ export function migrateTraceEventsCreatedAtIndex(database: DrizzleDb): void {
12
+ withCrashRecovery(database, CHECKPOINT_KEY, () => {
13
+ const raw = getSqliteFrom(database);
14
+ raw.exec(
15
+ `CREATE INDEX IF NOT EXISTS idx_trace_events_created_at ON trace_events(created_at)`,
16
+ );
17
+ });
18
+ }
@@ -200,6 +200,7 @@ export {
200
200
  migrateHeartbeatRuns,
201
201
  } from "./237-heartbeat-runs.js";
202
202
  export { migrateScheduleRetryPolicy } from "./238-schedule-retry-policy.js";
203
+ export { migrateTraceEventsCreatedAtIndex } from "./239-trace-events-created-at-index.js";
203
204
  export {
204
205
  MIGRATION_REGISTRY,
205
206
  type MigrationRegistryEntry,
@@ -2,6 +2,13 @@ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  import { makeMockLogger } from "../../__tests__/helpers/mock-logger.js";
4
4
 
5
+ // This test exercises the v1 PKB search path. `config.memory.v2.enabled`
6
+ // (default `true`) makes pkb-search short-circuit to keep traffic off the
7
+ // legacy collection — force it off so the v1 path stays under test.
8
+ mock.module("../../config/loader.js", () => ({
9
+ getConfig: () => ({ memory: { v2: { enabled: false } } }),
10
+ }));
11
+
5
12
  mock.module("../../util/logger.js", () => ({
6
13
  getLogger: () => makeMockLogger(),
7
14
  }));
@@ -4,7 +4,6 @@
4
4
 
5
5
  import { getConfig } from "../../config/loader.js";
6
6
  import { getLogger } from "../../util/logger.js";
7
- import { isMemoryV2ReadActive } from "../context-search/sources/memory-v2.js";
8
7
  import {
9
8
  isQdrantBreakerOpen,
10
9
  withQdrantBreaker,
@@ -42,10 +41,10 @@ export async function searchPkbFiles(
42
41
  limit: number,
43
42
  scopeIds?: string[],
44
43
  ): Promise<PkbSearchResult[]> {
45
- // v2 owns the read path when both gates are on; v2 absorbs PKB as a read
46
- // source, so PKB hint search short-circuits to keep traffic off the v1
47
- // collection (avoiding OOM-crash risk from a corrupted sparse segment).
48
- if (isMemoryV2ReadActive(getConfig())) return [];
44
+ // v2 owns the read path when enabled; v2 absorbs PKB as a read source,
45
+ // so PKB hint search short-circuits to keep traffic off the v1 collection
46
+ // (avoiding OOM-crash risk from a corrupted sparse segment).
47
+ if (getConfig().memory.v2.enabled) return [];
49
48
 
50
49
  if (isQdrantBreakerOpen()) {
51
50
  log.warn("Qdrant circuit breaker open, skipping PKB search");
@@ -248,6 +248,9 @@ export class VellumQdrantClient {
248
248
  m: 16,
249
249
  ef_construct: 100,
250
250
  },
251
+ optimizers_config: {
252
+ default_segment_number: 2,
253
+ },
251
254
  quantization_config:
252
255
  this.quantization === "scalar"
253
256
  ? {
@@ -388,7 +391,6 @@ export class VellumQdrantClient {
388
391
  limit: number,
389
392
  targetTypes: Array<"segment" | "item" | "summary" | "media">,
390
393
  excludeMessageIds?: string[],
391
- scopeIds?: string[],
392
394
  ): Promise<QdrantSearchResult[]> {
393
395
  const mustConditions: Array<Record<string, unknown>> = [
394
396
  {
@@ -415,18 +417,6 @@ export class VellumQdrantClient {
415
417
  });
416
418
  }
417
419
 
418
- // Scope filtering: accept points whose memory_scope_id matches one of the
419
- // allowed scopes, OR points that lack the field entirely (legacy data).
420
- // Post-query DB filtering remains as defense-in-depth for legacy points.
421
- if (scopeIds && scopeIds.length > 0) {
422
- mustConditions.push({
423
- should: [
424
- { key: "memory_scope_id", match: { any: scopeIds } },
425
- { is_empty: { key: "memory_scope_id" } },
426
- ],
427
- });
428
- }
429
-
430
420
  const mustNotConditions: Array<Record<string, unknown>> = [
431
421
  { key: "_meta", match: { value: true } },
432
422
  ];