@vellumai/assistant 0.10.3 → 0.10.4-dev.202607010028.1a4efcc

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 (2236) hide show
  1. package/ARCHITECTURE.md +13 -13
  2. package/Dockerfile +5 -15
  3. package/bun.lock +165 -3
  4. package/docs/architecture/memory.md +26 -0
  5. package/eslint-rules/cli-no-daemon-internals.js +9 -8
  6. package/knip.json +0 -1
  7. package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +18 -0
  8. package/node_modules/@vellumai/service-contracts/src/__tests__/package-boundary.test.ts +1 -5
  9. package/openapi.yaml +1057 -88
  10. package/package.json +8 -3
  11. package/scripts/generate-openapi.ts +149 -62
  12. package/src/__tests__/acp-session.test.ts +2 -2
  13. package/src/__tests__/activation-early-marking.test.ts +4 -4
  14. package/src/__tests__/actor-token-service.test.ts +2 -3
  15. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +83 -31
  16. package/src/__tests__/agent-loop-compaction-events.test.ts +1 -0
  17. package/src/__tests__/agent-loop-compaction-strip.test.ts +2 -0
  18. package/src/__tests__/agent-loop-exit-reason.test.ts +4 -1
  19. package/src/__tests__/agent-loop-override-profile.test.ts +2 -2
  20. package/src/__tests__/agent-loop-regrowth-guard.test.ts +8 -0
  21. package/src/__tests__/agent-loop-set-system-prompt.test.ts +139 -0
  22. package/src/__tests__/agent-loop.test.ts +1 -0
  23. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +3 -3
  24. package/src/__tests__/agent-wake-override-profile.test.ts +3 -3
  25. package/src/__tests__/annotate-activity-metadata.test.ts +4 -4
  26. package/src/__tests__/annotate-risk-options.test.ts +4 -4
  27. package/src/__tests__/anthropic-provider.test.ts +53 -2
  28. package/src/__tests__/app-builder-tool-scripts.test.ts +2 -2
  29. package/src/__tests__/app-bundler.test.ts +1 -1
  30. package/src/__tests__/app-conversation-ids-backfill.test.ts +4 -4
  31. package/src/__tests__/app-conversation-ids.test.ts +1 -1
  32. package/src/__tests__/app-dir-path-guard.test.ts +2 -2
  33. package/src/__tests__/app-executors.test.ts +1 -1
  34. package/src/__tests__/app-git-history.test.ts +2 -2
  35. package/src/__tests__/app-git-service.test.ts +2 -2
  36. package/src/__tests__/app-routes-csp.test.ts +2 -2
  37. package/src/__tests__/app-source-watcher.test.ts +1 -1
  38. package/src/__tests__/app-store-dir-names.test.ts +1 -1
  39. package/src/__tests__/approval-cascade.test.ts +7 -7
  40. package/src/__tests__/approval-interception-trust-gates.test.ts +1 -1
  41. package/src/__tests__/approval-primitive.test.ts +3 -3
  42. package/src/__tests__/approval-routes-http.test.ts +2 -2
  43. package/src/__tests__/assistant-event-hub-machine-name.test.ts +1 -1
  44. package/src/__tests__/assistant-events-sse-hardening.test.ts +2 -2
  45. package/src/__tests__/assistant-events-sse-shed.test.ts +2 -2
  46. package/src/__tests__/assistant-stream-state.test.ts +3 -76
  47. package/src/__tests__/attachment-upload-trusted-source.test.ts +4 -2
  48. package/src/__tests__/attachments-store.test.ts +9 -6
  49. package/src/__tests__/audit-log-rotation.test.ts +6 -4
  50. package/src/__tests__/auth-fallback-events-store.test.ts +4 -4
  51. package/src/__tests__/auto-analysis-end-to-end.test.ts +13 -9
  52. package/src/__tests__/background-shell-bash.test.ts +34 -0
  53. package/src/__tests__/background-shell-host-bash.test.ts +12 -0
  54. package/src/__tests__/background-tool-registry.test.ts +97 -0
  55. package/src/__tests__/background-tool-routes.test.ts +72 -1
  56. package/src/__tests__/background-workers-disk-pressure.test.ts +17 -10
  57. package/src/__tests__/btw-routes.test.ts +4 -5
  58. package/src/__tests__/build-persisted-content.test.ts +4 -4
  59. package/src/__tests__/call-controller.test.ts +6 -6
  60. package/src/__tests__/call-conversation-messages.test.ts +4 -4
  61. package/src/__tests__/call-domain.test.ts +5 -5
  62. package/src/__tests__/call-pointer-messages.test.ts +5 -5
  63. package/src/__tests__/call-recovery.test.ts +3 -3
  64. package/src/__tests__/call-routes-http.test.ts +3 -3
  65. package/src/__tests__/call-store.test.ts +3 -3
  66. package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -3
  67. package/src/__tests__/canonical-guardian-store.test.ts +3 -3
  68. package/src/__tests__/channel-approval-routes.test.ts +30 -33
  69. package/src/__tests__/channel-delivery-store.test.ts +36 -8
  70. package/src/__tests__/channel-guardian.test.ts +62 -54
  71. package/src/__tests__/channel-inbound-disk-pressure.test.ts +15 -23
  72. package/src/__tests__/channel-reply-delivery.test.ts +8 -4
  73. package/src/__tests__/channel-retry-sweep.test.ts +49 -4
  74. package/src/__tests__/clawhub.test.ts +4 -0
  75. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +2 -2
  76. package/src/__tests__/compaction-events.test.ts +8 -8
  77. package/src/__tests__/compaction-ledger-store.test.ts +128 -0
  78. package/src/__tests__/compaction-trail-store.test.ts +5 -5
  79. package/src/__tests__/compaction.benchmark.test.ts +5 -5
  80. package/src/__tests__/compactor-call-site-logging.test.ts +5 -5
  81. package/src/__tests__/compactor-image-manifest-trust.test.ts +7 -4
  82. package/src/__tests__/compactor-low-watermark-cut.test.ts +5 -5
  83. package/src/__tests__/compactor-preserved-tail-count.test.ts +4 -4
  84. package/src/__tests__/compactor-summary-call-truncation.test.ts +5 -5
  85. package/src/__tests__/compactor-web-search-strip.test.ts +4 -4
  86. package/src/__tests__/config-get-vision-flag.test.ts +1 -1
  87. package/src/__tests__/config-loader-backfill.test.ts +230 -102
  88. package/src/__tests__/config-set-route.test.ts +5 -2
  89. package/src/__tests__/config-watcher-cleanup-throttle.test.ts +3 -3
  90. package/src/__tests__/config-watcher-skill-reseed.test.ts +39 -112
  91. package/src/__tests__/config-watcher.test.ts +54 -31
  92. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +4 -4
  93. package/src/__tests__/consult-deadline.test.ts +60 -0
  94. package/src/__tests__/contact-store-interaction-info.test.ts +156 -0
  95. package/src/__tests__/contact-store-user-file.test.ts +98 -91
  96. package/src/__tests__/contacts-relay-reads.test.ts +27 -12
  97. package/src/__tests__/contacts-tools.test.ts +2 -2
  98. package/src/__tests__/contacts-write.test.ts +2 -4
  99. package/src/__tests__/context-search-agent-protocol.test.ts +2 -2
  100. package/src/__tests__/context-search-agent-runner.test.ts +2 -2
  101. package/src/__tests__/context-search-conversations-source.test.ts +5 -5
  102. package/src/__tests__/context-search-fanout.test.ts +3 -3
  103. package/src/__tests__/context-search-memory-source.test.ts +9 -8
  104. package/src/__tests__/context-search-memory-v2-source.test.ts +9 -8
  105. package/src/__tests__/context-search-types.test.ts +2 -2
  106. package/src/__tests__/context-search-workspace-source.test.ts +2 -2
  107. package/src/__tests__/conversation-abort-tool-results.test.ts +5 -5
  108. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +4 -3
  109. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +40 -11
  110. package/src/__tests__/conversation-agent-loop-overflow.test.ts +11 -8
  111. package/src/__tests__/conversation-agent-loop.test.ts +150 -20
  112. package/src/__tests__/conversation-analysis-routes.test.ts +4 -4
  113. package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -1
  114. package/src/__tests__/conversation-app-control-lifecycle.test.ts +7 -7
  115. package/src/__tests__/conversation-attachments.test.ts +7 -4
  116. package/src/__tests__/conversation-attention-store.test.ts +4 -4
  117. package/src/__tests__/conversation-attention-telegram.test.ts +17 -16
  118. package/src/__tests__/conversation-clear-safety.test.ts +3 -4
  119. package/src/__tests__/conversation-confirmation-signals.test.ts +7 -7
  120. package/src/__tests__/conversation-crud-inference-profile.test.ts +3 -3
  121. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +25 -26
  122. package/src/__tests__/conversation-directories-parse.test.ts +1 -1
  123. package/src/__tests__/conversation-disk-view-integration.test.ts +5 -5
  124. package/src/__tests__/conversation-disk-view.test.ts +6 -6
  125. package/src/__tests__/conversation-error.test.ts +18 -18
  126. package/src/__tests__/conversation-evictor.test.ts +32 -7
  127. package/src/__tests__/conversation-fork-crud.test.ts +441 -44
  128. package/src/__tests__/conversation-fork-retrospective.test.ts +12 -10
  129. package/src/__tests__/conversation-fork-route.test.ts +6 -3
  130. package/src/__tests__/conversation-history-web-search.test.ts +8 -145
  131. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -3
  132. package/src/__tests__/conversation-inference-profile-route.test.ts +3 -3
  133. package/src/__tests__/conversation-init.benchmark.test.ts +1 -1
  134. package/src/__tests__/conversation-initial-prompt.test.ts +110 -0
  135. package/src/__tests__/conversation-key-store-disk-view.test.ts +7 -4
  136. package/src/__tests__/conversation-lifecycle.test.ts +10 -13
  137. package/src/__tests__/conversation-list-source.test.ts +3 -3
  138. package/src/__tests__/conversation-load-history-repair.test.ts +4 -4
  139. package/src/__tests__/conversation-load-history-stripped.test.ts +4 -4
  140. package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +191 -0
  141. package/src/__tests__/conversation-pairing.test.ts +4 -4
  142. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +5 -5
  143. package/src/__tests__/conversation-process-callsite.test.ts +42 -5
  144. package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -5
  145. package/src/__tests__/conversation-queue.test.ts +142 -9
  146. package/src/__tests__/conversation-routes-disk-view.test.ts +5 -5
  147. package/src/__tests__/conversation-routes-guardian-reply.test.ts +6 -6
  148. package/src/__tests__/conversation-routes-slash-commands.test.ts +57 -10
  149. package/src/__tests__/conversation-runtime-assembly.test.ts +25 -19
  150. package/src/__tests__/conversation-runtime-workspace.test.ts +8 -1
  151. package/src/__tests__/conversation-skill-tools.test.ts +155 -2
  152. package/src/__tests__/conversation-slash-queue.test.ts +6 -6
  153. package/src/__tests__/conversation-slash-unknown.test.ts +6 -6
  154. package/src/__tests__/conversation-speed-override.test.ts +7 -7
  155. package/src/__tests__/conversation-starter-routes.test.ts +2 -2
  156. package/src/__tests__/conversation-store.test.ts +6 -6
  157. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +8 -5
  158. package/src/__tests__/conversation-surfaces-data-persist.test.ts +2 -2
  159. package/src/__tests__/conversation-sync-tags.test.ts +7 -4
  160. package/src/__tests__/conversation-title-service.test.ts +223 -203
  161. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +1 -1
  162. package/src/__tests__/conversation-tool-setup-attribution.test.ts +1 -1
  163. package/src/__tests__/conversation-unread-route.test.ts +2 -2
  164. package/src/__tests__/conversation-usage.test.ts +6 -6
  165. package/src/__tests__/conversation-wipe.test.ts +6 -4
  166. package/src/__tests__/conversation-workspace-cache-state.test.ts +9 -9
  167. package/src/__tests__/conversation-workspace-injection.test.ts +9 -9
  168. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +9 -9
  169. package/src/__tests__/conversations-import-system-filter.test.ts +5 -5
  170. package/src/__tests__/credential-security-invariants.test.ts +4 -7
  171. package/src/__tests__/db-acp-history.test.ts +4 -4
  172. package/src/__tests__/db-activation-state-fk-cascade.test.ts +4 -4
  173. package/src/__tests__/db-activation-state.test.ts +3 -3
  174. package/src/__tests__/db-compaction-events-migration.test.ts +129 -0
  175. package/src/__tests__/db-connection-isolation.test.ts +1 -1
  176. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +3 -3
  177. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +6 -6
  178. package/src/__tests__/db-drop-contact-acl-columns-migration.test.ts +159 -0
  179. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +3 -3
  180. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +3 -3
  181. package/src/__tests__/db-migration-rollback.test.ts +48 -43
  182. package/src/__tests__/db-proxy-transaction.test.ts +2 -2
  183. package/src/__tests__/db-rename-inference-profile-snake-case-migration.test.ts +3 -3
  184. package/src/__tests__/db-schedule-syntax-migration.test.ts +4 -4
  185. package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +3 -3
  186. package/src/__tests__/db-slack-external-content-normalization.test.ts +4 -4
  187. package/src/__tests__/db-test-helpers.ts +7 -0
  188. package/src/__tests__/delete-propagation.test.ts +9 -7
  189. package/src/__tests__/deterministic-verification-control-plane.test.ts +3 -3
  190. package/src/__tests__/device-id.test.ts +38 -1
  191. package/src/__tests__/dm-backfill.test.ts +9 -7
  192. package/src/__tests__/dm-persistence.test.ts +5 -5
  193. package/src/__tests__/document-conversations.test.ts +3 -3
  194. package/src/__tests__/document-create-dedupe.test.ts +1 -1
  195. package/src/__tests__/document-find-replace.test.ts +1 -1
  196. package/src/__tests__/document-tool-security.test.ts +1 -1
  197. package/src/__tests__/document-update-default-surface.test.ts +1 -1
  198. package/src/__tests__/drop-capability-card-state-migration.test.ts +3 -5
  199. package/src/__tests__/edit-propagation.test.ts +6 -6
  200. package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
  201. package/src/__tests__/emit-signal-routing-intent.test.ts +2 -6
  202. package/src/__tests__/empty-state-greeting-cache.test.ts +1 -1
  203. package/src/__tests__/events-client-registration.test.ts +1 -1
  204. package/src/__tests__/exploration-drift-hook.test.ts +7 -23
  205. package/src/__tests__/file-write-tool.test.ts +3 -3
  206. package/src/__tests__/filing-service.test.ts +6 -5
  207. package/src/__tests__/followup-tools.test.ts +2 -2
  208. package/src/__tests__/get-skill-detail-audit.test.ts +1 -1
  209. package/src/__tests__/graph-extraction-event-date.test.ts +1 -1
  210. package/src/__tests__/guardian-action-sweep.test.ts +3 -3
  211. package/src/__tests__/guardian-binding-drift-heal.test.ts +48 -25
  212. package/src/__tests__/guardian-card-withdrawal.test.ts +3 -3
  213. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +4 -4
  214. package/src/__tests__/guardian-dispatch.test.ts +28 -11
  215. package/src/__tests__/guardian-expiry-notifier.test.ts +4 -4
  216. package/src/__tests__/guardian-outbound-http.test.ts +3 -4
  217. package/src/__tests__/guardian-principal-id-roundtrip.test.ts +3 -3
  218. package/src/__tests__/guardian-routing-invariants.test.ts +3 -3
  219. package/src/__tests__/guardian-routing-state.test.ts +12 -14
  220. package/src/__tests__/guardian-verification-voice-binding.test.ts +4 -4
  221. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +1 -1
  222. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +3 -3
  223. package/src/__tests__/heartbeat-disk-pressure.test.ts +7 -13
  224. package/src/__tests__/heartbeat-service.test.ts +31 -19
  225. package/src/__tests__/helpers/channel-test-adapter.ts +25 -18
  226. package/src/__tests__/helpers/create-guardian-binding.ts +16 -24
  227. package/src/__tests__/helpers/derive-guardian-delivery.ts +66 -0
  228. package/src/__tests__/helpers/gateway-acl-store.ts +81 -0
  229. package/src/__tests__/helpers/mock-logger.ts +1 -0
  230. package/src/__tests__/helpers/seed-contact-channel.ts +117 -0
  231. package/src/__tests__/history-repair-hook.test.ts +1 -1
  232. package/src/__tests__/home-state-routes.test.ts +1 -1
  233. package/src/__tests__/http-conversation-lineage.test.ts +4 -4
  234. package/src/__tests__/http-user-message-parity.test.ts +8 -12
  235. package/src/__tests__/identity-routes.test.ts +113 -25
  236. package/src/__tests__/image-recovery-hook.test.ts +3 -3
  237. package/src/__tests__/inbound-invite-redemption.test.ts +87 -12
  238. package/src/__tests__/inbound-slack-persistence.test.ts +5 -5
  239. package/src/__tests__/inbound-trust-verdict.test.ts +5 -4
  240. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +13 -6
  241. package/src/__tests__/inference-profile-reaper.test.ts +3 -3
  242. package/src/__tests__/inference-profile-session-handler.test.ts +3 -3
  243. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -3
  244. package/src/__tests__/init-feature-flag-overrides.test.ts +1 -4
  245. package/src/__tests__/injection-block.test.ts +5 -2
  246. package/src/__tests__/injector-background-turn.test.ts +3 -5
  247. package/src/__tests__/injector-chain.test.ts +25 -16
  248. package/src/__tests__/injector-config-quarantine-notice.test.ts +3 -5
  249. package/src/__tests__/injector-disk-pressure.test.ts +10 -8
  250. package/src/__tests__/injector-document-comments.test.ts +5 -3
  251. package/src/__tests__/injector-pkb-v2-silenced.test.ts +5 -2
  252. package/src/__tests__/injector-registry-order-guard.test.ts +132 -0
  253. package/src/__tests__/injector-v3-suppression.test.ts +15 -9
  254. package/src/__tests__/install-meta.test.ts +104 -0
  255. package/src/__tests__/install-skill-routing.test.ts +1 -1
  256. package/src/__tests__/internal-telemetry-routes.test.ts +4 -4
  257. package/src/__tests__/invite-redemption-service.test.ts +274 -57
  258. package/src/__tests__/invite-routes-http.test.ts +37 -3
  259. package/src/__tests__/invite-service-ipc.test.ts +68 -5
  260. package/src/__tests__/job-handler-registry-guard.test.ts +129 -0
  261. package/src/__tests__/jobs-store-qdrant-breaker.test.ts +8 -8
  262. package/src/__tests__/jobs-store-upsert-debounced.test.ts +7 -4
  263. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +9 -8
  264. package/src/__tests__/list-messages-attachments.test.ts +7 -4
  265. package/src/__tests__/list-messages-background-tool-completion.test.ts +141 -0
  266. package/src/__tests__/list-messages-client-message-id.test.ts +6 -3
  267. package/src/__tests__/list-messages-hidden-metadata.test.ts +5 -5
  268. package/src/__tests__/list-messages-page-latest.test.ts +176 -7
  269. package/src/__tests__/list-messages-queued.test.ts +223 -0
  270. package/src/__tests__/list-messages-tool-merge.test.ts +6 -3
  271. package/src/__tests__/llm-context-route-provider.test.ts +3 -3
  272. package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +4 -4
  273. package/src/__tests__/llm-request-log-call-site.test.ts +5 -5
  274. package/src/__tests__/llm-request-log-error-payload.test.ts +1 -1
  275. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +2 -1
  276. package/src/__tests__/llm-request-log-source-factory.test.ts +3 -3
  277. package/src/__tests__/llm-request-log-turn-query.test.ts +9 -6
  278. package/src/__tests__/llm-usage-store.test.ts +137 -3
  279. package/src/__tests__/log-export-routes.test.ts +3 -3
  280. package/src/__tests__/log-export-workspace.test.ts +3 -3
  281. package/src/__tests__/managed-profile-guard.test.ts +1 -1
  282. package/src/__tests__/managed-skill-lifecycle.test.ts +3 -3
  283. package/src/__tests__/managed-store.test.ts +381 -0
  284. package/src/__tests__/mcp-config-secret-boundary.test.ts +5 -1
  285. package/src/__tests__/media-stream-server-integration.test.ts +1 -1
  286. package/src/__tests__/memory-jobs-worker-backoff.test.ts +4 -4
  287. package/src/__tests__/memory-jobs-worker-lanes.test.ts +11 -9
  288. package/src/__tests__/memory-recall-log-store.test.ts +4 -4
  289. package/src/__tests__/memory-retrieval-budget.test.ts +1 -1
  290. package/src/__tests__/memory-retrieval-hook.test.ts +8 -8
  291. package/src/__tests__/memory-upsert-concurrency.test.ts +9 -5
  292. package/src/__tests__/memory-v2-static-injector.test.ts +3 -3
  293. package/src/__tests__/messages-after-tiebreaker.test.ts +4 -4
  294. package/src/__tests__/messaging-send-tool.test.ts +5 -5
  295. package/src/__tests__/mock-gateway-ipc.ts +1 -1
  296. package/src/__tests__/mtime-cache.test.ts +19 -0
  297. package/src/__tests__/native-web-search.test.ts +11 -11
  298. package/src/__tests__/non-member-access-request.test.ts +24 -20
  299. package/src/__tests__/notification-candidate-guardian-context.test.ts +4 -4
  300. package/src/__tests__/notification-deep-link.test.ts +3 -3
  301. package/src/__tests__/notification-guardian-path.test.ts +3 -3
  302. package/src/__tests__/notification-schedule-notify-dedup.test.ts +3 -3
  303. package/src/__tests__/oauth-provider-profiles.test.ts +1 -1
  304. package/src/__tests__/oauth-provider-visibility.test.ts +2 -2
  305. package/src/__tests__/oauth-store.test.ts +6 -6
  306. package/src/__tests__/onboarding-persona-write.test.ts +52 -22
  307. package/src/__tests__/onboarding-template-contract.test.ts +27 -43
  308. package/src/__tests__/openai-provider.test.ts +33 -0
  309. package/src/__tests__/openai-responses-provider.test.ts +40 -0
  310. package/src/__tests__/outbound-slack-persistence.test.ts +8 -8
  311. package/src/__tests__/persist-onboarding-artifacts.test.ts +1 -0
  312. package/src/__tests__/persist-unsendable-image-downscale.test.ts +3 -3
  313. package/src/__tests__/persist-unsendable-image.test.ts +3 -3
  314. package/src/__tests__/persist-user-message-set-processing-failure.test.ts +70 -0
  315. package/src/__tests__/persistence-layering-guard.test.ts +222 -0
  316. package/src/__tests__/persistence-secret-redaction.test.ts +6 -6
  317. package/src/__tests__/persona-resolver.test.ts +75 -45
  318. package/src/__tests__/pkb-autoinject.test.ts +1 -1
  319. package/src/__tests__/platform-bash-auto-approve.test.ts +3 -3
  320. package/src/__tests__/playbook-execution.test.ts +4 -4
  321. package/src/__tests__/playbook-tools.test.ts +3 -3
  322. package/src/__tests__/plugin-bootstrap.test.ts +78 -19
  323. package/src/__tests__/plugin-config-data-migration.test.ts +263 -0
  324. package/src/__tests__/plugin-disabled-state.test.ts +323 -0
  325. package/src/__tests__/plugin-event-hub-facade.test.ts +323 -0
  326. package/src/__tests__/plugin-import-boundary-guard.test.ts +506 -0
  327. package/src/__tests__/plugin-injector-contribution.test.ts +133 -0
  328. package/src/__tests__/plugin-route-contribution.test.ts +62 -115
  329. package/src/__tests__/plugin-tool-contribution.test.ts +0 -22
  330. package/src/__tests__/pointer-conversation-trust.test.ts +141 -0
  331. package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +8 -1
  332. package/src/__tests__/process-message-background-slack.test.ts +6 -6
  333. package/src/__tests__/process-message-display-content.test.ts +5 -5
  334. package/src/__tests__/processing-flag-persist-failure.test.ts +280 -0
  335. package/src/__tests__/provider-usage-tracking.test.ts +4 -4
  336. package/src/__tests__/prune-jobs-changes-parser.test.ts +1 -1
  337. package/src/__tests__/prune-old-conversations-job.test.ts +5 -5
  338. package/src/__tests__/prune-old-tool-invocations-job.test.ts +97 -0
  339. package/src/__tests__/published-app-updater.test.ts +3 -3
  340. package/src/__tests__/qdrant-collection-migration.test.ts +5 -2
  341. package/src/__tests__/qdrant-manager.test.ts +1 -1
  342. package/src/__tests__/reaction-intercept-cold-cache-warm.test.ts +141 -0
  343. package/src/__tests__/reaction-intercept-member-verdict-warm.test.ts +158 -0
  344. package/src/__tests__/reaction-persistence.test.ts +60 -10
  345. package/src/__tests__/rebuild-index-graph-nodes.test.ts +5 -5
  346. package/src/__tests__/recording-handler.test.ts +2 -2
  347. package/src/__tests__/relay-server.test.ts +183 -142
  348. package/src/__tests__/require-fresh-approval.test.ts +1 -1
  349. package/src/__tests__/resolve-app-id.test.ts +3 -3
  350. package/src/__tests__/runtime-attachment-metadata.test.ts +16 -18
  351. package/src/__tests__/runtime-events-sse-bilingual.test.ts +3 -3
  352. package/src/__tests__/runtime-events-sse-parity.test.ts +3 -3
  353. package/src/__tests__/runtime-events-sse-reconnect.test.ts +3 -3
  354. package/src/__tests__/runtime-events-sse.test.ts +3 -3
  355. package/src/__tests__/scaffold-managed-skill-tool.test.ts +489 -2
  356. package/src/__tests__/schedule-retry.test.ts +91 -67
  357. package/src/__tests__/schedule-routes-workflow-validation.test.ts +47 -43
  358. package/src/__tests__/schedule-routes.test.ts +199 -187
  359. package/src/__tests__/schedule-store.test.ts +174 -172
  360. package/src/__tests__/schedule-tools.test.ts +2 -2
  361. package/src/__tests__/scheduler-disk-pressure.test.ts +20 -9
  362. package/src/__tests__/scheduler-recurrence.test.ts +72 -122
  363. package/src/__tests__/scheduler-reuse-conversation.test.ts +65 -60
  364. package/src/__tests__/scheduler-wake.test.ts +21 -31
  365. package/src/__tests__/scoped-approval-grants.test.ts +4 -4
  366. package/src/__tests__/scoped-grant-security-matrix.test.ts +4 -4
  367. package/src/__tests__/scrub-corrupted-image-attachments.test.ts +2 -2
  368. package/src/__tests__/search-skills-unified.test.ts +1 -1
  369. package/src/__tests__/secret-ingress-channel.test.ts +3 -3
  370. package/src/__tests__/secret-ingress-http.test.ts +6 -6
  371. package/src/__tests__/secret-routes-platform-proxy.test.ts +9 -8
  372. package/src/__tests__/send-endpoint-busy.test.ts +6 -6
  373. package/src/__tests__/sequence-store.test.ts +3 -3
  374. package/src/__tests__/server-history-render.test.ts +7 -4
  375. package/src/__tests__/settings-routes.test.ts +34 -2
  376. package/src/__tests__/shell-observability.test.ts +1 -0
  377. package/src/__tests__/skill-boundary-guard.test.ts +3 -4
  378. package/src/__tests__/skill-docs-sync-guard.test.ts +34 -0
  379. package/src/__tests__/skill-projection-feature-flag.test.ts +2 -1
  380. package/src/__tests__/skill-projection.benchmark.test.ts +2 -1
  381. package/src/__tests__/skill-script-runner-host.test.ts +53 -0
  382. package/src/__tests__/skill-script-runner-sandbox.test.ts +5 -2
  383. package/src/__tests__/skill-tool-factory.test.ts +20 -0
  384. package/src/__tests__/skill-version-hash.test.ts +32 -0
  385. package/src/__tests__/skills-file-content-endpoint.test.ts +1 -1
  386. package/src/__tests__/skills-files-catalog-fallback.test.ts +1 -1
  387. package/src/__tests__/slack-inbound-verification.test.ts +2 -2
  388. package/src/__tests__/slack-messaging-token-resolution.test.ts +2 -2
  389. package/src/__tests__/slack-reaction-canonical-approval.test.ts +4 -4
  390. package/src/__tests__/slack-share-routes.test.ts +1 -1
  391. package/src/__tests__/slim-skill-category.test.ts +34 -2
  392. package/src/__tests__/sse-actor-principal-guardian-source.test.ts +13 -36
  393. package/src/__tests__/starter-task-flow.test.ts +1 -1
  394. package/src/__tests__/strip-memory-injections.test.ts +2 -2
  395. package/src/__tests__/stt-hints.test.ts +6 -3
  396. package/src/__tests__/subagent-allowlist-validation.test.ts +47 -0
  397. package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
  398. package/src/__tests__/subagent-detail.test.ts +1 -1
  399. package/src/__tests__/subagent-fork-notifications.test.ts +14 -2
  400. package/src/__tests__/subagent-fork-prompt-role.test.ts +195 -0
  401. package/src/__tests__/subagent-fork-spawn.test.ts +6 -7
  402. package/src/__tests__/subagent-notify-parent.test.ts +3 -3
  403. package/src/__tests__/subagent-persistence.test.ts +122 -0
  404. package/src/__tests__/subagent-role-registry.test.ts +17 -4
  405. package/src/__tests__/subagent-spawn-and-await.test.ts +546 -0
  406. package/src/__tests__/subagent-spawn-tool-fork.test.ts +3 -3
  407. package/src/__tests__/subagent-terminal-message.test.ts +99 -0
  408. package/src/__tests__/subagent-tool-gate-mode.test.ts +1 -1
  409. package/src/__tests__/subagent-tools.test.ts +396 -4
  410. package/src/__tests__/suggestion-routes.test.ts +4 -4
  411. package/src/__tests__/system-prompt.test.ts +4 -4
  412. package/src/__tests__/task-compiler.test.ts +2 -2
  413. package/src/__tests__/task-management-tools.test.ts +2 -2
  414. package/src/__tests__/task-memory-cleanup.test.ts +9 -7
  415. package/src/__tests__/task-progress-nudge-hook.test.ts +37 -94
  416. package/src/__tests__/task-scheduler.test.ts +94 -115
  417. package/src/__tests__/test-support/tool-invocation-seed.ts +5 -2
  418. package/src/__tests__/thread-backfill.test.ts +7 -7
  419. package/src/__tests__/title-generate-hook.test.ts +6 -6
  420. package/src/__tests__/tool-approval-handler.test.ts +4 -4
  421. package/src/__tests__/tool-audit-listener.test.ts +1 -1
  422. package/src/__tests__/tool-error-hook.test.ts +2 -0
  423. package/src/__tests__/tool-executor-lifecycle-events.test.ts +5 -5
  424. package/src/__tests__/tool-executor-redaction.test.ts +11 -0
  425. package/src/__tests__/tool-executor.test.ts +24 -2
  426. package/src/__tests__/tool-grant-request-escalation.test.ts +5 -5
  427. package/src/__tests__/tool-preview-lifecycle.test.ts +102 -17
  428. package/src/__tests__/tool-result-metadata-plumbing.test.ts +4 -4
  429. package/src/__tests__/tool-result-truncate-hook.test.ts +2 -0
  430. package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -1
  431. package/src/__tests__/tool-start-timestamp.test.ts +69 -5
  432. package/src/__tests__/tools-get-route.test.ts +44 -1
  433. package/src/__tests__/trace-emitter.test.ts +1 -1
  434. package/src/__tests__/trust-context-guards.test.ts +1 -1
  435. package/src/__tests__/trusted-contact-approval-notifier.test.ts +37 -51
  436. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +7 -7
  437. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +20 -12
  438. package/src/__tests__/trusted-contact-multichannel.test.ts +17 -8
  439. package/src/__tests__/trusted-contact-verification.test.ts +60 -57
  440. package/src/__tests__/turn-boundary-resolution.test.ts +7 -4
  441. package/src/__tests__/turn-call-site.test.ts +29 -0
  442. package/src/__tests__/turn-events-store.test.ts +8 -5
  443. package/src/__tests__/twilio-routes.test.ts +3 -3
  444. package/src/__tests__/unified-turn-context-client-os.test.ts +45 -0
  445. package/src/__tests__/usage-cache-backfill-migration.test.ts +4 -8
  446. package/src/__tests__/usage-grouped-buckets.test.ts +1 -1
  447. package/src/__tests__/usage-routes.test.ts +61 -3
  448. package/src/__tests__/verification-control-plane-policy.test.ts +6 -6
  449. package/src/__tests__/voice-guardian-cold-cache-warm.test.ts +137 -0
  450. package/src/__tests__/voice-invite-redemption.test.ts +183 -24
  451. package/src/__tests__/voice-quality.test.ts +38 -12
  452. package/src/__tests__/voice-scoped-grant-consumer.test.ts +22 -14
  453. package/src/__tests__/voice-session-bridge.test.ts +16 -10
  454. package/src/__tests__/web-search-backend-failure.test.ts +4 -4
  455. package/src/__tests__/workspace-lifecycle.test.ts +29 -18
  456. package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +4 -4
  457. package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +5 -5
  458. package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +3 -3
  459. package/src/__tests__/workspace-migration-102-preserve-heartbeat-enabled-for-existing-workspaces.test.ts +3 -3
  460. package/src/__tests__/workspace-migration-111-prune-seeded-callsite-defaults.test.ts +2 -2
  461. package/src/__tests__/workspace-migration-112-remove-advisor-callsite-override.test.ts +170 -0
  462. package/src/__tests__/workspace-migration-113-swap-balanced-profile-to-glm-5p2.test.ts +241 -0
  463. package/src/__tests__/workspace-migration-114-swap-quality-profile-to-opus.test.ts +172 -0
  464. package/src/__tests__/workspace-migration-116-rename-memory-plugin-disabled-sentinel.test.ts +128 -0
  465. package/src/__tests__/workspace-migration-117-normalize-stale-lean-memory-v3-defaults.test.ts +221 -0
  466. package/src/__tests__/workspace-migration-118-seed-now-md.test.ts +120 -0
  467. package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +1 -1
  468. package/src/__tests__/workspace-migration-drop-user-md.test.ts +273 -238
  469. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +41 -49
  470. package/src/a2a/__tests__/task-store.test.ts +2 -2
  471. package/src/a2a/task-store.ts +4 -4
  472. package/src/acp/__tests__/client-handler.test.ts +680 -0
  473. package/src/acp/__tests__/helpers/acp-history-db.ts +32 -4
  474. package/src/acp/__tests__/prepare-agent-env.test.ts +0 -97
  475. package/src/acp/__tests__/session-manager-persistence.test.ts +215 -7
  476. package/src/acp/__tests__/session-manager-resume.test.ts +113 -2
  477. package/src/acp/__tests__/session-manager-startup.test.ts +3 -3
  478. package/src/acp/__tests__/session-manager-usage.test.ts +113 -0
  479. package/src/acp/auto-install.ts +12 -8
  480. package/src/acp/client-handler.ts +140 -21
  481. package/src/acp/prepare-agent-env.ts +0 -12
  482. package/src/acp/resolve-agent.test.ts +6 -45
  483. package/src/acp/resolve-agent.ts +2 -4
  484. package/src/acp/session-manager.ts +127 -4
  485. package/src/acp/types.ts +18 -0
  486. package/src/agent/loop-exclusive-tool.test.ts +19 -15
  487. package/src/agent/loop-native-web-search.test.ts +200 -0
  488. package/src/agent/loop.ts +321 -149
  489. package/src/api/events/acp-session-completed.ts +33 -0
  490. package/src/api/events/acp-session-error.ts +21 -0
  491. package/src/api/events/acp-session-spawned.ts +32 -0
  492. package/src/api/events/acp-session-update.test.ts +122 -0
  493. package/src/api/events/acp-session-update.ts +51 -0
  494. package/src/api/events/acp-session-usage.test.ts +49 -0
  495. package/src/api/events/acp-session-usage.ts +31 -0
  496. package/src/api/events/background-tool-completed.test.ts +51 -0
  497. package/src/api/events/background-tool-completed.ts +29 -0
  498. package/src/api/events/background-tool-started.test.ts +36 -0
  499. package/src/api/events/background-tool-started.ts +28 -0
  500. package/src/api/events/conversation-error.ts +0 -1
  501. package/src/api/events/subagent-status-changed.ts +4 -1
  502. package/src/api/events/tool-use-preview-start.ts +11 -0
  503. package/src/api/events/tool-use-start.ts +14 -0
  504. package/src/api/index.ts +51 -0
  505. package/src/api/responses/conversation-message.ts +80 -1
  506. package/src/api/responses/llm-request-log-entry.ts +41 -0
  507. package/src/api/responses/memory-v3-selection-log.ts +5 -7
  508. package/src/approvals/approval-primitive.ts +1 -1
  509. package/src/approvals/guardian-card-withdrawal.ts +2 -2
  510. package/src/approvals/guardian-decision-primitive.ts +1 -1
  511. package/src/approvals/guardian-expiry-notifier.ts +1 -1
  512. package/src/approvals/guardian-request-resolvers.ts +19 -7
  513. package/src/approvals/scoped-approval-grants.ts +551 -0
  514. package/src/apps/app-store.ts +1058 -0
  515. package/src/apps/published-pages-store.ts +67 -0
  516. package/src/apps/shared-app-links-store.ts +130 -0
  517. package/src/background-wake/background-wake-routes.test.ts +53 -23
  518. package/src/background-wake/wake-intent-hooks.test.ts +18 -12
  519. package/src/backup/restore.ts +1 -1
  520. package/src/bundler/app-bundler.ts +1 -1
  521. package/src/calls/__tests__/relay-setup-router.test.ts +11 -19
  522. package/src/calls/call-controller.ts +5 -5
  523. package/src/calls/call-conversation-messages.ts +1 -1
  524. package/src/calls/call-domain.ts +5 -5
  525. package/src/calls/call-pointer-messages.ts +1 -1
  526. package/src/calls/call-store.ts +3 -3
  527. package/src/calls/guardian-action-sweep.ts +1 -1
  528. package/src/calls/guardian-dispatch.ts +15 -12
  529. package/src/calls/inbound-trust-reader.ts +7 -1
  530. package/src/calls/media-stream-server.ts +1 -1
  531. package/src/calls/relay-access-wait.ts +7 -7
  532. package/src/calls/relay-server.ts +25 -5
  533. package/src/calls/relay-setup-router.ts +11 -11
  534. package/src/calls/tts-call-strategy.ts +4 -3
  535. package/src/calls/voice-quality.ts +47 -59
  536. package/src/calls/voice-session-bridge.ts +2 -16
  537. package/src/channels/__tests__/types.test.ts +28 -0
  538. package/src/channels/channel-verification-sessions.ts +557 -0
  539. package/src/channels/types.ts +23 -0
  540. package/src/cli/commands/__tests__/conversations-new.test.ts +186 -0
  541. package/src/cli/commands/__tests__/conversations-slack.test.ts +2 -1
  542. package/src/cli/commands/__tests__/conversations-wake.test.ts +147 -0
  543. package/src/cli/commands/__tests__/ps.test.ts +205 -0
  544. package/src/cli/commands/__tests__/schedules.test.ts +52 -0
  545. package/src/cli/commands/contacts.ts +10 -7
  546. package/src/cli/commands/conversations.ts +90 -30
  547. package/src/cli/commands/db/__tests__/repair.test.ts +4 -3
  548. package/src/cli/commands/db/repair-step-conversation-backfill.ts +2 -2
  549. package/src/cli/commands/memory/__tests__/memory-v2-compare-render.test.ts +1 -1
  550. package/src/cli/commands/memory/__tests__/worker.test.ts +112 -183
  551. package/src/cli/commands/memory/memory-retrospective.ts +32 -28
  552. package/src/cli/commands/memory/memory-v2-compare-render.ts +1 -1
  553. package/src/cli/commands/memory/memory-v2.ts +2 -2
  554. package/src/cli/commands/memory/memory-v3.ts +2 -2
  555. package/src/cli/commands/memory/worker.ts +103 -113
  556. package/src/cli/commands/plugins.ts +150 -157
  557. package/src/cli/commands/ps.ts +90 -0
  558. package/src/cli/commands/schedules.ts +52 -8
  559. package/src/cli/commands/tools-run.ts +114 -0
  560. package/src/cli/commands/tools.ts +19 -5
  561. package/src/cli/lib/__tests__/cli-colors.test.ts +30 -1
  562. package/src/cli/lib/__tests__/install-from-github.test.ts +168 -8
  563. package/src/cli/lib/__tests__/list-installed-plugins.test.ts +23 -18
  564. package/src/cli/lib/__tests__/parse-github-plugin-spec.test.ts +121 -0
  565. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +1 -0
  566. package/src/cli/lib/__tests__/publish-plugin.test.ts +98 -0
  567. package/src/cli/lib/__tests__/search-plugins.test.ts +29 -1
  568. package/src/cli/lib/__tests__/toggle-plugin.test.ts +10 -4
  569. package/src/cli/lib/cli-colors.ts +6 -0
  570. package/src/cli/lib/diff-plugin.ts +3 -7
  571. package/src/cli/lib/inspect-plugin.ts +2 -4
  572. package/src/cli/lib/install-from-github.ts +96 -24
  573. package/src/cli/lib/merge-plugin-tree.ts +5 -3
  574. package/src/cli/lib/parse-github-plugin-spec.ts +163 -0
  575. package/src/cli/lib/plugin-fingerprint.ts +22 -0
  576. package/src/cli/lib/publish-plugin.ts +231 -1
  577. package/src/cli/lib/search-plugins.ts +6 -0
  578. package/src/cli/lib/upgrade-plugin.ts +6 -5
  579. package/src/cli/program.ts +5 -8
  580. package/src/cli.ts +6 -3
  581. package/src/config/__tests__/deployment-context-defaults.test.ts +228 -0
  582. package/src/config/__tests__/proc-to-skills.test.ts +21 -0
  583. package/src/config/__tests__/sync-gated-profiles.test.ts +7 -9
  584. package/src/config/acp-defaults.test.ts +0 -10
  585. package/src/config/acp-defaults.ts +0 -6
  586. package/src/config/bundled-skills/AGENTS.md +11 -0
  587. package/src/config/bundled-skills/acp/SKILL.md +13 -45
  588. package/src/config/bundled-skills/acp/TOOLS.json +3 -3
  589. package/src/config/bundled-skills/app-builder/SKILL.md +5 -3
  590. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +9 -9
  591. package/src/config/bundled-skills/app-builder/tools/app-create.ts +2 -2
  592. package/src/config/bundled-skills/app-builder/tools/app-delete.ts +2 -2
  593. package/src/config/bundled-skills/app-builder/tools/app-generate-icon.ts +2 -2
  594. package/src/config/bundled-skills/app-builder/tools/app-list.ts +1 -1
  595. package/src/config/bundled-skills/app-builder/tools/app-refresh.ts +2 -2
  596. package/src/config/bundled-skills/app-builder/tools/app-update.ts +2 -2
  597. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  598. package/src/config/bundled-skills/media-processing/__tests__/extract-keyframes.test.ts +1 -1
  599. package/src/config/bundled-skills/media-processing/__tests__/preprocess-audio.test.ts +1 -1
  600. package/src/config/bundled-skills/media-processing/services/preprocess.ts +1 -1
  601. package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +1 -1
  602. package/src/config/bundled-skills/media-processing/services/reduce.ts +1 -1
  603. package/src/config/bundled-skills/media-processing/tools/analyze-keyframes.ts +1 -1
  604. package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +1 -1
  605. package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +2 -2
  606. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +2 -2
  607. package/src/config/bundled-skills/media-processing/tools/media-status.ts +1 -1
  608. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +5 -5
  609. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +6 -6
  610. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +8 -5
  611. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +4 -1
  612. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +2 -2
  613. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -4
  614. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +7 -7
  615. package/src/config/bundled-skills/skill-management/TOOLS.json +45 -0
  616. package/src/config/bundled-skills/skill-management/tools/find-similar.ts +12 -0
  617. package/src/config/bundled-skills/subagent/SKILL.md +16 -1
  618. package/src/config/bundled-skills/subagent/TOOLS.json +5 -4
  619. package/src/config/bundled-tool-registry.ts +2 -0
  620. package/src/config/call-site-defaults.ts +0 -8
  621. package/src/config/feature-flag-registry.json +16 -24
  622. package/src/config/llm-resolver.ts +17 -3
  623. package/src/config/loader.ts +38 -58
  624. package/src/config/memory-v3-gate.ts +16 -0
  625. package/src/config/schema.ts +2 -0
  626. package/src/config/schemas/__tests__/memory-v2.test.ts +2 -2
  627. package/src/config/schemas/__tests__/memory-v3.test.ts +16 -5
  628. package/src/config/schemas/call-site-catalog.ts +0 -19
  629. package/src/config/schemas/conversations.ts +8 -0
  630. package/src/config/schemas/heartbeat.ts +2 -5
  631. package/src/config/schemas/llm.ts +3 -14
  632. package/src/config/schemas/memory-lifecycle.ts +10 -1
  633. package/src/config/schemas/memory-v2.ts +1 -1
  634. package/src/config/schemas/memory-v3.ts +56 -6
  635. package/src/config/schemas/migrations.ts +25 -0
  636. package/src/config/schemas/services.ts +0 -37
  637. package/src/config/seed-inference-profiles.ts +88 -84
  638. package/src/config/sync-gated-profiles.ts +6 -20
  639. package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +7 -8
  640. package/src/contacts/__tests__/guardian-contact-reader.test.ts +89 -0
  641. package/src/contacts/__tests__/guardian-delivery-reader.test.ts +3 -14
  642. package/src/contacts/__tests__/member-write-relay.test.ts +35 -11
  643. package/src/contacts/canonical-guardian-store.ts +891 -0
  644. package/src/contacts/contact-store.ts +37 -245
  645. package/src/contacts/contacts-write.ts +18 -58
  646. package/src/contacts/gateway-channel-read.ts +51 -0
  647. package/src/contacts/guardian-contact-reader.ts +52 -0
  648. package/src/contacts/guardian-delivery-reader.ts +21 -23
  649. package/src/contacts/guardian-rate-limits.ts +191 -0
  650. package/src/contacts/member-write-relay.ts +25 -31
  651. package/src/contacts/notify-contacts-changed.ts +17 -0
  652. package/src/contacts/types.ts +3 -15
  653. package/src/context/compactor.ts +3 -3
  654. package/src/context/strip-injections.ts +1 -1
  655. package/src/conversations/__tests__/message-consolidation.test.ts +10 -26
  656. package/src/conversations/job-handlers/summarization.ts +246 -0
  657. package/src/conversations/message-consolidation.ts +1 -1
  658. package/src/credential-execution/ces-runtime.ts +285 -0
  659. package/src/daemon/__tests__/abort-null-controller.test.ts +167 -0
  660. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +25 -22
  661. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +5 -4
  662. package/src/daemon/__tests__/conversation-tool-setup.test.ts +0 -44
  663. package/src/daemon/__tests__/daemon-readiness.test.ts +51 -0
  664. package/src/daemon/__tests__/embedding-reconcile.test.ts +456 -0
  665. package/src/daemon/__tests__/inference-profile-notification.test.ts +9 -6
  666. package/src/daemon/__tests__/lifecycle-embedding-reconcile.test.ts +119 -0
  667. package/src/daemon/__tests__/native-web-search-metadata.test.ts +2 -2
  668. package/src/daemon/__tests__/wake-conversation-ops-completion.test.ts +107 -0
  669. package/src/daemon/__tests__/web-search-status-text.test.ts +3 -5
  670. package/src/daemon/app-source-watcher.ts +71 -10
  671. package/src/daemon/channel-ui-capability.ts +25 -0
  672. package/src/daemon/config-watcher.ts +71 -47
  673. package/src/daemon/conversation-agent-loop-handlers.ts +266 -49
  674. package/src/daemon/conversation-agent-loop.ts +166 -89
  675. package/src/daemon/conversation-attachments.ts +2 -2
  676. package/src/daemon/conversation-error.ts +8 -25
  677. package/src/daemon/conversation-evictor.ts +42 -9
  678. package/src/daemon/conversation-history.ts +8 -234
  679. package/src/daemon/conversation-initial-prompt.ts +77 -0
  680. package/src/daemon/conversation-launch.ts +2 -2
  681. package/src/daemon/conversation-lifecycle.ts +32 -5
  682. package/src/daemon/conversation-messaging.ts +25 -11
  683. package/src/daemon/conversation-notifiers.ts +1 -1
  684. package/src/daemon/conversation-process.ts +27 -15
  685. package/src/daemon/conversation-queue-manager.ts +6 -0
  686. package/src/daemon/conversation-registry.ts +6 -5
  687. package/src/daemon/conversation-runtime-assembly.ts +45 -31
  688. package/src/daemon/conversation-skill-tools.ts +26 -2
  689. package/src/daemon/conversation-slash.ts +1 -1
  690. package/src/daemon/conversation-store.ts +47 -42
  691. package/src/daemon/conversation-surfaces.ts +4 -4
  692. package/src/daemon/conversation-tool-setup.ts +2 -11
  693. package/src/daemon/conversation-usage.ts +4 -2
  694. package/src/daemon/conversation-workspace.ts +2 -2
  695. package/src/daemon/conversation.ts +104 -17
  696. package/src/daemon/daemon-readiness.ts +33 -0
  697. package/src/daemon/embedding-reconcile.ts +340 -0
  698. package/src/daemon/event-loop-watchdog.ts +1 -1
  699. package/src/daemon/external-plugins-bootstrap.ts +123 -92
  700. package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +2 -3
  701. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +3 -5
  702. package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +3 -3
  703. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +7 -13
  704. package/src/daemon/handlers/__tests__/config-a2a.test.ts +2 -2
  705. package/src/daemon/handlers/__tests__/config-channels.test.ts +22 -21
  706. package/src/daemon/handlers/config-a2a.ts +3 -3
  707. package/src/daemon/handlers/config-channels.ts +21 -33
  708. package/src/daemon/handlers/config-embeddings.ts +1 -1
  709. package/src/daemon/handlers/conversation-history.ts +2 -2
  710. package/src/daemon/handlers/conversations.ts +7 -56
  711. package/src/daemon/handlers/recording.ts +6 -3
  712. package/src/daemon/handlers/shared.ts +2 -0
  713. package/src/daemon/handlers/skills.ts +9 -1
  714. package/src/daemon/lifecycle.ts +714 -1242
  715. package/src/daemon/message-protocol.ts +3 -3
  716. package/src/daemon/message-provenance.ts +1 -1
  717. package/src/daemon/message-types/acp.ts +27 -1
  718. package/src/daemon/message-types/background-tools.ts +28 -0
  719. package/src/daemon/message-types/bookmarks.ts +1 -1
  720. package/src/daemon/message-types/conversations.ts +10 -0
  721. package/src/daemon/message-types/skills.ts +20 -2
  722. package/src/daemon/message-types/surfaces.ts +2 -0
  723. package/src/daemon/pointer-conversation-trust.ts +66 -0
  724. package/src/daemon/process-message.ts +24 -3
  725. package/src/daemon/providers-setup.ts +16 -14
  726. package/src/daemon/shutdown-handlers.ts +195 -166
  727. package/src/daemon/skill-memory-refresh.ts +3 -3
  728. package/src/daemon/status.ts +15 -0
  729. package/src/daemon/tool-setup-types.ts +17 -0
  730. package/src/daemon/tool-side-effects.ts +4 -4
  731. package/src/daemon/trace-emitter.ts +1 -1
  732. package/src/daemon/trust-context.ts +1 -1
  733. package/src/daemon/turn-call-site.ts +25 -0
  734. package/src/daemon/turn-latency-tracker.test.ts +137 -0
  735. package/src/daemon/turn-latency-tracker.ts +134 -0
  736. package/src/daemon/wake-conversation-ops.ts +14 -4
  737. package/src/documents/document-comments-store.test.ts +2 -2
  738. package/src/documents/document-comments-store.ts +1 -1
  739. package/src/documents/document-store.ts +1 -1
  740. package/src/events/tool-audit-listener.ts +4 -4
  741. package/src/events/tool-permission-telemetry-listener.ts +1 -1
  742. package/src/export/__tests__/transcript-formatter.test.ts +1 -1
  743. package/src/export/transcript-formatter.ts +1 -1
  744. package/src/followups/followup-store.ts +2 -2
  745. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +2 -2
  746. package/src/heartbeat/__tests__/heartbeat-service.test.ts +45 -39
  747. package/src/heartbeat/heartbeat-run-store.ts +3 -3
  748. package/src/heartbeat/heartbeat-service.ts +34 -11
  749. package/src/home/__tests__/relationship-state-writer.test.ts +1 -1
  750. package/src/home/__tests__/suggested-prompts.test.ts +1 -1
  751. package/src/home/conversation-starter-checkpoints.ts +64 -0
  752. package/src/home/feed-source-enrichment.ts +3 -3
  753. package/src/home/home-greeting-cache.ts +1 -1
  754. package/src/home/job-handlers/conversation-starters.ts +484 -0
  755. package/src/home/relationship-state-writer.ts +6 -1
  756. package/src/home/suggested-prompts.ts +1 -1
  757. package/src/hooks/hook-loader.ts +141 -6
  758. package/src/hooks/registry.ts +129 -0
  759. package/src/ipc/__tests__/attachment-ipc.test.ts +1 -1
  760. package/src/ipc/__tests__/cli-ipc.test.ts +1 -1
  761. package/src/ipc/__tests__/inject-local-actor-header.test.ts +33 -0
  762. package/src/ipc/__tests__/watcher-ipc.test.ts +1 -1
  763. package/src/ipc/assistant-server.ts +79 -33
  764. package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +3 -3
  765. package/src/ipc/routes/db-proxy-transaction.ts +1 -1
  766. package/src/ipc/routes/db-proxy.ts +4 -2
  767. package/src/jobs/register-job-handlers.ts +78 -0
  768. package/src/jobs/worker.ts +91 -0
  769. package/src/live-voice/__tests__/live-voice-archive.test.ts +5 -5
  770. package/src/live-voice/live-voice-archive.ts +2 -2
  771. package/src/mcp/manager.ts +11 -0
  772. package/src/media/app-icon-generator.ts +1 -1
  773. package/src/media/job-handlers/media-processing.ts +126 -0
  774. package/src/messaging/channel-binding-metadata.ts +31 -0
  775. package/src/messaging/channel-binding-schema.ts +51 -0
  776. package/src/messaging/content/parse.test.ts +34 -0
  777. package/src/messaging/content/parse.ts +23 -0
  778. package/src/messaging/providers/__tests__/callback-routing.test.ts +45 -0
  779. package/src/messaging/providers/__tests__/transport-dispatch.test.ts +196 -0
  780. package/src/messaging/providers/a2a/__tests__/deliver.test.ts +11 -0
  781. package/src/messaging/providers/a2a/deliver.ts +5 -1
  782. package/src/messaging/providers/a2a/transport.ts +10 -0
  783. package/src/messaging/providers/callback-routing.ts +48 -0
  784. package/src/messaging/providers/channel-transport.ts +55 -0
  785. package/src/messaging/providers/index.ts +65 -241
  786. package/src/messaging/providers/slack/binding-metadata.ts +62 -0
  787. package/src/messaging/providers/slack/render.test.ts +309 -0
  788. package/src/messaging/providers/slack/render.ts +459 -0
  789. package/src/messaging/providers/slack/send.test.ts +39 -0
  790. package/src/messaging/providers/slack/send.ts +38 -18
  791. package/src/messaging/providers/slack/transport.ts +92 -0
  792. package/src/messaging/providers/telegram-bot/adapter.ts +2 -2
  793. package/src/messaging/providers/telegram-bot/api.ts +17 -3
  794. package/src/messaging/providers/telegram-bot/render.test.ts +146 -0
  795. package/src/messaging/providers/telegram-bot/render.ts +292 -0
  796. package/src/messaging/providers/telegram-bot/send.test.ts +197 -0
  797. package/src/messaging/providers/telegram-bot/send.ts +70 -2
  798. package/src/messaging/providers/telegram-bot/transport.ts +60 -0
  799. package/src/messaging/providers/whatsapp/adapter.ts +2 -2
  800. package/src/messaging/providers/whatsapp/send.ts +1 -1
  801. package/src/messaging/providers/whatsapp/transport.ts +38 -0
  802. package/src/notifications/__tests__/broadcaster.test.ts +0 -8
  803. package/src/notifications/__tests__/connected-channels.test.ts +8 -36
  804. package/src/notifications/__tests__/destination-resolver.test.ts +12 -117
  805. package/src/notifications/__tests__/deterministic-checks.test.ts +3 -3
  806. package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -1
  807. package/src/notifications/broadcaster.ts +1 -1
  808. package/src/notifications/canonical-delivery-recorder.ts +1 -1
  809. package/src/notifications/conversation-candidates.ts +3 -3
  810. package/src/notifications/conversation-pairing.ts +25 -16
  811. package/src/notifications/decisions-store.ts +2 -2
  812. package/src/notifications/deliveries-store.ts +3 -3
  813. package/src/notifications/destination-resolver.ts +7 -23
  814. package/src/notifications/deterministic-checks.ts +2 -2
  815. package/src/notifications/emit-signal.ts +6 -12
  816. package/src/notifications/events-store.ts +2 -2
  817. package/src/notifications/home-feed-side-effect.ts +2 -2
  818. package/src/notifications/preferences-store.ts +2 -2
  819. package/src/notifications/signal.ts +1 -1
  820. package/src/oauth/oauth-store.ts +3 -3
  821. package/src/onboarding/__tests__/onboarding-events-store.test.ts +80 -0
  822. package/src/onboarding/checkin-event.test.ts +5 -2
  823. package/src/onboarding/checkin-event.ts +7 -1
  824. package/src/onboarding/onboarding-events-store.ts +161 -0
  825. package/src/permissions/checker.test.ts +319 -1
  826. package/src/permissions/checker.ts +52 -0
  827. package/src/permissions/types.ts +23 -2
  828. package/src/persistence/__tests__/db-init-migrations-ok.test.ts +20 -0
  829. package/src/persistence/__tests__/worker-control.test.ts +260 -0
  830. package/src/persistence/attachments-store.ts +1136 -0
  831. package/src/persistence/checkpoints.ts +65 -0
  832. package/src/persistence/compaction-ledger-store.ts +107 -0
  833. package/src/persistence/conversation-attention-store.ts +689 -0
  834. package/src/persistence/conversation-bootstrap.ts +59 -0
  835. package/src/persistence/conversation-crud.ts +3404 -0
  836. package/src/persistence/conversation-group-migration.test.ts +99 -0
  837. package/src/persistence/conversation-key-store.ts +274 -0
  838. package/src/persistence/conversation-queries.ts +768 -0
  839. package/src/persistence/conversation-row-batch-delete.ts +212 -0
  840. package/src/persistence/conversation-title-service.ts +755 -0
  841. package/src/persistence/db-async-query.ts +329 -0
  842. package/src/persistence/db-connection.ts +242 -0
  843. package/src/persistence/db-init.ts +282 -0
  844. package/src/persistence/db-maintenance.ts +158 -0
  845. package/src/persistence/embeddings/__tests__/embedding-identity.test.ts +156 -0
  846. package/src/persistence/embeddings/__tests__/messages-lexical-index.test.ts +307 -0
  847. package/src/persistence/embeddings/__tests__/reconcile-decision.test.ts +95 -0
  848. package/src/persistence/embeddings/embed.ts +87 -0
  849. package/src/persistence/embeddings/embedding-backend.test.ts +355 -0
  850. package/src/persistence/embeddings/embedding-backend.ts +968 -0
  851. package/src/persistence/embeddings/embedding-billing-breaker.ts +96 -0
  852. package/src/persistence/embeddings/embedding-cache.ts +139 -0
  853. package/src/persistence/embeddings/embedding-identity.ts +88 -0
  854. package/src/persistence/embeddings/embedding-local.ts +587 -0
  855. package/src/persistence/embeddings/embedding-ollama.ts +79 -0
  856. package/src/persistence/embeddings/embedding-runtime-manager.ts +573 -0
  857. package/src/persistence/embeddings/embedding-types.ts +97 -0
  858. package/src/persistence/embeddings/messages-lexical-index.ts +368 -0
  859. package/src/persistence/embeddings/qdrant-circuit-breaker.ts +119 -0
  860. package/src/persistence/embeddings/qdrant-client.test.ts +60 -0
  861. package/src/persistence/embeddings/qdrant-client.ts +842 -0
  862. package/src/persistence/embeddings/qdrant-manager.ts +450 -0
  863. package/src/persistence/embeddings/reconcile-decision.ts +53 -0
  864. package/src/persistence/embeddings/sparse-tokenize.ts +51 -0
  865. package/src/persistence/external-conversation-store.ts +315 -0
  866. package/src/persistence/fork-message-copy.ts +225 -0
  867. package/src/persistence/job-handlers/cleanup.ts +266 -0
  868. package/src/persistence/job-utils.ts +286 -0
  869. package/src/persistence/jobs-store.ts +866 -0
  870. package/src/persistence/jobs-worker.ts +842 -0
  871. package/src/persistence/llm-request-log-source-clickhouse.ts +525 -0
  872. package/src/persistence/llm-request-log-store.ts +740 -0
  873. package/src/persistence/llm-usage-store.ts +961 -0
  874. package/src/persistence/memory-lifecycle-hooks.test.ts +81 -0
  875. package/src/persistence/memory-lifecycle-hooks.ts +120 -0
  876. package/src/persistence/message-content.test.ts +35 -0
  877. package/src/persistence/migrations/126-backfill-guardian-principal-id.ts +300 -0
  878. package/src/persistence/migrations/140-backfill-usage-cache-accounting.ts +364 -0
  879. package/src/persistence/migrations/142-rename-verification-session-id-column.ts +55 -0
  880. package/src/persistence/migrations/182-oauth-providers-display-metadata.ts +22 -0
  881. package/src/persistence/migrations/196-strip-integration-prefix-from-provider-keys.ts +175 -0
  882. package/src/persistence/migrations/199-guardian-request-enrichment-columns.ts +50 -0
  883. package/src/persistence/migrations/202-memory-graph-tables.ts +128 -0
  884. package/src/persistence/migrations/203-drop-memory-items-tables.ts +53 -0
  885. package/src/persistence/migrations/206-scrub-corrupted-image-attachments.ts +121 -0
  886. package/src/persistence/migrations/209-strip-thinking-from-consolidated.ts +196 -0
  887. package/src/persistence/migrations/211-memory-recall-logs-query-context.ts +14 -0
  888. package/src/persistence/migrations/220-normalize-user-file-by-principal.ts +171 -0
  889. package/src/persistence/migrations/222-strip-placeholder-sentinels-from-messages.ts +179 -0
  890. package/src/persistence/migrations/236-tool-invocations-matched-rule-id.ts +23 -0
  891. package/src/persistence/migrations/243-provider-connections.ts +80 -0
  892. package/src/persistence/migrations/244-provider-connection-status-label.ts +29 -0
  893. package/src/persistence/migrations/246-backfill-provider-connection-label.ts +83 -0
  894. package/src/persistence/migrations/255-channel-inbound-delivery-attempts.ts +17 -0
  895. package/src/persistence/migrations/301-create-watchdog-events.ts +42 -0
  896. package/src/persistence/migrations/302-create-compaction-events.ts +107 -0
  897. package/src/persistence/migrations/303-add-conversation-creation-seq.ts +33 -0
  898. package/src/persistence/migrations/304-add-llm-usage-cron-run-id.ts +31 -0
  899. package/src/persistence/migrations/305-drop-contact-acl-columns.ts +49 -0
  900. package/src/persistence/migrations/306-rewrite-frontier-profile-pins.test.ts +110 -0
  901. package/src/persistence/migrations/306-rewrite-frontier-profile-pins.ts +65 -0
  902. package/src/persistence/migrations/307-acp-session-history-usage-columns.test.ts +124 -0
  903. package/src/persistence/migrations/307-acp-session-history-usage-columns.ts +36 -0
  904. package/src/persistence/migrations/308-acp-session-history-token-columns.test.ts +119 -0
  905. package/src/persistence/migrations/308-acp-session-history-token-columns.ts +32 -0
  906. package/src/persistence/migrations/309-drop-redundant-indexes.ts +60 -0
  907. package/src/persistence/migrations/310-llm-request-log-latency-breakdown.ts +37 -0
  908. package/src/persistence/migrations/311-create-subagents-table.ts +50 -0
  909. package/src/persistence/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +328 -0
  910. package/src/persistence/migrations/__tests__/222-strip-placeholder-sentinels-from-messages.test.ts +273 -0
  911. package/src/persistence/migrations/__tests__/244-provider-connection-status-label.test.ts +90 -0
  912. package/src/persistence/migrations/__tests__/246-backfill-provider-connection-label.test.ts +250 -0
  913. package/src/persistence/migrations/__tests__/run-migrations.test.ts +380 -0
  914. package/src/persistence/migrations/helpers/relocation.ts +230 -0
  915. package/src/persistence/migrations/validate-migration-state.ts +279 -0
  916. package/src/persistence/schedule-attribution-sql.ts +106 -0
  917. package/src/persistence/schema/acp.ts +51 -0
  918. package/src/persistence/schema/contacts.ts +110 -0
  919. package/src/persistence/schema/conversations.ts +235 -0
  920. package/src/persistence/schema/infrastructure.ts +389 -0
  921. package/src/persistence/steps.ts +1312 -0
  922. package/src/persistence/subagent-store.ts +122 -0
  923. package/src/persistence/worker-control.ts +277 -0
  924. package/src/platform/sync-identity.ts +24 -0
  925. package/src/playbooks/playbook-compiler.ts +2 -2
  926. package/src/plugin-api/event-hub-facade.ts +172 -0
  927. package/src/plugin-api/index.ts +14 -1
  928. package/src/plugin-api/types.ts +61 -24
  929. package/src/plugins/defaults/channel/injectors.ts +101 -0
  930. package/src/plugins/defaults/channel/package.json +14 -0
  931. package/src/plugins/defaults/compaction/compact.ts +2 -1
  932. package/src/plugins/defaults/compaction/context-overflow-reducer.ts +2 -1
  933. package/src/plugins/defaults/compaction/window-manager.ts +8 -7
  934. package/src/plugins/defaults/documents/injectors.ts +125 -0
  935. package/src/plugins/defaults/documents/package.json +14 -0
  936. package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +6 -2
  937. package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +10 -11
  938. package/src/plugins/defaults/history-repair/terminal.ts +1 -1
  939. package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +23 -9
  940. package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +2 -3
  941. package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +7 -14
  942. package/src/plugins/defaults/image-fallback/src/vision-caption.ts +12 -4
  943. package/src/plugins/defaults/image-recovery/recover.ts +6 -3
  944. package/src/plugins/defaults/index.ts +235 -78
  945. package/src/plugins/defaults/injection-presence.ts +80 -0
  946. package/src/plugins/defaults/injector-order.ts +54 -0
  947. package/src/plugins/defaults/max-tokens-continue/hooks/post-model-call.ts +5 -2
  948. package/src/plugins/defaults/memory/__tests__/301-create-watchdog-events.test.ts +110 -0
  949. package/src/plugins/defaults/memory/__tests__/activation-session-store.test.ts +41 -0
  950. package/src/plugins/defaults/memory/__tests__/bookmark-crud.test.ts +264 -0
  951. package/src/plugins/defaults/memory/__tests__/bookmark-schema.test.ts +181 -0
  952. package/src/plugins/defaults/memory/__tests__/clear-stale-processing-flags.test.ts +52 -0
  953. package/src/plugins/defaults/memory/__tests__/compaction-log-store-clickhouse.test.ts +432 -0
  954. package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +843 -0
  955. package/src/plugins/defaults/memory/__tests__/conversation-row-batch-delete.test.ts +199 -0
  956. package/src/plugins/defaults/memory/__tests__/conversation-types.test.ts +36 -0
  957. package/src/plugins/defaults/memory/__tests__/db-async-query.test.ts +172 -0
  958. package/src/plugins/defaults/memory/__tests__/db-busy-timeout.test.ts +26 -0
  959. package/src/plugins/defaults/memory/__tests__/db-logs-attach.test.ts +113 -0
  960. package/src/plugins/defaults/memory/__tests__/db-maintenance.test.ts +238 -0
  961. package/src/plugins/defaults/memory/__tests__/db-memory-attach.test.ts +116 -0
  962. package/src/plugins/defaults/memory/__tests__/embedding-cache.test.ts +137 -0
  963. package/src/plugins/defaults/memory/__tests__/find-analysis-conversation.test.ts +197 -0
  964. package/src/plugins/defaults/memory/__tests__/find-most-recent-retrospective-for.test.ts +138 -0
  965. package/src/plugins/defaults/memory/__tests__/fork-message-copy.test.ts +232 -0
  966. package/src/plugins/defaults/memory/__tests__/jobs-store-enqueue-gate.test.ts +245 -0
  967. package/src/plugins/defaults/memory/__tests__/jobs-store-job-classes.test.ts +52 -0
  968. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +115 -0
  969. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +508 -0
  970. package/src/plugins/defaults/memory/__tests__/memory-retrospective-enqueue.test.ts +160 -0
  971. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +1568 -0
  972. package/src/plugins/defaults/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +549 -0
  973. package/src/plugins/defaults/memory/__tests__/memory-retrospective-state.test.ts +195 -0
  974. package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +221 -0
  975. package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +275 -0
  976. package/src/plugins/defaults/memory/__tests__/memory-v3-selections-migration.test.ts +103 -0
  977. package/src/plugins/defaults/memory/__tests__/prompt-override.test.ts +192 -0
  978. package/src/plugins/defaults/memory/__tests__/qdrant-client-sentinel.test.ts +49 -0
  979. package/src/plugins/defaults/memory/__tests__/table-relocation.test.ts +130 -0
  980. package/src/plugins/defaults/memory/activation-session-store.ts +43 -0
  981. package/src/plugins/defaults/memory/anisotropy.ts +443 -0
  982. package/src/plugins/defaults/memory/context-search/agent-protocol.ts +428 -0
  983. package/src/plugins/defaults/memory/context-search/agent-runner.ts +1311 -0
  984. package/src/plugins/defaults/memory/context-search/search.ts +297 -0
  985. package/src/plugins/defaults/memory/context-search/sources/conversations.ts +341 -0
  986. package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +600 -0
  987. package/src/plugins/defaults/memory/context-search/sources/memory.ts +101 -0
  988. package/src/plugins/defaults/memory/context-search/types.ts +48 -0
  989. package/src/plugins/defaults/memory/filing-service.ts +430 -0
  990. package/src/plugins/defaults/memory/find-most-recent-retrospective-for.ts +66 -0
  991. package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-registry.test.ts +119 -0
  992. package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +663 -0
  993. package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +321 -0
  994. package/src/plugins/defaults/memory/graph/bootstrap.test.ts +287 -0
  995. package/src/plugins/defaults/memory/graph/bootstrap.ts +544 -0
  996. package/src/plugins/defaults/memory/graph/capability-seed.ts +454 -0
  997. package/src/plugins/defaults/memory/graph/consolidation.ts +712 -0
  998. package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +1181 -0
  999. package/src/plugins/defaults/memory/graph/decay.ts +195 -0
  1000. package/src/plugins/defaults/memory/graph/extraction-job.ts +77 -0
  1001. package/src/plugins/defaults/memory/graph/extraction.ts +1462 -0
  1002. package/src/plugins/defaults/memory/graph/graph-memory-state-store.ts +50 -0
  1003. package/src/plugins/defaults/memory/graph/graph-search.test.ts +132 -0
  1004. package/src/plugins/defaults/memory/graph/graph-search.ts +294 -0
  1005. package/src/plugins/defaults/memory/graph/image-ref-utils.ts +29 -0
  1006. package/src/plugins/defaults/memory/graph/injection.ts +469 -0
  1007. package/src/plugins/defaults/memory/graph/narrative.ts +267 -0
  1008. package/src/plugins/defaults/memory/graph/pattern-scan.ts +269 -0
  1009. package/src/plugins/defaults/memory/graph/retriever.test.ts +624 -0
  1010. package/src/plugins/defaults/memory/graph/retriever.ts +1357 -0
  1011. package/src/plugins/defaults/memory/graph/store.test.ts +1093 -0
  1012. package/src/plugins/defaults/memory/graph/store.ts +923 -0
  1013. package/src/plugins/defaults/memory/graph/tool-handlers.ts +195 -0
  1014. package/src/plugins/defaults/memory/graph/tools.ts +95 -0
  1015. package/src/plugins/defaults/memory/hooks/init.ts +26 -0
  1016. package/src/plugins/defaults/memory/hooks/post-compact.ts +115 -0
  1017. package/src/plugins/defaults/memory/hooks/shutdown.ts +14 -0
  1018. package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +371 -0
  1019. package/src/plugins/defaults/memory/indexer.ts +409 -0
  1020. package/src/plugins/defaults/memory/injectors.ts +388 -0
  1021. package/src/plugins/defaults/memory/job-handlers/__tests__/backfill-lexical-index.test.ts +310 -0
  1022. package/src/plugins/defaults/memory/job-handlers/__tests__/index-message-lexical.test.ts +265 -0
  1023. package/src/plugins/defaults/memory/job-handlers/backfill-lexical-index.ts +108 -0
  1024. package/src/plugins/defaults/memory/job-handlers/backfill.ts +107 -0
  1025. package/src/plugins/defaults/memory/job-handlers/embedding.test.ts +236 -0
  1026. package/src/plugins/defaults/memory/job-handlers/embedding.ts +133 -0
  1027. package/src/plugins/defaults/memory/job-handlers/index-maintenance.ts +117 -0
  1028. package/src/plugins/defaults/memory/job-handlers/index-message-lexical.ts +106 -0
  1029. package/src/plugins/defaults/memory/job-handlers.ts +220 -0
  1030. package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +565 -0
  1031. package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +424 -0
  1032. package/src/plugins/defaults/memory/jobs/embed-pkb-file.test.ts +169 -0
  1033. package/src/plugins/defaults/memory/jobs/embed-pkb-file.ts +59 -0
  1034. package/src/plugins/defaults/memory/memory-recall-log-store.ts +172 -0
  1035. package/src/plugins/defaults/memory/memory-retrospective-constants.ts +60 -0
  1036. package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +131 -0
  1037. package/src/plugins/defaults/memory/memory-retrospective-fork-boundary.ts +94 -0
  1038. package/src/plugins/defaults/memory/memory-retrospective-job.ts +958 -0
  1039. package/src/plugins/defaults/memory/memory-retrospective-startup-cleanup.ts +264 -0
  1040. package/src/plugins/defaults/memory/memory-retrospective-state.ts +259 -0
  1041. package/src/plugins/defaults/memory/memory-retrospective-trigger-check.ts +91 -0
  1042. package/src/plugins/defaults/memory/memory-v2-activation-log-store.ts +216 -0
  1043. package/src/plugins/defaults/memory/memory-v2-concept-frequency.ts +173 -0
  1044. package/src/plugins/defaults/memory/package.json +14 -0
  1045. package/src/plugins/defaults/memory/persistence-hooks.ts +119 -0
  1046. package/src/plugins/defaults/memory/pkb/autoinject.ts +61 -0
  1047. package/src/plugins/defaults/memory/pkb/context.ts +50 -0
  1048. package/src/plugins/defaults/memory/pkb/pkb-index.test.ts +371 -0
  1049. package/src/plugins/defaults/memory/pkb/pkb-index.ts +256 -0
  1050. package/src/plugins/defaults/memory/pkb/pkb-reconcile.test.ts +254 -0
  1051. package/src/plugins/defaults/memory/pkb/pkb-reconcile.ts +144 -0
  1052. package/src/plugins/defaults/memory/pkb/pkb-search.test.ts +589 -0
  1053. package/src/plugins/defaults/memory/pkb/pkb-search.ts +178 -0
  1054. package/src/plugins/defaults/memory/pkb/types.ts +67 -0
  1055. package/src/plugins/defaults/memory/rerank-local.ts +374 -0
  1056. package/src/plugins/defaults/memory/routes/__tests__/memory-v2-routes.test.ts +165 -0
  1057. package/src/plugins/defaults/memory/routes/__tests__/memory-v2-simulate-route.test.ts +347 -0
  1058. package/src/plugins/defaults/memory/routes/memory-eval-routes.ts +179 -0
  1059. package/src/plugins/defaults/memory/routes/memory-item-routes.test.ts +922 -0
  1060. package/src/plugins/defaults/memory/routes/memory-item-routes.ts +814 -0
  1061. package/src/plugins/defaults/memory/routes/memory-v2-routes.ts +850 -0
  1062. package/src/plugins/defaults/memory/routes/memory-v3-routes.ts +125 -0
  1063. package/src/plugins/defaults/memory/routes/messages-lexical-routes.ts +67 -0
  1064. package/src/plugins/defaults/memory/search/semantic.ts +241 -0
  1065. package/src/plugins/defaults/memory/segmenter.ts +76 -0
  1066. package/src/plugins/defaults/memory/startup.ts +234 -0
  1067. package/src/plugins/defaults/memory/tail-reinjection-strip.ts +65 -0
  1068. package/src/plugins/defaults/memory/task-memory-cleanup.ts +241 -0
  1069. package/src/plugins/defaults/memory/tools.test.ts +382 -0
  1070. package/src/plugins/defaults/memory/tools.ts +87 -0
  1071. package/src/plugins/defaults/memory/v2/__tests__/activation-store.test.ts +207 -0
  1072. package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +1273 -0
  1073. package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +510 -0
  1074. package/src/plugins/defaults/memory/v2/__tests__/cli-command-store.test.ts +432 -0
  1075. package/src/plugins/defaults/memory/v2/__tests__/consolidation-job.test.ts +744 -0
  1076. package/src/plugins/defaults/memory/v2/__tests__/consolidation-prompt-flag-gating-guard.test.ts +205 -0
  1077. package/src/plugins/defaults/memory/v2/__tests__/frontmatter-sweep.test.ts +136 -0
  1078. package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +186 -0
  1079. package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  1080. package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
  1081. package/src/plugins/defaults/memory/v2/__tests__/harness-runner.test.ts +135 -0
  1082. package/src/plugins/defaults/memory/v2/__tests__/injection-events.test.ts +318 -0
  1083. package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +2308 -0
  1084. package/src/plugins/defaults/memory/v2/__tests__/memory-v2-startup.test.ts +86 -0
  1085. package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +940 -0
  1086. package/src/plugins/defaults/memory/v2/__tests__/page-index.test.ts +760 -0
  1087. package/src/plugins/defaults/memory/v2/__tests__/prompts-consolidation.test.ts +332 -0
  1088. package/src/plugins/defaults/memory/v2/__tests__/qdrant.test.ts +974 -0
  1089. package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +338 -0
  1090. package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +1198 -0
  1091. package/src/plugins/defaults/memory/v2/__tests__/sim.test.ts +704 -0
  1092. package/src/plugins/defaults/memory/v2/__tests__/skill-content.test.ts +115 -0
  1093. package/src/plugins/defaults/memory/v2/__tests__/skill-store.test.ts +986 -0
  1094. package/src/plugins/defaults/memory/v2/__tests__/sparse-bm25.test.ts +292 -0
  1095. package/src/plugins/defaults/memory/v2/__tests__/static-context.test.ts +223 -0
  1096. package/src/plugins/defaults/memory/v2/__tests__/sweep-job.test.ts +530 -0
  1097. package/src/plugins/defaults/memory/v2/activation-store.ts +185 -0
  1098. package/src/plugins/defaults/memory/v2/activation.ts +560 -0
  1099. package/src/plugins/defaults/memory/v2/backfill-jobs.ts +296 -0
  1100. package/src/plugins/defaults/memory/v2/cli-command-store.ts +341 -0
  1101. package/src/plugins/defaults/memory/v2/consolidation-job.ts +550 -0
  1102. package/src/plugins/defaults/memory/v2/frontmatter-sweep.ts +98 -0
  1103. package/src/plugins/defaults/memory/v2/harness/compare.ts +57 -0
  1104. package/src/plugins/defaults/memory/v2/harness/oracle.ts +148 -0
  1105. package/src/plugins/defaults/memory/v2/harness/replay-input.ts +243 -0
  1106. package/src/plugins/defaults/memory/v2/harness/retriever.ts +74 -0
  1107. package/src/plugins/defaults/memory/v2/harness/router-retriever.ts +43 -0
  1108. package/src/plugins/defaults/memory/v2/injected-block-slugs.ts +79 -0
  1109. package/src/plugins/defaults/memory/v2/injection-events.ts +101 -0
  1110. package/src/plugins/defaults/memory/v2/injection.ts +932 -0
  1111. package/src/plugins/defaults/memory/v2/memory-v2-startup.test.ts +203 -0
  1112. package/src/plugins/defaults/memory/v2/memory-v2-startup.ts +378 -0
  1113. package/src/plugins/defaults/memory/v2/migration.ts +774 -0
  1114. package/src/plugins/defaults/memory/v2/page-index.ts +459 -0
  1115. package/src/plugins/defaults/memory/v2/page-store.ts +443 -0
  1116. package/src/plugins/defaults/memory/v2/prompts/consolidation.ts +868 -0
  1117. package/src/plugins/defaults/memory/v2/prompts/router.ts +148 -0
  1118. package/src/plugins/defaults/memory/v2/qdrant.ts +939 -0
  1119. package/src/plugins/defaults/memory/v2/reranker.ts +184 -0
  1120. package/src/plugins/defaults/memory/v2/router.ts +602 -0
  1121. package/src/plugins/defaults/memory/v2/sim.ts +310 -0
  1122. package/src/plugins/defaults/memory/v2/skill-content.ts +61 -0
  1123. package/src/plugins/defaults/memory/v2/skill-store.ts +431 -0
  1124. package/src/plugins/defaults/memory/v2/sparse-bm25.ts +245 -0
  1125. package/src/plugins/defaults/memory/v2/static-context.ts +100 -0
  1126. package/src/plugins/defaults/memory/v2/sweep-job.ts +323 -0
  1127. package/src/plugins/defaults/memory/v3/__tests__/candidate-match.test.ts +316 -0
  1128. package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +1163 -0
  1129. package/src/plugins/defaults/memory/v3/__tests__/dense.test.ts +211 -0
  1130. package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +247 -0
  1131. package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +685 -0
  1132. package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +365 -0
  1133. package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +1012 -0
  1134. package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +977 -0
  1135. package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +599 -0
  1136. package/src/plugins/defaults/memory/v3/__tests__/render-injection.test.ts +128 -0
  1137. package/src/plugins/defaults/memory/v3/__tests__/section-dense-store.test.ts +756 -0
  1138. package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +422 -0
  1139. package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +501 -0
  1140. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +885 -0
  1141. package/src/plugins/defaults/memory/v3/__tests__/tuning-profile.test.ts +96 -0
  1142. package/src/plugins/defaults/memory/v3/candidate-match.ts +197 -0
  1143. package/src/plugins/defaults/memory/v3/capabilities.ts +88 -0
  1144. package/src/plugins/defaults/memory/v3/card.ts +160 -0
  1145. package/src/plugins/defaults/memory/v3/dense.ts +108 -0
  1146. package/src/plugins/defaults/memory/v3/edge.ts +252 -0
  1147. package/src/plugins/defaults/memory/v3/entity-lane.test.ts +124 -0
  1148. package/src/plugins/defaults/memory/v3/entity-lane.ts +113 -0
  1149. package/src/plugins/defaults/memory/v3/ever-injected-store.test.ts +307 -0
  1150. package/src/plugins/defaults/memory/v3/ever-injected-store.ts +278 -0
  1151. package/src/plugins/defaults/memory/v3/hot-set.test.ts +143 -0
  1152. package/src/plugins/defaults/memory/v3/hot-set.ts +85 -0
  1153. package/src/plugins/defaults/memory/v3/injector.ts +423 -0
  1154. package/src/plugins/defaults/memory/v3/learned-edges.test.ts +169 -0
  1155. package/src/plugins/defaults/memory/v3/learned-edges.ts +178 -0
  1156. package/src/plugins/defaults/memory/v3/maintain-job.ts +988 -0
  1157. package/src/plugins/defaults/memory/v3/orchestrate.ts +483 -0
  1158. package/src/plugins/defaults/memory/v3/page-content.ts +102 -0
  1159. package/src/plugins/defaults/memory/v3/pool-select.test.ts +147 -0
  1160. package/src/plugins/defaults/memory/v3/pool-select.ts +586 -0
  1161. package/src/plugins/defaults/memory/v3/prune.test.ts +760 -0
  1162. package/src/plugins/defaults/memory/v3/prune.ts +469 -0
  1163. package/src/plugins/defaults/memory/v3/render-injection.ts +92 -0
  1164. package/src/plugins/defaults/memory/v3/section-dense-store.ts +471 -0
  1165. package/src/plugins/defaults/memory/v3/section-needle.ts +215 -0
  1166. package/src/plugins/defaults/memory/v3/selection-log-store.ts +277 -0
  1167. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +656 -0
  1168. package/src/plugins/defaults/memory/v3/tuning-profile.ts +91 -0
  1169. package/src/plugins/defaults/memory/v3/types.ts +130 -0
  1170. package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +731 -0
  1171. package/src/plugins/defaults/session/injectors.ts +84 -0
  1172. package/src/plugins/defaults/session/package.json +14 -0
  1173. package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +6 -2
  1174. package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +39 -45
  1175. package/src/plugins/defaults/title-generate/hooks/stop.ts +4 -5
  1176. package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +3 -3
  1177. package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +5 -3
  1178. package/src/plugins/defaults/turn-context/injectors.ts +53 -0
  1179. package/src/plugins/defaults/turn-context/package.json +14 -0
  1180. package/src/plugins/defaults/turn-context/unified-turn-context.ts +235 -0
  1181. package/src/plugins/defaults/workspace/injectors.ts +295 -0
  1182. package/src/plugins/defaults/workspace/package.json +14 -0
  1183. package/src/plugins/disabled-state.ts +31 -0
  1184. package/src/plugins/injector-registry.ts +127 -0
  1185. package/src/plugins/job-handler-registry.ts +94 -0
  1186. package/src/plugins/mtime-cache.ts +27 -47
  1187. package/src/plugins/pipeline.ts +1 -1
  1188. package/src/plugins/registry.ts +40 -132
  1189. package/src/plugins/types.ts +44 -1
  1190. package/src/prompts/persona-resolver.ts +43 -11
  1191. package/src/prompts/system-prompt.ts +1 -1
  1192. package/src/prompts/templates/BOOTSTRAP.md +16 -119
  1193. package/src/prompts/templates/SOUL.md +4 -0
  1194. package/src/providers/__tests__/connection-model-compat.test.ts +1 -1
  1195. package/src/providers/__tests__/dispatch-connection-routing.test.ts +1 -1
  1196. package/src/providers/__tests__/inference.test.ts +6 -6
  1197. package/src/providers/__tests__/placeholder-sentinels.test.ts +80 -0
  1198. package/src/providers/__tests__/retry-callsite.test.ts +31 -3
  1199. package/src/providers/__tests__/satellite-connection-routing.test.ts +1 -1
  1200. package/src/providers/anthropic/client.ts +23 -24
  1201. package/src/providers/call-site-routing.ts +42 -1
  1202. package/src/providers/connection-resolution.ts +7 -3
  1203. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +7 -8
  1204. package/src/providers/inference/__tests__/base-url-security.test.ts +8 -8
  1205. package/src/providers/inference/__tests__/connections-label.test.ts +5 -5
  1206. package/src/providers/inference/__tests__/connections-openai-compatible.test.ts +4 -4
  1207. package/src/providers/inference/backfill.ts +9 -5
  1208. package/src/providers/inference/connections.ts +2 -2
  1209. package/src/providers/inference/resolve-auth.ts +3 -3
  1210. package/src/providers/model-catalog.ts +38 -0
  1211. package/src/providers/openai/chat-completions-provider.ts +14 -1
  1212. package/src/providers/openai/responses-provider.ts +18 -0
  1213. package/src/providers/placeholder-sentinels.ts +50 -15
  1214. package/src/providers/provider-send-message.ts +7 -1
  1215. package/src/providers/ratelimit.ts +6 -0
  1216. package/src/providers/registry.ts +3 -1
  1217. package/src/providers/retry.ts +22 -0
  1218. package/src/providers/stop-reasons.ts +32 -0
  1219. package/src/providers/tool-progress-events.test.ts +50 -0
  1220. package/src/providers/tool-progress-events.ts +99 -0
  1221. package/src/providers/types.ts +14 -1
  1222. package/src/providers/usage-tracking.ts +7 -1
  1223. package/src/runtime/__tests__/agent-wake.test.ts +100 -29
  1224. package/src/runtime/__tests__/background-job-runner.test.ts +19 -2
  1225. package/src/runtime/__tests__/channel-verification-service.test.ts +9 -5
  1226. package/src/runtime/__tests__/guardian-vellum-migration.test.ts +37 -32
  1227. package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +3 -3
  1228. package/src/runtime/__tests__/local-principal-trust.test.ts +16 -18
  1229. package/src/runtime/__tests__/member-verdict-cache.test.ts +119 -0
  1230. package/src/runtime/__tests__/pre-first-message-gate.test.ts +1 -1
  1231. package/src/runtime/__tests__/trust-verdict-consumer.test.ts +115 -168
  1232. package/src/runtime/access-request-helper.ts +4 -5
  1233. package/src/runtime/actor-trust-resolver.ts +44 -17
  1234. package/src/runtime/agent-wake.ts +69 -12
  1235. package/src/runtime/anchored-guardian.test.ts +7 -54
  1236. package/src/runtime/anchored-guardian.ts +4 -53
  1237. package/src/runtime/assistant-event-hub.ts +1 -1
  1238. package/src/runtime/assistant-event.ts +86 -12
  1239. package/src/runtime/assistant-stream-state.ts +12 -74
  1240. package/src/runtime/background-job-runner.ts +30 -10
  1241. package/src/runtime/channel-reply-delivery.ts +6 -11
  1242. package/src/runtime/channel-retry-sweep.ts +23 -3
  1243. package/src/runtime/channel-verification-service.ts +9 -9
  1244. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  1245. package/src/runtime/finalize-event-delivery.ts +2 -2
  1246. package/src/runtime/guardian-action-service.ts +1 -2
  1247. package/src/runtime/guardian-reply-router.ts +1 -1
  1248. package/src/runtime/guardian-vellum-migration.ts +18 -16
  1249. package/src/runtime/http-server.ts +45 -1
  1250. package/src/runtime/invite-redemption-service.ts +36 -13
  1251. package/src/runtime/invite-service.ts +6 -4
  1252. package/src/runtime/local-actor-identity.test.ts +108 -0
  1253. package/src/runtime/local-actor-identity.ts +27 -20
  1254. package/src/runtime/member-verdict-cache.ts +0 -0
  1255. package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +28 -0
  1256. package/src/runtime/migrations/vbundle-streaming-importer.ts +1 -1
  1257. package/src/runtime/pre-first-message-gate.ts +1 -1
  1258. package/src/runtime/routes/__tests__/acp-routes.test.ts +74 -8
  1259. package/src/runtime/routes/__tests__/backup-routes.test.ts +1 -1
  1260. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +3 -3
  1261. package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +17 -23
  1262. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +3 -3
  1263. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +5 -5
  1264. package/src/runtime/routes/__tests__/contact-routes.test.ts +188 -14
  1265. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +5 -5
  1266. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +5 -5
  1267. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +3 -3
  1268. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +12 -12
  1269. package/src/runtime/routes/__tests__/conversation-surface-routes.test.ts +4 -4
  1270. package/src/runtime/routes/__tests__/global-search-routes.test.ts +1 -2
  1271. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +3 -3
  1272. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +3 -3
  1273. package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +21 -7
  1274. package/src/runtime/routes/__tests__/memory-worker-routes.test.ts +306 -0
  1275. package/src/runtime/routes/__tests__/migration-import-allowed-hosts-env.test.ts +70 -0
  1276. package/src/runtime/routes/__tests__/plugins-routes.test.ts +395 -26
  1277. package/src/runtime/routes/__tests__/ps-routes.test.ts +114 -0
  1278. package/src/runtime/routes/__tests__/retrospective-routes.test.ts +6 -6
  1279. package/src/runtime/routes/__tests__/schedule-routes-create.test.ts +72 -0
  1280. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +4 -4
  1281. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +3 -2
  1282. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +1 -1
  1283. package/src/runtime/routes/__tests__/wake-conversation-routes.test.ts +125 -0
  1284. package/src/runtime/routes/acp-routes-event-log.test.ts +283 -0
  1285. package/src/runtime/routes/acp-routes-list.test.ts +24 -25
  1286. package/src/runtime/routes/acp-routes.test.ts +4 -4
  1287. package/src/runtime/routes/acp-routes.ts +31 -4
  1288. package/src/runtime/routes/app-management-routes.ts +9 -9
  1289. package/src/runtime/routes/app-routes.ts +3 -7
  1290. package/src/runtime/routes/approval-routes.ts +2 -4
  1291. package/src/runtime/routes/attachment-routes.ts +2 -2
  1292. package/src/runtime/routes/audit-routes.ts +2 -3
  1293. package/src/runtime/routes/background-tool-routes.ts +34 -5
  1294. package/src/runtime/routes/background-wake-routes.ts +19 -5
  1295. package/src/runtime/routes/backup-routes.ts +1 -1
  1296. package/src/runtime/routes/bookmark-routes.ts +3 -3
  1297. package/src/runtime/routes/brain-graph-routes.ts +2 -2
  1298. package/src/runtime/routes/btw-routes.ts +1 -1
  1299. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +1 -1
  1300. package/src/runtime/routes/channel-delivery-routes.ts +1 -1
  1301. package/src/runtime/routes/channel-readiness-routes.ts +7 -3
  1302. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +3 -8
  1303. package/src/runtime/routes/consolidation-routes.ts +6 -6
  1304. package/src/runtime/routes/contact-routes.ts +98 -32
  1305. package/src/runtime/routes/conversation-attention-routes.ts +2 -2
  1306. package/src/runtime/routes/conversation-cli-routes.ts +32 -7
  1307. package/src/runtime/routes/conversation-compaction-routes.ts +4 -4
  1308. package/src/runtime/routes/conversation-list-routes.ts +9 -37
  1309. package/src/runtime/routes/conversation-management-routes.ts +9 -46
  1310. package/src/runtime/routes/conversation-query-routes.ts +35 -11
  1311. package/src/runtime/routes/conversation-routes.ts +174 -23
  1312. package/src/runtime/routes/conversation-starter-routes.ts +11 -5
  1313. package/src/runtime/routes/conversations-import-routes.ts +10 -6
  1314. package/src/runtime/routes/debug-routes.ts +3 -3
  1315. package/src/runtime/routes/defer-routes.ts +4 -4
  1316. package/src/runtime/routes/documents-routes.ts +1 -1
  1317. package/src/runtime/routes/empty-state-greeting-cache.ts +1 -1
  1318. package/src/runtime/routes/events-routes.ts +4 -4
  1319. package/src/runtime/routes/filing-routes.ts +1 -1
  1320. package/src/runtime/routes/global-search-routes.ts +4 -4
  1321. package/src/runtime/routes/group-routes.ts +1 -1
  1322. package/src/runtime/routes/guardian-action-routes.ts +1 -1
  1323. package/src/runtime/routes/heartbeat-routes.ts +2 -2
  1324. package/src/runtime/routes/home-feed-routes.ts +10 -5
  1325. package/src/runtime/routes/identity-routes.ts +33 -14
  1326. package/src/runtime/routes/inbound-conversation.ts +3 -3
  1327. package/src/runtime/routes/inbound-message-handler.ts +25 -25
  1328. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +8 -4
  1329. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +13 -16
  1330. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +5 -5
  1331. package/src/runtime/routes/inbound-stages/background-dispatch.ts +15 -19
  1332. package/src/runtime/routes/inbound-stages/edit-intercept.ts +12 -12
  1333. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +2 -2
  1334. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +1 -1
  1335. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +1 -1
  1336. package/src/runtime/routes/inbound-stages/reaction-intercept.ts +27 -8
  1337. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +5 -2
  1338. package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +1 -1
  1339. package/src/runtime/routes/inbound-stages/transcribe-audio.ts +1 -1
  1340. package/src/runtime/routes/index.ts +8 -4
  1341. package/src/runtime/routes/inference-profile-session-handler.ts +2 -2
  1342. package/src/runtime/routes/inference-profile-session-reaper.ts +1 -1
  1343. package/src/runtime/routes/inference-provider-connection-routes.ts +5 -2
  1344. package/src/runtime/routes/integrations/slack/__tests__/share.test.ts +3 -4
  1345. package/src/runtime/routes/integrations/slack/share.ts +1 -1
  1346. package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
  1347. package/src/runtime/routes/log-export/__tests__/workspace-allowlist-error-contract.test.ts +1 -1
  1348. package/src/runtime/routes/log-export/workspace-allowlist.ts +1 -1
  1349. package/src/runtime/routes/log-export-routes.ts +2 -2
  1350. package/src/runtime/routes/memory-worker-routes.ts +227 -0
  1351. package/src/runtime/routes/migration-rollback-routes.ts +11 -12
  1352. package/src/runtime/routes/migration-routes.ts +211 -10
  1353. package/src/runtime/routes/notification-routes.ts +2 -2
  1354. package/src/runtime/routes/platform-routes.ts +3 -0
  1355. package/src/runtime/routes/playground/helpers.ts +3 -3
  1356. package/src/runtime/routes/plugins-routes.ts +180 -7
  1357. package/src/runtime/routes/ps-routes.ts +37 -66
  1358. package/src/runtime/routes/publish-routes.ts +3 -3
  1359. package/src/runtime/routes/rename-conversation-routes.ts +1 -1
  1360. package/src/runtime/routes/retrospective-routes.ts +5 -5
  1361. package/src/runtime/routes/schedule-routes.ts +88 -45
  1362. package/src/runtime/routes/secret-routes.ts +11 -10
  1363. package/src/runtime/routes/sequence-routes.ts +1 -1
  1364. package/src/runtime/routes/settings-routes.ts +26 -12
  1365. package/src/runtime/routes/skills-routes.ts +11 -1
  1366. package/src/runtime/routes/slack-channel-routes.ts +4 -4
  1367. package/src/runtime/routes/subagents-routes.ts +2 -2
  1368. package/src/runtime/routes/surface-conversation-resolver.ts +1 -1
  1369. package/src/runtime/routes/task-routes.ts +18 -29
  1370. package/src/runtime/routes/telemetry-routes.ts +1 -1
  1371. package/src/runtime/routes/trace-event-routes.ts +1 -1
  1372. package/src/runtime/routes/types.ts +7 -0
  1373. package/src/runtime/routes/usage-routes.ts +2 -2
  1374. package/src/runtime/routes/wake-conversation-routes.ts +44 -8
  1375. package/src/runtime/routes/wipe-conversation-routes.ts +3 -3
  1376. package/src/runtime/routes/work-items-routes.test.ts +1 -1
  1377. package/src/runtime/routes/work-items-routes.ts +1 -1
  1378. package/src/runtime/runtime-mode.ts +5 -7
  1379. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
  1380. package/src/runtime/services/__tests__/auto-analysis-enqueue.test.ts +362 -0
  1381. package/src/runtime/services/__tests__/auto-analysis-guard.test.ts +57 -0
  1382. package/src/runtime/services/__tests__/conversation-analyze-job.test.ts +178 -0
  1383. package/src/runtime/services/__tests__/conversation-serializer.test.ts +1 -1
  1384. package/src/runtime/services/analyze-conversation.ts +22 -13
  1385. package/src/runtime/services/auto-analysis-enqueue.ts +130 -0
  1386. package/src/runtime/services/auto-analysis-guard.ts +13 -0
  1387. package/src/runtime/services/conversation-analyze-job.ts +53 -0
  1388. package/src/runtime/services/conversation-serializer.ts +10 -53
  1389. package/src/runtime/tool-grant-request-helper.ts +1 -1
  1390. package/src/runtime/trust-verdict-consumer.ts +36 -41
  1391. package/src/schedule/__tests__/run-script.test.ts +21 -0
  1392. package/src/schedule/retry-policy.ts +8 -8
  1393. package/src/schedule/run-script.ts +16 -4
  1394. package/src/schedule/schedule-recovery.ts +8 -5
  1395. package/src/schedule/schedule-store.ts +270 -162
  1396. package/src/schedule/schedule-usage-store.ts +2 -2
  1397. package/src/schedule/scheduler-types.ts +6 -0
  1398. package/src/schedule/scheduler.ts +218 -121
  1399. package/src/security/auth-fallback-events-store.ts +94 -0
  1400. package/src/security/redaction.ts +18 -14
  1401. package/src/sequence/engine.ts +1 -1
  1402. package/src/sequence/store.ts +3 -3
  1403. package/src/services/published-app-updater.ts +2 -2
  1404. package/src/signals/cancel.ts +1 -1
  1405. package/src/signals/user-message.ts +2 -2
  1406. package/src/skills/__tests__/categories-cache.test.ts +38 -0
  1407. package/src/skills/catalog-install.ts +2 -1
  1408. package/src/skills/categories-cache.ts +40 -5
  1409. package/src/skills/clawhub.ts +1 -0
  1410. package/src/skills/install-meta.ts +44 -0
  1411. package/src/skills/managed-store.ts +120 -3
  1412. package/src/skills/skillssh-registry.ts +1 -0
  1413. package/src/skills/version-hash.ts +20 -0
  1414. package/src/subagent/__tests__/consult-prompt.test.ts +35 -0
  1415. package/src/subagent/__tests__/consult-transcript.test.ts +184 -0
  1416. package/src/subagent/consult-prompt.ts +57 -0
  1417. package/src/subagent/consult-transcript.ts +86 -0
  1418. package/src/subagent/index.ts +1 -1
  1419. package/src/subagent/manager.ts +502 -72
  1420. package/src/subagent/types.ts +14 -3
  1421. package/src/subagent/validate-allowlists.ts +65 -0
  1422. package/src/tasks/task-compiler.ts +2 -2
  1423. package/src/tasks/task-runner.ts +3 -3
  1424. package/src/tasks/task-store.ts +2 -2
  1425. package/src/telemetry/__tests__/watchdog-events-store.test.ts +161 -0
  1426. package/src/telemetry/skill-loaded-events-store.test.ts +152 -0
  1427. package/src/telemetry/skill-loaded-events-store.ts +95 -0
  1428. package/src/telemetry/tool-executed-events-store.test.ts +219 -0
  1429. package/src/telemetry/tool-executed-events-store.ts +102 -0
  1430. package/src/telemetry/tool-usage-store.ts +114 -0
  1431. package/src/telemetry/trace-event-store.ts +133 -0
  1432. package/src/telemetry/turn-events-store.ts +173 -0
  1433. package/src/telemetry/turn-trace-store.test.ts +736 -0
  1434. package/src/telemetry/turn-trace-store.ts +364 -0
  1435. package/src/telemetry/usage-telemetry-reporter.test.ts +12 -12
  1436. package/src/telemetry/usage-telemetry-reporter.ts +46 -17
  1437. package/src/telemetry/watchdog-events-store.ts +87 -0
  1438. package/src/tools/__tests__/run-standalone.test.ts +19 -0
  1439. package/src/tools/acp/list-agents.test.ts +0 -6
  1440. package/src/tools/acp/spawn.test.ts +18 -7
  1441. package/src/tools/acp/spawn.ts +1 -0
  1442. package/src/tools/apps/executors.ts +2 -2
  1443. package/src/tools/apps/resolve-app-id.ts +1 -1
  1444. package/src/tools/background-tool-registry.ts +61 -0
  1445. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/discovery.test.ts +3 -3
  1446. package/src/tools/document/document-comment-tool.test.ts +2 -2
  1447. package/src/tools/filesystem/write.ts +5 -4
  1448. package/src/tools/host-terminal/host-shell.test.ts +397 -0
  1449. package/src/tools/host-terminal/host-shell.ts +203 -14
  1450. package/src/tools/policy-context.ts +21 -0
  1451. package/src/tools/registry.ts +41 -4
  1452. package/src/tools/run-standalone.ts +101 -0
  1453. package/src/tools/schedule/create.ts +2 -2
  1454. package/src/tools/schedule/delete.ts +1 -1
  1455. package/src/tools/schedule/update.ts +1 -1
  1456. package/src/tools/skills/find-similar-skills.test.ts +277 -0
  1457. package/src/tools/skills/find-similar-skills.ts +120 -0
  1458. package/src/tools/skills/scaffold-managed.ts +123 -4
  1459. package/src/tools/skills/skill-script-runner.ts +17 -0
  1460. package/src/tools/subagent/consult-deadline.ts +49 -0
  1461. package/src/tools/subagent/read.ts +1 -1
  1462. package/src/tools/subagent/spawn.ts +234 -5
  1463. package/src/tools/terminal/safe-env.ts +1 -0
  1464. package/src/tools/terminal/shell.test.ts +177 -0
  1465. package/src/tools/terminal/shell.ts +98 -4
  1466. package/src/tools/tool-approval-handler.ts +1 -1
  1467. package/src/tools/tool-manifest.ts +1 -1
  1468. package/src/tools/tool-types.ts +445 -0
  1469. package/src/tools/types.ts +28 -17
  1470. package/src/usage/types.ts +7 -0
  1471. package/src/util/__tests__/process-tree.test.ts +123 -0
  1472. package/src/util/device-id.ts +52 -12
  1473. package/src/util/logger.ts +9 -0
  1474. package/src/util/process-tree.ts +203 -0
  1475. package/src/util/sqlite-retry.ts +90 -0
  1476. package/src/watcher/__tests__/telemetry.test.ts +2 -2
  1477. package/src/watcher/telemetry.ts +2 -2
  1478. package/src/watcher/watcher-store.ts +3 -3
  1479. package/src/work-items/work-item-store.ts +2 -2
  1480. package/src/workflows/engine-integration.test.ts +2 -2
  1481. package/src/workflows/engine.test.ts +2 -2
  1482. package/src/workflows/fanout-load.test.ts +2 -2
  1483. package/src/workflows/journal-store.test.ts +3 -3
  1484. package/src/workflows/journal-store.ts +1 -1
  1485. package/src/workflows/leaf-runner.test.ts +9 -6
  1486. package/src/workflows/leaf-runner.ts +1 -1
  1487. package/src/workspace/heartbeat-service.ts +29 -0
  1488. package/src/workspace/migrations/011-backfill-installation-id.ts +1 -1
  1489. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +5 -2
  1490. package/src/workspace/migrations/031-drop-user-md.ts +258 -148
  1491. package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +1 -1
  1492. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +1 -1
  1493. package/src/workspace/migrations/112-remove-advisor-callsite-override.ts +64 -0
  1494. package/src/workspace/migrations/113-swap-balanced-profile-to-glm-5p2.ts +101 -0
  1495. package/src/workspace/migrations/114-swap-quality-profile-to-opus.ts +83 -0
  1496. package/src/workspace/migrations/115-drop-frontier-profile.ts +129 -0
  1497. package/src/workspace/migrations/116-rename-memory-plugin-disabled-sentinel.ts +53 -0
  1498. package/src/workspace/migrations/117-normalize-stale-lean-memory-v3-defaults.ts +116 -0
  1499. package/src/workspace/migrations/118-seed-now-md.ts +64 -0
  1500. package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +5 -2
  1501. package/src/workspace/migrations/rebuild-conversation-disk-view.ts +4 -4
  1502. package/src/workspace/migrations/registry.ts +14 -0
  1503. package/drizzle/0000_dizzy_maggott.sql +0 -301
  1504. package/drizzle/meta/0000_snapshot.json +0 -1933
  1505. package/drizzle/meta/_journal.json +0 -13
  1506. package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +0 -887
  1507. package/node_modules/@vellumai/skill-host-contracts/bun.lock +0 -24
  1508. package/node_modules/@vellumai/skill-host-contracts/package.json +0 -18
  1509. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -97
  1510. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +0 -1349
  1511. package/node_modules/@vellumai/skill-host-contracts/src/index.ts +0 -6
  1512. package/node_modules/@vellumai/skill-host-contracts/src/runtime-mode.ts +0 -11
  1513. package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +0 -32
  1514. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +0 -333
  1515. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +0 -446
  1516. package/node_modules/@vellumai/skill-host-contracts/tsconfig.json +0 -20
  1517. package/node_modules/@vellumai/skill-host-contracts/tsconfig.test.json +0 -12
  1518. package/src/__tests__/config-managed-gemini-defaults.test.ts +0 -277
  1519. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +0 -203
  1520. package/src/__tests__/slack-block-formatting.test.ts +0 -210
  1521. package/src/background-wake/runtime-registry.ts +0 -24
  1522. package/src/contacts/contact-events.ts +0 -21
  1523. package/src/daemon/__tests__/daemon-skill-host.test.ts +0 -273
  1524. package/src/daemon/__tests__/meet-host-supervisor.test.ts +0 -587
  1525. package/src/daemon/__tests__/meet-manifest-loader.test.ts +0 -476
  1526. package/src/daemon/daemon-skill-host.ts +0 -262
  1527. package/src/daemon/meet-host-startup.ts +0 -51
  1528. package/src/daemon/meet-host-supervisor.ts +0 -782
  1529. package/src/daemon/meet-manifest-loader.ts +0 -396
  1530. package/src/daemon/memory-v2-startup.test.ts +0 -203
  1531. package/src/daemon/memory-v2-startup.ts +0 -345
  1532. package/src/daemon/message-types/meet.ts +0 -143
  1533. package/src/daemon/server.ts +0 -423
  1534. package/src/daemon/shutdown-registry.ts +0 -40
  1535. package/src/filing/filing-service.ts +0 -429
  1536. package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -253
  1537. package/src/ipc/__tests__/skill-server.test.ts +0 -182
  1538. package/src/ipc/skill-ipc-types.ts +0 -54
  1539. package/src/ipc/skill-routes/__tests__/config.test.ts +0 -146
  1540. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +0 -448
  1541. package/src/ipc/skill-routes/__tests__/identity.test.ts +0 -62
  1542. package/src/ipc/skill-routes/__tests__/log.test.ts +0 -133
  1543. package/src/ipc/skill-routes/__tests__/memory.test.ts +0 -203
  1544. package/src/ipc/skill-routes/__tests__/platform.test.ts +0 -111
  1545. package/src/ipc/skill-routes/__tests__/providers.test.ts +0 -265
  1546. package/src/ipc/skill-routes/__tests__/registries.test.ts +0 -400
  1547. package/src/ipc/skill-routes/config.ts +0 -47
  1548. package/src/ipc/skill-routes/events.ts +0 -147
  1549. package/src/ipc/skill-routes/identity.ts +0 -21
  1550. package/src/ipc/skill-routes/index.ts +0 -37
  1551. package/src/ipc/skill-routes/log.ts +0 -40
  1552. package/src/ipc/skill-routes/memory.ts +0 -92
  1553. package/src/ipc/skill-routes/platform.ts +0 -39
  1554. package/src/ipc/skill-routes/providers.ts +0 -162
  1555. package/src/ipc/skill-routes/registries.ts +0 -340
  1556. package/src/ipc/skill-server.ts +0 -795
  1557. package/src/ipc/skill-socket-path.ts +0 -20
  1558. package/src/memory/__tests__/301-create-watchdog-events.test.ts +0 -110
  1559. package/src/memory/__tests__/activation-session-store.test.ts +0 -41
  1560. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +0 -359
  1561. package/src/memory/__tests__/auto-analysis-guard.test.ts +0 -57
  1562. package/src/memory/__tests__/bookmark-crud.test.ts +0 -264
  1563. package/src/memory/__tests__/bookmark-schema.test.ts +0 -181
  1564. package/src/memory/__tests__/compaction-log-store-clickhouse.test.ts +0 -432
  1565. package/src/memory/__tests__/conversation-analyze-job.test.ts +0 -178
  1566. package/src/memory/__tests__/conversation-group-migration.test.ts +0 -99
  1567. package/src/memory/__tests__/conversation-queries.test.ts +0 -843
  1568. package/src/memory/__tests__/conversation-types.test.ts +0 -36
  1569. package/src/memory/__tests__/db-async-query.test.ts +0 -165
  1570. package/src/memory/__tests__/db-logs-attach.test.ts +0 -110
  1571. package/src/memory/__tests__/db-maintenance.test.ts +0 -235
  1572. package/src/memory/__tests__/db-memory-attach.test.ts +0 -113
  1573. package/src/memory/__tests__/find-analysis-conversation.test.ts +0 -197
  1574. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +0 -140
  1575. package/src/memory/__tests__/fork-message-copy.test.ts +0 -232
  1576. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +0 -241
  1577. package/src/memory/__tests__/jobs-store-job-classes.test.ts +0 -52
  1578. package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +0 -113
  1579. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +0 -505
  1580. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +0 -160
  1581. package/src/memory/__tests__/memory-retrospective-job.test.ts +0 -1443
  1582. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +0 -544
  1583. package/src/memory/__tests__/memory-retrospective-state.test.ts +0 -195
  1584. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +0 -221
  1585. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +0 -275
  1586. package/src/memory/__tests__/memory-v3-selections-migration.test.ts +0 -103
  1587. package/src/memory/__tests__/message-content.test.ts +0 -35
  1588. package/src/memory/__tests__/onboarding-events-store.test.ts +0 -80
  1589. package/src/memory/__tests__/prompt-override.test.ts +0 -192
  1590. package/src/memory/__tests__/qdrant-client-sentinel.test.ts +0 -49
  1591. package/src/memory/__tests__/table-relocation.test.ts +0 -129
  1592. package/src/memory/__tests__/watchdog-events-store.test.ts +0 -161
  1593. package/src/memory/activation-session-store.ts +0 -43
  1594. package/src/memory/anisotropy.ts +0 -443
  1595. package/src/memory/app-store.ts +0 -1058
  1596. package/src/memory/attachments-store.ts +0 -1136
  1597. package/src/memory/auth-fallback-events-store.ts +0 -94
  1598. package/src/memory/auto-analysis-enqueue.ts +0 -127
  1599. package/src/memory/auto-analysis-guard.ts +0 -17
  1600. package/src/memory/canonical-guardian-store.ts +0 -891
  1601. package/src/memory/channel-verification-sessions.ts +0 -557
  1602. package/src/memory/checkpoints.ts +0 -65
  1603. package/src/memory/context-search/agent-protocol.ts +0 -428
  1604. package/src/memory/context-search/agent-runner.ts +0 -1310
  1605. package/src/memory/context-search/search.ts +0 -297
  1606. package/src/memory/context-search/sources/conversations.ts +0 -341
  1607. package/src/memory/context-search/sources/memory-v2.ts +0 -600
  1608. package/src/memory/context-search/sources/memory.ts +0 -101
  1609. package/src/memory/context-search/types.ts +0 -48
  1610. package/src/memory/conversation-analyze-job.ts +0 -53
  1611. package/src/memory/conversation-attention-store.ts +0 -689
  1612. package/src/memory/conversation-bootstrap.ts +0 -50
  1613. package/src/memory/conversation-crud.ts +0 -3361
  1614. package/src/memory/conversation-key-store.ts +0 -274
  1615. package/src/memory/conversation-queries.ts +0 -768
  1616. package/src/memory/conversation-starter-checkpoints.ts +0 -64
  1617. package/src/memory/conversation-title-service.ts +0 -606
  1618. package/src/memory/db-async-query.ts +0 -298
  1619. package/src/memory/db-connection.ts +0 -228
  1620. package/src/memory/db-init.ts +0 -265
  1621. package/src/memory/db-maintenance.ts +0 -154
  1622. package/src/memory/embed.ts +0 -73
  1623. package/src/memory/embedding-backend.test.ts +0 -204
  1624. package/src/memory/embedding-backend.ts +0 -855
  1625. package/src/memory/embedding-billing-breaker.ts +0 -96
  1626. package/src/memory/embedding-local.ts +0 -587
  1627. package/src/memory/embedding-ollama.ts +0 -79
  1628. package/src/memory/embedding-runtime-manager.ts +0 -573
  1629. package/src/memory/embedding-types.ts +0 -90
  1630. package/src/memory/external-conversation-store.ts +0 -315
  1631. package/src/memory/fork-message-copy.ts +0 -170
  1632. package/src/memory/graph/__tests__/conversation-graph-memory-registry.test.ts +0 -119
  1633. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +0 -655
  1634. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +0 -321
  1635. package/src/memory/graph/bootstrap.test.ts +0 -280
  1636. package/src/memory/graph/bootstrap.ts +0 -532
  1637. package/src/memory/graph/capability-seed.ts +0 -451
  1638. package/src/memory/graph/consolidation.ts +0 -712
  1639. package/src/memory/graph/conversation-graph-memory.ts +0 -1185
  1640. package/src/memory/graph/decay.ts +0 -195
  1641. package/src/memory/graph/extraction-job.ts +0 -74
  1642. package/src/memory/graph/extraction.ts +0 -1462
  1643. package/src/memory/graph/graph-memory-state-store.ts +0 -50
  1644. package/src/memory/graph/graph-search.test.ts +0 -129
  1645. package/src/memory/graph/graph-search.ts +0 -292
  1646. package/src/memory/graph/image-ref-utils.ts +0 -29
  1647. package/src/memory/graph/injection.ts +0 -469
  1648. package/src/memory/graph/narrative.ts +0 -267
  1649. package/src/memory/graph/pattern-scan.ts +0 -269
  1650. package/src/memory/graph/retriever.test.ts +0 -624
  1651. package/src/memory/graph/retriever.ts +0 -1356
  1652. package/src/memory/graph/store.test.ts +0 -1093
  1653. package/src/memory/graph/store.ts +0 -923
  1654. package/src/memory/graph/tool-handlers.ts +0 -195
  1655. package/src/memory/graph/tools.ts +0 -95
  1656. package/src/memory/guardian-rate-limits.ts +0 -191
  1657. package/src/memory/indexer.ts +0 -406
  1658. package/src/memory/job-handlers/backfill.ts +0 -104
  1659. package/src/memory/job-handlers/cleanup.ts +0 -237
  1660. package/src/memory/job-handlers/conversation-starters.ts +0 -481
  1661. package/src/memory/job-handlers/embedding.test.ts +0 -234
  1662. package/src/memory/job-handlers/embedding.ts +0 -133
  1663. package/src/memory/job-handlers/index-maintenance.ts +0 -111
  1664. package/src/memory/job-handlers/media-processing.ts +0 -120
  1665. package/src/memory/job-handlers/summarization.ts +0 -240
  1666. package/src/memory/job-utils.ts +0 -286
  1667. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +0 -559
  1668. package/src/memory/jobs/embed-concept-page.ts +0 -417
  1669. package/src/memory/jobs/embed-pkb-file.test.ts +0 -169
  1670. package/src/memory/jobs/embed-pkb-file.ts +0 -59
  1671. package/src/memory/jobs-store.ts +0 -813
  1672. package/src/memory/jobs-worker.ts +0 -975
  1673. package/src/memory/llm-request-log-source-clickhouse.ts +0 -521
  1674. package/src/memory/llm-request-log-store.ts +0 -717
  1675. package/src/memory/llm-usage-store.ts +0 -900
  1676. package/src/memory/memory-recall-log-store.ts +0 -172
  1677. package/src/memory/memory-retrospective-constants.ts +0 -50
  1678. package/src/memory/memory-retrospective-enqueue.ts +0 -125
  1679. package/src/memory/memory-retrospective-fork-boundary.ts +0 -94
  1680. package/src/memory/memory-retrospective-job.ts +0 -879
  1681. package/src/memory/memory-retrospective-startup-cleanup.ts +0 -261
  1682. package/src/memory/memory-retrospective-state.ts +0 -245
  1683. package/src/memory/memory-retrospective-trigger-check.ts +0 -91
  1684. package/src/memory/memory-v2-activation-log-store.ts +0 -216
  1685. package/src/memory/memory-v2-concept-frequency.ts +0 -173
  1686. package/src/memory/migrations/126-backfill-guardian-principal-id.ts +0 -303
  1687. package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +0 -365
  1688. package/src/memory/migrations/142-rename-verification-session-id-column.ts +0 -55
  1689. package/src/memory/migrations/182-oauth-providers-display-metadata.ts +0 -20
  1690. package/src/memory/migrations/196-strip-integration-prefix-from-provider-keys.ts +0 -179
  1691. package/src/memory/migrations/199-guardian-request-enrichment-columns.ts +0 -64
  1692. package/src/memory/migrations/202-memory-graph-tables.ts +0 -130
  1693. package/src/memory/migrations/203-drop-memory-items-tables.ts +0 -55
  1694. package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +0 -124
  1695. package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +0 -152
  1696. package/src/memory/migrations/211-memory-recall-logs-query-context.ts +0 -16
  1697. package/src/memory/migrations/220-normalize-user-file-by-principal.ts +0 -183
  1698. package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +0 -76
  1699. package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +0 -21
  1700. package/src/memory/migrations/243-provider-connections.ts +0 -68
  1701. package/src/memory/migrations/244-provider-connection-status-label.ts +0 -23
  1702. package/src/memory/migrations/246-backfill-provider-connection-label.ts +0 -81
  1703. package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +0 -19
  1704. package/src/memory/migrations/301-create-watchdog-events.ts +0 -45
  1705. package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +0 -224
  1706. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +0 -84
  1707. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +0 -192
  1708. package/src/memory/migrations/__tests__/run-migrations.test.ts +0 -378
  1709. package/src/memory/migrations/helpers/relocation.ts +0 -227
  1710. package/src/memory/migrations/validate-migration-state.ts +0 -277
  1711. package/src/memory/onboarding-events-store.ts +0 -161
  1712. package/src/memory/pkb/autoinject.ts +0 -61
  1713. package/src/memory/pkb/context.ts +0 -50
  1714. package/src/memory/pkb/pkb-index.test.ts +0 -368
  1715. package/src/memory/pkb/pkb-index.ts +0 -255
  1716. package/src/memory/pkb/pkb-reconcile.test.ts +0 -251
  1717. package/src/memory/pkb/pkb-reconcile.ts +0 -148
  1718. package/src/memory/pkb/pkb-search.test.ts +0 -586
  1719. package/src/memory/pkb/pkb-search.ts +0 -178
  1720. package/src/memory/pkb/types.ts +0 -67
  1721. package/src/memory/published-pages-store.ts +0 -67
  1722. package/src/memory/qdrant-circuit-breaker.ts +0 -119
  1723. package/src/memory/qdrant-client.test.ts +0 -60
  1724. package/src/memory/qdrant-client.ts +0 -834
  1725. package/src/memory/qdrant-manager.ts +0 -422
  1726. package/src/memory/rerank-local.ts +0 -374
  1727. package/src/memory/schedule-attribution-sql.ts +0 -104
  1728. package/src/memory/schema/acp.ts +0 -34
  1729. package/src/memory/schema/contacts.ts +0 -116
  1730. package/src/memory/schema/conversations.ts +0 -197
  1731. package/src/memory/schema/infrastructure.ts +0 -381
  1732. package/src/memory/scoped-approval-grants.ts +0 -551
  1733. package/src/memory/search/semantic.ts +0 -238
  1734. package/src/memory/segmenter.ts +0 -76
  1735. package/src/memory/shared-app-links-store.ts +0 -130
  1736. package/src/memory/skill-loaded-events-store.test.ts +0 -152
  1737. package/src/memory/skill-loaded-events-store.ts +0 -95
  1738. package/src/memory/sparse-tokenize.ts +0 -49
  1739. package/src/memory/steps.ts +0 -573
  1740. package/src/memory/task-memory-cleanup.ts +0 -236
  1741. package/src/memory/tool-executed-events-store.test.ts +0 -219
  1742. package/src/memory/tool-executed-events-store.ts +0 -102
  1743. package/src/memory/tool-usage-store.ts +0 -113
  1744. package/src/memory/trace-event-store.ts +0 -133
  1745. package/src/memory/turn-events-store.ts +0 -173
  1746. package/src/memory/turn-trace-store.test.ts +0 -736
  1747. package/src/memory/turn-trace-store.ts +0 -364
  1748. package/src/memory/v2/__tests__/activation-store.test.ts +0 -204
  1749. package/src/memory/v2/__tests__/activation.test.ts +0 -1227
  1750. package/src/memory/v2/__tests__/backfill-jobs.test.ts +0 -504
  1751. package/src/memory/v2/__tests__/cli-command-store.test.ts +0 -429
  1752. package/src/memory/v2/__tests__/consolidation-job.test.ts +0 -747
  1753. package/src/memory/v2/__tests__/consolidation-prompt-flag-gating-guard.test.ts +0 -189
  1754. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +0 -136
  1755. package/src/memory/v2/__tests__/harness-compare.test.ts +0 -186
  1756. package/src/memory/v2/__tests__/harness-oracle.test.ts +0 -257
  1757. package/src/memory/v2/__tests__/harness-replay-input.test.ts +0 -230
  1758. package/src/memory/v2/__tests__/harness-runner.test.ts +0 -135
  1759. package/src/memory/v2/__tests__/injection-events.test.ts +0 -318
  1760. package/src/memory/v2/__tests__/injection.test.ts +0 -2301
  1761. package/src/memory/v2/__tests__/migration.test.ts +0 -939
  1762. package/src/memory/v2/__tests__/page-index.test.ts +0 -760
  1763. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +0 -313
  1764. package/src/memory/v2/__tests__/qdrant.test.ts +0 -950
  1765. package/src/memory/v2/__tests__/reranker.test.ts +0 -338
  1766. package/src/memory/v2/__tests__/router.test.ts +0 -1197
  1767. package/src/memory/v2/__tests__/sim.test.ts +0 -670
  1768. package/src/memory/v2/__tests__/skill-content.test.ts +0 -115
  1769. package/src/memory/v2/__tests__/skill-store.test.ts +0 -983
  1770. package/src/memory/v2/__tests__/sparse-bm25.test.ts +0 -292
  1771. package/src/memory/v2/__tests__/static-context.test.ts +0 -223
  1772. package/src/memory/v2/__tests__/sweep-job.test.ts +0 -526
  1773. package/src/memory/v2/activation-store.ts +0 -185
  1774. package/src/memory/v2/activation.ts +0 -548
  1775. package/src/memory/v2/backfill-jobs.ts +0 -296
  1776. package/src/memory/v2/cli-command-store.ts +0 -341
  1777. package/src/memory/v2/consolidation-job.ts +0 -561
  1778. package/src/memory/v2/frontmatter-sweep.ts +0 -98
  1779. package/src/memory/v2/harness/compare.ts +0 -57
  1780. package/src/memory/v2/harness/oracle.ts +0 -145
  1781. package/src/memory/v2/harness/replay-input.ts +0 -240
  1782. package/src/memory/v2/harness/retriever.ts +0 -74
  1783. package/src/memory/v2/harness/router-retriever.ts +0 -43
  1784. package/src/memory/v2/injected-block-slugs.ts +0 -79
  1785. package/src/memory/v2/injection-events.ts +0 -101
  1786. package/src/memory/v2/injection.ts +0 -932
  1787. package/src/memory/v2/migration.ts +0 -776
  1788. package/src/memory/v2/page-index.ts +0 -459
  1789. package/src/memory/v2/page-store.ts +0 -443
  1790. package/src/memory/v2/prompts/consolidation.ts +0 -857
  1791. package/src/memory/v2/prompts/router.ts +0 -148
  1792. package/src/memory/v2/qdrant.ts +0 -892
  1793. package/src/memory/v2/reranker.ts +0 -184
  1794. package/src/memory/v2/router.ts +0 -601
  1795. package/src/memory/v2/sim.ts +0 -296
  1796. package/src/memory/v2/skill-content.ts +0 -61
  1797. package/src/memory/v2/skill-store.ts +0 -431
  1798. package/src/memory/v2/sparse-bm25.ts +0 -245
  1799. package/src/memory/v2/static-context.ts +0 -100
  1800. package/src/memory/v2/sweep-job.ts +0 -320
  1801. package/src/memory/v3-eval/eval-packets.ts +0 -731
  1802. package/src/memory/watchdog-events-store.ts +0 -87
  1803. package/src/memory/worker-control.ts +0 -118
  1804. package/src/memory/worker-process.ts +0 -72
  1805. package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +0 -56
  1806. package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +0 -43
  1807. package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +0 -137
  1808. package/src/plugins/defaults/advisor/__tests__/consult.test.ts +0 -314
  1809. package/src/plugins/defaults/advisor/__tests__/context-pack-gating.test.ts +0 -106
  1810. package/src/plugins/defaults/advisor/__tests__/context-pack.test.ts +0 -60
  1811. package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +0 -138
  1812. package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +0 -147
  1813. package/src/plugins/defaults/advisor/advisor-gate.ts +0 -29
  1814. package/src/plugins/defaults/advisor/advisor-state-store.ts +0 -94
  1815. package/src/plugins/defaults/advisor/config.ts +0 -21
  1816. package/src/plugins/defaults/advisor/consult.ts +0 -197
  1817. package/src/plugins/defaults/advisor/context-pack.ts +0 -288
  1818. package/src/plugins/defaults/advisor/hooks/post-model-call.ts +0 -34
  1819. package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +0 -30
  1820. package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +0 -19
  1821. package/src/plugins/defaults/advisor/package.json +0 -14
  1822. package/src/plugins/defaults/advisor/steering.ts +0 -79
  1823. package/src/plugins/defaults/advisor/tools/advisor.ts +0 -92
  1824. package/src/plugins/defaults/advisor/transcript.ts +0 -76
  1825. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +0 -116
  1826. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +0 -370
  1827. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +0 -41
  1828. package/src/plugins/defaults/memory-retrieval/injectors.ts +0 -1061
  1829. package/src/plugins/defaults/memory-retrieval/package.json +0 -14
  1830. package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +0 -64
  1831. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +0 -231
  1832. package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +0 -1164
  1833. package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +0 -181
  1834. package/src/plugins/defaults/memory-v3-shadow/__tests__/edge.test.ts +0 -247
  1835. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +0 -717
  1836. package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +0 -365
  1837. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +0 -736
  1838. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +0 -839
  1839. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +0 -598
  1840. package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +0 -128
  1841. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +0 -469
  1842. package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +0 -425
  1843. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +0 -493
  1844. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +0 -856
  1845. package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +0 -91
  1846. package/src/plugins/defaults/memory-v3-shadow/card.ts +0 -160
  1847. package/src/plugins/defaults/memory-v3-shadow/dense.ts +0 -97
  1848. package/src/plugins/defaults/memory-v3-shadow/edge.ts +0 -252
  1849. package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.test.ts +0 -305
  1850. package/src/plugins/defaults/memory-v3-shadow/ever-injected-store.ts +0 -278
  1851. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +0 -14
  1852. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +0 -19
  1853. package/src/plugins/defaults/memory-v3-shadow/hot-set.test.ts +0 -138
  1854. package/src/plugins/defaults/memory-v3-shadow/hot-set.ts +0 -85
  1855. package/src/plugins/defaults/memory-v3-shadow/injector.ts +0 -453
  1856. package/src/plugins/defaults/memory-v3-shadow/learned-edges.test.ts +0 -169
  1857. package/src/plugins/defaults/memory-v3-shadow/learned-edges.ts +0 -178
  1858. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +0 -794
  1859. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +0 -431
  1860. package/src/plugins/defaults/memory-v3-shadow/package.json +0 -14
  1861. package/src/plugins/defaults/memory-v3-shadow/page-content.ts +0 -102
  1862. package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +0 -146
  1863. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +0 -578
  1864. package/src/plugins/defaults/memory-v3-shadow/prune.test.ts +0 -758
  1865. package/src/plugins/defaults/memory-v3-shadow/prune.ts +0 -471
  1866. package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +0 -92
  1867. package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +0 -269
  1868. package/src/plugins/defaults/memory-v3-shadow/section-needle.ts +0 -200
  1869. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +0 -281
  1870. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +0 -642
  1871. package/src/plugins/defaults/memory-v3-shadow/types.ts +0 -127
  1872. package/src/plugins/feature-gate.ts +0 -22
  1873. package/src/runtime/__tests__/slack-block-formatting.test.ts +0 -510
  1874. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +0 -165
  1875. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +0 -347
  1876. package/src/runtime/routes/memory-eval-routes.ts +0 -179
  1877. package/src/runtime/routes/memory-item-routes.test.ts +0 -912
  1878. package/src/runtime/routes/memory-item-routes.ts +0 -815
  1879. package/src/runtime/routes/memory-v2-routes.ts +0 -850
  1880. package/src/runtime/routes/memory-v3-routes.ts +0 -122
  1881. package/src/runtime/routes/secrets-deps.ts +0 -24
  1882. package/src/runtime/slack-block-formatting.ts +0 -601
  1883. package/src/tools/memory/register.test.ts +0 -382
  1884. package/src/tools/memory/register.ts +0 -81
  1885. /package/src/{memory → apps}/app-git-service.ts +0 -0
  1886. /package/src/{memory → channels}/slack-thread-store.ts +0 -0
  1887. /package/src/{memory → home}/conversation-starter-validation.ts +0 -0
  1888. /package/src/{memory → persistence}/auto-analysis-constants.ts +0 -0
  1889. /package/src/{memory → persistence}/bookmark-crud.ts +0 -0
  1890. /package/src/{memory → persistence}/cleanup-schedule-state.ts +0 -0
  1891. /package/src/{memory → persistence}/compaction-log-store-clickhouse.ts +0 -0
  1892. /package/src/{memory → persistence}/conversation-directories.ts +0 -0
  1893. /package/src/{memory → persistence}/conversation-disk-view.ts +0 -0
  1894. /package/src/{memory → persistence}/conversation-display-order-migration.ts +0 -0
  1895. /package/src/{memory → persistence}/conversation-group-migration.ts +0 -0
  1896. /package/src/{memory → persistence}/conversation-types.ts +0 -0
  1897. /package/src/{memory → persistence}/db-singleton.ts +0 -0
  1898. /package/src/{memory → persistence}/delivery-channels.ts +0 -0
  1899. /package/src/{memory → persistence}/delivery-crud.ts +0 -0
  1900. /package/src/{memory → persistence}/delivery-status.ts +0 -0
  1901. /package/src/{memory → persistence/embeddings}/__tests__/sparse-tokenize.test.ts +0 -0
  1902. /package/src/{memory → persistence/embeddings}/embedding-gemini.test.ts +0 -0
  1903. /package/src/{memory → persistence/embeddings}/embedding-gemini.ts +0 -0
  1904. /package/src/{memory → persistence/embeddings}/embedding-openai.ts +0 -0
  1905. /package/src/{memory → persistence/embeddings}/embedding-types.test.ts +0 -0
  1906. /package/src/{memory → persistence}/fingerprint.ts +0 -0
  1907. /package/src/{memory → persistence}/group-crud.ts +0 -0
  1908. /package/src/{memory → persistence}/invite-store.ts +0 -0
  1909. /package/src/{memory → persistence}/lifecycle-events-store.ts +0 -0
  1910. /package/src/{memory → persistence}/llm-request-log-source-local.ts +0 -0
  1911. /package/src/{memory → persistence}/llm-request-log-source.ts +0 -0
  1912. /package/src/{memory → persistence}/media-store.ts +0 -0
  1913. /package/src/{memory → persistence}/message-content.ts +0 -0
  1914. /package/src/{memory → persistence}/migrations/000-core-tables.ts +0 -0
  1915. /package/src/{memory → persistence}/migrations/001-job-deferrals.ts +0 -0
  1916. /package/src/{memory → persistence}/migrations/002-tool-invocations-fk.ts +0 -0
  1917. /package/src/{memory → persistence}/migrations/003-memory-fts-backfill.ts +0 -0
  1918. /package/src/{memory → persistence}/migrations/004-entity-relation-dedup.ts +0 -0
  1919. /package/src/{memory → persistence}/migrations/005-fingerprint-scope-unique.ts +0 -0
  1920. /package/src/{memory → persistence}/migrations/006-scope-salted-fingerprints.ts +0 -0
  1921. /package/src/{memory → persistence}/migrations/007-assistant-id-to-self.ts +0 -0
  1922. /package/src/{memory → persistence}/migrations/008-remove-assistant-id-columns.ts +0 -0
  1923. /package/src/{memory → persistence}/migrations/009-llm-usage-events-drop-assistant-id.ts +0 -0
  1924. /package/src/{memory → persistence}/migrations/011-call-sessions-provider-sid-dedup.ts +0 -0
  1925. /package/src/{memory → persistence}/migrations/012-call-sessions-add-initiated-from.ts +0 -0
  1926. /package/src/{memory → persistence}/migrations/013-guardian-action-tables.ts +0 -0
  1927. /package/src/{memory → persistence}/migrations/014-backfill-inbox-thread-state.ts +0 -0
  1928. /package/src/{memory → persistence}/migrations/015-drop-active-search-index.ts +0 -0
  1929. /package/src/{memory → persistence}/migrations/016-memory-segments-indexes.ts +0 -0
  1930. /package/src/{memory → persistence}/migrations/017-memory-items-indexes.ts +0 -0
  1931. /package/src/{memory → persistence}/migrations/018-remaining-table-indexes.ts +0 -0
  1932. /package/src/{memory → persistence}/migrations/019-notification-tables-schema-migration.ts +0 -0
  1933. /package/src/{memory → persistence}/migrations/020-rename-macos-ios-channel-to-vellum.ts +0 -0
  1934. /package/src/{memory → persistence}/migrations/021-conversation-status-indexes.ts +0 -0
  1935. /package/src/{memory → persistence}/migrations/022-add-origin-interface.ts +0 -0
  1936. /package/src/{memory → persistence}/migrations/023-memory-item-sources-indexes.ts +0 -0
  1937. /package/src/{memory → persistence}/migrations/024-embedding-vector-blob.ts +0 -0
  1938. /package/src/{memory → persistence}/migrations/025-messages-fts-backfill.ts +0 -0
  1939. /package/src/{memory → persistence}/migrations/026-guardian-verification-sessions.ts +0 -0
  1940. /package/src/{memory → persistence}/migrations/026a-embeddings-nullable-vector-json.ts +0 -0
  1941. /package/src/{memory → persistence}/migrations/027-notification-delivery-pairing-columns.ts +0 -0
  1942. /package/src/{memory → persistence}/migrations/027a-guardian-bootstrap-token.ts +0 -0
  1943. /package/src/{memory → persistence}/migrations/028-call-session-mode.ts +0 -0
  1944. /package/src/{memory → persistence}/migrations/028-notification-delivery-client-ack.ts +0 -0
  1945. /package/src/{memory → persistence}/migrations/029-channel-inbound-delivered-segments.ts +0 -0
  1946. /package/src/{memory → persistence}/migrations/030-guardian-action-followup.ts +0 -0
  1947. /package/src/{memory → persistence}/migrations/030-guardian-verification-purpose.ts +0 -0
  1948. /package/src/{memory → persistence}/migrations/031-conversations-thread-type-index.ts +0 -0
  1949. /package/src/{memory → persistence}/migrations/032-guardian-delivery-conversation-index.ts +0 -0
  1950. /package/src/{memory → persistence}/migrations/032-notification-delivery-thread-decision.ts +0 -0
  1951. /package/src/{memory → persistence}/migrations/033-scoped-approval-grants.ts +0 -0
  1952. /package/src/{memory → persistence}/migrations/034-guardian-action-tool-metadata.ts +0 -0
  1953. /package/src/{memory → persistence}/migrations/035-guardian-action-supersession.ts +0 -0
  1954. /package/src/{memory → persistence}/migrations/036-normalize-phone-identities.ts +0 -0
  1955. /package/src/{memory → persistence}/migrations/037-voice-invite-columns.ts +0 -0
  1956. /package/src/{memory → persistence}/migrations/040-invite-code-hash-column.ts +0 -0
  1957. /package/src/{memory → persistence}/migrations/041-approval-prompt-ts-tracker.ts +0 -0
  1958. /package/src/{memory → persistence}/migrations/101-watchers-and-logs.ts +0 -0
  1959. /package/src/{memory → persistence}/migrations/102-alter-table-columns.ts +0 -0
  1960. /package/src/{memory → persistence}/migrations/104-core-indexes.ts +0 -0
  1961. /package/src/{memory → persistence}/migrations/105-contacts-and-triage.ts +0 -0
  1962. /package/src/{memory → persistence}/migrations/106-call-sessions.ts +0 -0
  1963. /package/src/{memory → persistence}/migrations/107-followups.ts +0 -0
  1964. /package/src/{memory → persistence}/migrations/108-tasks-and-work-items.ts +0 -0
  1965. /package/src/{memory → persistence}/migrations/109-external-conversation-bindings.ts +0 -0
  1966. /package/src/{memory → persistence}/migrations/110-channel-guardian.ts +0 -0
  1967. /package/src/{memory → persistence}/migrations/111-media-assets.ts +0 -0
  1968. /package/src/{memory → persistence}/migrations/112-assistant-inbox.ts +0 -0
  1969. /package/src/{memory → persistence}/migrations/114-notifications.ts +0 -0
  1970. /package/src/{memory → persistence}/migrations/115-sequences.ts +0 -0
  1971. /package/src/{memory → persistence}/migrations/116-messages-fts.ts +0 -0
  1972. /package/src/{memory → persistence}/migrations/117-conversation-attention.ts +0 -0
  1973. /package/src/{memory → persistence}/migrations/118-reminder-routing-intent.ts +0 -0
  1974. /package/src/{memory → persistence}/migrations/119-schema-indexes-and-columns.ts +0 -0
  1975. /package/src/{memory → persistence}/migrations/120-fk-cascade-rebuilds.ts +0 -0
  1976. /package/src/{memory → persistence}/migrations/121-canonical-guardian-requests.ts +0 -0
  1977. /package/src/{memory → persistence}/migrations/122-canonical-guardian-requester-chat-id.ts +0 -0
  1978. /package/src/{memory → persistence}/migrations/123-canonical-guardian-deliveries-destination-index.ts +0 -0
  1979. /package/src/{memory → persistence}/migrations/124-voice-invite-display-metadata.ts +0 -0
  1980. /package/src/{memory → persistence}/migrations/125-guardian-principal-id-columns.ts +0 -0
  1981. /package/src/{memory → persistence}/migrations/127-guardian-principal-id-not-null.ts +0 -0
  1982. /package/src/{memory → persistence}/migrations/128-contacts-role-principal.ts +0 -0
  1983. /package/src/{memory → persistence}/migrations/129-contact-channels-access-fields.ts +0 -0
  1984. /package/src/{memory → persistence}/migrations/130-contact-channels-type-ext-chat-id-index.ts +0 -0
  1985. /package/src/{memory → persistence}/migrations/131-drop-legacy-member-guardian-tables.ts +0 -0
  1986. /package/src/{memory → persistence}/migrations/132-contacts-assistant-id.ts +0 -0
  1987. /package/src/{memory → persistence}/migrations/133-assistant-contact-metadata.ts +0 -0
  1988. /package/src/{memory → persistence}/migrations/134-contacts-notes-column.ts +0 -0
  1989. /package/src/{memory → persistence}/migrations/135-backfill-contact-interaction-stats.ts +0 -0
  1990. /package/src/{memory → persistence}/migrations/136-drop-assistant-id-columns.ts +0 -0
  1991. /package/src/{memory → persistence}/migrations/137-usage-dashboard-indexes.ts +0 -0
  1992. /package/src/{memory → persistence}/migrations/139-drop-usage-composite-indexes.ts +0 -0
  1993. /package/src/{memory → persistence}/migrations/141-rename-verification-table.ts +0 -0
  1994. /package/src/{memory → persistence}/migrations/143-rename-guardian-verification-values.ts +0 -0
  1995. /package/src/{memory → persistence}/migrations/144-rename-voice-to-phone.ts +0 -0
  1996. /package/src/{memory → persistence}/migrations/145-drop-accounts-table.ts +0 -0
  1997. /package/src/{memory → persistence}/migrations/146-schedule-oneshot-routing.ts +0 -0
  1998. /package/src/{memory → persistence}/migrations/147-migrate-reminders-to-schedules.ts +0 -0
  1999. /package/src/{memory → persistence}/migrations/148-drop-reminders-table.ts +0 -0
  2000. /package/src/{memory → persistence}/migrations/149-oauth-tables.ts +0 -0
  2001. /package/src/{memory → persistence}/migrations/150-oauth-apps-client-secret-path.ts +0 -0
  2002. /package/src/{memory → persistence}/migrations/151-oauth-providers-ping-url.ts +0 -0
  2003. /package/src/{memory → persistence}/migrations/152-memory-item-supersession.ts +0 -0
  2004. /package/src/{memory → persistence}/migrations/153-drop-entity-tables.ts +0 -0
  2005. /package/src/{memory → persistence}/migrations/154-drop-fts.ts +0 -0
  2006. /package/src/{memory → persistence}/migrations/155-drop-conflicts.ts +0 -0
  2007. /package/src/{memory → persistence}/migrations/156-call-session-invite-metadata.ts +0 -0
  2008. /package/src/{memory → persistence}/migrations/157-invite-contact-id.ts +0 -0
  2009. /package/src/{memory → persistence}/migrations/158-channel-interaction-columns.ts +0 -0
  2010. /package/src/{memory → persistence}/migrations/159-drop-contact-interaction-columns.ts +0 -0
  2011. /package/src/{memory → persistence}/migrations/160-drop-loopback-port-column.ts +0 -0
  2012. /package/src/{memory → persistence}/migrations/161-drop-orphaned-media-tables.ts +0 -0
  2013. /package/src/{memory → persistence}/migrations/162-guardian-timestamps-epoch-ms.ts +0 -0
  2014. /package/src/{memory → persistence}/migrations/163-rename-notification-thread-columns.ts +0 -0
  2015. /package/src/{memory → persistence}/migrations/164-rename-conversation-type-column.ts +0 -0
  2016. /package/src/{memory → persistence}/migrations/165-rename-inbox-thread-state-table.ts +0 -0
  2017. /package/src/{memory → persistence}/migrations/166-rename-followups-thread-id.ts +0 -0
  2018. /package/src/{memory → persistence}/migrations/167-rename-sequence-enrollments-thread-id.ts +0 -0
  2019. /package/src/{memory → persistence}/migrations/168-rename-sequence-steps-reply-key.ts +0 -0
  2020. /package/src/{memory → persistence}/migrations/169-rename-gmail-provider-key-to-google.ts +0 -0
  2021. /package/src/{memory → persistence}/migrations/170-thread-starters-table.ts +0 -0
  2022. /package/src/{memory → persistence}/migrations/171-capability-card-columns.ts +0 -0
  2023. /package/src/{memory → persistence}/migrations/172-rename-created-by-session-id.ts +0 -0
  2024. /package/src/{memory → persistence}/migrations/173-rename-source-session-id.ts +0 -0
  2025. /package/src/{memory → persistence}/migrations/174-rename-thread-starters-table.ts +0 -0
  2026. /package/src/{memory → persistence}/migrations/175-create-lifecycle-events.ts +0 -0
  2027. /package/src/{memory → persistence}/migrations/176-drop-capability-card-state.ts +0 -0
  2028. /package/src/{memory → persistence}/migrations/177-create-trace-events-table.ts +0 -0
  2029. /package/src/{memory → persistence}/migrations/178-oauth-providers-managed-service-config-key.ts +0 -0
  2030. /package/src/{memory → persistence}/migrations/179-llm-request-log-message-id.ts +0 -0
  2031. /package/src/{memory → persistence}/migrations/180-backfill-inline-attachments-to-disk.ts +0 -0
  2032. /package/src/{memory → persistence}/migrations/181-rename-thread-starters-checkpoints.ts +0 -0
  2033. /package/src/{memory → persistence}/migrations/183-add-conversation-fork-lineage.ts +0 -0
  2034. /package/src/{memory → persistence}/migrations/184-llm-request-log-provider.ts +0 -0
  2035. /package/src/{memory → persistence}/migrations/188-schedule-quiet-flag.ts +0 -0
  2036. /package/src/{memory → persistence}/migrations/189-drop-simplified-memory.ts +0 -0
  2037. /package/src/{memory → persistence}/migrations/190-call-session-skip-disclosure.ts +0 -0
  2038. /package/src/{memory → persistence}/migrations/191-backfill-audio-attachment-mime-types.ts +0 -0
  2039. /package/src/{memory → persistence}/migrations/192-contacts-user-file-column.ts +0 -0
  2040. /package/src/{memory → persistence}/migrations/193-add-source-type-columns.ts +0 -0
  2041. /package/src/{memory → persistence}/migrations/194-memory-recall-logs.ts +0 -0
  2042. /package/src/{memory → persistence}/migrations/195-oauth-providers-ping-config.ts +0 -0
  2043. /package/src/{memory → persistence}/migrations/196-messages-conversation-created-at-index.ts +0 -0
  2044. /package/src/{memory → persistence}/migrations/197-oauth-providers-behavior-columns.ts +0 -0
  2045. /package/src/{memory → persistence}/migrations/198-drop-setup-skill-id-column.ts +0 -0
  2046. /package/src/{memory → persistence}/migrations/200-usage-llm-call-count.ts +0 -0
  2047. /package/src/{memory → persistence}/migrations/201-oauth-providers-feature-flag.ts +0 -0
  2048. /package/src/{memory → persistence}/migrations/202-drop-callback-transport-column.ts +0 -0
  2049. /package/src/{memory → persistence}/migrations/204-rename-memory-graph-type-values.ts +0 -0
  2050. /package/src/{memory → persistence}/migrations/205-memory-graph-image-refs.ts +0 -0
  2051. /package/src/{memory → persistence}/migrations/206-memory-graph-node-edits.ts +0 -0
  2052. /package/src/{memory → persistence}/migrations/207-conversation-graph-memory-state.ts +0 -0
  2053. /package/src/{memory → persistence}/migrations/208-conversations-last-message-at.ts +0 -0
  2054. /package/src/{memory → persistence}/migrations/210-schedule-reuse-conversation.ts +0 -0
  2055. /package/src/{memory → persistence}/migrations/212-llm-request-logs-created-at-index.ts +0 -0
  2056. /package/src/{memory → persistence}/migrations/213-oauth-providers-scope-separator.ts +0 -0
  2057. /package/src/{memory → persistence}/migrations/214-oauth-providers-refresh-url.ts +0 -0
  2058. /package/src/{memory → persistence}/migrations/215-oauth-providers-revoke.ts +0 -0
  2059. /package/src/{memory → persistence}/migrations/216-oauth-providers-token-auth-method.ts +0 -0
  2060. /package/src/{memory → persistence}/migrations/217-conversation-host-access.ts +0 -0
  2061. /package/src/{memory → persistence}/migrations/218-oauth-providers-logo-url.ts +0 -0
  2062. /package/src/{memory → persistence}/migrations/219-oauth-providers-token-exchange-body-format.ts +0 -0
  2063. /package/src/{memory → persistence}/migrations/221-conversations-archived-at.ts +0 -0
  2064. /package/src/{memory → persistence}/migrations/223-schedule-script-column.ts +0 -0
  2065. /package/src/{memory → persistence}/migrations/224-oauth-providers-managed-service-is-paid.ts +0 -0
  2066. /package/src/{memory → persistence}/migrations/225-oauth-providers-available-scopes.ts +0 -0
  2067. /package/src/{memory → persistence}/migrations/226-schedule-wake-conversation-id.ts +0 -0
  2068. /package/src/{memory → persistence}/migrations/227-add-conversation-inference-profile.ts +0 -0
  2069. /package/src/{memory → persistence}/migrations/228-rename-inference-profile-snake-case.ts +0 -0
  2070. /package/src/{memory → persistence}/migrations/229-delete-private-conversations.test.ts +0 -0
  2071. /package/src/{memory → persistence}/migrations/229-delete-private-conversations.ts +0 -0
  2072. /package/src/{memory → persistence}/migrations/230-acp-session-history.ts +0 -0
  2073. /package/src/{memory → persistence}/migrations/231-repair-memory-graph-event-dates.ts +0 -0
  2074. /package/src/{memory → persistence}/migrations/232-activation-state.ts +0 -0
  2075. /package/src/{memory → persistence}/migrations/233-document-conversations.ts +0 -0
  2076. /package/src/{memory → persistence}/migrations/234-memory-v2-activation-logs.ts +0 -0
  2077. /package/src/{memory → persistence}/migrations/235-llm-usage-attribution.ts +0 -0
  2078. /package/src/{memory → persistence}/migrations/235-slack-compaction-watermark.ts +0 -0
  2079. /package/src/{memory → persistence}/migrations/237-heartbeat-runs.ts +0 -0
  2080. /package/src/{memory → persistence}/migrations/238-schedule-retry-policy.ts +0 -0
  2081. /package/src/{memory → persistence}/migrations/239-trace-events-created-at-index.ts +0 -0
  2082. /package/src/{memory → persistence}/migrations/240-conversation-inference-profile-session.ts +0 -0
  2083. /package/src/{memory → persistence}/migrations/241-activation-state-fk-cascade.ts +0 -0
  2084. /package/src/{memory → persistence}/migrations/242-message-bookmarks.ts +0 -0
  2085. /package/src/{memory → persistence}/migrations/245-memory-retrospective-state.ts +0 -0
  2086. /package/src/{memory → persistence}/migrations/247-external-conversation-binding-thread-id.ts +0 -0
  2087. /package/src/{memory → persistence}/migrations/248-create-onboarding-events.ts +0 -0
  2088. /package/src/{memory → persistence}/migrations/249-normalize-slack-external-content.ts +0 -0
  2089. /package/src/{memory → persistence}/migrations/250-provider-connection-base-url-and-models.ts +0 -0
  2090. /package/src/{memory → persistence}/migrations/251-a2a-tasks.ts +0 -0
  2091. /package/src/{memory → persistence}/migrations/252-llm-request-log-agent-loop-exit-reason.ts +0 -0
  2092. /package/src/{memory → persistence}/migrations/253-conversation-last-notified-profile.ts +0 -0
  2093. /package/src/{memory → persistence}/migrations/253-document-comments.ts +0 -0
  2094. /package/src/{memory → persistence}/migrations/254-external-conversation-binding-chat-name.ts +0 -0
  2095. /package/src/{memory → persistence}/migrations/256-memory-v2-injection-events.ts +0 -0
  2096. /package/src/{memory → persistence}/migrations/257-strip-base-url-non-openai-compatible.ts +0 -0
  2097. /package/src/{memory → persistence}/migrations/258-onboarding-events-prior-assistants.ts +0 -0
  2098. /package/src/{memory → persistence}/migrations/259-conversation-cleaned-at.ts +0 -0
  2099. /package/src/{memory → persistence}/migrations/260-rename-cleaned-at.ts +0 -0
  2100. /package/src/{memory → persistence}/migrations/261-llm-usage-add-raw-usage.ts +0 -0
  2101. /package/src/{memory → persistence}/migrations/262-memory-v3-coactivation.ts +0 -0
  2102. /package/src/{memory → persistence}/migrations/263-memory-v3-auto-edges.ts +0 -0
  2103. /package/src/{memory → persistence}/migrations/264-llm-request-log-call-site.ts +0 -0
  2104. /package/src/{memory → persistence}/migrations/265-drop-provider-connection-status.ts +0 -0
  2105. /package/src/{memory → persistence}/migrations/266-messages-client-message-id.ts +0 -0
  2106. /package/src/{memory → persistence}/migrations/267-llm-usage-events-add-assistant-version.ts +0 -0
  2107. /package/src/{memory → persistence}/migrations/268-add-memory-v3-selections.ts +0 -0
  2108. /package/src/{memory → persistence}/migrations/269-schedule-script-timeout.ts +0 -0
  2109. /package/src/{memory → persistence}/migrations/270-messages-role-created-at-index.ts +0 -0
  2110. /package/src/{memory → persistence}/migrations/270-schedule-description.ts +0 -0
  2111. /package/src/{memory → persistence}/migrations/270-schedule-source-conversation.ts +0 -0
  2112. /package/src/{memory → persistence}/migrations/271-create-auth-fallback-events.ts +0 -0
  2113. /package/src/{memory → persistence}/migrations/272-acp-session-history-cwd.ts +0 -0
  2114. /package/src/{memory → persistence}/migrations/273-onboarding-events-funnel-columns.ts +0 -0
  2115. /package/src/{memory → persistence}/migrations/274-create-activation-sessions.ts +0 -0
  2116. /package/src/{memory → persistence}/migrations/275-tool-invocations-add-skill-id.test.ts +0 -0
  2117. /package/src/{memory → persistence}/migrations/275-tool-invocations-add-skill-id.ts +0 -0
  2118. /package/src/{memory → persistence}/migrations/276-tool-invocations-created-at-id-index.test.ts +0 -0
  2119. /package/src/{memory → persistence}/migrations/276-tool-invocations-created-at-id-index.ts +0 -0
  2120. /package/src/{memory → persistence}/migrations/277-add-memory-v3-ever-injected.ts +0 -0
  2121. /package/src/{memory → persistence}/migrations/278-tool-invocations-telemetry-columns.test.ts +0 -0
  2122. /package/src/{memory → persistence}/migrations/278-tool-invocations-telemetry-columns.ts +0 -0
  2123. /package/src/{memory → persistence}/migrations/279-create-skill-loaded-events.test.ts +0 -0
  2124. /package/src/{memory → persistence}/migrations/279-create-skill-loaded-events.ts +0 -0
  2125. /package/src/{memory → persistence}/migrations/280-conversations-surfaced-at.test.ts +0 -0
  2126. /package/src/{memory → persistence}/migrations/280-conversations-surfaced-at.ts +0 -0
  2127. /package/src/{memory → persistence}/migrations/281-memory-retrospective-remembered-log.ts +0 -0
  2128. /package/src/{memory → persistence}/migrations/282-schedule-inference-profile.test.ts +0 -0
  2129. /package/src/{memory → persistence}/migrations/282-schedule-inference-profile.ts +0 -0
  2130. /package/src/{memory → persistence}/migrations/283-memory-v3-selections-message-id-and-sections.test.ts +0 -0
  2131. /package/src/{memory → persistence}/migrations/283-memory-v3-selections-message-id-and-sections.ts +0 -0
  2132. /package/src/{memory → persistence}/migrations/284-workflow-runs.ts +0 -0
  2133. /package/src/{memory → persistence}/migrations/285-schedule-workflow-mode.ts +0 -0
  2134. /package/src/{memory → persistence}/migrations/286-workflow-run-trust.ts +0 -0
  2135. /package/src/{memory → persistence}/migrations/287-conversation-origin-channel-index.ts +0 -0
  2136. /package/src/{memory → persistence}/migrations/288-backfill-origin-channel-from-bindings.ts +0 -0
  2137. /package/src/{memory → persistence}/migrations/289-contact-channels-unique-ext-user.ts +0 -0
  2138. /package/src/{memory → persistence}/migrations/290-schedule-capabilities.test.ts +0 -0
  2139. /package/src/{memory → persistence}/migrations/290-schedule-capabilities.ts +0 -0
  2140. /package/src/{memory → persistence}/migrations/291-contact-channels-renormalize-addresses.ts +0 -0
  2141. /package/src/{memory → persistence}/migrations/292-schedule-default-no-reuse-conversation.test.ts +0 -0
  2142. /package/src/{memory → persistence}/migrations/292-schedule-default-no-reuse-conversation.ts +0 -0
  2143. /package/src/{memory → persistence}/migrations/293-workflow-journal-leaf-tokens.ts +0 -0
  2144. /package/src/{memory → persistence}/migrations/294-drop-external-user-id.ts +0 -0
  2145. /package/src/{memory → persistence}/migrations/295-drop-approval-prompt-ts-tracker.ts +0 -0
  2146. /package/src/{memory → persistence}/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +0 -0
  2147. /package/src/{memory → persistence}/migrations/296-rewrite-balanced-economy-profile-pins.ts +0 -0
  2148. /package/src/{memory → persistence}/migrations/297-move-llm-request-logs-to-logs-db.ts +0 -0
  2149. /package/src/{memory → persistence}/migrations/298-move-memory-jobs-to-memory-db.ts +0 -0
  2150. /package/src/{memory → persistence}/migrations/299-canonical-guardian-deliveries-conversation-index.ts +0 -0
  2151. /package/src/{memory → persistence}/migrations/300-add-processing-started-at.ts +0 -0
  2152. /package/src/{memory → persistence}/migrations/__tests__/014-backfill-inbox-thread-state.test.ts +0 -0
  2153. /package/src/{memory → persistence}/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +0 -0
  2154. /package/src/{memory → persistence}/migrations/__tests__/136-drop-assistant-id-columns.test.ts +0 -0
  2155. /package/src/{memory → persistence}/migrations/__tests__/234-memory-v2-activation-logs.test.ts +0 -0
  2156. /package/src/{memory → persistence}/migrations/__tests__/245-memory-retrospective-state.test.ts +0 -0
  2157. /package/src/{memory → persistence}/migrations/__tests__/267-llm-usage-events-add-assistant-version.test.ts +0 -0
  2158. /package/src/{memory → persistence}/migrations/__tests__/281-memory-retrospective-remembered-log.test.ts +0 -0
  2159. /package/src/{memory → persistence}/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +0 -0
  2160. /package/src/{memory → persistence}/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +0 -0
  2161. /package/src/{memory → persistence}/migrations/__tests__/297-move-llm-request-logs.test.ts +0 -0
  2162. /package/src/{memory → persistence}/migrations/run-migrations.ts +0 -0
  2163. /package/src/{memory → persistence}/migrations/schema-introspection.ts +0 -0
  2164. /package/src/{memory → persistence}/raw-query.ts +0 -0
  2165. /package/src/{memory → persistence}/schema/a2a.ts +0 -0
  2166. /package/src/{memory → persistence}/schema/bookmarks.ts +0 -0
  2167. /package/src/{memory → persistence}/schema/calls.ts +0 -0
  2168. /package/src/{memory → persistence}/schema/guardian.ts +0 -0
  2169. /package/src/{memory → persistence}/schema/index.ts +0 -0
  2170. /package/src/{memory → persistence}/schema/inference.ts +0 -0
  2171. /package/src/{memory → persistence}/schema/memory-core.ts +0 -0
  2172. /package/src/{memory → persistence}/schema/memory-graph.ts +0 -0
  2173. /package/src/{memory → persistence}/schema/notifications.ts +0 -0
  2174. /package/src/{memory → persistence}/schema/oauth.ts +0 -0
  2175. /package/src/{memory → persistence}/schema/tasks.ts +0 -0
  2176. /package/src/{memory → persistence}/schema.ts +0 -0
  2177. /package/src/{memory → persistence}/usage-buckets.ts +0 -0
  2178. /package/src/{memory → persistence}/usage-grouped-buckets.ts +0 -0
  2179. /package/src/{memory → plugins/defaults/memory}/__tests__/fixtures/memory-v2-activation-fixtures.ts +0 -0
  2180. /package/src/{memory → plugins/defaults/memory}/__tests__/memory-retrospective-trigger-check.test.ts +0 -0
  2181. /package/src/{memory → plugins/defaults/memory}/anisotropy.test.ts +0 -0
  2182. /package/src/{memory → plugins/defaults/memory}/context-search/__tests__/agent-runner-redaction.test.ts +0 -0
  2183. /package/src/{memory → plugins/defaults/memory}/context-search/format.ts +0 -0
  2184. /package/src/{memory → plugins/defaults/memory}/context-search/limits.ts +0 -0
  2185. /package/src/{memory → plugins/defaults/memory}/context-search/sources/workspace.ts +0 -0
  2186. /package/src/{memory → plugins/defaults/memory}/graph/decay.test.ts +0 -0
  2187. /package/src/{memory → plugins/defaults/memory}/graph/extraction.test.ts +0 -0
  2188. /package/src/{memory → plugins/defaults/memory}/graph/injection.test.ts +0 -0
  2189. /package/src/{memory → plugins/defaults/memory}/graph/scoring.test.ts +0 -0
  2190. /package/src/{memory → plugins/defaults/memory}/graph/scoring.ts +0 -0
  2191. /package/src/{memory → plugins/defaults/memory}/graph/serendipity.ts +0 -0
  2192. /package/src/{memory → plugins/defaults/memory}/graph/triggers.test.ts +0 -0
  2193. /package/src/{memory → plugins/defaults/memory}/graph/triggers.ts +0 -0
  2194. /package/src/{memory → plugins/defaults/memory}/graph/types.ts +0 -0
  2195. /package/src/plugins/defaults/{memory-retrieval → memory}/hooks/__tests__/user-prompt-submit.test.ts +0 -0
  2196. /package/src/{memory → plugins/defaults/memory}/memory-marker.ts +0 -0
  2197. /package/src/{memory → plugins/defaults/memory}/prompt-override.ts +0 -0
  2198. /package/src/{memory → plugins/defaults/memory}/retrieval-budget.ts +0 -0
  2199. /package/src/{memory → plugins/defaults/memory}/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +0 -0
  2200. /package/src/{memory → plugins/defaults/memory}/v2/__tests__/concept-page-frontmatter-schema.test.ts +0 -0
  2201. /package/src/{memory → plugins/defaults/memory}/v2/__tests__/edge-index.test.ts +0 -0
  2202. /package/src/{memory → plugins/defaults/memory}/v2/__tests__/harness-metrics.test.ts +0 -0
  2203. /package/src/{memory → plugins/defaults/memory}/v2/__tests__/injected-block-slugs.test.ts +0 -0
  2204. /package/src/{memory → plugins/defaults/memory}/v2/__tests__/page-store.test.ts +0 -0
  2205. /package/src/{memory → plugins/defaults/memory}/v2/__tests__/prompts-router.test.ts +0 -0
  2206. /package/src/{memory → plugins/defaults/memory}/v2/cli-command-content.ts +0 -0
  2207. /package/src/{memory → plugins/defaults/memory}/v2/constants.ts +0 -0
  2208. /package/src/{memory → plugins/defaults/memory}/v2/edge-index.ts +0 -0
  2209. /package/src/{memory → plugins/defaults/memory}/v2/harness/metrics.ts +0 -0
  2210. /package/src/{memory → plugins/defaults/memory}/v2/harness/runner.ts +0 -0
  2211. /package/src/{memory → plugins/defaults/memory}/v2/harness/trace.ts +0 -0
  2212. /package/src/{memory → plugins/defaults/memory}/v2/now-text.ts +0 -0
  2213. /package/src/{memory → plugins/defaults/memory}/v2/prompts/sweep.ts +0 -0
  2214. /package/src/{memory → plugins/defaults/memory}/v2/types.ts +0 -0
  2215. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/__tests__/capabilities.test.ts +0 -0
  2216. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/__tests__/card.test.ts +0 -0
  2217. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/__tests__/fresh-set.test.ts +0 -0
  2218. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/__tests__/section-needle.test.ts +0 -0
  2219. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/__tests__/sections.test.ts +0 -0
  2220. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/__tests__/types.test.ts +0 -0
  2221. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/card.test.ts +0 -0
  2222. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/core-set.test.ts +0 -0
  2223. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/core-set.ts +0 -0
  2224. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/data/README.md +0 -0
  2225. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/data/assignments.json +0 -0
  2226. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/data/core.json +0 -0
  2227. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/data/leaves/domain-a/topic-x.md +0 -0
  2228. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/data/leaves/domain-a/topic-y.md +0 -0
  2229. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/data/leaves/domain-b/topic-z.md +0 -0
  2230. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/fresh-set.ts +0 -0
  2231. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/llm-retry.ts +0 -0
  2232. /package/src/plugins/defaults/{memory-v3-shadow → memory/v3}/sections.ts +0 -0
  2233. /package/src/{memory → plugins/defaults/memory}/v3-eval/__tests__/eval-packets.test.ts +0 -0
  2234. /package/src/{memory → plugins/defaults/memory}/v3-eval/__tests__/eval-tally.test.ts +0 -0
  2235. /package/src/{memory → plugins/defaults/memory}/v3-eval/eval-tally.ts +0 -0
  2236. /package/src/{memory → plugins/defaults/memory}/validation.ts +0 -0
