@vellumai/assistant 0.8.6 → 0.8.7

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 (891) hide show
  1. package/AGENTS.md +4 -4
  2. package/Dockerfile +1 -0
  3. package/bun.lock +11 -2
  4. package/docker-entrypoint.sh +8 -6
  5. package/docs/plugins.md +63 -28
  6. package/examples/plugins/echo/register.ts +4 -7
  7. package/knip.json +1 -0
  8. package/node_modules/@vellumai/environments/bun.lock +24 -0
  9. package/node_modules/@vellumai/environments/package.json +18 -0
  10. package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +95 -0
  11. package/node_modules/@vellumai/environments/src/index.ts +11 -0
  12. package/node_modules/@vellumai/environments/src/seeds.ts +73 -0
  13. package/node_modules/@vellumai/environments/src/types.ts +70 -0
  14. package/node_modules/@vellumai/environments/tsconfig.json +20 -0
  15. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +11 -0
  16. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +3 -4
  17. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +6 -2
  18. package/openapi.yaml +3735 -353
  19. package/package.json +7 -3
  20. package/scripts/generate-openapi.ts +20 -13
  21. package/src/__tests__/agent-loop-callsite-precedence.test.ts +42 -80
  22. package/src/__tests__/agent-loop-exit-reason.test.ts +240 -39
  23. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +141 -0
  24. package/src/__tests__/agent-loop-override-profile.test.ts +19 -32
  25. package/src/__tests__/agent-loop-provider-error-recording.test.ts +6 -4
  26. package/src/__tests__/agent-loop-thinking.test.ts +17 -12
  27. package/src/__tests__/agent-loop.test.ts +207 -341
  28. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +4 -2
  29. package/src/__tests__/agent-wake-override-profile.test.ts +22 -40
  30. package/src/__tests__/anthropic-provider.test.ts +201 -55
  31. package/src/__tests__/app-builder-skill-instructions.test.ts +22 -0
  32. package/src/__tests__/app-control-flow.test.ts +5 -0
  33. package/src/__tests__/approval-cascade.test.ts +4 -11
  34. package/src/__tests__/approval-routes-http.test.ts +4 -2
  35. package/src/__tests__/assistant-event.test.ts +15 -0
  36. package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
  37. package/src/__tests__/avatar-e2e.test.ts +7 -37
  38. package/src/__tests__/avatar-generator.test.ts +12 -42
  39. package/src/__tests__/avatar-identity-sync.test.ts +28 -3
  40. package/src/__tests__/background-shell-bash.test.ts +3 -7
  41. package/src/__tests__/btw-routes.test.ts +7 -12
  42. package/src/__tests__/call-pointer-messages.test.ts +5 -3
  43. package/src/__tests__/call-site-routing-provider.test.ts +22 -40
  44. package/src/__tests__/catalog-files.test.ts +1 -0
  45. package/src/__tests__/channel-approval-routes.test.ts +48 -20
  46. package/src/__tests__/channel-approvals.test.ts +3 -1
  47. package/src/__tests__/channel-invite-transport.test.ts +1 -5
  48. package/src/__tests__/channel-readiness-routes.test.ts +0 -4
  49. package/src/__tests__/channel-readiness-slack-remote.test.ts +2 -7
  50. package/src/__tests__/channel-retry-sweep.test.ts +71 -79
  51. package/src/__tests__/circuit-breaker-pipeline.test.ts +3 -3
  52. package/src/__tests__/clawhub-files.test.ts +1 -0
  53. package/src/__tests__/compaction-events.test.ts +5 -17
  54. package/src/__tests__/compaction-pipeline.test.ts +1 -1
  55. package/src/__tests__/compaction-timeout-recovery.test.ts +37 -48
  56. package/src/__tests__/compaction-trail-store.test.ts +1 -79
  57. package/src/__tests__/compactor-image-manifest-trust.test.ts +112 -0
  58. package/src/__tests__/computer-use-tools.test.ts +2 -2
  59. package/src/__tests__/config-watcher.test.ts +28 -0
  60. package/src/__tests__/context-search-agent-runner.test.ts +6 -3
  61. package/src/__tests__/context-token-estimator.test.ts +34 -0
  62. package/src/__tests__/context-window-manager-compact-retry.test.ts +291 -0
  63. package/src/__tests__/conversation-abort-tool-results.test.ts +14 -7
  64. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -2
  65. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +12 -27
  66. package/src/__tests__/conversation-agent-loop-overflow.test.ts +430 -90
  67. package/src/__tests__/conversation-agent-loop.test.ts +581 -62
  68. package/src/__tests__/conversation-analysis-routes.test.ts +1 -3
  69. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
  70. package/src/__tests__/conversation-clear-safety.test.ts +20 -10
  71. package/src/__tests__/conversation-confirmation-signals.test.ts +15 -45
  72. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  73. package/src/__tests__/conversation-disk-view.test.ts +10 -17
  74. package/src/__tests__/conversation-fork-crud.test.ts +86 -172
  75. package/src/__tests__/conversation-fork-route.test.ts +16 -14
  76. package/src/__tests__/conversation-init.benchmark.test.ts +6 -6
  77. package/src/__tests__/conversation-lifecycle.test.ts +3 -2
  78. package/src/__tests__/conversation-load-history-repair.test.ts +3 -2
  79. package/src/__tests__/conversation-load-history-stripped.test.ts +1 -1
  80. package/src/__tests__/conversation-message-sync-tags.test.ts +3 -4
  81. package/src/__tests__/conversation-pairing.test.ts +34 -4
  82. package/src/__tests__/conversation-pre-run-repair.test.ts +1 -1
  83. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -0
  84. package/src/__tests__/conversation-process-callsite.test.ts +27 -30
  85. package/src/__tests__/conversation-provider-retry-repair.test.ts +53 -44
  86. package/src/__tests__/conversation-queue.test.ts +270 -164
  87. package/src/__tests__/conversation-routes-disk-view.test.ts +3 -2
  88. package/src/__tests__/conversation-routes-guardian-reply.test.ts +2 -2
  89. package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -2
  90. package/src/__tests__/conversation-runtime-assembly.test.ts +20 -22
  91. package/src/__tests__/conversation-runtime-workspace.test.ts +19 -1
  92. package/src/__tests__/conversation-slash-queue.test.ts +37 -31
  93. package/src/__tests__/conversation-slash-unknown.test.ts +13 -15
  94. package/src/__tests__/conversation-speed-override.test.ts +8 -22
  95. package/src/__tests__/conversation-stream-state.test.ts +484 -0
  96. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +6 -15
  97. package/src/__tests__/conversation-surfaces-app-control.test.ts +32 -4
  98. package/src/__tests__/conversation-surfaces-state-update.test.ts +5 -2
  99. package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -15
  100. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +23 -11
  101. package/src/__tests__/conversation-unread-route.test.ts +14 -2
  102. package/src/__tests__/conversation-usage.test.ts +0 -2
  103. package/src/__tests__/conversation-wipe.test.ts +1 -1
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +3 -1
  105. package/src/__tests__/conversation-workspace-injection.test.ts +48 -22
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +27 -7
  107. package/src/__tests__/credential-execution-tools.test.ts +1 -2
  108. package/src/__tests__/credential-security-invariants.test.ts +0 -1
  109. package/src/__tests__/cross-provider-web-search.test.ts +6 -2
  110. package/src/__tests__/cu-unified-flow.test.ts +26 -1
  111. package/src/__tests__/db-schedule-syntax-migration.test.ts +11 -0
  112. package/src/__tests__/disk-pressure-guard.test.ts +66 -0
  113. package/src/__tests__/disk-pressure-routes.test.ts +9 -2
  114. package/src/__tests__/dm-persistence.test.ts +7 -2
  115. package/src/__tests__/dynamic-page-surface.test.ts +68 -0
  116. package/src/__tests__/edit-propagation.test.ts +1 -2
  117. package/src/__tests__/empty-response-pipeline.test.ts +127 -5
  118. package/src/__tests__/filing-service.test.ts +2 -2
  119. package/src/__tests__/first-greeting.test.ts +55 -14
  120. package/src/__tests__/gemini-inline-media.test.ts +78 -0
  121. package/src/__tests__/gemini-provider.test.ts +351 -28
  122. package/src/__tests__/guardian-routing-state.test.ts +60 -71
  123. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +9 -7
  124. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  125. package/src/__tests__/heartbeat-service.test.ts +2 -1
  126. package/src/__tests__/history-repair-hook.test.ts +161 -0
  127. package/src/__tests__/history-repair-observability.test.ts +1 -1
  128. package/src/__tests__/history-repair.test.ts +2 -1
  129. package/src/__tests__/host-app-control-proxy.test.ts +2 -0
  130. package/src/__tests__/host-cu-proxy.test.ts +2 -0
  131. package/src/__tests__/host-file-edit-tool.test.ts +4 -2
  132. package/src/__tests__/host-file-proxy.test.ts +31 -0
  133. package/src/__tests__/host-file-read-tool.test.ts +4 -2
  134. package/src/__tests__/host-file-write-tool.test.ts +9 -3
  135. package/src/__tests__/host-proxy-preactivation.test.ts +53 -14
  136. package/src/__tests__/host-shell-tool.test.ts +9 -4
  137. package/src/__tests__/http-user-message-parity.test.ts +2 -2
  138. package/src/__tests__/identity-intro-cache.test.ts +35 -14
  139. package/src/__tests__/inbound-slack-persistence.test.ts +7 -2
  140. package/src/__tests__/injector-background-turn.test.ts +1 -1
  141. package/src/__tests__/injector-chain.test.ts +1 -1
  142. package/src/__tests__/injector-disk-pressure.test.ts +1 -1
  143. package/src/__tests__/injector-document-comments.test.ts +1 -1
  144. package/src/__tests__/injector-pkb-v2-silenced.test.ts +1 -1
  145. package/src/__tests__/injector-v3-suppression.test.ts +220 -0
  146. package/src/__tests__/list-messages-attachments.test.ts +7 -8
  147. package/src/__tests__/list-messages-hidden-metadata.test.ts +17 -15
  148. package/src/__tests__/list-messages-page-latest.test.ts +0 -1
  149. package/src/__tests__/list-messages-tool-merge.test.ts +36 -6
  150. package/src/__tests__/llm-call-pipeline.test.ts +21 -15
  151. package/src/__tests__/llm-request-log-turn-query.test.ts +42 -86
  152. package/src/__tests__/llm-resolver.test.ts +23 -47
  153. package/src/__tests__/llm-usage-store.test.ts +45 -0
  154. package/src/__tests__/log-export-routes.test.ts +59 -0
  155. package/src/__tests__/managed-skill-lifecycle.test.ts +1 -8
  156. package/src/__tests__/mcp-auth-routes.test.ts +15 -10
  157. package/src/__tests__/mcp-health-check.test.ts +18 -13
  158. package/src/__tests__/memory-retrieval-pipeline.test.ts +1 -1
  159. package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
  160. package/src/__tests__/messaging-send-tool.test.ts +8 -4
  161. package/src/__tests__/migration-export-http.test.ts +12 -12
  162. package/src/__tests__/migration-import-commit-http.test.ts +8 -8
  163. package/src/__tests__/migration-import-preflight-http.test.ts +7 -7
  164. package/src/__tests__/migration-validate-http.test.ts +3 -3
  165. package/src/__tests__/native-web-search.test.ts +14 -20
  166. package/src/__tests__/notification-decision-identity.test.ts +9 -18
  167. package/src/__tests__/notification-decision-recipient-context.test.ts +3 -6
  168. package/src/__tests__/oauth-commands-routes.test.ts +1 -1
  169. package/src/__tests__/onboarding-template-contract.test.ts +10 -0
  170. package/src/__tests__/openai-provider.test.ts +66 -70
  171. package/src/__tests__/openai-responses-provider.test.ts +21 -77
  172. package/src/__tests__/outbound-slack-persistence.test.ts +2 -1
  173. package/src/__tests__/overflow-reduce-pipeline.test.ts +2 -4
  174. package/src/__tests__/parallel-tool.benchmark.test.ts +24 -36
  175. package/src/__tests__/persistence-pipeline.test.ts +15 -26
  176. package/src/__tests__/persistence-secret-redaction.test.ts +2 -1
  177. package/src/__tests__/pipeline-runner.test.ts +2 -3
  178. package/src/__tests__/plugin-bootstrap.test.ts +51 -25
  179. package/src/__tests__/plugin-route-contribution.test.ts +6 -16
  180. package/src/__tests__/plugin-skill-contribution.test.ts +7 -17
  181. package/src/__tests__/plugin-tool-contribution.test.ts +10 -26
  182. package/src/__tests__/plugin-types.test.ts +7 -14
  183. package/src/__tests__/prechat-onboarding-contract.test.ts +23 -0
  184. package/src/__tests__/process-message-background-slack.test.ts +17 -16
  185. package/src/__tests__/process-message-display-content.test.ts +30 -42
  186. package/src/__tests__/provider-commit-message-generator.test.ts +19 -14
  187. package/src/__tests__/provider-error-scenarios.test.ts +7 -6
  188. package/src/__tests__/provider-platform-proxy-integration.test.ts +3 -8
  189. package/src/__tests__/provider-send-message-override-profile.test.ts +9 -25
  190. package/src/__tests__/provider-streaming.benchmark.test.ts +12 -22
  191. package/src/__tests__/provider-usage-tracking.test.ts +0 -6
  192. package/src/__tests__/ratelimit.test.ts +9 -4
  193. package/src/__tests__/relay-server.test.ts +20 -13
  194. package/src/__tests__/retry-openrouter-only-normalization.test.ts +5 -8
  195. package/src/__tests__/retry-thinking-tool-choice.test.ts +10 -13
  196. package/src/__tests__/retry-verbosity-normalization.test.ts +5 -8
  197. package/src/__tests__/runtime-events-sse-reconnect.test.ts +353 -0
  198. package/src/__tests__/schedule-routes.test.ts +80 -10
  199. package/src/__tests__/schedule-store.test.ts +67 -0
  200. package/src/__tests__/schedule-tools.test.ts +125 -0
  201. package/src/__tests__/secret-ingress-http.test.ts +2 -2
  202. package/src/__tests__/secret-prompt-log-hygiene.test.ts +11 -7
  203. package/src/__tests__/secret-prompter-channel-fallback.test.ts +11 -9
  204. package/src/__tests__/secret-response-routing.test.ts +13 -11
  205. package/src/__tests__/send-endpoint-busy.test.ts +2 -1
  206. package/src/__tests__/shell-observability.test.ts +249 -0
  207. package/src/__tests__/skill-feature-flags-integration.test.ts +11 -11
  208. package/src/__tests__/skill-feature-flags.test.ts +6 -6
  209. package/src/__tests__/skill-load-feature-flag.test.ts +10 -10
  210. package/src/__tests__/skills-files-catalog-fallback.test.ts +10 -0
  211. package/src/__tests__/skillssh-files.test.ts +1 -0
  212. package/src/__tests__/starter-task-flow.test.ts +6 -6
  213. package/src/__tests__/strip-memory-injections.test.ts +102 -14
  214. package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
  215. package/src/__tests__/suggestion-routes.test.ts +3 -3
  216. package/src/__tests__/sync-message-contract.test.ts +19 -16
  217. package/src/__tests__/system-prompt.test.ts +54 -0
  218. package/src/__tests__/terminal-tools.test.ts +3 -24
  219. package/src/__tests__/thread-backfill.test.ts +4 -9
  220. package/src/__tests__/title-generate-pipeline.test.ts +1 -1
  221. package/src/__tests__/token-estimate-pipeline.test.ts +2 -4
  222. package/src/__tests__/tool-error-pipeline.test.ts +2 -2
  223. package/src/__tests__/tool-execute-pipeline.test.ts +1 -1
  224. package/src/__tests__/tool-preview-lifecycle.test.ts +13 -11
  225. package/src/__tests__/tool-result-truncate-pipeline.test.ts +9 -12
  226. package/src/__tests__/tool-result-truncation.test.ts +3 -1
  227. package/src/__tests__/tools-audio-read.test.ts +113 -0
  228. package/src/__tests__/turn-boundary-resolution.test.ts +44 -84
  229. package/src/__tests__/turn-events-store.test.ts +11 -7
  230. package/src/__tests__/voice-scoped-grant-consumer.test.ts +8 -6
  231. package/src/__tests__/voice-session-bridge.test.ts +13 -7
  232. package/src/acp/__tests__/prepare-agent-env.test.ts +143 -31
  233. package/src/acp/prepare-agent-env.ts +52 -11
  234. package/src/agent/compaction-circuit.ts +140 -0
  235. package/src/agent/loop.ts +409 -85
  236. package/src/api/README.md +19 -17
  237. package/src/api/constants/tool-execution.ts +21 -0
  238. package/src/api/events/assistant-activity-state.ts +75 -0
  239. package/src/api/events/assistant-outbound-attachment.ts +25 -27
  240. package/src/api/events/assistant-text-delta.ts +6 -8
  241. package/src/api/events/assistant-turn-start.ts +5 -7
  242. package/src/api/events/avatar-updated.ts +24 -0
  243. package/src/api/events/compaction-circuit-closed.ts +26 -0
  244. package/src/api/events/compaction-circuit-open.ts +28 -0
  245. package/src/api/events/confirmation-request.ts +114 -0
  246. package/src/api/events/contact-request.ts +33 -0
  247. package/src/api/events/conversation-error.ts +77 -0
  248. package/src/api/events/conversation-list-invalidated.ts +38 -0
  249. package/src/api/events/conversation-title-updated.ts +24 -0
  250. package/src/api/events/disk-pressure-status-changed.ts +61 -0
  251. package/src/api/events/document-comment-created.ts +24 -28
  252. package/src/api/events/document-comment-deleted.ts +6 -8
  253. package/src/api/events/document-comment-reopened.ts +6 -8
  254. package/src/api/events/document-comment-resolved.ts +8 -10
  255. package/src/api/events/document-editor-update.ts +27 -0
  256. package/src/api/events/error.ts +32 -0
  257. package/src/api/events/generation-cancelled.ts +4 -6
  258. package/src/api/events/generation-handoff.ts +13 -15
  259. package/src/api/events/home-feed-updated.ts +26 -0
  260. package/src/api/events/identity-changed.ts +32 -0
  261. package/src/api/events/interaction-resolved.ts +50 -0
  262. package/src/api/events/message-complete.ts +10 -12
  263. package/src/api/events/message-dequeued.ts +21 -0
  264. package/src/api/events/message-queued-deleted.ts +23 -0
  265. package/src/api/events/message-queued.ts +22 -0
  266. package/src/api/events/message-request-complete.ts +29 -0
  267. package/src/api/events/navigate-settings.ts +20 -0
  268. package/src/api/events/notification-intent.ts +33 -0
  269. package/src/api/events/open-url.ts +6 -8
  270. package/src/api/events/question-request.ts +67 -0
  271. package/src/api/events/relationship-state-updated.ts +4 -6
  272. package/src/api/events/secret-request.ts +42 -0
  273. package/src/api/events/subagent-event.ts +79 -0
  274. package/src/api/events/subagent-spawned.ts +40 -0
  275. package/src/api/events/subagent-status-changed.ts +65 -0
  276. package/src/api/events/sync-changed.ts +29 -0
  277. package/src/api/events/tool-result.ts +129 -0
  278. package/src/api/events/tool-use-start.ts +8 -10
  279. package/src/api/events/turn-profile-auto-routed.ts +28 -0
  280. package/src/api/events/ui-surface-complete.ts +30 -0
  281. package/src/api/events/ui-surface-dismiss.ts +22 -0
  282. package/src/api/events/ui-surface-show.ts +67 -0
  283. package/src/api/events/ui-surface-update.ts +26 -0
  284. package/src/api/events/usage-update.ts +34 -0
  285. package/src/api/events/user-message-echo.ts +35 -0
  286. package/src/api/index.ts +354 -0
  287. package/src/api/requests/dictation.ts +45 -0
  288. package/src/api/responses/disk-pressure-status.ts +26 -0
  289. package/src/api/responses/home.ts +217 -0
  290. package/src/api/responses/llm-context-response.ts +2 -0
  291. package/src/api/responses/memory-v3-selection-log.ts +50 -0
  292. package/src/api/responses/subagent-detail.ts +48 -0
  293. package/src/approvals/guardian-decision-primitive.ts +7 -15
  294. package/src/approvals/guardian-request-resolvers.ts +6 -9
  295. package/src/avatar/__tests__/avatar-manifest.test.ts +236 -0
  296. package/src/avatar/__tests__/avatar-store.test.ts +193 -0
  297. package/src/avatar/avatar-manifest.ts +195 -0
  298. package/src/avatar/avatar-store.ts +113 -0
  299. package/src/avatar/traits-png-sync.ts +8 -2
  300. package/src/background-wake/next-wake.test.ts +31 -1
  301. package/src/background-wake/next-wake.ts +4 -1
  302. package/src/calls/call-conversation-messages.ts +6 -4
  303. package/src/calls/guardian-action-sweep.ts +6 -4
  304. package/src/calls/relay-server.ts +12 -8
  305. package/src/calls/voice-session-bridge.ts +13 -27
  306. package/src/cli/commands/__tests__/memory-v3.test.ts +245 -0
  307. package/src/cli/commands/avatar.ts +17 -11
  308. package/src/cli/commands/conversations.ts +15 -1
  309. package/src/cli/commands/db/__tests__/repair.test.ts +540 -0
  310. package/src/cli/commands/db/__tests__/status.test.ts +253 -0
  311. package/src/cli/commands/db/format.ts +48 -0
  312. package/src/cli/commands/db/index.ts +29 -0
  313. package/src/cli/commands/db/repair-step-conversation-backfill.ts +345 -0
  314. package/src/cli/commands/db/repair-step-integrity.ts +146 -0
  315. package/src/cli/commands/db/repair-steps.ts +164 -0
  316. package/src/cli/commands/db/repair.ts +141 -0
  317. package/src/cli/commands/db/status.ts +366 -0
  318. package/src/cli/commands/memory-v3.ts +159 -445
  319. package/src/cli/lib/cli-colors.ts +24 -6
  320. package/src/cli/program.ts +4 -5
  321. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  322. package/src/config/assistant-feature-flags.ts +2 -2
  323. package/src/config/bundled-skills/app-builder/SKILL.md +14 -3
  324. package/src/config/bundled-skills/media-processing/services/reduce.ts +6 -9
  325. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +7 -2
  326. package/src/config/bundled-skills/schedule/SKILL.md +1 -1
  327. package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
  328. package/src/config/call-site-defaults.ts +2 -7
  329. package/src/config/feature-flag-registry.json +25 -9
  330. package/src/config/schemas/__tests__/memory-v2.test.ts +1 -226
  331. package/src/config/schemas/call-site-catalog.ts +8 -15
  332. package/src/config/schemas/llm.ts +2 -3
  333. package/src/config/schemas/memory-lifecycle.ts +24 -0
  334. package/src/config/schemas/memory-v2.ts +0 -253
  335. package/src/config/schemas/memory-v3.ts +39 -0
  336. package/src/config/schemas/memory.ts +6 -1
  337. package/src/config/schemas/timeouts.ts +3 -1
  338. package/src/context/compactor.ts +54 -31
  339. package/src/context/token-estimator.ts +19 -0
  340. package/src/context/tool-result-truncation.ts +1 -43
  341. package/src/context/window-manager.ts +138 -20
  342. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +2 -2
  343. package/src/daemon/__tests__/web-search-status-text.test.ts +10 -6
  344. package/src/daemon/approval-generators.ts +4 -4
  345. package/src/daemon/config-watcher.ts +7 -1
  346. package/src/daemon/conversation-agent-loop-handlers.ts +225 -88
  347. package/src/daemon/conversation-agent-loop.ts +284 -584
  348. package/src/daemon/conversation-error.ts +7 -7
  349. package/src/daemon/conversation-history.ts +22 -6
  350. package/src/daemon/conversation-launch.ts +4 -8
  351. package/src/daemon/conversation-lifecycle.ts +10 -38
  352. package/src/daemon/conversation-messaging.ts +1 -3
  353. package/src/daemon/conversation-notifiers.ts +7 -5
  354. package/src/daemon/conversation-process.ts +100 -79
  355. package/src/daemon/conversation-runtime-assembly.ts +47 -21
  356. package/src/daemon/conversation-store.ts +6 -5
  357. package/src/daemon/conversation-surfaces.ts +55 -69
  358. package/src/daemon/conversation-tool-setup.ts +3 -0
  359. package/src/daemon/conversation.ts +91 -126
  360. package/src/daemon/daemon-skill-host.ts +2 -6
  361. package/src/daemon/disk-pressure-guard.ts +35 -29
  362. package/src/daemon/external-plugins-bootstrap.ts +46 -24
  363. package/src/daemon/first-greeting.ts +26 -4
  364. package/src/daemon/guardian-action-generators.ts +2 -2
  365. package/src/daemon/handlers/conversations.ts +6 -22
  366. package/src/daemon/handlers/shared.ts +4 -0
  367. package/src/daemon/handlers/skills.ts +15 -14
  368. package/src/daemon/host-app-control-proxy.ts +54 -1
  369. package/src/daemon/host-cu-proxy.ts +46 -22
  370. package/src/daemon/host-file-proxy.ts +25 -1
  371. package/src/daemon/host-proxy-preactivation.ts +25 -6
  372. package/src/daemon/lifecycle.ts +28 -55
  373. package/src/daemon/message-protocol.ts +2 -3
  374. package/src/daemon/message-provenance.ts +49 -0
  375. package/src/daemon/message-types/contacts.ts +3 -20
  376. package/src/daemon/message-types/conversations.ts +13 -111
  377. package/src/daemon/message-types/documents.ts +3 -9
  378. package/src/daemon/message-types/home.ts +4 -17
  379. package/src/daemon/message-types/integrations.ts +2 -6
  380. package/src/daemon/message-types/messages.ts +28 -343
  381. package/src/daemon/message-types/notifications.ts +2 -32
  382. package/src/daemon/message-types/settings.ts +3 -8
  383. package/src/daemon/message-types/skills.ts +2 -0
  384. package/src/daemon/message-types/surfaces.ts +2 -0
  385. package/src/daemon/message-types/sync.ts +12 -25
  386. package/src/daemon/message-types/workspace.ts +3 -11
  387. package/src/daemon/process-message.ts +49 -46
  388. package/src/daemon/server.ts +12 -0
  389. package/src/daemon/tool-side-effects.ts +10 -7
  390. package/src/daemon/trust-context.ts +13 -0
  391. package/src/daemon/wake-target-adapter.ts +11 -1
  392. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -1
  393. package/src/heartbeat/heartbeat-run-store.ts +31 -0
  394. package/src/heartbeat/heartbeat-service.ts +16 -0
  395. package/src/home/feature-gate.ts +22 -0
  396. package/src/home/feed-types.ts +36 -221
  397. package/src/ipc/__tests__/email-ipc.test.ts +0 -9
  398. package/src/ipc/routes/__tests__/route-adapter.test.ts +244 -0
  399. package/src/ipc/routes/route-adapter.ts +45 -6
  400. package/src/ipc/skill-routes/__tests__/memory.test.ts +18 -9
  401. package/src/ipc/skill-routes/__tests__/providers.test.ts +10 -10
  402. package/src/ipc/skill-routes/__tests__/registries.test.ts +28 -18
  403. package/src/ipc/skill-routes/memory.ts +26 -13
  404. package/src/ipc/skill-routes/providers.ts +5 -6
  405. package/src/ipc/skill-routes/registries.ts +13 -61
  406. package/src/live-voice/__tests__/live-voice-archive.test.ts +24 -11
  407. package/src/memory/__tests__/conversation-queries.test.ts +192 -8
  408. package/src/memory/__tests__/db-maintenance.test.ts +128 -0
  409. package/src/memory/__tests__/jobs-store-job-classes.test.ts +5 -4
  410. package/src/memory/__tests__/memory-retrospective-job.test.ts +10 -6
  411. package/src/memory/__tests__/memory-v3-selections-migration.test.ts +103 -0
  412. package/src/memory/context-search/agent-runner.ts +2 -4
  413. package/src/memory/conversation-crud.ts +39 -8
  414. package/src/memory/conversation-queries.ts +78 -22
  415. package/src/memory/db-init.ts +8 -0
  416. package/src/memory/db-maintenance.ts +18 -2
  417. package/src/memory/graph/consolidation.ts +8 -11
  418. package/src/memory/graph/conversation-graph-memory.ts +41 -8
  419. package/src/memory/graph/extraction.ts +6 -9
  420. package/src/memory/graph/narrative.ts +2 -2
  421. package/src/memory/graph/pattern-scan.ts +2 -2
  422. package/src/memory/graph/retriever.ts +20 -26
  423. package/src/memory/graph/tools.ts +4 -4
  424. package/src/memory/job-handlers/conversation-starters.ts +32 -32
  425. package/src/memory/job-handlers/summarization.ts +1 -2
  426. package/src/memory/jobs-store.ts +3 -1
  427. package/src/memory/jobs-worker.ts +51 -39
  428. package/src/memory/llm-request-log-source-clickhouse.ts +5 -31
  429. package/src/memory/llm-request-log-source-local.ts +0 -11
  430. package/src/memory/llm-request-log-source.ts +9 -25
  431. package/src/memory/llm-request-log-store.ts +0 -41
  432. package/src/memory/llm-usage-store.ts +10 -0
  433. package/src/memory/memory-marker.ts +17 -0
  434. package/src/memory/memory-retrospective-job.ts +6 -2
  435. package/src/memory/memory-v2-activation-log-store.ts +1 -83
  436. package/src/memory/migrations/267-llm-usage-events-add-assistant-version.ts +46 -0
  437. package/src/memory/migrations/268-add-memory-v3-selections.ts +28 -0
  438. package/src/memory/migrations/269-schedule-script-timeout.ts +11 -0
  439. package/src/memory/migrations/270-messages-role-created-at-index.ts +18 -0
  440. package/src/memory/migrations/__tests__/267-llm-usage-events-add-assistant-version.test.ts +117 -0
  441. package/src/memory/migrations/index.ts +4 -0
  442. package/src/memory/schema/infrastructure.ts +11 -0
  443. package/src/memory/v2/__tests__/consolidation-job.test.ts +124 -0
  444. package/src/memory/v2/__tests__/migration.test.ts +11 -3
  445. package/src/memory/v2/__tests__/page-index.test.ts +37 -1
  446. package/src/memory/v2/__tests__/router.test.ts +14 -4
  447. package/src/memory/v2/__tests__/sweep-job.test.ts +6 -5
  448. package/src/memory/v2/backfill-jobs.ts +6 -0
  449. package/src/memory/v2/consolidation-job.ts +89 -9
  450. package/src/memory/v2/migration.ts +5 -3
  451. package/src/memory/v2/page-index.ts +11 -0
  452. package/src/memory/v2/router.ts +8 -11
  453. package/src/memory/v2/sweep-job.ts +8 -11
  454. package/src/memory/v2/types.ts +1 -0
  455. package/src/memory/v3/__tests__/assign.test.ts +242 -0
  456. package/src/memory/v3/__tests__/capabilities.test.ts +118 -0
  457. package/src/memory/v3/__tests__/core.test.ts +39 -0
  458. package/src/memory/v3/__tests__/fixtures/eval-turns.json +36 -0
  459. package/src/memory/v3/__tests__/fixtures/live-turns.json +37 -0
  460. package/src/memory/v3/__tests__/health.test.ts +203 -0
  461. package/src/memory/v3/__tests__/live-integration.test.ts +330 -0
  462. package/src/memory/v3/__tests__/maintain-job.test.ts +288 -0
  463. package/src/memory/v3/__tests__/needle.test.ts +107 -0
  464. package/src/memory/v3/__tests__/orchestrate.test.ts +400 -0
  465. package/src/memory/v3/__tests__/reconcile.test.ts +274 -0
  466. package/src/memory/v3/__tests__/render-injection.test.ts +61 -0
  467. package/src/memory/v3/__tests__/router.test.ts +260 -0
  468. package/src/memory/v3/__tests__/selection-log-store.test.ts +179 -0
  469. package/src/memory/v3/__tests__/selector.test.ts +404 -0
  470. package/src/memory/v3/__tests__/shadow-plugin.test.ts +414 -0
  471. package/src/memory/v3/__tests__/snapshot.test.ts +168 -0
  472. package/src/memory/v3/__tests__/tree.test.ts +192 -0
  473. package/src/memory/v3/__tests__/types.test.ts +54 -0
  474. package/src/memory/v3/__tests__/working-set-eviction.test.ts +106 -0
  475. package/src/memory/v3/__tests__/working-set-skeleton.test.ts +44 -0
  476. package/src/memory/v3/assign.ts +268 -0
  477. package/src/memory/v3/capabilities.ts +124 -0
  478. package/src/memory/v3/core.ts +26 -0
  479. package/src/memory/v3/data/README.md +84 -0
  480. package/src/memory/v3/data/assignments.json +5 -0
  481. package/src/memory/v3/data/core.json +1 -0
  482. package/src/memory/v3/data/leaves/domain-a/topic-x.md +9 -0
  483. package/src/memory/v3/data/leaves/domain-a/topic-y.md +9 -0
  484. package/src/memory/v3/data/leaves/domain-b/topic-z.md +9 -0
  485. package/src/memory/v3/health.ts +0 -0
  486. package/src/memory/v3/maintain-job.ts +314 -0
  487. package/src/memory/v3/needle.ts +115 -0
  488. package/src/memory/v3/orchestrate.ts +114 -0
  489. package/src/memory/v3/page-content.ts +34 -0
  490. package/src/memory/v3/provider-blocks.ts +16 -0
  491. package/src/memory/v3/reconcile.ts +523 -0
  492. package/src/memory/v3/render-injection.ts +32 -0
  493. package/src/memory/v3/router.ts +184 -0
  494. package/src/memory/v3/selection-log-store.ts +84 -0
  495. package/src/memory/v3/selector.ts +211 -0
  496. package/src/memory/v3/shadow-plugin.ts +379 -0
  497. package/src/memory/v3/snapshot.ts +209 -0
  498. package/src/memory/v3/tree.ts +174 -0
  499. package/src/memory/v3/types.ts +46 -60
  500. package/src/memory/v3/working-set.ts +88 -0
  501. package/src/messaging/providers/slack/render-transcript.test.ts +1 -1
  502. package/src/messaging/providers/slack/render-transcript.ts +2 -2
  503. package/src/messaging/style-analyzer.ts +8 -11
  504. package/src/notifications/conversation-pairing.ts +8 -6
  505. package/src/notifications/decision-engine.ts +10 -13
  506. package/src/notifications/preference-extractor.ts +11 -14
  507. package/src/permissions/prompter.ts +42 -36
  508. package/src/permissions/question-prompter.test.ts +35 -26
  509. package/src/permissions/question-prompter.ts +6 -10
  510. package/src/plugin-api/index.ts +2 -0
  511. package/src/plugin-api/types.ts +25 -3
  512. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +93 -0
  513. package/src/plugins/defaults/circuit-breaker/package.json +15 -0
  514. package/src/plugins/defaults/circuit-breaker/register.ts +39 -0
  515. package/src/plugins/defaults/compaction/middlewares/compaction.ts +25 -0
  516. package/src/plugins/defaults/compaction/package.json +15 -0
  517. package/src/plugins/defaults/compaction/register.ts +35 -0
  518. package/src/plugins/defaults/compaction/terminal.ts +73 -0
  519. package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +22 -0
  520. package/src/plugins/defaults/empty-response/package.json +15 -0
  521. package/src/plugins/defaults/empty-response/register.ts +28 -0
  522. package/src/plugins/defaults/empty-response/terminal.ts +106 -0
  523. package/src/plugins/defaults/history-repair/hooks/user-prompt-submit.ts +35 -0
  524. package/src/plugins/defaults/history-repair/package.json +15 -0
  525. package/src/plugins/defaults/history-repair/register.ts +24 -0
  526. package/src/{daemon/history-repair.ts → plugins/defaults/history-repair/terminal.ts} +48 -35
  527. package/src/plugins/defaults/index.ts +29 -40
  528. package/src/plugins/defaults/injectors/package.json +15 -0
  529. package/src/plugins/defaults/{injectors.ts → injectors/register.ts} +14 -38
  530. package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +17 -0
  531. package/src/plugins/defaults/llm-call/package.json +15 -0
  532. package/src/plugins/defaults/{llm-call.ts → llm-call/register.ts} +6 -38
  533. package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +17 -0
  534. package/src/plugins/defaults/memory-retrieval/package.json +15 -0
  535. package/src/plugins/defaults/{memory-retrieval.ts → memory-retrieval/register.ts} +10 -48
  536. package/src/plugins/defaults/{overflow-reduce.ts → overflow-reduce/middlewares/overflowReduce.ts} +18 -77
  537. package/src/plugins/defaults/overflow-reduce/package.json +15 -0
  538. package/src/plugins/defaults/overflow-reduce/register.ts +42 -0
  539. package/src/plugins/defaults/persistence/middlewares/persistence.ts +19 -0
  540. package/src/plugins/defaults/persistence/package.json +15 -0
  541. package/src/plugins/defaults/persistence/register.ts +38 -0
  542. package/src/plugins/defaults/persistence/terminal.ts +83 -0
  543. package/src/plugins/defaults/title-generate/package.json +15 -0
  544. package/src/plugins/defaults/title-generate/register.ts +35 -0
  545. package/src/plugins/defaults/title-generate/terminal.ts +31 -0
  546. package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +23 -0
  547. package/src/plugins/defaults/token-estimate/package.json +15 -0
  548. package/src/plugins/defaults/token-estimate/register.ts +34 -0
  549. package/src/plugins/defaults/token-estimate/terminal.ts +40 -0
  550. package/src/plugins/defaults/tool-error/middlewares/toolError.ts +21 -0
  551. package/src/plugins/defaults/tool-error/package.json +15 -0
  552. package/src/plugins/defaults/tool-error/register.ts +35 -0
  553. package/src/plugins/defaults/tool-error/terminal.ts +47 -0
  554. package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +23 -0
  555. package/src/plugins/defaults/tool-execute/package.json +15 -0
  556. package/src/plugins/defaults/{tool-execute.ts → tool-execute/register.ts} +8 -46
  557. package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +23 -0
  558. package/src/plugins/defaults/tool-result-truncate/package.json +15 -0
  559. package/src/plugins/defaults/tool-result-truncate/register.ts +35 -0
  560. package/src/plugins/defaults/tool-result-truncate/terminal.ts +113 -0
  561. package/src/plugins/defaults/tool-result-truncate/types.ts +22 -0
  562. package/src/plugins/external-plugin-loader.ts +2 -2
  563. package/src/plugins/pipeline.ts +0 -12
  564. package/src/plugins/types.ts +51 -90
  565. package/src/plugins/user-loader.ts +4 -3
  566. package/src/proactive-artifact/aux-message-injector.ts +0 -1
  567. package/src/proactive-artifact/job.test.ts +20 -8
  568. package/src/proactive-artifact/job.ts +3 -1
  569. package/src/prompts/sections.ts +20 -7
  570. package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +2 -2
  571. package/src/prompts/templates/BOOTSTRAP.md +5 -1
  572. package/src/prompts/templates/system-sections.ts +6 -0
  573. package/src/providers/__tests__/retry-callsite.test.ts +25 -25
  574. package/src/providers/__tests__/satellite-connection-routing.test.ts +7 -21
  575. package/src/providers/anthropic/client.ts +24 -5
  576. package/src/providers/call-site-routing.ts +1 -9
  577. package/src/providers/gemini/client.ts +152 -34
  578. package/src/providers/gemini/inline-media.ts +74 -0
  579. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +0 -2
  580. package/src/providers/openai/chat-completions-provider.ts +1 -4
  581. package/src/providers/openai/responses-provider.ts +1 -4
  582. package/src/providers/openrouter/client.ts +1 -6
  583. package/src/providers/provider-send-message.ts +6 -6
  584. package/src/providers/ratelimit.ts +1 -9
  585. package/src/providers/retry.ts +0 -5
  586. package/src/providers/types.ts +11 -2
  587. package/src/providers/usage-tracking.ts +1 -9
  588. package/src/runtime/__tests__/agent-wake.test.ts +131 -26
  589. package/src/runtime/__tests__/background-job-runner.test.ts +1 -3
  590. package/src/runtime/agent-wake.ts +93 -18
  591. package/src/runtime/assistant-event-hub.ts +2 -2
  592. package/src/runtime/auth/__tests__/guard-tests.test.ts +75 -109
  593. package/src/runtime/auth/__tests__/route-policy.test.ts +153 -170
  594. package/src/runtime/auth/route-policy.ts +42 -1079
  595. package/src/runtime/background-job-runner.ts +1 -4
  596. package/src/runtime/btw-sidechain.ts +3 -1
  597. package/src/runtime/channel-approvals.ts +3 -14
  598. package/src/runtime/channel-invite-transport.ts +5 -6
  599. package/src/runtime/channel-readiness-service.ts +2 -5
  600. package/src/runtime/channel-retry-sweep.ts +12 -16
  601. package/src/runtime/conversation-stream-state.ts +294 -0
  602. package/src/runtime/http-router.ts +19 -22
  603. package/src/runtime/http-types.ts +12 -6
  604. package/src/runtime/invite-instruction-generator.ts +3 -3
  605. package/src/runtime/pending-interactions.ts +2 -2
  606. package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +565 -0
  607. package/src/runtime/routes/__tests__/content-source-routes.test.ts +4 -4
  608. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +62 -32
  609. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +237 -0
  610. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -22
  611. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +7 -2
  612. package/src/runtime/routes/__tests__/sanity-routes.test.ts +6 -6
  613. package/src/runtime/routes/__tests__/stt-routes.test.ts +3 -3
  614. package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +5 -2
  615. package/src/runtime/routes/__tests__/tts-routes.test.ts +3 -3
  616. package/src/runtime/routes/acp-routes.test.ts +97 -75
  617. package/src/runtime/routes/acp-routes.ts +29 -6
  618. package/src/runtime/routes/app-management-routes.ts +97 -24
  619. package/src/runtime/routes/app-routes.ts +25 -5
  620. package/src/runtime/routes/approval-routes.ts +16 -4
  621. package/src/runtime/routes/attachment-routes.ts +25 -1
  622. package/src/runtime/routes/audio-routes.ts +1 -0
  623. package/src/runtime/routes/audit-routes.ts +5 -0
  624. package/src/runtime/routes/auth-routes.ts +5 -0
  625. package/src/runtime/routes/avatar-routes.ts +238 -59
  626. package/src/runtime/routes/background-tool-routes.ts +9 -0
  627. package/src/runtime/routes/background-wake-routes.ts +13 -3
  628. package/src/runtime/routes/backup-routes.ts +45 -0
  629. package/src/runtime/routes/bookmark-routes.ts +13 -0
  630. package/src/runtime/routes/brain-graph-routes.ts +9 -0
  631. package/src/runtime/routes/browser-routes.ts +5 -0
  632. package/src/runtime/routes/browser-tabs-routes.ts +5 -0
  633. package/src/runtime/routes/btw-routes.ts +5 -1
  634. package/src/runtime/routes/cache-routes.ts +13 -0
  635. package/src/runtime/routes/call-routes.ts +21 -10
  636. package/src/runtime/routes/channel-availability-routes.ts +5 -1
  637. package/src/runtime/routes/channel-readiness-routes.ts +37 -4
  638. package/src/runtime/routes/channel-route-definitions.ts +21 -0
  639. package/src/runtime/routes/channel-verification-routes.ts +21 -0
  640. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +9 -2
  641. package/src/runtime/routes/client-routes.ts +9 -0
  642. package/src/runtime/routes/consolidation-routes.ts +13 -5
  643. package/src/runtime/routes/contact-prompt-routes.ts +9 -0
  644. package/src/runtime/routes/contact-routes.ts +90 -23
  645. package/src/runtime/routes/content-source-routes.ts +5 -1
  646. package/src/runtime/routes/conversation-analysis-routes.ts +5 -1
  647. package/src/runtime/routes/conversation-attention-routes.ts +5 -0
  648. package/src/runtime/routes/conversation-cli-routes.ts +54 -7
  649. package/src/runtime/routes/conversation-compaction-routes.ts +54 -25
  650. package/src/runtime/routes/conversation-list-routes.ts +81 -12
  651. package/src/runtime/routes/conversation-management-routes.ts +57 -14
  652. package/src/runtime/routes/conversation-query-routes.ts +88 -41
  653. package/src/runtime/routes/conversation-routes.ts +74 -19
  654. package/src/runtime/routes/conversation-starter-routes.ts +22 -13
  655. package/src/runtime/routes/conversations-import-routes.ts +6 -1
  656. package/src/runtime/routes/credential-prompt-routes.ts +5 -0
  657. package/src/runtime/routes/credential-routes.ts +25 -6
  658. package/src/runtime/routes/debug-bash-routes.ts +5 -0
  659. package/src/runtime/routes/debug-routes.ts +11 -2
  660. package/src/runtime/routes/defer-routes.ts +13 -0
  661. package/src/runtime/routes/diagnostics-routes.ts +37 -46
  662. package/src/runtime/routes/disk-pressure-routes.ts +17 -31
  663. package/src/runtime/routes/document-comments-routes.ts +46 -27
  664. package/src/runtime/routes/documents-routes.ts +21 -10
  665. package/src/runtime/routes/domain-routes.ts +61 -28
  666. package/src/runtime/routes/email-routes.ts +33 -0
  667. package/src/runtime/routes/events-routes.ts +114 -9
  668. package/src/runtime/routes/filing-routes.ts +9 -4
  669. package/src/runtime/routes/gateway-log-routes.ts +5 -0
  670. package/src/runtime/routes/global-search-routes.ts +53 -50
  671. package/src/runtime/routes/group-routes.ts +21 -5
  672. package/src/runtime/routes/guardian-action-routes.ts +9 -0
  673. package/src/runtime/routes/guardian-approval-interception.ts +0 -31
  674. package/src/runtime/routes/heartbeat-routes.ts +25 -9
  675. package/src/runtime/routes/home-feed-routes.ts +23 -19
  676. package/src/runtime/routes/home-state-routes.ts +8 -40
  677. package/src/runtime/routes/host-app-control-routes.ts +5 -0
  678. package/src/runtime/routes/host-bash-routes.ts +5 -0
  679. package/src/runtime/routes/host-browser-routes.ts +13 -0
  680. package/src/runtime/routes/host-cu-routes.ts +5 -0
  681. package/src/runtime/routes/host-file-routes.ts +26 -6
  682. package/src/runtime/routes/host-transfer-routes.ts +13 -2
  683. package/src/runtime/routes/http-adapter.ts +1 -2
  684. package/src/runtime/routes/identity-intro-cache.ts +17 -6
  685. package/src/runtime/routes/identity-routes.ts +12 -2
  686. package/src/runtime/routes/image-generation-routes.ts +5 -0
  687. package/src/runtime/routes/inbound-message-handler.ts +15 -11
  688. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +0 -12
  689. package/src/runtime/routes/inbound-stages/background-dispatch.ts +15 -19
  690. package/src/runtime/routes/inference-profile-session-routes.ts +13 -3
  691. package/src/runtime/routes/inference-provider-connection-routes.ts +21 -5
  692. package/src/runtime/routes/inference-send-routes.ts +11 -11
  693. package/src/runtime/routes/integrations/a2a.ts +30 -7
  694. package/src/runtime/routes/integrations/slack/channel.ts +19 -3
  695. package/src/runtime/routes/integrations/slack/share.ts +9 -2
  696. package/src/runtime/routes/integrations/telegram.ts +28 -9
  697. package/src/runtime/routes/integrations/twilio.ts +35 -7
  698. package/src/runtime/routes/integrations/vercel.ts +3 -3
  699. package/src/runtime/routes/internal-oauth-routes.ts +5 -0
  700. package/src/runtime/routes/internal-twilio-routes.ts +13 -0
  701. package/src/runtime/routes/llm-call-sites-routes.ts +39 -4
  702. package/src/runtime/routes/log-export-routes.ts +28 -10
  703. package/src/runtime/routes/mcp-auth-routes.ts +25 -0
  704. package/src/runtime/routes/memory-item-routes.ts +21 -10
  705. package/src/runtime/routes/memory-v2-routes.ts +90 -36
  706. package/src/runtime/routes/memory-v3-routes.ts +273 -407
  707. package/src/runtime/routes/migration-rollback-routes.ts +5 -1
  708. package/src/runtime/routes/migration-routes.ts +29 -0
  709. package/src/runtime/routes/notification-routes.ts +17 -1
  710. package/src/runtime/routes/oauth-apps.ts +33 -11
  711. package/src/runtime/routes/oauth-commands-routes.ts +37 -14
  712. package/src/runtime/routes/oauth-connect-routes.ts +9 -0
  713. package/src/runtime/routes/oauth-lifecycle-routes.ts +5 -1
  714. package/src/runtime/routes/oauth-providers.ts +35 -10
  715. package/src/runtime/routes/platform-routes.ts +21 -0
  716. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +3 -2
  717. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +37 -16
  718. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +7 -3
  719. package/src/runtime/routes/playground/__tests__/state.test.ts +10 -3
  720. package/src/runtime/routes/playground/force-compact.ts +1 -1
  721. package/src/runtime/routes/playground/helpers.ts +0 -1
  722. package/src/runtime/routes/playground/inject-failures.ts +13 -8
  723. package/src/runtime/routes/playground/reset-circuit.ts +14 -9
  724. package/src/runtime/routes/playground/seed-conversation.ts +1 -1
  725. package/src/runtime/routes/playground/seeded-conversations.ts +3 -3
  726. package/src/runtime/routes/playground/state.ts +4 -3
  727. package/src/runtime/routes/plugins-routes.ts +22 -19
  728. package/src/runtime/routes/profiler-routes.ts +17 -4
  729. package/src/runtime/routes/ps-routes.ts +5 -0
  730. package/src/runtime/routes/publish-routes.ts +13 -3
  731. package/src/runtime/routes/question-routes.ts +5 -0
  732. package/src/runtime/routes/recording-routes.ts +25 -12
  733. package/src/runtime/routes/rename-conversation-routes.ts +5 -0
  734. package/src/runtime/routes/sanity-routes.ts +9 -2
  735. package/src/runtime/routes/schedule-routes.ts +137 -47
  736. package/src/runtime/routes/secret-routes.ts +17 -4
  737. package/src/runtime/routes/sequence-routes.ts +33 -0
  738. package/src/runtime/routes/settings-routes.ts +65 -19
  739. package/src/runtime/routes/skills-routes.ts +133 -69
  740. package/src/runtime/routes/slack-channel-routes.ts +5 -0
  741. package/src/runtime/routes/stt-routes.ts +13 -6
  742. package/src/runtime/routes/subagents-routes.ts +24 -18
  743. package/src/runtime/routes/suggest-trust-rule-routes.ts +7 -2
  744. package/src/runtime/routes/surface-action-routes.ts +9 -0
  745. package/src/runtime/routes/surface-content-routes.ts +10 -2
  746. package/src/runtime/routes/task-routes.ts +37 -0
  747. package/src/runtime/routes/telemetry-routes.ts +9 -0
  748. package/src/runtime/routes/trace-event-routes.ts +42 -1
  749. package/src/runtime/routes/trust-rules-routes.ts +5 -0
  750. package/src/runtime/routes/tts-routes.ts +13 -6
  751. package/src/runtime/routes/types.ts +17 -8
  752. package/src/runtime/routes/ui-request-routes.ts +5 -0
  753. package/src/runtime/routes/upgrade-broadcast-routes.ts +5 -0
  754. package/src/runtime/routes/usage-routes.ts +71 -3
  755. package/src/runtime/routes/user-routes-cli.ts +9 -0
  756. package/src/runtime/routes/user-routes.ts +5 -1
  757. package/src/runtime/routes/wake-conversation-routes.ts +5 -0
  758. package/src/runtime/routes/watcher-routes.ts +21 -0
  759. package/src/runtime/routes/webhook-routes.ts +9 -0
  760. package/src/runtime/routes/wipe-conversation-routes.ts +5 -0
  761. package/src/runtime/routes/work-items-routes.ts +47 -19
  762. package/src/runtime/routes/workspace-commit-routes.ts +5 -0
  763. package/src/runtime/routes/workspace-routes.test.ts +42 -0
  764. package/src/runtime/routes/workspace-routes.ts +120 -9
  765. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -4
  766. package/src/runtime/services/analyze-conversation.ts +3 -6
  767. package/src/runtime/services/conversation-serializer.ts +24 -2
  768. package/src/runtime/sync/resource-sync-events.ts +16 -2
  769. package/src/runtime/sync/sync-publisher.ts +2 -2
  770. package/src/schedule/run-script.ts +28 -3
  771. package/src/schedule/schedule-store.ts +8 -0
  772. package/src/schedule/scheduler.ts +3 -1
  773. package/src/signals/user-message.ts +5 -8
  774. package/src/skills/catalog-files.ts +4 -1
  775. package/src/skills/clawhub-files.ts +2 -0
  776. package/src/skills/skillssh-files.ts +2 -0
  777. package/src/subagent/manager.ts +3 -6
  778. package/src/telemetry/types.ts +26 -0
  779. package/src/telemetry/usage-telemetry-reporter.test.ts +138 -1
  780. package/src/telemetry/usage-telemetry-reporter.ts +31 -0
  781. package/src/tools/acp/spawn.test.ts +88 -38
  782. package/src/tools/apps/definitions.ts +8 -4
  783. package/src/tools/ask-question/ask-question-tool.test.ts +120 -105
  784. package/src/tools/ask-question/ask-question-tool.ts +85 -90
  785. package/src/tools/computer-use/definitions.ts +28 -24
  786. package/src/tools/credential-execution/make-authenticated-request.ts +56 -51
  787. package/src/tools/credential-execution/manage-secure-command-tool.ts +2 -2
  788. package/src/tools/credential-execution/run-authenticated-command.ts +82 -77
  789. package/src/tools/credentials/vault.ts +112 -111
  790. package/src/tools/execution-target.ts +1 -1
  791. package/src/tools/execution-timeout.ts +3 -4
  792. package/src/tools/filesystem/edit.ts +45 -42
  793. package/src/tools/filesystem/list.ts +33 -30
  794. package/src/tools/filesystem/read.ts +54 -35
  795. package/src/tools/filesystem/write.ts +34 -31
  796. package/src/tools/host-filesystem/edit.ts +44 -42
  797. package/src/tools/host-filesystem/read.ts +49 -35
  798. package/src/tools/host-filesystem/transfer.ts +121 -108
  799. package/src/tools/host-filesystem/write.ts +33 -31
  800. package/src/tools/host-terminal/host-shell.ts +50 -48
  801. package/src/tools/memory/register.ts +23 -24
  802. package/src/tools/network/web-fetch.ts +49 -46
  803. package/src/tools/network/web-search.ts +16 -13
  804. package/src/tools/registry.ts +39 -16
  805. package/src/tools/schedule/create.ts +11 -0
  806. package/src/tools/schedule/update.ts +16 -0
  807. package/src/tools/shared/filesystem/audio-read.ts +122 -0
  808. package/src/tools/shared/filesystem/image-read.ts +1 -1
  809. package/src/tools/skills/execute.ts +34 -31
  810. package/src/tools/skills/load.ts +29 -23
  811. package/src/tools/subagent/notify-parent.ts +35 -32
  812. package/src/tools/system/avatar-generator.ts +13 -22
  813. package/src/tools/system/request-permission.ts +30 -27
  814. package/src/tools/terminal/shell.ts +190 -61
  815. package/src/tools/tool-defaults.ts +20 -9
  816. package/src/tools/tool-manifest.ts +4 -4
  817. package/src/tools/types.ts +74 -23
  818. package/src/tools/ui-surface/definitions.ts +69 -9
  819. package/src/usage/types.ts +10 -0
  820. package/src/util/errors.ts +2 -2
  821. package/src/util/map-limit.ts +27 -0
  822. package/src/util/platform.ts +15 -12
  823. package/src/work-items/work-item-runner.ts +7 -2
  824. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +7 -20
  825. package/src/workspace/migrations/092-backfill-v3-leaves.ts +169 -0
  826. package/src/workspace/migrations/093-backfill-leaf-ids.ts +144 -0
  827. package/src/workspace/migrations/094-seed-avatar-manifest.ts +155 -0
  828. package/src/workspace/migrations/__tests__/094-seed-avatar-manifest.test.ts +136 -0
  829. package/src/workspace/migrations/__tests__/backfill-leaf-ids.test.ts +175 -0
  830. package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +124 -0
  831. package/src/workspace/migrations/registry.ts +6 -0
  832. package/src/workspace/provider-commit-message-generator.ts +15 -17
  833. package/tsconfig.json +4 -1
  834. package/src/__tests__/history-repair-pipeline.test.ts +0 -396
  835. package/src/cli/commands/__tests__/memory-v3-render.test.ts +0 -340
  836. package/src/cli/commands/memory-v3-render.ts +0 -491
  837. package/src/daemon/message-types/disk-pressure.ts +0 -9
  838. package/src/email/feature-gate.ts +0 -23
  839. package/src/memory/v3/__tests__/coactivation-store.test.ts +0 -422
  840. package/src/memory/v3/__tests__/consolidation-job.test.ts +0 -466
  841. package/src/memory/v3/__tests__/coretrieval-seed.test.ts +0 -270
  842. package/src/memory/v3/__tests__/edge-learning-job.test.ts +0 -324
  843. package/src/memory/v3/__tests__/edges.test.ts +0 -706
  844. package/src/memory/v3/__tests__/filter.test.ts +0 -560
  845. package/src/memory/v3/__tests__/gate.test.ts +0 -637
  846. package/src/memory/v3/__tests__/index-composition.test.ts +0 -291
  847. package/src/memory/v3/__tests__/loop.test.ts +0 -775
  848. package/src/memory/v3/__tests__/retriever.test.ts +0 -226
  849. package/src/memory/v3/__tests__/scouts.test.ts +0 -489
  850. package/src/memory/v3/__tests__/shadow-diff.test.ts +0 -225
  851. package/src/memory/v3/__tests__/shadow-middleware.test.ts +0 -398
  852. package/src/memory/v3/__tests__/system-prompts.test.ts +0 -154
  853. package/src/memory/v3/__tests__/traversal.test.ts +0 -508
  854. package/src/memory/v3/__tests__/tree-index.test.ts +0 -280
  855. package/src/memory/v3/__tests__/tree-store.test.ts +0 -529
  856. package/src/memory/v3/__tests__/tree-walk.test.ts +0 -784
  857. package/src/memory/v3/__tests__/validate.test.ts +0 -277
  858. package/src/memory/v3/auto-edges.ts +0 -223
  859. package/src/memory/v3/coactivation-store.ts +0 -124
  860. package/src/memory/v3/consolidation-job.ts +0 -323
  861. package/src/memory/v3/coretrieval-seed.ts +0 -240
  862. package/src/memory/v3/edge-learning-job.ts +0 -160
  863. package/src/memory/v3/edges.ts +0 -286
  864. package/src/memory/v3/filter.ts +0 -286
  865. package/src/memory/v3/gate.ts +0 -349
  866. package/src/memory/v3/index-composition.ts +0 -126
  867. package/src/memory/v3/llm-capture.ts +0 -46
  868. package/src/memory/v3/loop.ts +0 -430
  869. package/src/memory/v3/maintenance.ts +0 -144
  870. package/src/memory/v3/prompt-context.ts +0 -33
  871. package/src/memory/v3/prompts/consolidation.ts +0 -458
  872. package/src/memory/v3/prompts/system-prompts.ts +0 -196
  873. package/src/memory/v3/retriever.ts +0 -33
  874. package/src/memory/v3/scouts.ts +0 -431
  875. package/src/memory/v3/shadow-diff.ts +0 -287
  876. package/src/memory/v3/shadow-middleware.ts +0 -347
  877. package/src/memory/v3/traversal.ts +0 -211
  878. package/src/memory/v3/tree-index.ts +0 -237
  879. package/src/memory/v3/tree-store.ts +0 -394
  880. package/src/memory/v3/tree-walk.ts +0 -356
  881. package/src/memory/v3/validate.ts +0 -323
  882. package/src/plugins/defaults/circuit-breaker.ts +0 -141
  883. package/src/plugins/defaults/compaction.ts +0 -141
  884. package/src/plugins/defaults/empty-response.ts +0 -124
  885. package/src/plugins/defaults/history-repair.ts +0 -83
  886. package/src/plugins/defaults/persistence.ts +0 -146
  887. package/src/plugins/defaults/title-generate.ts +0 -90
  888. package/src/plugins/defaults/token-estimate.ts +0 -101
  889. package/src/plugins/defaults/tool-error.ts +0 -119
  890. package/src/plugins/defaults/tool-result-truncate.ts +0 -84
  891. package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +0 -35
