@vellumai/assistant 0.6.4 → 0.6.5

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 (717) hide show
  1. package/.prettierignore +5 -0
  2. package/ARCHITECTURE.md +32 -36
  3. package/Dockerfile +12 -0
  4. package/README.md +3 -4
  5. package/bun.lock +8 -3
  6. package/docs/architecture/integrations.md +1 -20
  7. package/docs/architecture/security.md +16 -16
  8. package/docs/error-handling.md +111 -0
  9. package/docs/skills.md +10 -10
  10. package/docs/stt-provider-onboarding.md +2 -1
  11. package/knip.json +9 -2
  12. package/node_modules/@vellumai/ces-contracts/package.json +2 -1
  13. package/node_modules/@vellumai/ces-contracts/src/__tests__/trust-rules.test.ts +471 -0
  14. package/node_modules/@vellumai/ces-contracts/src/trust-rules.ts +398 -4
  15. package/node_modules/@vellumai/credential-storage/bun.lock +2 -2
  16. package/node_modules/@vellumai/credential-storage/package.json +2 -2
  17. package/node_modules/@vellumai/credential-storage/src/oauth-runtime.ts +20 -2
  18. package/node_modules/@vellumai/egress-proxy/bun.lock +2 -2
  19. package/node_modules/@vellumai/egress-proxy/package.json +2 -2
  20. package/openapi.yaml +123 -11
  21. package/package.json +6 -3
  22. package/scripts/generate-openapi.ts +50 -11
  23. package/src/__tests__/agent-loop-callsite-precedence.test.ts +318 -0
  24. package/src/__tests__/agent-loop-sentry-hygiene.test.ts +137 -0
  25. package/src/__tests__/agent-loop.test.ts +112 -1
  26. package/src/__tests__/anthropic-error-formatting.test.ts +98 -0
  27. package/src/__tests__/anthropic-provider.test.ts +171 -2
  28. package/src/__tests__/approval-cascade.test.ts +31 -10
  29. package/src/__tests__/approval-routes-http.test.ts +134 -10
  30. package/src/__tests__/assistant-attachments.test.ts +44 -0
  31. package/src/__tests__/assistant-feature-flags-integration.test.ts +29 -0
  32. package/src/__tests__/browser-fill-credential.test.ts +1 -1
  33. package/src/__tests__/browser-identifier-parity-guard.test.ts +53 -0
  34. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +23 -33
  35. package/src/__tests__/browser-skill-endstate.test.ts +51 -182
  36. package/src/__tests__/btw-routes.test.ts +47 -1
  37. package/src/__tests__/call-controller.test.ts +1 -2
  38. package/src/__tests__/call-site-routing-provider.test.ts +214 -0
  39. package/src/__tests__/catalog-cache.test.ts +27 -4
  40. package/src/__tests__/channel-approval-routes.test.ts +4 -4
  41. package/src/__tests__/channel-reply-delivery.test.ts +300 -2
  42. package/src/__tests__/checker.test.ts +428 -501
  43. package/src/__tests__/cli-command-risk-guard.test.ts +30 -33
  44. package/src/__tests__/compaction-circuit-breaker.test.ts +336 -0
  45. package/src/__tests__/compaction.benchmark.test.ts +1 -1
  46. package/src/__tests__/config-analysis.test.ts +11 -28
  47. package/src/__tests__/config-loader-backfill.test.ts +174 -0
  48. package/src/__tests__/config-loader-corrupt.test.ts +183 -0
  49. package/src/__tests__/config-loader-quarantine-bulletin.test.ts +202 -0
  50. package/src/__tests__/config-schema-cmd.test.ts +11 -5
  51. package/src/__tests__/config-schema.test.ts +427 -114
  52. package/src/__tests__/config-watcher.test.ts +2 -2
  53. package/src/__tests__/contact-store-user-file.test.ts +72 -73
  54. package/src/__tests__/contacts-write.test.ts +4 -4
  55. package/src/__tests__/context-token-estimator.test.ts +191 -1
  56. package/src/__tests__/context-window-manager.test.ts +530 -2
  57. package/src/__tests__/conversation-abort-tool-results.test.ts +30 -16
  58. package/src/__tests__/conversation-agent-loop-overflow.test.ts +61 -17
  59. package/src/__tests__/conversation-agent-loop.test.ts +412 -82
  60. package/src/__tests__/conversation-attachments.test.ts +1 -1
  61. package/src/__tests__/conversation-confirmation-signals.test.ts +30 -9
  62. package/src/__tests__/conversation-error.test.ts +37 -6
  63. package/src/__tests__/conversation-history-web-search.test.ts +6 -0
  64. package/src/__tests__/conversation-init.benchmark.test.ts +36 -0
  65. package/src/__tests__/conversation-lifecycle.test.ts +336 -0
  66. package/src/__tests__/conversation-load-history-repair.test.ts +27 -10
  67. package/src/__tests__/conversation-pre-run-repair.test.ts +30 -16
  68. package/src/__tests__/conversation-process-callsite.test.ts +306 -0
  69. package/src/__tests__/conversation-provider-retry-repair.test.ts +30 -16
  70. package/src/__tests__/conversation-queue.test.ts +41 -26
  71. package/src/__tests__/conversation-routes-disk-view.test.ts +29 -1
  72. package/src/__tests__/conversation-routes-slash-commands.test.ts +31 -3
  73. package/src/__tests__/conversation-runtime-assembly.test.ts +2735 -55
  74. package/src/__tests__/conversation-runtime-workspace.test.ts +12 -12
  75. package/src/__tests__/conversation-skill-tools.test.ts +12 -146
  76. package/src/__tests__/conversation-slash-queue.test.ts +34 -19
  77. package/src/__tests__/conversation-slash-unknown.test.ts +30 -16
  78. package/src/__tests__/conversation-speed-override.test.ts +30 -11
  79. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1035 -0
  80. package/src/__tests__/conversation-surfaces-standalone.test.ts +630 -0
  81. package/src/__tests__/conversation-title-service.test.ts +2 -2
  82. package/src/__tests__/conversation-tool-setup-batch-authorized.test.ts +1 -1
  83. package/src/__tests__/conversation-unread-route.test.ts +2 -2
  84. package/src/__tests__/conversation-usage.test.ts +3 -1
  85. package/src/__tests__/conversation-workspace-cache-state.test.ts +31 -10
  86. package/src/__tests__/conversation-workspace-injection.test.ts +43 -15
  87. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +44 -16
  88. package/src/__tests__/credential-broker-browser-fill.test.ts +110 -0
  89. package/src/__tests__/credential-security-invariants.test.ts +3 -0
  90. package/src/__tests__/credential-storage-oauth-compat.test.ts +18 -0
  91. package/src/__tests__/credential-storage-static-compat.test.ts +28 -0
  92. package/src/__tests__/credential-vault-unit.test.ts +135 -19
  93. package/src/__tests__/credentials-cli.test.ts +1 -9
  94. package/src/__tests__/cross-provider-web-search.test.ts +84 -0
  95. package/src/__tests__/daemon-server-persist-and-process-callsite.test.ts +92 -0
  96. package/src/__tests__/delete-propagation.test.ts +437 -0
  97. package/src/__tests__/dm-backfill.test.ts +417 -0
  98. package/src/__tests__/dm-persistence.test.ts +227 -0
  99. package/src/__tests__/edit-propagation.test.ts +280 -0
  100. package/src/__tests__/ephemeral-permissions.test.ts +93 -3
  101. package/src/__tests__/estimator-calibration-integration.test.ts +208 -0
  102. package/src/__tests__/estimator-calibration.test.ts +213 -0
  103. package/src/__tests__/extension-id-sync-guard.test.ts +26 -7
  104. package/src/__tests__/file-write-tool.test.ts +151 -1
  105. package/src/__tests__/filing-service.test.ts +255 -0
  106. package/src/__tests__/gemini-provider.test.ts +0 -3
  107. package/src/__tests__/guardian-grant-minting.test.ts +8 -0
  108. package/src/__tests__/headless-browser-interactions.test.ts +1 -1
  109. package/src/__tests__/heartbeat-service.test.ts +96 -15
  110. package/src/__tests__/host-shell-tool.test.ts +124 -18
  111. package/src/__tests__/http-user-message-parity.test.ts +29 -1
  112. package/src/__tests__/inbound-slack-persistence.test.ts +340 -0
  113. package/src/__tests__/intent-routing.test.ts +1 -40
  114. package/src/__tests__/llm-catalog-parity.test.ts +174 -0
  115. package/src/__tests__/llm-context-normalization.test.ts +121 -0
  116. package/src/__tests__/llm-resolver.test.ts +214 -0
  117. package/src/__tests__/llm-schema.test.ts +223 -0
  118. package/src/__tests__/managed-proxy-context.test.ts +6 -2
  119. package/src/__tests__/messaging-skill-split.test.ts +3 -34
  120. package/src/__tests__/migration-import-from-url.test.ts +684 -0
  121. package/src/__tests__/model-intents.test.ts +9 -83
  122. package/src/__tests__/notification-decision-fallback.test.ts +0 -10
  123. package/src/__tests__/notification-decision-identity.test.ts +0 -9
  124. package/src/__tests__/notification-decision-recipient-context.test.ts +0 -9
  125. package/src/__tests__/oauth-store.test.ts +10 -7
  126. package/src/__tests__/oauth2-gateway-transport.test.ts +8 -3
  127. package/src/__tests__/oauth2-refresh-retry.test.ts +279 -0
  128. package/src/__tests__/openai-provider.test.ts +7 -0
  129. package/src/__tests__/openai-responses-provider.test.ts +396 -0
  130. package/src/__tests__/openrouter-provider-only.test.ts +135 -0
  131. package/src/__tests__/outbound-slack-persistence.test.ts +293 -0
  132. package/src/__tests__/permission-checker-host-gate.test.ts +1 -1
  133. package/src/__tests__/permission-mode.test.ts +16 -0
  134. package/src/__tests__/permission-types.test.ts +0 -1
  135. package/src/__tests__/persona-resolver.test.ts +13 -13
  136. package/src/__tests__/pkb-autoinject.test.ts +37 -1
  137. package/src/__tests__/platform-bash-auto-approve.test.ts +1 -1
  138. package/src/__tests__/pricing.test.ts +50 -3
  139. package/src/__tests__/profiler-routes.test.ts +1 -1
  140. package/src/__tests__/provider-commit-message-generator.test.ts +14 -84
  141. package/src/__tests__/provider-env-vars-scope.test.ts +52 -0
  142. package/src/__tests__/provider-error-scenarios.test.ts +135 -6
  143. package/src/__tests__/provider-managed-proxy-integration.test.ts +42 -11
  144. package/src/__tests__/provider-registry-ollama.test.ts +1 -2
  145. package/src/__tests__/proxy-approval-callback.test.ts +0 -1
  146. package/src/__tests__/reaction-persistence.test.ts +560 -0
  147. package/src/__tests__/relay-server.test.ts +1 -1
  148. package/src/__tests__/require-fresh-approval.test.ts +1 -1
  149. package/src/__tests__/retry-openrouter-only-normalization.test.ts +136 -0
  150. package/src/__tests__/retry-thinking-tool-choice.test.ts +226 -0
  151. package/src/__tests__/risk-classifier-parity.test.ts +230 -0
  152. package/src/__tests__/sanitize-config-for-transfer.test.ts +78 -1
  153. package/src/__tests__/secret-ingress-http.test.ts +28 -0
  154. package/src/__tests__/secret-prompter-channel-fallback.test.ts +125 -0
  155. package/src/__tests__/secret-routes-managed-proxy.test.ts +2 -3
  156. package/src/__tests__/secret-scanner-executor.test.ts +1 -1
  157. package/src/__tests__/send-endpoint-busy.test.ts +29 -1
  158. package/src/__tests__/server-history-render.test.ts +31 -0
  159. package/src/__tests__/shell-parser-property.test.ts +13 -13
  160. package/src/__tests__/skill-cache-store.test.ts +182 -0
  161. package/src/__tests__/skills.test.ts +19 -33
  162. package/src/__tests__/slack-app-setup-skill-regression.test.ts +3 -1
  163. package/src/__tests__/slack-skill.test.ts +3 -8
  164. package/src/__tests__/starter-bundle.test.ts +35 -0
  165. package/src/__tests__/subagent-call-site-routing.test.ts +280 -0
  166. package/src/__tests__/suggestion-routes.test.ts +160 -3
  167. package/src/__tests__/system-prompt.test.ts +22 -35
  168. package/src/__tests__/task-runner.test.ts +3 -1
  169. package/src/__tests__/tcc-sandbox-deny.test.ts +198 -0
  170. package/src/__tests__/terminal-tools.test.ts +8 -0
  171. package/src/__tests__/test-support/browser-skill-harness.ts +2 -52
  172. package/src/__tests__/thread-backfill.test.ts +941 -0
  173. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -2
  174. package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -2
  175. package/src/__tests__/tool-executor.test.ts +60 -94
  176. package/src/__tests__/trust-store.test.ts +442 -109
  177. package/src/__tests__/update-bulletin-job.test.ts +389 -0
  178. package/src/__tests__/usage-cache-backfill-migration.test.ts +3 -1
  179. package/src/__tests__/verification-control-plane-policy.test.ts +1 -22
  180. package/src/__tests__/voice-session-bridge.test.ts +39 -0
  181. package/src/__tests__/volume-security-guard.test.ts +3 -2
  182. package/src/__tests__/web-search-history.test.ts +337 -0
  183. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +343 -0
  184. package/src/__tests__/workspace-migration-043-release-notes-latex-rendering.test.ts +202 -0
  185. package/src/__tests__/workspace-migration-045-release-notes-meet-avatar.test.ts +210 -0
  186. package/src/__tests__/workspace-migration-drop-user-md.test.ts +11 -11
  187. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +841 -0
  188. package/src/__tests__/workspace-policy.test.ts +1 -13
  189. package/src/acp/client-handler.ts +1 -2
  190. package/src/agent/loop.ts +209 -17
  191. package/src/avatar/resvg-lazy.test.ts +136 -0
  192. package/src/avatar/resvg-lazy.ts +82 -9
  193. package/src/avatar/traits-png-sync.ts +21 -1
  194. package/src/browser/__tests__/operations.test.ts +163 -0
  195. package/src/browser/identifiers.ts +51 -0
  196. package/src/browser/operations.ts +660 -0
  197. package/src/browser/types.ts +81 -0
  198. package/src/calls/guardian-question-copy.ts +2 -2
  199. package/src/calls/telephony-stt-routing.ts +1 -1
  200. package/src/calls/voice-session-bridge.ts +1 -0
  201. package/src/cli/AGENTS.md +1 -1
  202. package/src/cli/commands/__tests__/attachment.test.ts +438 -0
  203. package/src/cli/commands/__tests__/browser.test.ts +554 -0
  204. package/src/cli/commands/__tests__/cache.test.ts +623 -0
  205. package/src/cli/commands/__tests__/email-list.test.ts +6 -0
  206. package/src/cli/commands/__tests__/email-send.test.ts +93 -1
  207. package/src/cli/commands/__tests__/image-generation.test.ts +666 -0
  208. package/src/cli/commands/__tests__/inference-send.test.ts +451 -0
  209. package/src/cli/commands/__tests__/stt-transcribe.test.ts +454 -0
  210. package/src/cli/commands/__tests__/task.test.ts +913 -0
  211. package/src/cli/commands/__tests__/tts-synthesize.test.ts +594 -0
  212. package/src/cli/commands/__tests__/ui-confirm.test.ts +650 -0
  213. package/src/cli/commands/__tests__/ui.test.ts +1215 -0
  214. package/src/cli/commands/__tests__/watchers.test.ts +716 -0
  215. package/src/cli/commands/attachment.ts +182 -0
  216. package/src/cli/commands/browser.ts +350 -0
  217. package/src/cli/commands/cache.ts +341 -0
  218. package/src/cli/commands/completions.ts +0 -3
  219. package/src/cli/commands/config.ts +6 -6
  220. package/src/cli/commands/conversations-import.ts +347 -0
  221. package/src/cli/commands/conversations.ts +14 -1
  222. package/src/cli/commands/email.ts +234 -194
  223. package/src/cli/commands/image-generation.ts +300 -0
  224. package/src/cli/commands/inference.ts +200 -0
  225. package/src/cli/commands/memory.ts +127 -17
  226. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +0 -1
  227. package/src/cli/commands/platform/__tests__/connect.test.ts +0 -1
  228. package/src/cli/commands/platform/__tests__/disconnect.test.ts +0 -1
  229. package/src/cli/commands/platform/__tests__/status.test.ts +0 -1
  230. package/src/cli/commands/stt.ts +339 -0
  231. package/src/cli/commands/task.ts +795 -0
  232. package/src/cli/commands/trust.ts +50 -19
  233. package/src/cli/commands/tts.ts +273 -0
  234. package/src/cli/commands/ui.ts +670 -0
  235. package/src/cli/commands/watchers.ts +509 -0
  236. package/src/cli/lib/daemon-credential-client.ts +0 -19
  237. package/src/cli/program.ts +23 -4
  238. package/src/cli.ts +0 -37
  239. package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +23 -1
  240. package/src/config/bundled-skills/media-processing/services/reduce.ts +1 -1
  241. package/src/config/bundled-skills/messaging/SKILL.md +2 -2
  242. package/src/config/bundled-skills/messaging/TOOLS.json +4 -0
  243. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +8 -1
  244. package/src/config/bundled-skills/messaging/tools/messaging-read.ts +15 -1
  245. package/src/config/bundled-skills/messaging/tools/messaging-search.ts +21 -1
  246. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +11 -12
  247. package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -8
  248. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  249. package/src/config/bundled-tool-registry.ts +0 -175
  250. package/src/config/env.ts +7 -2
  251. package/src/config/feature-flag-registry.json +25 -9
  252. package/src/config/llm-resolver.ts +128 -0
  253. package/src/config/loader.ts +194 -10
  254. package/src/config/raw-config-utils.ts +30 -2
  255. package/src/config/sanitize-for-transfer.ts +35 -0
  256. package/src/config/schema.ts +30 -41
  257. package/src/config/schemas/analysis.ts +3 -22
  258. package/src/config/schemas/calls.ts +0 -4
  259. package/src/config/schemas/filing.ts +2 -7
  260. package/src/config/schemas/heartbeat.ts +0 -5
  261. package/src/config/schemas/inference.ts +3 -23
  262. package/src/config/schemas/llm.ts +318 -0
  263. package/src/config/schemas/memory-processing.ts +1 -9
  264. package/src/config/schemas/notifications.ts +4 -11
  265. package/src/config/schemas/platform.ts +3 -9
  266. package/src/config/schemas/security.ts +33 -0
  267. package/src/config/schemas/services.ts +9 -4
  268. package/src/config/schemas/stt.ts +1 -0
  269. package/src/config/schemas/tts.ts +53 -0
  270. package/src/config/schemas/updates.ts +1 -1
  271. package/src/config/schemas/workspace-git.ts +3 -40
  272. package/src/config/skills.ts +2 -2
  273. package/src/context/__tests__/compact-prompt.test.ts +45 -0
  274. package/src/context/__tests__/microcompact.test.ts +805 -0
  275. package/src/context/estimator-calibration.ts +136 -0
  276. package/src/context/microcompact.ts +443 -0
  277. package/src/context/prompts/compact.md +12 -0
  278. package/src/context/token-estimator.ts +61 -3
  279. package/src/context/window-manager.ts +229 -25
  280. package/src/credential-execution/approval-bridge.ts +0 -1
  281. package/src/credential-execution/executable-discovery.ts +19 -8
  282. package/src/credential-execution/process-manager.test.ts +109 -0
  283. package/src/credential-execution/process-manager.ts +65 -2
  284. package/src/daemon/approval-generators.ts +29 -4
  285. package/src/daemon/assistant-attachments.ts +24 -13
  286. package/src/daemon/classifier.ts +2 -2
  287. package/src/daemon/config-watcher.ts +0 -1
  288. package/src/daemon/context-overflow-reducer.ts +4 -1
  289. package/src/daemon/conversation-agent-loop-handlers.ts +79 -12
  290. package/src/daemon/conversation-agent-loop.ts +462 -80
  291. package/src/daemon/conversation-attachments.ts +2 -6
  292. package/src/daemon/conversation-error.ts +36 -1
  293. package/src/daemon/conversation-lifecycle.ts +30 -6
  294. package/src/daemon/conversation-messaging.ts +73 -4
  295. package/src/daemon/conversation-process.ts +10 -4
  296. package/src/daemon/conversation-queue-manager.ts +3 -0
  297. package/src/daemon/conversation-runtime-assembly.ts +760 -29
  298. package/src/daemon/conversation-slash.ts +2 -2
  299. package/src/daemon/conversation-surfaces.ts +389 -1
  300. package/src/daemon/conversation-tool-setup.ts +10 -5
  301. package/src/daemon/conversation-usage.ts +1 -1
  302. package/src/daemon/conversation.ts +118 -30
  303. package/src/daemon/external-skills-bootstrap.ts +41 -0
  304. package/src/daemon/guardian-action-generators.ts +34 -14
  305. package/src/daemon/handlers/config-model.test.ts +86 -0
  306. package/src/daemon/handlers/config-model.ts +54 -12
  307. package/src/daemon/handlers/conversations.ts +9 -2
  308. package/src/daemon/handlers/shared.ts +39 -11
  309. package/src/daemon/handlers/skills.ts +2 -2
  310. package/src/daemon/handlers/slack-channel-oauth-install.ts +197 -0
  311. package/src/daemon/lifecycle.ts +76 -14
  312. package/src/daemon/message-types/conversations.ts +14 -0
  313. package/src/daemon/message-types/messages.ts +9 -1
  314. package/src/daemon/message-types/trust.ts +0 -2
  315. package/src/daemon/parse-actual-tokens-from-error.test.ts +57 -1
  316. package/src/daemon/parse-actual-tokens-from-error.ts +66 -0
  317. package/src/daemon/pkb-context-tracker.test.ts +169 -0
  318. package/src/daemon/pkb-context-tracker.ts +125 -0
  319. package/src/daemon/pkb-reminder-builder.test.ts +70 -0
  320. package/src/daemon/pkb-reminder-builder.ts +31 -0
  321. package/src/daemon/providers-setup.ts +6 -0
  322. package/src/daemon/server.ts +117 -9
  323. package/src/daemon/tool-side-effects.ts +0 -9
  324. package/src/daemon/watch-handler.ts +4 -4
  325. package/src/daemon/web-search-history.ts +126 -0
  326. package/src/events/domain-events.ts +0 -1
  327. package/src/filing/filing-service.ts +9 -10
  328. package/src/heartbeat/heartbeat-service.ts +76 -28
  329. package/src/home/__tests__/feed-scheduler.test.ts +39 -11
  330. package/src/home/__tests__/rollup-producer.test.ts +44 -0
  331. package/src/home/assistant-feed-authoring.ts +4 -0
  332. package/src/home/emit-feed-event.ts +4 -0
  333. package/src/home/feed-scheduler.ts +20 -4
  334. package/src/home/feed-types.ts +56 -2
  335. package/src/home/relationship-state-writer.ts +2 -2
  336. package/src/home/rollup-producer.ts +34 -5
  337. package/src/home/suggested-prompts.ts +101 -0
  338. package/src/ipc/__tests__/attachment-ipc.test.ts +213 -0
  339. package/src/ipc/__tests__/browser-ipc.test.ts +339 -0
  340. package/src/ipc/__tests__/cache-ipc.test.ts +266 -0
  341. package/src/ipc/__tests__/socket-path.test.ts +73 -0
  342. package/src/ipc/__tests__/task-ipc.test.ts +577 -0
  343. package/src/ipc/__tests__/ui-request-route.test.ts +495 -0
  344. package/src/ipc/__tests__/watcher-ipc.test.ts +295 -0
  345. package/src/ipc/cli-client.ts +2 -1
  346. package/src/ipc/cli-server.ts +26 -8
  347. package/src/ipc/gateway-client.ts +4 -4
  348. package/src/ipc/routes/attachment.ts +114 -0
  349. package/src/ipc/routes/browser-context.ts +61 -0
  350. package/src/ipc/routes/browser.ts +96 -0
  351. package/src/ipc/routes/cache.ts +96 -0
  352. package/src/ipc/routes/index.ts +17 -1
  353. package/src/ipc/routes/task-queue.ts +226 -0
  354. package/src/ipc/routes/task.ts +173 -0
  355. package/src/ipc/routes/ui-request.ts +50 -0
  356. package/src/ipc/routes/watcher.ts +203 -0
  357. package/src/ipc/socket-path.ts +100 -0
  358. package/src/memory/__tests__/conversation-analyze-job.test.ts +9 -8
  359. package/src/memory/__tests__/conversation-group-migration.test.ts +99 -0
  360. package/src/memory/admin.ts +18 -0
  361. package/src/memory/conversation-analyze-job.ts +14 -13
  362. package/src/memory/conversation-attention-store.ts +13 -6
  363. package/src/memory/conversation-crud.ts +103 -3
  364. package/src/memory/conversation-group-migration.ts +38 -6
  365. package/src/memory/conversation-title-service.ts +7 -4
  366. package/src/memory/db-init.ts +2 -0
  367. package/src/memory/embedding-backend.ts +1 -1
  368. package/src/memory/graph/compaction.ts +299 -0
  369. package/src/memory/graph/consolidation.ts +4 -4
  370. package/src/memory/graph/conversation-graph-memory.ts +89 -29
  371. package/src/memory/graph/extraction.test.ts +272 -2
  372. package/src/memory/graph/extraction.ts +173 -51
  373. package/src/memory/graph/graph-search.test.ts +92 -0
  374. package/src/memory/graph/graph-search.ts +4 -1
  375. package/src/memory/graph/narrative.ts +2 -2
  376. package/src/memory/graph/pattern-scan.ts +2 -2
  377. package/src/memory/graph/retriever.test.ts +459 -0
  378. package/src/memory/graph/retriever.ts +230 -48
  379. package/src/memory/graph/store.ts +41 -0
  380. package/src/memory/graph/tool-handlers.ts +27 -0
  381. package/src/memory/graph/tools.ts +6 -1
  382. package/src/memory/indexer.ts +5 -5
  383. package/src/memory/job-handlers/conversation-starters.ts +23 -20
  384. package/src/memory/job-handlers/summarization.ts +2 -2
  385. package/src/memory/job-utils.ts +7 -1
  386. package/src/memory/jobs/embed-pkb-file.test.ts +168 -0
  387. package/src/memory/jobs/embed-pkb-file.ts +54 -0
  388. package/src/memory/jobs-store.ts +44 -3
  389. package/src/memory/jobs-worker.ts +4 -0
  390. package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +1 -1
  391. package/src/memory/migrations/220-normalize-user-file-by-principal.ts +2 -2
  392. package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +82 -0
  393. package/src/memory/migrations/index.ts +1 -0
  394. package/src/memory/pkb/pkb-index.test.ts +368 -0
  395. package/src/memory/pkb/pkb-index.ts +255 -0
  396. package/src/memory/pkb/pkb-reconcile.test.ts +251 -0
  397. package/src/memory/pkb/pkb-reconcile.ts +148 -0
  398. package/src/memory/pkb/pkb-search.test.ts +438 -0
  399. package/src/memory/pkb/pkb-search.ts +137 -0
  400. package/src/memory/pkb/types.ts +53 -0
  401. package/src/memory/qdrant-client.ts +122 -1
  402. package/src/memory/slack-thread-store.ts +37 -0
  403. package/src/messaging/providers/gmail/adapter.ts +6 -16
  404. package/src/messaging/providers/gmail/client.ts +22 -0
  405. package/src/messaging/providers/gmail/types.ts +7 -0
  406. package/src/messaging/providers/slack/adapter.ts +14 -2
  407. package/src/messaging/providers/slack/backfill.test.ts +257 -0
  408. package/src/messaging/providers/slack/backfill.ts +101 -0
  409. package/src/messaging/providers/slack/message-metadata.test.ts +316 -0
  410. package/src/messaging/providers/slack/message-metadata.ts +123 -0
  411. package/src/messaging/providers/slack/render-transcript.test.ts +1373 -0
  412. package/src/messaging/providers/slack/render-transcript.ts +443 -0
  413. package/src/messaging/style-analyzer.ts +5 -2
  414. package/src/notifications/README.md +9 -5
  415. package/src/notifications/decision-engine.ts +3 -9
  416. package/src/notifications/preference-extractor.ts +2 -6
  417. package/src/oauth/oauth-store.ts +1 -0
  418. package/src/oauth/platform-connection.test.ts +47 -0
  419. package/src/oauth/platform-connection.ts +15 -5
  420. package/src/oauth/seed-providers.ts +4 -2
  421. package/src/permissions/approval-policy.test.ts +948 -0
  422. package/src/permissions/approval-policy.ts +257 -0
  423. package/src/permissions/bash-risk-classifier.test.ts +1208 -0
  424. package/src/permissions/bash-risk-classifier.ts +707 -0
  425. package/src/permissions/checker.ts +217 -708
  426. package/src/permissions/command-registry.test.ts +535 -0
  427. package/src/permissions/command-registry.ts +825 -0
  428. package/src/permissions/defaults.ts +26 -78
  429. package/src/permissions/file-risk-classifier.test.ts +535 -0
  430. package/src/permissions/file-risk-classifier.ts +274 -0
  431. package/src/permissions/risk-types.ts +205 -0
  432. package/src/permissions/secret-prompter.ts +53 -2
  433. package/src/permissions/skill-risk-classifier.test.ts +311 -0
  434. package/src/permissions/skill-risk-classifier.ts +214 -0
  435. package/src/permissions/trust-client.ts +52 -25
  436. package/src/permissions/trust-store-interface.ts +1 -6
  437. package/src/permissions/trust-store.ts +161 -62
  438. package/src/permissions/types.ts +23 -14
  439. package/src/permissions/web-risk-classifier.test.ts +170 -0
  440. package/src/permissions/web-risk-classifier.ts +89 -0
  441. package/src/permissions/workspace-policy.ts +1 -16
  442. package/src/platform/client.ts +19 -1
  443. package/src/prompts/persona-resolver.ts +3 -3
  444. package/src/prompts/system-prompt.ts +19 -20
  445. package/src/prompts/templates/SOUL.md +2 -2
  446. package/src/prompts/update-bulletin-job.ts +190 -0
  447. package/src/providers/__tests__/context-overflow-error.test.ts +328 -0
  448. package/src/providers/__tests__/provider-env-vars.test.ts +102 -0
  449. package/src/providers/__tests__/retry-callsite.test.ts +424 -0
  450. package/src/providers/anthropic/client.ts +183 -14
  451. package/src/providers/call-site-routing.ts +71 -0
  452. package/src/providers/gemini/client.ts +65 -2
  453. package/src/providers/managed-proxy/constants.ts +2 -1
  454. package/src/providers/model-catalog.ts +501 -33
  455. package/src/providers/model-intents.ts +4 -4
  456. package/src/providers/openai/chat-completions-provider.ts +57 -1
  457. package/src/providers/openai/responses-provider.ts +86 -9
  458. package/src/providers/openrouter/client.ts +76 -9
  459. package/src/providers/provider-env-vars.ts +56 -0
  460. package/src/providers/provider-send-message.ts +22 -5
  461. package/src/providers/ratelimit.ts +4 -0
  462. package/src/providers/registry.ts +19 -8
  463. package/src/providers/retry.ts +174 -39
  464. package/src/providers/speech-to-text/__tests__/resolve.test.ts +55 -0
  465. package/src/providers/speech-to-text/google-gemini-live-stream.ts +4 -4
  466. package/src/providers/speech-to-text/provider-catalog.ts +17 -0
  467. package/src/providers/speech-to-text/resolve.ts +7 -0
  468. package/src/providers/speech-to-text/xai-realtime.test.ts +578 -0
  469. package/src/providers/speech-to-text/xai-realtime.ts +796 -0
  470. package/src/providers/speech-to-text/xai.test.ts +155 -0
  471. package/src/providers/speech-to-text/xai.ts +97 -0
  472. package/src/providers/types.ts +93 -3
  473. package/src/runtime/AGENTS.md +2 -2
  474. package/src/runtime/__tests__/agent-wake.test.ts +43 -2
  475. package/src/runtime/__tests__/interactive-ui.test.ts +673 -0
  476. package/src/runtime/agent-wake.ts +63 -22
  477. package/src/runtime/auth/route-policy.ts +4 -0
  478. package/src/runtime/btw-sidechain.ts +13 -3
  479. package/src/runtime/channel-reply-delivery.ts +106 -2
  480. package/src/runtime/decision-token.ts +116 -0
  481. package/src/runtime/gateway-client.ts +2 -2
  482. package/src/runtime/http-router.ts +32 -0
  483. package/src/runtime/http-server.ts +52 -1
  484. package/src/runtime/http-types.ts +23 -1
  485. package/src/runtime/interactive-ui.ts +362 -0
  486. package/src/runtime/invite-instruction-generator.ts +2 -2
  487. package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +176 -0
  488. package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +390 -0
  489. package/src/runtime/migrations/__tests__/vbundle-metadata-merge.test.ts +221 -0
  490. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +1540 -0
  491. package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +453 -0
  492. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +222 -0
  493. package/src/runtime/migrations/gcs-signed-url.ts +162 -0
  494. package/src/runtime/migrations/vbundle-importer.ts +154 -9
  495. package/src/runtime/migrations/vbundle-metadata-merge.ts +124 -0
  496. package/src/runtime/migrations/vbundle-streaming-importer.ts +2522 -0
  497. package/src/runtime/migrations/vbundle-streaming-validator.ts +244 -0
  498. package/src/runtime/migrations/vbundle-tar-stream.ts +217 -0
  499. package/src/runtime/migrations/vbundle-validator.ts +15 -6
  500. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +111 -0
  501. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +114 -75
  502. package/src/runtime/routes/__tests__/migration-vellum-metadata-reconcile.test.ts +246 -0
  503. package/src/runtime/routes/approval-prompt-ts-tracker.ts +58 -0
  504. package/src/runtime/routes/approval-routes.ts +12 -17
  505. package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +9 -0
  506. package/src/runtime/routes/avatar-routes.ts +20 -4
  507. package/src/runtime/routes/btw-routes.ts +1 -4
  508. package/src/runtime/routes/conversation-management-routes.ts +20 -2
  509. package/src/runtime/routes/conversation-routes.ts +133 -27
  510. package/src/runtime/routes/debug-routes.ts +1 -1
  511. package/src/runtime/routes/diagnostics-routes.ts +6 -4
  512. package/src/runtime/routes/events-routes.ts +16 -0
  513. package/src/runtime/routes/guardian-approval-interception.ts +33 -3
  514. package/src/runtime/routes/guardian-approval-prompt.ts +13 -3
  515. package/src/runtime/routes/home-feed-routes.ts +120 -2
  516. package/src/runtime/routes/inbound-message-handler.ts +912 -2
  517. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +113 -2
  518. package/src/runtime/routes/inbound-stages/background-dispatch.ts +61 -3
  519. package/src/runtime/routes/inbound-stages/edit-intercept.ts +129 -6
  520. package/src/runtime/routes/integrations/slack/channel.ts +25 -3
  521. package/src/runtime/routes/llm-context-normalization.ts +23 -1
  522. package/src/runtime/routes/migration-routes.ts +720 -124
  523. package/src/runtime/routes/settings-routes.ts +4 -2
  524. package/src/runtime/routes/trust-rules-routes.ts +30 -14
  525. package/src/runtime/routes/work-items-routes.test.ts +1 -1
  526. package/src/runtime/routes/work-items-routes.ts +3 -2
  527. package/src/runtime/services/__tests__/analyze-conversation.test.ts +25 -43
  528. package/src/runtime/services/analyze-conversation.ts +12 -16
  529. package/src/runtime/skill-route-registry.ts +28 -6
  530. package/src/schedule/scheduler.ts +8 -0
  531. package/src/security/__tests__/provider-key-env-fallback.test.ts +119 -0
  532. package/src/security/__tests__/untrusted-content.test.ts +109 -0
  533. package/src/security/oauth2.ts +98 -35
  534. package/src/security/secure-keys.ts +7 -8
  535. package/src/security/token-manager.ts +27 -13
  536. package/src/security/untrusted-content.ts +102 -0
  537. package/src/skills/catalog-cache.ts +26 -7
  538. package/src/skills/catalog-install.ts +31 -3
  539. package/src/skills/skill-cache-store.ts +97 -0
  540. package/src/stt/__tests__/daemon-batch-transcriber.test.ts +76 -0
  541. package/src/stt/daemon-batch-transcriber.ts +33 -0
  542. package/src/stt/stt-stream-session.ts +8 -1
  543. package/src/stt/types.ts +5 -1
  544. package/src/subagent/manager.ts +41 -13
  545. package/src/tasks/ephemeral-permissions.ts +9 -4
  546. package/src/telemetry/usage-telemetry-reporter.ts +27 -5
  547. package/src/tools/browser/__tests__/browser-status.test.ts +45 -2
  548. package/src/tools/browser/browser-execution.ts +65 -38
  549. package/src/tools/browser/cdp-client/cdp-inspect/discovery.ts +22 -0
  550. package/src/tools/credentials/tool-policy.ts +39 -5
  551. package/src/tools/credentials/vault.ts +9 -4
  552. package/src/tools/executor.ts +4 -0
  553. package/src/tools/filesystem/write.ts +52 -0
  554. package/src/tools/host-terminal/host-shell.ts +45 -5
  555. package/src/tools/memory/register.test.ts +185 -0
  556. package/src/tools/memory/register.ts +3 -1
  557. package/src/tools/network/web-fetch.ts +20 -10
  558. package/src/tools/network/web-search.ts +19 -4
  559. package/src/tools/permission-checker.ts +36 -15
  560. package/src/tools/policy-context.ts +25 -8
  561. package/src/tools/registry.ts +55 -3
  562. package/src/tools/side-effects.ts +0 -11
  563. package/src/tools/skills/execute.ts +2 -2
  564. package/src/tools/skills/sandbox-runner.ts +5 -2
  565. package/src/tools/terminal/backends/native.ts +51 -2
  566. package/src/tools/terminal/safe-env.ts +3 -2
  567. package/src/tools/terminal/shell.ts +1 -0
  568. package/src/tools/tool-manifest.ts +6 -21
  569. package/src/tools/types.ts +12 -3
  570. package/src/tools/verification-control-plane-policy.ts +1 -1
  571. package/src/tts/__tests__/provider-adapters.test.ts +240 -13
  572. package/src/tts/provider-catalog.ts +18 -0
  573. package/src/tts/providers/index.ts +2 -0
  574. package/src/tts/providers/xai-provider.ts +224 -0
  575. package/src/tts/types.ts +46 -0
  576. package/src/types/tar-stream.d.ts +66 -0
  577. package/src/util/json.ts +17 -0
  578. package/src/util/platform.ts +2 -2
  579. package/src/util/pricing.ts +15 -5
  580. package/src/watcher/engine.ts +1 -1
  581. package/src/watcher/providers/google-calendar.ts +134 -8
  582. package/src/watcher/providers/outlook-calendar.ts +42 -2
  583. package/src/workspace/git-service.ts +23 -4
  584. package/src/workspace/migrations/038-unify-llm-callsite-configs.ts +516 -0
  585. package/src/workspace/migrations/039-drop-legacy-llm-keys.ts +171 -0
  586. package/src/workspace/migrations/040-seed-latency-callsite-defaults.ts +154 -0
  587. package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +57 -0
  588. package/src/workspace/migrations/042-fix-backfill-google-gmail-settings-scope.ts +70 -0
  589. package/src/workspace/migrations/043-release-notes-latex-rendering.ts +75 -0
  590. package/src/workspace/migrations/044-bump-stale-provider-stream-timeout.ts +51 -0
  591. package/src/workspace/migrations/045-release-notes-meet-avatar.ts +130 -0
  592. package/src/workspace/migrations/AGENTS.md +1 -1
  593. package/src/workspace/migrations/registry.ts +16 -0
  594. package/src/workspace/provider-commit-message-generator.ts +19 -38
  595. package/src/__tests__/gmail-archive-fallback.test.ts +0 -193
  596. package/src/__tests__/gmail-archive-gate.test.ts +0 -246
  597. package/src/__tests__/gmail-preferences.test.ts +0 -117
  598. package/src/__tests__/outlook-attachments.test.ts +0 -301
  599. package/src/__tests__/outlook-automation-tools.test.ts +0 -425
  600. package/src/__tests__/outlook-categories.test.ts +0 -212
  601. package/src/__tests__/outlook-compose-tools.test.ts +0 -325
  602. package/src/__tests__/outlook-declutter-tools.test.ts +0 -585
  603. package/src/__tests__/outlook-follow-up.test.ts +0 -196
  604. package/src/__tests__/outlook-trash.test.ts +0 -77
  605. package/src/__tests__/outlook-unsubscribe.test.ts +0 -279
  606. package/src/__tests__/update-bulletin-format.test.ts +0 -181
  607. package/src/__tests__/update-bulletin-state.test.ts +0 -135
  608. package/src/__tests__/update-bulletin.test.ts +0 -478
  609. package/src/__tests__/update-template-contract.test.ts +0 -29
  610. package/src/cli/commands/doctor.ts +0 -341
  611. package/src/config/bundled-skills/browser/SKILL.md +0 -88
  612. package/src/config/bundled-skills/browser/TOOLS.json +0 -516
  613. package/src/config/bundled-skills/browser/tools/browser-attach.ts +0 -12
  614. package/src/config/bundled-skills/browser/tools/browser-click.ts +0 -12
  615. package/src/config/bundled-skills/browser/tools/browser-close.ts +0 -12
  616. package/src/config/bundled-skills/browser/tools/browser-detach.ts +0 -12
  617. package/src/config/bundled-skills/browser/tools/browser-extract.ts +0 -12
  618. package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +0 -12
  619. package/src/config/bundled-skills/browser/tools/browser-hover.ts +0 -12
  620. package/src/config/bundled-skills/browser/tools/browser-navigate.ts +0 -12
  621. package/src/config/bundled-skills/browser/tools/browser-press-key.ts +0 -12
  622. package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +0 -12
  623. package/src/config/bundled-skills/browser/tools/browser-scroll.ts +0 -12
  624. package/src/config/bundled-skills/browser/tools/browser-select-option.ts +0 -12
  625. package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +0 -12
  626. package/src/config/bundled-skills/browser/tools/browser-status.ts +0 -12
  627. package/src/config/bundled-skills/browser/tools/browser-type.ts +0 -12
  628. package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +0 -49
  629. package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +0 -12
  630. package/src/config/bundled-skills/chatgpt-import/SKILL.md +0 -27
  631. package/src/config/bundled-skills/chatgpt-import/TOOLS.json +0 -27
  632. package/src/config/bundled-skills/chatgpt-import/tools/chatgpt-import.ts +0 -378
  633. package/src/config/bundled-skills/gmail/SKILL.md +0 -221
  634. package/src/config/bundled-skills/gmail/TOOLS.json +0 -588
  635. package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +0 -256
  636. package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +0 -112
  637. package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +0 -44
  638. package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +0 -81
  639. package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +0 -108
  640. package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +0 -146
  641. package/src/config/bundled-skills/gmail/tools/gmail-label.ts +0 -53
  642. package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +0 -347
  643. package/src/config/bundled-skills/gmail/tools/gmail-preferences-tool.ts +0 -59
  644. package/src/config/bundled-skills/gmail/tools/gmail-preferences.ts +0 -82
  645. package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +0 -26
  646. package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +0 -347
  647. package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +0 -29
  648. package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +0 -122
  649. package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +0 -67
  650. package/src/config/bundled-skills/gmail/tools/scan-result-store.ts +0 -100
  651. package/src/config/bundled-skills/gmail/tools/shared.ts +0 -47
  652. package/src/config/bundled-skills/google-calendar/SKILL.md +0 -51
  653. package/src/config/bundled-skills/google-calendar/TOOLS.json +0 -226
  654. package/src/config/bundled-skills/google-calendar/calendar-client.ts +0 -223
  655. package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +0 -27
  656. package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +0 -48
  657. package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +0 -19
  658. package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +0 -36
  659. package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +0 -58
  660. package/src/config/bundled-skills/google-calendar/tools/shared.ts +0 -17
  661. package/src/config/bundled-skills/google-calendar/types.ts +0 -97
  662. package/src/config/bundled-skills/outlook/SKILL.md +0 -196
  663. package/src/config/bundled-skills/outlook/TOOLS.json +0 -530
  664. package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +0 -85
  665. package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +0 -77
  666. package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +0 -84
  667. package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +0 -94
  668. package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +0 -49
  669. package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +0 -237
  670. package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +0 -161
  671. package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +0 -32
  672. package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +0 -272
  673. package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +0 -29
  674. package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +0 -129
  675. package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +0 -87
  676. package/src/config/bundled-skills/outlook/tools/shared.ts +0 -20
  677. package/src/config/bundled-skills/outlook-calendar/SKILL.md +0 -51
  678. package/src/config/bundled-skills/outlook-calendar/TOOLS.json +0 -221
  679. package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +0 -252
  680. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +0 -53
  681. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +0 -74
  682. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +0 -18
  683. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +0 -46
  684. package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +0 -36
  685. package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +0 -17
  686. package/src/config/bundled-skills/outlook-calendar/types.ts +0 -120
  687. package/src/config/bundled-skills/slack/SKILL.md +0 -108
  688. package/src/config/bundled-skills/tasks/SKILL.md +0 -37
  689. package/src/config/bundled-skills/tasks/TOOLS.json +0 -353
  690. package/src/config/bundled-skills/tasks/icon.svg +0 -34
  691. package/src/config/bundled-skills/tasks/tools/task-delete.ts +0 -12
  692. package/src/config/bundled-skills/tasks/tools/task-list-add.ts +0 -12
  693. package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +0 -12
  694. package/src/config/bundled-skills/tasks/tools/task-list-show.ts +0 -12
  695. package/src/config/bundled-skills/tasks/tools/task-list-update.ts +0 -12
  696. package/src/config/bundled-skills/tasks/tools/task-list.ts +0 -12
  697. package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +0 -12
  698. package/src/config/bundled-skills/tasks/tools/task-run.ts +0 -12
  699. package/src/config/bundled-skills/tasks/tools/task-save.ts +0 -12
  700. package/src/config/bundled-skills/watcher/SKILL.md +0 -31
  701. package/src/config/bundled-skills/watcher/TOOLS.json +0 -167
  702. package/src/config/bundled-skills/watcher/tools/watcher-create.ts +0 -12
  703. package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +0 -12
  704. package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +0 -12
  705. package/src/config/bundled-skills/watcher/tools/watcher-list.ts +0 -12
  706. package/src/config/bundled-skills/watcher/tools/watcher-update.ts +0 -12
  707. package/src/prompts/templates/UPDATES.md +0 -50
  708. package/src/prompts/update-bulletin-format.ts +0 -85
  709. package/src/prompts/update-bulletin-state.ts +0 -58
  710. package/src/prompts/update-bulletin-template-path.ts +0 -13
  711. package/src/prompts/update-bulletin.ts +0 -139
  712. package/src/shared/provider-env-vars.ts +0 -19
  713. package/src/tools/watcher/create.ts +0 -86
  714. package/src/tools/watcher/delete.ts +0 -36
  715. package/src/tools/watcher/digest.ts +0 -54
  716. package/src/tools/watcher/list.ts +0 -83
  717. package/src/tools/watcher/update.ts +0 -71
