@vellumai/assistant 0.8.5 → 0.8.7-dev.202606052118.34cd356

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 (1323) hide show
  1. package/AGENTS.md +33 -1
  2. package/ARCHITECTURE.md +1 -1
  3. package/Dockerfile +21 -4
  4. package/bun.lock +13 -4
  5. package/bunfig.toml +6 -1
  6. package/docker-entrypoint.sh +12 -8
  7. package/docker-init-apt-root.sh +3 -1
  8. package/docker-kata-apt-env.sh +3 -1
  9. package/docker-kata-runtime-family.sh +12 -0
  10. package/docs/architecture/memory.md +1 -1
  11. package/docs/credential-execution-service.md +6 -6
  12. package/docs/plugins.md +114 -86
  13. package/examples/plugins/echo/README.md +13 -12
  14. package/examples/plugins/echo/register.ts +0 -54
  15. package/knip.json +1 -0
  16. package/node_modules/@vellumai/environments/bun.lock +24 -0
  17. package/node_modules/@vellumai/environments/package.json +18 -0
  18. package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +95 -0
  19. package/node_modules/@vellumai/environments/src/index.ts +11 -0
  20. package/node_modules/@vellumai/environments/src/seeds.ts +73 -0
  21. package/node_modules/@vellumai/environments/src/types.ts +70 -0
  22. package/node_modules/@vellumai/environments/tsconfig.json +20 -0
  23. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +11 -0
  24. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +15 -17
  25. package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +3 -3
  26. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +15 -7
  27. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
  28. package/openapi.yaml +8748 -589
  29. package/package.json +8 -4
  30. package/scripts/generate-openapi.ts +88 -54
  31. package/src/__tests__/actor-token-service.test.ts +3 -2
  32. package/src/__tests__/agent-loop-callsite-precedence.test.ts +42 -80
  33. package/src/__tests__/agent-loop-exit-reason.test.ts +284 -48
  34. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +141 -0
  35. package/src/__tests__/agent-loop-override-profile.test.ts +21 -33
  36. package/src/__tests__/agent-loop-provider-error-recording.test.ts +7 -5
  37. package/src/__tests__/agent-loop-thinking.test.ts +17 -12
  38. package/src/__tests__/agent-loop.test.ts +238 -422
  39. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +7 -2
  40. package/src/__tests__/agent-wake-override-profile.test.ts +23 -40
  41. package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
  42. package/src/__tests__/annotate-activity-metadata.test.ts +262 -0
  43. package/src/__tests__/annotate-risk-options.test.ts +3 -3
  44. package/src/__tests__/anthropic-provider.test.ts +296 -57
  45. package/src/__tests__/app-builder-skill-instructions.test.ts +22 -0
  46. package/src/__tests__/app-control-flow.test.ts +6 -1
  47. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  48. package/src/__tests__/approval-cascade.test.ts +5 -11
  49. package/src/__tests__/approval-routes-http.test.ts +17 -16
  50. package/src/__tests__/assert-not-live-db.ts +79 -0
  51. package/src/__tests__/assistant-event-hub.test.ts +25 -0
  52. package/src/__tests__/assistant-event.test.ts +15 -0
  53. package/src/__tests__/assistant-events-sse-shed.test.ts +8 -0
  54. package/src/__tests__/assistant-feature-flags-integration.test.ts +11 -27
  55. package/src/__tests__/assistant-stream-state.test.ts +645 -0
  56. package/src/__tests__/audit-log-rotation.test.ts +2 -2
  57. package/src/__tests__/auth-fallback-events-store.test.ts +116 -0
  58. package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
  59. package/src/__tests__/avatar-e2e.test.ts +7 -37
  60. package/src/__tests__/avatar-generator.test.ts +12 -42
  61. package/src/__tests__/avatar-identity-sync.test.ts +28 -3
  62. package/src/__tests__/background-shell-bash.test.ts +3 -7
  63. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -8
  64. package/src/__tests__/browser-skill-endstate.test.ts +3 -3
  65. package/src/__tests__/btw-routes.test.ts +72 -17
  66. package/src/__tests__/build-persisted-content.test.ts +184 -0
  67. package/src/__tests__/call-controller.test.ts +3 -2
  68. package/src/__tests__/call-pointer-messages.test.ts +5 -3
  69. package/src/__tests__/call-site-routing-provider.test.ts +22 -40
  70. package/src/__tests__/catalog-files.test.ts +1 -0
  71. package/src/__tests__/channel-approval-routes.test.ts +52 -23
  72. package/src/__tests__/channel-approvals.test.ts +4 -2
  73. package/src/__tests__/channel-guardian.test.ts +3 -2
  74. package/src/__tests__/channel-invite-transport.test.ts +1 -5
  75. package/src/__tests__/channel-readiness-routes.test.ts +0 -4
  76. package/src/__tests__/channel-readiness-slack-remote.test.ts +170 -0
  77. package/src/__tests__/channel-reply-delivery.test.ts +35 -0
  78. package/src/__tests__/channel-retry-sweep.test.ts +388 -79
  79. package/src/__tests__/checker.test.ts +12 -12
  80. package/src/__tests__/clawhub-files.test.ts +1 -0
  81. package/src/__tests__/compaction-circuit.test.ts +258 -0
  82. package/src/__tests__/compaction-direct.test.ts +132 -0
  83. package/src/__tests__/compaction-events.test.ts +6 -17
  84. package/src/__tests__/compaction-trail-store.test.ts +186 -0
  85. package/src/__tests__/compaction.benchmark.test.ts +0 -30
  86. package/src/__tests__/compactor-call-site-logging.test.ts +1 -0
  87. package/src/__tests__/compactor-image-manifest-trust.test.ts +112 -0
  88. package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
  89. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +7 -5
  90. package/src/__tests__/computer-use-tools.test.ts +14 -16
  91. package/src/__tests__/config-loader-backfill.test.ts +13 -28
  92. package/src/__tests__/config-loader-corrupt.test.ts +5 -5
  93. package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
  94. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
  95. package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
  96. package/src/__tests__/config-schema.test.ts +10 -10
  97. package/src/__tests__/config-watcher.test.ts +28 -0
  98. package/src/__tests__/connection-model-compat.test.ts +83 -0
  99. package/src/__tests__/contacts-tools.test.ts +3 -2
  100. package/src/__tests__/context-search-agent-runner.test.ts +6 -3
  101. package/src/__tests__/context-token-estimator.test.ts +56 -0
  102. package/src/__tests__/context-window-manager-compact-retry.test.ts +291 -0
  103. package/src/__tests__/conversation-abort-tool-results.test.ts +73 -23
  104. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +10 -7
  105. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
  106. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +23 -34
  107. package/src/__tests__/conversation-agent-loop-overflow.test.ts +477 -930
  108. package/src/__tests__/conversation-agent-loop.test.ts +1056 -1068
  109. package/src/__tests__/conversation-analysis-routes.test.ts +8 -3
  110. package/src/__tests__/conversation-app-control-instantiation.test.ts +29 -19
  111. package/src/__tests__/conversation-app-control-lifecycle.test.ts +2 -1
  112. package/src/__tests__/conversation-attention-store.test.ts +101 -0
  113. package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
  114. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  115. package/src/__tests__/conversation-clear-safety.test.ts +20 -10
  116. package/src/__tests__/conversation-confirmation-signals.test.ts +16 -45
  117. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  118. package/src/__tests__/conversation-disk-view.test.ts +10 -17
  119. package/src/__tests__/conversation-error.test.ts +30 -0
  120. package/src/__tests__/conversation-fork-crud.test.ts +132 -157
  121. package/src/__tests__/conversation-fork-route.test.ts +19 -16
  122. package/src/__tests__/conversation-history-web-search.test.ts +12 -1
  123. package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
  124. package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
  125. package/src/__tests__/conversation-init.benchmark.test.ts +6 -6
  126. package/src/__tests__/conversation-lifecycle.test.ts +4 -2
  127. package/src/__tests__/conversation-list-source.test.ts +3 -2
  128. package/src/__tests__/conversation-load-history-repair.test.ts +5 -3
  129. package/src/__tests__/conversation-load-history-stripped.test.ts +2 -1
  130. package/src/__tests__/conversation-message-sync-tags.test.ts +3 -4
  131. package/src/__tests__/conversation-pairing.test.ts +60 -4
  132. package/src/__tests__/conversation-pre-run-repair.test.ts +1 -1
  133. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +36 -7
  134. package/src/__tests__/conversation-process-callsite.test.ts +28 -30
  135. package/src/__tests__/conversation-provider-retry-repair.test.ts +85 -51
  136. package/src/__tests__/conversation-queue.test.ts +605 -455
  137. package/src/__tests__/conversation-routes-disk-view.test.ts +9 -20
  138. package/src/__tests__/conversation-routes-guardian-reply.test.ts +35 -10
  139. package/src/__tests__/conversation-routes-slash-commands.test.ts +40 -8
  140. package/src/__tests__/conversation-runtime-assembly.test.ts +395 -313
  141. package/src/__tests__/conversation-runtime-workspace.test.ts +114 -36
  142. package/src/__tests__/conversation-skill-tools.test.ts +38 -142
  143. package/src/__tests__/conversation-slash-commands.test.ts +8 -42
  144. package/src/__tests__/conversation-slash-queue.test.ts +125 -62
  145. package/src/__tests__/conversation-slash-unknown.test.ts +18 -15
  146. package/src/__tests__/conversation-speed-override.test.ts +9 -22
  147. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  148. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +136 -15
  149. package/src/__tests__/conversation-surfaces-app-control.test.ts +32 -4
  150. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
  151. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
  152. package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
  153. package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
  154. package/src/__tests__/conversation-surfaces-table-action.test.ts +13 -32
  155. package/src/__tests__/conversation-sync-tags.test.ts +140 -12
  156. package/src/__tests__/conversation-title-service.test.ts +136 -2
  157. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +53 -11
  158. package/src/__tests__/conversation-unread-route.test.ts +14 -2
  159. package/src/__tests__/conversation-usage.test.ts +1 -2
  160. package/src/__tests__/conversation-wipe.test.ts +1 -1
  161. package/src/__tests__/conversation-workspace-cache-state.test.ts +21 -17
  162. package/src/__tests__/conversation-workspace-injection.test.ts +119 -23
  163. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +39 -13
  164. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  165. package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
  166. package/src/__tests__/credential-broker-server-use.test.ts +5 -5
  167. package/src/__tests__/credential-execution-client.test.ts +72 -1
  168. package/src/__tests__/credential-execution-feature-gates.test.ts +10 -12
  169. package/src/__tests__/credential-execution-tools.test.ts +1 -2
  170. package/src/__tests__/credential-health-service.test.ts +252 -3
  171. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  172. package/src/__tests__/credential-vault-unit.test.ts +19 -19
  173. package/src/__tests__/credential-vault.test.ts +5 -5
  174. package/src/__tests__/cross-provider-web-search.test.ts +275 -4
  175. package/src/__tests__/cu-unified-flow.test.ts +26 -1
  176. package/src/__tests__/db-acp-history.test.ts +101 -0
  177. package/src/__tests__/db-connection-isolation.test.ts +7 -6
  178. package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
  179. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
  180. package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
  181. package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -0
  182. package/src/__tests__/db-test-helpers.ts +58 -0
  183. package/src/__tests__/disk-pressure-guard.test.ts +119 -36
  184. package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
  185. package/src/__tests__/disk-pressure-routes.test.ts +9 -35
  186. package/src/__tests__/disk-pressure-tools.test.ts +0 -4
  187. package/src/__tests__/dm-persistence.test.ts +38 -43
  188. package/src/__tests__/document-create-dedupe.test.ts +189 -0
  189. package/src/__tests__/document-find-replace.test.ts +3 -2
  190. package/src/__tests__/document-tool-security.test.ts +81 -2
  191. package/src/__tests__/dynamic-page-surface.test.ts +99 -0
  192. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
  193. package/src/__tests__/edit-propagation.test.ts +1 -2
  194. package/src/__tests__/empty-response-hook.test.ts +304 -0
  195. package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
  196. package/src/__tests__/encrypted-store.test.ts +11 -9
  197. package/src/__tests__/feature-flag-test-helpers.ts +53 -0
  198. package/src/__tests__/file-write-tool.test.ts +63 -0
  199. package/src/__tests__/filing-service.test.ts +3 -2
  200. package/src/__tests__/first-greeting.test.ts +103 -12
  201. package/src/__tests__/gateway-flag-listener.test.ts +0 -1
  202. package/src/__tests__/gemini-image-service.test.ts +13 -0
  203. package/src/__tests__/gemini-inline-media.test.ts +78 -0
  204. package/src/__tests__/gemini-provider.test.ts +375 -26
  205. package/src/__tests__/guardian-action-sweep.test.ts +3 -2
  206. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  207. package/src/__tests__/guardian-outbound-http.test.ts +3 -2
  208. package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
  209. package/src/__tests__/guardian-routing-state.test.ts +60 -71
  210. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
  211. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +11 -8
  212. package/src/__tests__/heartbeat-disk-pressure.test.ts +3 -0
  213. package/src/__tests__/heartbeat-service.test.ts +4 -1
  214. package/src/__tests__/helpers/mock-logger.ts +26 -0
  215. package/src/__tests__/helpers/mock-provider.ts +110 -0
  216. package/src/__tests__/helpers/native-web-search-harness.ts +129 -0
  217. package/src/__tests__/history-repair-hook.test.ts +162 -0
  218. package/src/__tests__/history-repair-observability.test.ts +1 -1
  219. package/src/__tests__/history-repair.test.ts +2 -1
  220. package/src/__tests__/host-app-control-proxy.test.ts +2 -0
  221. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  222. package/src/__tests__/host-bash-routes.test.ts +1 -0
  223. package/src/__tests__/host-cu-proxy.test.ts +2 -0
  224. package/src/__tests__/host-cu-routes-targeted.test.ts +4 -3
  225. package/src/__tests__/host-file-edit-tool.test.ts +4 -2
  226. package/src/__tests__/host-file-proxy.test.ts +31 -0
  227. package/src/__tests__/host-file-read-tool.test.ts +4 -2
  228. package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
  229. package/src/__tests__/host-file-write-tool.test.ts +9 -3
  230. package/src/__tests__/host-proxy-preactivation.test.ts +53 -14
  231. package/src/__tests__/host-shell-tool.test.ts +11 -5
  232. package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
  233. package/src/__tests__/http-conversation-lineage.test.ts +3 -2
  234. package/src/__tests__/http-user-message-parity.test.ts +31 -9
  235. package/src/__tests__/identity-intro-cache.test.ts +140 -96
  236. package/src/__tests__/identity-routes.test.ts +248 -7
  237. package/src/__tests__/inbound-slack-persistence.test.ts +56 -75
  238. package/src/__tests__/inference-profile-reaper.test.ts +3 -2
  239. package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
  240. package/src/__tests__/injector-background-turn.test.ts +3 -9
  241. package/src/__tests__/injector-chain.test.ts +139 -275
  242. package/src/__tests__/injector-disk-pressure.test.ts +78 -58
  243. package/src/__tests__/injector-document-comments.test.ts +3 -3
  244. package/src/__tests__/injector-pkb-v2-silenced.test.ts +30 -22
  245. package/src/__tests__/injector-v3-suppression.test.ts +214 -0
  246. package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
  247. package/src/__tests__/internal-telemetry-routes.test.ts +109 -0
  248. package/src/__tests__/list-messages-attachments.test.ts +7 -8
  249. package/src/__tests__/list-messages-hidden-metadata.test.ts +131 -11
  250. package/src/__tests__/list-messages-page-latest.test.ts +60 -1
  251. package/src/__tests__/list-messages-tool-merge.test.ts +56 -6
  252. package/src/__tests__/llm-context-normalization.test.ts +42 -0
  253. package/src/__tests__/llm-request-log-turn-query.test.ts +42 -86
  254. package/src/__tests__/llm-resolver.test.ts +346 -39
  255. package/src/__tests__/llm-schema.test.ts +1 -1
  256. package/src/__tests__/llm-usage-store.test.ts +268 -1
  257. package/src/__tests__/log-export-routes.test.ts +59 -0
  258. package/src/__tests__/managed-skill-lifecycle.test.ts +1 -8
  259. package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
  260. package/src/__tests__/mcp-abort-signal.test.ts +14 -0
  261. package/src/__tests__/mcp-auth-routes.test.ts +15 -10
  262. package/src/__tests__/mcp-client-auth.test.ts +14 -0
  263. package/src/__tests__/mcp-health-check.test.ts +18 -13
  264. package/src/__tests__/memory-retrieval-hook.test.ts +297 -0
  265. package/src/__tests__/memory-v2-static-injector.test.ts +103 -35
  266. package/src/__tests__/messaging-send-tool.test.ts +9 -4
  267. package/src/__tests__/migration-export-http.test.ts +12 -12
  268. package/src/__tests__/migration-import-commit-http.test.ts +8 -8
  269. package/src/__tests__/migration-import-from-url.test.ts +3 -3
  270. package/src/__tests__/migration-import-preflight-http.test.ts +7 -7
  271. package/src/__tests__/migration-validate-http.test.ts +3 -3
  272. package/src/__tests__/mock-gateway-ipc.ts +18 -2
  273. package/src/__tests__/model-intents.test.ts +3 -3
  274. package/src/__tests__/native-web-search.test.ts +235 -22
  275. package/src/__tests__/notification-decision-identity.test.ts +9 -18
  276. package/src/__tests__/notification-decision-recipient-context.test.ts +3 -6
  277. package/src/__tests__/notification-deep-link.test.ts +62 -0
  278. package/src/__tests__/oauth-commands-routes.test.ts +38 -1
  279. package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
  280. package/src/__tests__/oauth-store.test.ts +3 -2
  281. package/src/__tests__/onboarding-template-contract.test.ts +15 -2
  282. package/src/__tests__/openai-image-service.test.ts +17 -0
  283. package/src/__tests__/openai-provider.test.ts +105 -80
  284. package/src/__tests__/openai-responses-provider.test.ts +90 -86
  285. package/src/__tests__/openrouter-provider-only.test.ts +27 -5
  286. package/src/__tests__/outbound-slack-persistence.test.ts +48 -2
  287. package/src/__tests__/{overflow-reduce-pipeline.test.ts → overflow-reduction-loop.test.ts} +64 -286
  288. package/src/__tests__/parallel-tool.benchmark.test.ts +24 -36
  289. package/src/__tests__/persist-unsendable-image.test.ts +215 -0
  290. package/src/__tests__/persistence-secret-redaction.test.ts +86 -13
  291. package/src/__tests__/pipeline-runner.test.ts +31 -43
  292. package/src/__tests__/pkb-autoinject.test.ts +2 -5
  293. package/src/__tests__/plugin-bootstrap.test.ts +72 -63
  294. package/src/__tests__/plugin-registry.test.ts +0 -27
  295. package/src/__tests__/plugin-route-contribution.test.ts +6 -16
  296. package/src/__tests__/plugin-skill-contribution.test.ts +7 -17
  297. package/src/__tests__/plugin-tool-contribution.test.ts +51 -64
  298. package/src/__tests__/plugin-types.test.ts +8 -173
  299. package/src/__tests__/prechat-onboarding-contract.test.ts +23 -0
  300. package/src/__tests__/process-message-background-slack.test.ts +38 -32
  301. package/src/__tests__/process-message-display-content.test.ts +55 -66
  302. package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
  303. package/src/__tests__/provider-commit-message-generator.test.ts +19 -14
  304. package/src/__tests__/provider-error-scenarios.test.ts +7 -6
  305. package/src/__tests__/provider-platform-proxy-integration.test.ts +215 -8
  306. package/src/__tests__/provider-registry-ollama.test.ts +45 -22
  307. package/src/__tests__/provider-send-message-override-profile.test.ts +9 -25
  308. package/src/__tests__/provider-streaming.benchmark.test.ts +12 -22
  309. package/src/__tests__/provider-usage-tracking.test.ts +0 -6
  310. package/src/__tests__/ratelimit.test.ts +9 -4
  311. package/src/__tests__/reaction-persistence.test.ts +1 -1
  312. package/src/__tests__/recording-handler.test.ts +1 -0
  313. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +6 -1
  314. package/src/__tests__/registry.test.ts +82 -76
  315. package/src/__tests__/relay-server.test.ts +30 -23
  316. package/src/__tests__/resolve-trust-class.test.ts +4 -4
  317. package/src/__tests__/retry-openrouter-only-normalization.test.ts +5 -8
  318. package/src/__tests__/retry-thinking-tool-choice.test.ts +10 -13
  319. package/src/__tests__/retry-verbosity-normalization.test.ts +5 -8
  320. package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
  321. package/src/__tests__/runtime-events-sse-reconnect.test.ts +390 -0
  322. package/src/__tests__/schedule-routes.test.ts +683 -12
  323. package/src/__tests__/schedule-store.test.ts +124 -1
  324. package/src/__tests__/schedule-tools.test.ts +160 -0
  325. package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
  326. package/src/__tests__/secret-ingress-http.test.ts +7 -3
  327. package/src/__tests__/secret-prompt-log-hygiene.test.ts +11 -7
  328. package/src/__tests__/secret-prompter-channel-fallback.test.ts +11 -9
  329. package/src/__tests__/secret-response-routing.test.ts +13 -11
  330. package/src/__tests__/secure-keys.test.ts +3 -3
  331. package/src/__tests__/send-endpoint-busy.test.ts +87 -44
  332. package/src/__tests__/server-history-render.test.ts +318 -2
  333. package/src/__tests__/shell-observability.test.ts +249 -0
  334. package/src/__tests__/skill-feature-flags-integration.test.ts +52 -21
  335. package/src/__tests__/skill-feature-flags.test.ts +20 -22
  336. package/src/__tests__/skill-load-feature-flag.test.ts +15 -15
  337. package/src/__tests__/skill-projection-feature-flag.test.ts +44 -30
  338. package/src/__tests__/skill-projection.benchmark.test.ts +5 -7
  339. package/src/__tests__/skill-tool-factory.test.ts +96 -95
  340. package/src/__tests__/skills-files-catalog-fallback.test.ts +10 -0
  341. package/src/__tests__/skillssh-files.test.ts +1 -0
  342. package/src/__tests__/slack-channel-config.test.ts +3 -3
  343. package/src/__tests__/starter-task-flow.test.ts +6 -6
  344. package/src/__tests__/strip-memory-injections.test.ts +102 -14
  345. package/src/__tests__/subagent-call-site-routing.test.ts +14 -6
  346. package/src/__tests__/subagent-disposal.test.ts +27 -8
  347. package/src/__tests__/subagent-fork-notifications.test.ts +25 -12
  348. package/src/__tests__/subagent-fork-spawn.test.ts +14 -5
  349. package/src/__tests__/subagent-manager-notify.test.ts +21 -11
  350. package/src/__tests__/subagent-notify-parent.test.ts +6 -7
  351. package/src/__tests__/subagent-spawn-tool-fork.test.ts +59 -1
  352. package/src/__tests__/subagent-tools.test.ts +2 -1
  353. package/src/__tests__/suggestion-routes.test.ts +4 -3
  354. package/src/__tests__/sync-message-contract.test.ts +19 -16
  355. package/src/__tests__/system-prompt.test.ts +112 -0
  356. package/src/__tests__/task-scheduler.test.ts +162 -1
  357. package/src/__tests__/terminal-tools.test.ts +9 -25
  358. package/src/__tests__/test-preload-verifier.ts +68 -0
  359. package/src/__tests__/test-preload.ts +32 -39
  360. package/src/__tests__/thread-backfill.test.ts +4 -9
  361. package/src/__tests__/title-generate-hook.test.ts +319 -0
  362. package/src/__tests__/tool-error-hook.test.ts +278 -0
  363. package/src/__tests__/tool-executor-lifecycle-events.test.ts +20 -7
  364. package/src/__tests__/tool-executor.test.ts +55 -10
  365. package/src/__tests__/tool-preview-lifecycle.test.ts +481 -15
  366. package/src/__tests__/tool-result-metadata-plumbing.test.ts +2 -0
  367. package/src/__tests__/tool-result-truncate-hook.test.ts +127 -0
  368. package/src/__tests__/tool-result-truncation.test.ts +1 -1
  369. package/src/__tests__/tools-audio-read.test.ts +113 -0
  370. package/src/__tests__/turn-boundary-resolution.test.ts +44 -84
  371. package/src/__tests__/turn-events-store.test.ts +11 -7
  372. package/src/__tests__/twilio-routes.test.ts +3 -2
  373. package/src/__tests__/ui-choice-copy-surfaces.test.ts +254 -0
  374. package/src/__tests__/ui-work-result-surface.test.ts +159 -0
  375. package/src/__tests__/usage-routes.test.ts +285 -1
  376. package/src/__tests__/user-plugin-loader.test.ts +2 -2
  377. package/src/__tests__/validate-input.test.ts +381 -0
  378. package/src/__tests__/verification-control-plane-policy.test.ts +1 -0
  379. package/src/__tests__/voice-scoped-grant-consumer.test.ts +10 -7
  380. package/src/__tests__/voice-session-bridge.test.ts +56 -38
  381. package/src/__tests__/web-search-backend-failure.test.ts +166 -0
  382. package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
  383. package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
  384. package/src/acp/__tests__/agent-process.test.ts +161 -0
  385. package/src/acp/__tests__/client-handler.test.ts +40 -0
  386. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  387. package/src/acp/__tests__/helpers/exec-file-stub.ts +101 -0
  388. package/src/acp/__tests__/prepare-agent-env.test.ts +143 -31
  389. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  390. package/src/acp/__tests__/session-manager-resume.test.ts +695 -0
  391. package/src/acp/agent-process.ts +61 -1
  392. package/src/acp/auto-install.test.ts +125 -0
  393. package/src/acp/auto-install.ts +174 -0
  394. package/src/acp/client-handler.ts +31 -0
  395. package/src/acp/feature-gate.test.ts +48 -0
  396. package/src/acp/feature-gate.ts +34 -0
  397. package/src/acp/prepare-agent-env.ts +52 -11
  398. package/src/acp/resolve-agent.test.ts +147 -6
  399. package/src/acp/resolve-agent.ts +81 -7
  400. package/src/acp/resume-hint.ts +22 -0
  401. package/src/acp/session-manager.ts +492 -77
  402. package/src/agent/compaction-circuit.ts +98 -0
  403. package/src/agent/loop.ts +730 -449
  404. package/src/api/README.md +126 -2
  405. package/src/api/constants/call-sites.ts +27 -0
  406. package/src/api/constants/tool-execution.ts +21 -0
  407. package/src/api/events/assistant-activity-state.ts +75 -0
  408. package/src/api/events/assistant-outbound-attachment.ts +49 -0
  409. package/src/api/events/assistant-text-delta.ts +30 -0
  410. package/src/api/events/assistant-thinking-delta.ts +33 -0
  411. package/src/api/events/assistant-turn-start.ts +31 -0
  412. package/src/api/events/avatar-updated.ts +24 -0
  413. package/src/api/events/compaction-circuit-closed.ts +26 -0
  414. package/src/api/events/compaction-circuit-open.ts +28 -0
  415. package/src/api/events/confirmation-request.ts +114 -0
  416. package/src/api/events/contact-request.ts +33 -0
  417. package/src/api/events/conversation-error.ts +77 -0
  418. package/src/api/events/conversation-list-invalidated.ts +38 -0
  419. package/src/api/events/conversation-title-updated.ts +24 -0
  420. package/src/api/events/disk-pressure-status-changed.ts +61 -0
  421. package/src/api/events/document-comment-created.ts +44 -0
  422. package/src/api/events/document-comment-deleted.ts +22 -0
  423. package/src/api/events/document-comment-reopened.ts +23 -0
  424. package/src/api/events/document-comment-resolved.ts +25 -0
  425. package/src/api/events/document-editor-update.ts +27 -0
  426. package/src/api/events/error.ts +32 -0
  427. package/src/api/events/generation-cancelled.ts +22 -0
  428. package/src/api/events/generation-handoff.ts +39 -0
  429. package/src/api/events/home-feed-updated.ts +26 -0
  430. package/src/api/events/identity-changed.ts +32 -0
  431. package/src/api/events/interaction-resolved.ts +50 -0
  432. package/src/api/events/message-complete.ts +40 -0
  433. package/src/api/events/message-dequeued.ts +21 -0
  434. package/src/api/events/message-queued-deleted.ts +23 -0
  435. package/src/api/events/message-queued.ts +22 -0
  436. package/src/api/events/message-request-complete.ts +29 -0
  437. package/src/api/events/navigate-settings.ts +20 -0
  438. package/src/api/events/notification-intent.ts +33 -0
  439. package/src/api/events/open-url.ts +28 -0
  440. package/src/api/events/question-request.ts +67 -0
  441. package/src/{events → api/events}/relationship-state-updated.ts +6 -8
  442. package/src/api/events/secret-request.ts +42 -0
  443. package/src/api/events/subagent-event.ts +79 -0
  444. package/src/api/events/subagent-spawned.ts +40 -0
  445. package/src/api/events/subagent-status-changed.ts +65 -0
  446. package/src/api/events/sync-changed.ts +29 -0
  447. package/src/api/events/tool-output-chunk.ts +45 -0
  448. package/src/api/events/tool-result.ts +129 -0
  449. package/src/api/events/tool-use-preview-start.ts +32 -0
  450. package/src/api/events/tool-use-start.ts +30 -0
  451. package/src/api/events/trace-event.ts +69 -0
  452. package/src/api/events/turn-profile-auto-routed.ts +28 -0
  453. package/src/api/events/ui-surface-complete.ts +30 -0
  454. package/src/api/events/ui-surface-dismiss.ts +22 -0
  455. package/src/api/events/ui-surface-show.ts +67 -0
  456. package/src/api/events/ui-surface-update.ts +26 -0
  457. package/src/api/events/usage-update.ts +34 -0
  458. package/src/api/events/user-message-echo.ts +35 -0
  459. package/src/api/index.ts +517 -3
  460. package/src/api/requests/dictation.ts +45 -0
  461. package/src/api/responses/conversation-message.ts +374 -0
  462. package/src/api/responses/disk-pressure-status.ts +26 -0
  463. package/src/api/responses/home.ts +217 -0
  464. package/src/api/responses/llm-context-response.ts +41 -0
  465. package/src/api/responses/llm-request-log-entry.ts +93 -0
  466. package/src/api/responses/memory-recall-log.ts +65 -0
  467. package/src/api/responses/memory-v2-activation-log.ts +78 -0
  468. package/src/api/responses/memory-v3-selection-log.ts +50 -0
  469. package/src/api/responses/subagent-detail.ts +48 -0
  470. package/src/approvals/guardian-decision-primitive.ts +7 -15
  471. package/src/approvals/guardian-request-resolvers.ts +7 -10
  472. package/src/avatar/__tests__/avatar-manifest.test.ts +236 -0
  473. package/src/avatar/__tests__/avatar-store.test.ts +198 -0
  474. package/src/avatar/avatar-manifest.ts +195 -0
  475. package/src/avatar/avatar-store.ts +113 -0
  476. package/src/avatar/traits-png-sync.ts +8 -2
  477. package/src/background-wake/background-wake-routes.test.ts +687 -52
  478. package/src/background-wake/next-wake.test.ts +31 -1
  479. package/src/background-wake/next-wake.ts +5 -1
  480. package/src/background-wake/platform-client.test.ts +308 -0
  481. package/src/background-wake/platform-client.ts +167 -0
  482. package/src/background-wake/publisher.ts +91 -0
  483. package/src/background-wake/runtime-registry.ts +2 -2
  484. package/src/background-wake/wake-intent-hooks.test.ts +282 -0
  485. package/src/calls/call-conversation-messages.ts +6 -4
  486. package/src/calls/guardian-action-sweep.ts +6 -4
  487. package/src/calls/guardian-dispatch.ts +1 -0
  488. package/src/calls/relay-server.ts +12 -8
  489. package/src/calls/voice-session-bridge.ts +17 -31
  490. package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
  491. package/src/cli/commands/__tests__/memory-v3.test.ts +245 -0
  492. package/src/cli/commands/__tests__/notifications.test.ts +242 -54
  493. package/src/cli/commands/avatar.ts +17 -11
  494. package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
  495. package/src/cli/commands/channels/index.ts +229 -0
  496. package/src/cli/commands/conversations.ts +15 -1
  497. package/src/cli/commands/db/__tests__/repair.test.ts +540 -0
  498. package/src/cli/commands/db/__tests__/status.test.ts +253 -0
  499. package/src/cli/commands/db/format.ts +48 -0
  500. package/src/cli/commands/db/index.ts +29 -0
  501. package/src/cli/commands/db/repair-step-conversation-backfill.ts +345 -0
  502. package/src/cli/commands/db/repair-step-integrity.ts +146 -0
  503. package/src/cli/commands/db/repair-steps.ts +164 -0
  504. package/src/cli/commands/db/repair.ts +141 -0
  505. package/src/cli/commands/db/status.ts +366 -0
  506. package/src/cli/commands/memory-v3.ts +168 -203
  507. package/src/cli/commands/notifications.ts +427 -65
  508. package/src/cli/lib/cli-colors.ts +24 -6
  509. package/src/cli/lib/open-browser.ts +7 -2
  510. package/src/cli/program.ts +6 -5
  511. package/src/config/__tests__/feature-flag-registry-guard.test.ts +4 -4
  512. package/src/config/acp-defaults.test.ts +10 -0
  513. package/src/config/acp-defaults.ts +6 -0
  514. package/src/config/assistant-feature-flags.ts +47 -55
  515. package/src/config/bundled-skills/acp/SKILL.md +64 -30
  516. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  517. package/src/config/bundled-skills/app-builder/SKILL.md +224 -387
  518. package/src/config/bundled-skills/app-builder/TOOLS.json +29 -0
  519. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  520. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  521. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  522. package/src/config/bundled-skills/app-builder/references/examples/README.md +17 -0
  523. package/src/config/bundled-skills/app-builder/references/examples/expense-tracker.md +515 -0
  524. package/src/config/bundled-skills/app-builder/references/examples/focus-timer.md +342 -0
  525. package/src/config/bundled-skills/app-builder/references/examples/habit-tracker.md +490 -0
  526. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  527. package/src/config/bundled-skills/document-editor/SKILL.md +33 -24
  528. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  529. package/src/config/bundled-skills/media-processing/services/reduce.ts +6 -9
  530. package/src/config/bundled-skills/messaging/SKILL.md +0 -7
  531. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +7 -2
  532. package/src/config/bundled-skills/schedule/SKILL.md +2 -2
  533. package/src/config/bundled-skills/schedule/TOOLS.json +10 -2
  534. package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
  535. package/src/config/bundled-tool-registry.ts +2 -0
  536. package/src/config/call-site-defaults.ts +3 -8
  537. package/src/config/feature-flag-cache.ts +86 -0
  538. package/src/config/feature-flag-registry.json +81 -25
  539. package/src/config/llm-context-resolution.ts +10 -1
  540. package/src/config/llm-resolver.ts +121 -15
  541. package/src/config/loader.ts +4 -5
  542. package/src/config/schemas/__tests__/memory-v2.test.ts +2 -211
  543. package/src/config/schemas/__tests__/memory-v3.test.ts +25 -0
  544. package/src/config/schemas/call-site-catalog.ts +8 -15
  545. package/src/config/schemas/heartbeat.ts +10 -1
  546. package/src/config/schemas/llm.ts +93 -4
  547. package/src/config/schemas/memory-lifecycle.ts +24 -0
  548. package/src/config/schemas/memory-v2.ts +8 -227
  549. package/src/config/schemas/memory-v3.ts +47 -0
  550. package/src/config/schemas/memory.ts +6 -1
  551. package/src/config/schemas/platform.ts +8 -0
  552. package/src/config/schemas/services.ts +6 -2
  553. package/src/config/schemas/timeouts.ts +3 -1
  554. package/src/config/seed-inference-profiles.ts +38 -18
  555. package/src/config/skills.ts +13 -0
  556. package/src/context/compactor.ts +55 -32
  557. package/src/context/strip-injections.ts +128 -0
  558. package/src/context/token-estimator.ts +52 -5
  559. package/src/context/tool-result-truncation.ts +1 -66
  560. package/src/context/window-manager.ts +141 -26
  561. package/src/credential-execution/executable-discovery.ts +56 -0
  562. package/src/credential-execution/process-manager.ts +6 -2
  563. package/src/credential-health/credential-health-service.ts +125 -40
  564. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +9 -6
  565. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +15 -17
  566. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -2
  567. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
  568. package/src/daemon/__tests__/inference-profile-notification.test.ts +153 -0
  569. package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
  570. package/src/daemon/__tests__/native-web-search-metadata.test.ts +11 -8
  571. package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
  572. package/src/daemon/__tests__/web-search-status-text.test.ts +11 -6
  573. package/src/daemon/approval-generators.ts +4 -4
  574. package/src/daemon/assistant-attachments.ts +1 -1
  575. package/src/daemon/config-watcher.ts +7 -1
  576. package/src/daemon/context-overflow-reducer.ts +0 -1
  577. package/src/daemon/conversation-agent-loop-handlers.ts +1146 -247
  578. package/src/daemon/conversation-agent-loop.ts +570 -1457
  579. package/src/daemon/conversation-error.ts +40 -12
  580. package/src/daemon/conversation-history.ts +27 -10
  581. package/src/daemon/conversation-launch.ts +4 -8
  582. package/src/daemon/conversation-lifecycle.ts +13 -42
  583. package/src/daemon/conversation-messaging.ts +89 -49
  584. package/src/daemon/conversation-notifiers.ts +7 -5
  585. package/src/daemon/conversation-process.ts +183 -130
  586. package/src/daemon/conversation-registry.ts +159 -0
  587. package/src/daemon/conversation-runtime-assembly.ts +209 -362
  588. package/src/daemon/conversation-skill-tools.ts +14 -30
  589. package/src/daemon/conversation-slash.ts +6 -25
  590. package/src/daemon/conversation-store.ts +15 -95
  591. package/src/daemon/conversation-surfaces.ts +346 -107
  592. package/src/daemon/conversation-tool-setup.ts +38 -77
  593. package/src/daemon/conversation-workspace.ts +17 -0
  594. package/src/daemon/conversation.ts +143 -186
  595. package/src/daemon/daemon-control.ts +1 -1
  596. package/src/daemon/daemon-skill-host.ts +7 -4
  597. package/src/daemon/disk-pressure-guard.ts +54 -50
  598. package/src/daemon/external-plugins-bootstrap.ts +53 -32
  599. package/src/daemon/first-greeting.ts +53 -13
  600. package/src/daemon/guardian-action-generators.ts +2 -2
  601. package/src/daemon/handlers/config-a2a.ts +51 -36
  602. package/src/daemon/handlers/config-slack-channel.ts +20 -14
  603. package/src/daemon/handlers/config-telegram.ts +16 -2
  604. package/src/daemon/handlers/conversations.ts +9 -23
  605. package/src/daemon/handlers/shared.ts +158 -77
  606. package/src/daemon/handlers/skills.ts +53 -20
  607. package/src/daemon/host-app-control-proxy.ts +54 -1
  608. package/src/daemon/host-cu-proxy.ts +46 -22
  609. package/src/daemon/host-file-proxy.ts +25 -1
  610. package/src/daemon/host-proxy-preactivation.ts +25 -6
  611. package/src/daemon/lifecycle.ts +65 -67
  612. package/src/daemon/mcp-reload-service.ts +1 -1
  613. package/src/daemon/meet-manifest-loader.ts +10 -17
  614. package/src/daemon/message-protocol.ts +2 -3
  615. package/src/daemon/message-provenance.ts +49 -0
  616. package/src/daemon/message-types/apps.ts +1 -29
  617. package/src/daemon/message-types/contacts.ts +3 -20
  618. package/src/daemon/message-types/conversations.ts +25 -125
  619. package/src/daemon/message-types/document-comments.ts +8 -44
  620. package/src/daemon/message-types/documents.ts +3 -9
  621. package/src/daemon/message-types/home.ts +5 -18
  622. package/src/daemon/message-types/integrations.ts +4 -13
  623. package/src/daemon/message-types/messages.ts +50 -428
  624. package/src/daemon/message-types/notifications.ts +2 -32
  625. package/src/daemon/message-types/settings.ts +3 -8
  626. package/src/daemon/message-types/skills.ts +4 -0
  627. package/src/daemon/message-types/subagents.ts +6 -0
  628. package/src/daemon/message-types/surfaces.ts +138 -3
  629. package/src/daemon/message-types/sync.ts +12 -25
  630. package/src/daemon/message-types/workspace.ts +3 -11
  631. package/src/daemon/now-scratchpad.ts +21 -0
  632. package/src/daemon/orphan-reaper.test.ts +210 -0
  633. package/src/daemon/orphan-reaper.ts +240 -0
  634. package/src/daemon/overflow-reduction-loop.ts +230 -0
  635. package/src/daemon/persist-unsendable-image.ts +117 -0
  636. package/src/daemon/process-message.ts +59 -58
  637. package/src/daemon/providers-setup.ts +1 -1
  638. package/src/daemon/server.ts +30 -0
  639. package/src/daemon/switch-inference-profile-tool.ts +13 -3
  640. package/src/daemon/tool-setup-types.ts +0 -6
  641. package/src/daemon/tool-side-effects.ts +10 -7
  642. package/src/daemon/trace-emitter.ts +6 -4
  643. package/src/daemon/trust-context.ts +32 -0
  644. package/src/daemon/wake-target-adapter.ts +24 -2
  645. package/src/documents/document-store.ts +38 -0
  646. package/src/export/__tests__/transcript-formatter.test.ts +1 -0
  647. package/src/heartbeat/__tests__/heartbeat-service.test.ts +34 -0
  648. package/src/heartbeat/heartbeat-run-store.ts +54 -1
  649. package/src/heartbeat/heartbeat-service.ts +105 -0
  650. package/src/home/__tests__/feed-writer.test.ts +161 -0
  651. package/src/home/__tests__/post-connect-feed.test.ts +1 -0
  652. package/src/home/__tests__/suggested-prompts.test.ts +55 -59
  653. package/src/home/feed-types.ts +36 -221
  654. package/src/home/feed-writer.ts +146 -7
  655. package/src/home/home-greeting-cache.ts +24 -1
  656. package/src/home/suggested-prompts.ts +27 -145
  657. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  658. package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
  659. package/src/ipc/__tests__/email-ipc.test.ts +0 -9
  660. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  661. package/src/ipc/gateway-client.test.ts +6 -3
  662. package/src/ipc/gateway-client.ts +3 -3
  663. package/src/ipc/routes/__tests__/route-adapter.test.ts +244 -0
  664. package/src/ipc/routes/route-adapter.ts +45 -6
  665. package/src/ipc/skill-routes/__tests__/memory.test.ts +34 -9
  666. package/src/ipc/skill-routes/__tests__/providers.test.ts +10 -10
  667. package/src/ipc/skill-routes/__tests__/registries.test.ts +59 -20
  668. package/src/ipc/skill-routes/memory.ts +29 -13
  669. package/src/ipc/skill-routes/providers.ts +5 -6
  670. package/src/ipc/skill-routes/registries.ts +39 -88
  671. package/src/live-voice/__tests__/live-voice-archive.test.ts +24 -11
  672. package/src/media/gemini-image-service.ts +15 -0
  673. package/src/media/openai-image-service.ts +14 -0
  674. package/src/media/types.ts +34 -0
  675. package/src/memory/__tests__/conversation-queries.test.ts +192 -8
  676. package/src/memory/__tests__/db-maintenance.test.ts +128 -0
  677. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +1 -0
  678. package/src/memory/__tests__/jobs-store-job-classes.test.ts +5 -4
  679. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +82 -5
  680. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
  681. package/src/memory/__tests__/memory-retrospective-job.test.ts +11 -6
  682. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
  683. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
  684. package/src/memory/__tests__/memory-v3-selections-migration.test.ts +103 -0
  685. package/src/memory/auth-fallback-events-store.ts +94 -0
  686. package/src/memory/context-search/agent-runner.ts +2 -4
  687. package/src/memory/conversation-attention-store.ts +17 -3
  688. package/src/memory/conversation-crud.ts +386 -115
  689. package/src/memory/conversation-queries.ts +78 -22
  690. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  691. package/src/memory/conversation-title-service.ts +65 -41
  692. package/src/memory/db-connection.ts +29 -19
  693. package/src/memory/db-init.ts +18 -0
  694. package/src/memory/db-maintenance.ts +18 -2
  695. package/src/memory/db-singleton.ts +77 -0
  696. package/src/memory/delivery-channels.ts +82 -0
  697. package/src/memory/graph/__tests__/conversation-graph-memory-registry.test.ts +119 -0
  698. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
  699. package/src/memory/graph/consolidation.ts +8 -11
  700. package/src/memory/graph/conversation-graph-memory.ts +106 -8
  701. package/src/memory/graph/extraction.ts +6 -9
  702. package/src/memory/graph/narrative.ts +2 -2
  703. package/src/memory/graph/pattern-scan.ts +2 -2
  704. package/src/memory/graph/retriever.test.ts +3 -3
  705. package/src/memory/graph/retriever.ts +20 -26
  706. package/src/memory/graph/tools.ts +4 -4
  707. package/src/memory/job-handlers/conversation-starters.ts +45 -34
  708. package/src/memory/job-handlers/embedding.test.ts +3 -2
  709. package/src/memory/job-handlers/summarization.ts +1 -2
  710. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
  711. package/src/memory/jobs-store.ts +36 -1
  712. package/src/memory/jobs-worker.ts +93 -43
  713. package/src/memory/llm-request-log-source-clickhouse.ts +55 -1
  714. package/src/memory/llm-request-log-source-local.ts +13 -0
  715. package/src/memory/llm-request-log-source.ts +21 -6
  716. package/src/memory/llm-request-log-store.ts +147 -3
  717. package/src/memory/llm-usage-store.ts +234 -50
  718. package/src/memory/memory-marker.ts +17 -0
  719. package/src/memory/memory-retrospective-job.ts +6 -2
  720. package/src/memory/memory-v2-activation-log-store.ts +13 -1
  721. package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +6 -5
  722. package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
  723. package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
  724. package/src/memory/migrations/267-llm-usage-events-add-assistant-version.ts +46 -0
  725. package/src/memory/migrations/268-add-memory-v3-selections.ts +28 -0
  726. package/src/memory/migrations/269-schedule-script-timeout.ts +11 -0
  727. package/src/memory/migrations/270-messages-role-created-at-index.ts +18 -0
  728. package/src/memory/migrations/270-schedule-source-conversation.ts +13 -0
  729. package/src/memory/migrations/271-create-auth-fallback-events.ts +21 -0
  730. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  731. package/src/memory/migrations/__tests__/267-llm-usage-events-add-assistant-version.test.ts +117 -0
  732. package/src/memory/migrations/index.ts +9 -0
  733. package/src/memory/pkb/autoinject.ts +61 -0
  734. package/src/memory/pkb/context.ts +50 -0
  735. package/src/memory/pkb/types.ts +14 -0
  736. package/src/memory/schedule-attribution-sql.ts +104 -0
  737. package/src/memory/schema/acp.ts +4 -0
  738. package/src/memory/schema/conversations.ts +9 -1
  739. package/src/memory/schema/inference.ts +0 -1
  740. package/src/memory/schema/infrastructure.ts +27 -0
  741. package/src/memory/usage-grouped-buckets.ts +6 -1
  742. package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
  743. package/src/memory/v2/__tests__/consolidation-job.test.ts +125 -1
  744. package/src/memory/v2/__tests__/harness-metrics.test.ts +9 -0
  745. package/src/memory/v2/__tests__/harness-replay-input.test.ts +9 -4
  746. package/src/memory/v2/__tests__/harness-runner.test.ts +26 -0
  747. package/src/memory/v2/__tests__/migration.test.ts +11 -3
  748. package/src/memory/v2/__tests__/page-index.test.ts +37 -1
  749. package/src/memory/v2/__tests__/router.test.ts +14 -4
  750. package/src/memory/v2/__tests__/sweep-job.test.ts +9 -5
  751. package/src/memory/v2/backfill-jobs.ts +6 -0
  752. package/src/memory/v2/consolidation-job.ts +99 -10
  753. package/src/memory/v2/harness/metrics.ts +5 -1
  754. package/src/memory/v2/harness/replay-input.ts +19 -3
  755. package/src/memory/v2/harness/runner.ts +6 -0
  756. package/src/memory/v2/harness/trace.ts +6 -0
  757. package/src/memory/v2/migration.ts +5 -3
  758. package/src/memory/v2/page-index.ts +11 -0
  759. package/src/memory/v2/router.ts +8 -11
  760. package/src/memory/v2/sweep-job.ts +8 -11
  761. package/src/memory/v2/types.ts +1 -0
  762. package/src/messaging/providers/slack/render-transcript.test.ts +1 -1
  763. package/src/messaging/providers/slack/render-transcript.ts +2 -2
  764. package/src/messaging/style-analyzer.ts +8 -11
  765. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
  766. package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
  767. package/src/notifications/adapters/slack.ts +45 -11
  768. package/src/notifications/broadcaster.ts +114 -63
  769. package/src/notifications/conversation-pairing.ts +23 -8
  770. package/src/notifications/decision-engine.ts +16 -16
  771. package/src/notifications/decisions-store.ts +32 -1
  772. package/src/notifications/deliveries-store.ts +45 -0
  773. package/src/notifications/edit-notification.ts +201 -0
  774. package/src/notifications/emit-signal.ts +11 -1
  775. package/src/notifications/home-feed-side-effect.ts +12 -1
  776. package/src/notifications/preference-extractor.ts +11 -14
  777. package/src/notifications/signal.ts +10 -0
  778. package/src/notifications/types.ts +37 -0
  779. package/src/oauth/byo-connection.test.ts +67 -3
  780. package/src/oauth/byo-connection.ts +32 -5
  781. package/src/oauth/connect-orchestrator.ts +9 -0
  782. package/src/oauth/connection-resolver.test.ts +76 -0
  783. package/src/oauth/connection-resolver.ts +49 -10
  784. package/src/oauth/manual-token-connection.ts +51 -3
  785. package/src/oauth/seed-providers.ts +3 -0
  786. package/src/permissions/approval-policy.test.ts +19 -5
  787. package/src/permissions/approval-policy.ts +14 -3
  788. package/src/permissions/checker.ts +21 -8
  789. package/src/permissions/prompter.ts +46 -36
  790. package/src/permissions/question-prompter.test.ts +35 -26
  791. package/src/permissions/question-prompter.ts +6 -10
  792. package/src/platform/client.test.ts +24 -1
  793. package/src/platform/client.ts +8 -0
  794. package/src/platform/feature-gate.ts +15 -0
  795. package/src/plugin-api/constants.ts +4 -0
  796. package/src/plugin-api/index.ts +10 -1
  797. package/src/plugin-api/types.ts +176 -4
  798. package/src/plugins/defaults/compaction/compact.ts +59 -0
  799. package/src/plugins/defaults/compaction/package.json +15 -0
  800. package/src/plugins/defaults/compaction/register.ts +24 -0
  801. package/src/plugins/defaults/empty-response/hooks/stop.ts +126 -0
  802. package/src/plugins/defaults/empty-response/package.json +15 -0
  803. package/src/plugins/defaults/empty-response/register.ts +23 -0
  804. package/src/plugins/defaults/history-repair/hooks/user-prompt-submit.ts +35 -0
  805. package/src/plugins/defaults/history-repair/package.json +15 -0
  806. package/src/plugins/defaults/history-repair/register.ts +24 -0
  807. package/src/{daemon/history-repair.ts → plugins/defaults/history-repair/terminal.ts} +48 -35
  808. package/src/plugins/defaults/index.ts +22 -49
  809. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +95 -0
  810. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +216 -0
  811. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +35 -0
  812. package/src/plugins/defaults/{injectors.ts → memory-retrieval/injectors.ts} +297 -120
  813. package/src/plugins/defaults/memory-v3-shadow/__tests__/assign.test.ts +242 -0
  814. package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +118 -0
  815. package/src/plugins/defaults/memory-v3-shadow/__tests__/core.test.ts +39 -0
  816. package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/eval-turns.json +36 -0
  817. package/src/plugins/defaults/memory-v3-shadow/__tests__/fixtures/live-turns.json +37 -0
  818. package/src/plugins/defaults/memory-v3-shadow/__tests__/health.test.ts +219 -0
  819. package/src/plugins/defaults/memory-v3-shadow/__tests__/live-integration.test.ts +330 -0
  820. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +288 -0
  821. package/src/plugins/defaults/memory-v3-shadow/__tests__/needle.test.ts +107 -0
  822. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +436 -0
  823. package/src/plugins/defaults/memory-v3-shadow/__tests__/provider-blocks.test.ts +13 -0
  824. package/src/plugins/defaults/memory-v3-shadow/__tests__/reconcile.test.ts +274 -0
  825. package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +61 -0
  826. package/src/plugins/defaults/memory-v3-shadow/__tests__/router.test.ts +332 -0
  827. package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +179 -0
  828. package/src/plugins/defaults/memory-v3-shadow/__tests__/selector.test.ts +470 -0
  829. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +432 -0
  830. package/src/plugins/defaults/memory-v3-shadow/__tests__/snapshot.test.ts +168 -0
  831. package/src/plugins/defaults/memory-v3-shadow/__tests__/tree.test.ts +192 -0
  832. package/src/plugins/defaults/memory-v3-shadow/__tests__/types.test.ts +54 -0
  833. package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-eviction.test.ts +106 -0
  834. package/src/plugins/defaults/memory-v3-shadow/__tests__/working-set-skeleton.test.ts +44 -0
  835. package/src/plugins/defaults/memory-v3-shadow/assign.ts +268 -0
  836. package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +124 -0
  837. package/src/plugins/defaults/memory-v3-shadow/core.ts +26 -0
  838. package/src/plugins/defaults/memory-v3-shadow/data/README.md +84 -0
  839. package/src/plugins/defaults/memory-v3-shadow/data/assignments.json +5 -0
  840. package/src/plugins/defaults/memory-v3-shadow/data/core.json +1 -0
  841. package/src/plugins/defaults/memory-v3-shadow/data/leaves/domain-a/topic-x.md +9 -0
  842. package/src/plugins/defaults/memory-v3-shadow/data/leaves/domain-a/topic-y.md +9 -0
  843. package/src/plugins/defaults/memory-v3-shadow/data/leaves/domain-b/topic-z.md +9 -0
  844. package/src/plugins/defaults/memory-v3-shadow/health.ts +0 -0
  845. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  846. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  847. package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
  848. package/src/plugins/defaults/memory-v3-shadow/llm-retry.ts +32 -0
  849. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +314 -0
  850. package/src/plugins/defaults/memory-v3-shadow/needle.ts +115 -0
  851. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +126 -0
  852. package/src/plugins/defaults/memory-v3-shadow/package.json +15 -0
  853. package/src/plugins/defaults/memory-v3-shadow/page-content.ts +34 -0
  854. package/src/plugins/defaults/memory-v3-shadow/provider-blocks.ts +26 -0
  855. package/src/plugins/defaults/memory-v3-shadow/reconcile.ts +523 -0
  856. package/src/plugins/defaults/memory-v3-shadow/register.ts +26 -0
  857. package/src/plugins/defaults/memory-v3-shadow/render-injection.ts +32 -0
  858. package/src/plugins/defaults/memory-v3-shadow/router.ts +190 -0
  859. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +84 -0
  860. package/src/plugins/defaults/memory-v3-shadow/selector.ts +226 -0
  861. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +349 -0
  862. package/src/plugins/defaults/memory-v3-shadow/snapshot.ts +209 -0
  863. package/src/plugins/defaults/memory-v3-shadow/tree.ts +174 -0
  864. package/src/plugins/defaults/memory-v3-shadow/types.ts +59 -0
  865. package/src/plugins/defaults/memory-v3-shadow/working-set.ts +88 -0
  866. package/src/plugins/defaults/title-generate/hooks/stop.ts +75 -0
  867. package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +35 -0
  868. package/src/plugins/defaults/title-generate/package.json +15 -0
  869. package/src/plugins/defaults/title-generate/register.ts +35 -0
  870. package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +118 -0
  871. package/src/plugins/defaults/tool-error/package.json +15 -0
  872. package/src/plugins/defaults/tool-error/register.ts +23 -0
  873. package/src/plugins/defaults/tool-result-truncate/hooks/post-tool-use.ts +32 -0
  874. package/src/plugins/defaults/tool-result-truncate/package.json +15 -0
  875. package/src/plugins/defaults/tool-result-truncate/register.ts +24 -0
  876. package/src/plugins/defaults/tool-result-truncate/terminal.ts +132 -0
  877. package/src/plugins/external-plugin-loader.ts +2 -2
  878. package/src/plugins/pipeline.ts +8 -35
  879. package/src/plugins/registry.ts +8 -25
  880. package/src/plugins/types.ts +62 -677
  881. package/src/plugins/user-loader.ts +4 -3
  882. package/src/proactive-artifact/aux-message-injector.ts +4 -5
  883. package/src/proactive-artifact/job.test.ts +29 -21
  884. package/src/proactive-artifact/job.ts +3 -1
  885. package/src/prompts/__tests__/system-prompt.test.ts +46 -4
  886. package/src/prompts/sections.ts +20 -7
  887. package/src/prompts/system-prompt.ts +38 -40
  888. package/src/prompts/template-detection.ts +10 -4
  889. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +64 -0
  890. package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +2 -2
  891. package/src/prompts/templates/BOOTSTRAP.md +12 -12
  892. package/src/prompts/templates/IDENTITY.md +0 -2
  893. package/src/prompts/templates/system-sections.ts +21 -0
  894. package/src/providers/__tests__/connection-model-compat.test.ts +3 -4
  895. package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
  896. package/src/providers/__tests__/retry-callsite.test.ts +25 -25
  897. package/src/providers/__tests__/satellite-connection-routing.test.ts +7 -21
  898. package/src/providers/anthropic/client.ts +61 -34
  899. package/src/providers/call-site-routing.ts +34 -18
  900. package/src/providers/connection-model-compat.ts +23 -0
  901. package/src/providers/connection-resolution.ts +39 -20
  902. package/src/providers/fireworks/client.ts +1 -0
  903. package/src/providers/gemini/client.ts +176 -37
  904. package/src/providers/gemini/inline-media.ts +74 -0
  905. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
  906. package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
  907. package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
  908. package/src/providers/inference/auth.ts +0 -8
  909. package/src/providers/inference/connections.ts +3 -66
  910. package/src/providers/inference/resolve-auth.ts +2 -3
  911. package/src/providers/model-catalog.ts +35 -1
  912. package/src/providers/model-intents.ts +3 -3
  913. package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
  914. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +269 -7
  915. package/src/providers/openai/chat-completions-provider.ts +155 -16
  916. package/src/providers/openai/codex-models.ts +2 -0
  917. package/src/providers/openai/responses-provider.ts +54 -57
  918. package/src/providers/openrouter/client.ts +15 -14
  919. package/src/providers/placeholder-sentinels.ts +35 -0
  920. package/src/providers/provider-send-message.ts +23 -14
  921. package/src/providers/ratelimit.ts +1 -9
  922. package/src/providers/registry.ts +48 -8
  923. package/src/providers/retry.ts +16 -9
  924. package/src/providers/search-provider-catalog.ts +17 -9
  925. package/src/providers/types.ts +20 -2
  926. package/src/providers/usage-tracking.ts +1 -9
  927. package/src/runtime/__tests__/agent-wake.test.ts +142 -32
  928. package/src/runtime/__tests__/background-job-runner.test.ts +2 -3
  929. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  930. package/src/runtime/access-request-helper.ts +1 -0
  931. package/src/runtime/agent-wake.ts +95 -23
  932. package/src/runtime/assistant-event-hub.ts +38 -8
  933. package/src/runtime/assistant-stream-state.ts +368 -0
  934. package/src/runtime/auth/__tests__/guard-tests.test.ts +75 -109
  935. package/src/runtime/auth/__tests__/route-policy.test.ts +153 -170
  936. package/src/runtime/auth/route-policy.ts +42 -1069
  937. package/src/runtime/background-job-runner.ts +1 -4
  938. package/src/runtime/btw-sidechain.ts +3 -1
  939. package/src/runtime/channel-approvals.ts +4 -15
  940. package/src/runtime/channel-invite-transport.ts +5 -6
  941. package/src/runtime/channel-readiness-service.ts +70 -5
  942. package/src/runtime/channel-reply-delivery.ts +23 -0
  943. package/src/runtime/channel-retry-sweep.ts +59 -30
  944. package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
  945. package/src/runtime/http-router.ts +35 -43
  946. package/src/runtime/http-types.ts +23 -71
  947. package/src/runtime/interactive-ui.ts +1 -1
  948. package/src/runtime/invite-instruction-generator.ts +3 -3
  949. package/src/runtime/migrations/vbundle-builder.ts +3 -2
  950. package/src/runtime/pending-interactions.ts +3 -2
  951. package/src/runtime/routes/__tests__/acp-routes.test.ts +253 -55
  952. package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +565 -0
  953. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
  954. package/src/runtime/routes/__tests__/consolidation-routes.test.ts +265 -2
  955. package/src/runtime/routes/__tests__/content-source-routes.test.ts +4 -4
  956. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +436 -0
  957. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +237 -0
  958. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +129 -1
  959. package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
  960. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
  961. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +26 -72
  962. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +6 -2
  963. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +58 -5
  964. package/src/runtime/routes/__tests__/sanity-routes.test.ts +6 -6
  965. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
  966. package/src/runtime/routes/__tests__/stt-routes.test.ts +3 -3
  967. package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +5 -2
  968. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  969. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +297 -0
  970. package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
  971. package/src/runtime/routes/__tests__/tts-routes.test.ts +9 -5
  972. package/src/runtime/routes/acp-routes-list.test.ts +3 -0
  973. package/src/runtime/routes/acp-routes.test.ts +186 -100
  974. package/src/runtime/routes/acp-routes.ts +110 -35
  975. package/src/runtime/routes/app-management-routes.ts +175 -106
  976. package/src/runtime/routes/app-routes.ts +38 -20
  977. package/src/runtime/routes/approval-routes.ts +17 -5
  978. package/src/runtime/routes/attachment-routes.ts +51 -16
  979. package/src/runtime/routes/audio-routes.ts +1 -0
  980. package/src/runtime/routes/audit-routes.ts +5 -0
  981. package/src/runtime/routes/auth-routes.ts +5 -0
  982. package/src/runtime/routes/avatar-routes.ts +264 -59
  983. package/src/runtime/routes/background-tool-routes.ts +9 -0
  984. package/src/runtime/routes/background-wake-routes.ts +201 -23
  985. package/src/runtime/routes/backup-routes.ts +45 -0
  986. package/src/runtime/routes/bookmark-routes.ts +13 -0
  987. package/src/runtime/routes/brain-graph-routes.ts +9 -0
  988. package/src/runtime/routes/browser-routes.ts +6 -1
  989. package/src/runtime/routes/browser-tabs-routes.ts +11 -10
  990. package/src/runtime/routes/btw-routes.ts +37 -27
  991. package/src/runtime/routes/cache-routes.ts +13 -0
  992. package/src/runtime/routes/call-routes.ts +21 -10
  993. package/src/runtime/routes/channel-availability-routes.ts +5 -1
  994. package/src/runtime/routes/channel-readiness-routes.ts +37 -4
  995. package/src/runtime/routes/channel-route-definitions.ts +21 -0
  996. package/src/runtime/routes/channel-verification-routes.ts +21 -0
  997. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +9 -2
  998. package/src/runtime/routes/client-routes.ts +9 -0
  999. package/src/runtime/routes/consolidation-routes.ts +133 -25
  1000. package/src/runtime/routes/contact-prompt-routes.ts +9 -0
  1001. package/src/runtime/routes/contact-routes.ts +90 -23
  1002. package/src/runtime/routes/content-source-routes.ts +5 -1
  1003. package/src/runtime/routes/conversation-analysis-routes.ts +11 -1
  1004. package/src/runtime/routes/conversation-attention-routes.ts +5 -0
  1005. package/src/runtime/routes/conversation-cli-routes.ts +54 -7
  1006. package/src/runtime/routes/conversation-compaction-routes.ts +292 -0
  1007. package/src/runtime/routes/conversation-list-routes.ts +225 -9
  1008. package/src/runtime/routes/conversation-management-routes.ts +96 -28
  1009. package/src/runtime/routes/conversation-query-routes.ts +150 -51
  1010. package/src/runtime/routes/conversation-routes.ts +615 -327
  1011. package/src/runtime/routes/conversation-starter-routes.ts +35 -20
  1012. package/src/runtime/routes/conversations-import-routes.ts +48 -13
  1013. package/src/runtime/routes/credential-prompt-routes.ts +5 -0
  1014. package/src/runtime/routes/credential-routes.ts +25 -6
  1015. package/src/runtime/routes/debug-bash-routes.ts +5 -0
  1016. package/src/runtime/routes/debug-routes.ts +11 -2
  1017. package/src/runtime/routes/defer-routes.ts +13 -0
  1018. package/src/runtime/routes/diagnostics-routes.ts +37 -46
  1019. package/src/runtime/routes/disk-pressure-routes.ts +17 -31
  1020. package/src/runtime/routes/document-comments-routes.ts +46 -27
  1021. package/src/runtime/routes/documents-routes.ts +35 -11
  1022. package/src/runtime/routes/domain-routes.ts +98 -51
  1023. package/src/runtime/routes/email-routes.ts +33 -0
  1024. package/src/runtime/routes/epoch-millis-range.ts +34 -0
  1025. package/src/runtime/routes/events-routes.ts +107 -8
  1026. package/src/runtime/routes/filing-routes.ts +9 -4
  1027. package/src/runtime/routes/gateway-log-routes.ts +31 -4
  1028. package/src/runtime/routes/global-search-routes.ts +53 -50
  1029. package/src/runtime/routes/group-routes.ts +32 -5
  1030. package/src/runtime/routes/guardian-action-routes.ts +9 -0
  1031. package/src/runtime/routes/guardian-approval-interception.ts +0 -31
  1032. package/src/runtime/routes/heartbeat-routes.ts +57 -21
  1033. package/src/runtime/routes/home-feed-routes.ts +149 -16
  1034. package/src/runtime/routes/home-state-routes.ts +8 -40
  1035. package/src/runtime/routes/host-app-control-routes.ts +6 -1
  1036. package/src/runtime/routes/host-bash-routes.ts +5 -0
  1037. package/src/runtime/routes/host-browser-routes.ts +13 -0
  1038. package/src/runtime/routes/host-cu-routes.ts +6 -1
  1039. package/src/runtime/routes/host-file-routes.ts +26 -6
  1040. package/src/runtime/routes/host-transfer-routes.ts +13 -2
  1041. package/src/runtime/routes/http-adapter.ts +1 -2
  1042. package/src/runtime/routes/identity-intro-cache.ts +72 -39
  1043. package/src/runtime/routes/identity-routes.ts +257 -20
  1044. package/src/runtime/routes/image-generation-routes.ts +45 -2
  1045. package/src/runtime/routes/inbound-message-handler.ts +16 -12
  1046. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +524 -12
  1047. package/src/runtime/routes/inbound-stages/background-dispatch.ts +72 -27
  1048. package/src/runtime/routes/index.ts +4 -0
  1049. package/src/runtime/routes/inference-profile-session-routes.ts +13 -3
  1050. package/src/runtime/routes/inference-provider-connection-routes.ts +26 -31
  1051. package/src/runtime/routes/inference-send-routes.ts +11 -11
  1052. package/src/runtime/routes/integrations/a2a.ts +32 -7
  1053. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +16 -0
  1054. package/src/runtime/routes/integrations/slack/channel.ts +23 -3
  1055. package/src/runtime/routes/integrations/slack/share.ts +36 -8
  1056. package/src/runtime/routes/integrations/telegram.ts +34 -9
  1057. package/src/runtime/routes/integrations/twilio.ts +77 -7
  1058. package/src/runtime/routes/integrations/vercel.ts +18 -3
  1059. package/src/runtime/routes/internal-oauth-routes.ts +5 -0
  1060. package/src/runtime/routes/internal-telemetry-routes.ts +88 -0
  1061. package/src/runtime/routes/internal-twilio-routes.ts +13 -0
  1062. package/src/runtime/routes/llm-call-sites-routes.ts +39 -4
  1063. package/src/runtime/routes/llm-context-normalization.ts +7 -2
  1064. package/src/runtime/routes/log-export-routes.ts +36 -10
  1065. package/src/runtime/routes/mcp-auth-routes.ts +25 -0
  1066. package/src/runtime/routes/memory-item-routes.ts +21 -10
  1067. package/src/runtime/routes/memory-v2-routes.ts +105 -44
  1068. package/src/runtime/routes/memory-v3-routes.ts +313 -257
  1069. package/src/runtime/routes/migration-rollback-routes.ts +5 -1
  1070. package/src/runtime/routes/migration-routes.ts +49 -13
  1071. package/src/runtime/routes/notification-routes.ts +80 -2
  1072. package/src/runtime/routes/oauth-apps.ts +99 -23
  1073. package/src/runtime/routes/oauth-commands-routes.ts +43 -15
  1074. package/src/runtime/routes/oauth-connect-routes.ts +9 -0
  1075. package/src/runtime/routes/oauth-lifecycle-routes.ts +5 -1
  1076. package/src/runtime/routes/oauth-providers.ts +79 -15
  1077. package/src/runtime/routes/platform-routes.ts +102 -5
  1078. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +9 -6
  1079. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +37 -16
  1080. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +7 -3
  1081. package/src/runtime/routes/playground/__tests__/state.test.ts +10 -3
  1082. package/src/runtime/routes/playground/force-compact.ts +2 -2
  1083. package/src/runtime/routes/playground/helpers.ts +1 -2
  1084. package/src/runtime/routes/playground/inject-failures.ts +13 -8
  1085. package/src/runtime/routes/playground/reset-circuit.ts +14 -9
  1086. package/src/runtime/routes/playground/seed-conversation.ts +1 -1
  1087. package/src/runtime/routes/playground/seeded-conversations.ts +3 -3
  1088. package/src/runtime/routes/playground/state.ts +4 -3
  1089. package/src/runtime/routes/plugins-routes.ts +22 -19
  1090. package/src/runtime/routes/profiler-routes.ts +17 -4
  1091. package/src/runtime/routes/ps-routes.ts +5 -0
  1092. package/src/runtime/routes/publish-routes.ts +13 -3
  1093. package/src/runtime/routes/question-routes.ts +5 -0
  1094. package/src/runtime/routes/recording-routes.ts +25 -12
  1095. package/src/runtime/routes/rename-conversation-routes.ts +10 -0
  1096. package/src/runtime/routes/sanity-routes.ts +9 -2
  1097. package/src/runtime/routes/schedule-routes.ts +288 -88
  1098. package/src/runtime/routes/secret-routes.ts +31 -6
  1099. package/src/runtime/routes/sequence-routes.ts +33 -0
  1100. package/src/runtime/routes/settings-routes.ts +65 -19
  1101. package/src/runtime/routes/skills-routes.ts +166 -73
  1102. package/src/runtime/routes/slack-channel-routes.ts +5 -0
  1103. package/src/runtime/routes/stt-routes.ts +13 -6
  1104. package/src/runtime/routes/subagents-routes.ts +24 -18
  1105. package/src/runtime/routes/suggest-trust-rule-routes.ts +7 -2
  1106. package/src/runtime/routes/surface-action-routes.ts +10 -38
  1107. package/src/runtime/routes/surface-content-routes.ts +21 -6
  1108. package/src/runtime/routes/surface-conversation-resolver.ts +66 -0
  1109. package/src/runtime/routes/task-routes.ts +37 -0
  1110. package/src/runtime/routes/telemetry-routes.ts +9 -0
  1111. package/src/runtime/routes/tool-call-confirmation-enrichment.test.ts +161 -0
  1112. package/src/runtime/routes/tool-call-confirmation-enrichment.ts +107 -0
  1113. package/src/runtime/routes/trace-event-routes.ts +42 -1
  1114. package/src/runtime/routes/trust-rules-routes.ts +31 -2
  1115. package/src/runtime/routes/tts-routes.ts +48 -6
  1116. package/src/runtime/routes/types.ts +83 -16
  1117. package/src/runtime/routes/ui-request-routes.ts +5 -0
  1118. package/src/runtime/routes/upgrade-broadcast-routes.ts +5 -0
  1119. package/src/runtime/routes/usage-routes.ts +118 -42
  1120. package/src/runtime/routes/user-routes-cli.ts +9 -0
  1121. package/src/runtime/routes/user-routes.ts +5 -1
  1122. package/src/runtime/routes/wake-conversation-routes.ts +5 -0
  1123. package/src/runtime/routes/watcher-routes.ts +21 -0
  1124. package/src/runtime/routes/webhook-routes.ts +50 -2
  1125. package/src/runtime/routes/wipe-conversation-routes.ts +8 -0
  1126. package/src/runtime/routes/work-items-routes.ts +49 -23
  1127. package/src/runtime/routes/workspace-commit-routes.ts +5 -0
  1128. package/src/runtime/routes/workspace-routes.test.ts +42 -0
  1129. package/src/runtime/routes/workspace-routes.ts +124 -9
  1130. package/src/runtime/services/__tests__/analyze-conversation.test.ts +10 -4
  1131. package/src/runtime/services/analyze-conversation.ts +5 -8
  1132. package/src/runtime/services/conversation-serializer.ts +24 -2
  1133. package/src/runtime/slack-dm-text-delivery.ts +177 -0
  1134. package/src/runtime/sync/resource-sync-events.ts +17 -3
  1135. package/src/runtime/sync/sync-publisher.ts +2 -2
  1136. package/src/runtime/tool-grant-request-helper.ts +1 -0
  1137. package/src/schedule/run-script.ts +28 -3
  1138. package/src/schedule/schedule-store.ts +36 -2
  1139. package/src/schedule/schedule-usage-store.ts +83 -0
  1140. package/src/schedule/scheduler.ts +126 -21
  1141. package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
  1142. package/src/security/encrypted-store.ts +7 -16
  1143. package/src/security/store-path-override.ts +61 -0
  1144. package/src/signals/cancel.ts +2 -4
  1145. package/src/signals/user-message.ts +10 -16
  1146. package/src/skills/catalog-files.ts +4 -1
  1147. package/src/skills/catalog-install.ts +3 -0
  1148. package/src/skills/categories-cache.ts +118 -0
  1149. package/src/skills/clawhub-files.ts +1 -0
  1150. package/src/skills/skillssh-files.ts +1 -0
  1151. package/src/skills/validate-input.ts +177 -0
  1152. package/src/subagent/manager.ts +33 -24
  1153. package/src/subagent/types.ts +6 -0
  1154. package/src/tasks/tool-sanitizer.ts +2 -2
  1155. package/src/telemetry/types.ts +55 -1
  1156. package/src/telemetry/usage-telemetry-reporter.test.ts +250 -4
  1157. package/src/telemetry/usage-telemetry-reporter.ts +88 -2
  1158. package/src/tools/acp/context.ts +20 -0
  1159. package/src/tools/acp/list-agents.test.ts +7 -1
  1160. package/src/tools/acp/spawn.test.ts +198 -93
  1161. package/src/tools/acp/spawn.ts +32 -70
  1162. package/src/tools/acp/steer.test.ts +105 -8
  1163. package/src/tools/acp/steer.ts +48 -17
  1164. package/src/tools/apps/definitions.ts +42 -24
  1165. package/src/tools/apps/executors.ts +13 -8
  1166. package/src/tools/ask-question/ask-question-tool.test.ts +120 -105
  1167. package/src/tools/ask-question/ask-question-tool.ts +85 -90
  1168. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
  1169. package/src/tools/computer-use/definitions.ts +295 -289
  1170. package/src/tools/credential-execution/make-authenticated-request.ts +56 -51
  1171. package/src/tools/credential-execution/manage-secure-command-tool.ts +2 -2
  1172. package/src/tools/credential-execution/run-authenticated-command.ts +82 -77
  1173. package/src/tools/credentials/vault.ts +112 -111
  1174. package/src/tools/document/document-tool.ts +131 -8
  1175. package/src/tools/execution-target.ts +3 -6
  1176. package/src/tools/execution-timeout.ts +3 -4
  1177. package/src/tools/executor.ts +18 -107
  1178. package/src/tools/filesystem/edit.ts +45 -42
  1179. package/src/tools/filesystem/list.ts +33 -30
  1180. package/src/tools/filesystem/read.ts +54 -35
  1181. package/src/tools/filesystem/write.ts +69 -32
  1182. package/src/tools/host-filesystem/edit.test.ts +1 -0
  1183. package/src/tools/host-filesystem/edit.ts +44 -42
  1184. package/src/tools/host-filesystem/read.test.ts +1 -0
  1185. package/src/tools/host-filesystem/read.ts +49 -35
  1186. package/src/tools/host-filesystem/transfer.test.ts +31 -6
  1187. package/src/tools/host-filesystem/transfer.ts +121 -108
  1188. package/src/tools/host-filesystem/write.test.ts +1 -0
  1189. package/src/tools/host-filesystem/write.ts +33 -31
  1190. package/src/tools/host-terminal/host-shell.ts +50 -48
  1191. package/src/tools/mcp/mcp-tool-factory.ts +0 -2
  1192. package/src/tools/memory/register.ts +23 -24
  1193. package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
  1194. package/src/tools/network/__tests__/web-search-metadata.test.ts +7 -1
  1195. package/src/tools/network/__tests__/web-search.test.ts +222 -6
  1196. package/src/tools/network/managed-search-proxy.ts +183 -0
  1197. package/src/tools/network/web-fetch.ts +49 -46
  1198. package/src/tools/network/web-search-error.test.ts +248 -0
  1199. package/src/tools/network/web-search-error.ts +267 -0
  1200. package/src/tools/network/web-search.ts +414 -97
  1201. package/src/tools/policy-context.ts +3 -1
  1202. package/src/tools/registry.ts +184 -118
  1203. package/src/tools/schedule/create.ts +14 -1
  1204. package/src/tools/schedule/update.ts +16 -0
  1205. package/src/tools/shared/filesystem/audio-read.ts +122 -0
  1206. package/src/tools/shared/filesystem/image-read.ts +1 -1
  1207. package/src/tools/skills/execute.ts +34 -31
  1208. package/src/tools/skills/load.ts +29 -23
  1209. package/src/tools/skills/skill-tool-factory.ts +17 -36
  1210. package/src/tools/subagent/notify-parent.ts +35 -32
  1211. package/src/tools/subagent/spawn.ts +2 -1
  1212. package/src/tools/system/avatar-generator.ts +13 -22
  1213. package/src/tools/system/request-permission.ts +30 -27
  1214. package/src/tools/terminal/safe-env.ts +10 -1
  1215. package/src/tools/terminal/shell.ts +190 -61
  1216. package/src/tools/tool-approval-handler.ts +10 -4
  1217. package/src/tools/tool-defaults.ts +20 -9
  1218. package/src/tools/tool-manifest.ts +4 -4
  1219. package/src/tools/tool-name-aliases.ts +72 -14
  1220. package/src/tools/types.ts +86 -33
  1221. package/src/tools/ui-surface/definitions.ts +196 -95
  1222. package/src/tts/__tests__/provider-catalog-consistency.test.ts +85 -1
  1223. package/src/tts/provider-catalog.ts +76 -1
  1224. package/src/types/onboarding-context.ts +6 -0
  1225. package/src/usage/attribution.ts +32 -1
  1226. package/src/usage/types.ts +10 -0
  1227. package/src/util/browser.ts +7 -2
  1228. package/src/util/errors.ts +2 -2
  1229. package/src/util/map-limit.ts +27 -0
  1230. package/src/util/mutex.ts +47 -0
  1231. package/src/util/platform.ts +15 -12
  1232. package/src/work-items/work-item-runner.ts +7 -2
  1233. package/src/workspace/git-service.ts +1 -42
  1234. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +7 -20
  1235. package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
  1236. package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
  1237. package/src/workspace/migrations/092-backfill-v3-leaves.ts +169 -0
  1238. package/src/workspace/migrations/093-backfill-leaf-ids.ts +144 -0
  1239. package/src/workspace/migrations/094-seed-avatar-manifest.ts +155 -0
  1240. package/src/workspace/migrations/095-bump-heartbeat-interval-30m-to-60m.ts +51 -0
  1241. package/src/workspace/migrations/096-reduce-quality-profile-effort.ts +72 -0
  1242. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +117 -0
  1243. package/src/workspace/migrations/__tests__/094-seed-avatar-manifest.test.ts +136 -0
  1244. package/src/workspace/migrations/__tests__/backfill-leaf-ids.test.ts +175 -0
  1245. package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +124 -0
  1246. package/src/workspace/migrations/registry.ts +16 -0
  1247. package/src/workspace/provider-commit-message-generator.ts +15 -17
  1248. package/tsconfig.json +4 -1
  1249. package/src/__tests__/bootstrap-turn-cleanup.test.ts +0 -44
  1250. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  1251. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  1252. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -262
  1253. package/src/__tests__/empty-response-pipeline.test.ts +0 -301
  1254. package/src/__tests__/history-repair-pipeline.test.ts +0 -396
  1255. package/src/__tests__/llm-call-pipeline.test.ts +0 -281
  1256. package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -418
  1257. package/src/__tests__/persistence-pipeline.test.ts +0 -376
  1258. package/src/__tests__/title-generate-pipeline.test.ts +0 -211
  1259. package/src/__tests__/token-estimate-pipeline.test.ts +0 -481
  1260. package/src/__tests__/tool-error-pipeline.test.ts +0 -241
  1261. package/src/__tests__/tool-execute-pipeline.test.ts +0 -417
  1262. package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -344
  1263. package/src/cli/commands/__tests__/memory-v3-render.test.ts +0 -340
  1264. package/src/cli/commands/memory-v3-render.ts +0 -344
  1265. package/src/daemon/bootstrap-turn-cleanup.ts +0 -45
  1266. package/src/daemon/message-types/disk-pressure.ts +0 -9
  1267. package/src/email/feature-gate.ts +0 -23
  1268. package/src/gallery/default-gallery.ts +0 -1359
  1269. package/src/gallery/gallery-manifest.ts +0 -28
  1270. package/src/memory/v3/__tests__/coactivation-store.test.ts +0 -422
  1271. package/src/memory/v3/__tests__/consolidation-job.test.ts +0 -468
  1272. package/src/memory/v3/__tests__/edge-learning-job.test.ts +0 -324
  1273. package/src/memory/v3/__tests__/edges.test.ts +0 -563
  1274. package/src/memory/v3/__tests__/filter.test.ts +0 -512
  1275. package/src/memory/v3/__tests__/gate.test.ts +0 -574
  1276. package/src/memory/v3/__tests__/index-composition.test.ts +0 -233
  1277. package/src/memory/v3/__tests__/loop.test.ts +0 -530
  1278. package/src/memory/v3/__tests__/retriever.test.ts +0 -226
  1279. package/src/memory/v3/__tests__/scouts.test.ts +0 -440
  1280. package/src/memory/v3/__tests__/shadow-middleware.test.ts +0 -312
  1281. package/src/memory/v3/__tests__/system-prompts.test.ts +0 -154
  1282. package/src/memory/v3/__tests__/traversal.test.ts +0 -469
  1283. package/src/memory/v3/__tests__/tree-index.test.ts +0 -280
  1284. package/src/memory/v3/__tests__/tree-store.test.ts +0 -529
  1285. package/src/memory/v3/__tests__/tree-walk.test.ts +0 -707
  1286. package/src/memory/v3/__tests__/validate.test.ts +0 -245
  1287. package/src/memory/v3/auto-edges.ts +0 -223
  1288. package/src/memory/v3/coactivation-store.ts +0 -124
  1289. package/src/memory/v3/consolidation-job.ts +0 -323
  1290. package/src/memory/v3/edge-learning-job.ts +0 -160
  1291. package/src/memory/v3/edges.ts +0 -249
  1292. package/src/memory/v3/filter.ts +0 -281
  1293. package/src/memory/v3/gate.ts +0 -334
  1294. package/src/memory/v3/index-composition.ts +0 -113
  1295. package/src/memory/v3/llm-capture.ts +0 -46
  1296. package/src/memory/v3/loop.ts +0 -382
  1297. package/src/memory/v3/maintenance.ts +0 -144
  1298. package/src/memory/v3/prompt-context.ts +0 -33
  1299. package/src/memory/v3/prompts/consolidation.ts +0 -458
  1300. package/src/memory/v3/prompts/system-prompts.ts +0 -196
  1301. package/src/memory/v3/retriever.ts +0 -33
  1302. package/src/memory/v3/scouts.ts +0 -420
  1303. package/src/memory/v3/shadow-middleware.ts +0 -305
  1304. package/src/memory/v3/traversal.ts +0 -206
  1305. package/src/memory/v3/tree-index.ts +0 -237
  1306. package/src/memory/v3/tree-store.ts +0 -394
  1307. package/src/memory/v3/tree-walk.ts +0 -351
  1308. package/src/memory/v3/types.ts +0 -65
  1309. package/src/memory/v3/validate.ts +0 -300
  1310. package/src/plugins/defaults/circuit-breaker.ts +0 -141
  1311. package/src/plugins/defaults/compaction.ts +0 -141
  1312. package/src/plugins/defaults/empty-response.ts +0 -124
  1313. package/src/plugins/defaults/history-repair.ts +0 -83
  1314. package/src/plugins/defaults/llm-call.ts +0 -77
  1315. package/src/plugins/defaults/memory-retrieval.ts +0 -219
  1316. package/src/plugins/defaults/overflow-reduce.ts +0 -185
  1317. package/src/plugins/defaults/persistence.ts +0 -127
  1318. package/src/plugins/defaults/title-generate.ts +0 -90
  1319. package/src/plugins/defaults/token-estimate.ts +0 -101
  1320. package/src/plugins/defaults/tool-error.ts +0 -119
  1321. package/src/plugins/defaults/tool-execute.ts +0 -87
  1322. package/src/plugins/defaults/tool-result-truncate.ts +0 -84
  1323. package/src/skills/category-inference.ts +0 -111