@@ -1,474 +1,340 @@
1
1
  /**
2
- * Memory v3 route definitions — read-only diagnostics over the hand-authored
3
- * v3 tree DAG.
2
+ * Memory v3 route definitions — tree-gardening + core-editing operations for
3
+ * the leaf-tree memory model.
4
4
  *
5
- * Two operations, both side-effect-free (no LLM, no writes):
5
+ * The daemon owns the live tree, so the *mutating* gardening verbs
6
+ * (`reconcile`, `set-core --write`, `rebuild-index`) run here, inside the
7
+ * daemon process, where the in-memory shadow lanes can be invalidated after a
8
+ * write. The read-only `health` report and the `set-core` cost preview also
9
+ * route through the daemon so it stays the single source of truth for the live
10
+ * workspace tree.
6
11
  *
7
- * - `memory_v3_validate` returns the {@link TreeValidationReport} from
8
- * `validateTree(workspaceDir)` (orphan pages, cycles, dangling refs,
9
- * stale-index, unknown edge targets).
10
- * - `memory_v3_tree` returns a JSON-serializable view of
11
- * `getTreeIndex(workspaceDir)`: the root id, every node id, and each
12
- * node's ordered child refs. `TreeIndex` is Map-based, so the handler
13
- * flattens it into arrays/objects the wire protocol can carry.
14
- *
15
- * The v3 tree is authored by the v2 → v3 data-migration; these routes are the
16
- * on-demand inspection surface operators run while that migration is in flight.
17
- * They are NOT invoked on any turn.
12
+ * Each route's behavior lives in a small DI-friendly `handle*` function that
13
+ * takes an optional `MemoryV3Deps` (filesystem overrides) so tests can drive it
14
+ * against a temp workspace without mocking module globals. The exported
15
+ * `RouteDefinition`s are thin `RouteHandlerArgs` adapters over those handlers.
18
16
  */