@@ -10,6 +10,7 @@ import {
10
10
  gte,
11
11
  inArray,
12
12
  isNull,
13
+ like,
13
14
  lt,
14
15
  lte,
15
16
  sql,
@@ -23,6 +24,7 @@ import { CHANNEL_IDS, INTERFACE_IDS, isChannelId } from "../channels/types.js";
23
24
  import { getConfig } from "../config/loader.js";
24
25
  import type { TrustContext } from "../daemon/conversation-runtime-assembly.js";
25
26
  import { UserError } from "../util/errors.js";
27
+ import { safeParseRecord } from "../util/json.js";
26
28
  import { getLogger } from "../util/logger.js";
27
29
  import { getConversationsDir } from "../util/platform.js";
28
30
  import { createRowMapper } from "../util/row-mapper.js";
@@ -102,6 +104,9 @@ export const messageMetadataSchema = z
102
104
  forkSourceMessageId: z.string().optional(),
103
105
  /** Image source paths from desktop attachments, keyed by filename. */
104
106
  imageSourcePaths: z.record(z.string(), z.string()).optional(),
107
+ memoryInjectedBlock: z.string().optional(),
108
+ turnContextBlock: z.string().optional(),
109
+ pkbSystemReminderBlock: z.string().optional(),
105
110
  })
