@vellumai/assistant 0.4.48 → 0.4.50

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 (423) hide show
  1. package/ARCHITECTURE.md +26 -35
  2. package/README.md +5 -26
  3. package/docs/architecture/integrations.md +45 -41
  4. package/docs/architecture/keychain-broker.md +3 -3
  5. package/docs/architecture/memory.md +180 -119
  6. package/docs/runbook-trusted-contacts.md +3 -8
  7. package/hook-templates/debug-prompt-logger/hook.json +1 -1
  8. package/hook-templates/debug-prompt-logger/run.sh +1 -3
  9. package/package.json +2 -2
  10. package/src/__tests__/actor-token-service.test.ts +0 -1
  11. package/src/__tests__/agent-loop.test.ts +3 -1
  12. package/src/__tests__/anthropic-provider.test.ts +249 -2
  13. package/src/__tests__/approval-cascade.test.ts +796 -0
  14. package/src/__tests__/approval-primitive.test.ts +0 -1
  15. package/src/__tests__/approval-routes-http.test.ts +4 -0
  16. package/src/__tests__/assistant-attachments.test.ts +12 -34
  17. package/src/__tests__/assistant-feature-flag-guard.test.ts +0 -23
  18. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +76 -0
  19. package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -1
  20. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
  21. package/src/__tests__/canonical-guardian-store.test.ts +95 -0
  22. package/src/__tests__/channel-guardian.test.ts +0 -2
  23. package/src/__tests__/channel-readiness-routes.test.ts +15 -6
  24. package/src/__tests__/channel-readiness-service.test.ts +10 -9
  25. package/src/__tests__/checker.test.ts +13 -20
  26. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
  27. package/src/__tests__/computer-use-tools.test.ts +2 -19
  28. package/src/__tests__/config-schema.test.ts +1 -68
  29. package/src/__tests__/config-watcher.test.ts +0 -1
  30. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  31. package/src/__tests__/context-image-dimensions.test.ts +332 -0
  32. package/src/__tests__/context-memory-e2e.test.ts +11 -100
  33. package/src/__tests__/context-token-estimator.test.ts +196 -13
  34. package/src/__tests__/conversation-attention-store.test.ts +0 -1
  35. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  36. package/src/__tests__/conversation-routes-guardian-reply.test.ts +152 -0
  37. package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -0
  38. package/src/__tests__/credential-metadata-store.test.ts +64 -73
  39. package/src/__tests__/credential-security-e2e.test.ts +1 -0
  40. package/src/__tests__/credential-security-invariants.test.ts +13 -7
  41. package/src/__tests__/credential-vault-unit.test.ts +284 -49
  42. package/src/__tests__/credential-vault.test.ts +150 -16
  43. package/src/__tests__/credentials-cli.test.ts +71 -0
  44. package/src/__tests__/cu-unified-flow.test.ts +532 -0
  45. package/src/__tests__/date-context.test.ts +93 -77
  46. package/src/__tests__/deterministic-verification-control-plane.test.ts +64 -0
  47. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
  48. package/src/__tests__/ephemeral-permissions.test.ts +3 -3
  49. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  50. package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
  51. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
  52. package/src/__tests__/guardian-routing-invariants.test.ts +93 -1
  53. package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
  54. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -39
  55. package/src/__tests__/heartbeat-service.test.ts +0 -1
  56. package/src/__tests__/history-repair.test.ts +245 -0
  57. package/src/__tests__/host-cu-proxy.test.ts +791 -0
  58. package/src/__tests__/host-shell-tool.test.ts +27 -15
  59. package/src/__tests__/http-user-message-parity.test.ts +2 -0
  60. package/src/__tests__/ingress-url-consistency.test.ts +14 -21
  61. package/src/__tests__/integration-status.test.ts +32 -51
  62. package/src/__tests__/intent-routing.test.ts +0 -1
  63. package/src/__tests__/invite-redemption-service.test.ts +65 -1
  64. package/src/__tests__/invite-routes-http.test.ts +10 -9
  65. package/src/__tests__/keychain-broker-client.test.ts +14 -46
  66. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +56 -18
  67. package/src/__tests__/memory-lifecycle-e2e.test.ts +244 -387
  68. package/src/__tests__/memory-recall-quality.test.ts +244 -407
  69. package/src/__tests__/memory-regressions.experimental.test.ts +126 -101
  70. package/src/__tests__/memory-regressions.test.ts +477 -2841
  71. package/src/__tests__/memory-retrieval.benchmark.test.ts +33 -150
  72. package/src/__tests__/memory-upsert-concurrency.test.ts +5 -244
  73. package/src/__tests__/mime-builder.test.ts +28 -0
  74. package/src/__tests__/native-web-search.test.ts +1 -0
  75. package/src/__tests__/notification-routing-intent.test.ts +0 -1
  76. package/src/__tests__/oauth-cli.test.ts +941 -15
  77. package/src/__tests__/oauth-provider-profiles.test.ts +9 -9
  78. package/src/__tests__/oauth-scope-policy.test.ts +4 -6
  79. package/src/__tests__/oauth-store.test.ts +870 -0
  80. package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
  81. package/src/__tests__/provider-error-scenarios.test.ts +0 -1
  82. package/src/__tests__/provider-streaming.benchmark.test.ts +0 -1
  83. package/src/__tests__/public-ingress-urls.test.ts +15 -21
  84. package/src/__tests__/qdrant-collection-migration.test.ts +53 -8
  85. package/src/__tests__/recording-handler.test.ts +3 -4
  86. package/src/__tests__/registry.test.ts +2 -3
  87. package/src/__tests__/relay-server.test.ts +46 -1
  88. package/src/__tests__/runtime-events-sse.test.ts +55 -7
  89. package/src/__tests__/schedule-store.test.ts +0 -1
  90. package/src/__tests__/schedule-tools.test.ts +32 -0
  91. package/src/__tests__/scheduler-recurrence.test.ts +0 -1
  92. package/src/__tests__/scoped-approval-grants.test.ts +0 -1
  93. package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
  94. package/src/__tests__/script-proxy-certs.test.ts +1 -1
  95. package/src/__tests__/secret-ingress-handler.test.ts +0 -1
  96. package/src/__tests__/secret-onetime-send.test.ts +1 -0
  97. package/src/__tests__/secure-keys.test.ts +7 -2
  98. package/src/__tests__/send-endpoint-busy.test.ts +24 -6
  99. package/src/__tests__/sequence-store.test.ts +0 -1
  100. package/src/__tests__/session-abort-tool-results.test.ts +1 -14
  101. package/src/__tests__/session-agent-loop-overflow.test.ts +1583 -0
  102. package/src/__tests__/session-agent-loop.test.ts +19 -15
  103. package/src/__tests__/session-confirmation-signals.test.ts +1 -15
  104. package/src/__tests__/session-error.test.ts +124 -2
  105. package/src/__tests__/session-history-web-search.test.ts +918 -0
  106. package/src/__tests__/session-init.benchmark.test.ts +4 -5
  107. package/src/__tests__/session-pre-run-repair.test.ts +1 -14
  108. package/src/__tests__/session-provider-retry-repair.test.ts +25 -28
  109. package/src/__tests__/session-queue.test.ts +37 -27
  110. package/src/__tests__/session-runtime-assembly.test.ts +54 -0
  111. package/src/__tests__/session-slash-known.test.ts +1 -15
  112. package/src/__tests__/session-slash-queue.test.ts +1 -15
  113. package/src/__tests__/session-slash-unknown.test.ts +1 -15
  114. package/src/__tests__/session-workspace-cache-state.test.ts +3 -33
  115. package/src/__tests__/session-workspace-injection.test.ts +3 -37
  116. package/src/__tests__/session-workspace-tool-tracking.test.ts +3 -37
  117. package/src/__tests__/skill-include-graph.test.ts +66 -0
  118. package/src/__tests__/skill-load-feature-flag.test.ts +0 -1
  119. package/src/__tests__/skill-load-tool.test.ts +149 -1
  120. package/src/__tests__/skill-projection-feature-flag.test.ts +0 -1
  121. package/src/__tests__/skills-install-extract.test.ts +93 -0
  122. package/src/__tests__/skills-uninstall.test.ts +1 -1
  123. package/src/__tests__/skills.test.ts +3 -3
  124. package/src/__tests__/skillssh-registry.test.ts +451 -0
  125. package/src/__tests__/slack-channel-config.test.ts +67 -3
  126. package/src/__tests__/slack-share-routes.test.ts +17 -19
  127. package/src/__tests__/system-prompt.test.ts +0 -1
  128. package/src/__tests__/telegram-invite-adapter.test.ts +18 -22
  129. package/src/__tests__/terminal-tools.test.ts +4 -3
  130. package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
  131. package/src/__tests__/tool-approval-handler.test.ts +0 -1
  132. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
  133. package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
  134. package/src/__tests__/tool-executor-shell-integration.test.ts +0 -1
  135. package/src/__tests__/tool-executor.test.ts +0 -1
  136. package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
  137. package/src/__tests__/trust-store-pattern-matches.test.ts +29 -0
  138. package/src/__tests__/trust-store.test.ts +7 -13
  139. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  140. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
  141. package/src/__tests__/twilio-routes.test.ts +0 -16
  142. package/src/__tests__/verification-control-plane-policy.test.ts +0 -1
  143. package/src/__tests__/voice-invite-redemption.test.ts +32 -1
  144. package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
  145. package/src/agent/ax-tree-compaction.test.ts +286 -0
  146. package/src/agent/loop.ts +104 -131
  147. package/src/approvals/AGENTS.md +1 -1
  148. package/src/approvals/guardian-request-resolvers.ts +14 -2
  149. package/src/bundler/compiler-tools.ts +66 -2
  150. package/src/calls/call-domain.ts +133 -6
  151. package/src/calls/call-store.ts +6 -0
  152. package/src/calls/relay-server.ts +52 -18
  153. package/src/calls/relay-setup-router.ts +17 -1
  154. package/src/calls/twilio-config.ts +3 -8
  155. package/src/calls/twilio-routes.ts +1 -2
  156. package/src/calls/types.ts +3 -1
  157. package/src/calls/voice-ingress-preflight.ts +1 -1
  158. package/src/cli/commands/browser-relay.ts +18 -12
  159. package/src/cli/commands/completions.ts +0 -3
  160. package/src/cli/commands/credentials.ts +101 -15
  161. package/src/cli/commands/doctor.ts +4 -3
  162. package/src/cli/commands/mcp.ts +46 -59
  163. package/src/cli/commands/memory.ts +16 -165
  164. package/src/cli/commands/oauth/apps.ts +284 -0
  165. package/src/cli/commands/oauth/connections.ts +633 -0
  166. package/src/cli/commands/oauth/index.ts +52 -0
  167. package/src/cli/commands/oauth/providers.ts +256 -0
  168. package/src/cli/commands/sessions.ts +5 -2
  169. package/src/cli/commands/skills.ts +177 -339
  170. package/src/cli/http-client.ts +0 -20
  171. package/src/cli/main-screen.tsx +2 -2
  172. package/src/cli/program.ts +6 -11
  173. package/src/cli/reference.ts +1 -3
  174. package/src/cli.ts +4 -10
  175. package/src/config/assistant-feature-flags.ts +0 -3
  176. package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
  177. package/src/config/bundled-skills/computer-use/SKILL.md +3 -6
  178. package/src/config/bundled-skills/computer-use/TOOLS.json +23 -5
  179. package/src/config/bundled-skills/computer-use/tools/{computer-use-request-control.ts → computer-use-observe.ts} +1 -5
  180. package/src/config/bundled-skills/google-calendar/calendar-client.ts +21 -16
  181. package/src/config/bundled-skills/messaging/tools/shared.ts +1 -4
  182. package/src/config/bundled-skills/settings/SKILL.md +1 -1
  183. package/src/config/bundled-skills/settings/TOOLS.json +2 -8
  184. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +5 -33
  185. package/src/config/bundled-tool-registry.ts +2 -5
  186. package/src/config/env-registry.ts +14 -83
  187. package/src/config/env.ts +11 -50
  188. package/src/config/feature-flag-registry.json +16 -16
  189. package/src/config/loader.ts +0 -6
  190. package/src/config/schema.ts +4 -13
  191. package/src/config/schemas/memory-lifecycle.ts +0 -9
  192. package/src/config/schemas/memory-processing.ts +0 -180
  193. package/src/config/schemas/memory-retrieval.ts +32 -104
  194. package/src/config/schemas/memory.ts +0 -10
  195. package/src/config/skills.ts +21 -2
  196. package/src/config/types.ts +0 -4
  197. package/src/context/image-dimensions.ts +229 -0
  198. package/src/context/token-estimator.ts +75 -12
  199. package/src/context/window-manager.ts +53 -11
  200. package/src/daemon/assistant-attachments.ts +1 -13
  201. package/src/daemon/config-watcher.ts +61 -3
  202. package/src/daemon/daemon-control.ts +1 -1
  203. package/src/daemon/date-context.ts +114 -31
  204. package/src/daemon/handlers/config-ingress.ts +8 -33
  205. package/src/daemon/handlers/config-slack-channel.ts +49 -46
  206. package/src/daemon/handlers/config-telegram.ts +32 -16
  207. package/src/daemon/handlers/sessions.ts +27 -36
  208. package/src/daemon/handlers/shared.ts +0 -130
  209. package/src/daemon/handlers/skills.ts +20 -1
  210. package/src/daemon/history-repair.ts +72 -8
  211. package/src/daemon/host-cu-proxy.ts +430 -0
  212. package/src/daemon/lifecycle.ts +67 -71
  213. package/src/daemon/mcp-reload-service.ts +2 -2
  214. package/src/daemon/message-protocol.ts +3 -0
  215. package/src/daemon/message-types/computer-use.ts +1 -129
  216. package/src/daemon/message-types/host-cu.ts +19 -0
  217. package/src/daemon/message-types/memory.ts +4 -16
  218. package/src/daemon/message-types/messages.ts +4 -0
  219. package/src/daemon/message-types/sessions.ts +4 -0
  220. package/src/daemon/server.ts +25 -21
  221. package/src/daemon/session-agent-loop-handlers.ts +40 -0
  222. package/src/daemon/session-agent-loop.ts +334 -48
  223. package/src/daemon/session-attachments.ts +1 -2
  224. package/src/daemon/session-error.ts +89 -6
  225. package/src/daemon/session-history.ts +17 -7
  226. package/src/daemon/session-media-retry.ts +6 -2
  227. package/src/daemon/session-memory.ts +69 -149
  228. package/src/daemon/session-process.ts +10 -1
  229. package/src/daemon/session-runtime-assembly.ts +49 -19
  230. package/src/daemon/session-slash.ts +1 -1
  231. package/src/daemon/session-surfaces.ts +43 -28
  232. package/src/daemon/session-tool-setup.ts +9 -10
  233. package/src/daemon/session.ts +150 -17
  234. package/src/daemon/tool-side-effects.ts +2 -8
  235. package/src/daemon/watch-handler.ts +2 -2
  236. package/src/events/tool-metrics-listener.ts +2 -2
  237. package/src/hooks/manager.ts +1 -4
  238. package/src/inbound/public-ingress-urls.ts +7 -7
  239. package/src/instrument.ts +61 -1
  240. package/src/logfire.ts +16 -5
  241. package/src/memory/admin.ts +2 -191
  242. package/src/memory/canonical-guardian-store.ts +38 -2
  243. package/src/memory/conversation-crud.ts +0 -33
  244. package/src/memory/conversation-key-store.ts +21 -0
  245. package/src/memory/conversation-queries.ts +22 -3
  246. package/src/memory/db-init.ts +32 -0
  247. package/src/memory/embedding-backend.ts +84 -8
  248. package/src/memory/embedding-types.ts +9 -1
  249. package/src/memory/indexer.ts +7 -46
  250. package/src/memory/items-extractor.ts +274 -76
  251. package/src/memory/job-handlers/backfill.ts +2 -127
  252. package/src/memory/job-handlers/cleanup.ts +2 -16
  253. package/src/memory/job-handlers/extraction.ts +2 -138
  254. package/src/memory/job-handlers/index-maintenance.ts +1 -6
  255. package/src/memory/job-handlers/summarization.ts +3 -148
  256. package/src/memory/job-utils.ts +21 -59
  257. package/src/memory/jobs-store.ts +1 -159
  258. package/src/memory/jobs-worker.ts +9 -52
  259. package/src/memory/migrations/104-core-indexes.ts +3 -3
  260. package/src/memory/migrations/149-oauth-tables.ts +62 -0
  261. package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +98 -0
  262. package/src/memory/migrations/151-oauth-providers-ping-url.ts +11 -0
  263. package/src/memory/migrations/152-memory-item-supersession.ts +44 -0
  264. package/src/memory/migrations/153-drop-entity-tables.ts +15 -0
  265. package/src/memory/migrations/154-drop-fts.ts +20 -0
  266. package/src/memory/migrations/155-drop-conflicts.ts +7 -0
  267. package/src/memory/migrations/156-call-session-invite-metadata.ts +24 -0
  268. package/src/memory/migrations/index.ts +8 -0
  269. package/src/memory/qdrant-client.ts +148 -51
  270. package/src/memory/raw-query.ts +1 -1
  271. package/src/memory/retriever.test.ts +294 -273
  272. package/src/memory/retriever.ts +421 -645
  273. package/src/memory/schema/calls.ts +2 -0
  274. package/src/memory/schema/index.ts +1 -0
  275. package/src/memory/schema/memory-core.ts +3 -48
  276. package/src/memory/schema/oauth.ts +67 -0
  277. package/src/memory/search/formatting.ts +263 -176
  278. package/src/memory/search/lexical.ts +1 -254
  279. package/src/memory/search/ranking.ts +0 -455
  280. package/src/memory/search/semantic.ts +100 -14
  281. package/src/memory/search/staleness.ts +47 -0
  282. package/src/memory/search/tier-classifier.ts +21 -0
  283. package/src/memory/search/types.ts +15 -77
  284. package/src/memory/task-memory-cleanup.ts +4 -6
  285. package/src/messaging/provider.ts +4 -4
  286. package/src/messaging/providers/gmail/client.ts +82 -2
  287. package/src/messaging/providers/gmail/mime-builder.ts +17 -7
  288. package/src/messaging/providers/gmail/people-client.ts +10 -10
  289. package/src/messaging/providers/telegram-bot/adapter.ts +17 -17
  290. package/src/messaging/providers/whatsapp/adapter.ts +11 -8
  291. package/src/messaging/registry.ts +2 -32
  292. package/src/notifications/copy-composer.ts +0 -5
  293. package/src/notifications/signal.ts +4 -5
  294. package/src/oauth/byo-connection.test.ts +133 -25
  295. package/src/oauth/byo-connection.ts +22 -6
  296. package/src/oauth/connect-orchestrator.ts +113 -57
  297. package/src/oauth/connect-types.ts +17 -23
  298. package/src/oauth/connection-resolver.ts +35 -11
  299. package/src/oauth/connection.ts +1 -1
  300. package/src/oauth/manual-token-connection.ts +104 -0
  301. package/src/oauth/oauth-store.ts +582 -0
  302. package/src/oauth/platform-connection.test.ts +29 -0
  303. package/src/oauth/platform-connection.ts +6 -5
  304. package/src/oauth/provider-behaviors.ts +124 -0
  305. package/src/oauth/scope-policy.ts +9 -2
  306. package/src/oauth/seed-providers.ts +167 -0
  307. package/src/oauth/token-persistence.ts +81 -77
  308. package/src/permissions/checker.ts +3 -3
  309. package/src/permissions/defaults.ts +1 -1
  310. package/src/permissions/prompter.ts +10 -1
  311. package/src/permissions/trust-store.ts +36 -1
  312. package/src/playbooks/playbook-compiler.ts +1 -1
  313. package/src/prompts/__tests__/build-cli-reference-section.test.ts +3 -1
  314. package/src/prompts/system-prompt.ts +46 -42
  315. package/src/providers/anthropic/client.ts +59 -20
  316. package/src/providers/retry.ts +1 -27
  317. package/src/providers/types.ts +7 -1
  318. package/src/runtime/AGENTS.md +9 -0
  319. package/src/runtime/auth/route-policy.ts +6 -6
  320. package/src/runtime/channel-reply-delivery.ts +0 -40
  321. package/src/runtime/gateway-client.ts +0 -7
  322. package/src/runtime/guardian-reply-router.ts +24 -22
  323. package/src/runtime/http-server.ts +10 -8
  324. package/src/runtime/http-types.ts +2 -2
  325. package/src/runtime/invite-redemption-service.ts +19 -1
  326. package/src/runtime/invite-service.ts +25 -0
  327. package/src/runtime/middleware/twilio-validation.ts +1 -11
  328. package/src/runtime/pending-interactions.ts +14 -12
  329. package/src/runtime/routes/brain-graph-routes.ts +10 -90
  330. package/src/runtime/routes/channel-delivery-routes.ts +0 -1
  331. package/src/runtime/routes/conversation-routes.ts +81 -19
  332. package/src/runtime/routes/events-routes.ts +21 -11
  333. package/src/runtime/routes/host-cu-routes.ts +97 -0
  334. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +21 -12
  335. package/src/runtime/routes/inbound-stages/background-dispatch.ts +12 -111
  336. package/src/runtime/routes/integrations/slack/share.ts +6 -7
  337. package/src/runtime/routes/log-export-routes.ts +126 -8
  338. package/src/runtime/routes/memory-item-routes.test.ts +754 -0
  339. package/src/runtime/routes/memory-item-routes.ts +503 -0
  340. package/src/runtime/routes/session-management-routes.ts +3 -3
  341. package/src/runtime/routes/settings-routes.ts +55 -48
  342. package/src/runtime/routes/surface-action-routes.ts +1 -1
  343. package/src/runtime/routes/trust-rules-routes.ts +14 -0
  344. package/src/runtime/routes/watch-routes.ts +128 -0
  345. package/src/runtime/routes/workspace-routes.ts +2 -1
  346. package/src/schedule/integration-status.ts +10 -9
  347. package/src/security/credential-key.ts +0 -156
  348. package/src/security/keychain-broker-client.ts +22 -10
  349. package/src/security/oauth2.ts +1 -1
  350. package/src/security/secure-keys.ts +25 -3
  351. package/src/security/token-manager.ts +137 -64
  352. package/src/skills/catalog-install.ts +414 -0
  353. package/src/skills/include-graph.ts +32 -0
  354. package/src/skills/skillssh-registry.ts +503 -0
  355. package/src/telegram/bot-username.ts +2 -3
  356. package/src/tools/assets/search.ts +5 -1
  357. package/src/tools/browser/network-recorder.ts +1 -1
  358. package/src/tools/browser/network-recording-types.ts +1 -1
  359. package/src/tools/computer-use/definitions.ts +36 -11
  360. package/src/tools/computer-use/registry.ts +5 -6
  361. package/src/tools/credentials/broker.ts +1 -2
  362. package/src/tools/credentials/metadata-store.ts +17 -121
  363. package/src/tools/credentials/vault.ts +92 -167
  364. package/src/tools/memory/definitions.ts +4 -13
  365. package/src/tools/memory/handlers.test.ts +83 -103
  366. package/src/tools/memory/handlers.ts +50 -85
  367. package/src/tools/registry.ts +2 -7
  368. package/src/tools/schedule/create.ts +8 -1
  369. package/src/tools/schedule/update.ts +8 -1
  370. package/src/tools/skills/load.ts +85 -3
  371. package/src/tools/watch/watch-state.ts +0 -12
  372. package/src/util/logger.ts +7 -41
  373. package/src/util/platform.ts +9 -28
  374. package/src/watcher/providers/google-calendar.ts +2 -1
  375. package/src/__tests__/clarification-resolver.test.ts +0 -193
  376. package/src/__tests__/computer-use-session-compaction.test.ts +0 -143
  377. package/src/__tests__/computer-use-session-lifecycle.test.ts +0 -322
  378. package/src/__tests__/computer-use-session-working-dir.test.ts +0 -166
  379. package/src/__tests__/computer-use-skill-baseline.test.ts +0 -78
  380. package/src/__tests__/computer-use-skill-endstate.test.ts +0 -105
  381. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +0 -249
  382. package/src/__tests__/conflict-intent-tokenization.test.ts +0 -160
  383. package/src/__tests__/conflict-policy.test.ts +0 -269
  384. package/src/__tests__/conflict-store.test.ts +0 -372
  385. package/src/__tests__/contradiction-checker.test.ts +0 -361
  386. package/src/__tests__/entity-extractor.test.ts +0 -211
  387. package/src/__tests__/entity-search.test.ts +0 -1117
  388. package/src/__tests__/profile-compiler.test.ts +0 -392
  389. package/src/__tests__/ride-shotgun-handler.test.ts +0 -452
  390. package/src/__tests__/session-conflict-gate.test.ts +0 -1228
  391. package/src/__tests__/session-profile-injection.test.ts +0 -557
  392. package/src/cli/commands/dev.ts +0 -129
  393. package/src/cli/commands/map.ts +0 -391
  394. package/src/cli/commands/oauth.ts +0 -77
  395. package/src/config/bundled-skills/knowledge-graph/SKILL.md +0 -25
  396. package/src/config/bundled-skills/knowledge-graph/TOOLS.json +0 -66
  397. package/src/config/bundled-skills/knowledge-graph/tools/graph-query.ts +0 -211
  398. package/src/daemon/computer-use-session.ts +0 -1026
  399. package/src/daemon/ride-shotgun-handler.ts +0 -569
  400. package/src/daemon/session-conflict-gate.ts +0 -167
  401. package/src/daemon/session-dynamic-profile.ts +0 -77
  402. package/src/memory/clarification-resolver.ts +0 -417
  403. package/src/memory/conflict-intent.ts +0 -205
  404. package/src/memory/conflict-policy.ts +0 -127
  405. package/src/memory/conflict-store.ts +0 -410
  406. package/src/memory/contradiction-checker.ts +0 -508
  407. package/src/memory/entity-extractor.ts +0 -535
  408. package/src/memory/format-recall.ts +0 -47
  409. package/src/memory/fts-reconciler.ts +0 -165
  410. package/src/memory/job-handlers/conflict.ts +0 -200
  411. package/src/memory/profile-compiler.ts +0 -195
  412. package/src/memory/recall-cache.ts +0 -117
  413. package/src/memory/search/entity.ts +0 -535
  414. package/src/memory/search/query-expansion.test.ts +0 -70
  415. package/src/memory/search/query-expansion.ts +0 -118
  416. package/src/oauth/provider-base-urls.ts +0 -21
  417. package/src/oauth/provider-profiles.ts +0 -192
  418. package/src/prompts/computer-use-prompt.ts +0 -98
  419. package/src/runtime/routes/computer-use-routes.ts +0 -641
  420. package/src/runtime/routes/mcp-routes.ts +0 -20
  421. package/src/runtime/telegram-streaming-delivery.test.ts +0 -729
  422. package/src/runtime/telegram-streaming-delivery.ts +0 -393
  423. package/src/tools/computer-use/request-computer-control.ts +0 -56