19
17
 
20
- import { z } from "zod";
21
-
22
- import { loadConfig } from "../../config/loader.js";
23
- import type { AssistantConfig } from "../../config/types.js";
24
- import { getDb } from "../../memory/db-connection.js";
25
- import { readActivationLogsForShadowDiff } from "../../memory/memory-v2-activation-log-store.js";
26
- import type {
27
- RetrievalCost,
28
- RetrievalInput,
29
- } from "../../memory/v2/harness/retriever.js";
30
- import type { DescentTrace } from "../../memory/v2/harness/trace.js";
31
- import { loadNowText } from "../../memory/v2/now-text.js";
18
+ import { writeFile } from "node:fs/promises";
19
+ import { join } from "node:path";
20
+
21
+ import { getPageIndex } from "../../memory/v2/page-index.js";
22
+ import { loadCore } from "../../memory/v3/core.js";
23
+ import { computeV3Health, renderV3Health } from "../../memory/v3/health.js";
24
+ import { type LeafRef, reconcileTree } from "../../memory/v3/reconcile.js";
25
+ import { invalidateLanes } from "../../memory/v3/shadow-plugin.js";
32
26
  import {
33
- DEFAULT_SEED_OPTIONS,
34
- seedCoretrievalEdges,
35
- type SeedCoretrievalResult,
36
- } from "../../memory/v3/coretrieval-seed.js";
37
- import type { LlmCallRecord } from "../../memory/v3/llm-capture.js";
38
- import { runRetrievalLoop } from "../../memory/v3/loop.js";
39
- import type {
40
- ShadowDiffResult,
41
- ShadowDiffTurn,
42
- SlugFrequency,
43
- UnpairedShadowTurn,
44
- } from "../../memory/v3/shadow-diff.js";
45
- import { computeShadowDiff } from "../../memory/v3/shadow-diff.js";
46
- import { getTreeIndex } from "../../memory/v3/tree-index.js";
47
- import type { TreeValidationReport } from "../../memory/v3/validate.js";
48
- import { validateTree } from "../../memory/v3/validate.js";
27
+ coreSlugs,
28
+ loadLeafTree,
29
+ resolveDataDir,
30
+ } from "../../memory/v3/tree.js";
31
+ import type { LeafPath, LeafTree, Slug } from "../../memory/v3/types.js";
32
+ import { getLogger } from "../../util/logger.js";
49
33
  import { getWorkspaceDir } from "../../util/platform.js";