106
111
  .passthrough();
107
112
 
@@ -420,9 +425,7 @@ export function findAnalysisConversationFor(
420
425
  * not found. Tiny convenience used by the recursion guard in the
421
426
  * auto-analyze loop.
422
427
  */
423
- export function getConversationSource(
424
- conversationId: string,
425
- ): string | null {
428
+ export function getConversationSource(conversationId: string): string | null {
426
429
  const db = getDb();
427
430
  const row = db
428
431
  .select({ source: conversations.source })
@@ -1044,6 +1047,49 @@ export function getMessages(conversationId: string): MessageRow[] {
1044
1047
  .map(parseMessage);
1045
1048
  }
1046
1049
 
1050
+ /**
1051
+ * Count messages whose metadata JSON contains a `slackMeta` envelope, capped
1052
+ * at `limit`. Pushes the cap into SQL (`LIKE` + `LIMIT`) so warm Slack DM
1053
+ * conversations don't require a full-table scan + JSON parse on every
1054
+ * inbound message to confirm the cold-start threshold has been cleared.
1055
+ * Returns the number of matching rows up to `limit`; callers compare against
1056
+ * the cold-start threshold to decide whether to backfill.
1057
+ */
1058
+ export function countMessagesWithSlackMeta(
1059
+ conversationId: string,
1060
+ limit: number,
1061
+ ): number {
1062
+ const db = getDb();
1063
+ const rows = db
1064
+ .select({ one: sql`1` })
1065
+ .from(messages)
1066
+ .where(
1067
+ and(
1068
+ eq(messages.conversationId, conversationId),
1069
+ like(messages.metadata, '%"slackMeta"%'),
1070
+ ),
1071
+ )
1072
+ .limit(limit)
1073
+ .all();
1074
+ return rows.length;
1075
+ }
1076
+
1077
+ /**
1078
+ * Efficient existence check — returns true if the conversation has at least
1079
+ * one message row. Uses `LIMIT 1` + `select({ 1 })` to avoid loading and
1080
+ * parsing any message content.
1081
+ */
1082
+ export function hasMessages(conversationId: string): boolean {
1083
+ const db = getDb();
1084
+ const row = db
1085
+ .select({ one: sql`1` })
1086
+ .from(messages)
1087
+ .where(eq(messages.conversationId, conversationId))
1088
+ .limit(1)
1089
+ .get();
1090
+ return row !== undefined;
1091
+ }
1092
+
1047
1093
  export interface PaginatedMessagesResult {
1048
1094
  messages: MessageRow[];
1049
1095
  hasMore: boolean;
@@ -1456,6 +1502,60 @@ export function updateMessageMetadata(
1456
1502
  .run();
1457
1503
  }
1458
1504
 
1505
+ /**
1506
+ * Bulk-remove the `pkbSystemReminderBlock` field from every user-message
1507
+ * metadata row in a conversation. Called from compaction-strip sites so
1508
+ * post-restart rehydration stays consistent with the in-memory state
1509
+ * produced by `stripInjectionsForCompaction` (which removes
1510
+ * `<system_reminder>` from live messages but cannot touch the DB).
1511
+ */
1512
+ export function clearPkbSystemReminderMetadataForConversation(
1513
+ conversationId: string,
1514
+ ): void {
1515
+ rawRun(
1516
+ `UPDATE messages
1517
+ SET metadata = json_remove(metadata, '$.pkbSystemReminderBlock')
1518
+ WHERE conversation_id = ?
1519
+ AND role = 'user'
1520
+ AND metadata IS NOT NULL
1521
+ AND json_extract(metadata, '$.pkbSystemReminderBlock') IS NOT NULL`,
1522
+ conversationId,
1523
+ );
1524
+ }
1525
+
1526
+ /**
1527
+ * Atomically update both `content` and (shallow-merged) `metadata` for a
1528
+ * message. Used by edit-propagation paths that need to update the message
1529
+ * body and stamp metadata (e.g. `slackMeta.editedAt`) in a single
1530
+ * transaction so a partial write cannot leak.
1531
+ *
1532
+ * `metadataUpdates` is shallow-merged into the existing top-level metadata
1533
+ * object. To merge into a nested sub-key (e.g. `slackMeta`), the caller
1534
+ * must compute the merged sub-value first and pass `{ slackMeta: merged }`.
1535
+ */
1536
+ export function updateMessageContentAndMetadata(
1537
+ messageId: string,
1538
+ newContent: string,
1539
+ metadataUpdates: Record<string, unknown>,
1540
+ ): void {
1541
+ const db = getDb();
1542
+ db.transaction((tx) => {
1543
+ const row = tx
1544
+ .select({ metadata: messages.metadata })
1545
+ .from(messages)
1546
+ .where(eq(messages.id, messageId))
1547
+ .get();
1548
+ const existing = row?.metadata ? safeParseRecord(row.metadata) : {};
1549
+ tx.update(messages)
1550
+ .set({
1551
+ content: newContent,
1552
+ metadata: JSON.stringify({ ...existing, ...metadataUpdates }),
1553
+ })
1554
+ .where(eq(messages.id, messageId))
1555
+ .run();
1556
+ });
1557
+ }
1558
+
1459
1559
  /**
1460
1560
  * Re-link all attachments from a set of source messages to a target message.
1461
1561
  * Used during message consolidation so that attachments linked to deleted
@@ -58,10 +58,6 @@ export function ensureGroupMigration(): void {
58
58
  }
59
59
 
60
60
  // 3. Seed system groups.
61
- //
62
- // `system:reflections` is a legacy group kept for backward compatibility
63
- // with existing installations. New auto-analysis conversations are assigned
64
- // to `system:background`; the migration in step 6 moves existing ones.
65
61
  const now = Math.floor(Date.now() / 1000);
66
62
  rawExec(`
67
63
  INSERT OR IGNORE INTO conversation_groups (id, name, sort_position, is_system_group, created_at, updated_at)
@@ -69,8 +65,7 @@ export function ensureGroupMigration(): void {
69
65
  ('system:pinned', 'Pinned', 0, TRUE, ${now}, ${now}),
70
66
  ('system:scheduled', 'Scheduled', 1, TRUE, ${now}, ${now}),
71
67
  ('system:background', 'Background', 2, TRUE, ${now}, ${now}),
72
- ('system:all', 'Recents', 3, TRUE, ${now}, ${now}),
73
- ('system:reflections', 'Reflections', 100, TRUE, ${now}, ${now})
68
+ ('system:all', 'Recents', 3, TRUE, ${now}, ${now})
74
69
  `);
75
70
 
76
71
  // One-time migration: move system:all to sortPosition 3 (from 999999).
@@ -245,5 +240,42 @@ export function ensureGroupMigration(): void {
245
240
  }
246
241
  }
247
242
 
243
+ // 7. One-time cleanup: delete the orphaned system:reflections group row.
244
+ //
245
+ // Reflections render as a sub-group under Background via the client's
246
+ // sub-group label provider; the standalone system:reflections group is no
247
+ // longer referenced by any conversation after step 6. Leaving the row in
248
+ // place causes the macOS sidebar to render an empty duplicate "Reflections"
249
+ // entry with a fallback folder icon alongside the Background sub-group.
250
+ const reflectionsGroupDeleted = rawGet<{ id: string }>(
251
+ "SELECT id FROM conversation_groups WHERE id = '_reflections_group_deleted_complete'",
252
+ );
253
+
254
+ if (!reflectionsGroupDeleted) {
255
+ try {
256
+ rawExec("BEGIN");
257
+
258
+ // Belt-and-suspenders: re-run the conversation move in case a straggler
259
+ // crept in between step 6's sentinel being set and this step shipping.
260
+ rawExec(`
261
+ UPDATE conversations SET group_id = 'system:background'
262
+ WHERE group_id = 'system:reflections'
263
+ `);
264
+
265
+ rawExec(`DELETE FROM conversation_groups WHERE id = 'system:reflections'`);
266
+
267
+ rawExec(`
268
+ INSERT OR IGNORE INTO conversation_groups (id, name, sort_position, is_system_group)
269
+ VALUES ('_reflections_group_deleted_complete', '_reflections_group_deleted_complete', -1, TRUE)
270
+ `);
271
+
272
+ rawExec("COMMIT");
273
+ } catch (err) {
274
+ rawExec("ROLLBACK");
275
+ log.error({ err }, "reflections-group deletion failed, rolled back");
276
+ throw err;
277
+ }
278
+ }
279
+
248
280
  migrated = true;
249
281
  }
@@ -37,6 +37,7 @@ export type TitleOrigin =
37
37
  | "filing"
38
38
  | "local"
39
39
  | "task_submit"
40
+ | "updates_bulletin"
40
41
  | "misc";
41
42
 
42
43
  export interface TitleContext {
@@ -118,7 +119,8 @@ export async function generateAndPersistConversationTitle(
118
119
  return { title: conversation.title!, updated: false };
119
120
  }
120
121
 
121
- const provider = params.provider ?? (await getConfiguredProvider());
122
+ const provider =
123
+ params.provider ?? (await getConfiguredProvider("conversationTitle"));
122
124
  if (!provider) {
123
125
  // No provider available — fall back to context-derived title or untitled
124
126
  const fallback = deriveFallbackTitle(context) ?? UNTITLED_FALLBACK;
@@ -133,7 +135,7 @@ export async function generateAndPersistConversationTitle(
133
135
  provider,
134
136
  systemPrompt: buildTitleSystemPrompt(),
135
137
  tools: [],
136
- modelIntent: "quality-optimized",
138
+ callSite: "conversationTitle",
137
139
  signal,
138
140
  timeoutMs: 10_000,
139
141
  });
@@ -219,7 +221,8 @@ export async function regenerateConversationTitle(
219
221
  return { title: conversation?.title ?? UNTITLED_FALLBACK, updated: false };
220
222
  }
221
223
 
222
- const provider = params.provider ?? (await getConfiguredProvider());
224
+ const provider =
225
+ params.provider ?? (await getConfiguredProvider("conversationTitle"));
223
226
  if (!provider) {
224
227
  return { title: conversation.title ?? UNTITLED_FALLBACK, updated: false };
225
228
  }
@@ -236,7 +239,7 @@ export async function regenerateConversationTitle(
236
239
  provider,
237
240
  systemPrompt: buildTitleSystemPrompt(),
238
241
  tools: [],
239
- modelIntent: "quality-optimized",
242
+ callSite: "conversationTitle",
240
243
  signal,
241
244
  timeoutMs: 10_000,
242
245
  });
@@ -146,6 +146,7 @@ import {
146
146
  migrateSchemaIndexesAndColumns,
147
147
  migrateScrubCorruptedImageAttachments,
148
148
  migrateStripIntegrationPrefixFromProviderKeys,
149
+ migrateStripPlaceholderSentinelsFromMessages,
149
150
  migrateStripThinkingFromConsolidated,
150
151
  migrateUsageDashboardIndexes,
151
152
  migrateUsageLlmCallCount,
@@ -370,6 +371,7 @@ export function initializeDb(): void {
370
371
  migrateOAuthProvidersTokenExchangeBodyFormat,
371
372
  migrateNormalizeUserFileByPrincipal,
372
373
  migrateConversationsArchivedAt,
374
+ migrateStripPlaceholderSentinelsFromMessages,
373
375
  ];
374
376
 
375
377
  // Run each migration step, catching and logging individual failures so one
@@ -795,7 +795,7 @@ export async function selectedBackendSupportsMultimodal(
795
795
 
796
796
  async function isOllamaConfigured(config: AssistantConfig): Promise<boolean> {
797
797
  return (
798
- config.services.inference.provider === "ollama" ||
798
+ config.llm.default.provider === "ollama" ||
799
799
  Boolean(await getProviderKeyAsync("ollama")) ||
800
800
  Boolean(getOllamaBaseUrlEnv())
801
801
  );
@@ -0,0 +1,299 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Memory Graph — One-off backfill to compact over-long node content
3
+ //
4
+ // Scans memory_graph_nodes for entries whose `content` exceeds a length
5
+ // threshold and rewrites them via an LLM call constrained to the same
6
+ // "1-3 sentences / ~300 chars" rule the extraction prompt now enforces.
7
+ // Preserves all other node fields (significance, emotionalCharge, edges,
8
+ // triggers, image_refs). Each rewrite is logged in memory_graph_node_edits
9
+ // with source="manual" so it is reversible and auditable.
10
+ // ---------------------------------------------------------------------------
11
+
12
+ import { and, sql } from "drizzle-orm";
13
+
14
+ import {
15
+ extractToolUse,
16
+ getConfiguredProvider,
17
+ userMessage,
18
+ } from "../../providers/provider-send-message.js";
19
+ import { BackendUnavailableError } from "../../util/errors.js";
20
+ import { getLogger } from "../../util/logger.js";
21
+ import { getDb } from "../db.js";
22
+ import { memoryGraphNodes } from "../schema.js";
23
+ import { recordNodeEdit, updateNode } from "./store.js";
24
+
25
+ const log = getLogger("graph-compaction");
26
+
27
+ const COMPACTION_TOOL_SCHEMA = {
28
+ name: "compact_memory",
29
+ description: "Rewrite a memory node's content to fit the length cap",
30
+ input_schema: {
31
+ type: "object" as const,
32
+ properties: {
33
+ compacted_content: {
34
+ type: "string" as const,
35
+ description:
36
+ "The rewritten content — 1-3 sentences, first-person, ~300 characters or fewer",
37
+ },
38
+ },
39
+ required: ["compacted_content"] as const,
40
+ },
41
+ };
42
+
43
+ const COMPACTION_SYSTEM_PROMPT = `You are compacting an over-long memory node in an AI assistant's memory graph. The original content exceeds the extraction prompt's 1-3 sentence / ~300 character cap because it was written before the cap existed. Rewrite it to fit.
44
+
45
+ ## Rules
46
+
47
+ **LENGTH: 1-3 sentences. Target ~300 characters. Hard cap ~400.** No exceptions.
48
+
49
+ **Preserve:**
50
+ - The core fact, event, or moment being remembered
51
+ - First-person prose style if the original is first-person
52
+ - The essential emotional tone of the memory
53
+
54
+ **Drop:**
55
+ - Scene-setting and surrounding context
56
+ - Dialogue preservation (unless one short quote IS the memory)
57
+ - Narrative "what it meant" commentary
58
+ - Cataloging of every emotional nuance
59
+ - Image descriptions packed into prose (images live in image_refs, not content)
60
+
61
+ **Never:**
62
+ - Invent facts not present in the original
63
+ - Change the core subject or emotional valence
64
+ - Pad to hit a target length — shorter than 300 chars is fine if the essence is there
65
+
66
+ The node's \`emotionalCharge\` and \`significance\` fields (not shown) already carry the weight. Content stays lean.
67
+
68
+ Call the \`compact_memory\` tool with the rewritten content. No preamble.`;
69
+
70
+ export interface CompactionCandidate {
71
+ id: string;
72
+ beforeLen: number;
73
+ }
74
+
75
+ export interface CompactionProgress {
76
+ nodeId: string;
77
+ beforeLen: number;
78
+ afterLen: number;
79
+ action: "compacted" | "skipped" | "failed";
80
+ newContent?: string;
81
+ reason?: string;
82
+ }
83
+
84
+ export interface CompactionResult {
85
+ /** Nodes whose content exceeded the threshold (before --limit is applied). */
86
+ scanned: number;
87
+ /** Nodes actually processed (scanned ∩ limit). */
88
+ processed: number;
89
+ compacted: number;
90
+ skipped: number;
91
+ failures: number;
92
+ beforeChars: number;
93
+ afterChars: number;
94
+ }
95
+
96
+ export interface CompactionOptions {
97
+ /** Content length threshold — nodes above this get compacted. Default 400. */
98
+ threshold?: number;
99
+ /** If true, write changes. If false, only list candidates (no LLM calls). Default false. */
100
+ apply?: boolean;
101
+ /** Max nodes to process. Default: no limit. */
102
+ limit?: number;
103
+ /** Called for each node as it is processed in apply mode. */
104
+ onProgress?: (evt: CompactionProgress) => void;
105
+ /** Called once with the full candidate list (both preview and apply modes). */
106
+ onCandidates?: (candidates: CompactionCandidate[]) => void;
107
+ }
108
+
109
+ /**
110
+ * Find over-length nodes in the memory graph and (optionally) rewrite their
111
+ * content to fit the length cap. In preview mode (apply=false) no LLM calls
112
+ * are made — only the candidate list is returned.
113
+ */
114
+ export async function compactLongMemories(
115
+ opts: CompactionOptions = {},
116
+ ): Promise<CompactionResult> {
117
+ const threshold = opts.threshold ?? 400;
118
+ const apply = opts.apply ?? false;
119
+
120
+ const db = getDb();
121
+ const rows = db
122
+ .select({
123
+ id: memoryGraphNodes.id,
124
+ content: memoryGraphNodes.content,
125
+ })
126
+ .from(memoryGraphNodes)
127
+ .where(
128
+ and(
129
+ // Skip already-dead nodes — rewriting content on "gone" fidelity is wasted work
130
+ sql`${memoryGraphNodes.fidelity} != 'gone'`,
131
+ sql`LENGTH(${memoryGraphNodes.content}) > ${threshold}`,
132
+ ),
133
+ )
134
+ .all();
135
+
136
+ const candidates = opts.limit != null ? rows.slice(0, opts.limit) : rows;
137
+
138
+ opts.onCandidates?.(
139
+ candidates.map((r) => ({ id: r.id, beforeLen: r.content.length })),
140
+ );
141
+
142
+ const result: CompactionResult = {
143
+ scanned: rows.length,
144
+ processed: candidates.length,
145
+ compacted: 0,
146
+ skipped: 0,
147
+ failures: 0,
148
+ beforeChars: candidates.reduce((sum, r) => sum + r.content.length, 0),
149
+ afterChars: 0,
150
+ };
151
+
152
+ if (!apply) {
153
+ // Preview mode: record beforeChars as afterChars (no rewrites attempted)
154
+ result.afterChars = result.beforeChars;
155
+ return result;
156
+ }
157
+
158
+ if (candidates.length === 0) return result;
159
+
160
+ const provider = await getConfiguredProvider("memoryConsolidation");
161
+ if (!provider) {
162
+ throw new BackendUnavailableError(
163
+ "Provider unavailable for memory compaction",
164
+ );
165
+ }
166
+
167
+ for (const row of candidates) {
168
+ const beforeLen = row.content.length;
169
+
170
+ try {
171
+ const response = await provider.sendMessage(
172
+ [
173
+ userMessage(
174
+ `Original memory content (length: ${beforeLen} chars):\n\n${row.content}`,
175
+ ),
176
+ ],
177
+ [COMPACTION_TOOL_SCHEMA],
178
+ COMPACTION_SYSTEM_PROMPT,
179
+ {
180
+ config: {
181
+ callSite: "memoryConsolidation" as const,
182
+ tool_choice: {
183
+ type: "tool" as const,
184
+ name: "compact_memory",
185
+ },
186
+ },
187
+ },
188
+ );
189
+
190
+ const toolBlock = extractToolUse(response);
191
+ if (!toolBlock) {
192
+ result.failures += 1;
193
+ result.afterChars += beforeLen;
194
+ opts.onProgress?.({
195
+ nodeId: row.id,
196
+ beforeLen,
197
+ afterLen: beforeLen,
198
+ action: "failed",
199
+ reason: "no tool_use block in response",
200
+ });
201
+ continue;
202
+ }
203
+
204
+ const input = toolBlock.input as { compacted_content?: string };
205
+ const newContent =
206
+ typeof input.compacted_content === "string"
207
+ ? input.compacted_content.trim()
208
+ : "";
209
+
210
+ if (!newContent) {
211
+ result.failures += 1;
212
+ result.afterChars += beforeLen;
213
+ opts.onProgress?.({
214
+ nodeId: row.id,
215
+ beforeLen,
216
+ afterLen: beforeLen,
217
+ action: "failed",
218
+ reason: "empty compacted_content",
219
+ });
220
+ continue;
221
+ }
222
+
223
+ // If the model didn't actually shrink it, skip — never overwrite with
224
+ // something equivalent or longer. Preserves the original when the LLM
225
+ // fails to compress.
226
+ if (newContent.length >= beforeLen) {
227
+ result.skipped += 1;
228
+ result.afterChars += beforeLen;
229
+ opts.onProgress?.({
230
+ nodeId: row.id,
231
+ beforeLen,
232
+ afterLen: newContent.length,
233
+ action: "skipped",
234
+ reason: "rewrite was not shorter than original",
235
+ newContent,
236
+ });
237
+ continue;
238
+ }
239
+
240
+ // Reject rewrites that are shorter than the original but still exceed
241
+ // the threshold cap — the whole point of the compaction is to land
242
+ // under the cap, not merely to reduce length.
243
+ if (newContent.length > threshold) {
244
+ result.skipped += 1;
245
+ result.afterChars += beforeLen;
246
+ opts.onProgress?.({
247
+ nodeId: row.id,
248
+ beforeLen,
249
+ afterLen: newContent.length,
250
+ action: "skipped",
251
+ reason: `rewrite still exceeds threshold (${newContent.length} > ${threshold})`,
252
+ newContent,
253
+ });
254
+ continue;
255
+ }
256
+
257
+ // Wrap edit recording + node update in a transaction so they are
258
+ // atomic: if updateNode fails, the edit record is rolled back. Without
259
+ // this, a mid-operation throw leaves an orphaned audit row pointing at
260
+ // a change that never committed.
261
+ getDb().transaction(() => {
262
+ recordNodeEdit({
263
+ nodeId: row.id,
264
+ previousContent: row.content,
265
+ newContent,
266
+ source: "manual",
267
+ });
268
+ updateNode(row.id, {
269
+ content: newContent,
270
+ lastConsolidated: Date.now(),
271
+ });
272
+ });
273
+
274
+ result.compacted += 1;
275
+ result.afterChars += newContent.length;
276
+ opts.onProgress?.({
277
+ nodeId: row.id,
278
+ beforeLen,
279
+ afterLen: newContent.length,
280
+ action: "compacted",
281
+ newContent,
282
+ });
283
+ } catch (err) {
284
+ result.failures += 1;
285
+ result.afterChars += beforeLen;
286
+ const reason = err instanceof Error ? err.message : String(err);
287
+ log.warn({ nodeId: row.id, err: reason }, "Compaction failed for node");
288
+ opts.onProgress?.({
289
+ nodeId: row.id,
290
+ beforeLen,
291
+ afterLen: beforeLen,
292
+ action: "failed",
293
+ reason,
294
+ });
295
+ }
296
+ }
297
+
298
+ return result;
299
+ }
@@ -262,7 +262,7 @@ async function identifyDuplicateGroups(
262
262
  ): Promise<MemoryNode[][]> {
263
263
  if (nodes.length < 2) return [];
264
264
 
265
- const provider = await getConfiguredProvider();
265
+ const provider = await getConfiguredProvider("memoryConsolidation");
266
266
  if (!provider) return [];
267
267
 
268
268
  // Compact listing: ID + first 100 chars of content
@@ -282,7 +282,7 @@ async function identifyDuplicateGroups(
282
282
  systemPrompt,
283
283
  {
284
284
  config: {
285
- modelIntent: "quality-optimized" as const,
285
+ callSite: "memoryConsolidation" as const,
286
286
  tool_choice: { type: "tool" as const, name: "report_duplicate_groups" },
287
287
  },
288
288
  },
@@ -428,7 +428,7 @@ async function consolidateChunk(
428
428
  return true;
429
429
  });
430
430
 
431
- const provider = await getConfiguredProvider();
431
+ const provider = await getConfiguredProvider("memoryConsolidation");
432
432
  if (!provider) {
433
433
  throw new BackendUnavailableError("Provider unavailable for consolidation");
434
434
  }
@@ -459,7 +459,7 @@ async function consolidateChunk(
459
459
  systemPrompt,
460
460
  {
461
461
  config: {
462
- modelIntent: "quality-optimized" as const,
462
+ callSite: "memoryConsolidation" as const,
463
463
  tool_choice: { type: "tool" as const, name: "consolidate_diff" },
464
464
  },
465
465
  },