@vellumai/assistant 0.7.3 → 0.8.1

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 (778) hide show
  1. package/AGENTS.md +11 -0
  2. package/ARCHITECTURE.md +29 -28
  3. package/Dockerfile +6 -4
  4. package/README.md +2 -2
  5. package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
  6. package/bun.lock +3 -0
  7. package/docker-entrypoint.sh +16 -0
  8. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
  9. package/eslint-rules/cli-no-daemon-internals.js +283 -0
  10. package/eslint.config.mjs +12 -0
  11. package/knip.json +3 -1
  12. package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
  13. package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
  14. package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
  15. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
  16. package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
  17. package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
  18. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
  19. package/openapi.yaml +4126 -959
  20. package/package.json +5 -1
  21. package/scripts/generate-openapi.ts +52 -4
  22. package/scripts/sync-llm-catalog.ts +165 -0
  23. package/scripts/sync-web-search-catalog.ts +107 -0
  24. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
  25. package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
  26. package/src/__tests__/annotate-risk-options.test.ts +291 -0
  27. package/src/__tests__/anthropic-provider.test.ts +92 -2
  28. package/src/__tests__/app-control-flow.test.ts +7 -0
  29. package/src/__tests__/approval-cascade.test.ts +8 -16
  30. package/src/__tests__/approval-routes-http.test.ts +6 -0
  31. package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
  32. package/src/__tests__/auto-analysis-end-to-end.test.ts +12 -25
  33. package/src/__tests__/avatar-identity-sync.test.ts +87 -0
  34. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
  35. package/src/__tests__/btw-routes.test.ts +1 -0
  36. package/src/__tests__/call-constants.test.ts +10 -1
  37. package/src/__tests__/call-controller.test.ts +127 -0
  38. package/src/__tests__/call-site-routing-provider.test.ts +172 -45
  39. package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
  40. package/src/__tests__/channel-policy.test.ts +12 -0
  41. package/src/__tests__/checker.test.ts +89 -0
  42. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +88 -30
  43. package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
  44. package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
  45. package/src/__tests__/config-loader-backfill.test.ts +526 -102
  46. package/src/__tests__/config-loader-corrupt.test.ts +68 -0
  47. package/src/__tests__/config-loader-platform-defaults.test.ts +345 -8
  48. package/src/__tests__/config-schema-cmd.test.ts +63 -29
  49. package/src/__tests__/config-schema.test.ts +14 -3
  50. package/src/__tests__/config-set-platform-guard.test.ts +75 -152
  51. package/src/__tests__/config-set-route.test.ts +198 -0
  52. package/src/__tests__/config-watcher.test.ts +6 -0
  53. package/src/__tests__/contacts-tools.test.ts +51 -199
  54. package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
  55. package/src/__tests__/context-search-agent-runner.test.ts +22 -138
  56. package/src/__tests__/context-search-conversations-source.test.ts +42 -16
  57. package/src/__tests__/context-search-fanout.test.ts +20 -157
  58. package/src/__tests__/context-search-memory-source.test.ts +3 -26
  59. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
  60. package/src/__tests__/context-search-types.test.ts +7 -2
  61. package/src/__tests__/context-window-manager.test.ts +389 -1
  62. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -6
  63. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
  64. package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
  65. package/src/__tests__/conversation-agent-loop.test.ts +3 -3
  66. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
  67. package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
  68. package/src/__tests__/conversation-error.test.ts +38 -0
  69. package/src/__tests__/conversation-fork-crud.test.ts +241 -1
  70. package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
  71. package/src/__tests__/conversation-init.benchmark.test.ts +2 -1
  72. package/src/__tests__/conversation-lifecycle.test.ts +124 -0
  73. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
  74. package/src/__tests__/conversation-process-callsite.test.ts +22 -7
  75. package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -6
  76. package/src/__tests__/conversation-runtime-assembly.test.ts +19 -10
  77. package/src/__tests__/conversation-slash-commands.test.ts +194 -2
  78. package/src/__tests__/conversation-slash-unknown.test.ts +1 -6
  79. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
  80. package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
  81. package/src/__tests__/conversation-surfaces-data-persist.test.ts +73 -1
  82. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +59 -0
  83. package/src/__tests__/conversation-workspace-injection.test.ts +1 -7
  84. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -7
  85. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  86. package/src/__tests__/daemon-credential-client.test.ts +56 -1
  87. package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
  88. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
  89. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
  90. package/src/__tests__/db-proxy-transaction.test.ts +206 -0
  91. package/src/__tests__/external-plugin-loader.test.ts +458 -0
  92. package/src/__tests__/filing-service.test.ts +25 -22
  93. package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
  94. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  95. package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
  96. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -34
  97. package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
  98. package/src/__tests__/heartbeat-service.test.ts +50 -233
  99. package/src/__tests__/history-repair.test.ts +89 -0
  100. package/src/__tests__/host-app-control-proxy.test.ts +109 -1
  101. package/src/__tests__/host-app-control-routes.test.ts +247 -1
  102. package/src/__tests__/host-browser-proxy.test.ts +416 -20
  103. package/src/__tests__/host-browser-routes.test.ts +325 -33
  104. package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
  105. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
  106. package/src/__tests__/inference-profile-reaper.test.ts +154 -0
  107. package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
  108. package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
  109. package/src/__tests__/injector-chain.test.ts +24 -16
  110. package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
  111. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
  112. package/src/__tests__/install-skill-routing.test.ts +2 -2
  113. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +169 -67
  114. package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
  115. package/src/__tests__/llm-catalog-parity.test.ts +146 -0
  116. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
  117. package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
  118. package/src/__tests__/llm-resolver.test.ts +46 -0
  119. package/src/__tests__/managed-profile-guard.test.ts +131 -2
  120. package/src/__tests__/mcp-auth-routes.test.ts +1 -0
  121. package/src/__tests__/mcp-cli.test.ts +182 -220
  122. package/src/__tests__/mcp-health-check.test.ts +56 -27
  123. package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
  124. package/src/__tests__/message-complete-display-id.test.ts +175 -0
  125. package/src/__tests__/notification-decision-fallback.test.ts +91 -0
  126. package/src/__tests__/notification-decision-strategy.test.ts +22 -0
  127. package/src/__tests__/notification-platform-adapter.test.ts +229 -0
  128. package/src/__tests__/oauth-cli.test.ts +38 -1888
  129. package/src/__tests__/oauth-commands-routes.test.ts +711 -0
  130. package/src/__tests__/oauth-connect-routes.test.ts +174 -11
  131. package/src/__tests__/oauth-providers-routes.test.ts +14 -10
  132. package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
  133. package/src/__tests__/openai-responses-provider.test.ts +17 -0
  134. package/src/__tests__/plugin-bootstrap.test.ts +31 -2
  135. package/src/__tests__/plugin-route-contribution.test.ts +31 -3
  136. package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
  137. package/src/__tests__/plugin-types.test.ts +13 -11
  138. package/src/__tests__/process-message-background-slack.test.ts +46 -0
  139. package/src/__tests__/profile-entry-status.test.ts +43 -0
  140. package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
  141. package/src/__tests__/provider-registry-ollama.test.ts +12 -4
  142. package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
  143. package/src/__tests__/relay-server.test.ts +164 -2
  144. package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
  145. package/src/__tests__/schedule-retry.test.ts +56 -4
  146. package/src/__tests__/schedule-routes.test.ts +104 -0
  147. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
  148. package/src/__tests__/scheduler-recurrence.test.ts +87 -34
  149. package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
  150. package/src/__tests__/scheduler-wake.test.ts +0 -63
  151. package/src/__tests__/secret-allowlist.test.ts +1 -0
  152. package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
  153. package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
  154. package/src/__tests__/secret-response-routing.test.ts +7 -5
  155. package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
  156. package/src/__tests__/server-history-render.test.ts +82 -0
  157. package/src/__tests__/shell-credential-ref.test.ts +95 -3
  158. package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
  159. package/src/__tests__/skill-include-graph.test.ts +31 -0
  160. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  161. package/src/__tests__/skill-load-tool.test.ts +42 -16
  162. package/src/__tests__/skills.test.ts +39 -0
  163. package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
  164. package/src/__tests__/suggestion-routes.test.ts +3 -3
  165. package/src/__tests__/sync-message-contract.test.ts +63 -0
  166. package/src/__tests__/task-scheduler.test.ts +88 -23
  167. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
  168. package/src/__tests__/tool-executor.test.ts +155 -0
  169. package/src/__tests__/update-bulletin-job.test.ts +96 -193
  170. package/src/__tests__/usage-cli.test.ts +11 -73
  171. package/src/__tests__/user-plugin-loader.test.ts +145 -0
  172. package/src/__tests__/vercel-config.test.ts +168 -0
  173. package/src/__tests__/voice-session-bridge.test.ts +3 -0
  174. package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
  175. package/src/__tests__/web-search.test.ts +303 -2
  176. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
  177. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
  178. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +153 -0
  179. package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
  180. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
  181. package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
  182. package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
  183. package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
  184. package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
  185. package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
  186. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
  187. package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +15 -27
  188. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
  189. package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
  190. package/src/acp/__tests__/helpers/which-stub.ts +4 -2
  191. package/src/acp/resolve-agent.test.ts +25 -0
  192. package/src/acp/resolve-agent.ts +13 -2
  193. package/src/acp/session-manager.ts +14 -0
  194. package/src/agent/loop.ts +11 -0
  195. package/src/approvals/guardian-decision-primitive.ts +0 -13
  196. package/src/approvals/guardian-request-resolvers.ts +19 -102
  197. package/src/calls/call-constants.ts +5 -8
  198. package/src/calls/call-controller.ts +130 -67
  199. package/src/calls/relay-server.ts +42 -1
  200. package/src/calls/relay-setup-router.ts +36 -0
  201. package/src/calls/types.ts +1 -0
  202. package/src/calls/voice-session-bridge.ts +24 -5
  203. package/src/channels/config.ts +14 -1
  204. package/src/channels/types.ts +1 -0
  205. package/src/cli/AGENTS.md +164 -4
  206. package/src/cli/__tests__/notifications.test.ts +54 -0
  207. package/src/cli/commands/__tests__/avatar.test.ts +540 -0
  208. package/src/cli/commands/__tests__/backup.test.ts +236 -776
  209. package/src/cli/commands/__tests__/cache.test.ts +1 -1
  210. package/src/cli/commands/__tests__/changelog.test.ts +593 -0
  211. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
  212. package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
  213. package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
  214. package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
  215. package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
  216. package/src/cli/commands/__tests__/email-core.test.ts +579 -0
  217. package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
  218. package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
  219. package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
  220. package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
  221. package/src/cli/commands/__tests__/skills.test.ts +563 -0
  222. package/src/cli/commands/__tests__/status.test.ts +249 -0
  223. package/src/cli/commands/__tests__/stt.test.ts +320 -0
  224. package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
  225. package/src/cli/commands/__tests__/tts.test.ts +321 -0
  226. package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
  227. package/src/cli/commands/attachment.ts +8 -3
  228. package/src/cli/commands/audit.ts +95 -64
  229. package/src/cli/commands/auth.ts +61 -58
  230. package/src/cli/commands/avatar.ts +276 -390
  231. package/src/cli/commands/backup.ts +409 -505
  232. package/src/cli/commands/bash.ts +9 -5
  233. package/src/cli/commands/browser.ts +28 -9
  234. package/src/cli/commands/cache.ts +9 -4
  235. package/src/cli/commands/changelog.ts +414 -0
  236. package/src/cli/commands/channel-verification-sessions.ts +238 -317
  237. package/src/cli/commands/clients.ts +8 -3
  238. package/src/cli/commands/completions.ts +9 -9
  239. package/src/cli/commands/config.ts +102 -72
  240. package/src/cli/commands/contacts.ts +575 -696
  241. package/src/cli/commands/conversations-defer.ts +17 -69
  242. package/src/cli/commands/conversations-import.ts +90 -253
  243. package/src/cli/commands/conversations.ts +346 -436
  244. package/src/cli/commands/credential-execution.ts +9 -6
  245. package/src/cli/commands/credentials.ts +456 -736
  246. package/src/cli/commands/domain.ts +128 -206
  247. package/src/cli/commands/email.ts +606 -794
  248. package/src/cli/commands/gateway.ts +8 -1
  249. package/src/cli/commands/image-generation.ts +157 -205
  250. package/src/cli/commands/inference-providers.ts +352 -0
  251. package/src/cli/commands/inference-session.ts +415 -0
  252. package/src/cli/commands/inference.ts +87 -65
  253. package/src/cli/commands/keys.ts +8 -3
  254. package/src/cli/commands/mcp.ts +103 -287
  255. package/src/cli/commands/memory-v2.ts +163 -517
  256. package/src/cli/commands/notifications.ts +33 -7
  257. package/src/cli/commands/oauth/apps.ts +292 -261
  258. package/src/cli/commands/oauth/connect.ts +182 -345
  259. package/src/cli/commands/oauth/disconnect.ts +16 -215
  260. package/src/cli/commands/oauth/index.ts +49 -45
  261. package/src/cli/commands/oauth/mode.ts +43 -199
  262. package/src/cli/commands/oauth/ping.ts +17 -125
  263. package/src/cli/commands/oauth/providers.ts +732 -921
  264. package/src/cli/commands/oauth/request.ts +60 -350
  265. package/src/cli/commands/oauth/shared.ts +11 -121
  266. package/src/cli/commands/oauth/status.ts +31 -121
  267. package/src/cli/commands/oauth/token.ts +13 -55
  268. package/src/cli/commands/pending.ts +19 -10
  269. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
  270. package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
  271. package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
  272. package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
  273. package/src/cli/commands/platform/connect.ts +16 -80
  274. package/src/cli/commands/platform/disconnect.ts +14 -112
  275. package/src/cli/commands/platform/index.ts +177 -246
  276. package/src/cli/commands/routes.ts +153 -336
  277. package/src/cli/commands/sequence.ts +316 -360
  278. package/src/cli/commands/skills.ts +449 -671
  279. package/src/cli/commands/status.ts +58 -37
  280. package/src/cli/commands/stt.ts +94 -262
  281. package/src/cli/commands/task.ts +14 -40
  282. package/src/cli/commands/trust.ts +8 -3
  283. package/src/cli/commands/tts.ts +162 -167
  284. package/src/cli/commands/ui.ts +35 -42
  285. package/src/cli/commands/usage.ts +188 -126
  286. package/src/cli/commands/watchers.ts +8 -3
  287. package/src/cli/commands/webhooks.ts +99 -193
  288. package/src/cli/lib/__tests__/register-command.test.ts +85 -0
  289. package/src/cli/lib/daemon-credential-client.ts +4 -5
  290. package/src/cli/lib/nested-value.ts +44 -0
  291. package/src/cli/lib/open-browser.ts +36 -0
  292. package/src/cli/lib/register-command.ts +19 -0
  293. package/src/cli/lib/time-ago.ts +34 -0
  294. package/src/cli/program.ts +2 -4
  295. package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
  296. package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
  297. package/src/cli/utils/conversation-id.ts +30 -0
  298. package/src/cli/utils/parse-duration.ts +41 -0
  299. package/src/config/acp-defaults.test.ts +5 -1
  300. package/src/config/acp-defaults.ts +11 -4
  301. package/src/config/bundled-skills/acp/TOOLS.json +2 -2
  302. package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
  303. package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
  304. package/src/config/bundled-skills/contacts/SKILL.md +12 -45
  305. package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
  306. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
  307. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
  308. package/src/config/bundled-tool-registry.ts +0 -2
  309. package/src/config/feature-flag-registry.json +17 -17
  310. package/src/config/llm-resolver.ts +16 -1
  311. package/src/config/loader.ts +148 -33
  312. package/src/config/raw-config-utils.ts +2 -30
  313. package/src/config/schema.ts +4 -0
  314. package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
  315. package/src/config/schemas/call-site-catalog.ts +29 -7
  316. package/src/config/schemas/llm-request-logs.ts +57 -0
  317. package/src/config/schemas/llm.ts +52 -2
  318. package/src/config/schemas/memory-retrospective.ts +48 -0
  319. package/src/config/schemas/memory-v2.ts +33 -2
  320. package/src/config/schemas/memory.ts +4 -0
  321. package/src/config/schemas/services.ts +15 -12
  322. package/src/config/seed-inference-profiles.ts +195 -134
  323. package/src/contacts/contact-store.ts +0 -61
  324. package/src/context/window-manager.ts +191 -5
  325. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +111 -0
  326. package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
  327. package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
  328. package/src/daemon/approval-generators.ts +23 -29
  329. package/src/daemon/config-watcher.ts +2 -0
  330. package/src/daemon/conversation-agent-loop-handlers.ts +56 -0
  331. package/src/daemon/conversation-agent-loop.ts +140 -107
  332. package/src/daemon/conversation-error.ts +21 -0
  333. package/src/daemon/conversation-lifecycle.ts +68 -13
  334. package/src/daemon/conversation-process.ts +36 -19
  335. package/src/daemon/conversation-runtime-assembly.ts +14 -5
  336. package/src/daemon/conversation-slash.ts +175 -23
  337. package/src/daemon/conversation-store.ts +17 -10
  338. package/src/daemon/conversation-surfaces.ts +92 -26
  339. package/src/daemon/conversation-tool-setup.ts +33 -19
  340. package/src/daemon/conversation.ts +49 -10
  341. package/src/daemon/external-plugins-bootstrap.ts +18 -8
  342. package/src/daemon/guardian-action-generators.ts +7 -22
  343. package/src/daemon/handlers/config-model.ts +8 -126
  344. package/src/daemon/handlers/config-slack-channel.ts +10 -7
  345. package/src/daemon/handlers/config-vercel.ts +3 -1
  346. package/src/daemon/handlers/shared.ts +26 -0
  347. package/src/daemon/handlers/skills.ts +84 -5
  348. package/src/daemon/history-repair.ts +33 -6
  349. package/src/daemon/host-app-control-proxy.ts +44 -19
  350. package/src/daemon/host-bash-proxy.ts +85 -158
  351. package/src/daemon/host-browser-proxy.ts +97 -36
  352. package/src/daemon/host-cu-proxy.ts +1 -1
  353. package/src/daemon/host-file-proxy.ts +1 -1
  354. package/src/daemon/host-proxy-base.ts +13 -1
  355. package/src/daemon/host-proxy-preactivation.ts +25 -1
  356. package/src/daemon/host-transfer-proxy.ts +2 -2
  357. package/src/daemon/identity-helpers.ts +19 -0
  358. package/src/daemon/lifecycle.ts +128 -114
  359. package/src/daemon/meet-host-supervisor.ts +15 -15
  360. package/src/daemon/memory-v2-startup.ts +62 -14
  361. package/src/daemon/message-protocol.ts +6 -0
  362. package/src/daemon/message-types/bookmarks.ts +18 -0
  363. package/src/daemon/message-types/conversations.ts +12 -9
  364. package/src/daemon/message-types/messages.ts +28 -2
  365. package/src/daemon/message-types/sync.ts +60 -0
  366. package/src/daemon/pkb-reminder-builder.test.ts +54 -13
  367. package/src/daemon/pkb-reminder-builder.ts +21 -7
  368. package/src/daemon/process-message.ts +56 -23
  369. package/src/daemon/server.ts +23 -18
  370. package/src/daemon/shutdown-handlers.ts +0 -2
  371. package/src/daemon/tool-setup-types.ts +9 -0
  372. package/src/daemon/tool-side-effects.ts +6 -4
  373. package/src/daemon/wake-target-adapter.ts +11 -0
  374. package/src/documents/document-store.ts +35 -1
  375. package/src/export/transcript-formatter.ts +61 -2
  376. package/src/filing/filing-service.ts +42 -56
  377. package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
  378. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  379. package/src/heartbeat/heartbeat-service.ts +149 -128
  380. package/src/home/__tests__/feed-types.test.ts +63 -131
  381. package/src/home/__tests__/feed-writer.test.ts +77 -278
  382. package/src/home/__tests__/post-connect-feed.test.ts +9 -12
  383. package/src/home/feed-types.ts +19 -73
  384. package/src/home/feed-writer.ts +25 -156
  385. package/src/home/post-connect-feed.ts +1 -3
  386. package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
  387. package/src/ipc/__tests__/email-ipc.test.ts +506 -0
  388. package/src/ipc/__tests__/exit-helper.test.ts +104 -0
  389. package/src/ipc/__tests__/streaming-client.test.ts +237 -0
  390. package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
  391. package/src/ipc/assistant-server.ts +148 -42
  392. package/src/ipc/cli-client.ts +370 -50
  393. package/src/ipc/routes/db-proxy-transaction.ts +151 -0
  394. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
  395. package/src/ipc/skill-routes/events.ts +30 -3
  396. package/src/ipc/skill-server.ts +99 -42
  397. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
  398. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
  399. package/src/live-voice/live-voice-session-manager.ts +11 -4
  400. package/src/live-voice/live-voice-session.ts +14 -6
  401. package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
  402. package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
  403. package/src/memory/__tests__/conversation-types.test.ts +36 -0
  404. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
  405. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +10 -57
  406. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
  407. package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
  408. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
  409. package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
  410. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
  411. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
  412. package/src/memory/bookmark-crud.ts +179 -0
  413. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
  414. package/src/memory/context-search/agent-protocol.ts +5 -1
  415. package/src/memory/context-search/agent-runner.ts +60 -85
  416. package/src/memory/context-search/limits.ts +1 -4
  417. package/src/memory/context-search/search.ts +23 -113
  418. package/src/memory/context-search/sources/conversations.ts +18 -6
  419. package/src/memory/context-search/sources/memory-v2.ts +40 -31
  420. package/src/memory/context-search/sources/memory.ts +9 -2
  421. package/src/memory/context-search/sources/workspace.ts +13 -10
  422. package/src/memory/context-search/types.ts +1 -1
  423. package/src/memory/conversation-bootstrap.ts +11 -0
  424. package/src/memory/conversation-crud.ts +312 -10
  425. package/src/memory/conversation-queries.ts +9 -5
  426. package/src/memory/conversation-title-service.ts +1 -0
  427. package/src/memory/conversation-types.ts +16 -0
  428. package/src/memory/db-init.ts +14 -0
  429. package/src/memory/embedding-backend.ts +2 -1
  430. package/src/memory/embedding-runtime-manager.ts +1 -2
  431. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +104 -61
  432. package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
  433. package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
  434. package/src/memory/graph/conversation-graph-memory.ts +108 -14
  435. package/src/memory/graph/extraction.ts +4 -0
  436. package/src/memory/graph/graph-memory-state-store.ts +16 -3
  437. package/src/memory/graph/graph-search.test.ts +6 -5
  438. package/src/memory/graph/graph-search.ts +3 -4
  439. package/src/memory/graph/retriever.test.ts +12 -7
  440. package/src/memory/graph/retriever.ts +4 -5
  441. package/src/memory/graph/tool-handlers.ts +20 -11
  442. package/src/memory/graph/tools.ts +48 -9
  443. package/src/memory/indexer.ts +18 -2
  444. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +120 -6
  445. package/src/memory/jobs/embed-concept-page.ts +261 -89
  446. package/src/memory/jobs-store.ts +51 -1
  447. package/src/memory/jobs-worker.ts +60 -7
  448. package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
  449. package/src/memory/llm-request-log-source-local.ts +26 -0
  450. package/src/memory/llm-request-log-source.ts +97 -0
  451. package/src/memory/llm-request-log-store.ts +1 -1
  452. package/src/memory/memory-retrospective-constants.ts +13 -0
  453. package/src/memory/memory-retrospective-enqueue.ts +114 -0
  454. package/src/memory/memory-retrospective-job.ts +351 -0
  455. package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
  456. package/src/memory/memory-retrospective-state.ts +162 -0
  457. package/src/memory/memory-retrospective-trigger-check.ts +91 -0
  458. package/src/memory/memory-v2-activation-log-store.ts +49 -5
  459. package/src/memory/memory-v2-concept-frequency.ts +4 -0
  460. package/src/memory/message-content.ts +38 -1
  461. package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
  462. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
  463. package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
  464. package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
  465. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
  466. package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
  467. package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
  468. package/src/memory/migrations/242-message-bookmarks.ts +38 -0
  469. package/src/memory/migrations/243-provider-connections.ts +68 -0
  470. package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
  471. package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
  472. package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
  473. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
  474. package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
  475. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
  476. package/src/memory/migrations/index.ts +7 -0
  477. package/src/memory/pkb/pkb-search.test.ts +6 -5
  478. package/src/memory/pkb/pkb-search.ts +4 -5
  479. package/src/memory/published-pages-store.ts +16 -0
  480. package/src/memory/qdrant-client.ts +3 -0
  481. package/src/memory/schema/bookmarks.ts +38 -0
  482. package/src/memory/schema/conversations.ts +2 -0
  483. package/src/memory/schema/index.ts +2 -0
  484. package/src/memory/schema/inference.ts +29 -0
  485. package/src/memory/schema/memory-core.ts +9 -0
  486. package/src/memory/search/semantic.ts +5 -9
  487. package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
  488. package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
  489. package/src/memory/v2/__tests__/activation.test.ts +46 -9
  490. package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
  491. package/src/memory/v2/__tests__/consolidation-job.test.ts +140 -163
  492. package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
  493. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
  494. package/src/memory/v2/__tests__/injection.test.ts +768 -33
  495. package/src/memory/v2/__tests__/migration.test.ts +7 -3
  496. package/src/memory/v2/__tests__/page-index.test.ts +277 -0
  497. package/src/memory/v2/__tests__/page-store.test.ts +14 -1
  498. package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
  499. package/src/memory/v2/__tests__/qdrant.test.ts +382 -9
  500. package/src/memory/v2/__tests__/reranker.test.ts +4 -4
  501. package/src/memory/v2/__tests__/router.test.ts +516 -0
  502. package/src/memory/v2/__tests__/sim.test.ts +163 -8
  503. package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
  504. package/src/memory/v2/__tests__/static-context.test.ts +8 -35
  505. package/src/memory/v2/__tests__/sweep-job.test.ts +114 -33
  506. package/src/memory/v2/activation-store.ts +34 -5
  507. package/src/memory/v2/activation.ts +40 -27
  508. package/src/memory/v2/backfill-jobs.ts +17 -84
  509. package/src/memory/v2/consolidation-job.ts +92 -86
  510. package/src/memory/v2/frontmatter-sweep.ts +91 -0
  511. package/src/memory/v2/injection.ts +466 -115
  512. package/src/memory/v2/migration.ts +117 -20
  513. package/src/memory/v2/page-index.ts +191 -0
  514. package/src/memory/v2/page-store.ts +42 -0
  515. package/src/memory/v2/prompts/consolidation.ts +14 -7
  516. package/src/memory/v2/prompts/router.ts +192 -0
  517. package/src/memory/v2/qdrant.ts +307 -133
  518. package/src/memory/v2/reranker.ts +14 -7
  519. package/src/memory/v2/router.ts +322 -0
  520. package/src/memory/v2/sim.ts +88 -34
  521. package/src/memory/v2/skill-store.ts +118 -29
  522. package/src/memory/v2/static-context.ts +20 -17
  523. package/src/memory/v2/sweep-job.ts +127 -102
  524. package/src/memory/v2/types.ts +16 -5
  525. package/src/memory/validation.ts +13 -0
  526. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
  527. package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
  528. package/src/notifications/__tests__/signal-registry.test.ts +17 -0
  529. package/src/notifications/adapters/platform.ts +171 -0
  530. package/src/notifications/conversation-pairing.ts +2 -2
  531. package/src/notifications/copy-composer.ts +61 -12
  532. package/src/notifications/decision-engine.ts +46 -0
  533. package/src/notifications/destination-resolver.ts +21 -0
  534. package/src/notifications/emit-signal.ts +28 -1
  535. package/src/notifications/home-feed-side-effect.ts +111 -0
  536. package/src/notifications/signal.ts +5 -0
  537. package/src/permissions/checker.ts +12 -0
  538. package/src/permissions/gateway-threshold-reader.ts +116 -8
  539. package/src/permissions/ipc-risk-types.ts +2 -0
  540. package/src/permissions/prompter.ts +86 -96
  541. package/src/permissions/secret-prompter.ts +31 -31
  542. package/src/plugin-api/index.ts +13 -0
  543. package/src/plugin-api/package.json +12 -0
  544. package/src/plugin-api/types.ts +62 -0
  545. package/src/plugins/defaults/injectors.ts +20 -5
  546. package/src/plugins/external-plugin-loader.ts +294 -0
  547. package/src/plugins/types.ts +46 -30
  548. package/src/plugins/user-loader.ts +64 -41
  549. package/src/proactive-artifact/job.test.ts +63 -8
  550. package/src/proactive-artifact/job.ts +20 -2
  551. package/src/proactive-artifact/message-copy.ts +18 -1
  552. package/src/proactive-artifact/trigger-state.test.ts +9 -0
  553. package/src/proactive-artifact/trigger-state.ts +4 -0
  554. package/src/prompts/__tests__/system-prompt.test.ts +105 -0
  555. package/src/prompts/system-prompt.ts +22 -1
  556. package/src/prompts/templates/SOUL.md +13 -28
  557. package/src/prompts/update-bulletin-job.ts +61 -73
  558. package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
  559. package/src/providers/__tests__/inference.test.ts +288 -0
  560. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  561. package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
  562. package/src/providers/__tests__/retry-callsite.test.ts +14 -32
  563. package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
  564. package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
  565. package/src/providers/anthropic/client.ts +95 -26
  566. package/src/providers/call-site-routing.ts +94 -16
  567. package/src/providers/connection-resolution.ts +163 -0
  568. package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
  569. package/src/providers/inference/adapter-factory.ts +173 -0
  570. package/src/providers/inference/auth.ts +112 -0
  571. package/src/providers/inference/backfill.ts +196 -0
  572. package/src/providers/inference/connections.ts +356 -0
  573. package/src/providers/inference/resolve-auth.ts +65 -0
  574. package/src/providers/model-catalog.ts +104 -6
  575. package/src/providers/openai/responses-provider.ts +4 -2
  576. package/src/providers/provider-env-vars.ts +17 -7
  577. package/src/providers/provider-secret-catalog.ts +49 -30
  578. package/src/providers/provider-send-message.ts +41 -20
  579. package/src/providers/registry.ts +143 -159
  580. package/src/providers/retry.ts +18 -10
  581. package/src/providers/search-provider-catalog.ts +121 -0
  582. package/src/runtime/AGENTS.md +18 -5
  583. package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
  584. package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
  585. package/src/runtime/actor-trust-resolver.ts +32 -10
  586. package/src/runtime/agent-wake.ts +35 -6
  587. package/src/runtime/assistant-event-hub.ts +3 -85
  588. package/src/runtime/auth/route-policy.ts +304 -8
  589. package/src/runtime/auth/same-actor.ts +2 -0
  590. package/src/runtime/background-job-runner.ts +339 -0
  591. package/src/runtime/btw-sidechain.ts +1 -0
  592. package/src/runtime/channel-approvals.ts +3 -2
  593. package/src/runtime/guardian-reply-router.ts +0 -10
  594. package/src/runtime/http-router.ts +36 -1
  595. package/src/runtime/http-server.ts +31 -5
  596. package/src/runtime/http-types.ts +2 -0
  597. package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
  598. package/src/runtime/middleware/request-logger.ts +62 -1
  599. package/src/runtime/pending-interactions.ts +19 -15
  600. package/src/runtime/pre-first-message-gate.ts +83 -0
  601. package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
  602. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
  603. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
  604. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
  605. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
  606. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
  607. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
  608. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
  609. package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
  610. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
  611. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  612. package/src/runtime/routes/acp-routes.ts +10 -8
  613. package/src/runtime/routes/app-management-routes.ts +228 -3
  614. package/src/runtime/routes/approval-routes.ts +7 -21
  615. package/src/runtime/routes/audit-routes.ts +43 -0
  616. package/src/runtime/routes/auth-routes.ts +72 -0
  617. package/src/runtime/routes/avatar-routes.ts +273 -20
  618. package/src/runtime/routes/backup-routes.ts +406 -2
  619. package/src/runtime/routes/bookmark-routes.ts +154 -0
  620. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  621. package/src/runtime/routes/consolidation-routes.ts +8 -9
  622. package/src/runtime/routes/contact-routes.ts +0 -160
  623. package/src/runtime/routes/conversation-cli-routes.ts +192 -0
  624. package/src/runtime/routes/conversation-management-routes.ts +30 -43
  625. package/src/runtime/routes/conversation-query-routes.ts +373 -82
  626. package/src/runtime/routes/conversation-routes.ts +31 -10
  627. package/src/runtime/routes/conversations-import-routes.ts +229 -0
  628. package/src/runtime/routes/credential-routes.ts +540 -0
  629. package/src/runtime/routes/debug-bash-routes.ts +2 -0
  630. package/src/runtime/routes/debug-routes.ts +2 -2
  631. package/src/runtime/routes/document-pdf-renderer.ts +5 -1
  632. package/src/runtime/routes/domain-routes.ts +167 -0
  633. package/src/runtime/routes/email-routes.ts +603 -0
  634. package/src/runtime/routes/errors.ts +2 -2
  635. package/src/runtime/routes/events-routes.ts +192 -0
  636. package/src/runtime/routes/filing-routes.ts +2 -3
  637. package/src/runtime/routes/home-feed-routes.ts +6 -78
  638. package/src/runtime/routes/host-app-control-routes.ts +44 -2
  639. package/src/runtime/routes/host-browser-routes.ts +103 -22
  640. package/src/runtime/routes/http-adapter.ts +2 -0
  641. package/src/runtime/routes/identity-routes.ts +5 -0
  642. package/src/runtime/routes/image-generation-routes.ts +99 -0
  643. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
  644. package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
  645. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
  646. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -7
  647. package/src/runtime/routes/index.ts +36 -0
  648. package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
  649. package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
  650. package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
  651. package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
  652. package/src/runtime/routes/inference-send-routes.ts +115 -0
  653. package/src/runtime/routes/integrations/twilio.ts +1 -0
  654. package/src/runtime/routes/mcp-auth-routes.ts +283 -9
  655. package/src/runtime/routes/memory-item-routes.test.ts +3 -9
  656. package/src/runtime/routes/memory-item-routes.ts +5 -6
  657. package/src/runtime/routes/memory-v2-routes.ts +105 -404
  658. package/src/runtime/routes/notification-routes.ts +2 -0
  659. package/src/runtime/routes/oauth-apps.ts +112 -7
  660. package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
  661. package/src/runtime/routes/oauth-connect-routes.ts +67 -5
  662. package/src/runtime/routes/oauth-providers.ts +298 -8
  663. package/src/runtime/routes/platform-routes.ts +336 -0
  664. package/src/runtime/routes/playground/inject-failures.ts +2 -1
  665. package/src/runtime/routes/playground/reset-circuit.ts +2 -1
  666. package/src/runtime/routes/playground/state.ts +2 -1
  667. package/src/runtime/routes/publish-routes.ts +221 -0
  668. package/src/runtime/routes/schedule-routes.ts +82 -0
  669. package/src/runtime/routes/sequence-routes.ts +291 -0
  670. package/src/runtime/routes/settings-routes.ts +2 -10
  671. package/src/runtime/routes/skills-routes.ts +31 -1
  672. package/src/runtime/routes/stt-routes.ts +240 -3
  673. package/src/runtime/routes/surface-action-routes.ts +43 -7
  674. package/src/runtime/routes/tts-routes.ts +67 -0
  675. package/src/runtime/routes/types.ts +32 -0
  676. package/src/runtime/routes/user-routes-cli.ts +243 -0
  677. package/src/runtime/routes/webhook-routes.ts +165 -0
  678. package/src/runtime/sync/resource-sync-events.ts +25 -0
  679. package/src/runtime/sync/sync-publisher.test.ts +105 -0
  680. package/src/runtime/sync/sync-publisher.ts +21 -0
  681. package/src/schedule/scheduler.ts +200 -123
  682. package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
  683. package/src/security/secret-patterns.ts +3 -0
  684. package/src/sequence/engine.ts +38 -40
  685. package/src/skills/include-graph.ts +35 -13
  686. package/src/subagent/manager.ts +20 -15
  687. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
  688. package/src/tools/browser/browser-execution.ts +15 -4
  689. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
  690. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
  691. package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
  692. package/src/tools/browser/cdp-client/factory.ts +66 -5
  693. package/src/tools/browser/runtime-check.ts +77 -0
  694. package/src/tools/document/document-tool.ts +20 -0
  695. package/src/tools/executor.ts +18 -2
  696. package/src/tools/memory/register.test.ts +10 -8
  697. package/src/tools/memory/register.ts +9 -1
  698. package/src/tools/network/__tests__/web-search.test.ts +156 -0
  699. package/src/tools/network/web-search.ts +280 -37
  700. package/src/tools/permission-checker.ts +28 -5
  701. package/src/tools/skills/load.ts +24 -20
  702. package/src/tools/subagent/spawn.ts +3 -3
  703. package/src/tools/terminal/shell.ts +44 -0
  704. package/src/tools/tool-name-aliases.ts +19 -0
  705. package/src/tools/types.ts +19 -1
  706. package/src/usage/attribution.ts +3 -2
  707. package/src/util/pricing.ts +86 -160
  708. package/src/watcher/__tests__/engine.test.ts +301 -0
  709. package/src/watcher/constants.ts +7 -0
  710. package/src/watcher/engine.ts +90 -90
  711. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
  712. package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
  713. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
  714. package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +4 -62
  715. package/src/workspace/migrations/069-seed-onboarding-threads.ts +34 -0
  716. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
  717. package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
  718. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
  719. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
  720. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
  721. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
  722. package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
  723. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
  724. package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
  725. package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
  726. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
  727. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
  728. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
  729. package/src/workspace/migrations/registry.ts +28 -0
  730. package/src/workspace/migrations/runner.ts +13 -2
  731. package/src/workspace/migrations/types.ts +13 -3
  732. package/src/workspace/provider-commit-message-generator.ts +3 -2
  733. package/src/__tests__/context-search-pkb-source.test.ts +0 -492
  734. package/src/__tests__/credentials-cli.test.ts +0 -1225
  735. package/src/__tests__/memory-admin-recall.test.ts +0 -213
  736. package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
  737. package/src/cli/commands/__tests__/email-download.test.ts +0 -260
  738. package/src/cli/commands/__tests__/email-list.test.ts +0 -216
  739. package/src/cli/commands/__tests__/email-register.test.ts +0 -186
  740. package/src/cli/commands/__tests__/email-send.test.ts +0 -416
  741. package/src/cli/commands/__tests__/email-status.test.ts +0 -185
  742. package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
  743. package/src/cli/commands/__tests__/routes.test.ts +0 -562
  744. package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
  745. package/src/cli/commands/autonomy.ts +0 -365
  746. package/src/cli/commands/memory.ts +0 -424
  747. package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -1201
  748. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
  749. package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
  750. package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
  751. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
  752. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
  753. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
  754. package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
  755. package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
  756. package/src/cli/lib/daemon-avatar-client.ts +0 -37
  757. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
  758. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
  759. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
  760. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
  761. package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
  762. package/src/home/__tests__/emit-feed-event.test.ts +0 -169
  763. package/src/home/__tests__/feed-population-integration.test.ts +0 -312
  764. package/src/home/__tests__/feed-scheduler.test.ts +0 -222
  765. package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
  766. package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
  767. package/src/home/__tests__/rollup-producer.test.ts +0 -507
  768. package/src/home/assistant-feed-authoring.ts +0 -135
  769. package/src/home/emit-feed-event.ts +0 -169
  770. package/src/home/feed-scheduler.ts +0 -281
  771. package/src/home/platform-gmail-digest.ts +0 -163
  772. package/src/home/rewrite-command-preview.ts +0 -66
  773. package/src/home/rewrite-feed-title.ts +0 -58
  774. package/src/home/rollup-producer.ts +0 -426
  775. package/src/memory/admin.ts +0 -326
  776. package/src/memory/context-search/sources/pkb.ts +0 -477
  777. package/src/memory/graph/compaction.ts +0 -299
  778. /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