@@ -1,4 +1,6 @@
1
- import { beforeEach, describe, expect, mock, test } from "bun:test";
1
+ import { mkdirSync, rmSync, writeFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
2
4
 
3
5
  // This test exercises v1 PKB injection. `config.memory.v2.enabled` (default
4
6
  // `true`) makes the PKB injector go silent — force it off here so the v1
@@ -33,6 +35,10 @@ mock.module("../memory/pkb/pkb-search.js", () => ({
33
35
  },
34
36
  }));
35
37
 
38
+ import {
39
+ clearConversations,
40
+ setConversation,
41
+ } from "../daemon/conversation-registry.js";
36
42
  import type {
37
43
  ChannelCapabilities,
38
44
  SlackTranscriptInputRow,
@@ -44,7 +50,6 @@ import {
44
50
  assembleSlackChronologicalMessages,
45
51
  buildSubagentStatusBlock,
46
52
  buildUnifiedTurnContextBlock,
47
- findLastInjectedNowContent,
48
53
  getSlackCompactionWatermarkForPrefix,
49
54
  injectChannelCapabilityContext,
50
55
  injectChannelCommandContext,
@@ -58,31 +63,102 @@ import {
58
63
  stripInjectionsForCompaction,
59
64
  stripNowScratchpad,
60
65
  } from "../daemon/conversation-runtime-assembly.js";
66
+ import type { SurfaceData, SurfaceType } from "../daemon/message-protocol.js";
61
67
  import { buildPkbReminder } from "../daemon/pkb-reminder-builder.js";
62
68
  import type { MessageRow } from "../memory/conversation-crud.js";
69
+ import { ConversationGraphMemory } from "../memory/graph/conversation-graph-memory.js";
70
+ import { getPkbRoot } from "../memory/pkb/types.js";
63
71
  import {
64
72
  type SlackMessageMetadata,
65
73
  writeSlackMetadata,
66
74
  } from "../messaging/providers/slack/message-metadata.js";
67
75
  import { parentAlias } from "../messaging/providers/slack/render-transcript.js";
68
- import { defaultInjectorsPlugin } from "../plugins/defaults/injectors.js";
69
- import {
70
- registerPlugin,
71
- resetPluginRegistryForTests,
72
- } from "../plugins/registry.js";
73
76
  import type { Message } from "../providers/types.js";
74
77
  import { wrapUntrustedContent } from "../security/untrusted-content.js";
75
78
  import type { SubagentState } from "../subagent/types.js";
79
+ import { getWorkspacePromptPath } from "../util/platform.js";
80
+
81
+ // The pkb-reminder injector derives PKB-active state from the workspace itself
82
+ // — `readPkbContext()` returning content behind the personal-memory trust gate
83
+ // — rather than from a threaded flag. Tests that need the reminder to fire seed
84
+ // a default auto-injected PKB file under the workspace pkb root; tests that
85
+ // need it suppressed leave the pkb dir empty.
86
+ function seedPkbContent(): void {
87
+ const root = getPkbRoot();
88
+ mkdirSync(root, { recursive: true });
89
+ writeFileSync(join(root, "INDEX.md"), "workspace knowledge index", "utf-8");
90
+ }
76
91
 
77
- // `applyRuntimeInjections` is now driven by the default injector chain
78
- // (PR G2.1). The default-injectors plugin must be registered for the chain
79
- // to emit workspace, PKB, NOW.md, subagent, Slack, and thread-focus blocks.
80
- // Each test gets a clean registry so a test that registers its own plugin
81
- // doesn't leak into the next one.
82
- beforeEach(() => {
83
- resetPluginRegistryForTests();
84
- registerPlugin(defaultInjectorsPlugin);
85
- });
92
+ function clearPkbContent(): void {
93
+ rmSync(getPkbRoot(), { recursive: true, force: true });
94
+ }
95
+
96
+ // The now-md injector derives NOW.md state from the workspace itself —
97
+ // `readNowScratchpad()` returning content behind the personal-memory trust gate
98
+ // and the `scratchpadInjection` config toggle — rather than from a threaded
99
+ // option. Seed the file so the injector fires; clear it so suites that assert
100
+ // NOW.md is absent stay unaffected.
101
+ function seedNowScratchpad(content: string): void {
102
+ const nowPath = getWorkspacePromptPath("NOW.md");
103
+ mkdirSync(dirname(nowPath), { recursive: true });
104
+ writeFileSync(nowPath, content, "utf-8");
105
+ }
106
+
107
+ function clearNowScratchpad(): void {
108
+ rmSync(getWorkspacePromptPath("NOW.md"), { force: true });
109
+ }
110
+
111
+ // The workspace-context injector sources its block off the live `Conversation`
112
+ // looked up by `conversationId`. Register a fake instance carrying both a
113
+ // non-dirty workspace context (non-null content, not dirty) so
114
+ // `resolveWorkspaceTopLevelContext` returns it verbatim without rescanning the
115
+ // filesystem, and an active dynamic-page surface, so `applyRuntimeInjections`
116
+ // resolves the `<workspace>` and `<active_workspace>` blocks from it;
117
+ // `clearConversations()` between tests keeps suites that assert the blocks are
118
+ // absent unaffected.
119
+ function seedActiveSurfaceConversation(
120
+ conversationId: string,
121
+ workspaceText: string,
122
+ surfaceId: string,
123
+ data: SurfaceData,
124
+ channelCapabilities?: ChannelCapabilities,
125
+ ): void {
126
+ setConversation(conversationId, {
127
+ conversationId,
128
+ workingDir: "/sandbox",
129
+ workspaceTopLevelContext: workspaceText,
130
+ workspaceTopLevelDirty: false,
131
+ currentActiveSurfaceId: surfaceId,
132
+ surfaceState: new Map<
133
+ string,
134
+ { surfaceType: SurfaceType; data: SurfaceData }
135
+ >([[surfaceId, { surfaceType: "dynamic_page", data }]]),
136
+ channelCapabilities: channelCapabilities ?? undefined,
137
+ } as never);
138
+ }
139
+
140
+ function clearWorkspaceContext(): void {
141
+ clearConversations();
142
+ }
143
+
144
+ // The `<channel_capabilities>` branch and the Slack gates source the channel
145
+ // capabilities off the live `Conversation` looked up by `conversationId`.
146
+ // Register a fake fallback instance carrying the given capabilities (and a
147
+ // non-dirty empty workspace + empty surface so the other live-sourced branches
148
+ // stay inert) so `applyRuntimeInjections` resolves them; `clearConversations()`
149
+ // between tests keeps suites asserting absence unaffected.
150
+ function seedChannelCapabilitiesConversation(
151
+ caps: ChannelCapabilities | null,
152
+ ): void {
153
+ setConversation("runtime-assembly-fallback", {
154
+ conversationId: "runtime-assembly-fallback",
155
+ workingDir: "/sandbox",
156
+ workspaceTopLevelContext: "",
157
+ workspaceTopLevelDirty: false,
158
+ surfaceState: new Map(),
159
+ channelCapabilities: caps ?? undefined,
160
+ } as never);
161
+ }
86
162
 
87
163
  // ---------------------------------------------------------------------------
88
164
  // resolveChannelCapabilities
@@ -556,6 +632,8 @@ describe("stripChannelCapabilityContext", () => {
556
632
  // ---------------------------------------------------------------------------
557
633
 
558
634
  describe("applyRuntimeInjections with channelCapabilities", () => {
635
+ afterEach(clearConversations);
636
+
559
637
  const baseMessages: Message[] = [
560
638
  {
561
639
  role: "user",
@@ -571,9 +649,8 @@ describe("applyRuntimeInjections with channelCapabilities", () => {
571
649
  supportsVoiceInput: false,
572
650
  };
573
651
 
574
- const { messages: result } = await applyRuntimeInjections(baseMessages, {
575
- channelCapabilities: caps,
576
- });
652
+ seedChannelCapabilitiesConversation(caps);
653
+ const { messages: result } = await applyRuntimeInjections(baseMessages, {});
577
654
 
578
655
  expect(result.length).toBe(1);
579
656
  expect(result[0].content.length).toBe(2);
@@ -584,9 +661,8 @@ describe("applyRuntimeInjections with channelCapabilities", () => {
584
661
  });
585
662
 
586
663
  test("does not inject when channelCapabilities is null", async () => {
587
- const { messages: result } = await applyRuntimeInjections(baseMessages, {
588
- channelCapabilities: null,
589
- });
664
+ seedChannelCapabilitiesConversation(null);
665
+ const { messages: result } = await applyRuntimeInjections(baseMessages, {});
590
666
 
591
667
  expect(result.length).toBe(1);
592
668
  expect(result[0].content.length).toBe(1);
@@ -607,9 +683,8 @@ describe("applyRuntimeInjections with channelCapabilities", () => {
607
683
  supportsVoiceInput: false,
608
684
  };
609
685
 
610
- const { messages: result } = await applyRuntimeInjections(baseMessages, {
611
- channelCapabilities: caps,
612
- });
686
+ seedChannelCapabilitiesConversation(caps);
687
+ const { messages: result } = await applyRuntimeInjections(baseMessages, {});
613
688
 
614
689
  expect(result.length).toBe(1);
615
690
  // channelCapabilities prepends
@@ -736,24 +811,52 @@ describe("applyRuntimeInjections — injection mode", () => {
736
811
  },
737
812
  ];
738
813
 
814
+ const channelCapabilities: ChannelCapabilities = {
815
+ channel: "telegram",
816
+ dashboardCapable: false,
817
+ supportsDynamicUi: false,
818
+ supportsVoiceInput: false,
819
+ };
820
+
739
821
  const fullOptions = {
740
- workspaceTopLevelContext: "<workspace>\nRoot: /sandbox\n</workspace>",
741
822
  channelCommandContext: { type: "start" } as const,
742
- activeSurface: { surfaceId: "sf_1", html: "<div>test</div>" },
743
- channelCapabilities: {
744
- channel: "telegram",
745
- dashboardCapable: false,
746
- supportsDynamicUi: false,
747
- supportsVoiceInput: false,
748
- } as ChannelCapabilities,
749
823
  unifiedTurnContext:
750
824
  "<turn_context>\ncurrent_time: 2026-03-04 (Tuesday) 12:00:00 +00:00 (UTC)\ninterface: telegram\n</turn_context>",
751
- nowScratchpad: "Current focus: shipping PR 3",
752
- pkbContext: "essentials content here",
753
- pkbActive: true,
754
825
  isNonInteractive: true,
826
+ // Guardian trust so the personal-memory gate admits the actor regardless
827
+ // of the telegram channel capabilities under test, letting the reminder
828
+ // gate hinge purely on PKB content presence.
829
+ turnContext: {
830
+ requestId: "injection-mode-req",
831
+ conversationId: "injection-mode-conv",
832
+ turnIndex: 0,
833
+ trust: {
834
+ sourceChannel: "vellum" as const,
835
+ trustClass: "guardian" as const,
836
+ },
837
+ },
755
838
  };
756
839
 
840
+ // The reminder fires only when the workspace has PKB content, and the now-md
841
+ // injector only when NOW.md has content; seed both so the full-mode cases
842
+ // exercise the active branch.
843
+ beforeEach(() => {
844
+ seedPkbContent();
845
+ seedNowScratchpad("Current focus: shipping PR 3");
846
+ seedActiveSurfaceConversation(
847
+ "injection-mode-conv",
848
+ "<workspace>\nRoot: /sandbox\n</workspace>",
849
+ "sf_1",
850
+ { html: "<div>test</div>" },
851
+ channelCapabilities,
852
+ );
853
+ });
854
+ afterEach(() => {
855
+ clearPkbContent();
856
+ clearNowScratchpad();
857
+ clearWorkspaceContext();
858
+ });
859
+
757
860
  test("full mode (default) includes all injections", async () => {
758
861
  const { messages: result } = await applyRuntimeInjections(
759
862
  baseMessages,
@@ -860,12 +963,10 @@ describe("applyRuntimeInjections — injection mode", () => {
860
963
  });
861
964
  });
862
965
 
863
- // The standalone `injectNowScratchpad` helper was removed in G2.1. The
864
- // now-md default injector (registered by `defaultInjectorsPlugin`) emits
865
- // the `<NOW.md>` block as an `after-memory-prefix` placement during
866
- // `applyRuntimeInjections`. The suites below (`applyRuntimeInjections with
867
- // nowScratchpad` and the injection-mode tests) cover that behaviour
868
- // end-to-end.
966
+ // The now-md default injector emits the `<NOW.md>` block as an
967
+ // `after-memory-prefix` placement during `applyRuntimeInjections`. The suites
968
+ // below (`applyRuntimeInjections with nowScratchpad` and the injection-mode
969
+ // tests) cover that behaviour end-to-end.
869
970
 
870
971
  // ---------------------------------------------------------------------------
871
972
  // stripNowScratchpad
@@ -1013,7 +1114,7 @@ describe("stripInjectionsForCompaction preserves persistent blocks", () => {
1013
1114
  ).toContain("<turn_context>");
1014
1115
  });
1015
1116
 
1016
- test("<workspace> blocks are NOT stripped", () => {
1117
+ test("<workspace> blocks ARE stripped so the injector re-sources them post-compaction", () => {
1017
1118
  const messages: Message[] = [
1018
1119
  {
1019
1120
  role: "user",
@@ -1029,10 +1130,10 @@ describe("stripInjectionsForCompaction preserves persistent blocks", () => {
1029
1130
 
1030
1131
  const result = stripInjectionsForCompaction(messages);
1031
1132
  expect(result.length).toBe(1);
1032
- expect(result[0].content.length).toBe(2);
1033
- expect(
1034
- (result[0].content[0] as { type: "text"; text: string }).text,
1035
- ).toContain("<workspace>");
1133
+ expect(result[0].content.length).toBe(1);
1134
+ expect((result[0].content[0] as { type: "text"; text: string }).text).toBe(
1135
+ "Hello",
1136
+ );
1036
1137
  });
1037
1138
 
1038
1139
  test("legacy <workspace_top_level> blocks ARE stripped for backward compat", () => {
@@ -1102,6 +1203,84 @@ describe("stripInjectionsForCompaction preserves persistent blocks", () => {
1102
1203
  });
1103
1204
  });
1104
1205
 
1206
+ // ---------------------------------------------------------------------------
1207
+ // stripInjectionsForCompaction — memory/info wrapper shape
1208
+ // ---------------------------------------------------------------------------
1209
+
1210
+ describe("stripInjectionsForCompaction memory/info wrapper matching", () => {
1211
+ test("injected <info>…</info> static-memory block IS stripped", () => {
1212
+ const messages: Message[] = [
1213
+ {
1214
+ role: "user",
1215
+ content: [
1216
+ { type: "text", text: "<info>\nessentials and threads\n</info>" },
1217
+ { type: "text", text: "Hello" },
1218
+ ],
1219
+ },
1220
+ ];
1221
+
1222
+ const result = stripInjectionsForCompaction(messages);
1223
+ expect(result.length).toBe(1);
1224
+ expect(result[0].content.length).toBe(1);
1225
+ expect((result[0].content[0] as { type: "text"; text: string }).text).toBe(
1226
+ "Hello",
1227
+ );
1228
+ });
1229
+
1230
+ test("injected <memory>…</memory> activation block IS stripped", () => {
1231
+ const messages: Message[] = [
1232
+ {
1233
+ role: "user",
1234
+ content: [
1235
+ { type: "text", text: "<memory>\nactivated slugs\n</memory>" },
1236
+ { type: "text", text: "Hello" },
1237
+ ],
1238
+ },
1239
+ ];
1240
+
1241
+ const result = stripInjectionsForCompaction(messages);
1242
+ expect(result.length).toBe(1);
1243
+ expect(result[0].content.length).toBe(1);
1244
+ expect((result[0].content[0] as { type: "text"; text: string }).text).toBe(
1245
+ "Hello",
1246
+ );
1247
+ });
1248
+
1249
+ test("user text merely starting with <info>\\n (no closing tag) is NOT stripped", () => {
1250
+ const userText = "<info>\nHere is what I want to discuss about the markup";
1251
+ const messages: Message[] = [
1252
+ {
1253
+ role: "user",
1254
+ content: [{ type: "text", text: userText }],
1255
+ },
1256
+ ];
1257
+
1258
+ const result = stripInjectionsForCompaction(messages);
1259
+ expect(result.length).toBe(1);
1260
+ expect(result[0].content.length).toBe(1);
1261
+ expect((result[0].content[0] as { type: "text"; text: string }).text).toBe(
1262
+ userText,
1263
+ );
1264
+ });
1265
+
1266
+ test("user text merely starting with <memory>\\n (no closing tag) is NOT stripped", () => {
1267
+ const userText = "<memory>\nplease remember to buy milk";
1268
+ const messages: Message[] = [
1269
+ {
1270
+ role: "user",
1271
+ content: [{ type: "text", text: userText }],
1272
+ },
1273
+ ];
1274
+
1275
+ const result = stripInjectionsForCompaction(messages);
1276
+ expect(result.length).toBe(1);
1277
+ expect(result[0].content.length).toBe(1);
1278
+ expect((result[0].content[0] as { type: "text"; text: string }).text).toBe(
1279
+ userText,
1280
+ );
1281
+ });
1282
+ });
1283
+
1105
1284
  // ---------------------------------------------------------------------------
1106
1285
  // applyRuntimeInjections with nowScratchpad
1107
1286
  // ---------------------------------------------------------------------------
@@ -1114,10 +1293,14 @@ describe("applyRuntimeInjections with nowScratchpad", () => {
1114
1293
  },
1115
1294
  ];
1116
1295
 
1117
- test("injects NOW.md block when provided", async () => {
1118
- const { messages: result } = await applyRuntimeInjections(baseMessages, {
1119
- nowScratchpad: "Current focus: fix the bug",
1120
- });
1296
+ // The now-md injector sources NOW.md from the workspace itself rather than
1297
+ // from a threaded option, so seed the file to drive injection and clear it so
1298
+ // the absent-content cases see no block.
1299
+ afterEach(clearNowScratchpad);
1300
+
1301
+ test("injects NOW.md block when the file has content", async () => {
1302
+ seedNowScratchpad("Current focus: fix the bug");
1303
+ const { messages: result } = await applyRuntimeInjections(baseMessages, {});
1121
1304
 
1122
1305
  expect(result.length).toBe(1);
1123
1306
  expect(result[0].content.length).toBe(2);
@@ -1128,9 +1311,8 @@ describe("applyRuntimeInjections with nowScratchpad", () => {
1128
1311
  });
1129
1312
 
1130
1313
  test("scratchpad appears before user's original text content", async () => {
1131
- const { messages: result } = await applyRuntimeInjections(baseMessages, {
1132
- nowScratchpad: "scratchpad notes",
1133
- });
1314
+ seedNowScratchpad("scratchpad notes");
1315
+ const { messages: result } = await applyRuntimeInjections(baseMessages, {});
1134
1316
 
1135
1317
  // Scratchpad comes first (before user content)
1136
1318
  expect(
@@ -1142,16 +1324,7 @@ describe("applyRuntimeInjections with nowScratchpad", () => {
1142
1324
  );
1143
1325
  });
1144
1326
 
1145
- test("does not inject when nowScratchpad is null", async () => {
1146
- const { messages: result } = await applyRuntimeInjections(baseMessages, {
1147
- nowScratchpad: null,
1148
- });
1149
-
1150
- expect(result.length).toBe(1);
1151
- expect(result[0].content.length).toBe(1);
1152
- });
1153
-
1154
- test("does not inject when nowScratchpad is omitted", async () => {
1327
+ test("does not inject when the NOW.md file is absent", async () => {
1155
1328
  const { messages: result } = await applyRuntimeInjections(baseMessages, {});
1156
1329
 
1157
1330
  expect(result.length).toBe(1);
@@ -1159,8 +1332,8 @@ describe("applyRuntimeInjections with nowScratchpad", () => {
1159
1332
  });
1160
1333
 
1161
1334
  test("skipped in minimal mode", async () => {
1335
+ seedNowScratchpad("Current focus: fix the bug");
1162
1336
  const { messages: result } = await applyRuntimeInjections(baseMessages, {
1163
- nowScratchpad: "Current focus: fix the bug",
1164
1337
  mode: "minimal",
1165
1338
  });
1166
1339
 
@@ -1704,85 +1877,6 @@ describe("applyRuntimeInjections blocks.unifiedTurnContext", () => {
1704
1877
  });
1705
1878
  });
1706
1879
 
1707
- // ---------------------------------------------------------------------------
1708
- // findLastInjectedNowContent
1709
- // ---------------------------------------------------------------------------
1710
-
1711
- describe("findLastInjectedNowContent", () => {
1712
- test("extracts NOW.md content from the last user message", () => {
1713
- const messages: Message[] = [
1714
- {
1715
- role: "user",
1716
- content: [
1717
- {
1718
- type: "text",
1719
- text: "<NOW.md Always keep this up to date>\nCurrent focus: fix the bug\n</NOW.md>",
1720
- },
1721
- { type: "text", text: "Hello" },
1722
- ],
1723
- },
1724
- ];
1725
-
1726
- expect(findLastInjectedNowContent(messages)).toBe(
1727
- "Current focus: fix the bug",
1728
- );
1729
- });
1730
-
1731
- test("returns null when no NOW.md injection exists", () => {
1732
- const messages: Message[] = [
1733
- {
1734
- role: "user",
1735
- content: [{ type: "text", text: "Hello" }],
1736
- },
1737
- ];
1738
-
1739
- expect(findLastInjectedNowContent(messages)).toBeNull();
1740
- });
1741
-
1742
- test("returns the most recent injection when multiple exist", () => {
1743
- const messages: Message[] = [
1744
- {
1745
- role: "user",
1746
- content: [
1747
- {
1748
- type: "text",
1749
- text: "<NOW.md Always keep this up to date>\nOld focus\n</NOW.md>",
1750
- },
1751
- ],
1752
- },
1753
- { role: "assistant", content: [{ type: "text", text: "OK" }] },
1754
- {
1755
- role: "user",
1756
- content: [
1757
- {
1758
- type: "text",
1759
- text: "<NOW.md Always keep this up to date>\nNew focus\n</NOW.md>",
1760
- },
1761
- ],
1762
- },
1763
- ];
1764
-
1765
- expect(findLastInjectedNowContent(messages)).toBe("New focus");
1766
- });
1767
-
1768
- test("skips assistant messages", () => {
1769
- const messages: Message[] = [
1770
- {
1771
- role: "user",
1772
- content: [
1773
- {
1774
- type: "text",
1775
- text: "<NOW.md Always keep this up to date>\nUser focus\n</NOW.md>",
1776
- },
1777
- ],
1778
- },
1779
- { role: "assistant", content: [{ type: "text", text: "response" }] },
1780
- ];
1781
-
1782
- expect(findLastInjectedNowContent(messages)).toBe("User focus");
1783
- });
1784
- });
1785
-
1786
1880
  // ---------------------------------------------------------------------------
1787
1881
  // Subagent status injection
1788
1882
  // ---------------------------------------------------------------------------
@@ -1954,21 +2048,33 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
1954
2048
 
1955
2049
  const FLAT_REMINDER = buildPkbReminder([]);
1956
2050
 
1957
- // Use a platform-agnostic absolute workspace root so the tests work on
1958
- // macOS and Linux runners alike. `pkbRoot` sits under `pkbWorkingDir` to
1959
- // mirror production, where `pkbRoot = join(workingDir, "pkb")`.
1960
- const pkbWorkingDir = "/tmp/fake-workspace";
1961
- const pkbRoot = `${pkbWorkingDir}/pkb`;
2051
+ // The pkb-reminder injector sources the PKB root itself via `getPkbRoot()`,
2052
+ // so the in-context file paths these tests build must resolve against the
2053
+ // same per-test workspace the injector sees.
2054
+ const pkbRoot = getPkbRoot();
2055
+
2056
+ // The pkb-reminder injector reads the dense/sparse PKB query pair off the
2057
+ // conversation's live graph handle (the memory-retrieval hook records it
2058
+ // there during retrieval), not from the injection options. Register a handle
2059
+ // for the fallback conversation id `applyRuntimeInjections` synthesizes and
2060
+ // seed it with a query vector so the hint-search branch runs.
2061
+ let graphHandle: ConversationGraphMemory;
2062
+ beforeEach(() => {
2063
+ graphHandle = new ConversationGraphMemory("runtime-assembly-fallback");
2064
+ graphHandle.recordPkbQueryVectors([0.1, 0.2, 0.3], undefined);
2065
+ });
2066
+ afterEach(() => {
2067
+ graphHandle.dispose();
2068
+ });
2069
+
2070
+ // PKB content makes `readPkbContext()` non-null so the (vellum/guardian-
2071
+ // equivalent) fallback trust gate admits the reminder; cleared after each
2072
+ // test to avoid leaking into suites that assert the reminder is absent.
2073
+ beforeEach(seedPkbContent);
2074
+ afterEach(clearPkbContent);
1962
2075
 
1963
2076
  function makePkbOptions(overrides: Record<string, unknown> = {}) {
1964
2077
  return {
1965
- pkbActive: true,
1966
- pkbQueryVector: [0.1, 0.2, 0.3],
1967
- pkbScopeId: "scope-1",
1968
- pkbConversation: { messages: baseMessages },
1969
- pkbRoot,
1970
- pkbWorkingDir,
1971
- pkbAutoInjectList: [],
1972
2078
  ...overrides,
1973
2079
  };
1974
2080
  }
@@ -2004,10 +2110,11 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
2004
2110
  test("default auto-injected files (from PKB_DEFAULT_FILES) are filtered out of hints", async () => {
2005
2111
  // Regression test: when `_autoinject.md` is missing, `readPkbContext`
2006
2112
  // falls back to PKB_DEFAULT_FILES — so those files ARE in the prompt.
2007
- // The tracker must know about them too, otherwise the reminder would
2008
- // redundantly recommend e.g. `essentials.md` even though its contents
2009
- // are already injected. The agent-loop passes the effective auto-inject
2010
- // list (via `getPkbAutoInjectList`) to `applyRuntimeInjections`.
2113
+ // The injector sources the same fallback via `getPkbAutoInjectList`, so
2114
+ // it must know about them too, otherwise the reminder would redundantly
2115
+ // recommend e.g. `essentials.md` even though its contents are already
2116
+ // injected. The per-test workspace has no `_autoinject.md`, so the
2117
+ // injector resolves PKB_DEFAULT_FILES here.
2011
2118
  pkbSearchResults = [
2012
2119
  { path: "essentials.md", denseScore: 0.95 },
2013
2120
  { path: "topics/alpha.md", denseScore: 0.9 },
@@ -2016,16 +2123,7 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
2016
2123
 
2017
2124
  const { messages: result } = await applyRuntimeInjections(
2018
2125
  baseMessages,
2019
- makePkbOptions({
2020
- // Simulate the fallback the agent-loop now threads through:
2021
- // `_autoinject.md` is missing, so defaults are injected.
2022
- pkbAutoInjectList: [
2023
- "INDEX.md",
2024
- "essentials.md",
2025
- "threads.md",
2026
- "buffer.md",
2027
- ],
2028
- }),
2126
+ makePkbOptions(),
2029
2127
  );
2030
2128
  const texts = extractTexts(result);
2031
2129
  const reminder = texts.find((t) => t.startsWith("<system_reminder>"));
@@ -2065,27 +2163,26 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
2065
2163
  ];
2066
2164
  pkbSearchThrows = null;
2067
2165
 
2068
- // Build a conversation that has already read topics/beta.md via file_read.
2069
- const conversationWithRead: { messages: Message[] } = {
2070
- messages: [
2071
- ...baseMessages,
2072
- {
2073
- role: "assistant",
2074
- content: [
2075
- {
2076
- type: "tool_use",
2077
- id: "tu_1",
2078
- name: "file_read",
2079
- input: { path: `${pkbRoot}/topics/beta.md` },
2080
- },
2081
- ],
2082
- },
2083
- ],
2084
- };
2166
+ // Working messages where topics/beta.md was already read via file_read on
2167
+ // an earlier turn, followed by the current user prompt as the tail.
2168
+ const conversationWithRead: Message[] = [
2169
+ {
2170
+ role: "assistant",
2171
+ content: [
2172
+ {
2173
+ type: "tool_use",
2174
+ id: "tu_1",
2175
+ name: "file_read",
2176
+ input: { path: `${pkbRoot}/topics/beta.md` },
2177
+ },
2178
+ ],
2179
+ },
2180
+ ...baseMessages,
2181
+ ];
2085
2182
 
2086
2183
  const { messages: result } = await applyRuntimeInjections(
2087
- baseMessages,
2088
- makePkbOptions({ pkbConversation: conversationWithRead }),
2184
+ conversationWithRead,
2185
+ makePkbOptions(),
2089
2186
  );
2090
2187
  const texts = extractTexts(result);
2091
2188
  const reminder = texts.find((t) => t.startsWith("<system_reminder>"));
@@ -2123,10 +2220,13 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
2123
2220
 
2124
2221
  test("missing query vector → flat fallback, search is not attempted", async () => {
2125
2222
  pkbSearchThrows = new Error("should not be called");
2223
+ // No dense vector was recorded on the graph handle this turn, so the
2224
+ // injector must skip the hint search entirely.
2225
+ graphHandle.recordPkbQueryVectors(undefined, undefined);
2126
2226
 
2127
2227
  const { messages: result } = await applyRuntimeInjections(
2128
2228
  baseMessages,
2129
- makePkbOptions({ pkbQueryVector: undefined }),
2229
+ makePkbOptions(),
2130
2230
  );
2131
2231
  const texts = extractTexts(result);
2132
2232
  const reminder = texts.find((t) => t.startsWith("<system_reminder>"));
@@ -2240,37 +2340,28 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
2240
2340
  ];
2241
2341
  pkbSearchThrows = null;
2242
2342
 
2243
- // Pre-compaction conversation: beta was already read.
2244
- const preCompactionConversation: { messages: Message[] } = {
2245
- messages: [
2246
- ...baseMessages,
2247
- {
2248
- role: "assistant",
2249
- content: [
2250
- {
2251
- type: "tool_use",
2252
- id: "tu_pre",
2253
- name: "file_read",
2254
- input: { path: `${pkbRoot}/topics/beta.md` },
2255
- },
2256
- ],
2257
- },
2258
- ],
2259
- };
2343
+ // Pre-compaction working messages: beta was already read on an earlier
2344
+ // turn, followed by the current user prompt as the tail.
2345
+ const preCompactionMessages: Message[] = [
2346
+ {
2347
+ role: "assistant",
2348
+ content: [
2349
+ {
2350
+ type: "tool_use",
2351
+ id: "tu_pre",
2352
+ name: "file_read",
2353
+ input: { path: `${pkbRoot}/topics/beta.md` },
2354
+ },
2355
+ ],
2356
+ },
2357
+ ...baseMessages,
2358
+ ];
2260
2359
 
2261
2360
  // 1. Initial injection sees the pre-compaction state — beta should be
2262
2361
  // filtered out.
2263
2362
  const { messages: initialResult } = await applyRuntimeInjections(
2264
- baseMessages,
2265
- {
2266
- pkbActive: true,
2267
- pkbQueryVector: [0.1, 0.2],
2268
- pkbScopeId: "scope-1",
2269
- pkbConversation: preCompactionConversation,
2270
- pkbRoot,
2271
- pkbWorkingDir,
2272
- pkbAutoInjectList: [],
2273
- },
2363
+ preCompactionMessages,
2364
+ {},
2274
2365
  );
2275
2366
  // Unwrap the injected reminder from the last user message.
2276
2367
  const initialTexts = extractTexts(initialResult);
@@ -2282,41 +2373,29 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
2282
2373
  expect(initialReminder).toBeDefined();
2283
2374
  expect(initialReminder).not.toContain("- topics/beta.md");
2284
2375
 
2285
- // 2. Simulate compaction: strip all runtime injections, rebuild
2286
- // conversation to reflect the post-compaction state (tool_use blocks
2287
- // are serialized into summary text, so the only live file_read is the
2288
- // newly-read gamma).
2289
- const postCompactionConversation: { messages: Message[] } = {
2290
- messages: [
2291
- ...baseMessages,
2292
- {
2293
- role: "assistant",
2294
- content: [
2295
- {
2296
- type: "tool_use",
2297
- id: "tu_post",
2298
- name: "file_read",
2299
- input: { path: `${pkbRoot}/topics/gamma.md` },
2300
- },
2301
- ],
2302
- },
2303
- ],
2304
- };
2305
- const postCompactionMessages = stripInjectionsForCompaction(initialResult);
2376
+ // 2. After compaction the working messages reflect the post-compaction
2377
+ // state: beta's tool_use was serialized into summary text and dropped,
2378
+ // so the only live file_read is the newly-read gamma.
2379
+ const postCompactionMessages: Message[] = [
2380
+ {
2381
+ role: "assistant",
2382
+ content: [
2383
+ {
2384
+ type: "tool_use",
2385
+ id: "tu_post",
2386
+ name: "file_read",
2387
+ input: { path: `${pkbRoot}/topics/gamma.md` },
2388
+ },
2389
+ ],
2390
+ },
2391
+ ...baseMessages,
2392
+ ];
2306
2393
 
2307
- // 3. Re-inject with the new conversation — gamma (now in context)
2394
+ // 3. Re-inject over the post-compaction messages — gamma (now in context)
2308
2395
  // should be filtered, and beta (no longer "in context") should appear.
2309
2396
  const { messages: rebuiltResult } = await applyRuntimeInjections(
2310
2397
  postCompactionMessages,
2311
- {
2312
- pkbActive: true,
2313
- pkbQueryVector: [0.1, 0.2],
2314
- pkbScopeId: "scope-1",
2315
- pkbConversation: postCompactionConversation,
2316
- pkbRoot,
2317
- pkbWorkingDir,
2318
- pkbAutoInjectList: [],
2319
- },
2398
+ {},
2320
2399
  );
2321
2400
  const rebuiltTexts = extractTexts(rebuiltResult);
2322
2401
  const rebuiltReminder = rebuiltTexts.find(
@@ -2336,6 +2415,8 @@ describe("applyRuntimeInjections — PKB relevance hints", () => {
2336
2415
  // ---------------------------------------------------------------------------
2337
2416
 
2338
2417
  describe("Slack channel chronological rendering — multi-thread", () => {
2418
+ afterEach(clearConversations);
2419
+
2339
2420
  // Slack ts values are seconds-since-epoch with microsecond precision.
2340
2421
  // Pick a few stable anchors so thread aliases (sha-derived) stay
2341
2422
  // predictable across the scenarios.
@@ -2421,8 +2502,8 @@ describe("Slack channel chronological rendering — multi-thread", () => {
2421
2502
  role: "user",
2422
2503
  content: [{ type: "text", text: "current turn" }],
2423
2504
  };
2505
+ seedChannelCapabilitiesConversation(slackChannelCaps);
2424
2506
  const { messages } = await applyRuntimeInjections([lastUserMessage], {
2425
- channelCapabilities: slackChannelCaps,
2426
2507
  slackChronologicalMessages,
2427
2508
  });
2428
2509
  return messages;
@@ -2710,15 +2791,15 @@ describe("Slack channel chronological rendering — multi-thread", () => {
2710
2791
  role: "user",
2711
2792
  content: [{ type: "text", text: "vellum question" }],
2712
2793
  };
2794
+ seedChannelCapabilitiesConversation({
2795
+ channel: "vellum",
2796
+ dashboardCapable: true,
2797
+ supportsDynamicUi: true,
2798
+ supportsVoiceInput: true,
2799
+ });
2713
2800
  const { messages: result } = await applyRuntimeInjections(
2714
2801
  [lastUserMessage],
2715
2802
  {
2716
- channelCapabilities: {
2717
- channel: "vellum",
2718
- dashboardCapable: true,
2719
- supportsDynamicUi: true,
2720
- supportsVoiceInput: true,
2721
- },
2722
2803
  // Even if we accidentally pass a chronological transcript, the
2723
2804
  // branch must be a no-op for non-slack channels.
2724
2805
  slackChronologicalMessages: [
@@ -2748,16 +2829,16 @@ describe("Slack channel chronological rendering — multi-thread", () => {
2748
2829
  role: "user",
2749
2830
  content: [{ type: "text", text: "DM question" }],
2750
2831
  };
2832
+ seedChannelCapabilitiesConversation({
2833
+ channel: "slack",
2834
+ dashboardCapable: false,
2835
+ supportsDynamicUi: false,
2836
+ supportsVoiceInput: false,
2837
+ chatType: "im",
2838
+ });
2751
2839
  const { messages: result } = await applyRuntimeInjections(
2752
2840
  [lastUserMessage],
2753
2841
  {
2754
- channelCapabilities: {
2755
- channel: "slack",
2756
- dashboardCapable: false,
2757
- supportsDynamicUi: false,
2758
- supportsVoiceInput: false,
2759
- chatType: "im",
2760
- },
2761
2842
  slackChronologicalMessages: [
2762
2843
  {
2763
2844
  role: "user",
@@ -2816,10 +2897,10 @@ describe("Slack channel chronological rendering — multi-thread", () => {
2816
2897
  ],
2817
2898
  },
2818
2899
  ];
2900
+ seedChannelCapabilitiesConversation(slackCaps);
2819
2901
  const { messages: result } = await applyRuntimeInjections(
2820
2902
  runMessagesWithMemory,
2821
2903
  {
2822
- channelCapabilities: slackCaps,
2823
2904
  slackChronologicalMessages: [
2824
2905
  {
2825
2906
  role: "user",
@@ -2880,10 +2961,10 @@ describe("Slack channel chronological rendering — multi-thread", () => {
2880
2961
  ],
2881
2962
  },
2882
2963
  ];
2964
+ seedChannelCapabilitiesConversation(slackCaps);
2883
2965
  const { messages: result } = await applyRuntimeInjections(
2884
2966
  runMessagesWithMemory,
2885
2967
  {
2886
- channelCapabilities: slackCaps,
2887
2968
  slackChronologicalMessages: [
2888
2969
  {
2889
2970
  role: "user",
@@ -2919,10 +3000,10 @@ describe("Slack channel chronological rendering — multi-thread", () => {
2919
3000
  supportsVoiceInput: false,
2920
3001
  chatType: "im",
2921
3002
  };
3003
+ seedChannelCapabilitiesConversation(slackCaps);
2922
3004
  const { messages: result } = await applyRuntimeInjections(
2923
3005
  [{ role: "user", content: [{ type: "text", text: "inbound" }] }],
2924
3006
  {
2925
- channelCapabilities: slackCaps,
2926
3007
  slackChronologicalMessages: [
2927
3008
  {
2928
3009
  role: "user",
@@ -2963,10 +3044,10 @@ describe("Slack channel chronological rendering — multi-thread", () => {
2963
3044
  { loader: () => rows, trustClass: "guardian" },
2964
3045
  );
2965
3046
 
3047
+ seedChannelCapabilitiesConversation(slackChannelCaps);
2966
3048
  const { messages: result } = await applyRuntimeInjections(
2967
3049
  [{ role: "user", content: [{ type: "text", text: "current turn" }] }],
2968
3050
  {
2969
- channelCapabilities: slackChannelCaps,
2970
3051
  slackChronologicalMessages,
2971
3052
  transportHints: ["thread context: ..."],
2972
3053
  },
@@ -2993,10 +3074,10 @@ describe("Slack channel chronological rendering — multi-thread", () => {
2993
3074
  chatType: "im",
2994
3075
  };
2995
3076
 
3077
+ seedChannelCapabilitiesConversation(slackDmCaps);
2996
3078
  const { messages: result } = await applyRuntimeInjections(
2997
3079
  [{ role: "user", content: [{ type: "text", text: "hi DM" }] }],
2998
3080
  {
2999
- channelCapabilities: slackDmCaps,
3000
3081
  transportHints: ["dm context: ..."],
3001
3082
  },
3002
3083
  );
@@ -3012,16 +3093,16 @@ describe("Slack channel chronological rendering — multi-thread", () => {
3012
3093
 
3013
3094
  // ── transport_hints kept for non-slack channels ───────────────────────
3014
3095
  test("non-slack conversations still receive <transport_hints>", async () => {
3096
+ seedChannelCapabilitiesConversation({
3097
+ channel: "telegram",
3098
+ dashboardCapable: false,
3099
+ supportsDynamicUi: false,
3100
+ supportsVoiceInput: false,
3101
+ chatType: "private",
3102
+ });
3015
3103
  const { messages: result } = await applyRuntimeInjections(
3016
3104
  [{ role: "user", content: [{ type: "text", text: "hi" }] }],
3017
3105
  {
3018
- channelCapabilities: {
3019
- channel: "telegram",
3020
- dashboardCapable: false,
3021
- supportsDynamicUi: false,
3022
- supportsVoiceInput: false,
3023
- chatType: "private",
3024
- },
3025
3106
  transportHints: ["please answer concisely"],
3026
3107
  },
3027
3108
  );
@@ -3348,8 +3429,8 @@ describe("Slack channel chronological rendering — multi-thread", () => {
3348
3429
  role: "user",
3349
3430
  content: [{ type: "text", text: "current turn" }],
3350
3431
  };
3432
+ seedChannelCapabilitiesConversation(slackChannelCaps);
3351
3433
  const { messages } = await applyRuntimeInjections([lastUserMessage], {
3352
- channelCapabilities: slackChannelCaps,
3353
3434
  slackChronologicalMessages,
3354
3435
  slackActiveThreadFocusBlock: focusBlock,
3355
3436
  });
@@ -3618,8 +3699,8 @@ describe("Slack channel chronological rendering — multi-thread", () => {
3618
3699
  chatType: "channel",
3619
3700
  };
3620
3701
  const newFocus = "<active_thread>\nnewly built\n</active_thread>";
3702
+ seedChannelCapabilitiesConversation(slackChannelCaps);
3621
3703
  const { messages: reInjected } = await applyRuntimeInjections(stripped, {
3622
- channelCapabilities: slackChannelCaps,
3623
3704
  slackActiveThreadFocusBlock: newFocus,
3624
3705
  });
3625
3706
  const reInjectedTexts = reInjected
@@ -3639,15 +3720,15 @@ describe("Slack channel chronological rendering — multi-thread", () => {
3639
3720
  // Defensive: the focus injection is gated on `slackChannel` (i.e.
3640
3721
  // `isSlackChannelConversation`). Even if a caller mistakenly forwards
3641
3722
  // a focus block on a non-Slack channel, it must NOT be appended.
3723
+ seedChannelCapabilitiesConversation({
3724
+ channel: "vellum",
3725
+ dashboardCapable: true,
3726
+ supportsDynamicUi: true,
3727
+ supportsVoiceInput: true,
3728
+ });
3642
3729
  const { messages: result } = await applyRuntimeInjections(
3643
3730
  [{ role: "user", content: [{ type: "text", text: "vellum question" }] }],
3644
3731
  {
3645
- channelCapabilities: {
3646
- channel: "vellum",
3647
- dashboardCapable: true,
3648
- supportsDynamicUi: true,
3649
- supportsVoiceInput: true,
3650
- },
3651
3732
  slackActiveThreadFocusBlock: "<active_thread>\nbogus\n</active_thread>",
3652
3733
  },
3653
3734
  );
@@ -3664,16 +3745,16 @@ describe("Slack channel chronological rendering — multi-thread", () => {
3664
3745
  // Same as above but for Slack DMs (chatType === "im"). The focus
3665
3746
  // injection is keyed on `isSlackChannelConversation` which excludes
3666
3747
  // DMs, so the block must not appear.
3748
+ seedChannelCapabilitiesConversation({
3749
+ channel: "slack",
3750
+ dashboardCapable: false,
3751
+ supportsDynamicUi: false,
3752
+ supportsVoiceInput: false,
3753
+ chatType: "im",
3754
+ });
3667
3755
  const { messages: result } = await applyRuntimeInjections(
3668
3756
  [{ role: "user", content: [{ type: "text", text: "DM question" }] }],
3669
3757
  {
3670
- channelCapabilities: {
3671
- channel: "slack",
3672
- dashboardCapable: false,
3673
- supportsDynamicUi: false,
3674
- supportsVoiceInput: false,
3675
- chatType: "im",
3676
- },
3677
3758
  slackActiveThreadFocusBlock: "<active_thread>\nbogus\n</active_thread>",
3678
3759
  },
3679
3760
  );
@@ -3912,11 +3993,11 @@ describe("assembleSlackActiveThreadFocusBlock", () => {
3912
3993
  expect(result!).not.toContain("Sibling top-level");
3913
3994
  });
3914
3995
 
3915
- test("preserves speaker attribution when flattening to plain text", () => {
3996
+ test("preserves user attribution while leaving assistant text unchanged", () => {
3916
3997
  // The `<active_thread>` block is rendered as newline-joined plain text,
3917
- // discarding `Message.role`. Assistant rows and unnamed user rows must
3918
- // therefore carry an explicit `@assistant` / `@user` label so the model
3919
- // can still tell turns apart inside the flattened block.
3998
+ // discarding `Message.role`. User rows keep explicit Slack attribution,
3999
+ // while assistant rows remain raw to avoid teaching the model a synthetic
4000
+ // reply prefix.
3920
4001
  const rows: SlackTranscriptInputRow[] = [
3921
4002
  buildRow(
3922
4003
  "user",
@@ -3943,17 +4024,16 @@ describe("assembleSlackActiveThreadFocusBlock", () => {
3943
4024
  const result = assembleSlackActiveThreadFocusBlock(rows, SLACK_CAPS);
3944
4025
  expect(result).not.toBeNull();
3945
4026
  expect(result!).toContain("@alice");
3946
- expect(result!).toContain("@assistant");
4027
+ expect(result!).toContain("Assistant reply");
4028
+ expect(result!).not.toContain("@assistant: Assistant reply");
3947
4029
  expect(result!).toContain("@user");
3948
4030
  });
3949
4031
 
3950
4032
  test("assistant reactions are not double-attributed (`@assistant: [... @assistant reacted ...]`)", () => {
3951
4033
  // `renderReaction` bakes `@assistant` into the reaction tag line
3952
4034
  // (`[11/14/23 14:28 @assistant reacted 👍 to Mxxxxxx]`). The
3953
- // post-render step that prepends `@assistant: ` to assistant content
3954
- // lines must skip reaction lines, otherwise the flattened block
3955
- // produces `@assistant: [... @assistant reacted ...]` — two
3956
- // attributions for one event.
4035
+ // flattened block should preserve that renderer-owned attribution without
4036
+ // adding any extra assistant-message prefix.
3957
4037
  const rows: SlackTranscriptInputRow[] = [
3958
4038
  buildRow(
3959
4039
  "user",
@@ -3961,7 +4041,7 @@ describe("assembleSlackActiveThreadFocusBlock", () => {
3961
4041
  1_000,
3962
4042
  buildMeta({ channelTs: PARENT_TS, displayName: "@alice" }),
3963
4043
  ),
3964
- // Assistant reply in the thread — gets an `@assistant:` prefix.
4044
+ // Assistant reply in the thread — stays unchanged.
3965
4045
  buildRow(
3966
4046
  "assistant",
3967
4047
  "Assistant reply",
@@ -4003,12 +4083,13 @@ describe("assembleSlackActiveThreadFocusBlock", () => {
4003
4083
  expect(result).not.toBeNull();
4004
4084
  // Double-attribution anti-pattern must NOT appear anywhere.
4005
4085
  expect(result!).not.toContain("@assistant: [");
4006
- // Both the reaction attribution and the reply prefix are still present.
4086
+ // Reaction attribution remains, and the assistant reply stays raw.
4007
4087
  expect(result!).toContain("@assistant reacted 👍");
4008
- expect(result!).toContain("@assistant: Assistant reply");
4088
+ expect(result!).toContain("Assistant reply");
4089
+ expect(result!).not.toContain("@assistant: Assistant reply");
4009
4090
  });
4010
4091
 
4011
- test("timezone-aware assistant rows keep renderer attribution in active-thread focus block", () => {
4092
+ test("timezone-aware assistant rows stay unchanged in active-thread focus block", () => {
4012
4093
  const rows: SlackTranscriptInputRow[] = [
4013
4094
  buildRow(
4014
4095
  "user",
@@ -4049,15 +4130,12 @@ describe("assembleSlackActiveThreadFocusBlock", () => {
4049
4130
 
4050
4131
  const result = assembleSlackActiveThreadFocusBlock(rows, SLACK_CAPS);
4051
4132
  expect(result).not.toBeNull();
4052
- expect(result!).toContain(
4053
- "[nov 14 2023 3:13 PM MT assistant] Assistant reply",
4054
- );
4055
- expect(result!).not.toContain(
4056
- "@assistant: [nov 14 2023 3:13 PM MT assistant]",
4057
- );
4133
+ expect(result!).toContain("\nAssistant reply\n");
4134
+ expect(result!).not.toContain("[nov 14 2023 3:13 PM MT assistant]");
4135
+ expect(result!).not.toContain("@assistant: Assistant reply");
4058
4136
  });
4059
4137
 
4060
- test("assistant content that only looks like a compact tag still gets active-thread attribution", () => {
4138
+ test("assistant content that only looks like a compact tag stays unchanged", () => {
4061
4139
  const compactLookingContent =
4062
4140
  "[nov 14 2023 3:13 PM MT assistant] Assistant reply";
4063
4141
  const rows: SlackTranscriptInputRow[] = [
@@ -4090,7 +4168,8 @@ describe("assembleSlackActiveThreadFocusBlock", () => {
4090
4168
 
4091
4169
  const result = assembleSlackActiveThreadFocusBlock(rows, SLACK_CAPS);
4092
4170
  expect(result).not.toBeNull();
4093
- expect(result!).toContain(`@assistant: ${compactLookingContent}`);
4171
+ expect(result!).toContain(`\n${compactLookingContent}\n`);
4172
+ expect(result!).not.toContain(`@assistant: ${compactLookingContent}`);
4094
4173
  });
4095
4174
 
4096
4175
  test("assistant reaction overflow trailer is not double-attributed", () => {
@@ -5024,11 +5103,15 @@ describe("applyRuntimeInjections blocks.pkbSystemReminder", () => {
5024
5103
  },
5025
5104
  ];
5026
5105
 
5106
+ // The reminder gate hinges on PKB content presence; clear it after each test
5107
+ // so the "PKB inactive" case starts from an empty workspace pkb dir.
5108
+ afterEach(clearPkbContent);
5109
+
5027
5110
  test("captures exact reminder bytes when full mode and PKB active", async () => {
5111
+ seedPkbContent();
5028
5112
  pkbSearchResults = [];
5029
5113
  pkbSearchThrows = null;
5030
5114
  const { blocks } = await applyRuntimeInjections(baseMessages, {
5031
- pkbActive: true,
5032
5115
  mode: "full",
5033
5116
  });
5034
5117
 
@@ -5037,8 +5120,8 @@ describe("applyRuntimeInjections blocks.pkbSystemReminder", () => {
5037
5120
  });
5038
5121
 
5039
5122
  test("not captured in minimal mode", async () => {
5123
+ seedPkbContent();
5040
5124
  const { blocks } = await applyRuntimeInjections(baseMessages, {
5041
- pkbActive: true,
5042
5125
  mode: "minimal",
5043
5126
  });
5044
5127
 
@@ -5047,7 +5130,6 @@ describe("applyRuntimeInjections blocks.pkbSystemReminder", () => {
5047
5130
 
5048
5131
  test("not captured when PKB inactive", async () => {
5049
5132
  const { blocks } = await applyRuntimeInjections(baseMessages, {
5050
- pkbActive: false,
5051
5133
  mode: "full",
5052
5134
  });
5053
5135