@vellumai/assistant 0.8.8 → 0.8.9-dev.202606091926.ebb2d62

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 (490) hide show
  1. package/ARCHITECTURE.md +6 -6
  2. package/bun.lock +2 -2
  3. package/docs/activation-funnel-telemetry.md +310 -0
  4. package/examples/plugins/echo/README.md +61 -60
  5. package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
  6. package/examples/plugins/echo/hooks/stop.ts +16 -0
  7. package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
  8. package/examples/plugins/echo/package.json +1 -2
  9. package/examples/plugins/echo/src/emit.ts +19 -0
  10. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
  11. package/openapi.yaml +273 -121
  12. package/package.json +2 -2
  13. package/scripts/sync-llm-catalog.ts +2 -0
  14. package/src/__tests__/activation-early-marking.test.ts +120 -0
  15. package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
  16. package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
  17. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
  18. package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
  19. package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
  20. package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
  21. package/src/__tests__/agent-loop-thinking.test.ts +36 -20
  22. package/src/__tests__/agent-loop.test.ts +441 -96
  23. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
  24. package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
  25. package/src/__tests__/anthropic-provider.test.ts +23 -8
  26. package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
  27. package/src/__tests__/app-control-flow.test.ts +1 -1
  28. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  29. package/src/__tests__/app-executors.test.ts +132 -0
  30. package/src/__tests__/approval-cascade.test.ts +6 -5
  31. package/src/__tests__/approval-routes-http.test.ts +4 -1
  32. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
  33. package/src/__tests__/build-persisted-content.test.ts +75 -1
  34. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  35. package/src/__tests__/channel-approvals.test.ts +1 -1
  36. package/src/__tests__/compaction-circuit.test.ts +258 -0
  37. package/src/__tests__/compaction-direct.test.ts +146 -0
  38. package/src/__tests__/compaction-events.test.ts +7 -7
  39. package/src/__tests__/compaction.benchmark.test.ts +1 -1
  40. package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
  41. package/src/__tests__/config-managed-gemini-defaults.test.ts +2 -46
  42. package/src/__tests__/context-overflow-reducer.test.ts +265 -125
  43. package/src/__tests__/context-window-manager-compact-retry.test.ts +121 -15
  44. package/src/__tests__/conversation-abort-tool-results.test.ts +7 -5
  45. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
  46. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
  47. package/src/__tests__/conversation-agent-loop-overflow.test.ts +158 -234
  48. package/src/__tests__/conversation-agent-loop.test.ts +342 -623
  49. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  50. package/src/__tests__/conversation-confirmation-signals.test.ts +6 -5
  51. package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
  52. package/src/__tests__/conversation-error.test.ts +15 -1
  53. package/src/__tests__/conversation-history-web-search.test.ts +6 -1
  54. package/src/__tests__/conversation-media-retry.test.ts +1 -1
  55. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +44 -4
  56. package/src/__tests__/conversation-process-callsite.test.ts +15 -15
  57. package/src/__tests__/conversation-provider-retry-repair.test.ts +66 -65
  58. package/src/__tests__/conversation-queue.test.ts +10 -10
  59. package/src/__tests__/conversation-runtime-assembly.test.ts +1059 -231
  60. package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
  61. package/src/__tests__/conversation-slash-queue.test.ts +7 -5
  62. package/src/__tests__/conversation-slash-unknown.test.ts +7 -5
  63. package/src/__tests__/conversation-speed-override.test.ts +11 -10
  64. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  65. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +395 -0
  66. package/src/__tests__/conversation-surfaces-app-control.test.ts +48 -1
  67. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +73 -4
  68. package/src/__tests__/conversation-undo.test.ts +2 -2
  69. package/src/__tests__/conversation-workspace-cache-state.test.ts +24 -21
  70. package/src/__tests__/conversation-workspace-injection.test.ts +69 -7
  71. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +15 -12
  72. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  73. package/src/__tests__/corrected-target.test.ts +93 -0
  74. package/src/__tests__/credential-execution-feature-gates.test.ts +5 -4
  75. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  76. package/src/__tests__/cu-unified-flow.test.ts +36 -0
  77. package/src/__tests__/db-acp-history.test.ts +101 -0
  78. package/src/__tests__/dynamic-page-surface.test.ts +31 -0
  79. package/src/__tests__/embedding-managed-proxy-selection.test.ts +6 -40
  80. package/src/__tests__/empty-response-hook.test.ts +1 -1
  81. package/src/__tests__/file-write-tool.test.ts +63 -0
  82. package/src/__tests__/gateway-only-guard.test.ts +17 -2
  83. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  84. package/src/__tests__/guardian-routing-invariants.test.ts +93 -4
  85. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  86. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  87. package/src/__tests__/heartbeat-service.test.ts +1 -0
  88. package/src/__tests__/history-repair-hook.test.ts +5 -1
  89. package/src/__tests__/host-app-control-proxy.test.ts +45 -0
  90. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  91. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  92. package/src/__tests__/inference-profile-reaper.test.ts +62 -0
  93. package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
  94. package/src/__tests__/injector-background-turn.test.ts +13 -23
  95. package/src/__tests__/injector-chain.test.ts +268 -44
  96. package/src/__tests__/injector-disk-pressure.test.ts +210 -52
  97. package/src/__tests__/injector-document-comments.test.ts +97 -114
  98. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  99. package/src/__tests__/injector-v3-suppression.test.ts +4 -4
  100. package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
  101. package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
  102. package/src/__tests__/llm-catalog-parity.test.ts +4 -0
  103. package/src/__tests__/llm-resolver.test.ts +73 -0
  104. package/src/__tests__/memory-retrieval-hook.test.ts +156 -38
  105. package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
  106. package/src/__tests__/notification-decision-strategy.test.ts +3 -3
  107. package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
  108. package/src/__tests__/persist-unsendable-image-downscale.test.ts +145 -0
  109. package/src/__tests__/persist-unsendable-image.test.ts +97 -1
  110. package/src/__tests__/persistence-secret-redaction.test.ts +78 -0
  111. package/src/__tests__/plugin-api-shim.test.ts +6 -9
  112. package/src/__tests__/plugin-bootstrap.test.ts +91 -81
  113. package/src/__tests__/plugin-registry.test.ts +3 -49
  114. package/src/__tests__/plugin-skill-contribution.test.ts +15 -14
  115. package/src/__tests__/plugin-tool-contribution.test.ts +7 -4
  116. package/src/__tests__/plugin-types.test.ts +0 -70
  117. package/src/__tests__/post-turn-tool-result-truncation.test.ts +69 -0
  118. package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
  119. package/src/__tests__/published-app-updater.test.ts +138 -0
  120. package/src/__tests__/reaction-persistence.test.ts +1 -1
  121. package/src/__tests__/retry-thinking-adaptive-only.test.ts +245 -0
  122. package/src/__tests__/send-endpoint-busy.test.ts +4 -1
  123. package/src/__tests__/server-history-render.test.ts +39 -0
  124. package/src/__tests__/skill-feature-flags-integration.test.ts +31 -0
  125. package/src/__tests__/steer-tool-repair.test.ts +1 -1
  126. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  127. package/src/__tests__/subagent-detail.test.ts +25 -7
  128. package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
  129. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  130. package/src/__tests__/subagent-manager-notify.test.ts +1 -3
  131. package/src/__tests__/subagent-notify-parent.test.ts +1 -3
  132. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  133. package/src/__tests__/title-generate-hook.test.ts +5 -1
  134. package/src/__tests__/tool-error-hook.test.ts +1 -1
  135. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
  136. package/src/__tests__/tool-start-timestamp.test.ts +218 -0
  137. package/src/__tests__/user-plugin-loader.test.ts +54 -286
  138. package/src/__tests__/web-fetch.test.ts +45 -0
  139. package/src/acp/__tests__/agent-process.test.ts +161 -0
  140. package/src/acp/__tests__/client-handler.test.ts +40 -0
  141. package/src/acp/__tests__/helpers/acp-config-stub.ts +0 -2
  142. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  143. package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
  144. package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
  145. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  146. package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
  147. package/src/acp/agent-process.ts +61 -1
  148. package/src/acp/auto-install.test.ts +280 -0
  149. package/src/acp/auto-install.ts +232 -0
  150. package/src/acp/client-handler.ts +31 -0
  151. package/src/acp/prepare-agent-env.ts +80 -27
  152. package/src/acp/resolve-agent.test.ts +188 -28
  153. package/src/acp/resolve-agent.ts +119 -42
  154. package/src/acp/resume-hint.ts +23 -0
  155. package/src/acp/session-manager.ts +507 -73
  156. package/src/agent/compaction-circuit.ts +60 -102
  157. package/src/agent/loop.ts +403 -251
  158. package/src/api/events/tool-result.ts +9 -0
  159. package/src/api/events/tool-use-start.ts +7 -0
  160. package/src/api/responses/conversation-message.ts +72 -13
  161. package/src/api/responses/memory-v3-selection-log.ts +19 -10
  162. package/src/approvals/guardian-request-resolvers.ts +27 -1
  163. package/src/background-wake/next-wake.ts +1 -0
  164. package/src/cli/commands/__tests__/memory-v3.test.ts +191 -210
  165. package/src/cli/commands/channel-verification-sessions.ts +6 -6
  166. package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
  167. package/src/cli/commands/memory-v3.ts +57 -199
  168. package/src/cli/commands/plugins.ts +43 -37
  169. package/src/cli/lib/__tests__/install-from-github.test.ts +790 -111
  170. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
  171. package/src/cli/lib/__tests__/plugin-details.test.ts +381 -0
  172. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +270 -0
  173. package/src/cli/lib/__tests__/search-plugins.test.ts +233 -32
  174. package/src/cli/lib/install-from-github.ts +797 -60
  175. package/src/cli/lib/plugin-catalog-cache.ts +84 -0
  176. package/src/cli/lib/plugin-details.ts +416 -0
  177. package/src/cli/lib/plugin-marketplace.ts +215 -0
  178. package/src/cli/lib/search-plugins.ts +201 -29
  179. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  180. package/src/config/acp-defaults.test.ts +10 -0
  181. package/src/config/acp-defaults.ts +9 -3
  182. package/src/config/acp-schema.ts +1 -7
  183. package/src/config/bundled-skills/acp/SKILL.md +80 -41
  184. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  185. package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
  186. package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
  187. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  188. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  189. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  190. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  191. package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -0
  192. package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
  193. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  194. package/src/config/bundled-tool-registry.ts +4 -0
  195. package/src/config/call-site-defaults.ts +0 -3
  196. package/src/config/feature-flag-registry.json +10 -56
  197. package/src/config/llm-resolver.ts +39 -7
  198. package/src/config/loader.ts +5 -22
  199. package/src/config/schemas/__tests__/memory-v3.test.ts +25 -9
  200. package/src/config/schemas/call-site-catalog.ts +0 -21
  201. package/src/config/schemas/heartbeat.ts +9 -0
  202. package/src/config/schemas/llm.ts +17 -3
  203. package/src/config/schemas/memory-v3.ts +58 -8
  204. package/src/config/seed-inference-profiles.ts +18 -0
  205. package/src/context/compactor.ts +22 -4
  206. package/src/context/post-turn-tool-result-truncation.ts +39 -1
  207. package/src/context/strip-injections.ts +8 -2
  208. package/src/daemon/conversation-agent-loop-handlers.ts +120 -42
  209. package/src/daemon/conversation-agent-loop.ts +308 -1297
  210. package/src/daemon/conversation-error.ts +31 -4
  211. package/src/daemon/conversation-history.ts +1 -1
  212. package/src/daemon/conversation-lifecycle.ts +11 -255
  213. package/src/daemon/conversation-media-retry.ts +19 -6
  214. package/src/daemon/conversation-messaging.ts +17 -0
  215. package/src/daemon/conversation-process.ts +22 -141
  216. package/src/daemon/conversation-queue-manager.ts +8 -0
  217. package/src/daemon/conversation-registry.ts +159 -0
  218. package/src/daemon/conversation-runtime-assembly.ts +361 -393
  219. package/src/daemon/conversation-store.ts +9 -90
  220. package/src/daemon/conversation-surfaces.ts +165 -11
  221. package/src/daemon/conversation-workspace.ts +17 -0
  222. package/src/daemon/conversation.ts +444 -62
  223. package/src/daemon/disk-pressure-policy.ts +0 -1
  224. package/src/daemon/external-plugins-bootstrap.ts +36 -46
  225. package/src/daemon/handlers/config-channels.ts +11 -2
  226. package/src/daemon/handlers/conversations.ts +3 -1
  227. package/src/daemon/handlers/shared.ts +9 -1
  228. package/src/daemon/handlers/skills.ts +4 -1
  229. package/src/daemon/host-app-control-proxy.ts +72 -57
  230. package/src/daemon/host-proxy-preactivation.ts +1 -3
  231. package/src/daemon/lifecycle.ts +21 -7
  232. package/src/daemon/persist-unsendable-image.ts +62 -25
  233. package/src/daemon/process-message.ts +1 -1
  234. package/src/daemon/server.ts +2 -0
  235. package/src/daemon/tool-side-effects.ts +15 -0
  236. package/src/daemon/wake-conversation-ops.ts +269 -0
  237. package/src/embedded/plugin-api.ts +2 -2
  238. package/src/export/__tests__/transcript-formatter.test.ts +5 -0
  239. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
  240. package/src/heartbeat/heartbeat-run-store.ts +23 -1
  241. package/src/heartbeat/heartbeat-service.ts +26 -0
  242. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  243. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  244. package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
  245. package/src/ipc/skill-routes/memory.ts +4 -2
  246. package/src/memory/__tests__/activation-session-store.test.ts +41 -0
  247. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
  248. package/src/memory/__tests__/onboarding-events-store.test.ts +80 -0
  249. package/src/memory/activation-session-store.ts +43 -0
  250. package/src/memory/conversation-crud.ts +29 -19
  251. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  252. package/src/memory/db-init.ts +6 -0
  253. package/src/memory/embedding-backend.ts +5 -22
  254. package/src/memory/job-handlers/conversation-starters.ts +13 -2
  255. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
  256. package/src/memory/jobs-worker.ts +25 -1
  257. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  258. package/src/memory/migrations/273-onboarding-events-funnel-columns.ts +46 -0
  259. package/src/memory/migrations/274-create-activation-sessions.ts +15 -0
  260. package/src/memory/migrations/index.ts +3 -0
  261. package/src/memory/onboarding-events-store.ts +66 -18
  262. package/src/memory/schema/acp.ts +4 -0
  263. package/src/memory/schema/infrastructure.ts +13 -0
  264. package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -97
  265. package/src/memory/v2/__tests__/page-store.test.ts +22 -0
  266. package/src/memory/v2/consolidation-job.ts +2 -63
  267. package/src/memory/v2/types.ts +5 -0
  268. package/src/messaging/providers/telegram-bot/api.ts +14 -5
  269. package/src/notifications/__tests__/copy-composer.test.ts +244 -0
  270. package/src/notifications/access-request-copy.ts +298 -0
  271. package/src/notifications/adapters/slack.ts +3 -3
  272. package/src/notifications/adapters/telegram.ts +9 -2
  273. package/src/notifications/copy-composer.ts +49 -267
  274. package/src/notifications/decision-engine.ts +16 -35
  275. package/src/notifications/home-feed-side-effect.ts +1 -6
  276. package/src/plugin-api/constants.ts +4 -0
  277. package/src/plugin-api/index.ts +40 -11
  278. package/src/plugin-api/types.ts +108 -0
  279. package/src/plugins/defaults/compaction/compact.ts +106 -0
  280. package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +250 -42
  281. package/src/plugins/defaults/compaction/corrected-target.ts +53 -0
  282. package/src/plugins/defaults/compaction/manager-store.ts +57 -0
  283. package/src/plugins/defaults/compaction/package.json +1 -2
  284. package/src/{context → plugins/defaults/compaction}/window-manager.ts +95 -25
  285. package/src/plugins/defaults/empty-response/package.json +0 -1
  286. package/src/plugins/defaults/history-repair/package.json +0 -1
  287. package/src/plugins/defaults/index.ts +156 -26
  288. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
  289. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +285 -0
  290. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  291. package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
  292. package/src/plugins/defaults/memory-retrieval/package.json +14 -0
  293. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
  294. package/src/plugins/defaults/memory-v3-shadow/__tests__/capabilities.test.ts +71 -0
  295. package/src/plugins/defaults/memory-v3-shadow/__tests__/dense.test.ts +181 -0
  296. package/src/plugins/defaults/memory-v3-shadow/__tests__/edge.test.ts +247 -0
  297. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +147 -134
  298. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +456 -0
  299. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +662 -0
  300. package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +306 -0
  301. package/src/plugins/defaults/memory-v3-shadow/__tests__/render-injection.test.ts +91 -0
  302. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-dense-store.test.ts +402 -0
  303. package/src/plugins/defaults/memory-v3-shadow/__tests__/section-needle.test.ts +135 -0
  304. package/src/plugins/defaults/memory-v3-shadow/__tests__/sections.test.ts +125 -0
  305. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +74 -19
  306. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-integration.test.ts +446 -0
  307. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +592 -0
  308. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -24
  309. package/src/plugins/defaults/memory-v3-shadow/capabilities.ts +91 -0
  310. package/src/plugins/defaults/memory-v3-shadow/dense.ts +97 -0
  311. package/src/plugins/defaults/memory-v3-shadow/edge.ts +252 -0
  312. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  313. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  314. package/src/plugins/defaults/memory-v3-shadow/injector.ts +76 -0
  315. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +555 -0
  316. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +266 -0
  317. package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
  318. package/src/plugins/defaults/memory-v3-shadow/page-content.ts +71 -0
  319. package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +204 -0
  320. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +16 -8
  321. package/src/plugins/defaults/memory-v3-shadow/section-dense-store.ts +236 -0
  322. package/src/plugins/defaults/memory-v3-shadow/section-needle.ts +200 -0
  323. package/src/plugins/defaults/memory-v3-shadow/sections.ts +115 -0
  324. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +156 -0
  325. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +382 -0
  326. package/src/plugins/defaults/memory-v3-shadow/types.ts +92 -0
  327. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +4 -1
  328. package/src/plugins/defaults/title-generate/package.json +0 -1
  329. package/src/plugins/defaults/tool-error/package.json +0 -1
  330. package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
  331. package/src/plugins/external-api.ts +12 -2
  332. package/src/plugins/pipeline.ts +6 -293
  333. package/src/plugins/registry.ts +9 -37
  334. package/src/plugins/types.ts +76 -381
  335. package/src/plugins/user-loader.ts +30 -127
  336. package/src/prompts/__tests__/system-prompt.test.ts +6 -0
  337. package/src/prompts/system-prompt.ts +61 -10
  338. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +71 -4
  339. package/src/providers/anthropic/client.ts +9 -10
  340. package/src/providers/inference/kimi-cjk-token-ids.ts +493 -0
  341. package/src/providers/inference/logit-bias.ts +55 -0
  342. package/src/providers/model-catalog.ts +57 -0
  343. package/src/providers/openai/__tests__/vision-not-supported.test.ts +75 -0
  344. package/src/providers/openai/chat-completions-provider.ts +44 -1
  345. package/src/providers/retry.ts +57 -7
  346. package/src/providers/types.ts +6 -0
  347. package/src/runtime/__tests__/agent-wake.test.ts +555 -691
  348. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  349. package/src/runtime/agent-wake.ts +108 -209
  350. package/src/runtime/assistant-event-hub.ts +1 -1
  351. package/src/runtime/channel-approvals.ts +1 -1
  352. package/src/runtime/interactive-ui.ts +1 -1
  353. package/src/runtime/routes/__tests__/acp-routes.test.ts +466 -55
  354. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  355. package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
  356. package/src/runtime/routes/__tests__/stt-routes.test.ts +112 -0
  357. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  358. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
  359. package/src/runtime/routes/acp-routes.test.ts +185 -32
  360. package/src/runtime/routes/acp-routes.ts +328 -30
  361. package/src/runtime/routes/app-management-routes.ts +3 -0
  362. package/src/runtime/routes/approval-routes.ts +1 -1
  363. package/src/runtime/routes/browser-routes.ts +1 -1
  364. package/src/runtime/routes/browser-tabs-routes.ts +6 -10
  365. package/src/runtime/routes/channel-verification-routes.ts +14 -5
  366. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  367. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  368. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  369. package/src/runtime/routes/conversation-routes.ts +30 -2
  370. package/src/runtime/routes/conversation-starter-routes.ts +13 -7
  371. package/src/runtime/routes/conversations-import-routes.ts +24 -7
  372. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  373. package/src/runtime/routes/host-cu-routes.ts +1 -1
  374. package/src/runtime/routes/identity-routes.ts +18 -3
  375. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  376. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +33 -34
  377. package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
  378. package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
  379. package/src/runtime/routes/memory-v3-routes.ts +65 -305
  380. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +1 -1
  381. package/src/runtime/routes/playground/helpers.ts +1 -1
  382. package/src/runtime/routes/plugins-routes.ts +337 -35
  383. package/src/runtime/routes/stt-routes.ts +45 -12
  384. package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
  385. package/src/runtime/routes/work-items-routes.ts +2 -4
  386. package/src/runtime/routes/workspace-routes.ts +50 -15
  387. package/src/runtime/services/conversation-serializer.ts +1 -1
  388. package/src/runtime/verification-outbound-actions.ts +147 -2
  389. package/src/runtime/verification-templates.ts +29 -3
  390. package/src/services/published-app-updater.ts +30 -8
  391. package/src/signals/cancel.ts +2 -4
  392. package/src/subagent/manager.ts +21 -5
  393. package/src/telemetry/__tests__/activation-funnel.test.ts +95 -0
  394. package/src/telemetry/activation-funnel.ts +167 -0
  395. package/src/telemetry/types.ts +13 -0
  396. package/src/telemetry/usage-telemetry-reporter.test.ts +154 -0
  397. package/src/telemetry/usage-telemetry-reporter.ts +26 -1
  398. package/src/tools/acp/context.ts +20 -0
  399. package/src/tools/acp/list-agents.test.ts +9 -19
  400. package/src/tools/acp/list-agents.ts +3 -15
  401. package/src/tools/acp/spawn.test.ts +173 -202
  402. package/src/tools/acp/spawn.ts +37 -172
  403. package/src/tools/acp/steer.test.ts +105 -8
  404. package/src/tools/acp/steer.ts +48 -17
  405. package/src/tools/apps/executors.ts +166 -50
  406. package/src/tools/browser/browser-execution.ts +12 -2
  407. package/src/tools/filesystem/write.ts +34 -0
  408. package/src/tools/network/web-fetch.ts +65 -24
  409. package/src/tools/skills/load.ts +1 -1
  410. package/src/tools/subagent/spawn.ts +2 -4
  411. package/src/tools/ui-surface/definitions.ts +32 -5
  412. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
  413. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
  414. package/docs/plugins.md +0 -832
  415. package/examples/plugins/echo/register.ts +0 -143
  416. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  417. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  418. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
  419. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
  420. package/src/__tests__/pipeline-runner.test.ts +0 -554
  421. package/src/daemon/wake-target-adapter.ts +0 -253
  422. package/src/memory/v3/__tests__/assign.test.ts +0 -242
  423. package/src/memory/v3/__tests__/capabilities.test.ts +0 -118
  424. package/src/memory/v3/__tests__/core.test.ts +0 -39
  425. package/src/memory/v3/__tests__/health.test.ts +0 -219
  426. package/src/memory/v3/__tests__/maintain-job.test.ts +0 -288
  427. package/src/memory/v3/__tests__/needle.test.ts +0 -107
  428. package/src/memory/v3/__tests__/orchestrate.test.ts +0 -436
  429. package/src/memory/v3/__tests__/provider-blocks.test.ts +0 -13
  430. package/src/memory/v3/__tests__/reconcile.test.ts +0 -274
  431. package/src/memory/v3/__tests__/render-injection.test.ts +0 -61
  432. package/src/memory/v3/__tests__/router.test.ts +0 -332
  433. package/src/memory/v3/__tests__/selector.test.ts +0 -470
  434. package/src/memory/v3/__tests__/shadow-plugin.test.ts +0 -432
  435. package/src/memory/v3/__tests__/snapshot.test.ts +0 -168
  436. package/src/memory/v3/__tests__/tree.test.ts +0 -192
  437. package/src/memory/v3/assign.ts +0 -268
  438. package/src/memory/v3/capabilities.ts +0 -124
  439. package/src/memory/v3/core.ts +0 -26
  440. package/src/memory/v3/health.ts +0 -0
  441. package/src/memory/v3/maintain-job.ts +0 -314
  442. package/src/memory/v3/needle.ts +0 -115
  443. package/src/memory/v3/orchestrate.ts +0 -126
  444. package/src/memory/v3/page-content.ts +0 -34
  445. package/src/memory/v3/provider-blocks.ts +0 -26
  446. package/src/memory/v3/reconcile.ts +0 -523
  447. package/src/memory/v3/router.ts +0 -190
  448. package/src/memory/v3/selection-log-store.ts +0 -84
  449. package/src/memory/v3/selector.ts +0 -226
  450. package/src/memory/v3/shadow-plugin.ts +0 -411
  451. package/src/memory/v3/snapshot.ts +0 -209
  452. package/src/memory/v3/tree.ts +0 -174
  453. package/src/memory/v3/types.ts +0 -59
  454. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +0 -187
  455. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
  456. package/src/plugins/defaults/circuit-breaker/package.json +0 -15
  457. package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
  458. package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
  459. package/src/plugins/defaults/compaction/register.ts +0 -35
  460. package/src/plugins/defaults/compaction/terminal.ts +0 -73
  461. package/src/plugins/defaults/empty-response/register.ts +0 -23
  462. package/src/plugins/defaults/history-repair/register.ts +0 -24
  463. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +0 -216
  464. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
  465. package/src/plugins/defaults/overflow-reduce/package.json +0 -15
  466. package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
  467. package/src/plugins/defaults/title-generate/register.ts +0 -35
  468. package/src/plugins/defaults/tool-error/register.ts +0 -23
  469. package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
  470. package/src/proactive-artifact/aux-message-injector.ts +0 -97
  471. package/src/proactive-artifact/decision.test.ts +0 -226
  472. package/src/proactive-artifact/decision.ts +0 -165
  473. package/src/proactive-artifact/index.ts +0 -7
  474. package/src/proactive-artifact/job.test.ts +0 -962
  475. package/src/proactive-artifact/job.ts +0 -372
  476. package/src/proactive-artifact/message-copy.ts +0 -58
  477. package/src/proactive-artifact/trigger-state.test.ts +0 -286
  478. package/src/proactive-artifact/trigger-state.ts +0 -123
  479. package/src/util/map-limit.ts +0 -27
  480. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
  481. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
  482. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
  483. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
  484. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
  485. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
  486. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
  487. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
  488. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
  489. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
  490. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