34
+ import { ACTOR_PRINCIPALS, type RoutePolicy } from "../auth/route-policy.js";
35
+ import { RouteError } from "./errors.js";
50
36
  import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
51
37
 
52
- // Re-export the loop trace/cost shapes so the CLI renderer can import them from
53
- // this route module (type-only) without reaching across the
54
- // `cli/no-daemon-internals` boundary into `memory/v2/harness/*`.
55
- export type { RetrievalCost } from "../../memory/v2/harness/retriever.js";
56
- export type {
57
- DescentPass,
58
- DescentTrace,
59
- EdgeExpansion,
60
- GateDecision,
61
- ScoutResult,
62
- TreeLevel,
63
- } from "../../memory/v2/harness/trace.js";
64
- export type { LlmCallRecord };
65
- export type {
66
- ShadowDiffResult,
67
- ShadowDiffTurn,
68
- SlugFrequency,
69
- UnpairedShadowTurn,
70
- };
71
- export type { SeedCoretrievalResult };
72
-
73
- // ── Validate ────────────────────────────────────────────────────────────
74
-
75
- const MemoryV3ValidateParams = z.object({}).strict();
38
+ const log = getLogger("memory-v3-routes");
76
39
 
77
40
  /**
78
- * Wire shape for `memory_v3_validate`. Identical to the daemon-internal
79
- * {@link TreeValidationReport} every field is already serializable, so the
80
- * route forwards it verbatim. Re-exported as its own type so the CLI can
81
- * import it without reaching into the validator module.
41
+ * Filesystem location overrides. Production callers omit these and the handlers
42
+ * resolve the live workspace; tests inject a temp workspace + data dir to
43
+ * exercise the handlers without mocking module globals.
82
44
  */