@@ -1,5 +1,11 @@
1
1
  import type { Command } from "commander";
2
2
 
3
+ import {
4
+ disconnectOAuthProvider,
5
+ getConnectionByProvider,
6
+ listConnections,
7
+ type OAuthConnectionRow,
8
+ } from "../../oauth/oauth-store.js";
3
9
  import { credentialKey } from "../../security/credential-key.js";
4
10
  import {
5
11
  deleteSecureKeyAsync,
@@ -48,15 +54,45 @@ function scrubSecret(secret: string | undefined): string {
48
54
  return "****" + secret.slice(-4);
49
55
  }
50
56
 
57
+ /**
58
+ * Safely look up an OAuth connection for a credential service.
59
+ * Returns undefined when the oauth-store has no data or the tables
60
+ * haven't been created yet (pre-migration).
61
+ */
62
+ function safeGetConnectionByProvider(
63
+ service: string,
64
+ ): OAuthConnectionRow | undefined {
65
+ try {
66
+ return getConnectionByProvider(service);
67
+ } catch {
68
+ return undefined;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Safely list all OAuth connections. Returns an empty array when the
74
+ * oauth-store has no data or the tables haven't been created yet.
75
+ */
76
+ function safeListConnections(): OAuthConnectionRow[] {
77
+ try {
78
+ return listConnections();
79
+ } catch {
80
+ return [];
81
+ }
82
+ }
83
+
51
84
  /**
52
85
  * Build a structured credential output object suitable for both `inspect`
53
86
  * and `list` responses. Produces an identical shape for every credential.
87
+ * Optionally enriches with data from the oauth-store when a matching
88
+ * connection exists.
54
89
  */
55
90
  function buildCredentialOutput(
56
91
  metadata: CredentialMetadata,
57
92
  secret: string | undefined,
93
+ connection?: OAuthConnectionRow,
58
94
  ): Record<string, unknown> {
59
- return {
95
+ const output: Record<string, unknown> = {
60
96
  ok: true,
61
97
  service: metadata.service,
62
98
  field: metadata.field,
@@ -67,14 +103,24 @@ function buildCredentialOutput(
67
103
  usageDescription: metadata.usageDescription ?? null,
68
104
  allowedTools: metadata.allowedTools,
69
105
  allowedDomains: metadata.allowedDomains,
70
- grantedScopes: metadata.grantedScopes ?? null,
71
- expiresAt: metadata.expiresAt
72
- ? new Date(metadata.expiresAt).toISOString()
73
- : null,
74
106
  createdAt: new Date(metadata.createdAt).toISOString(),
75
107
  updatedAt: new Date(metadata.updatedAt).toISOString(),
76
108
  injectionTemplateCount: metadata.injectionTemplates?.length ?? 0,
109
+ grantedScopes: connection ? JSON.parse(connection.grantedScopes) : null,
110
+ expiresAt: connection?.expiresAt
111
+ ? new Date(connection.expiresAt).toISOString()
112
+ : null,
77
113
  };
114
+
115
+ if (connection) {
116
+ output.oauthConnectionId = connection.id;
117
+ output.oauthAccountInfo = connection.accountInfo ?? null;
118
+ output.oauthStatus = connection.status;
119
+ output.oauthHasRefreshToken = connection.hasRefreshToken === 1;
120
+ output.oauthLabel = connection.label ?? null;
121
+ }
122
+
123
+ return output;
78
124
  }
79
125
 
80
126
  /**
@@ -101,15 +147,19 @@ function printCredentialHuman(output: Record<string, unknown>): void {
101
147
  log.info(
102
148
  ` Domains: ${(output.allowedDomains as string[]).join(", ")}`,
103
149
  );
104
- if (output.grantedScopes)
105
- log.info(
106
- ` Scopes: ${(output.grantedScopes as string[]).join(", ")}`,
107
- );
108
- if (output.expiresAt) log.info(` Expires: ${output.expiresAt}`);
109
150
  log.info(` Created: ${output.createdAt}`);
110
151
  log.info(` Updated: ${output.updatedAt}`);
111
152
  if ((output.injectionTemplateCount as number) > 0)
112
153
  log.info(` Templates: ${output.injectionTemplateCount}`);
154
+
155
+ // OAuth connection enrichment
156
+ if (output.oauthStatus) {
157
+ log.info(` OAuth: ${output.oauthStatus}`);
158
+ if (output.oauthAccountInfo)
159
+ log.info(` Account: ${output.oauthAccountInfo}`);
160
+ if (output.oauthLabel) log.info(` OAuth Label: ${output.oauthLabel}`);
161
+ log.info(` Refresh: ${output.oauthHasRefreshToken ? "yes" : "no"}`);
162
+ }
113
163
  }
114
164
 
115
165
  // ---------------------------------------------------------------------------
@@ -198,9 +248,24 @@ Examples:
198
248
  });
199
249
  }
200
250
 
251
+ // Build a lookup of oauth connections keyed by providerKey for enrichment.
252
+ // listConnections() returns rows in no guaranteed order, so we compare
253
+ // createdAt to keep the most recent active connection per provider —
254
+ // matching the behaviour of getConnectionByProvider() used by inspect.
255
+ const allConnections = safeListConnections();
256
+ const connectionsByProvider = new Map<string, OAuthConnectionRow>();
257
+ for (const conn of allConnections) {
258
+ if (conn.status !== "active") continue;
259
+ const existing = connectionsByProvider.get(conn.providerKey);
260
+ if (!existing || conn.createdAt > existing.createdAt) {
261
+ connectionsByProvider.set(conn.providerKey, conn);
262
+ }
263
+ }
264
+
201
265
  const credentials = allMetadata.map((m) => {
202
266
  const secret = getSecureKey(credentialKey(m.service, m.field));
203
- return buildCredentialOutput(m, secret);
267
+ const connection = connectionsByProvider.get(m.service);
268
+ return buildCredentialOutput(m, secret, connection);
204
269
  });
205
270
 
206
271
  writeOutput(cmd, { ok: true, credentials });
@@ -367,7 +432,29 @@ Examples:
367
432
 
368
433
  const metadataDeleted = deleteCredentialMetadata(service, field);
369
434
 
370
- if (secretResult !== "deleted" && !metadataDeleted) {
435
+ // Also clean up the OAuth connection and new-format secure keys.
436
+ // disconnectOAuthProvider is a no-op when no connection exists.
437
+ let oauthResult: "disconnected" | "not-found" | "error" = "not-found";
438
+ try {
439
+ oauthResult = await disconnectOAuthProvider(service);
440
+ } catch {
441
+ // Best-effort — OAuth tables may not exist yet
442
+ }
443
+
444
+ if (oauthResult === "error") {
445
+ writeOutput(cmd, {
446
+ ok: false,
447
+ error: "Failed to disconnect OAuth provider — please try again",
448
+ });
449
+ process.exitCode = 1;
450
+ return;
451
+ }
452
+
453
+ if (
454
+ secretResult !== "deleted" &&
455
+ !metadataDeleted &&
456
+ oauthResult !== "disconnected"
457
+ ) {
371
458
  writeOutput(cmd, { ok: false, error: "Credential not found" });
372
459
  process.exitCode = 1;
373
460
  return;
@@ -464,8 +551,6 @@ Examples:
464
551
  usageDescription: null,
465
552
  allowedTools: [],
466
553
  allowedDomains: [],
467
- grantedScopes: null,
468
- expiresAt: null,
469
554
  createdAt: null,
470
555
  updatedAt: null,
471
556
  injectionTemplateCount: 0,
@@ -479,7 +564,8 @@ Examples:
479
564
  return;
480
565
  }
481
566
 
482
- const output = buildCredentialOutput(metadata, secret);
567
+ const connection = safeGetConnectionByProvider(metadata.service);
568
+ const output = buildCredentialOutput(metadata, secret, connection);
483
569
  writeOutput(cmd, output);
484
570
 
485
571
  if (!shouldOutputJson(cmd)) {
@@ -3,8 +3,10 @@ import { existsSync, readFileSync, statSync } from "node:fs";
3
3
 
4
4
  import type { Command } from "commander";
5
5
 
6
+ import { getRuntimeHttpPort } from "../../config/env.js";
6
7
  import { loadRawConfig } from "../../config/loader.js";
7
8
  import { shouldAutoStartDaemon } from "../../daemon/connection-policy.js";
9
+ import { isHttpHealthy } from "../../daemon/daemon-control.js";
8
10
  import {
9
11
  getDbPath,
10
12
  getLogPath,
@@ -13,7 +15,6 @@ import {
13
15
  getWorkspaceHooksDir,
14
16
  getWorkspaceSkillsDir,
15
17
  } from "../../util/platform.js";
16
- import { getHttpBaseUrl, httpHealthCheck } from "../http-client.js";
17
18
  import { log } from "../logger.js";
18
19
 
19
20
  export function registerDoctorCommand(program: Command): void {
@@ -57,7 +58,7 @@ Examples:
57
58
  log.info("Vellum Doctor\n");
58
59
 
59
60
  // 0. Connection policy info
60
- const httpUrl = getHttpBaseUrl();
61
+ const httpUrl = `http://127.0.0.1:${getRuntimeHttpPort()}`;
61
62
  const autostart = shouldAutoStartDaemon();
62
63
  log.info(` HTTP: ${httpUrl}`);
63
64
  log.info(` Autostart: ${autostart ? "enabled" : "disabled"}\n`);
@@ -103,7 +104,7 @@ Examples:
103
104
 
104
105
  // 3. Daemon reachable (HTTP health check)
105
106
  try {
106
- const healthy = await httpHealthCheck(2000);
107
+ const healthy = await isHttpHealthy();
107
108
  if (healthy) {
108
109
  pass("Assistant reachable");
109
110
  } else {
@@ -1,3 +1,6 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+
1
4
  import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
2
5
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
6
  import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
@@ -11,7 +14,7 @@ import {
11
14
  deleteMcpOAuthCredentials,
12
15
  McpOAuthProvider,
13
16
  } from "../../mcp/mcp-oauth-provider.js";
14
- import { httpSend } from "../http-client.js";
17
+ import { getWorkspaceDir } from "../../util/platform.js";
15
18
  import { log } from "../logger.js";
16
19
 
17
20
  export const HEALTH_CHECK_TIMEOUT_MS = 10_000;
@@ -51,6 +54,21 @@ export async function checkServerHealth(
51
54
  }
52
55
  }
53
56
 
57
+ /**
58
+ * Write a signal file so the daemon's ConfigWatcher triggers an MCP reload.
59
+ * Used by `mcp reload`, `mcp auth`, and any operation that needs the daemon
60
+ * to reconnect MCP servers.
61
+ */
62
+ function signalMcpReload(): void {
63
+ try {
64
+ const signalsDir = join(getWorkspaceDir(), "signals");
65
+ mkdirSync(signalsDir, { recursive: true });
66
+ writeFileSync(join(signalsDir, "mcp-reload"), "");
67
+ } catch {
68
+ // Best-effort — the daemon may not be running or the directory may not exist.
69
+ }
70
+ }
71
+
54
72
  export function registerMcpCommand(program: Command): void {
55
73
  const mcp = program
56
74
  .command("mcp")
@@ -67,8 +85,8 @@ server uses one of three transport types:
67
85
  sse Remote server using Server-Sent Events
68
86
  streamable-http Remote server using Streamable HTTP transport
69
87
 
70
- After changing MCP server configuration, run 'vellum mcp reload' to apply
71
- changes without restarting the assistant.
88
+ MCP server configuration changes are detected automatically by the running
89
+ assistant. You can also run 'vellum mcp reload' to trigger a manual reload.
72
90
 
73
91
  Examples:
74
92
  $ assistant mcp list
@@ -251,61 +269,20 @@ Examples:
251
269
  .addHelpText(
252
270
  "after",
253
271
  `
254
- Sends a message to the running assistant to disconnect and reconnect all MCP
255
- servers using the current configuration from disk. Active sessions pick up
256
- new tools on their next turn automatically. The assistant must be running.
272
+ Signals the running assistant to disconnect and reconnect all MCP servers
273
+ using the current configuration from disk. Active sessions pick up new tools
274
+ on their next turn automatically. The assistant must be running.
257
275
 
258
276
  Examples:
259
277
  $ vellum mcp reload
260
278
  $ vellum mcp reload # after editing config.json to add a new server
261
279
  $ vellum mcp reload # after running "vellum mcp auth <server>"`,
262
280
  )
263
- .action(async () => {
264
- log.info("Sending reload request to assistant...");
265
- try {
266
- const res = await httpSend("/v1/mcp/reload", { method: "POST" });
267
- const response = (await res.json()) as {
268
- success: boolean;
269
- serverCount?: number;
270
- toolCount?: number;
271
- servers?: {
272
- id: string;
273
- connected: boolean;
274
- disabled?: boolean;
275
- toolCount: number;
276
- tools: string[];
277
- }[];
278
- error?: string;
279
- };
280
- if (response.success) {
281
- log.info(
282
- `MCP servers reloaded: ${response.serverCount} server(s), ${response.toolCount} tool(s)\n`,
283
- );
284
- if (response.servers && response.servers.length > 0) {
285
- for (const server of response.servers) {
286
- const status = server.disabled
287
- ? "⊘ Disabled"
288
- : server.connected
289
- ? "\u2713 Connected"
290
- : "\u2717 Not connected";
291
- log.info(` ${server.id}`);
292
- log.info(` Status: ${status}`);
293
- log.info(
294
- ` Tools: ${server.toolCount > 0 ? server.tools.join(", ") : "(none)"}`,
295
- );
296
- log.info("");
297
- }
298
- }
299
- } else {
300
- log.error(`Failed to reload: ${response.error}`);
301
- process.exitCode = 1;
302
- }
303
- } catch (err) {
304
- log.error(
305
- `Failed to send reload request: ${err instanceof Error ? err.message : err}`,
306
- );
307
- process.exitCode = 1;
308
- }
281
+ .action(() => {
282
+ signalMcpReload();
283
+ log.info(
284
+ "MCP reload signal sent. The running assistant will reconnect servers shortly.",
285
+ );
309
286
  });
310
287
 
311
288
  mcp
@@ -422,7 +399,10 @@ Examples:
422
399
 
423
400
  saveRawConfig(raw);
424
401
  log.info(`Added MCP server "${name}" (${opts.transportType})`);
425
- log.info("Run 'vellum mcp reload' to apply changes.");
402
+ log.info(
403
+ "The running assistant will pick up this change automatically. " +
404
+ "Or run 'vellum mcp reload' to apply now.",
405
+ );
426
406
  },
427
407
  );
428
408
 
@@ -444,8 +424,8 @@ OAuth flow. If the server already has valid cached tokens, the command succeeds
444
424
  immediately without opening a browser. Tokens are cached locally for future use
445
425
  by the assistant.
446
426
 
447
- After successful authentication, run 'vellum mcp reload' to apply changes
448
- without restarting the assistant.
427
+ After successful authentication, the running assistant detects the change
428
+ automatically. You can also run 'vellum mcp reload' to apply immediately.
449
429
 
450
430
  Examples:
451
431
  $ assistant mcp auth my-server
@@ -603,7 +583,11 @@ Examples:
603
583
  provider.stopCallbackServer();
604
584
 
605
585
  log.info(`Authentication successful for "${name}".`);
606
- log.info("Run 'vellum mcp reload' to apply changes.");
586
+ log.info(
587
+ "The running assistant will pick up this change automatically. " +
588
+ "Or run 'vellum mcp reload' to apply now.",
589
+ );
590
+ signalMcpReload();
607
591
  process.exit(0);
608
592
  });
609
593
 
@@ -621,8 +605,8 @@ any stored OAuth credentials (tokens, client info, discovery metadata) for
621
605
  sse/streamable-http servers. If no OAuth credentials exist, the cleanup is
622
606
  silently skipped.
623
607
 
624
- After removal, run 'vellum mcp reload' to apply changes without restarting
625
- the assistant.
608
+ After removal, the running assistant detects the change automatically. You
609
+ can also run 'vellum mcp reload' to apply immediately.
626
610
 
627
611
  Examples:
628
612
  $ assistant mcp remove my-server
@@ -655,6 +639,9 @@ Examples:
655
639
  delete servers[name];
656
640
  saveRawConfig(raw);
657
641
  log.info(`Removed MCP server "${name}".`);
658
- log.info("Run 'vellum mcp reload' to apply changes.");
642
+ log.info(
643
+ "The running assistant will pick up this change automatically. " +
644
+ "Or run 'vellum mcp reload' to apply now.",
645
+ );
659
646
  });
660
647
  }
@@ -1,21 +1,16 @@
1
1
  import type { Command } from "commander";
2
2
 
3
3
  import {
4
- dismissPendingConflicts,
5
4
  getMemorySystemStatus,
6
5
  queryMemory,
7
6
  requestMemoryBackfill,
8
7
  requestMemoryCleanup,
9
8
  requestMemoryRebuildIndex,
10
9
  } from "../../memory/admin.js";
11
- import { listPendingConflictDetails } from "../../memory/conflict-store.js";
12
10
  import { listConversations } from "../../memory/conversation-queries.js";
13
- import { rawGet } from "../../memory/db.js";
14
11
  import { initializeDb } from "../db.js";
15
12
  import { log } from "../logger.js";
16
13
 
17
- const SHORT_HASH_LENGTH = 8;
18
-
19
14
  export function registerMemoryCommand(program: Command): void {
20
15
  const memory = program
21
16
  .command("memory")
@@ -24,23 +19,20 @@ export function registerMemoryCommand(program: Command): void {
24
19
  memory.addHelpText(
25
20
  "after",
26
21
  `
27
- The memory subsystem indexes conversation segments into full-text search (FTS)
28
- and vector embeddings for semantic recall. When the assistant encounters new
29
- information that contradicts a stored fact, a conflict is created and held in
30
- "pending_clarification" status until explicitly dismissed or resolved.
22
+ The memory subsystem indexes conversation segments using hybrid search (dense
23
+ and sparse vector embeddings) for semantic recall, with tier classification
24
+ to prioritize high-value memories.
31
25
 
32
26
  Key concepts:
33
27
  segments Chunks of conversation text extracted for indexing
34
28
  items Distilled facts/statements derived from segments
35
29
  summaries Compressed representations of conversation history
36
30
  embeddings Vector representations used for semantic similarity search
37
- conflicts Pairs of contradictory statements awaiting resolution
38
31
 
39
32
  Examples:
40
33
  $ assistant memory status
41
34
  $ assistant memory query "What is the project deadline?"
42
- $ assistant memory backfill
43
- $ assistant memory dismiss-conflicts --all`,
35
+ $ assistant memory backfill`,
44
36
  );
45
37
 
46
38
  memory
@@ -59,10 +51,7 @@ Fields shown:
59
51
  items Total distilled fact items stored
60
52
  summaries Total compressed conversation summaries
61
53
  embeddings Total vector embeddings computed
62
- pending conflicts Conflicts awaiting user resolution
63
- resolved conflicts Conflicts that have been dismissed or resolved
64
- oldest pending age How long the oldest unresolved conflict has been waiting
65
- cleanup backlogs Number of resolved conflicts and superseded items pending cleanup
54
+ cleanup backlogs Number of superseded items pending cleanup
66
55
  cleanup throughput Number of cleanup operations completed in the last 24 hours
67
56
  jobs Status of background jobs (backfill, cleanup, rebuild-index)
68
57
 
@@ -84,29 +73,9 @@ Examples:
84
73
  log.info(`Items: ${status.counts.items.toLocaleString()}`);
85
74
  log.info(`Summaries: ${status.counts.summaries.toLocaleString()}`);
86
75
  log.info(`Embeddings: ${status.counts.embeddings.toLocaleString()}`);
87
- log.info(
88
- `Pending conflicts: ${status.conflicts.pending.toLocaleString()}`,
89
- );
90
- log.info(
91
- `Resolved conflicts: ${status.conflicts.resolved.toLocaleString()}`,
92
- );
93
- if (status.conflicts.oldestPendingAgeMs != null) {
94
- const oldestMinutes = Math.floor(
95
- status.conflicts.oldestPendingAgeMs / 60_000,
96
- );
97
- log.info(`Oldest pending conflict age: ${oldestMinutes} min`);
98
- } else {
99
- log.info("Oldest pending conflict age: n/a");
100
- }
101
- log.info(
102
- `Cleanup backlog (resolved conflicts): ${status.cleanup.resolvedBacklog.toLocaleString()}`,
103
- );
104
76
  log.info(
105
77
  `Cleanup backlog (superseded items): ${status.cleanup.supersededBacklog.toLocaleString()}`,
106
78
  );
107
- log.info(
108
- `Cleanup throughput 24h (resolved conflicts): ${status.cleanup.resolvedCompleted24h.toLocaleString()}`,
109
- );
110
79
  log.info(
111
80
  `Cleanup throughput 24h (superseded items): ${status.cleanup.supersededCompleted24h.toLocaleString()}`,
112
81
  );
@@ -123,8 +92,8 @@ Examples:
123
92
  .addHelpText(
124
93
  "after",
125
94
  `
126
- Queues a background job to index unprocessed conversation segments into FTS
127
- and vector embeddings. The job resumes from where the last backfill left off,
95
+ Queues a background job to index unprocessed conversation segments into
96
+ vector embeddings. The job resumes from where the last backfill left off,
128
97
  processing only new or unindexed segments.
129
98
 
130
99
  The --force flag restarts the backfill from the very beginning, reprocessing
@@ -144,7 +113,7 @@ Examples:
144
113
  memory
145
114
  .command("cleanup")
146
115
  .description(
147
- "Queue cleanup jobs for resolved conflicts and stale superseded items",
116
+ "Queue cleanup jobs for stale superseded items",
148
117
  )
149
118
  .option(
150
119
  "--retention-ms <ms>",
@@ -153,11 +122,8 @@ Examples:
153
122
  .addHelpText(
154
123
  "after",
155
124
  `
156
- Queues two background cleanup jobs:
157
- 1. Resolved conflicts cleanup removes conflict records that have been
158
- dismissed or resolved past the retention threshold.
159
- 2. Stale superseded items cleanup — removes memory items that have been
160
- superseded by newer, corrected facts past the retention threshold.
125
+ Queues a background cleanup job to remove memory items that have been
126
+ superseded by newer, corrected facts past the retention threshold.
161
127
 
162
128
  The optional --retention-ms flag sets the minimum age (in milliseconds) a
163
129
  record must have before it is eligible for cleanup. If omitted, the system
@@ -175,9 +141,6 @@ Examples:
175
141
  const jobs = requestMemoryCleanup(
176
142
  Number.isFinite(retentionMs) ? retentionMs : undefined,
177
143
  );
178
- log.info(
179
- `Queued cleanup_resolved_conflicts job: ${jobs.resolvedConflictsJobId}`,
180
- );
181
144
  log.info(
182
145
  `Queued cleanup_stale_superseded_items job: ${jobs.staleSupersededItemsJobId}`,
183
146
  );
@@ -195,8 +158,8 @@ Examples:
195
158
  Arguments:
196
159
  text The recall query string used to search memory (e.g. "What is the
197
160
  project deadline?"). Matched against indexed segments using the full
198
- recall pipeline: lexical (FTS), semantic (vector similarity), recency
199
- (time-weighted), and entity (named entity extraction).
161
+ recall pipeline: semantic (dense + sparse vector similarity) and recency
162
+ (time-weighted).
200
163
 
201
164
  Runs the complete memory recall pipeline and displays hit counts for each
202
165
  retrieval strategy, the total injected token count, query latency, and the
@@ -221,10 +184,8 @@ Examples:
221
184
  if (result.degraded) {
222
185
  log.info(`Memory degraded: ${result.reason ?? "unknown reason"}`);
223
186
  }
224
- log.info(`Lexical hits: ${result.lexicalHits}`);
225
187
  log.info(`Semantic hits: ${result.semanticHits}`);
226
188
  log.info(`Recency hits: ${result.recencyHits}`);
227
- log.info(`Entity hits: ${result.entityHits}`);
228
189
  log.info(`Injected tokens: ${result.injectedTokens}`);
229
190
  log.info(`Latency: ${result.latencyMs}ms`);
230
191
  if (result.injectedText.length > 0) {
@@ -237,13 +198,13 @@ Examples:
237
198
 
238
199
  memory
239
200
  .command("rebuild-index")
240
- .description("Queue a memory FTS+embedding index rebuild job")
201
+ .description("Queue a memory embedding index rebuild job")
241
202
  .addHelpText(
242
203
  "after",
243
204
  `
244
- Queues a background job that performs a full rebuild of both the FTS (full-text
245
- search) index and the vector embedding index. All existing index data is
246
- dropped and reconstructed from the source memory items.
205
+ Queues a background job that performs a full rebuild of the vector embedding
206
+ index. All existing index data is dropped and reconstructed from the source
207
+ memory items.
247
208
 
248
209
  This is useful after schema changes, embedding model upgrades, or if index
249
210
  corruption is suspected. The rebuild runs asynchronously; use "assistant memory
@@ -258,114 +219,4 @@ Examples:
258
219
  const jobId = requestMemoryRebuildIndex();
259
220
  log.info(`Queued rebuild-index job: ${jobId}`);
260
221
  });
261
-
262
- memory
263
- .command("dismiss-conflicts")
264
- .description("Dismiss pending memory conflicts (all or matching a pattern)")
265
- .option("-a, --all", "Dismiss all pending conflicts")
266
- .option(
267
- "-p, --pattern <regex>",
268
- "Dismiss conflicts where either statement matches this regex",
269
- )
270
- .option("-s, --scope <id>", 'Memory scope (default: "default")')
271
- .option("--dry-run", "Show what would be dismissed without making changes")
272
- .addHelpText(
273
- "after",
274
- `
275
- Two modes of operation:
276
- --all Dismiss every pending conflict in the scope
277
- --pattern <regex> Dismiss only conflicts where either the existing or
278
- candidate statement matches the given regex (case-insensitive)
279
-
280
- At least one of --all or --pattern must be provided. If both are given,
281
- --all takes priority and all pending conflicts are dismissed.
282
-
283
- The --scope flag targets a specific memory scope. Defaults to "default" if
284
- omitted. The --dry-run flag previews which conflicts would be dismissed
285
- without actually modifying any records.
286
-
287
- Examples:
288
- $ assistant memory dismiss-conflicts --all
289
- $ assistant memory dismiss-conflicts --pattern "project deadline" --dry-run
290
- $ assistant memory dismiss-conflicts --pattern "^preferred\\b" --scope work`,
291
- )
292
- .action(
293
- (opts: {
294
- all?: boolean;
295
- pattern?: string;
296
- scope?: string;
297
- dryRun?: boolean;
298
- }) => {
299
- if (!opts.all && !opts.pattern) {
300
- log.info("At least one of --all or --pattern must be provided.");
301
- log.info("Use --dry-run to preview without making changes.");
302
- return;
303
- }
304
-
305
- initializeDb();
306
-
307
- const pattern = opts.pattern
308
- ? new RegExp(opts.pattern, "i")
309
- : undefined;
310
-
311
- if (opts.dryRun) {
312
- const scopeId = opts.scope ?? "default";
313
- const totalPending =
314
- rawGet<{ c: number }>(
315
- `SELECT COUNT(*) AS c FROM memory_item_conflicts WHERE scope_id = ? AND status = 'pending_clarification'`,
316
- scopeId,
317
- )?.c ?? 0;
318
-
319
- // Show a sample of conflicts (can't paginate without dismissing)
320
- const sample = listPendingConflictDetails(scopeId, 1000);
321
- let matchCount = 0;
322
- for (const conflict of sample) {
323
- const matches =
324
- opts.all ||
325
- (pattern &&
326
- (pattern.test(conflict.existingStatement) ||
327
- pattern.test(conflict.candidateStatement)));
328
- if (!matches) continue;
329
- matchCount++;
330
- log.info(
331
- ` [${conflict.id.slice(0, SHORT_HASH_LENGTH)}] "${
332
- conflict.existingStatement
333
- }" vs "${conflict.candidateStatement}"`,
334
- );
335
- }
336
-
337
- if (opts.all) {
338
- // --all matches everything, so matchCount is just the sample size
339
- log.info(
340
- `\nDry run: ${totalPending} of ${totalPending} pending conflicts would be dismissed.`,
341
- );
342
- } else {
343
- const moreNote =
344
- totalPending > sample.length
345
- ? ` (showing first ${sample.length} of ${totalPending})`
346
- : "";
347
- log.info(
348
- `\nDry run: ${matchCount} of ${totalPending} pending conflicts would be dismissed.${moreNote}`,
349
- );
350
- }
351
- return;
352
- }
353
-
354
- const result = dismissPendingConflicts({
355
- all: opts.all,
356
- pattern,
357
- scopeId: opts.scope,
358
- });
359
- for (const detail of result.details) {
360
- log.info(
361
- ` Dismissed [${detail.id.slice(0, SHORT_HASH_LENGTH)}]: "${
362
- detail.existingStatement
363
- }" vs "${detail.candidateStatement}"`,
364
- );
365
- }
366
- log.info(
367
- `\nDismissed ${result.dismissed} conflicts. ${result.remaining} pending conflicts remain.`,
368
- );
369
- },
370
- );
371
222
  }