@@ -23,6 +23,7 @@ import { initializeDb } from "../db-init.js";
23
23
  import {
24
24
  backfillMemoryV2ActivationMessageId,
25
25
  getMemoryV2ActivationLogByMessageIds,
26
+ type MemoryV2ConceptRowRecord,
26
27
  recordMemoryV2ActivationLog,
27
28
  } from "../memory-v2-activation-log-store.js";
28
29
  import { memoryV2ActivationLogs } from "../schema.js";
@@ -66,6 +67,74 @@ describe("memory-v2-activation-log-store", () => {
66
67
  expect(result!.config).toEqual(sampleConfig);
67
68
  });
68
69
 
70
+ test("round-trip: router-mode log row with zeroed activations and source: 'router'", () => {
71
+ const conversationId = "conv-router";
72
+ const messageId = "msg-router";
73
+
74
+ const routerConcepts: MemoryV2ConceptRowRecord[] = [
75
+ {
76
+ slug: "concept-router-a",
77
+ finalActivation: 0,
78
+ ownActivation: 0,
79
+ priorActivation: 0,
80
+ simUser: 0,
81
+ simAssistant: 0,
82
+ simNow: 0,
83
+ simUserRerankBoost: 0,
84
+ simAssistantRerankBoost: 0,
85
+ inRerankPool: false,
86
+ spreadContribution: 0,
87
+ source: "router",
88
+ status: "injected",
89
+ },
90
+ {
91
+ slug: "concept-router-b",
92
+ finalActivation: 0,
93
+ ownActivation: 0,
94
+ priorActivation: 0,
95
+ simUser: 0,
96
+ simAssistant: 0,
97
+ simNow: 0,
98
+ simUserRerankBoost: 0,
99
+ simAssistantRerankBoost: 0,
100
+ inRerankPool: false,
101
+ spreadContribution: 0,
102
+ source: "router",
103
+ status: "not_injected",
104
+ },
105
+ ];
106
+
107
+ recordMemoryV2ActivationLog({
108
+ conversationId,
109
+ turn: 7,
110
+ mode: "router",
111
+ concepts: routerConcepts,
112
+ config: sampleConfig,
113
+ });
114
+
115
+ backfillMemoryV2ActivationMessageId(conversationId, messageId);
116
+
117
+ const result = getMemoryV2ActivationLogByMessageIds([messageId]);
118
+ expect(result).not.toBeNull();
119
+ expect(result!.conversationId).toBe(conversationId);
120
+ expect(result!.turn).toBe(7);
121
+ expect(result!.mode).toBe("router");
122
+ expect(result!.concepts).toEqual(routerConcepts);
123
+ expect(result!.config).toEqual(sampleConfig);
124
+ for (const concept of result!.concepts) {
125
+ expect(concept.source).toBe("router");
126
+ expect(concept.finalActivation).toBe(0);
127
+ expect(concept.ownActivation).toBe(0);
128
+ expect(concept.priorActivation).toBe(0);
129
+ expect(concept.simUser).toBe(0);
130
+ expect(concept.simAssistant).toBe(0);
131
+ expect(concept.simNow).toBe(0);
132
+ expect(concept.simUserRerankBoost).toBe(0);
133
+ expect(concept.simAssistantRerankBoost).toBe(0);
134
+ expect(concept.spreadContribution).toBe(0);
135
+ }
136
+ });
137
+
69
138
  test("returns null for empty messageIds array", () => {
70
139
  const result = getMemoryV2ActivationLogByMessageIds([]);
71
140
  expect(result).toBeNull();
@@ -117,6 +117,7 @@ describe("memory-v2-concept-frequency", () => {
117
117
  in_context: 1,
118
118
  not_injected: 0,
119
119
  page_missing: 0,
120
+ corrupt: 0,
120
121
  });
121
122
  expect(bySlug.get("alice")!.totalEvaluations).toBe(3);
122
123
  expect(bySlug.get("alice")!.onDisk).toBe(true);
@@ -127,6 +128,7 @@ describe("memory-v2-concept-frequency", () => {
127
128
  in_context: 0,
128
129
  not_injected: 1,
129
130
  page_missing: 0,
131
+ corrupt: 0,
130
132
  });
131
133
  expect(bySlug.get("bob")!.totalEvaluations).toBe(2);
132
134
  expect(bySlug.get("bob")!.onDisk).toBe(true);
@@ -136,6 +138,7 @@ describe("memory-v2-concept-frequency", () => {
136
138
  in_context: 0,
137
139
  not_injected: 0,
138
140
  page_missing: 1,
141
+ corrupt: 0,
139
142
  });
140
143
  expect(bySlug.get("charlie")!.onDisk).toBe(false);
141
144
  expect(bySlug.get("charlie")!.lastInjectedAt).toBeNull();
@@ -0,0 +1,179 @@
1
+ import { desc, eq } from "drizzle-orm";
2
+ import { v4 as uuid } from "uuid";
3
+
4
+ import type { DrizzleDb } from "./db-connection.js";
5
+ import { stringifyMessageContent } from "./message-content.js";
6
+ import { conversations, messageBookmarks, messages } from "./schema.js";
7
+
8
+ /**
9
+ * Wire-shape representation of a bookmark, joined with the bookmarked
10
+ * message and its parent conversation. Mirrors
11
+ * `clients/shared/Network/BookmarkSummary.swift` — dates are emitted as
12
+ * unix-millisecond integers, and the message preview is capped to keep
13
+ * the list payload bounded.
14
+ */
15
+ export interface BookmarkSummary {
16
+ id: string;
17
+ messageId: string;
18
+ conversationId: string;
19
+ conversationTitle: string | null;
20
+ messagePreview: string;
21
+ /** "user" | "assistant" — kept as a free-form string so it round-trips raw. */
22
+ messageRole: string;
23
+ /** Unix milliseconds. */
24
+ messageCreatedAt: number;
25
+ /** Unix milliseconds. */
26
+ createdAt: number;
27
+ }
28
+
29
+ const PREVIEW_MAX_CHARS = 240;
30
+
31
+ /**
32
+ * Decode the on-disk message content (legacy plain string OR JSON-serialized
33
+ * `ContentBlock[]`) into a single text string and cap it at
34
+ * `PREVIEW_MAX_CHARS`. Without the decode step, modern rows would render as
35
+ * raw JSON in the bookmark list.
36
+ */
37
+ function buildPreview(content: string): string {
38
+ const text = stringifyMessageContent(content);
39
+ return text.length > PREVIEW_MAX_CHARS
40
+ ? text.slice(0, PREVIEW_MAX_CHARS)
41
+ : text;
42
+ }
43
+
44
+ /**
45
+ * Shared SELECT shape used by the JOIN-based readers. Pulling this out
46
+ * avoids duplicating the column list and the row-mapping below.
47
+ */
48
+ const BOOKMARK_JOIN_COLUMNS = {
49
+ id: messageBookmarks.id,
50
+ messageId: messageBookmarks.messageId,
51
+ conversationId: messageBookmarks.conversationId,
52
+ createdAt: messageBookmarks.createdAt,
53
+ conversationTitle: conversations.title,
54
+ messageContent: messages.content,
55
+ messageRole: messages.role,
56
+ messageCreatedAt: messages.createdAt,
57
+ } as const;
58
+
59
+ type BookmarkJoinRow = {
60
+ id: string;
61
+ messageId: string;
62
+ conversationId: string;
63
+ createdAt: number;
64
+ conversationTitle: string | null;
65
+ messageContent: string;
66
+ messageRole: string;
67
+ messageCreatedAt: number;
68
+ };
69
+
70
+ function rowToSummary(row: BookmarkJoinRow): BookmarkSummary {
71
+ return {
72
+ id: row.id,
73
+ messageId: row.messageId,
74
+ conversationId: row.conversationId,
75
+ conversationTitle: row.conversationTitle,
76
+ messagePreview: buildPreview(row.messageContent),
77
+ messageRole: row.messageRole,
78
+ messageCreatedAt: row.messageCreatedAt,
79
+ createdAt: row.createdAt,
80
+ };
81
+ }
82
+
83
+ function selectBookmarkJoin(db: DrizzleDb) {
84
+ return db
85
+ .select(BOOKMARK_JOIN_COLUMNS)
86
+ .from(messageBookmarks)
87
+ .innerJoin(messages, eq(messages.id, messageBookmarks.messageId))
88
+ .innerJoin(
89
+ conversations,
90
+ eq(conversations.id, messageBookmarks.conversationId),
91
+ );
92
+ }
93
+
94
+ /**
95
+ * List all bookmarks newest-first, joined against `messages` and
96
+ * `conversations`. Bookmarks whose parent message or conversation has
97
+ * been deleted are naturally excluded by the inner-join semantics; the
98
+ * `ON DELETE CASCADE` on the FKs means rows should never end up in this
99
+ * orphan state, but the join provides a defense-in-depth guarantee.
100
+ */
101
+ export function listBookmarks(db: DrizzleDb): BookmarkSummary[] {
102
+ const rows = selectBookmarkJoin(db)
103
+ .orderBy(desc(messageBookmarks.createdAt))
104
+ .all();
105
+ return rows.map(rowToSummary);
106
+ }
107
+
108
+ /**
109
+ * Create a bookmark for the given message and return its JOIN-shaped
110
+ * {@link BookmarkSummary}. Idempotent on the unique `message_id` index —
111
+ * if a bookmark already exists for `messageId`, the existing summary is
112
+ * returned and no new row is inserted.
113
+ */
114
+ export function createBookmark(
115
+ db: DrizzleDb,
116
+ params: { messageId: string; conversationId: string },
117
+ ): BookmarkSummary {
118
+ const { messageId, conversationId } = params;
119
+ const existing = db
120
+ .select({ id: messageBookmarks.id })
121
+ .from(messageBookmarks)
122
+ .where(eq(messageBookmarks.messageId, messageId))
123
+ .get();
124
+ if (existing) return readBookmarkSummaryOrThrow(db, existing.id);
125
+
126
+ const id = uuid();
127
+ try {
128
+ db.insert(messageBookmarks)
129
+ .values({ id, messageId, conversationId, createdAt: Date.now() })
130
+ .run();
131
+ } catch (err) {
132
+ // Lost a race against a concurrent create — fall back to fetch by
133
+ // messageId so we still return the winning row.
134
+ const winner = db
135
+ .select({ id: messageBookmarks.id })
136
+ .from(messageBookmarks)
137
+ .where(eq(messageBookmarks.messageId, messageId))
138
+ .get();
139
+ if (!winner) throw err;
140
+ return readBookmarkSummaryOrThrow(db, winner.id);
141
+ }
142
+ return readBookmarkSummaryOrThrow(db, id);
143
+ }
144
+
145
+ function readBookmarkSummaryOrThrow(
146
+ db: DrizzleDb,
147
+ id: string,
148
+ ): BookmarkSummary {
149
+ const row = selectBookmarkJoin(db).where(eq(messageBookmarks.id, id)).get();
150
+ if (!row) {
151
+ // Unreachable: caller just observed (or inserted) this id.
152
+ throw new Error(`Bookmark ${id} disappeared between insert and read`);
153
+ }
154
+ return rowToSummary(row);
155
+ }
156
+
157
+ /**
158
+ * Delete the bookmark (if any) attached to the given `messageId`.
159
+ * Returns true iff a row was removed.
160
+ *
161
+ * Drizzle's high-level `.run()` is typed as `void` for the sync sqlite
162
+ * driver, so we check existence with a follow-up SELECT instead of
163
+ * relying on a row-count from the delete statement.
164
+ */
165
+ export function deleteBookmarkByMessageId(
166
+ db: DrizzleDb,
167
+ messageId: string,
168
+ ): boolean {
169
+ const existed = db
170
+ .select({ id: messageBookmarks.id })
171
+ .from(messageBookmarks)
172
+ .where(eq(messageBookmarks.messageId, messageId))
173
+ .get();
174
+ if (!existed) return false;
175
+ db.delete(messageBookmarks)
176
+ .where(eq(messageBookmarks.messageId, messageId))
177
+ .run();
178
+ return true;
179
+ }
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * `redactWorkspaceEvidence` scrubs secrets from workspace-sourced evidence
6
6
  * excerpts before they are serialised into the prompt that is sent to the
7
- * external recall LLM provider. Memory/PKB/conversation evidence is left
7
+ * external recall LLM provider. Memory/conversation evidence is left
8
8
  * untouched — those sources contain intentionally stored user content.
9
9
  */
10
10
 
@@ -65,7 +65,10 @@ describe("redactWorkspaceEvidence", () => {
65
65
 
66
66
  test("does NOT modify non-secret workspace excerpts", () => {
67
67
  const safeContent = "This is a normal comment explaining the architecture.";
68
- const original = makeEvidence({ source: "workspace", excerpt: safeContent });
68
+ const original = makeEvidence({
69
+ source: "workspace",
70
+ excerpt: safeContent,
71
+ });
69
72
  const [result] = redactWorkspaceEvidence([original]);
70
73
 
71
74
  expect(result.excerpt).toBe(safeContent);
@@ -74,11 +77,11 @@ describe("redactWorkspaceEvidence", () => {
74
77
  });
75
78
 
76
79
  test("does NOT redact non-workspace sources", () => {
77
- // Memory/PKB/conversation evidence is intentionally stored user content —
80
+ // Memory/conversation evidence is intentionally stored user content —
78
81
  // redacting it would break recall for things the user deliberately noted.
79
82
  const secretLike = "token=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0In0.abc";
80
83
 
81
- for (const source of ["memory", "pkb", "conversations"] as const) {
84
+ for (const source of ["memory", "conversations"] as const) {
82
85
  const original = makeEvidence({ source, excerpt: secretLike });
83
86
  const [result] = redactWorkspaceEvidence([original]);
84
87
 
@@ -89,8 +92,16 @@ describe("redactWorkspaceEvidence", () => {
89
92
 
90
93
  test("redacts multiple secrets across multiple workspace evidence items", () => {
91
94
  const results = redactWorkspaceEvidence([
92
- makeEvidence({ id: "ev-1", source: "workspace", excerpt: `key=${ANTHROPIC_KEY}` }),
93
- makeEvidence({ id: "ev-2", source: "workspace", excerpt: GENERIC_SECRET_EXCERPT }),
95
+ makeEvidence({
96
+ id: "ev-1",
97
+ source: "workspace",
98
+ excerpt: `key=${ANTHROPIC_KEY}`,
99
+ }),
100
+ makeEvidence({
101
+ id: "ev-2",
102
+ source: "workspace",
103
+ excerpt: GENERIC_SECRET_EXCERPT,
104
+ }),
94
105
  ]);
95
106
 
96
107
  expect(results[0].excerpt).not.toContain(ANTHROPIC_KEY);
@@ -101,7 +112,10 @@ describe("redactWorkspaceEvidence", () => {
101
112
 
102
113
  test("does not mutate the original evidence objects", () => {
103
114
  const secret = ANTHROPIC_KEY;
104
- const original = makeEvidence({ source: "workspace", excerpt: `key=${secret}` });
115
+ const original = makeEvidence({
116
+ source: "workspace",
117
+ excerpt: `key=${secret}`,
118
+ });
105
119
  const originalExcerpt = original.excerpt;
106
120
 
107
121
  redactWorkspaceEvidence([original]);
@@ -111,8 +125,16 @@ describe("redactWorkspaceEvidence", () => {
111
125
 
112
126
  test("handles mixed sources in one batch correctly", () => {
113
127
  const secret = ANTHROPIC_KEY;
114
- const wsItem = makeEvidence({ id: "ev-ws", source: "workspace", excerpt: `key=${secret}` });
115
- const memItem = makeEvidence({ id: "ev-mem", source: "memory", excerpt: `key=${secret}` });
128
+ const wsItem = makeEvidence({
129
+ id: "ev-ws",
130
+ source: "workspace",
131
+ excerpt: `key=${secret}`,
132
+ });
133
+ const memItem = makeEvidence({
134
+ id: "ev-mem",
135
+ source: "memory",
136
+ excerpt: `key=${secret}`,
137
+ });
116
138
 
117
139
  const [wsResult, memResult] = redactWorkspaceEvidence([wsItem, memItem]);
118
140
 
@@ -34,6 +34,7 @@ type RecallFinishFallbackReason =
34
34
  | "malformed_finish_payload"
35
35
  | "invalid_confidence"
36
36
  | "invalid_citation_ids"
37
+ | "missing_citations"
37
38
  | "unknown_citation_ids"
38
39
  | "empty_answer";
39
40
 
@@ -57,7 +58,6 @@ const DEFAULT_MAX_SEARCH_CALLS = 4;
57
58
 
58
59
  const RECALL_SOURCE_DESCRIPTIONS: Record<RecallSource, string> = {
59
60
  memory: "durable memory graph facts and relationship/context memories",
60
- pkb: "personal knowledge base notes, NOW context, and pinned context",
61
61
  conversations: "past assistant conversations and conversation summaries",
62
62
  workspace: "files and text available in the current workspace",
63
63
  };
@@ -293,6 +293,10 @@ export function validateFinishRecallPayload(
293
293
  return fallbackFinish("invalid_citation_ids");
294
294
  }
295
295
 
296
+ if (payload.citation_ids.length === 0) {
297
+ return fallbackFinish("missing_citations");
298
+ }
299
+
296
300
  const citationValidation = validateRecallCitationIds(
297
301
  payload.citation_ids,
298
302
  evidence,
@@ -27,13 +27,13 @@ import {
27
27
  import {
28
28
  type DeterministicRecallSearchOptions,
29
29
  type DeterministicRecallSearchResult,
30
- isAutoInjectedPkbContextEvidence,
31
30
  runDeterministicRecallSearch,
32
31
  } from "./search.js";
33
32
  import {
34
33
  extractWorkspacePathLiterals,
35
34
  inspectWorkspacePaths,
36
35
  isSafeWorkspaceRelativePath,
36
+ normalizeWorkspacePathLiteral,
37
37
  } from "./sources/workspace.js";
38
38
  import type {
39
39
  RecallAnswer,
@@ -214,19 +214,6 @@ const FINISH_NEGATIVE_PATTERNS = [
214
214
  /\bno text\b/i,
215
215
  ];
216
216
 
217
- const PKB_RELATIVE_PATH_PREFIXES = [
218
- "archive/",
219
- "dpo/",
220
- "essentials.md",
221
- "INDEX.md",
222
- "intimate/",
223
- "people/",
224
- "preferences/",
225
- "procedures/",
226
- "schedule/",
227
- "us-arcs/",
228
- ];
229
-
230
217
  export async function runAgenticRecall(
231
218
  input: RecallInput,
232
219
  context: RecallSearchContext,
@@ -429,7 +416,7 @@ export async function runAgenticRecall(
429
416
  * Redact secrets from workspace-sourced evidence excerpts before they are
430
417
  * serialised into a prompt that will be sent to an external LLM provider.
431
418
  *
432
- * Memory, PKB, and conversation evidence is already controlled content —
419
+ * Memory and conversation evidence is already controlled content —
433
420
  * only workspace files can contain arbitrary secrets (API keys, tokens, etc.)
434
421
  * written by the user or by tools. This runs the same pattern-based scanner
435
422
  * used for shell command summaries and approval prompts, replacing any
@@ -499,7 +486,7 @@ async function runSeedRecallSearch(
499
486
  context,
500
487
  searchOptions,
501
488
  );
502
- evidence = mergeEvidence(expansionResult.evidence, evidence);
489
+ evidence = mergeEvidence(evidence, expansionResult.evidence);
503
490
  }
504
491
 
505
492
  return withFallbackEvidence(baseResult, evidence);
@@ -694,6 +681,13 @@ function finishRecallFromToolUse(
694
681
  }
695
682
 
696
683
  const citedEvidence = selectCitedEvidence(promptEvidence, finish.citationIds);
684
+ if (citedEvidence.length === 0) {
685
+ return {
686
+ ok: false,
687
+ reason: "citation_validation_failed",
688
+ detail: "finish_recall returned no resolvable citations",
689
+ };
690
+ }
697
691
  debug.finish = {
698
692
  confidence: finish.confidence,
699
693
  citationIds: finish.citationIds,
@@ -960,14 +954,16 @@ async function executeInspectWorkspacePaths(
960
954
  }> {
961
955
  const reason = readSearchReason(payload.reason);
962
956
  const requestedPaths = readInspectPaths(payload.paths);
963
- const allowedPaths = collectInspectableWorkspacePaths(input.query, evidence);
957
+ const workspaceSourceEnabled = input.sources.includes("workspace");
958
+ const allowedPaths = workspaceSourceEnabled
959
+ ? collectInspectableWorkspacePaths(input.query, evidence)
960
+ : new Set<string>();
964
961
  const acceptedPaths: string[] = [];
965
962
  const rejectedPaths: string[] = [];
966
963
  for (const requestedPath of requestedPaths) {
967
- const acceptedPath = normalizeRequestedWorkspaceInspectionPath(
968
- requestedPath,
969
- allowedPaths,
970
- );
964
+ const acceptedPath = workspaceSourceEnabled
965
+ ? normalizeRequestedWorkspaceInspectionPath(requestedPath, allowedPaths)
966
+ : null;
971
967
  if (acceptedPath) {
972
968
  acceptedPaths.push(acceptedPath);
973
969
  } else {
@@ -994,6 +990,7 @@ async function executeInspectWorkspacePaths(
994
990
  ],
995
991
  debug: {
996
992
  ...debug,
993
+ evidenceCount: 1,
997
994
  errors: [
998
995
  {
999
996
  path: "inspect_workspace_paths",
@@ -1006,8 +1003,9 @@ async function executeInspectWorkspacePaths(
1006
1003
 
1007
1004
  const errors = rejectedPaths.map((path) => ({
1008
1005
  path,
1009
- reason:
1010
- "path was not a safe relative workspace file surfaced by the query or prior evidence",
1006
+ reason: workspaceSourceEnabled
1007
+ ? "path was not a safe relative workspace file surfaced by the query or prior evidence"
1008
+ : "workspace source is disabled for this recall request",
1011
1009
  }));
1012
1010
 
1013
1011
  let inspectionEvidence: RecallEvidence[] = [];
@@ -1049,7 +1047,7 @@ async function runAutomaticWorkspaceInspection(
1049
1047
  evidence: RecallEvidence[];
1050
1048
  debug?: AgenticRecallInspectDebug;
1051
1049
  }> {
1052
- if (!input.sources.includes("workspace") && !input.sources.includes("pkb")) {
1050
+ if (!input.sources.includes("workspace")) {
1053
1051
  return { evidence: [] };
1054
1052
  }
1055
1053
 
@@ -1113,7 +1111,7 @@ function collectAutomaticWorkspaceInspectionPaths(
1113
1111
  for (const item of evidence) {
1114
1112
  collectEvidenceWorkspacePaths(item).forEach((path) => paths.add(path));
1115
1113
  }
1116
- return [...paths].filter(isSafeWorkspaceRelativePath).slice(0, 3);
1114
+ return [...paths].slice(0, 3);
1117
1115
  }
1118
1116
 
1119
1117
  function collectInspectableWorkspacePaths(
@@ -1128,62 +1126,33 @@ function collectInspectableWorkspacePaths(
1128
1126
  }
1129
1127
 
1130
1128
  function collectEvidenceWorkspacePaths(item: RecallEvidence): string[] {
1131
- if (isAutoInjectedPkbContextEvidence(item)) {
1132
- return [];
1133
- }
1134
-
1135
- const rawPaths = new Set<string>();
1129
+ const paths = new Set<string>();
1136
1130
  const metadataPath = item.metadata?.path;
1137
- if (typeof metadataPath === "string") {
1138
- rawPaths.add(metadataPath);
1131
+ if (
1132
+ typeof metadataPath === "string" &&
1133
+ isSafeWorkspaceRelativePath(metadataPath)
1134
+ ) {
1135
+ paths.add(metadataPath);
1139
1136
  }
1140
1137
  for (const text of [item.locator, item.title, item.excerpt]) {
1141
1138
  for (const path of extractWorkspacePathLiterals(text)) {
1142
- rawPaths.add(path);
1143
- }
1144
- }
1145
-
1146
- const paths: string[] = [];
1147
- for (const rawPath of rawPaths) {
1148
- for (const path of normalizeEvidenceWorkspacePath(rawPath, item.source)) {
1149
1139
  if (isSafeWorkspaceRelativePath(path)) {
1150
- paths.push(path);
1140
+ paths.add(path);
1151
1141
  }
1152
1142
  }
1153
1143
  }
1154
- return [...new Set(paths)];
1144
+ return [...paths];
1155
1145
  }
1156
1146
 
1157
1147
  function normalizeRequestedWorkspaceInspectionPath(
1158
1148
  requestedPath: string,
1159
1149
  allowedPaths: ReadonlySet<string>,
1160
1150
  ): string | null {
1161
- const pkbPrefixedPath = `pkb/${requestedPath}`;
1162
- if (!requestedPath.startsWith("pkb/") && allowedPaths.has(pkbPrefixedPath)) {
1163
- return pkbPrefixedPath;
1164
- }
1165
-
1166
- if (allowedPaths.has(requestedPath)) {
1167
- return requestedPath;
1168
- }
1169
-
1170
- return null;
1171
- }
1172
-
1173
- function normalizeEvidenceWorkspacePath(
1174
- path: string,
1175
- source: RecallSource,
1176
- ): string[] {
1177
- if (path.startsWith("pkb/")) {
1178
- return [path];
1179
- }
1180
- if (
1181
- source === "pkb" ||
1182
- PKB_RELATIVE_PATH_PREFIXES.some((prefix) => path.startsWith(prefix))
1183
- ) {
1184
- return [`pkb/${path}`];
1151
+ const normalized = normalizeWorkspacePathLiteral(requestedPath);
1152
+ if (!normalized) {
1153
+ return null;
1185
1154
  }
1186
- return [path];
1155
+ return allowedPaths.has(normalized) ? normalized : null;
1187
1156
  }
1188
1157
 
1189
1158
  function makeWorkspaceInspectionErrorEvidence(options: {
@@ -1240,24 +1209,7 @@ function mergeEvidence(
1240
1209
  merged.push(item);
1241
1210
  }
1242
1211
 
1243
- return demoteAutoInjectedContextEvidence(merged);
1244
- }
1245
-
1246
- function demoteAutoInjectedContextEvidence(
1247
- evidence: readonly RecallEvidence[],
1248
- ): RecallEvidence[] {
1249
- const regularEvidence: RecallEvidence[] = [];
1250
- const autoInjectedContextEvidence: RecallEvidence[] = [];
1251
-
1252
- for (const item of evidence) {
1253
- if (isAutoInjectedPkbContextEvidence(item)) {
1254
- autoInjectedContextEvidence.push(item);
1255
- } else {
1256
- regularEvidence.push(item);
1257
- }
1258
- }
1259
-
1260
- return [...regularEvidence, ...autoInjectedContextEvidence];
1212
+ return merged;
1261
1213
  }
1262
1214
 
1263
1215
  function toRecallInput(input: NormalizedRecallInput): RecallInput {
@@ -1284,7 +1236,7 @@ function withFallbackEvidence(
1284
1236
  result: DeterministicRecallSearchResult,
1285
1237
  evidence: readonly RecallEvidence[],
1286
1238
  ): DeterministicRecallSearchResult {
1287
- const orderedEvidence = demoteAutoInjectedContextEvidence(evidence);
1239
+ const orderedEvidence = dedupeEvidenceByContent(evidence);
1288
1240
  const evidenceCountBySource = new Map<RecallSource, number>();
1289
1241
  for (const item of orderedEvidence) {
1290
1242
  evidenceCountBySource.set(
@@ -1303,6 +1255,29 @@ function withFallbackEvidence(
1303
1255
  };
1304
1256
  }
1305
1257
 
1258
+ function dedupeEvidenceByContent(
1259
+ evidence: readonly RecallEvidence[],
1260
+ ): RecallEvidence[] {
1261
+ const seenIds = new Set<string>();
1262
+ const seenContent = new Set<string>();
1263
+ const deduped: RecallEvidence[] = [];
1264
+
1265
+ for (const item of evidence) {
1266
+ if (seenIds.has(item.id)) {
1267
+ continue;
1268
+ }
1269
+ const contentKey = `${item.source}\0${item.locator}\0${item.excerpt}`;
1270
+ if (seenContent.has(contentKey)) {
1271
+ continue;
1272
+ }
1273
+ seenIds.add(item.id);
1274
+ seenContent.add(contentKey);
1275
+ deduped.push(item);
1276
+ }
1277
+
1278
+ return deduped;
1279
+ }
1280
+
1306
1281
  function deterministicFallback(
1307
1282
  result: DeterministicRecallSearchResult,
1308
1283
  debug: AgenticRecallDebug,
@@ -2,7 +2,6 @@ import type { RecallDepth, RecallInput, RecallSource } from "./types.js";
2
2
 
3
3
  export const ALL_RECALL_SOURCES: readonly RecallSource[] = [
4
4
  "memory",
5
- "pkb",
6
5
  "conversations",
7
6
  "workspace",
8
7
  ] as const;
@@ -81,9 +80,7 @@ export function normalizeRecallMaxResults(
81
80
  );
82
81
  }
83
82
 
84
- function normalizeRecallDepth(
85
- depth: RecallDepth | undefined,
86
- ): RecallDepth {
83
+ function normalizeRecallDepth(depth: RecallDepth | undefined): RecallDepth {
87
84
  if (depth === undefined) {
88
85
  return DEFAULT_RECALL_DEPTH;
89
86
  }