@@ -1,2301 +0,0 @@
1
- /**
2
- * Tests for `assistant/src/memory/v2/injection.ts`.
3
- *
4
- * Coverage matrix:
5
- * - Empty state seeds the first injection (initial conversation turn).
6
- * - Second turn whose `topNow` overlaps prior `everInjected` returns
7
- * `toInject = []` and `block = null` (cache-stable empty path).
8
- * - A new topic appearing on a later turn injects only the new slug.
9
- * - `evictCompactedTurns` re-enables a previously-injected slug —
10
- * after eviction the same slug appears again in `toInject`.
11
- * - Unified-pool skills: a `skills/<id>` slug ranked into the top-K is
12
- * rendered under `### Skills You Can Use`, mixed concept-page+skill
13
- * blocks render concept sections first then the skills suffix, both
14
- * empty → null block, skills participate in `everInjected` so they
15
- * deduplicate across turns just like concepts.
16
- *
17
- * Hermetic by design: the embedding backend, qdrant client, and `getConfig`
18
- * are mocked at the module level so the suite never reaches a real backend.
19
- * The skill-store cache (`getSkillCapability`, `isSkillSlug`) is mocked so
20
- * each test can stage skill content without touching the real catalog.
21
- * The activation-store uses an in-memory SQLite database so writes are
22
- * real but contained.
23
- *
24
- * Tests use a temp workspace (mkdtemp) and never touch `~/.vellum/`. Sample
25
- * page content uses generic placeholders (Alice, Bob, etc.) per the cross-
26
- * cutting safety rules.
27
- */
28
- import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
29
- import { tmpdir } from "node:os";
30
- import { join } from "node:path";
31
- import { Database } from "bun:sqlite";
32
- import {
33
- afterAll,
34
- afterEach,
35
- beforeAll,
36
- beforeEach,
37
- describe,
38
- expect,
39
- mock,
40
- test,
41
- } from "bun:test";
42
-
43
- import { drizzle } from "drizzle-orm/bun-sqlite";
44
- import { z } from "zod";
45
-
46
- import { makeMockLogger } from "../../../__tests__/helpers/mock-logger.js";
47
- import type { AssistantConfig } from "../../../config/types.js";
48
-
49
- // ---------------------------------------------------------------------------
50
- // Module-level mocks
51
- // ---------------------------------------------------------------------------
52
-
53
- mock.module("../../../util/logger.js", () => ({
54
- getLogger: () => makeMockLogger(),
55
- }));
56
-
57
- const STUB_QDRANT_CONFIG = {
58
- memory: {
59
- qdrant: {
60
- url: "http://127.0.0.1:6333",
61
- vectorSize: 384,
62
- onDisk: true,
63
- },
64
- },
65
- };
66
- mock.module("../../../config/loader.js", () => ({
67
- getConfig: () => STUB_QDRANT_CONFIG,
68
- loadConfig: () => STUB_QDRANT_CONFIG,
69
- }));
70
-
71
- const realQdrantClient = await import("../../qdrant-client.js");
72
- mock.module("../../qdrant-client.js", () => ({
73
- ...realQdrantClient,
74
- resolveQdrantUrl: () => "http://127.0.0.1:6333",
75
- }));
76
-
77
- // Programmable embedding + Qdrant state — drives `selectCandidates`,
78
- // `simBatch`, and friends without a live backend.
79
- const state = {
80
- embedReturn: [[0.1, 0.2, 0.3]] as number[][],
81
- sparseReturn: { indices: [1, 2, 3], values: [0.5, 0.5, 0.5] },
82
- queryResponses: {
83
- dense: [] as Array<{
84
- points: Array<{ score?: number; payload: Record<string, unknown> }>;
85
- }>,
86
- sparse: [] as Array<{
87
- points: Array<{ score?: number; payload: Record<string, unknown> }>;
88
- }>,
89
- },
90
- };
91
-
92
- const realEmbeddingBackend = await import("../../embedding-backend.js");
93
- mock.module("../../embedding-backend.js", () => ({
94
- ...realEmbeddingBackend,
95
- embedWithBackend: async () => ({
96
- provider: "local",
97
- model: "test-model",
98
- vectors: state.embedReturn,
99
- }),
100
- generateSparseEmbedding: () => state.sparseReturn,
101
- }));
102
-
103
- class MockQdrantClient {
104
- constructor(_opts: unknown) {}
105
- async collectionExists(_name: string) {
106
- return { exists: true };
107
- }
108
- async createCollection() {
109
- return {};
110
- }
111
- async createPayloadIndex() {
112
- return {};
113
- }
114
- async query(
115
- _name: string,
116
- params: { using: string; limit: number; filter?: unknown },
117
- ) {
118
- // The four-channel hybrid query fires body-dense, body-sparse,
119
- // summary-dense, summary-sparse in order; both dense channels share
120
- // the dense queue and both sparse channels share the sparse queue.
121
- const channel = params.using.endsWith("sparse") ? "sparse" : "dense";
122
- return state.queryResponses[channel].shift() ?? { points: [] };
123
- }
124
- }
125
-
126
- mock.module("@qdrant/js-client-rest", () => ({
127
- QdrantClient: MockQdrantClient,
128
- }));
129
-
130
- // ---------------------------------------------------------------------------
131
- // Skill-store mock
132
- // ---------------------------------------------------------------------------
133
- //
134
- // Skills now flow through the unified pipeline under the `skills/<id>` slug
135
- // prefix — they are scored by `simBatch` against the same Qdrant collection
136
- // as concept pages, ranked by `selectInjections`, and rendered alongside
137
- // concept sections. The render path branches on `isSkillSlug(slug)` to fetch
138
- // content from the in-process cache via `getSkillCapability` instead of
139
- // reading a page from disk. Tests stage that cache and rely on the regular
140
- // `stageTurn` plumbing to land skill slugs in the candidate set.
141
-
142
- const skillState = {
143
- /** id → SkillEntry consulted by `getSkillCapability`. */
144
- entries: new Map<string, SkillEntry>(),
145
- };
146
-
147
- mock.module("../skill-store.js", () => ({
148
- getSkillCapability: (idOrSlug: string) => {
149
- const id = idOrSlug.startsWith("skills/")
150
- ? idOrSlug.slice("skills/".length)
151
- : idOrSlug;
152
- return skillState.entries.get(id) ?? null;
153
- },
154
- isSkillSlug: (slug: string) => slug.startsWith("skills/"),
155
- SKILL_SLUG_PREFIX: "skills/",
156
- skillSlugFor: (id: string) => `skills/${id}`,
157
- // PR 4 added `listSkillEntries`; `page-index.ts` (transitively imported
158
- // via `page-store.ts` and `skill-store.ts`) consumes it at module-init
159
- // time. Tests stage skill content via `skillState.entries`; expose them
160
- // here so the page-index loader sees a consistent view.
161
- listSkillEntries: () => Array.from(skillState.entries.values()),
162
- }));
163
-
164
- // ---------------------------------------------------------------------------
165
- // CLI-command-store mock
166
- // ---------------------------------------------------------------------------
167
- //
168
- // Mirrors the skill-store mock. CLI subcommand synthetic entries flow through
169
- // the unified pipeline under the `cli-commands/<name>` slug prefix and render
170
- // under `### CLI Commands You Can Use`. Tests stage `cliCommandState.entries`
171
- // and rely on `stageTurn` plumbing to land slugs in the candidate set.
172
-
173
- interface CliCommandEntryStub {
174
- id: string;
175
- description: string;
176
- content: string;
177
- }
178
-
179
- const cliCommandState = {
180
- entries: new Map<string, CliCommandEntryStub>(),
181
- };
182
-
183
- mock.module("../cli-command-store.js", () => ({
184
- getCliCommandCapability: (idOrSlug: string) => {
185
- const id = idOrSlug.startsWith("cli-commands/")
186
- ? idOrSlug.slice("cli-commands/".length)
187
- : idOrSlug;
188
- return cliCommandState.entries.get(id) ?? null;
189
- },
190
- isCliCommandSlug: (slug: string) => slug.startsWith("cli-commands/"),
191
- CLI_COMMAND_SLUG_PREFIX: "cli-commands/",
192
- cliCommandSlugFor: (name: string) => `cli-commands/${name}`,
193
- listCliCommandEntries: () => Array.from(cliCommandState.entries.values()),
194
- }));
195
-
196
- // ---------------------------------------------------------------------------
197
- // Activation-log store mock
198
- // ---------------------------------------------------------------------------
199
- //
200
- // The real `recordMemoryV2ActivationLog` writes to the singleton
201
- // `getDb()` — but this test uses an isolated in-memory database, so we mock
202
- // the writer to capture calls in-process. `recordCalls` is the captured log
203
- // array; `recordShouldThrow` makes the next call throw to verify the caller
204
- // swallows the failure.
205
-
206
- const telemetryState = {
207
- recordCalls: [] as Array<Record<string, unknown>>,
208
- recordShouldThrow: false,
209
- };
210
-
211
- mock.module("../../memory-v2-activation-log-store.js", () => ({
212
- recordMemoryV2ActivationLog: (params: Record<string, unknown>) => {
213
- if (telemetryState.recordShouldThrow) {
214
- throw new Error("simulated telemetry write failure");
215
- }
216
- telemetryState.recordCalls.push(params);
217
- },
218
- }));
219
-
220
- // ---------------------------------------------------------------------------
221
- // Page-store mock — pass-through with optional per-slug failure injection
222
- // ---------------------------------------------------------------------------
223
- //
224
- // Most tests want the real `readPage` (it walks the temp workspace seeded in
225
- // `beforeAll`). The error-isolation tests stage a slug whose `readPage` call
226
- // must throw — typically a Zod validation error mimicking the real-world
227
- // "unrecognized frontmatter key" failure that motivated this work. Tests
228
- // stage entries via `pageStoreState.failingSlugs` and reset in `resetState`.
229
- //
230
- // Bun's `mock.module` mutates the module's exports object in place, so
231
- // `realPageStore.readPage` AFTER the mock applies would resolve to the mock
232
- // itself — calling it would recurse. We capture the original function value
233
- // (not a property lookup) before installing the mock so the pass-through
234
- // path has a real reference to the underlying implementation.
235
-
236
- const realPageStoreModule = await import("../page-store.js");
237
- const realReadPage = realPageStoreModule.readPage;
238
- const pageStoreState = {
239
- failingSlugs: new Map<string, Error>(),
240
- };
241
- mock.module("../page-store.js", () => ({
242
- ...realPageStoreModule,
243
- readPage: async (workspaceDir: string, slug: string) => {
244
- const err = pageStoreState.failingSlugs.get(slug);
245
- if (err) throw err;
246
- return realReadPage(workspaceDir, slug);
247
- },
248
- }));
249
-
250
- // ---------------------------------------------------------------------------
251
- // Router mock — programmable per-call result
252
- // ---------------------------------------------------------------------------
253
- //
254
- // PR 10 wires `runRouter` into `injectMemoryV2Block` behind the
255
- // `memory.v2.router.enabled` flag. The activation-mode tests above never
256
- // flip the flag, so the default mock returns a no-op result and the router
257
- // branch is never exercised. Router-mode tests set `routerState.nextResult`
258
- // to stage a deterministic outcome before each call.
259
-
260
- interface RouterResultStub {
261
- selectedSlugs: string[];
262
- failureReason: string | null;
263
- /** Tier provenance per slug. Defaults to `tier3:0` for any selected slug. */
264
- sourceBySlug?: Map<string, string>;
265
- }
266
-
267
- const routerState = {
268
- nextResult: null as RouterResultStub | null,
269
- callCount: 0,
270
- };
271
-
272
- mock.module("../router.js", () => ({
273
- runRouter: async () => {
274
- routerState.callCount++;
275
- const result = routerState.nextResult ?? {
276
- selectedSlugs: [],
277
- failureReason: null,
278
- };
279
- // Synthesize a default sourceBySlug for stubs that don't set one — pre-
280
- // tier-provenance tests stage `selectedSlugs` only and expect every pick
281
- // to flow through as a router selection. Treating them as `tier3:0` is
282
- // the closest equivalent under the new model.
283
- if (!result.sourceBySlug) {
284
- const map = new Map<string, string>();
285
- for (const slug of result.selectedSlugs) map.set(slug, "tier3:0");
286
- result.sourceBySlug = map;
287
- }
288
- return result;
289
- },
290
- }));
291
-
292
- // ---------------------------------------------------------------------------
293
- // Activation-store mock — pass-through with optional `save` failure injection
294
- // ---------------------------------------------------------------------------
295
- //
296
- // One regression test forces `save` to throw to exercise the
297
- // `injectMemoryV2Block` outer try/finally — telemetry must still be flushed
298
- // (with `mode: "errored"`) and the error must propagate. Default behavior
299
- // delegates to the real activation-store so the rest of the suite stays
300
- // untouched. Same pre-mock function-capture trick as `readPage` above.
301
-
302
- const realActivationStoreModule = await import("../activation-store.js");
303
- const realSave = realActivationStoreModule.save;
304
- const activationStoreState = {
305
- saveShouldThrow: false,
306
- };
307
- mock.module("../activation-store.js", () => ({
308
- ...realActivationStoreModule,
309
- save: async (...args: Parameters<typeof realSave>) => {
310
- if (activationStoreState.saveShouldThrow) {
311
- throw new Error("simulated activation-store save failure");
312
- }
313
- return realSave(...args);
314
- },
315
- }));
316
-
317
- // ---------------------------------------------------------------------------
318
- // Workspace + DB setup
319
- // ---------------------------------------------------------------------------
320
-
321
- let tmpWorkspace: string;
322
- let previousWorkspaceEnv: string | undefined;
323
-
324
- beforeAll(() => {
325
- tmpWorkspace = mkdtempSync(join(tmpdir(), "memory-v2-injection-test-"));
326
- previousWorkspaceEnv = process.env.VELLUM_WORKSPACE_DIR;
327
- process.env.VELLUM_WORKSPACE_DIR = tmpWorkspace;
328
-
329
- // Seed the v2 directory layout the migration would normally create.
330
- mkdirSync(join(tmpWorkspace, "memory", "concepts"), { recursive: true });
331
- // Three concept pages with generic, placeholder bodies. Outgoing edges
332
- // live in each page's frontmatter `edges:` list — there is no separate
333
- // edges-index file under the directed-edges model.
334
- writeFileSync(
335
- join(tmpWorkspace, "memory", "concepts", "alice-vscode.md"),
336
- `---
337
- edges: [bob-coffee]
338
- ref_files: []
339
- ---
340
- Alice prefers VS Code as her editor.`,
341
- );
342
- writeFileSync(
343
- join(tmpWorkspace, "memory", "concepts", "bob-coffee.md"),
344
- `---
345
- edges: [alice-vscode]
346
- ref_files: []
347
- ---
348
- Bob takes his coffee black, no sugar.`,
349
- );
350
- writeFileSync(
351
- join(tmpWorkspace, "memory", "concepts", "carol-jazz.md"),
352
- `---
353
- edges: []
354
- ref_files: []
355
- ---
356
- Carol loves jazz music — Coltrane in particular.`,
357
- );
358
- // A page with both `edges` and `ref_files` populated so the frontmatter-
359
- // injection test can assert the full canonical shape.
360
- writeFileSync(
361
- join(tmpWorkspace, "memory", "concepts", "frontmatter-demo.md"),
362
- `---
363
- edges:
364
- - alice-vscode
365
- ref_files:
366
- - images/demo.jpg
367
- ---
368
- Demo body content.`,
369
- );
370
- // A page WITH a `summary` in its frontmatter — exercises the summary-only
371
- // injection path. Body is intentionally longer than the summary so tests
372
- // can assert that the body is *not* injected when the summary is present.
373
- writeFileSync(
374
- join(tmpWorkspace, "memory", "concepts", "summarized-page.md"),
375
- `---
376
- edges: []
377
- ref_files: []
378
- summary: A short prose description of the summarized page that retrieval injects in place of the full body.
379
- ---
380
- Long-form body content that should NOT appear in the injection block when the page has a summary in frontmatter — the agent reads the file on demand instead.`,
381
- );
382
- });
383
-
384
- afterAll(() => {
385
- if (previousWorkspaceEnv === undefined) {
386
- delete process.env.VELLUM_WORKSPACE_DIR;
387
- } else {
388
- process.env.VELLUM_WORKSPACE_DIR = previousWorkspaceEnv;
389
- }
390
- rmSync(tmpWorkspace, { recursive: true, force: true });
391
- });
392
-
393
- // Static `import type` is fine — types erase, so they don't run module-init
394
- // code that would race the mocks above.
395
- import type { DrizzleDb } from "../../db-connection.js";
396
- import type { SkillEntry } from "../types.js";
397
-
398
- const { getSqliteFrom } = await import("../../db-connection.js");
399
- const { migrateActivationState } =
400
- await import("../../migrations/232-activation-state.js");
401
- const { migrateMemoryV2InjectionEvents } =
402
- await import("../../migrations/256-memory-v2-injection-events.js");
403
- const schema = await import("../../schema.js");
404
- const { clearEverInjected, hydrate, save } =
405
- await import("../activation-store.js");
406
- const { injectMemoryV2Block } = await import("../injection.js");
407
- const { _resetMemoryV2QdrantForTests } = await import("../qdrant.js");
408
-
409
- function createTestDb(): DrizzleDb {
410
- const sqlite = new Database(":memory:");
411
- sqlite.exec("PRAGMA journal_mode=WAL");
412
- sqlite.exec("PRAGMA foreign_keys = ON");
413
- const db = drizzle(sqlite, { schema });
414
-
415
- // Migration uses the checkpoints table for crash recovery — bootstrap it.
416
- getSqliteFrom(db).exec(/*sql*/ `
417
- CREATE TABLE IF NOT EXISTS memory_checkpoints (
418
- key TEXT PRIMARY KEY,
419
- value TEXT NOT NULL,
420
- updated_at INTEGER NOT NULL
421
- )
422
- `);
423
- migrateActivationState(db);
424
- migrateMemoryV2InjectionEvents(db);
425
- return db;
426
- }
427
-
428
- function makeConfig(
429
- overrides: Partial<{
430
- d: number;
431
- c_user: number;
432
- c_assistant: number;
433
- c_now: number;
434
- k: number;
435
- hops: number;
436
- top_k: number;
437
- epsilon: number;
438
- dense_weight: number;
439
- sparse_weight: number;
440
- router: { enabled: boolean; max_page_ids?: number };
441
- }> = {},
442
- ): AssistantConfig {
443
- const { router, ...rest } = overrides;
444
- return {
445
- memory: {
446
- v2: {
447
- d: 0.3,
448
- c_user: 0.3,
449
- c_assistant: 0.2,
450
- c_now: 0.2,
451
- k: 0.5,
452
- hops: 2,
453
- top_k: 25,
454
- epsilon: 0.01,
455
- dense_weight: 1.0,
456
- sparse_weight: 0.0,
457
- router: { enabled: false, max_page_ids: 25, ...(router ?? {}) },
458
- ...rest,
459
- },
460
- },
461
- } as unknown as AssistantConfig;
462
- }
463
-
464
- /**
465
- * Stage one set of dense/sparse hits, used uniformly by every `simBatch`
466
- * channel call (user/assistant/now) AND by the un-restricted ANN candidate
467
- * query. The candidate query runs first, then three simBatch calls — that's
468
- * `channels` (= 4) logical hybrid queries. Each logical hybrid query now
469
- * fires a four-channel fan-out (body dense, body sparse, summary dense,
470
- * summary sparse), so we push 2 dense + 2 sparse responses per logical
471
- * call to match the post-summary-vector wire pattern.
472
- *
473
- * Each entry is mapped to a hit per channel; pass `denseScore`/`sparseScore`
474
- * undefined to omit a slug from that channel. `summaryDenseScore` /
475
- * `summarySparseScore` route to the summary-side channels — tests that
476
- * don't care about summary scoring leave them undefined and the summary
477
- * channel falls back to body-only behavior.
478
- */
479
- function stageTurn(
480
- hits: Array<{
481
- slug: string;
482
- denseScore?: number;
483
- sparseScore?: number;
484
- summaryDenseScore?: number;
485
- summarySparseScore?: number;
486
- }>,
487
- channels = 4,
488
- ): void {
489
- // Clear any leftovers from a prior turn before staging this one so unused
490
- // staged responses can't bleed into the next injection. The activation
491
- // pipeline now skips the embedding round-trip for empty texts (turn 1's
492
- // assistantMessage), so consumed-channel counts vary per turn — staging
493
- // exclusively is the only way multi-turn tests stay aligned.
494
- state.queryResponses.dense.length = 0;
495
- state.queryResponses.sparse.length = 0;
496
- for (let i = 0; i < channels; i++) {
497
- state.queryResponses.dense.push({
498
- points: hits
499
- .filter((h) => h.denseScore !== undefined)
500
- .map((h) => ({ score: h.denseScore, payload: { slug: h.slug } })),
501
- });
502
- state.queryResponses.sparse.push({
503
- points: hits
504
- .filter((h) => h.sparseScore !== undefined)
505
- .map((h) => ({ score: h.sparseScore, payload: { slug: h.slug } })),
506
- });
507
- state.queryResponses.dense.push({
508
- points: hits
509
- .filter((h) => h.summaryDenseScore !== undefined)
510
- .map((h) => ({
511
- score: h.summaryDenseScore,
512
- payload: { slug: h.slug },
513
- })),
514
- });
515
- state.queryResponses.sparse.push({
516
- points: hits
517
- .filter((h) => h.summarySparseScore !== undefined)
518
- .map((h) => ({
519
- score: h.summarySparseScore,
520
- payload: { slug: h.slug },
521
- })),
522
- });
523
- }
524
- }
525
-
526
- function resetState(): void {
527
- state.embedReturn = [[0.1, 0.2, 0.3]];
528
- state.sparseReturn = { indices: [1, 2, 3], values: [0.5, 0.5, 0.5] };
529
- state.queryResponses.dense.length = 0;
530
- state.queryResponses.sparse.length = 0;
531
- skillState.entries.clear();
532
- cliCommandState.entries.clear();
533
- telemetryState.recordCalls.length = 0;
534
- telemetryState.recordShouldThrow = false;
535
- pageStoreState.failingSlugs.clear();
536
- activationStoreState.saveShouldThrow = false;
537
- routerState.nextResult = null;
538
- routerState.callCount = 0;
539
- // The qdrant module caches its client; the cached client may be a
540
- // MockQdrantClient instance from a sibling test file. Reset to force a
541
- // fresh `new QdrantClient()` against this file's mock.
542
- _resetMemoryV2QdrantForTests();
543
- }
544
-
545
- /** Stage skill-store cache entries for the upcoming render. */
546
- function stageSkills(entries: SkillEntry[]): void {
547
- for (const entry of entries) {
548
- skillState.entries.set(entry.id, entry);
549
- }
550
- }
551
-
552
- /** Stage cli-command-store cache entries for the upcoming render. */
553
- function stageCliCommands(entries: CliCommandEntryStub[]): void {
554
- for (const entry of entries) {
555
- cliCommandState.entries.set(entry.id, entry);
556
- }
557
- }
558
-
559
- let db: DrizzleDb;
560
- beforeEach(() => {
561
- db = createTestDb();
562
- resetState();
563
- });
564
- afterEach(resetState);
565
-
566
- // ---------------------------------------------------------------------------
567
- // Tests
568
- // ---------------------------------------------------------------------------
569
-
570
- describe("injectMemoryV2Block", () => {
571
- test("seeds first injection from an empty state", async () => {
572
- // First turn: no prior state. The ANN candidate call surfaces alice; the
573
- // three simBatch channels score her highly enough to dominate top-K.
574
- stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
575
-
576
- const result = await injectMemoryV2Block({
577
- database: db,
578
- conversationId: "conv-1",
579
- currentTurn: 1,
580
- recentTurnPairs: [
581
- { assistantMessage: "", userMessage: "Tell me about Alice's editor" },
582
- ],
583
- nowText: "Spring afternoon",
584
- messageId: "msg-1",
585
- config: makeConfig(),
586
- });
587
-
588
- expect(result.toInject).toEqual(["alice-vscode"]);
589
- expect(result.block).not.toBeNull();
590
- // `block` is the unwrapped inner content; the caller adds the
591
- // `<memory>...</memory>` wrapper exactly once at injection time.
592
- expect(result.block).not.toContain("<memory>");
593
- expect(result.block).not.toContain("</memory>");
594
- expect(result.block).not.toContain("## What I Remember Right Now");
595
- expect(result.block).toContain("# memory/concepts/alice-vscode.md");
596
- expect(result.block).toContain("VS Code");
597
-
598
- // State persisted: alice's activation is above epsilon and recorded;
599
- // everInjected captured the new slug + currentTurn.
600
- const persisted = await hydrate(db, "conv-1");
601
- expect(persisted).not.toBeNull();
602
- expect(persisted!.everInjected).toEqual([
603
- { slug: "alice-vscode", turn: 1 },
604
- ]);
605
- expect(persisted!.state["alice-vscode"]).toBeGreaterThan(0.01);
606
- expect(persisted!.currentTurn).toBe(1);
607
- expect(persisted!.messageId).toBe("msg-1");
608
- });
609
-
610
- test("second turn with overlapping topNow returns null block + empty toInject", async () => {
611
- // Turn 1 — seed alice as injected.
612
- stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
613
- await injectMemoryV2Block({
614
- database: db,
615
- conversationId: "conv-1",
616
- currentTurn: 1,
617
- recentTurnPairs: [
618
- { assistantMessage: "", userMessage: "Alice's editor" },
619
- ],
620
- nowText: "Now",
621
- messageId: "msg-1",
622
- config: makeConfig(),
623
- });
624
-
625
- // Turn 2 — the same slug is still top-of-mind. After subtracting
626
- // everInjected, toInject is empty → block is null.
627
- stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
628
- const result = await injectMemoryV2Block({
629
- database: db,
630
- conversationId: "conv-1",
631
- currentTurn: 2,
632
- recentTurnPairs: [
633
- {
634
- assistantMessage: "Alice loves it.",
635
- userMessage: "And what about VS Code?",
636
- },
637
- ],
638
- nowText: "Now",
639
- messageId: "msg-2",
640
- config: makeConfig(),
641
- });
642
-
643
- expect(result.toInject).toEqual([]);
644
- expect(result.block).toBeNull();
645
-
646
- // State still advanced (currentTurn moved forward) and the existing
647
- // everInjected entry is preserved (no duplicate added).
648
- const persisted = await hydrate(db, "conv-1");
649
- expect(persisted!.currentTurn).toBe(2);
650
- expect(persisted!.everInjected).toEqual([
651
- { slug: "alice-vscode", turn: 1 },
652
- ]);
653
- expect(persisted!.messageId).toBe("msg-2");
654
- });
655
-
656
- test("new topic appears → only the new slug attaches", async () => {
657
- // Turn 1 — seed alice.
658
- stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
659
- await injectMemoryV2Block({
660
- database: db,
661
- conversationId: "conv-1",
662
- currentTurn: 1,
663
- recentTurnPairs: [
664
- { assistantMessage: "", userMessage: "Editor preferences" },
665
- ],
666
- nowText: "Now",
667
- messageId: "msg-1",
668
- config: makeConfig(),
669
- });
670
-
671
- // Turn 2 — carol is now in the candidate pool with high relevance.
672
- // Both alice (carry-forward) and carol should appear in topNow, but only
673
- // carol should be in toInject (alice was already attached on turn 1).
674
- stageTurn([
675
- { slug: "alice-vscode", denseScore: 0.6 },
676
- { slug: "carol-jazz", denseScore: 0.95 },
677
- ]);
678
- const result = await injectMemoryV2Block({
679
- database: db,
680
- conversationId: "conv-1",
681
- currentTurn: 2,
682
- recentTurnPairs: [
683
- {
684
- assistantMessage: "",
685
- userMessage: "Tell me about Carol's music taste",
686
- },
687
- ],
688
- nowText: "Now",
689
- messageId: "msg-2",
690
- config: makeConfig(),
691
- });
692
-
693
- expect(result.toInject).toEqual(["carol-jazz"]);
694
- expect(result.block).toContain("# memory/concepts/carol-jazz.md");
695
- // The block only shows the new slug — alice's attachment lives on the
696
- // previous turn's user message.
697
- expect(result.block).not.toContain("# memory/concepts/alice-vscode.md");
698
-
699
- const persisted = await hydrate(db, "conv-1");
700
- expect(persisted!.everInjected).toEqual([
701
- { slug: "alice-vscode", turn: 1 },
702
- { slug: "carol-jazz", turn: 2 },
703
- ]);
704
- });
705
-
706
- test("compaction eviction makes a previously-injected slug eligible again", async () => {
707
- // Turn 1 — seed alice.
708
- stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
709
- await injectMemoryV2Block({
710
- database: db,
711
- conversationId: "conv-1",
712
- currentTurn: 1,
713
- recentTurnPairs: [
714
- { assistantMessage: "", userMessage: "Alice's editor" },
715
- ],
716
- nowText: "Now",
717
- messageId: "msg-1",
718
- config: makeConfig(),
719
- });
720
-
721
- // Simulate compaction: clear the entire everInjected list.
722
- const beforeEvict = await hydrate(db, "conv-1");
723
- expect(beforeEvict).not.toBeNull();
724
- const afterEvict = clearEverInjected(beforeEvict!);
725
- expect(afterEvict.everInjected).toEqual([]);
726
- await save(db, "conv-1", afterEvict);
727
-
728
- // Turn 2 — alice should now be re-injectable since eviction cleared the
729
- // everInjected entry. Same simulated relevance as before.
730
- stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
731
- const result = await injectMemoryV2Block({
732
- database: db,
733
- conversationId: "conv-1",
734
- currentTurn: 2,
735
- recentTurnPairs: [
736
- { assistantMessage: "", userMessage: "Alice's editor again" },
737
- ],
738
- nowText: "Now",
739
- messageId: "msg-2",
740
- config: makeConfig(),
741
- });
742
-
743
- expect(result.toInject).toEqual(["alice-vscode"]);
744
- expect(result.block).toContain("# memory/concepts/alice-vscode.md");
745
-
746
- const persisted = await hydrate(db, "conv-1");
747
- expect(persisted!.everInjected).toEqual([
748
- { slug: "alice-vscode", turn: 2 },
749
- ]);
750
- });
751
-
752
- test("page with summary renders as path + summary, no body, with the CRITICAL header", async () => {
753
- // Pages whose frontmatter carries a `summary` should inject only the
754
- // summary text behind the path header — the agent reads the full file
755
- // on demand. The leading `**CRITICAL:**` line tells the agent how to
756
- // read the block.
757
- stageTurn([{ slug: "summarized-page", denseScore: 0.9 }]);
758
-
759
- const result = await injectMemoryV2Block({
760
- database: db,
761
- conversationId: "conv-1",
762
- currentTurn: 1,
763
- recentTurnPairs: [
764
- {
765
- assistantMessage: "",
766
- userMessage: "tell me about the summarized page",
767
- },
768
- ],
769
- nowText: "Now",
770
- messageId: "msg-1",
771
- config: makeConfig(),
772
- });
773
-
774
- expect(result.block).not.toBeNull();
775
- expect(result.block).toContain(
776
- 'Use `file_read("memory/concepts/path/to/file.md")` to read the full pages for any of the injected memory summaries you want more information on.',
777
- );
778
- expect(result.block).toContain(
779
- "# memory/concepts/summarized-page.md\nA short prose description",
780
- );
781
- // Body is NOT in the block — the agent must follow up with a read tool.
782
- expect(result.block).not.toContain("Long-form body content");
783
- // Frontmatter is also omitted; the path header carries the identifying
784
- // information by itself, and edges flow through the activation graph.
785
- expect(result.block).not.toContain("---\nedges:");
786
- });
787
-
788
- test("mixed batch — summary page renders short, fallback page renders full", async () => {
789
- // Both pages rank into top-K. summarized-page has a summary → short
790
- // form. frontmatter-demo has no summary → full-page fallback. The
791
- // single CRITICAL header sits at the top regardless.
792
- stageTurn([
793
- { slug: "summarized-page", denseScore: 0.95 },
794
- { slug: "frontmatter-demo", denseScore: 0.85 },
795
- ]);
796
-
797
- const result = await injectMemoryV2Block({
798
- database: db,
799
- conversationId: "conv-1",
800
- currentTurn: 1,
801
- recentTurnPairs: [
802
- { assistantMessage: "", userMessage: "show me everything" },
803
- ],
804
- nowText: "Now",
805
- messageId: "msg-1",
806
- config: makeConfig(),
807
- });
808
-
809
- expect(result.block).not.toBeNull();
810
- // Header appears exactly once.
811
- const headerCount = (
812
- result.block!.match(
813
- /Use `file_read\("memory\/concepts\/path\/to\/file\.md"\)` to read/g,
814
- ) ?? []
815
- ).length;
816
- expect(headerCount).toBe(1);
817
- // summarized-page → short form (path + summary, no body, no frontmatter).
818
- expect(result.block).toContain("# memory/concepts/summarized-page.md\nA");
819
- expect(result.block).not.toContain("Long-form body content");
820
- // frontmatter-demo → full-page fallback (path + frontmatter + body).
821
- expect(result.block).toContain(
822
- "# memory/concepts/frontmatter-demo.md\n---\n",
823
- );
824
- expect(result.block).toContain("Demo body content.");
825
- });
826
-
827
- test("includes the page frontmatter (edges, ref_files) in each rendered section", async () => {
828
- // The frontmatter (`edges`, `ref_files`) lives on disk above the page
829
- // body and is part of the page's content. Injection must reproduce both
830
- // fields verbatim — bracketed by the canonical `---` delimiters — so the
831
- // agent sees the page's edges and any referenced media paths alongside
832
- // the prose body.
833
- stageTurn([{ slug: "frontmatter-demo", denseScore: 0.9 }]);
834
-
835
- const result = await injectMemoryV2Block({
836
- database: db,
837
- conversationId: "conv-1",
838
- currentTurn: 1,
839
- recentTurnPairs: [
840
- { assistantMessage: "", userMessage: "show me the demo" },
841
- ],
842
- nowText: "Now",
843
- messageId: "msg-1",
844
- config: makeConfig(),
845
- });
846
-
847
- expect(result.block).not.toBeNull();
848
- // Path header is immediately followed by the frontmatter open delimiter.
849
- // The fallback path renders the full page (frontmatter + body) when the
850
- // page has no `summary` field — `frontmatter-demo` predates the field.
851
- expect(result.block).toContain(
852
- "# memory/concepts/frontmatter-demo.md\n---\n",
853
- );
854
- // Both fields render in YAML block style with their populated values.
855
- expect(result.block).toContain("edges:\n - alice-vscode");
856
- expect(result.block).toContain("ref_files:\n - images/demo.jpg");
857
- // Body still renders after the closing delimiter.
858
- expect(result.block).toContain("Demo body content.");
859
- });
860
-
861
- test("renders pages in activation-descending order", async () => {
862
- // Both slugs are fresh (no prior state). carol scores higher than alice
863
- // on every channel — so carol should be ranked first in topNow and
864
- // therefore appear first in the rendered block.
865
- stageTurn([
866
- { slug: "carol-jazz", denseScore: 0.95 },
867
- { slug: "alice-vscode", denseScore: 0.5 },
868
- ]);
869
- const result = await injectMemoryV2Block({
870
- database: db,
871
- conversationId: "conv-1",
872
- currentTurn: 1,
873
- recentTurnPairs: [
874
- { assistantMessage: "", userMessage: "music and editors" },
875
- ],
876
- nowText: "Now",
877
- messageId: "msg-1",
878
- config: makeConfig(),
879
- });
880
-
881
- expect(result.toInject).toEqual(["carol-jazz", "alice-vscode"]);
882
- const carolIdx = result.block!.indexOf("# memory/concepts/carol-jazz.md");
883
- const aliceIdx = result.block!.indexOf("# memory/concepts/alice-vscode.md");
884
- expect(carolIdx).toBeGreaterThan(-1);
885
- expect(aliceIdx).toBeGreaterThan(-1);
886
- expect(carolIdx).toBeLessThan(aliceIdx);
887
- });
888
-
889
- test("persists sparse state — only slugs above epsilon survive", async () => {
890
- // Carol scores high; alice essentially zero. After saving, only carol
891
- // should appear in the persisted state map. denseScore is the raw
892
- // Qdrant cosine in [-1, 1]; alice uses -1 so the post `(x+1)/2`
893
- // unit-mapping pins her fused score to 0 — below epsilon.
894
- stageTurn([
895
- { slug: "carol-jazz", denseScore: 1.0 },
896
- { slug: "alice-vscode", denseScore: -1.0 },
897
- ]);
898
- await injectMemoryV2Block({
899
- database: db,
900
- conversationId: "conv-1",
901
- currentTurn: 1,
902
- recentTurnPairs: [{ assistantMessage: "", userMessage: "carol" }],
903
- nowText: "",
904
- messageId: "msg-1",
905
- config: makeConfig({ epsilon: 0.05 }),
906
- });
907
-
908
- const persisted = await hydrate(db, "conv-1");
909
- expect(persisted!.state["carol-jazz"]).toBeGreaterThan(0.05);
910
- expect(persisted!.state["alice-vscode"]).toBeUndefined();
911
- });
912
-
913
- test("returns null block when toInject slugs all reference missing pages", async () => {
914
- // The ANN response contains a slug that is NOT on disk. After ranking,
915
- // toInject is non-empty (we don't pre-filter), but `renderInjectionBlock`
916
- // discovers the page is missing and returns null. The state is still
917
- // persisted so we don't keep re-attempting.
918
- stageTurn([{ slug: "phantom-slug", denseScore: 0.99 }]);
919
- const result = await injectMemoryV2Block({
920
- database: db,
921
- conversationId: "conv-1",
922
- currentTurn: 1,
923
- recentTurnPairs: [{ assistantMessage: "", userMessage: "phantom" }],
924
- nowText: "",
925
- messageId: "msg-1",
926
- config: makeConfig(),
927
- });
928
-
929
- expect(result.toInject).toEqual(["phantom-slug"]);
930
- expect(result.block).toBeNull();
931
-
932
- // everInjected still records the slug so future turns subtract it and
933
- // we don't infinite-loop on a missing page.
934
- const persisted = await hydrate(db, "conv-1");
935
- expect(persisted!.everInjected).toEqual([
936
- { slug: "phantom-slug", turn: 1 },
937
- ]);
938
-
939
- // Activation log marks the slug `page_missing` (not `injected`) so a
940
- // stale Qdrant / edge-index entry pointing at a vanished page is
941
- // visible in telemetry instead of masquerading as a successful inject.
942
- expect(telemetryState.recordCalls.length).toBe(1);
943
- const row = telemetryState.recordCalls[0] as {
944
- concepts: Array<{ slug: string; status: string }>;
945
- };
946
- const phantom = row.concepts.find((c) => c.slug === "phantom-slug");
947
- expect(phantom).toBeDefined();
948
- expect(phantom!.status).toBe("page_missing");
949
- });
950
-
951
- // ---------------------------------------------------------------------------
952
- // Unified pool — skills as `skills/<id>` slugs
953
- // ---------------------------------------------------------------------------
954
-
955
- test("renders a retrieved skills/<id> slug under Skills You Can Use", async () => {
956
- // No concept-page candidates this turn — the only ANN hit is a skill
957
- // slug. The render path branches on `skills/` prefix: it pulls the
958
- // entry from the skill-store cache (mocked) and emits the bullet under
959
- // the `### Skills You Can Use` subsection.
960
- stageTurn([{ slug: "skills/retrieved-skill", denseScore: 0.9 }]);
961
- stageSkills([
962
- {
963
- id: "retrieved-skill",
964
- content:
965
- 'The "Retrieved Skill" skill (retrieved-skill) is available. Helps with retrieved skills.',
966
- },
967
- ]);
968
-
969
- const result = await injectMemoryV2Block({
970
- database: db,
971
- conversationId: "conv-1",
972
- currentTurn: 1,
973
- recentTurnPairs: [
974
- { assistantMessage: "", userMessage: "Help me with examples" },
975
- ],
976
- nowText: "Now",
977
- messageId: "msg-1",
978
- config: makeConfig(),
979
- });
980
-
981
- expect(result.toInject).toEqual(["skills/retrieved-skill"]);
982
- expect(result.block).not.toBeNull();
983
- expect(result.block).not.toContain("<memory>");
984
- expect(result.block).not.toContain("</memory>");
985
- expect(result.block).not.toContain("## What I Remember Right Now");
986
- expect(result.block).not.toContain("# memory/concepts/alice-vscode.md");
987
- const headerIdx = result.block!.indexOf("### Skills You Can Use");
988
- const skillIdx = result.block!.indexOf(
989
- '- The "Retrieved Skill" skill (retrieved-skill) is available. Helps with retrieved skills. → use skill_load to activate',
990
- );
991
- expect(headerIdx).toBeGreaterThan(-1);
992
- expect(skillIdx).toBeGreaterThan(headerIdx);
993
- });
994
-
995
- test("renders concept-page sections before the skills subsection in mixed blocks", async () => {
996
- // Concept page hit AND a skill — concept-page sections come first, then
997
- // the skills subsection.
998
- stageTurn([
999
- { slug: "alice-vscode", denseScore: 0.9 },
1000
- { slug: "skills/example-skill-a", denseScore: 0.7 },
1001
- ]);
1002
- stageSkills([
1003
- {
1004
- id: "example-skill-a",
1005
- content:
1006
- 'The "Example Skill A" skill (example-skill-a) is available. Helps with examples.',
1007
- },
1008
- ]);
1009
-
1010
- const result = await injectMemoryV2Block({
1011
- database: db,
1012
- conversationId: "conv-1",
1013
- currentTurn: 1,
1014
- recentTurnPairs: [
1015
- { assistantMessage: "", userMessage: "Alice's editor" },
1016
- ],
1017
- nowText: "Now",
1018
- messageId: "msg-1",
1019
- config: makeConfig(),
1020
- });
1021
-
1022
- // Both slugs ranked into top-K and got freshly attached.
1023
- expect(new Set(result.toInject)).toEqual(
1024
- new Set(["alice-vscode", "skills/example-skill-a"]),
1025
- );
1026
- expect(result.block).not.toBeNull();
1027
-
1028
- const aliceHeaderIdx = result.block!.indexOf(
1029
- "# memory/concepts/alice-vscode.md",
1030
- );
1031
- const skillsIdx = result.block!.indexOf("### Skills You Can Use");
1032
- expect(aliceHeaderIdx).toBeGreaterThan(-1);
1033
- expect(skillsIdx).toBeGreaterThan(-1);
1034
- expect(aliceHeaderIdx).toBeLessThan(skillsIdx);
1035
-
1036
- expect(result.block).toContain(
1037
- '- The "Example Skill A" skill (example-skill-a) is available. Helps with examples. → use skill_load to activate',
1038
- );
1039
- });
1040
-
1041
- test("skills participate in everInjected — an attached skill is not re-attached on the next turn", async () => {
1042
- // Turn 1: skill ranks high, gets attached.
1043
- const skillEntry = {
1044
- id: "example-skill-a",
1045
- content:
1046
- 'The "Example Skill A" skill (example-skill-a) is available. Helps with examples.',
1047
- };
1048
- stageTurn([{ slug: "skills/example-skill-a", denseScore: 0.9 }]);
1049
- stageSkills([skillEntry]);
1050
- const result1 = await injectMemoryV2Block({
1051
- database: db,
1052
- conversationId: "conv-1",
1053
- currentTurn: 1,
1054
- recentTurnPairs: [{ assistantMessage: "", userMessage: "examples" }],
1055
- nowText: "Now",
1056
- messageId: "msg-1",
1057
- config: makeConfig(),
1058
- });
1059
- expect(result1.toInject).toEqual(["skills/example-skill-a"]);
1060
- expect(result1.block).toContain("### Skills You Can Use");
1061
-
1062
- // Turn 2: same skill ranks top again. It is already in `everInjected`, so
1063
- // `toInject` is empty and the block is null — the attachment from turn 1
1064
- // remains visible to the agent via the cached prior user message.
1065
- stageTurn([{ slug: "skills/example-skill-a", denseScore: 0.9 }]);
1066
- stageSkills([skillEntry]);
1067
- const result2 = await injectMemoryV2Block({
1068
- database: db,
1069
- conversationId: "conv-1",
1070
- currentTurn: 2,
1071
- recentTurnPairs: [
1072
- { assistantMessage: "ok", userMessage: "more examples" },
1073
- ],
1074
- nowText: "Now",
1075
- messageId: "msg-2",
1076
- config: makeConfig(),
1077
- });
1078
- expect(result2.toInject).toEqual([]);
1079
- expect(result2.block).toBeNull();
1080
-
1081
- const persisted = await hydrate(db, "conv-1");
1082
- expect(persisted!.everInjected).toEqual([
1083
- { slug: "skills/example-skill-a", turn: 1 },
1084
- ]);
1085
- });
1086
-
1087
- test("skill slugs whose entry is missing from the cache are dropped silently", async () => {
1088
- // The skill ranks into top-K but the in-process cache no longer knows
1089
- // its content (skill uninstalled mid-run, or a startup race where the
1090
- // Qdrant row landed before the skill cache was seeded). The render path
1091
- // drops it without surfacing it as a `missingSlugs` page-missing event —
1092
- // that status is reserved for on-disk concept pages, not catalog-derived
1093
- // skill entries.
1094
- stageTurn([{ slug: "skills/missing-skill", denseScore: 0.9 }]);
1095
- // No `stageSkills` call — cache stays empty.
1096
-
1097
- const result = await injectMemoryV2Block({
1098
- database: db,
1099
- conversationId: "conv-1",
1100
- currentTurn: 1,
1101
- recentTurnPairs: [{ assistantMessage: "", userMessage: "anything" }],
1102
- nowText: "Now",
1103
- messageId: "msg-1",
1104
- config: makeConfig(),
1105
- });
1106
-
1107
- // The skill is excluded from `toInject` (and `everInjected`) so future
1108
- // per-turn runs re-attempt the attach once the cache is populated.
1109
- // `block` collapses to null because the only candidate was a cache miss.
1110
- expect(result.toInject).toEqual([]);
1111
- expect(result.block).toBeNull();
1112
-
1113
- // Persisted `everInjected` must not record the missing skill — that
1114
- // would block retry on a later turn until compaction-driven eviction.
1115
- const persisted = await hydrate(db, "conv-1");
1116
- expect(persisted!.everInjected).toEqual([]);
1117
- });
1118
-
1119
- test("returns null when both concept pages and skills are empty", async () => {
1120
- stageTurn([]);
1121
-
1122
- const result = await injectMemoryV2Block({
1123
- database: db,
1124
- conversationId: "conv-1",
1125
- currentTurn: 1,
1126
- recentTurnPairs: [{ assistantMessage: "", userMessage: "anything" }],
1127
- nowText: "",
1128
- messageId: "msg-1",
1129
- config: makeConfig(),
1130
- });
1131
-
1132
- expect(result.toInject).toEqual([]);
1133
- expect(result.block).toBeNull();
1134
- });
1135
-
1136
- // ---------------------------------------------------------------------------
1137
- // CLI-command synthetic entries — same unified-pool plumbing as skills.
1138
- // ---------------------------------------------------------------------------
1139
-
1140
- test("renders a retrieved cli-commands/<name> slug under CLI Commands You Can Use", async () => {
1141
- stageTurn([{ slug: "cli-commands/attachment", denseScore: 0.9 }]);
1142
- stageCliCommands([
1143
- {
1144
- id: "attachment",
1145
- description: "Manage file attachments for conversations",
1146
- content: 'The "assistant attachment" CLI command is available...',
1147
- },
1148
- ]);
1149
-
1150
- const result = await injectMemoryV2Block({
1151
- database: db,
1152
- conversationId: "conv-1",
1153
- currentTurn: 1,
1154
- recentTurnPairs: [
1155
- { assistantMessage: "", userMessage: "How do I register a video?" },
1156
- ],
1157
- nowText: "Now",
1158
- messageId: "msg-1",
1159
- config: makeConfig(),
1160
- });
1161
-
1162
- expect(result.toInject).toEqual(["cli-commands/attachment"]);
1163
- expect(result.block).not.toBeNull();
1164
- const headerIdx = result.block!.indexOf("### CLI Commands You Can Use");
1165
- const lineIdx = result.block!.indexOf(
1166
- "- `assistant attachment`: Manage file attachments for conversations",
1167
- );
1168
- expect(headerIdx).toBeGreaterThan(-1);
1169
- expect(lineIdx).toBeGreaterThan(headerIdx);
1170
- });
1171
-
1172
- test("renders concepts, skills, then cli-commands in that order in mixed blocks", async () => {
1173
- stageTurn([
1174
- { slug: "alice-vscode", denseScore: 0.95 },
1175
- { slug: "skills/example-skill-a", denseScore: 0.85 },
1176
- { slug: "cli-commands/config", denseScore: 0.75 },
1177
- ]);
1178
- stageSkills([
1179
- {
1180
- id: "example-skill-a",
1181
- content:
1182
- 'The "Example Skill A" skill (example-skill-a) is available. Helps with examples.',
1183
- },
1184
- ]);
1185
- stageCliCommands([
1186
- {
1187
- id: "config",
1188
- description: "Manage configuration",
1189
- content: 'The "assistant config" CLI command is available...',
1190
- },
1191
- ]);
1192
-
1193
- const result = await injectMemoryV2Block({
1194
- database: db,
1195
- conversationId: "conv-1",
1196
- currentTurn: 1,
1197
- recentTurnPairs: [{ assistantMessage: "", userMessage: "Help me" }],
1198
- nowText: "Now",
1199
- messageId: "msg-1",
1200
- config: makeConfig(),
1201
- });
1202
-
1203
- expect(new Set(result.toInject)).toEqual(
1204
- new Set([
1205
- "alice-vscode",
1206
- "skills/example-skill-a",
1207
- "cli-commands/config",
1208
- ]),
1209
- );
1210
- const conceptIdx = result.block!.indexOf(
1211
- "# memory/concepts/alice-vscode.md",
1212
- );
1213
- const skillsIdx = result.block!.indexOf("### Skills You Can Use");
1214
- const cliIdx = result.block!.indexOf("### CLI Commands You Can Use");
1215
- expect(conceptIdx).toBeGreaterThan(-1);
1216
- expect(skillsIdx).toBeGreaterThan(conceptIdx);
1217
- expect(cliIdx).toBeGreaterThan(skillsIdx);
1218
- });
1219
-
1220
- test("cli-command slugs whose entry is missing from the cache are dropped silently", async () => {
1221
- stageTurn([{ slug: "cli-commands/missing-command", denseScore: 0.9 }]);
1222
-
1223
- const result = await injectMemoryV2Block({
1224
- database: db,
1225
- conversationId: "conv-1",
1226
- currentTurn: 1,
1227
- recentTurnPairs: [{ assistantMessage: "", userMessage: "anything" }],
1228
- nowText: "Now",
1229
- messageId: "msg-1",
1230
- config: makeConfig(),
1231
- });
1232
-
1233
- expect(result.toInject).toEqual([]);
1234
- expect(result.block).toBeNull();
1235
-
1236
- const persisted = await hydrate(db, "conv-1");
1237
- expect(persisted!.everInjected).toEqual([]);
1238
- });
1239
-
1240
- test("cli-commands participate in everInjected so they dedupe across turns", async () => {
1241
- const entry = {
1242
- id: "config",
1243
- description: "Manage configuration",
1244
- content: 'The "assistant config" CLI command is available...',
1245
- };
1246
- stageTurn([{ slug: "cli-commands/config", denseScore: 0.9 }]);
1247
- stageCliCommands([entry]);
1248
- const result1 = await injectMemoryV2Block({
1249
- database: db,
1250
- conversationId: "conv-1",
1251
- currentTurn: 1,
1252
- recentTurnPairs: [{ assistantMessage: "", userMessage: "config" }],
1253
- nowText: "Now",
1254
- messageId: "msg-1",
1255
- config: makeConfig(),
1256
- });
1257
- expect(result1.toInject).toEqual(["cli-commands/config"]);
1258
- expect(result1.block).toContain("### CLI Commands You Can Use");
1259
-
1260
- stageTurn([{ slug: "cli-commands/config", denseScore: 0.9 }]);
1261
- stageCliCommands([entry]);
1262
- const result2 = await injectMemoryV2Block({
1263
- database: db,
1264
- conversationId: "conv-1",
1265
- currentTurn: 2,
1266
- recentTurnPairs: [{ assistantMessage: "ok", userMessage: "more config" }],
1267
- nowText: "Now",
1268
- messageId: "msg-2",
1269
- config: makeConfig(),
1270
- });
1271
- expect(result2.toInject).toEqual([]);
1272
- expect(result2.block).toBeNull();
1273
-
1274
- const persisted = await hydrate(db, "conv-1");
1275
- expect(persisted!.everInjected).toEqual([
1276
- { slug: "cli-commands/config", turn: 1 },
1277
- ]);
1278
- });
1279
-
1280
- test("context-load mode renders topNow even when every slug was previously injected", async () => {
1281
- // Turn 1 (per-turn): seed alice as injected.
1282
- stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
1283
- await injectMemoryV2Block({
1284
- database: db,
1285
- conversationId: "conv-1",
1286
- currentTurn: 1,
1287
- recentTurnPairs: [
1288
- { assistantMessage: "", userMessage: "Alice's editor" },
1289
- ],
1290
- nowText: "Now",
1291
- messageId: "msg-1",
1292
- config: makeConfig(),
1293
- });
1294
-
1295
- // Subsequent context-load (post-compaction or fresh load): alice is
1296
- // back in the candidate pool. Per-turn would dedup against everInjected
1297
- // and produce a null block; context-load must re-render the full top-K
1298
- // because cached attachments don't exist on a fresh load.
1299
- stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
1300
- const result = await injectMemoryV2Block({
1301
- database: db,
1302
- conversationId: "conv-1",
1303
- currentTurn: 2,
1304
- recentTurnPairs: [
1305
- { assistantMessage: "", userMessage: "Reload context" },
1306
- ],
1307
- nowText: "Now",
1308
- messageId: "msg-2",
1309
- mode: "context-load",
1310
- config: makeConfig(),
1311
- });
1312
-
1313
- expect(result.block).not.toBeNull();
1314
- expect(result.block).toContain("# memory/concepts/alice-vscode.md");
1315
- // No newly-injected slug — alice was already in everInjected.
1316
- expect(result.toInject).toEqual([]);
1317
-
1318
- // everInjected stays a single entry (alice was already there) — context-
1319
- // load doesn't double-stamp.
1320
- const persisted = await hydrate(db, "conv-1");
1321
- expect(persisted!.everInjected).toEqual([
1322
- { slug: "alice-vscode", turn: 1 },
1323
- ]);
1324
- });
1325
-
1326
- test("context-load mode renders the full top-K on a fresh first turn", async () => {
1327
- // Turn 1 with no prior state and three candidates. Per-turn and context-
1328
- // load behave identically when everInjected is empty (toInject == topNow),
1329
- // but this asserts the contract: a fresh first user message gets the
1330
- // entire top-K rendered, not just a delta.
1331
- stageTurn([
1332
- { slug: "alice-vscode", denseScore: 0.9 },
1333
- { slug: "bob-coffee", denseScore: 0.8 },
1334
- { slug: "carol-jazz", denseScore: 0.7 },
1335
- ]);
1336
-
1337
- const result = await injectMemoryV2Block({
1338
- database: db,
1339
- conversationId: "conv-1",
1340
- currentTurn: 1,
1341
- recentTurnPairs: [{ assistantMessage: "", userMessage: "hi" }],
1342
- nowText: "",
1343
- messageId: "msg-1",
1344
- mode: "context-load",
1345
- config: makeConfig({ top_k: 3 }),
1346
- });
1347
-
1348
- expect(result.block).not.toBeNull();
1349
- expect(result.block).toContain("# memory/concepts/alice-vscode.md");
1350
- expect(result.block).toContain("# memory/concepts/bob-coffee.md");
1351
- expect(result.block).toContain("# memory/concepts/carol-jazz.md");
1352
- // The seeded directed edges (alice→bob, bob→alice, frontmatter-demo→alice)
1353
- // mean alice has two incoming predecessors and bob has one, so directed
1354
- // spread normalizes alice's activation more aggressively than bob's. The
1355
- // resulting rank order is bob > carol (no predecessors) > alice.
1356
- expect(new Set(result.toInject)).toEqual(
1357
- new Set(["alice-vscode", "bob-coffee", "carol-jazz"]),
1358
- );
1359
- expect(result.toInject).toHaveLength(3);
1360
-
1361
- // All three slugs persisted to everInjected so the next per-turn doesn't
1362
- // re-attach the same content.
1363
- const persisted = await hydrate(db, "conv-1");
1364
- expect(new Set(persisted!.everInjected.map((e) => e.slug))).toEqual(
1365
- new Set(["alice-vscode", "bob-coffee", "carol-jazz"]),
1366
- );
1367
- expect(persisted!.everInjected).toHaveLength(3);
1368
- });
1369
-
1370
- // ---------------------------------------------------------------------------
1371
- // Activation-log telemetry
1372
- // ---------------------------------------------------------------------------
1373
-
1374
- test("writes one activation-log row per turn with concept rows partitioned and sorted", async () => {
1375
- // Turn 1: seed alice as injected so turn 2 has an `in_context` candidate.
1376
- stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
1377
- await injectMemoryV2Block({
1378
- database: db,
1379
- conversationId: "conv-1",
1380
- currentTurn: 1,
1381
- recentTurnPairs: [
1382
- { assistantMessage: "", userMessage: "Alice's editor" },
1383
- ],
1384
- nowText: "Now",
1385
- messageId: "msg-1",
1386
- config: makeConfig(),
1387
- });
1388
- expect(telemetryState.recordCalls.length).toBe(1);
1389
-
1390
- // Turn 2: alice carries forward (now `in_context`); carol is freshly
1391
- // surfaced (`injected`); bob would be a candidate only if it carried
1392
- // forward, but with no prior bob entry it doesn't appear here.
1393
- stageTurn([
1394
- { slug: "alice-vscode", denseScore: 0.6 },
1395
- { slug: "carol-jazz", denseScore: 0.95 },
1396
- ]);
1397
- await injectMemoryV2Block({
1398
- database: db,
1399
- conversationId: "conv-1",
1400
- currentTurn: 2,
1401
- recentTurnPairs: [{ assistantMessage: "", userMessage: "Carol's music" }],
1402
- nowText: "Now",
1403
- messageId: "msg-2",
1404
- config: makeConfig(),
1405
- });
1406
-
1407
- expect(telemetryState.recordCalls.length).toBe(2);
1408
- const row = telemetryState.recordCalls[1] as {
1409
- conversationId: string;
1410
- turn: number;
1411
- mode: string;
1412
- concepts: Array<{
1413
- slug: string;
1414
- finalActivation: number;
1415
- status: string;
1416
- source: string;
1417
- }>;
1418
- config: { top_k: number };
1419
- };
1420
- expect(row.conversationId).toBe("conv-1");
1421
- expect(row.turn).toBe(2);
1422
- expect(row.mode).toBe("per-turn");
1423
- expect(row.config.top_k).toBe(25);
1424
-
1425
- // The candidate set is the union of fromPrior (alice) and fromAnn
1426
- // (alice + carol) → two concept rows.
1427
- expect(row.concepts.length).toBe(2);
1428
- const slugs = row.concepts.map((c) => c.slug);
1429
- expect(new Set(slugs)).toEqual(new Set(["alice-vscode", "carol-jazz"]));
1430
-
1431
- // Sorted descending by finalActivation.
1432
- for (let i = 1; i < row.concepts.length; i++) {
1433
- expect(row.concepts[i - 1]!.finalActivation).toBeGreaterThanOrEqual(
1434
- row.concepts[i]!.finalActivation,
1435
- );
1436
- }
1437
-
1438
- const byslug = new Map(row.concepts.map((c) => [c.slug, c]));
1439
- // Alice was attached on turn 1 → status `in_context` on turn 2.
1440
- expect(byslug.get("alice-vscode")!.status).toBe("in_context");
1441
- // Carol is freshly injected on turn 2.
1442
- expect(byslug.get("carol-jazz")!.status).toBe("injected");
1443
- });
1444
-
1445
- test("activation-log concepts include skill rows under the skills/ prefix", async () => {
1446
- // Skills participate in the unified telemetry list — they live in the
1447
- // same `concepts` array, identifiable by the `skills/` slug prefix.
1448
- stageTurn([
1449
- { slug: "alice-vscode", denseScore: 0.9 },
1450
- { slug: "skills/example-skill-a", denseScore: 0.7 },
1451
- ]);
1452
- stageSkills([
1453
- {
1454
- id: "example-skill-a",
1455
- content: "skill content",
1456
- },
1457
- ]);
1458
-
1459
- await injectMemoryV2Block({
1460
- database: db,
1461
- conversationId: "conv-1",
1462
- currentTurn: 1,
1463
- recentTurnPairs: [
1464
- { assistantMessage: "", userMessage: "Alice's editor" },
1465
- ],
1466
- nowText: "Now",
1467
- messageId: "msg-1",
1468
- config: makeConfig(),
1469
- });
1470
-
1471
- expect(telemetryState.recordCalls.length).toBe(1);
1472
- const row = telemetryState.recordCalls[0] as {
1473
- concepts: Array<{ slug: string; status: string }>;
1474
- };
1475
- const slugs = row.concepts.map((c) => c.slug);
1476
- expect(new Set(slugs)).toEqual(
1477
- new Set(["alice-vscode", "skills/example-skill-a"]),
1478
- );
1479
- });
1480
-
1481
- test("context-load mode marks every rendered slug as `injected`, never `in_context`", async () => {
1482
- // Turn 1 (per-turn): seed alice as injected so the next turn's prior
1483
- // `everInjected` includes her — the same setup the per-turn telemetry
1484
- // test uses, so the difference between modes is unambiguous.
1485
- stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
1486
- await injectMemoryV2Block({
1487
- database: db,
1488
- conversationId: "conv-1",
1489
- currentTurn: 1,
1490
- recentTurnPairs: [
1491
- { assistantMessage: "", userMessage: "Alice's editor" },
1492
- ],
1493
- nowText: "Now",
1494
- messageId: "msg-1",
1495
- config: makeConfig(),
1496
- });
1497
- expect(telemetryState.recordCalls.length).toBe(1);
1498
-
1499
- // Turn 2 in context-load mode (post-compaction or fresh load). Alice
1500
- // carries forward AND ranks high again; carol is a brand-new candidate.
1501
- // Both end up in `topNow` (and therefore in `slugsToRender` since
1502
- // context-load renders the full top-K). The status field must reflect
1503
- // that they were physically rendered into the new user message on this
1504
- // turn — `injected` for both — rather than reading `in_context` for
1505
- // alice based on stale prior `everInjected` state.
1506
- stageTurn([
1507
- { slug: "alice-vscode", denseScore: 0.6 },
1508
- { slug: "carol-jazz", denseScore: 0.95 },
1509
- ]);
1510
- await injectMemoryV2Block({
1511
- database: db,
1512
- conversationId: "conv-1",
1513
- currentTurn: 2,
1514
- recentTurnPairs: [
1515
- { assistantMessage: "", userMessage: "Reload context" },
1516
- ],
1517
- nowText: "Now",
1518
- messageId: "msg-2",
1519
- mode: "context-load",
1520
- config: makeConfig(),
1521
- });
1522
-
1523
- expect(telemetryState.recordCalls.length).toBe(2);
1524
- const row = telemetryState.recordCalls[1] as {
1525
- mode: string;
1526
- concepts: Array<{ slug: string; status: string }>;
1527
- };
1528
- expect(row.mode).toBe("context-load");
1529
-
1530
- const byslug = new Map(row.concepts.map((c) => [c.slug, c]));
1531
- // Both rendered slugs read as `injected` — alice especially, even though
1532
- // she's in prior `everInjected`, because context-load actually rendered
1533
- // her into the fresh user message on this turn.
1534
- expect(byslug.get("alice-vscode")!.status).toBe("injected");
1535
- expect(byslug.get("carol-jazz")!.status).toBe("injected");
1536
-
1537
- // No slug reads as `in_context` in context-load mode — the cache was
1538
- // wiped, so there is no prior cached attachment to reference.
1539
- for (const concept of row.concepts) {
1540
- expect(concept.status).not.toBe("in_context");
1541
- }
1542
- });
1543
-
1544
- test("context-load mode marks candidates outside `slugsToRender` as `not_injected`", async () => {
1545
- // Turn 1 (per-turn): seed both alice and bob with positive activation
1546
- // so they survive into turn 2's prior-state candidate pool.
1547
- stageTurn([
1548
- { slug: "alice-vscode", denseScore: 0.9 },
1549
- { slug: "bob-coffee", denseScore: 0.8 },
1550
- ]);
1551
- await injectMemoryV2Block({
1552
- database: db,
1553
- conversationId: "conv-1",
1554
- currentTurn: 1,
1555
- recentTurnPairs: [
1556
- {
1557
- assistantMessage: "",
1558
- userMessage: "Alice's editor and Bob's coffee",
1559
- },
1560
- ],
1561
- nowText: "Now",
1562
- messageId: "msg-1",
1563
- config: makeConfig(),
1564
- });
1565
-
1566
- // Turn 2 (context-load) with `top_k: 1`: alice and bob both carry
1567
- // forward as candidates, but only the top-ranked slug is rendered.
1568
- // Whichever slug doesn't make the cut must read as `not_injected`.
1569
- stageTurn([
1570
- { slug: "alice-vscode", denseScore: 0.95 },
1571
- { slug: "bob-coffee", denseScore: 0.05 },
1572
- ]);
1573
- await injectMemoryV2Block({
1574
- database: db,
1575
- conversationId: "conv-1",
1576
- currentTurn: 2,
1577
- recentTurnPairs: [
1578
- { assistantMessage: "", userMessage: "Reload context" },
1579
- ],
1580
- nowText: "Now",
1581
- messageId: "msg-2",
1582
- mode: "context-load",
1583
- config: makeConfig({ top_k: 1 }),
1584
- });
1585
-
1586
- expect(telemetryState.recordCalls.length).toBe(2);
1587
- const row = telemetryState.recordCalls[1] as {
1588
- mode: string;
1589
- concepts: Array<{ slug: string; status: string }>;
1590
- };
1591
- expect(row.mode).toBe("context-load");
1592
-
1593
- const byslug = new Map(row.concepts.map((c) => [c.slug, c]));
1594
- // Alice ranked first → she is in `slugsToRender` → `injected`.
1595
- expect(byslug.get("alice-vscode")!.status).toBe("injected");
1596
- // Bob was a candidate but didn't make `top_k: 1` → `not_injected`.
1597
- expect(byslug.get("bob-coffee")!.status).toBe("not_injected");
1598
- });
1599
-
1600
- test("telemetry write failure is non-fatal — injection still returns a normal result", async () => {
1601
- telemetryState.recordShouldThrow = true;
1602
-
1603
- stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
1604
- const result = await injectMemoryV2Block({
1605
- database: db,
1606
- conversationId: "conv-1",
1607
- currentTurn: 1,
1608
- recentTurnPairs: [
1609
- { assistantMessage: "", userMessage: "Alice's editor" },
1610
- ],
1611
- nowText: "Now",
1612
- messageId: "msg-1",
1613
- config: makeConfig(),
1614
- });
1615
-
1616
- // No row captured (the throw aborted the push), but the caller still
1617
- // produced a regular block + toInject result and persisted state.
1618
- expect(telemetryState.recordCalls.length).toBe(0);
1619
- expect(result.toInject).toEqual(["alice-vscode"]);
1620
- expect(result.block).not.toBeNull();
1621
- expect(result.block).toContain("# memory/concepts/alice-vscode.md");
1622
-
1623
- const persisted = await hydrate(db, "conv-1");
1624
- expect(persisted!.everInjected).toEqual([
1625
- { slug: "alice-vscode", turn: 1 },
1626
- ]);
1627
- });
1628
-
1629
- // ---------------------------------------------------------------------------
1630
- // Per-page error isolation + on-throw telemetry
1631
- // ---------------------------------------------------------------------------
1632
-
1633
- test("one slug's page-read failing isolates the error — other slugs still render and the corrupt slug records `status: corrupt`", async () => {
1634
- // Two slugs rank into top-K together. Carol's page reads cleanly; alice's
1635
- // `readPage` throws a ZodError mimicking the real "unrecognized
1636
- // frontmatter key" failure that motivated this work. Before the fix, the
1637
- // bare `Promise.all` rejected and the entire turn lost its block AND its
1638
- // activation log row. With per-page isolation, carol still renders and
1639
- // the activation log row marks alice as `corrupt` (telemetry remains
1640
- // observable for triage).
1641
- const zodErr = z.object({ x: z.string() }).safeParse({ x: 1 }).error!;
1642
- pageStoreState.failingSlugs.set("alice-vscode", zodErr);
1643
- stageTurn([
1644
- { slug: "alice-vscode", denseScore: 0.95 },
1645
- { slug: "carol-jazz", denseScore: 0.9 },
1646
- ]);
1647
-
1648
- const result = await injectMemoryV2Block({
1649
- database: db,
1650
- conversationId: "conv-1",
1651
- currentTurn: 1,
1652
- recentTurnPairs: [
1653
- { assistantMessage: "", userMessage: "music and editors" },
1654
- ],
1655
- nowText: "Now",
1656
- messageId: "msg-1",
1657
- config: makeConfig(),
1658
- });
1659
-
1660
- // (a) Block is non-null and contains content from the OTHER slug; alice
1661
- // is dropped from the rendered block but does not poison the batch.
1662
- expect(result.block).not.toBeNull();
1663
- expect(result.block).toContain("# memory/concepts/carol-jazz.md");
1664
- expect(result.block).not.toContain("# memory/concepts/alice-vscode.md");
1665
-
1666
- // (b) Activation log row exists with carol `injected` and alice
1667
- // `corrupt`. Status `corrupt` is reserved for read-time throws and is
1668
- // distinct from `page_missing` (which is null-return / file vanished).
1669
- expect(telemetryState.recordCalls.length).toBe(1);
1670
- const row = telemetryState.recordCalls[0] as {
1671
- mode: string;
1672
- concepts: Array<{ slug: string; status: string }>;
1673
- };
1674
- expect(row.mode).toBe("per-turn");
1675
- const byslug = new Map(row.concepts.map((c) => [c.slug, c]));
1676
- expect(byslug.get("alice-vscode")!.status).toBe("corrupt");
1677
- expect(byslug.get("carol-jazz")!.status).toBe("injected");
1678
-
1679
- // (c) Both slugs land in `toInject` and `everInjected` — same handling
1680
- // as `page_missing` (see the phantom-slug test): the slug was attempted
1681
- // this turn, telemetry records the outcome, and we don't keep re-trying
1682
- // a stale Qdrant / edge-index entry on every subsequent turn.
1683
- expect(new Set(result.toInject)).toEqual(
1684
- new Set(["alice-vscode", "carol-jazz"]),
1685
- );
1686
- const persisted = await hydrate(db, "conv-1");
1687
- const everInjectedSlugs = persisted!.everInjected.map((e) => e.slug);
1688
- expect(new Set(everInjectedSlugs)).toEqual(
1689
- new Set(["alice-vscode", "carol-jazz"]),
1690
- );
1691
- });
1692
-
1693
- test("a throw before renderInjectionBlock still flushes telemetry as `mode: errored` and re-throws", async () => {
1694
- // The activation-state save throws — the most realistic non-render
1695
- // failure mode (transient SQLite write error mid-injection). The
1696
- // `injectMemoryV2Block` outer try/finally must (a) flush an activation
1697
- // log row tagged `mode: "errored"` so silent failures stay observable
1698
- // in the database, and (b) re-throw so callers (e.g. `prepareMemory`'s
1699
- // outer catch) see the original error and can degrade gracefully.
1700
- activationStoreState.saveShouldThrow = true;
1701
- stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
1702
-
1703
- let threw: unknown = undefined;
1704
- try {
1705
- await injectMemoryV2Block({
1706
- database: db,
1707
- conversationId: "conv-1",
1708
- currentTurn: 1,
1709
- recentTurnPairs: [
1710
- { assistantMessage: "", userMessage: "Alice's editor" },
1711
- ],
1712
- nowText: "Now",
1713
- messageId: "msg-1",
1714
- config: makeConfig(),
1715
- });
1716
- } catch (err) {
1717
- threw = err;
1718
- }
1719
-
1720
- // The original error propagates to the caller.
1721
- expect(threw).toBeInstanceOf(Error);
1722
- expect((threw as Error).message).toContain(
1723
- "simulated activation-store save failure",
1724
- );
1725
-
1726
- // A telemetry row was still written, tagged `errored`. `concepts` is
1727
- // empty because the throw fired before the row-builder ran — that's
1728
- // expected and documented as part of the contract.
1729
- expect(telemetryState.recordCalls.length).toBe(1);
1730
- const row = telemetryState.recordCalls[0] as {
1731
- mode: string;
1732
- conversationId: string;
1733
- turn: number;
1734
- concepts: unknown[];
1735
- };
1736
- expect(row.mode).toBe("errored");
1737
- expect(row.conversationId).toBe("conv-1");
1738
- expect(row.turn).toBe(1);
1739
- expect(row.concepts).toEqual([]);
1740
- });
1741
-
1742
- test("activation pipeline routes through `finalizeInjection` — telemetry shape and config snapshot match the contract", async () => {
1743
- // Pure-refactor regression check: `injectMemoryV2Block` now delegates the
1744
- // tail (state save + render + telemetry finalization + log write) to a
1745
- // private `finalizeInjection` helper. This test asserts the helper is
1746
- // exercised by verifying `recordMemoryV2ActivationLog` is called with the
1747
- // same arg shape as before — same conversationId/turn/mode, same config
1748
- // snapshot, and a fully populated concept row whose status was finalized
1749
- // to `"injected"` on the freshly-attached slug.
1750
- stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
1751
-
1752
- const result = await injectMemoryV2Block({
1753
- database: db,
1754
- conversationId: "conv-finalize",
1755
- currentTurn: 7,
1756
- recentTurnPairs: [
1757
- { assistantMessage: "", userMessage: "Alice's editor" },
1758
- ],
1759
- nowText: "Now",
1760
- messageId: "msg-finalize",
1761
- config: makeConfig(),
1762
- });
1763
-
1764
- // The helper rendered + persisted just like the original tail did.
1765
- expect(result.block).toContain("alice-vscode");
1766
- expect(result.toInject).toEqual(["alice-vscode"]);
1767
-
1768
- expect(telemetryState.recordCalls.length).toBe(1);
1769
- const row = telemetryState.recordCalls[0] as {
1770
- conversationId: string;
1771
- turn: number;
1772
- mode: string;
1773
- concepts: Array<{
1774
- slug: string;
1775
- status: string;
1776
- finalActivation: number;
1777
- }>;
1778
- config: {
1779
- d: number;
1780
- c_user: number;
1781
- c_assistant: number;
1782
- c_now: number;
1783
- k: number;
1784
- hops: number;
1785
- top_k: number;
1786
- epsilon: number;
1787
- };
1788
- };
1789
- expect(row.conversationId).toBe("conv-finalize");
1790
- expect(row.turn).toBe(7);
1791
- expect(row.mode).toBe("per-turn");
1792
- // Config snapshot must include all eight tunables — proves the helper is
1793
- // pulling from `config.memory.v2` rather than synthesizing a partial.
1794
- expect(Object.keys(row.config).sort()).toEqual(
1795
- [
1796
- "c_assistant",
1797
- "c_now",
1798
- "c_user",
1799
- "d",
1800
- "epsilon",
1801
- "hops",
1802
- "k",
1803
- "top_k",
1804
- ].sort(),
1805
- );
1806
- // Status finalization ran inside the helper — alice was selected and
1807
- // rendered, so its row reads `injected`.
1808
- const aliceRow = row.concepts.find((c) => c.slug === "alice-vscode");
1809
- expect(aliceRow?.status).toBe("injected");
1810
- });
1811
-
1812
- // ---------------------------------------------------------------------------
1813
- // Router mode (flag-gated)
1814
- // ---------------------------------------------------------------------------
1815
-
1816
- describe("router mode", () => {
1817
- test("flag-on: router-selected slugs render and append to everInjected", async () => {
1818
- // Router picks alice. The activation pipeline never runs — we don't
1819
- // stage any qdrant responses here, and that's intentional. The
1820
- // candidate set comes straight from the router's `selectedSlugs`.
1821
- routerState.nextResult = {
1822
- selectedSlugs: ["alice-vscode"],
1823
- failureReason: null,
1824
- };
1825
-
1826
- const result = await injectMemoryV2Block({
1827
- database: db,
1828
- conversationId: "conv-router-1",
1829
- currentTurn: 1,
1830
- recentTurnPairs: [
1831
- { assistantMessage: "", userMessage: "Tell me about Alice" },
1832
- ],
1833
- nowText: "Now",
1834
- messageId: "msg-1",
1835
- config: makeConfig({ router: { enabled: true } }),
1836
- });
1837
-
1838
- expect(routerState.callCount).toBe(1);
1839
- expect(result.toInject).toEqual(["alice-vscode"]);
1840
- expect(result.block).not.toBeNull();
1841
- expect(result.block).toContain("# memory/concepts/alice-vscode.md");
1842
-
1843
- const persisted = await hydrate(db, "conv-router-1");
1844
- expect(persisted!.everInjected).toEqual([
1845
- { slug: "alice-vscode", turn: 1 },
1846
- ]);
1847
- // Router mode persists an empty sparse activation map — the router
1848
- // does not compute spreading-activation scores.
1849
- expect(persisted!.state).toEqual({});
1850
-
1851
- // Telemetry: success rows get `mode: "router"` and `source: "router"`,
1852
- // with all activation fields zeroed.
1853
- expect(telemetryState.recordCalls.length).toBe(1);
1854
- const row = telemetryState.recordCalls[0] as {
1855
- mode: string;
1856
- concepts: Array<{
1857
- slug: string;
1858
- source: string;
1859
- status: string;
1860
- finalActivation: number;
1861
- ownActivation: number;
1862
- }>;
1863
- };
1864
- expect(row.mode).toBe("router");
1865
- const aliceRow = row.concepts.find((c) => c.slug === "alice-vscode");
1866
- expect(aliceRow).toBeDefined();
1867
- // Default-stub provenance is `tier3:0` (single-batch path); see the
1868
- // runRouter mock for the synthesis rule.
1869
- expect(aliceRow!.source).toBe("tier3:0");
1870
- expect(aliceRow!.status).toBe("injected");
1871
- expect(aliceRow!.finalActivation).toBe(0);
1872
- expect(aliceRow!.ownActivation).toBe(0);
1873
- });
1874
-
1875
- test("flag-on: saturated index (every page already injected) skips the router LLM call", async () => {
1876
- // Turn 1 — normal router path injects alice.
1877
- routerState.nextResult = {
1878
- selectedSlugs: ["alice-vscode"],
1879
- failureReason: null,
1880
- };
1881
- await injectMemoryV2Block({
1882
- database: db,
1883
- conversationId: "conv-router-saturated",
1884
- currentTurn: 1,
1885
- recentTurnPairs: [
1886
- { assistantMessage: "", userMessage: "Tell me about Alice" },
1887
- ],
1888
- nowText: "Now",
1889
- messageId: "msg-1",
1890
- config: makeConfig({ router: { enabled: true } }),
1891
- });
1892
-
1893
- // Mark every page in the index as already injected — the state a
1894
- // small workspace reaches a few turns into any conversation.
1895
- const { getPageIndex } = await import("../page-index.js");
1896
- const index = await getPageIndex(tmpWorkspace);
1897
- const seeded = await hydrate(db, "conv-router-saturated");
1898
- await save(db, "conv-router-saturated", {
1899
- ...seeded!,
1900
- everInjected: index.entries.map((e) => ({ slug: e.slug, turn: 1 })),
1901
- });
1902
-
1903
- // Turn 2 — the router must not be called: any selection would dedupe
1904
- // against everInjected and render nothing.
1905
- const callsBefore = routerState.callCount;
1906
- routerState.nextResult = {
1907
- selectedSlugs: ["bob-coffee"],
1908
- failureReason: null,
1909
- };
1910
- const result = await injectMemoryV2Block({
1911
- database: db,
1912
- conversationId: "conv-router-saturated",
1913
- currentTurn: 2,
1914
- recentTurnPairs: [{ assistantMessage: "ok", userMessage: "and Bob?" }],
1915
- nowText: "Now",
1916
- messageId: "msg-2",
1917
- config: makeConfig({ router: { enabled: true } }),
1918
- });
1919
-
1920
- expect(routerState.callCount).toBe(callsBefore);
1921
- expect(result.block).toBeNull();
1922
- expect(result.toInject).toEqual([]);
1923
-
1924
- // State still advanced; everInjected preserved for future dedupe.
1925
- const persisted = await hydrate(db, "conv-router-saturated");
1926
- expect(persisted!.currentTurn).toBe(2);
1927
- expect(persisted!.messageId).toBe("msg-2");
1928
- expect(persisted!.everInjected.length).toBe(index.entries.length);
1929
-
1930
- // Telemetry row stays in router mode with every slug carried over.
1931
- const row = telemetryState.recordCalls.at(-1) as {
1932
- mode: string;
1933
- concepts: Array<{ source: string; status: string }>;
1934
- };
1935
- expect(row.mode).toBe("router");
1936
- expect(row.concepts.length).toBe(index.entries.length);
1937
- for (const concept of row.concepts) {
1938
- expect(concept.source).toBe("carry_over");
1939
- // `finalizeInjection` rewrites the placeholder status: slugs already
1940
- // in everInjected are reported as in_context.
1941
- expect(concept.status).toBe("in_context");
1942
- }
1943
- });
1944
-
1945
- test("flag-on: router failure logs warn, writes mode:`errored` telemetry, returns null block", async () => {
1946
- routerState.nextResult = {
1947
- selectedSlugs: [],
1948
- failureReason: "api_error",
1949
- };
1950
-
1951
- const result = await injectMemoryV2Block({
1952
- database: db,
1953
- conversationId: "conv-router-fail",
1954
- currentTurn: 3,
1955
- recentTurnPairs: [{ assistantMessage: "ok", userMessage: "anything" }],
1956
- nowText: "Now",
1957
- messageId: "msg-fail",
1958
- config: makeConfig({ router: { enabled: true } }),
1959
- });
1960
-
1961
- expect(result.block).toBeNull();
1962
- expect(result.toInject).toEqual([]);
1963
-
1964
- // Stub state still advanced.
1965
- const persisted = await hydrate(db, "conv-router-fail");
1966
- expect(persisted).not.toBeNull();
1967
- expect(persisted!.currentTurn).toBe(3);
1968
- expect(persisted!.messageId).toBe("msg-fail");
1969
- expect(persisted!.state).toEqual({});
1970
- expect(persisted!.everInjected).toEqual([]);
1971
-
1972
- // Single telemetry row with `mode: "errored"` (not `"router"`).
1973
- expect(telemetryState.recordCalls.length).toBe(1);
1974
- const row = telemetryState.recordCalls[0] as {
1975
- mode: string;
1976
- conversationId: string;
1977
- turn: number;
1978
- concepts: unknown[];
1979
- };
1980
- expect(row.mode).toBe("errored");
1981
- expect(row.conversationId).toBe("conv-router-fail");
1982
- expect(row.turn).toBe(3);
1983
- expect(row.concepts).toEqual([]);
1984
- });
1985
-
1986
- test("flag-on: router-failure path swallows a save() error and returns block:null instead of throwing", async () => {
1987
- // PR 30176 refactored router-failure handling to delegate to
1988
- // `finalizeInjection`. That regressed the prior inline log-and-continue
1989
- // semantics on the router-failure path: a transient SQLite write
1990
- // throwing during the stub-state save now aborted the whole turn
1991
- // because `finalizeInjection`'s try/catch re-threw caughtErr at the end.
1992
- //
1993
- // This test stages exactly that scenario — router returns
1994
- // `failureReason: api_error` AND `save()` throws — and asserts the
1995
- // turn completes with `{ block: null, toInject: [] }` rather than
1996
- // propagating the SQLite error to `prepareMemory`.
1997
- routerState.nextResult = {
1998
- selectedSlugs: [],
1999
- failureReason: "api_error",
2000
- };
2001
- activationStoreState.saveShouldThrow = true;
2002
-
2003
- let threw: unknown = undefined;
2004
- let result: Awaited<ReturnType<typeof injectMemoryV2Block>> | undefined;
2005
- try {
2006
- result = await injectMemoryV2Block({
2007
- database: db,
2008
- conversationId: "conv-router-fail-save-throws",
2009
- currentTurn: 5,
2010
- recentTurnPairs: [
2011
- { assistantMessage: "ok", userMessage: "anything" },
2012
- ],
2013
- nowText: "Now",
2014
- messageId: "msg-fail-save",
2015
- config: makeConfig({ router: { enabled: true } }),
2016
- });
2017
- } catch (err) {
2018
- threw = err;
2019
- }
2020
-
2021
- expect(threw).toBeUndefined();
2022
- expect(result).toBeDefined();
2023
- expect(result!.block).toBeNull();
2024
- expect(result!.toInject).toEqual([]);
2025
-
2026
- // Telemetry still flushes with `mode: "errored"` so the failure stays
2027
- // observable — the same row the inline pre-refactor path emitted.
2028
- expect(telemetryState.recordCalls.length).toBe(1);
2029
- const row = telemetryState.recordCalls[0] as {
2030
- mode: string;
2031
- concepts: unknown[];
2032
- };
2033
- expect(row.mode).toBe("errored");
2034
- expect(row.concepts).toEqual([]);
2035
- });
2036
-
2037
- test("flag-on: router abstention (empty selectedSlugs, no failure) writes mode:`router` row with no injected pages", async () => {
2038
- routerState.nextResult = {
2039
- selectedSlugs: [],
2040
- failureReason: null,
2041
- };
2042
-
2043
- const result = await injectMemoryV2Block({
2044
- database: db,
2045
- conversationId: "conv-router-abstain",
2046
- currentTurn: 1,
2047
- recentTurnPairs: [{ assistantMessage: "", userMessage: "small talk" }],
2048
- nowText: "Now",
2049
- messageId: "msg-abstain",
2050
- config: makeConfig({ router: { enabled: true } }),
2051
- });
2052
-
2053
- expect(result.block).toBeNull();
2054
- expect(result.toInject).toEqual([]);
2055
-
2056
- // No prior everInjected to dedup against, so toInject is empty and
2057
- // nothing renders. State still advanced.
2058
- const persisted = await hydrate(db, "conv-router-abstain");
2059
- expect(persisted!.everInjected).toEqual([]);
2060
- expect(persisted!.currentTurn).toBe(1);
2061
-
2062
- // Telemetry: `mode: "router"` row with zero injected pages.
2063
- expect(telemetryState.recordCalls.length).toBe(1);
2064
- const row = telemetryState.recordCalls[0] as {
2065
- mode: string;
2066
- concepts: Array<{ slug: string; status: string }>;
2067
- };
2068
- expect(row.mode).toBe("router");
2069
- const injectedCount = row.concepts.filter(
2070
- (c) => c.status === "injected",
2071
- ).length;
2072
- expect(injectedCount).toBe(0);
2073
- });
2074
-
2075
- test("flag-on: router-selected slug whose page is missing on disk records `page_missing` and is NOT added to everInjected", async () => {
2076
- routerState.nextResult = {
2077
- selectedSlugs: ["phantom-router-slug"],
2078
- failureReason: null,
2079
- };
2080
-
2081
- const result = await injectMemoryV2Block({
2082
- database: db,
2083
- conversationId: "conv-router-missing",
2084
- currentTurn: 1,
2085
- recentTurnPairs: [{ assistantMessage: "", userMessage: "phantom" }],
2086
- nowText: "Now",
2087
- messageId: "msg-missing",
2088
- config: makeConfig({ router: { enabled: true } }),
2089
- });
2090
-
2091
- // No backing page → block collapses to null.
2092
- expect(result.block).toBeNull();
2093
- // toInject mirrors `newlyInjected` from `finalizeInjection` — the
2094
- // missing slug still flowed through `slugsToRender` so it's recorded
2095
- // here (matching the activation-mode phantom-slug contract).
2096
- expect(result.toInject).toEqual(["phantom-router-slug"]);
2097
-
2098
- // Activation-mode parity: the phantom slug DOES land in everInjected
2099
- // so we don't infinite-retry it. (This matches the behavior the
2100
- // existing `returns null block when toInject slugs all reference
2101
- // missing pages` test asserts for activation mode.)
2102
- const persisted = await hydrate(db, "conv-router-missing");
2103
- expect(persisted!.everInjected).toEqual([
2104
- { slug: "phantom-router-slug", turn: 1 },
2105
- ]);
2106
-
2107
- // Telemetry: `status: "page_missing"` for the phantom slug.
2108
- expect(telemetryState.recordCalls.length).toBe(1);
2109
- const row = telemetryState.recordCalls[0] as {
2110
- mode: string;
2111
- concepts: Array<{ slug: string; status: string; source: string }>;
2112
- };
2113
- expect(row.mode).toBe("router");
2114
- const phantom = row.concepts.find(
2115
- (c) => c.slug === "phantom-router-slug",
2116
- );
2117
- expect(phantom).toBeDefined();
2118
- expect(phantom!.status).toBe("page_missing");
2119
- expect(phantom!.source).toBe("tier3:0");
2120
- });
2121
-
2122
- test("flag-on: router re-picking a prior-everInjected slug does NOT re-render it; non-overlapping picks render and append to everInjected", async () => {
2123
- // Turn 1: router picks alice. Standard append.
2124
- routerState.nextResult = {
2125
- selectedSlugs: ["alice-vscode"],
2126
- failureReason: null,
2127
- };
2128
- const turn1 = await injectMemoryV2Block({
2129
- database: db,
2130
- conversationId: "conv-router-dedup",
2131
- currentTurn: 1,
2132
- recentTurnPairs: [
2133
- { assistantMessage: "", userMessage: "Tell me about Alice" },
2134
- ],
2135
- nowText: "Now",
2136
- messageId: "msg-1",
2137
- config: makeConfig({ router: { enabled: true } }),
2138
- });
2139
- expect(turn1.toInject).toEqual(["alice-vscode"]);
2140
-
2141
- // Turn 2: router re-picks alice (the "re-anchor" prompt branch) AND
2142
- // adds bob. The block must NOT contain alice's body — her cached
2143
- // attachment from turn 1 is still on the prior user message — but
2144
- // must contain bob's.
2145
- telemetryState.recordCalls.length = 0;
2146
- routerState.nextResult = {
2147
- selectedSlugs: ["alice-vscode", "bob-coffee"],
2148
- failureReason: null,
2149
- };
2150
- const turn2 = await injectMemoryV2Block({
2151
- database: db,
2152
- conversationId: "conv-router-dedup",
2153
- currentTurn: 2,
2154
- recentTurnPairs: [
2155
- { assistantMessage: "Sure", userMessage: "And Bob?" },
2156
- ],
2157
- nowText: "Now",
2158
- messageId: "msg-2",
2159
- config: makeConfig({ router: { enabled: true } }),
2160
- });
2161
-
2162
- // Re-picked alice was deduped; only bob is freshly injected.
2163
- expect(turn2.toInject).toEqual(["bob-coffee"]);
2164
- expect(turn2.block).not.toBeNull();
2165
- expect(turn2.block).toContain("# memory/concepts/bob-coffee.md");
2166
- expect(turn2.block).toContain("Bob takes his coffee");
2167
- expect(turn2.block).not.toContain("VS Code");
2168
- expect(turn2.block).not.toContain("# memory/concepts/alice-vscode.md");
2169
-
2170
- // everInjected only gained bob — alice was already there.
2171
- const persisted = await hydrate(db, "conv-router-dedup");
2172
- expect(persisted!.everInjected).toEqual([
2173
- { slug: "alice-vscode", turn: 1 },
2174
- { slug: "bob-coffee", turn: 2 },
2175
- ]);
2176
- });
2177
-
2178
- test("flag-on: telemetry distinguishes `source: router` (router picks) from `source: carry_over` (prior-everInjected slugs the router did not re-pick)", async () => {
2179
- // Turn 1: seed everInjected with alice.
2180
- routerState.nextResult = {
2181
- selectedSlugs: ["alice-vscode"],
2182
- failureReason: null,
2183
- };
2184
- await injectMemoryV2Block({
2185
- database: db,
2186
- conversationId: "conv-router-source",
2187
- currentTurn: 1,
2188
- recentTurnPairs: [{ assistantMessage: "", userMessage: "Alice" }],
2189
- nowText: "Now",
2190
- messageId: "msg-1",
2191
- config: makeConfig({ router: { enabled: true } }),
2192
- });
2193
- telemetryState.recordCalls.length = 0;
2194
-
2195
- // Turn 2: router picks bob only. alice is still in everInjected but
2196
- // not re-picked — her telemetry row must read `source: carry_over`,
2197
- // not `source: router`.
2198
- routerState.nextResult = {
2199
- selectedSlugs: ["bob-coffee"],
2200
- failureReason: null,
2201
- };
2202
- await injectMemoryV2Block({
2203
- database: db,
2204
- conversationId: "conv-router-source",
2205
- currentTurn: 2,
2206
- recentTurnPairs: [{ assistantMessage: "", userMessage: "Bob" }],
2207
- nowText: "Now",
2208
- messageId: "msg-2",
2209
- config: makeConfig({ router: { enabled: true } }),
2210
- });
2211
-
2212
- expect(telemetryState.recordCalls.length).toBe(1);
2213
- const row = telemetryState.recordCalls[0] as {
2214
- mode: string;
2215
- concepts: Array<{ slug: string; source: string; status: string }>;
2216
- };
2217
- expect(row.mode).toBe("router");
2218
- const aliceRow = row.concepts.find((c) => c.slug === "alice-vscode");
2219
- const bobRow = row.concepts.find((c) => c.slug === "bob-coffee");
2220
- expect(aliceRow).toBeDefined();
2221
- expect(bobRow).toBeDefined();
2222
- expect(aliceRow!.source).toBe("carry_over");
2223
- expect(aliceRow!.status).toBe("in_context");
2224
- expect(bobRow!.source).toBe("tier3:0");
2225
- expect(bobRow!.status).toBe("injected");
2226
- });
2227
-
2228
- test("flag-off (default): activation pipeline still runs unchanged", async () => {
2229
- // Regression check — with the router flag explicitly off (the
2230
- // production default), `runRouter` must never be called and the
2231
- // activation pipeline drives the selection just like before.
2232
- stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
2233
- routerState.nextResult = {
2234
- selectedSlugs: ["should-not-be-used"],
2235
- failureReason: null,
2236
- };
2237
-
2238
- const result = await injectMemoryV2Block({
2239
- database: db,
2240
- conversationId: "conv-flag-off",
2241
- currentTurn: 1,
2242
- recentTurnPairs: [
2243
- { assistantMessage: "", userMessage: "Alice's editor" },
2244
- ],
2245
- nowText: "Now",
2246
- messageId: "msg-1",
2247
- config: makeConfig({ router: { enabled: false } }),
2248
- });
2249
-
2250
- // Router was not called.
2251
- expect(routerState.callCount).toBe(0);
2252
- // Activation pipeline produced its normal result.
2253
- expect(result.toInject).toEqual(["alice-vscode"]);
2254
- expect(result.block).toContain("# memory/concepts/alice-vscode.md");
2255
-
2256
- // Telemetry row carries the activation mode, not router.
2257
- expect(telemetryState.recordCalls.length).toBe(1);
2258
- const row = telemetryState.recordCalls[0] as { mode: string };
2259
- expect(row.mode).toBe("per-turn");
2260
- });
2261
-
2262
- test("flag-on + mode='context-load': router runs (everInjected was cleared by onCompacted so dedupe is a no-op; abstention is accepted as the trade-off)", async () => {
2263
- // Context-load is the full top-K bootstrap fired after compaction or
2264
- // a fresh conversation reload. The earlier worry about the router's
2265
- // `everInjected` dedupe filtering out post-compaction restorations
2266
- // doesn't apply: `ConversationGraphMemory.onCompacted` calls
2267
- // `evictCompactedTurnsV2` which empties the list before this code
2268
- // runs. Router abstention here means no v2 pages this turn — that's
2269
- // preferable to letting the activation graph pick something arbitrary.
2270
- routerState.nextResult = {
2271
- selectedSlugs: ["alice-vscode"],
2272
- failureReason: null,
2273
- };
2274
-
2275
- const result = await injectMemoryV2Block({
2276
- database: db,
2277
- conversationId: "conv-context-load-router-on",
2278
- currentTurn: 1,
2279
- recentTurnPairs: [
2280
- { assistantMessage: "", userMessage: "Tell me about Alice" },
2281
- ],
2282
- nowText: "Now",
2283
- messageId: "msg-1",
2284
- mode: "context-load",
2285
- config: makeConfig({ router: { enabled: true } }),
2286
- });
2287
-
2288
- // Router was called on context-load too.
2289
- expect(routerState.callCount).toBe(1);
2290
-
2291
- // Router's picks were rendered.
2292
- expect(result.toInject).toEqual(["alice-vscode"]);
2293
- expect(result.block).toContain("# memory/concepts/alice-vscode.md");
2294
-
2295
- // Telemetry row reflects the router mode, not the activation mode.
2296
- expect(telemetryState.recordCalls.length).toBe(1);
2297
- const row = telemetryState.recordCalls[0] as { mode: string };
2298
- expect(row.mode).toBe("router");
2299
- });
2300
- });
2301
- });