83
- export type MemoryV3ValidateResult = TreeValidationReport;
84
-
85
- async function handleValidate({
86
- body = {},
87
- }: RouteHandlerArgs): Promise<MemoryV3ValidateResult> {
88
- // Read-only structural validation of the v3 tree. Like the v2 validate
89
- // route, it is intentionally ungated: operators dry-run it while the
90
- // v2 → v3 migration is mid-flight, well before any v3 flag flips.
91
- MemoryV3ValidateParams.parse(body);
92
- return validateTree(getWorkspaceDir());
45
+ export interface MemoryV3Deps {
46
+ dataDir?: string;
47
+ workspaceDir?: string;
93
48
  }
94
49
 
95
- // ── Tree ────────────────────────────────────────────────────────────────
50
+ // ---------------------------------------------------------------------------
51
+ // Shared loading helpers
52
+ // ---------------------------------------------------------------------------
96
53
 
97
- const MemoryV3TreeParams = z.object({}).strict();
54
+ /**
55
+ * Load the live leaf tree + its full slug universe.
56
+ *
57
+ * Page `leaves:` frontmatter is the authoritative source of page→leaf
58
+ * membership: we build a `pageLeaves` map from the page index and union it over
59
+ * `assignments.json` via `loadLeafTree(dataDir, pageLeaves)`, and derive the
60
+ * slug universe (`allSlugs`) from the page index itself. This mirrors
61
+ * `maybePrependV3Health` in `memory/v2/consolidation-job.ts` so the CLI
62
+ * `health` / `set-core` cost computations agree with the consolidation-injected
63
+ * health block instead of disagreeing by reading stale assignments.json only.
64
+ */
65
+ async function loadTreeAndSlugs(deps?: MemoryV3Deps): Promise<{
66
+ dataDir: string;
67
+ tree: LeafTree;
68
+ allSlugs: Slug[];
69
+ }> {
70
+ const workspaceDir = deps?.workspaceDir ?? getWorkspaceDir();
71
+ const dataDir = deps?.dataDir ?? resolveDataDir();
72
+
73
+ // Each page contributes its `leaves:` frontmatter as the authoritative leaf
74
+ // set for that slug; the slug universe is every page the index knows about.
75
+ const pageIndex = await getPageIndex(workspaceDir);
76
+ const pageLeaves = new Map<Slug, LeafPath[]>();
77
+ const allSlugs: Slug[] = [];
78
+ for (const entry of pageIndex.entries) {
79
+ pageLeaves.set(entry.slug, entry.leaves);
80
+ allSlugs.push(entry.slug);
81
+ }
98
82
 
99
- /** One node in the serialized tree view: its id and ordered child refs. */
100
- export interface MemoryV3TreeNodeView {
101
- id: string;
102
- children: Array<{ kind: "node" | "page"; ref: string }>;
83
+ const tree = await loadLeafTree(dataDir, pageLeaves);
84
+ return { dataDir, tree, allSlugs };
103
85
  }
104
86
 
105
- /**
106
- * JSON-serializable projection of the {@link TreeIndex}. `TreeIndex` keys its
107
- * adjacency by `Map`, which doesn't survive JSON, so the handler flattens it:
108
- * `root` is the entry-point node id and `nodes` is every node with its ordered
109
- * child refs. The CLI renderer walks `nodes`/`root` to print an indented tree,
110
- * marking shared-DAG re-entries.
111
- */
112
- export interface MemoryV3TreeResult {
113
- root: string;
114
- nodes: MemoryV3TreeNodeView[];
87
+ // ---------------------------------------------------------------------------
88
+ // health
89
+ // ---------------------------------------------------------------------------
90
+
91
+ export interface MemoryV3HealthResult {
92
+ /** Pre-rendered, human-readable report. Empty string when all-green. */
93
+ rendered: string;
94
+ /** The structural counts, for `--json` consumers. */
95
+ counts: {
96
+ unassigned: number;
97
+ danglingRefs: number;
98
+ novelClusters: number;
99
+ oversizedLeaves: number;
100
+ tinyLeaves: number;
101
+ };
115
102
  }
116
103
 
117
- async function handleTree({
118
- body = {},
119
- }: RouteHandlerArgs): Promise<MemoryV3TreeResult> {
120
- MemoryV3TreeParams.parse(body);
104
+ export async function handleMemoryV3Health(
105
+ deps?: MemoryV3Deps,
106
+ ): Promise<MemoryV3HealthResult> {
107
+ const { dataDir, tree, allSlugs } = await loadTreeAndSlugs(deps);
108
+ const core = await loadCore(dataDir);
109
+ const report = computeV3Health({ tree, allSlugs, core });
110
+ return {
111
+ rendered: renderV3Health(report),
112
+ counts: {
113
+ unassigned: report.unassigned.length,
114
+ danglingRefs: report.danglingRefs.length,
115
+ novelClusters: report.novelClusters.length,
116
+ oversizedLeaves: report.oversizedLeaves.length,
117
+ tinyLeaves: report.tinyLeaves.length,
118
+ },
119
+ };
120
+ }
121
121
 
122
- const tree = await getTreeIndex(getWorkspaceDir());
122
+ // ---------------------------------------------------------------------------
123
+ // set-core
124
+ // ---------------------------------------------------------------------------
123
125
 
124
- const nodes: MemoryV3TreeNodeView[] = [...tree.nodes.keys()]
125
- .sort()
126
- .map((id) => ({
127
- id,
128
- children: (tree.childrenByNode.get(id) ?? []).map((child) => ({
129
- kind: child.kind,
130
- ref: child.ref,
131
- })),
132
- }));
126
+ export interface MemoryV3SetCoreBody {
127
+ /** Leaves to add to the always-on core set. */
128
+ add?: LeafPath[];
129
+ /** Leaves to remove from the always-on core set. */
130
+ remove?: LeafPath[];
131
+ /**
132
+ * When true, persist the new core to `core.json` and invalidate the lanes.
133
+ * When false (default), compute the preview WITHOUT writing.
134
+ */
135
+ write?: boolean;
136
+ }
133
137
 
134
- return { root: tree.root, nodes };
138
+ export interface MemoryV3SetCoreResult {
139
+ /** The core leaf set that would result (or did result, when `write`). */
140
+ nextCore: LeafPath[];
141
+ /** Number of unique page slugs the new core set pins always-on. */
142
+ alwaysOnPageCount: number;
143
+ /** Whether `core.json` was written. */
144
+ written: boolean;
135
145
  }
136
146
 
137
- // ── Simulate ──────────────────────────────────────────────────────────────
138
-
139
- /** The five v3 retrieval lanes, in fanout order. */
140
- const V3_LANE_NAMES = ["hot", "sparse", "dense", "tree", "edges"] as const;
141
-
142
- export const MemoryV3SimulateParams = z
143
- .object({
144
- /** The ad-hoc user query to route a single synthetic turn against. */
145
- query: z.string().min(1, "memory.v3.simulate query must be non-empty"),
146
- /**
147
- * Optional `<now>` override. When omitted the live workspace NOW.md is
148
- * loaded so the run exercises production-like standing context.
149
- */
150
- nowText: z.string().optional(),
151
- /** Override `memory.v3.passCap` for this run only. */
152
- passCap: z
153
- .number()
154
- .int("memory.v3.simulate passCap must be an integer")
155
- .positive("memory.v3.simulate passCap must be positive")
156
- .optional(),
157
- /**
158
- * Restrict the run to this allowlist of lanes (others forced off). Omit to
159
- * inherit the live `memory.v3.lanes` toggles.
160
- */
161
- lanes: z
162
- .array(z.enum(V3_LANE_NAMES))
163
- .min(1, "memory.v3.simulate lanes must list at least one lane")
164
- .optional(),
165
- })
166
- .strict();
167
-
168
- /** The v3 lane toggle block, echoed back so the caller sees what actually ran. */
169
- export interface MemoryV3SimulateLanes {
170
- hot: boolean;
171
- sparse: boolean;
172
- dense: boolean;
173
- tree: boolean;
174
- edges: boolean;
147
+ /** Wire-format error code for a `set-core` add referencing an unknown leaf. */
148
+ export const MEMORY_V3_UNKNOWN_LEAF_CODE = "MEMORY_V3_UNKNOWN_LEAF";
149
+
150
+ /** Thrown when a `set-core` add entry does not exist in the live tree. */
151
+ export class UnknownLeafError extends Error {
152
+ constructor(public readonly unknown: LeafPath[]) {
153
+ super(
154
+ `Unknown leaf path(s) not present in the tree: ${unknown.join(", ")}`,
155
+ );
156
+ this.name = "UnknownLeafError";
157
+ }
175
158
  }
176
159
 
177
- /**
178
- * Wire shape for `memory_v3_simulate`. The loop's `sourceBySlug` Map is
179
- * flattened to a plain object (lane label per slug); `trace`/`cost` are already
180
- * JSON-serializable. `effectiveConfig` echoes the passCap + lane toggles the
181
- * run actually used after overrides were applied.
182
- */
183
- export interface MemoryV3SimulateResult {
184
- query: string;
185
- selectedSlugs: string[];
186
- /** Per-slug provenance lane: `hot` | `sparse` | `dense` | `tree` | `edge`. */
187
- sourceBySlug: Record<string, string>;
188
- trace: DescentTrace;
189
- cost: RetrievalCost;
190
- /** Non-null when the dense filter failed open on any pass. */
191
- failureReason: string | null;
192
- /**
193
- * Every v3 LLM call made during the run (filter / each descender / gate),
194
- * with full input + raw response. Empty unless capture was on (it always is
195
- * for simulate). Read-only debug surface — persisted nowhere.
196
- */
197
- llmCalls: LlmCallRecord[];
198
- effectiveConfig: {
199
- passCap: number;
200
- lanes: MemoryV3SimulateLanes;
201
- };
160
+ /** Persist the always-on core set back to `<dataDir>/core.json`. */
161
+ async function writeCore(dataDir: string, alwaysOn: LeafPath[]): Promise<void> {
162
+ await writeFile(
163
+ join(dataDir, "core.json"),
164
+ `${JSON.stringify({ alwaysOn }, null, 2)}\n`,
165
+ );
202
166
  }
203
167
 
204
- /**
205
- * Overlay the simulate overrides on the live config. Only the v3 passCap + lane
206
- * toggles are exposed; everything else (providers, prompts, scout quotas) stays
207
- * exactly as a live turn would see it. `write.coactivation` is forced off so the
208
- * simulate stays strictly read-only — the loop's only persistence path is the
209
- * co-activation insert, which this guarantees never fires.
210
- */
211
- function applyV3SimulateOverrides(
212
- live: AssistantConfig,
213
- overrides: { passCap?: number; lanes?: ReadonlyArray<string> },
214
- ): AssistantConfig {
215
- const liveV3 = live.memory.v3;
216
- const lanes = overrides.lanes
217
- ? {
218
- hot: overrides.lanes.includes("hot"),
219
- sparse: overrides.lanes.includes("sparse"),
220
- dense: overrides.lanes.includes("dense"),
221
- tree: overrides.lanes.includes("tree"),
222
- edges: overrides.lanes.includes("edges"),
223
- }
224
- : liveV3.lanes;
225
- return {
226
- ...live,
227
- memory: {
228
- ...live.memory,
229
- v3: {
230
- ...liveV3,
231
- ...(overrides.passCap !== undefined
232
- ? { passCap: overrides.passCap }
233
- : {}),
234
- lanes,
235
- write: { ...liveV3.write, coactivation: false },
236
- },
237
- },
238
- };
168
+ export async function handleMemoryV3SetCore(
169
+ body: MemoryV3SetCoreBody,
170
+ deps?: MemoryV3Deps,
171
+ ): Promise<MemoryV3SetCoreResult> {
172
+ const add = body.add ?? [];
173
+ const remove = body.remove ?? [];
174
+ const { dataDir, tree } = await loadTreeAndSlugs(deps);
175
+
176
+ // Validate every ADD entry exists in the live tree. Removing an entry that is
177
+ // already absent is a no-op (idempotent), so only adds are validated.
178
+ const unknown = add.filter((leaf) => !tree.leaves.has(leaf));
179
+ if (unknown.length > 0) throw new UnknownLeafError(unknown);
180
+
181
+ const core = await loadCore(dataDir);
182
+ for (const leaf of remove) core.delete(leaf);
183
+ for (const leaf of add) core.add(leaf);
184
+
185
+ // Drop any pre-existing core entry that no longer maps to a live leaf, so the
186
+ // preview reflects what the tree can actually pin. Sorted for stable output.
187
+ const nextCore = [...core].filter((leaf) => tree.leaves.has(leaf)).sort();
188
+ const nextCoreSet = new Set<LeafPath>(nextCore);
189
+
190
+ // Cost preview: the number of UNIQUE page slugs the new core pins always-on.
191
+ const alwaysOnPageCount = coreSlugs(tree, nextCoreSet).size;
192
+
193
+ if (body.write === true) {
194
+ await writeCore(dataDir, nextCore);
195
+ invalidateLanes();
196
+ log.info(
197
+ { coreSize: nextCore.length, alwaysOnPageCount },
198
+ "memory-v3 core updated",
199
+ );
200
+ }
201
+
202
+ return { nextCore, alwaysOnPageCount, written: body.write === true };
203
+ }
204
+
205
+ // ---------------------------------------------------------------------------
206
+ // reconcile
207
+ // ---------------------------------------------------------------------------
208
+
209
+ export interface MemoryV3ReconcileResult {
210
+ renames: Array<{ id?: string; oldPath: LeafPath; newPath: LeafPath }>;
211
+ deleted: LeafPath[];
212
+ prunedCore: LeafPath[];
239
213
  }
240
214
 
241
215
  /**
242
- * Run the v3 retrieval loop read-only against a single ad-hoc query and return
243
- * its selection, per-lane provenance, and full descent trace. Mirrors the
244
- * single-turn semantics of `memory_v2_simulate_router` (the query becomes the
245
- * just-arrived `userMessage` of one synthetic turn) and the input-build of the
246
- * v3 shadow middleware, but persists nothing.
216
+ * Reconcile page + core references against the live on-disk tree.
247
217
  *
248
- * The loop is invoked directly it is NOT gated by `memory.v3.enabled` /
249
- * `.shadow` (those gates live in the shadow middleware), so operators can probe
250
- * v3 retrieval while the flags are still off.
218
+ * `prevLeaves` describes the tree as it was BEFORE the maintainer's on-disk
219
+ * restructuring. We derive it from the current leaf set, which makes reconcile
220
+ * a safe convergence pass: renames/deletes already applied on disk diff to
221
+ * nothing, while it still rewrites any page/core ref left dangling and prunes
222
+ * stale core entries (and fail-closed restores on a residual dangling ref).
223
+ * `reconcileTree` snapshots, applies, validates, and invalidates the lanes.
251
224
  */
252
- async function handleSimulate({
253
- body = {},
254
- }: RouteHandlerArgs): Promise<MemoryV3SimulateResult> {
255
- const {
256
- query,
257
- nowText: rawNowText,
258
- passCap,
259
- lanes,
260
- } = MemoryV3SimulateParams.parse(body);
261
-
262
- const config = applyV3SimulateOverrides(loadConfig(), { passCap, lanes });
263
-
264
- const workspaceDir = getWorkspaceDir();
265
- const nowText =
266
- rawNowText !== undefined ? rawNowText : await loadNowText(workspaceDir);
267
-
268
- const input: RetrievalInput = {
269
- workspaceDir,
270
- recentTurnPairs: [{ assistantMessage: "", userMessage: query }],
271
- nowText,
272
- priorEverInjected: [],
273
- config,
225
+ export async function handleMemoryV3Reconcile(
226
+ deps?: MemoryV3Deps,
227
+ ): Promise<MemoryV3ReconcileResult> {
228
+ const workspaceDir = deps?.workspaceDir ?? getWorkspaceDir();
229
+ const dataDir = deps?.dataDir ?? resolveDataDir();
230
+ // v1: prev == current is intentional. Without a captured prior leaf snapshot
231
+ // we cannot detect renames/moves/splits, so this runs as a convergence /
232
+ // dangling-ref prune pass. Full rename detection is a follow-up.
233
+ const prevLeaves = await loadPrevLeaves(dataDir);
234
+
235
+ const result = await reconcileTree({ prevLeaves, dataDir, workspaceDir });
236
+ return {
237
+ renames: result.renames,
238
+ deleted: result.deleted,
239
+ prunedCore: result.prunedCore,
274
240
  };
241
+ }
275
242
 
276
- const llmCalls: LlmCallRecord[] = [];
277
- const output = await runRetrievalLoop(input, {
278
- db: getDb(),
279
- capture: (record) => llmCalls.push(record),
280
- });
243
+ /** The current leaf set as `LeafRef`s (path + stable id when present). */
244
+ async function loadPrevLeaves(dataDir: string): Promise<LeafRef[]> {
245
+ const tree = await loadLeafTree(dataDir);
246
+ return [...tree.leaves.values()].map((node) => ({
247
+ path: node.path,
248
+ ...(node.frontmatter.id ? { id: node.frontmatter.id } : {}),
249
+ }));
250
+ }
281
251
 
282
- const sourceBySlug: Record<string, string> = {};
283
- for (const [slug, lane] of output.sourceBySlug.entries()) {
284
- sourceBySlug[slug] = lane;
285
- }
252
+ // ---------------------------------------------------------------------------
253
+ // rebuild-index
254
+ // ---------------------------------------------------------------------------
286
255
 
287
- return {
288
- query,
289
- selectedSlugs: output.selectedSlugs,
290
- sourceBySlug,
291
- trace: output.trace ?? { passes: [] },
292
- cost: output.cost ?? {},
293
- failureReason: output.failureReason ?? null,
294
- llmCalls,
295
- effectiveConfig: {
296
- passCap: config.memory.v3.passCap,
297
- lanes: config.memory.v3.lanes,
298
- },
299
- };
256
+ export interface MemoryV3RebuildIndexResult {
257
+ ok: true;
300
258
  }
301
259
 
302
- // ── Shadow-diff ─────────────────────────────────────────────────────────
303
-
304
- /** Default pairing tolerance: a shadow row + its router sibling land ~1-2s apart. */
305
- const DEFAULT_SHADOW_DIFF_TOLERANCE_SEC = 10;
306
- /** Default cap on per-turn detail rows returned (aggregates are unbounded). */
307
- const DEFAULT_SHADOW_DIFF_LIMIT = 50;
308
- /** Milliseconds per day, for the `sinceDays` read-window cutoff. */
309
- const MS_PER_DAY = 86_400_000;
310
-
311
- const MemoryV3ShadowDiffParams = z
312
- .object({
313
- /** Only consider shadow rows newer than this many days. Omit for all rows. */
314
- sinceDays: z
315
- .number()
316
- .positive("memory.v3.shadow-diff sinceDays must be positive")
317
- .optional(),
318
- /** Max |Δt| (seconds) to pair a shadow row with a router row. */
319
- toleranceSec: z
320
- .number()
321
- .positive("memory.v3.shadow-diff toleranceSec must be positive")
322
- .optional(),
323
- /** Cap on per-turn detail rows in the response (newest first). */
324
- limit: z
325
- .number()
326
- .int("memory.v3.shadow-diff limit must be an integer")
327
- .positive("memory.v3.shadow-diff limit must be positive")
328
- .optional(),
329
- })
330
- .strict();
331
-
332
260
  /**
333
- * Compare the v3 shadow selections against the live v2 router selections,
334
- * turn-for-turn, from the activation log. Read-only: reads `v3_shadow` rows and
335
- * the `router` rows they pair with (bounded to those conversations + time
336
- * span), then diffs each pair. Requires v3 shadow mode to have been running
337
- * (`memory.v3.enabled` + `.shadow`) so the `v3_shadow` rows exist; the route
338
- * itself runs no LLM and writes nothing.
261
+ * Invalidate the v3 shadow lanes so the next turn rebuilds the tree/needle
262
+ * from the current on-disk state. Runs in-daemon so it acts on the live
263
+ * process's cached lanes (an in-CLI call would invalidate nothing).
339
264
  */
340
- async function handleShadowDiff({
341
- body = {},
342
- }: RouteHandlerArgs): Promise<ShadowDiffResult> {
343
- const { sinceDays, toleranceSec, limit } =
344
- MemoryV3ShadowDiffParams.parse(body);
345
-
346
- const sinceMs =
347
- sinceDays !== undefined ? Date.now() - sinceDays * MS_PER_DAY : null;
348
- const toleranceMs =
349
- (toleranceSec ?? DEFAULT_SHADOW_DIFF_TOLERANCE_SEC) * 1000;
350
-
351
- const { shadow, router } = readActivationLogsForShadowDiff({
352
- sinceMs,
353
- paddingMs: toleranceMs,
354
- });
355
-
356
- return computeShadowDiff(shadow, router, {
357
- toleranceMs,
358
- detailLimit: limit ?? DEFAULT_SHADOW_DIFF_LIMIT,
359
- });
265
+ export async function handleMemoryV3RebuildIndex(): Promise<MemoryV3RebuildIndexResult> {
266
+ invalidateLanes();
267
+ log.info("memory-v3 lanes invalidated (rebuild-index)");
268
+ return { ok: true };
360
269
  }
361
270
 
362
- // ── Seed co-retrieval edges ───────────────────────────────────────────────
363
-
364
- const MemoryV3SeedEdgesParams = z
365
- .object({
366
- /** A pair must co-occur on at least this many router turns to earn an edge. */
367
- minCount: z
368
- .number()
369
- .int("memory.v3.seed-edges minCount must be an integer")
370
- .positive("memory.v3.seed-edges minCount must be positive")
371
- .optional(),
372
- /** Neighbors kept per source node, ranked by NPMI descending. */
373
- topK: z
374
- .number()
375
- .int("memory.v3.seed-edges topK must be an integer")
376
- .positive("memory.v3.seed-edges topK must be positive")
377
- .optional(),
378
- /** Exclude neighbors selected on more than this fraction of all turns. */
379
- maxNeighborFreqRatio: z
380
- .number()
381
- .positive("memory.v3.seed-edges maxNeighborFreqRatio must be positive")
382
- .max(1, "memory.v3.seed-edges maxNeighborFreqRatio must be <= 1")
383
- .optional(),
384
- /** Flat weight each seeded edge is written at. */
385
- seedWeight: z
386
- .number()
387
- .positive("memory.v3.seed-edges seedWeight must be positive")
388
- .optional(),
389
- })
390
- .strict();
271
+ // ---------------------------------------------------------------------------
272
+ // Route definitions (RouteHandlerArgs adapters over the handlers above)
273
+ // ---------------------------------------------------------------------------
274
+
275
+ /** Read-only verbs (the `health` report) require only `settings.read`. */
276
+ const READ_POLICY: RoutePolicy = {
277
+ requiredScopes: ["settings.read"],
278
+ allowedPrincipalTypes: ACTOR_PRINCIPALS,
279
+ };
391
280
 
392
281
  /**
393
- * Build the co-retrieval graph from the v2 router's selection history and
394
- * persist it into `memory_v3_auto_edges`. This is the one write surface among
395
- * the v3 routes it warm-starts the learned edge graph that the edge-expansion
396
- * lane merges (when `memory.v3.edges.learnedAdjacencyThreshold > 0`). Idempotent:
397
- * re-running upserts each seeded edge to the flat seed weight without unbounded
398
- * growth. Runs no LLM.
282
+ * Mutating verbs require `settings.write`. `set-core --write`, `reconcile`, and
283
+ * `rebuild-index` write `core.json`, rewrite page frontmatter, and invalidate
284
+ * the live lanes, so a `settings.read`-only principal must not reach them.
285
+ * (`set-core` without `write` is a preview, but it shares this route, so the
286
+ * route as a whole is gated on write.)
399
287
  */
400
- async function handleSeedEdges({
401
- body = {},
402
- }: RouteHandlerArgs): Promise<SeedCoretrievalResult> {
403
- const { minCount, topK, maxNeighborFreqRatio, seedWeight } =
404
- MemoryV3SeedEdgesParams.parse(body);
405
- return seedCoretrievalEdges(getDb(), {
406
- minCount: minCount ?? DEFAULT_SEED_OPTIONS.minCount,
407
- topK: topK ?? DEFAULT_SEED_OPTIONS.topK,
408
- maxNeighborFreqRatio:
409
- maxNeighborFreqRatio ?? DEFAULT_SEED_OPTIONS.maxNeighborFreqRatio,
410
- seedWeight: seedWeight ?? DEFAULT_SEED_OPTIONS.seedWeight,
411
- });
412
- }
413
-
414
- // ── Route definitions ───────────────────────────────────────────────────
288
+ const WRITE_POLICY: RoutePolicy = {
289
+ requiredScopes: ["settings.write"],
290
+ allowedPrincipalTypes: ACTOR_PRINCIPALS,
291
+ };
415
292
 
416
293
  export const ROUTES: RouteDefinition[] = [
417
294
  {
418
- operationId: "memory_v3_validate",
295
+ operationId: "memory_v3_health",
419
296
  method: "POST",
420
- endpoint: "memory/v3/validate",
421
- handler: handleValidate,
422
- summary: "Validate the memory v3 tree structure (read-only)",
423
- description:
424
- "Read-only structural validation of the hand-authored v3 tree DAG. Reports dangling child refs, orphan pages, cycles, stale compositional indexes, and unknown edge targets. Writes nothing and runs no LLM — operators dry-run it while the v2 → v3 migration is in flight.",
297
+ policy: READ_POLICY,
298
+ endpoint: "memory/v3/health",
299
+ handler: () => handleMemoryV3Health(),
300
+ summary: "Print the v3 structural health report (read-only)",
425
301
  tags: ["memory"],
426
- requestBody: MemoryV3ValidateParams,
427
302
  },
428
303
  {
429
- operationId: "memory_v3_tree",
304
+ operationId: "memory_v3_set_core",
430
305
  method: "POST",
431
- endpoint: "memory/v3/tree",
432
- handler: handleTree,
433
- summary: "Return a serializable view of the memory v3 tree DAG (read-only)",
434
- description:
435
- "Returns the v3 tree root id plus every node and its ordered child refs (page:/node:) as a JSON-serializable projection of the in-memory TreeIndex. Read-only; the CLI uses it to print an indented tree with shared-DAG re-entries marked.",
436
- tags: ["memory"],
437
- requestBody: MemoryV3TreeParams,
438
- },
439
- {
440
- operationId: "memory_v3_simulate",
441
- method: "POST",
442
- endpoint: "memory/v3/simulate",
443
- handler: handleSimulate,
444
- summary:
445
- "Dry-run the v3 retrieval loop against an ad-hoc query (read-only)",
446
- description:
447
- "Runs the v3 multi-lane bounded-descent retrieval loop read-only against a single synthetic turn built from the supplied query plus the live (or supplied) NOW context. Returns the selected page slugs, per-lane provenance, the full multi-pass descent trace, and accumulated cost. Optional passCap / lane-allowlist overrides apply on top of live config. Invoked directly (not gated by memory.v3.enabled/shadow) so operators can probe v3 retrieval before flipping the flags; writes nothing (co-activation persistence is forced off), though each pass still spends the loop's filter + gate LLM calls.",
306
+ policy: WRITE_POLICY,
307
+ endpoint: "memory/v3/set-core",
308
+ handler: async ({ body = {} }: RouteHandlerArgs) => {
309
+ try {
310
+ return await handleMemoryV3SetCore(body as MemoryV3SetCoreBody);
311
+ } catch (err) {
312
+ if (err instanceof UnknownLeafError) {
313
+ throw new RouteError(err.message, MEMORY_V3_UNKNOWN_LEAF_CODE, 422);
314
+ }
315
+ throw err;
316
+ }
317
+ },
318
+ summary: "Add/remove always-on core leaves (validates + previews cost)",
448
319
  tags: ["memory"],
449
- requestBody: MemoryV3SimulateParams,
450
320
  },
451
321
  {
452
- operationId: "memory_v3_shadow_diff",
322
+ operationId: "memory_v3_reconcile",
453
323
  method: "POST",
454
- endpoint: "memory/v3/shadow-diff",
455
- handler: handleShadowDiff,
324
+ policy: WRITE_POLICY,
325
+ endpoint: "memory/v3/reconcile",
326
+ handler: () => handleMemoryV3Reconcile(),
456
327
  summary:
457
- "Diff v3 shadow selections against live v2 router selections (read-only)",
458
- description:
459
- "Compares the v3 shadow-mode selections against the live v2 router selections turn-for-turn, from the memory activation log. Pairs each v3_shadow row with the nearest v2 router row in the same conversation (by timestamp, within a tolerance — the turn columns use different counters), then reports per-turn and aggregate overlap, what v3 surfaced that v2 did not, and what v2 had that v3 dropped, broken down by v3 provenance lane. The v2 comparand is the router's fresh per-turn pick (status='injected'), not its accumulated in-context set. Requires that v3 shadow mode has been running so v3_shadow rows exist; the route runs no LLM and writes nothing.",
328
+ "v1 convergence/prune pass over page+core refs (no rename detection without a prior snapshot)",
460
329
  tags: ["memory"],
461
- requestBody: MemoryV3ShadowDiffParams,
462
330
  },
463
331
  {
464
- operationId: "memory_v3_seed_edges",
332
+ operationId: "memory_v3_rebuild_index",
465
333
  method: "POST",
466
- endpoint: "memory/v3/seed-edges",
467
- handler: handleSeedEdges,
468
- summary: "Seed the learned co-retrieval edge graph from v2 router history",
469
- description:
470
- "Builds an NPMI-scored co-retrieval graph from the v2 router's per-turn selections (memory_v2_activation_logs, status='injected') and persists it into memory_v3_auto_edges, warm-starting the learned edge graph that the v3 edge-expansion lane merges with curated edges when memory.v3.edges.learnedAdjacencyThreshold > 0. NPMI plus a min co-occurrence floor and an always-on frequency ceiling keep the neighborhoods associative rather than base-rate noise. Idempotent (upserts to a flat seed weight). Runs no LLM; the only write among the v3 routes.",
334
+ policy: WRITE_POLICY,
335
+ endpoint: "memory/v3/rebuild-index",
336
+ handler: () => handleMemoryV3RebuildIndex(),
337
+ summary: "Invalidate the v3 lanes so the next turn rebuilds",
471
338
  tags: ["memory"],
472
- requestBody: MemoryV3SeedEdgesParams,
473
339
  },
474
340
  ];