@@ -1,470 +0,0 @@
1
- /**
2
- * Tests for `assistant/src/memory/v3/selector.ts`.
3
- *
4
- * Coverage matrix:
5
- * - Returned IDs map to the right member slugs by 1-based index, with
6
- * `pinned` driven by `pinned_ids`.
7
- * - Omitted `ids` → ALL members of the leaf (recall-safe; bounded to one
8
- * leaf, so this stays a select-all unlike the L1 router).
9
- * - Explicit `ids: []` → no pages (deliberate abstention).
10
- * - No provider / missing tool_use / schema mismatch / throw → no pages
11
- * (degrade to the deterministic lanes), the last three after a re-prompt
12
- * retry; a malformed response that recovers on retry returns its pages.
13
- * - The per-leaf `<pages>` prefix is byte-identical across two calls with
14
- * different turns (the cache invariant).
15
- * - `selectAcrossLeaves` flattens per-leaf results and never exceeds the
16
- * configured concurrency.
17
- *
18
- * The provider is stubbed so no network calls fire.
19
- */
20
-
21
- import { beforeEach, describe, expect, mock, test } from "bun:test";
22
-
23
- import type {
24
- Message,
25
- Provider,
26
- ProviderResponse,
27
- SendMessageOptions,
28
- ToolUseContent,
29
- } from "../../../providers/types.js";
30
- import type {
31
- LeafNode,
32
- LeafPath,
33
- LeafTree,
34
- Slug,
35
- TurnContext,
36
- } from "../types.js";
37
-
38
- // ---------------------------------------------------------------------------
39
- // Mocks installed BEFORE the selector import so the module observes them at
40
- // load time.
41
- // ---------------------------------------------------------------------------
42
-
43
- let providerStub: Provider | null = null;
44
-
45
- interface ProviderCall {
46
- messages: Message[];
47
- options: SendMessageOptions | undefined;
48
- }
49
- const providerCalls: ProviderCall[] = [];
50
-
51
- mock.module("../../../providers/provider-send-message.js", () => ({
52
- getConfiguredProvider: async () => providerStub,
53
- extractToolUse: (response: ProviderResponse) =>
54
- response.content.find((b): b is ToolUseContent => b.type === "tool_use"),
55
- }));
56
-
57
- mock.module("../../../util/logger.js", () => ({
58
- getLogger: () =>
59
- new Proxy({} as Record<string, unknown>, {
60
- get: (_t, prop) => (prop === "child" ? () => ({}) : () => {}),
61
- }),
62
- }));
63
-
64
- const { selectFromLeaf, selectAcrossLeaves } = await import("../selector.js");
65
-
66
- // ---------------------------------------------------------------------------
67
- // Helpers.
68
- // ---------------------------------------------------------------------------
69
-
70
- function makeProvider(response: ProviderResponse): Provider {
71
- return {
72
- name: "stub",
73
- sendMessage: async (messages, options) => {
74
- providerCalls.push({ messages, options });
75
- return response;
76
- },
77
- };
78
- }
79
-
80
- function toolUseResponse(input: Record<string, unknown>): ProviderResponse {
81
- return {
82
- model: "stub-model",
83
- stopReason: "tool_use",
84
- usage: { inputTokens: 0, outputTokens: 0 },
85
- content: [{ type: "tool_use", id: "tu-1", name: "select_pages", input }],
86
- };
87
- }
88
-
89
- /** A 200 response that carries no tool_use — the malformed-but-successful case
90
- * the re-prompt retry exists to recover from. */
91
- function noToolResponse(): ProviderResponse {
92
- return {
93
- model: "stub-model",
94
- stopReason: "end_turn",
95
- usage: { inputTokens: 0, outputTokens: 0 },
96
- content: [{ type: "text", text: "no tool call" }],
97
- };
98
- }
99
-
100
- /** Provider returning a different response per call (the i-th call returns
101
- * responses[i], or the last entry once exhausted), recording each call so a
102
- * test can assert how many attempts were made. */
103
- function makeSequenceProvider(responses: ProviderResponse[]): Provider {
104
- let i = 0;
105
- return {
106
- name: "sequence",
107
- sendMessage: async (messages, options) => {
108
- providerCalls.push({ messages, options });
109
- const response = responses[Math.min(i, responses.length - 1)];
110
- i += 1;
111
- return response;
112
- },
113
- };
114
- }
115
-
116
- /** Provider that records each call and then throws — for the throw-after-retries
117
- * path (the provider's own RetryProvider has already exhausted its backoff). */
118
- function makeThrowingProvider(): Provider {
119
- return {
120
- name: "throwing",
121
- sendMessage: async (messages, options) => {
122
- providerCalls.push({ messages, options });
123
- throw new Error("boom");
124
- },
125
- };
126
- }
127
-
128
- function makeLeaf(path: LeafPath, members: Slug[]): LeafNode {
129
- return {
130
- path,
131
- frontmatter: { path, in_core: false },
132
- description: `description for ${path}`,
133
- members,
134
- domain: path.split("/")[0],
135
- };
136
- }
137
-
138
- /** Tree with two leaves; `people/alice` has three member pages. */
139
- function makeTree(): LeafTree {
140
- const leaves: LeafNode[] = [
141
- makeLeaf("people/alice", ["alice-bio", "alice-1on1", "alice-feedback"]),
142
- makeLeaf("projects/atlas", ["atlas-roadmap", "atlas-status"]),
143
- ];
144
- const byPage = new Map<Slug, LeafPath[]>();
145
- for (const leaf of leaves) {
146
- for (const slug of leaf.members) {
147
- byPage.set(slug, [...(byPage.get(slug) ?? []), leaf.path]);
148
- }
149
- }
150
- return {
151
- leaves: new Map(leaves.map((n) => [n.path, n])),
152
- byPage,
153
- };
154
- }
155
-
156
- const ALICE_MEMBERS = ["alice-bio", "alice-1on1", "alice-feedback"];
157
-
158
- function makeTurn(currentMessage: string): TurnContext {
159
- return {
160
- conversationId: "conv-xyz",
161
- turnNumber: 1,
162
- currentMessage,
163
- recentContext: "earlier we talked about the timeline",
164
- };
165
- }
166
-
167
- /** Deterministic summary stub so the rendered prefix is reproducible. */
168
- const summaryOf = async (slug: Slug): Promise<string> => `summary of ${slug}`;
169
-
170
- beforeEach(() => {
171
- providerStub = null;
172
- providerCalls.length = 0;
173
- });
174
-
175
- // ---------------------------------------------------------------------------
176
- // selectFromLeaf — id mapping.
177
- // ---------------------------------------------------------------------------
178
-
179
- describe("selectFromLeaf — id mapping", () => {
180
- test("returned IDs map to member slugs, pinned driven by pinned_ids", async () => {
181
- providerStub = makeProvider(
182
- toolUseResponse({ ids: [3, 1], pinned_ids: [1] }),
183
- );
184
- const result = await selectFromLeaf(
185
- "people/alice",
186
- makeTurn("how's alice?"),
187
- makeTree(),
188
- summaryOf,
189
- );
190
- expect(result).toEqual([
191
- { slug: "alice-feedback", pinned: false },
192
- { slug: "alice-bio", pinned: true },
193
- ]);
194
- });
195
-
196
- test("omitted ids selects ALL members (recall-safe)", async () => {
197
- providerStub = makeProvider(toolUseResponse({}));
198
- const result = await selectFromLeaf(
199
- "people/alice",
200
- makeTurn("anything"),
201
- makeTree(),
202
- summaryOf,
203
- );
204
- expect(result).toEqual(
205
- ALICE_MEMBERS.map((slug) => ({ slug, pinned: false })),
206
- );
207
- });
208
-
209
- test("explicit empty ids selects no pages (abstention)", async () => {
210
- providerStub = makeProvider(toolUseResponse({ ids: [] }));
211
- const result = await selectFromLeaf(
212
- "people/alice",
213
- makeTurn("nothing relevant"),
214
- makeTree(),
215
- summaryOf,
216
- );
217
- expect(result).toEqual([]);
218
- });
219
-
220
- test("out-of-range and duplicate IDs are ignored without throwing", async () => {
221
- providerStub = makeProvider(toolUseResponse({ ids: [2, 99, 0, -1, 2] }));
222
- const result = await selectFromLeaf(
223
- "people/alice",
224
- makeTurn("the 1:1"),
225
- makeTree(),
226
- summaryOf,
227
- );
228
- expect(result).toEqual([{ slug: "alice-1on1", pinned: false }]);
229
- });
230
-
231
- test("empty leaf returns no pages and never calls the provider", async () => {
232
- providerStub = makeProvider(toolUseResponse({ ids: [1] }));
233
- const result = await selectFromLeaf(
234
- "people/empty",
235
- makeTurn("hi"),
236
- {
237
- leaves: new Map([["people/empty", makeLeaf("people/empty", [])]]),
238
- byPage: new Map(),
239
- },
240
- summaryOf,
241
- );
242
- expect(result).toEqual([]);
243
- expect(providerCalls).toHaveLength(0);
244
- });
245
- });
246
-
247
- // ---------------------------------------------------------------------------
248
- // selectFromLeaf — recall-safe fallbacks.
249
- // ---------------------------------------------------------------------------
250
-
251
- describe("selectFromLeaf — degradation on failure", () => {
252
- test("no provider → no pages, without calling the provider", async () => {
253
- providerStub = null;
254
- const result = await selectFromLeaf(
255
- "people/alice",
256
- makeTurn("x"),
257
- makeTree(),
258
- summaryOf,
259
- );
260
- expect(result).toEqual([]);
261
- expect(providerCalls).toHaveLength(0);
262
- });
263
-
264
- test("missing tool_use → no pages after retrying", async () => {
265
- providerStub = makeProvider(noToolResponse());
266
- const result = await selectFromLeaf(
267
- "people/alice",
268
- makeTurn("x"),
269
- makeTree(),
270
- summaryOf,
271
- );
272
- expect(result).toEqual([]);
273
- expect(providerCalls).toHaveLength(3);
274
- });
275
-
276
- test("schema mismatch → no pages after retrying", async () => {
277
- providerStub = makeProvider(toolUseResponse({ ids: "not-an-array" }));
278
- const result = await selectFromLeaf(
279
- "people/alice",
280
- makeTurn("x"),
281
- makeTree(),
282
- summaryOf,
283
- );
284
- expect(result).toEqual([]);
285
- expect(providerCalls).toHaveLength(3);
286
- });
287
-
288
- test("provider throw → no pages after retrying", async () => {
289
- providerStub = makeThrowingProvider();
290
- const result = await selectFromLeaf(
291
- "people/alice",
292
- makeTurn("x"),
293
- makeTree(),
294
- summaryOf,
295
- );
296
- expect(result).toEqual([]);
297
- expect(providerCalls).toHaveLength(3);
298
- });
299
-
300
- test("a malformed response that recovers on retry returns its pages", async () => {
301
- providerStub = makeSequenceProvider([
302
- noToolResponse(),
303
- toolUseResponse({ ids: [2] }),
304
- ]);
305
- const result = await selectFromLeaf(
306
- "people/alice",
307
- makeTurn("the 1:1"),
308
- makeTree(),
309
- summaryOf,
310
- );
311
- expect(result).toEqual([{ slug: "alice-1on1", pinned: false }]);
312
- expect(providerCalls).toHaveLength(2);
313
- });
314
- });
315
-
316
- // ---------------------------------------------------------------------------
317
- // selectFromLeaf — request shape and cache invariant.
318
- // ---------------------------------------------------------------------------
319
-
320
- describe("selectFromLeaf — request shape", () => {
321
- test("forces tool_choice to select_pages with the v3 L2 call site", async () => {
322
- providerStub = makeProvider(toolUseResponse({ ids: [1] }));
323
- await selectFromLeaf(
324
- "people/alice",
325
- makeTurn("alice?"),
326
- makeTree(),
327
- summaryOf,
328
- );
329
-
330
- expect(providerCalls).toHaveLength(1);
331
- const [call] = providerCalls;
332
- const cfg = call.options?.config as Record<string, unknown>;
333
- expect(cfg?.callSite).toBe("memoryV3SelectL2");
334
- expect(cfg?.tool_choice).toEqual({ type: "tool", name: "select_pages" });
335
- expect(call.options?.tools?.[0]?.name).toBe("select_pages");
336
- });
337
-
338
- test("pages block is the first content block with an ephemeral cache breakpoint", async () => {
339
- providerStub = makeProvider(toolUseResponse({ ids: [1] }));
340
- await selectFromLeaf(
341
- "people/alice",
342
- makeTurn("alice?"),
343
- makeTree(),
344
- summaryOf,
345
- );
346
-
347
- const [blockA, blockB] = providerCalls[0].messages[0].content as Array<{
348
- type: string;
349
- text: string;
350
- cache_control?: { type: string; ttl?: string };
351
- }>;
352
- expect(blockA.type).toBe("text");
353
- expect(blockA.text).toContain("<leaf>people/alice</leaf>");
354
- expect(blockA.text).toContain("<pages>");
355
- expect(blockA.text).toContain("[1] alice-bio — summary of alice-bio");
356
- expect(blockA.cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
357
-
358
- expect(blockB.type).toBe("text");
359
- expect(blockB.text).toContain("<current_message>alice?</current_message>");
360
- expect(blockB.text).toContain("<recent_context>");
361
- expect(blockB.cache_control).toBeUndefined();
362
- });
363
-
364
- test("situational context renders in the per-turn block when present", async () => {
365
- providerStub = makeProvider(toolUseResponse({ ids: [1] }));
366
- await selectFromLeaf(
367
- "people/alice",
368
- {
369
- ...makeTurn("alice?"),
370
- situationalContext: "Today is Saturday. Alice's anniversary is today.",
371
- },
372
- makeTree(),
373
- summaryOf,
374
- );
375
- const blockB = providerCalls[0].messages[0].content[1] as { text: string };
376
- expect(blockB.text).toContain(
377
- "<situation>Today is Saturday. Alice's anniversary is today.</situation>",
378
- );
379
- });
380
-
381
- test("system prompt mentions pinned (locks the pinning commitment)", async () => {
382
- providerStub = makeProvider(toolUseResponse({ ids: [1] }));
383
- await selectFromLeaf("people/alice", makeTurn("x"), makeTree(), summaryOf);
384
- expect(providerCalls[0].options?.systemPrompt).toMatch(/pinned/);
385
- });
386
- });
387
-
388
- describe("selectFromLeaf — per-leaf cache invariant", () => {
389
- test("the pages prefix is byte-identical across two calls with different turns", async () => {
390
- const tree = makeTree();
391
- providerStub = makeProvider(toolUseResponse({ ids: [1] }));
392
-
393
- await selectFromLeaf(
394
- "people/alice",
395
- makeTurn("first query"),
396
- tree,
397
- summaryOf,
398
- );
399
- await selectFromLeaf(
400
- "people/alice",
401
- makeTurn("totally different second query"),
402
- tree,
403
- summaryOf,
404
- );
405
-
406
- const prefixA = (
407
- providerCalls[0].messages[0].content[0] as { text: string }
408
- ).text;
409
- const prefixB = (
410
- providerCalls[1].messages[0].content[0] as { text: string }
411
- ).text;
412
- expect(prefixA).toBe(prefixB);
413
- });
414
- });
415
-
416
- // ---------------------------------------------------------------------------
417
- // selectAcrossLeaves — fan-out and bounded concurrency.
418
- // ---------------------------------------------------------------------------
419
-
420
- describe("selectAcrossLeaves", () => {
421
- test("flattens per-leaf selections", async () => {
422
- // The selector forces the tool, so omitted ids → all members per leaf.
423
- providerStub = makeProvider(toolUseResponse({}));
424
- const result = await selectAcrossLeaves(
425
- ["people/alice", "projects/atlas"],
426
- makeTurn("x"),
427
- makeTree(),
428
- summaryOf,
429
- );
430
- expect(result.map((p) => p.slug)).toEqual([
431
- "alice-bio",
432
- "alice-1on1",
433
- "alice-feedback",
434
- "atlas-roadmap",
435
- "atlas-status",
436
- ]);
437
- });
438
-
439
- test("never exceeds the configured concurrency", async () => {
440
- let inFlight = 0;
441
- let maxInFlight = 0;
442
- let calls = 0;
443
- providerStub = {
444
- name: "tracking",
445
- sendMessage: async () => {
446
- calls++;
447
- inFlight++;
448
- maxInFlight = Math.max(maxInFlight, inFlight);
449
- await new Promise((r) => setTimeout(r, 5));
450
- inFlight--;
451
- return toolUseResponse({ ids: [] });
452
- },
453
- };
454
-
455
- // Build a tree with eight single-member leaves so there are eight calls.
456
- const leaves: LeafNode[] = Array.from({ length: 8 }, (_, i) =>
457
- makeLeaf(`misc/leaf-${i}`, [`page-${i}`]),
458
- );
459
- const tree: LeafTree = {
460
- leaves: new Map(leaves.map((n) => [n.path, n])),
461
- byPage: new Map(),
462
- };
463
- const paths = leaves.map((l) => l.path);
464
-
465
- await selectAcrossLeaves(paths, makeTurn("x"), tree, summaryOf, 3);
466
- expect(maxInFlight).toBeLessThanOrEqual(3);
467
- expect(maxInFlight).toBeGreaterThan(1);
468
- expect(calls).toBe(8);
469
- });
470
- });