@vellumai/assistant 0.8.0 → 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 (692) hide show
  1. package/AGENTS.md +11 -0
  2. package/Dockerfile +5 -4
  3. package/README.md +2 -2
  4. package/docker-entrypoint.sh +16 -0
  5. package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
  6. package/eslint-rules/cli-no-daemon-internals.js +283 -0
  7. package/eslint.config.mjs +12 -0
  8. package/knip.json +2 -1
  9. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
  10. package/openapi.yaml +4847 -1698
  11. package/package.json +3 -1
  12. package/scripts/generate-openapi.ts +52 -4
  13. package/scripts/sync-llm-catalog.ts +165 -0
  14. package/scripts/sync-web-search-catalog.ts +107 -0
  15. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
  16. package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
  17. package/src/__tests__/anthropic-provider.test.ts +92 -2
  18. package/src/__tests__/app-control-flow.test.ts +7 -0
  19. package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
  20. package/src/__tests__/avatar-identity-sync.test.ts +87 -0
  21. package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
  22. package/src/__tests__/btw-routes.test.ts +1 -0
  23. package/src/__tests__/call-site-routing-provider.test.ts +172 -45
  24. package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
  25. package/src/__tests__/channel-policy.test.ts +12 -0
  26. package/src/__tests__/checker.test.ts +89 -0
  27. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
  28. package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
  29. package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
  30. package/src/__tests__/config-loader-backfill.test.ts +526 -102
  31. package/src/__tests__/config-loader-corrupt.test.ts +68 -0
  32. package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
  33. package/src/__tests__/config-schema-cmd.test.ts +63 -29
  34. package/src/__tests__/config-schema.test.ts +14 -3
  35. package/src/__tests__/config-set-platform-guard.test.ts +75 -152
  36. package/src/__tests__/config-set-route.test.ts +198 -0
  37. package/src/__tests__/config-watcher.test.ts +6 -0
  38. package/src/__tests__/contacts-tools.test.ts +51 -199
  39. package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
  40. package/src/__tests__/context-search-agent-runner.test.ts +22 -138
  41. package/src/__tests__/context-search-conversations-source.test.ts +42 -16
  42. package/src/__tests__/context-search-fanout.test.ts +20 -157
  43. package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
  44. package/src/__tests__/context-search-types.test.ts +7 -2
  45. package/src/__tests__/context-window-manager.test.ts +389 -1
  46. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  47. package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
  48. package/src/__tests__/conversation-error.test.ts +38 -0
  49. package/src/__tests__/conversation-fork-crud.test.ts +241 -1
  50. package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
  51. package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
  52. package/src/__tests__/conversation-lifecycle.test.ts +124 -0
  53. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
  54. package/src/__tests__/conversation-process-callsite.test.ts +21 -1
  55. package/src/__tests__/conversation-runtime-assembly.test.ts +4 -4
  56. package/src/__tests__/conversation-slash-commands.test.ts +194 -2
  57. package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
  58. package/src/__tests__/credential-security-invariants.test.ts +5 -6
  59. package/src/__tests__/daemon-credential-client.test.ts +56 -1
  60. package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
  61. package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
  62. package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
  63. package/src/__tests__/db-proxy-transaction.test.ts +206 -0
  64. package/src/__tests__/external-plugin-loader.test.ts +458 -0
  65. package/src/__tests__/filing-service.test.ts +23 -3
  66. package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
  67. package/src/__tests__/gateway-only-guard.test.ts +0 -1
  68. package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
  69. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +0 -8
  70. package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
  71. package/src/__tests__/heartbeat-service.test.ts +50 -233
  72. package/src/__tests__/history-repair.test.ts +89 -0
  73. package/src/__tests__/host-app-control-proxy.test.ts +109 -1
  74. package/src/__tests__/host-app-control-routes.test.ts +247 -1
  75. package/src/__tests__/host-browser-proxy.test.ts +416 -20
  76. package/src/__tests__/host-browser-routes.test.ts +325 -33
  77. package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
  78. package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
  79. package/src/__tests__/inference-profile-reaper.test.ts +154 -0
  80. package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
  81. package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
  82. package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
  83. package/src/__tests__/install-skill-routing.test.ts +2 -2
  84. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +15 -0
  85. package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
  86. package/src/__tests__/llm-catalog-parity.test.ts +146 -0
  87. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
  88. package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
  89. package/src/__tests__/llm-resolver.test.ts +46 -0
  90. package/src/__tests__/managed-profile-guard.test.ts +131 -2
  91. package/src/__tests__/mcp-auth-routes.test.ts +1 -0
  92. package/src/__tests__/mcp-cli.test.ts +182 -220
  93. package/src/__tests__/mcp-health-check.test.ts +56 -27
  94. package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
  95. package/src/__tests__/message-complete-display-id.test.ts +175 -0
  96. package/src/__tests__/notification-platform-adapter.test.ts +229 -0
  97. package/src/__tests__/oauth-cli.test.ts +38 -2009
  98. package/src/__tests__/oauth-commands-routes.test.ts +711 -0
  99. package/src/__tests__/oauth-connect-routes.test.ts +174 -11
  100. package/src/__tests__/oauth-providers-routes.test.ts +14 -10
  101. package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
  102. package/src/__tests__/openai-responses-provider.test.ts +17 -0
  103. package/src/__tests__/plugin-bootstrap.test.ts +31 -2
  104. package/src/__tests__/plugin-route-contribution.test.ts +31 -3
  105. package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
  106. package/src/__tests__/plugin-types.test.ts +13 -11
  107. package/src/__tests__/process-message-background-slack.test.ts +46 -0
  108. package/src/__tests__/profile-entry-status.test.ts +43 -0
  109. package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
  110. package/src/__tests__/provider-registry-ollama.test.ts +12 -4
  111. package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
  112. package/src/__tests__/relay-server.test.ts +118 -0
  113. package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
  114. package/src/__tests__/schedule-retry.test.ts +56 -4
  115. package/src/__tests__/schedule-routes.test.ts +104 -0
  116. package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
  117. package/src/__tests__/scheduler-recurrence.test.ts +87 -34
  118. package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
  119. package/src/__tests__/scheduler-wake.test.ts +0 -63
  120. package/src/__tests__/secret-allowlist.test.ts +1 -0
  121. package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
  122. package/src/__tests__/shell-credential-ref.test.ts +95 -3
  123. package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
  124. package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
  125. package/src/__tests__/skill-load-tool.test.ts +2 -4
  126. package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
  127. package/src/__tests__/suggestion-routes.test.ts +3 -3
  128. package/src/__tests__/sync-message-contract.test.ts +63 -0
  129. package/src/__tests__/task-scheduler.test.ts +88 -23
  130. package/src/__tests__/update-bulletin-job.test.ts +96 -193
  131. package/src/__tests__/usage-cli.test.ts +11 -73
  132. package/src/__tests__/user-plugin-loader.test.ts +145 -0
  133. package/src/__tests__/vercel-config.test.ts +168 -0
  134. package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
  135. package/src/__tests__/web-search.test.ts +303 -2
  136. package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
  137. package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
  138. package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
  139. package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
  140. package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
  141. package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
  142. package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
  143. package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
  144. package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
  145. package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
  146. package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
  147. package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
  148. package/src/acp/__tests__/helpers/which-stub.ts +4 -2
  149. package/src/acp/resolve-agent.test.ts +25 -0
  150. package/src/acp/resolve-agent.ts +13 -2
  151. package/src/acp/session-manager.ts +14 -0
  152. package/src/approvals/guardian-request-resolvers.ts +32 -87
  153. package/src/calls/relay-server.ts +35 -0
  154. package/src/calls/relay-setup-router.ts +36 -0
  155. package/src/calls/types.ts +1 -0
  156. package/src/calls/voice-session-bridge.ts +23 -4
  157. package/src/channels/config.ts +14 -1
  158. package/src/channels/types.ts +1 -0
  159. package/src/cli/AGENTS.md +164 -4
  160. package/src/cli/__tests__/notifications.test.ts +54 -0
  161. package/src/cli/commands/__tests__/avatar.test.ts +540 -0
  162. package/src/cli/commands/__tests__/backup.test.ts +236 -776
  163. package/src/cli/commands/__tests__/cache.test.ts +1 -1
  164. package/src/cli/commands/__tests__/changelog.test.ts +593 -0
  165. package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
  166. package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
  167. package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
  168. package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
  169. package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
  170. package/src/cli/commands/__tests__/email-core.test.ts +579 -0
  171. package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
  172. package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
  173. package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
  174. package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
  175. package/src/cli/commands/__tests__/skills.test.ts +563 -0
  176. package/src/cli/commands/__tests__/status.test.ts +249 -0
  177. package/src/cli/commands/__tests__/stt.test.ts +320 -0
  178. package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
  179. package/src/cli/commands/__tests__/tts.test.ts +321 -0
  180. package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
  181. package/src/cli/commands/attachment.ts +8 -3
  182. package/src/cli/commands/audit.ts +95 -64
  183. package/src/cli/commands/auth.ts +61 -58
  184. package/src/cli/commands/avatar.ts +276 -390
  185. package/src/cli/commands/backup.ts +409 -505
  186. package/src/cli/commands/bash.ts +9 -5
  187. package/src/cli/commands/browser.ts +28 -9
  188. package/src/cli/commands/cache.ts +9 -4
  189. package/src/cli/commands/changelog.ts +414 -0
  190. package/src/cli/commands/channel-verification-sessions.ts +238 -317
  191. package/src/cli/commands/clients.ts +8 -3
  192. package/src/cli/commands/completions.ts +9 -9
  193. package/src/cli/commands/config.ts +102 -72
  194. package/src/cli/commands/contacts.ts +575 -696
  195. package/src/cli/commands/conversations-defer.ts +17 -69
  196. package/src/cli/commands/conversations-import.ts +90 -253
  197. package/src/cli/commands/conversations.ts +346 -436
  198. package/src/cli/commands/credential-execution.ts +9 -6
  199. package/src/cli/commands/credentials.ts +456 -736
  200. package/src/cli/commands/domain.ts +128 -206
  201. package/src/cli/commands/email.ts +606 -794
  202. package/src/cli/commands/gateway.ts +8 -1
  203. package/src/cli/commands/image-generation.ts +157 -205
  204. package/src/cli/commands/inference-providers.ts +352 -0
  205. package/src/cli/commands/inference-session.ts +415 -0
  206. package/src/cli/commands/inference.ts +87 -65
  207. package/src/cli/commands/keys.ts +8 -3
  208. package/src/cli/commands/mcp.ts +103 -287
  209. package/src/cli/commands/memory-v2.ts +162 -516
  210. package/src/cli/commands/notifications.ts +33 -7
  211. package/src/cli/commands/oauth/apps.ts +292 -261
  212. package/src/cli/commands/oauth/connect.ts +176 -297
  213. package/src/cli/commands/oauth/disconnect.ts +16 -215
  214. package/src/cli/commands/oauth/index.ts +49 -45
  215. package/src/cli/commands/oauth/mode.ts +43 -199
  216. package/src/cli/commands/oauth/ping.ts +17 -125
  217. package/src/cli/commands/oauth/providers.ts +732 -921
  218. package/src/cli/commands/oauth/request.ts +60 -350
  219. package/src/cli/commands/oauth/shared.ts +11 -121
  220. package/src/cli/commands/oauth/status.ts +31 -121
  221. package/src/cli/commands/oauth/token.ts +13 -55
  222. package/src/cli/commands/pending.ts +19 -10
  223. package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
  224. package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
  225. package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
  226. package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
  227. package/src/cli/commands/platform/connect.ts +16 -80
  228. package/src/cli/commands/platform/disconnect.ts +14 -112
  229. package/src/cli/commands/platform/index.ts +177 -246
  230. package/src/cli/commands/routes.ts +153 -336
  231. package/src/cli/commands/sequence.ts +316 -360
  232. package/src/cli/commands/skills.ts +449 -671
  233. package/src/cli/commands/status.ts +58 -37
  234. package/src/cli/commands/stt.ts +94 -262
  235. package/src/cli/commands/task.ts +14 -40
  236. package/src/cli/commands/trust.ts +8 -3
  237. package/src/cli/commands/tts.ts +162 -167
  238. package/src/cli/commands/ui.ts +35 -42
  239. package/src/cli/commands/usage.ts +188 -126
  240. package/src/cli/commands/watchers.ts +8 -3
  241. package/src/cli/commands/webhooks.ts +99 -193
  242. package/src/cli/lib/__tests__/register-command.test.ts +85 -0
  243. package/src/cli/lib/daemon-credential-client.ts +4 -5
  244. package/src/cli/lib/nested-value.ts +44 -0
  245. package/src/cli/lib/open-browser.ts +36 -0
  246. package/src/cli/lib/register-command.ts +19 -0
  247. package/src/cli/lib/time-ago.ts +34 -0
  248. package/src/cli/program.ts +2 -4
  249. package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
  250. package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
  251. package/src/cli/utils/conversation-id.ts +30 -0
  252. package/src/cli/utils/parse-duration.ts +41 -0
  253. package/src/config/acp-defaults.test.ts +5 -1
  254. package/src/config/acp-defaults.ts +11 -4
  255. package/src/config/bundled-skills/acp/TOOLS.json +2 -2
  256. package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
  257. package/src/config/bundled-skills/contacts/SKILL.md +12 -45
  258. package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
  259. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
  260. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
  261. package/src/config/bundled-tool-registry.ts +0 -2
  262. package/src/config/feature-flag-registry.json +16 -0
  263. package/src/config/llm-resolver.ts +16 -1
  264. package/src/config/loader.ts +76 -14
  265. package/src/config/raw-config-utils.ts +2 -30
  266. package/src/config/schema.ts +4 -0
  267. package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
  268. package/src/config/schemas/call-site-catalog.ts +29 -7
  269. package/src/config/schemas/llm-request-logs.ts +57 -0
  270. package/src/config/schemas/llm.ts +52 -2
  271. package/src/config/schemas/memory-retrospective.ts +48 -0
  272. package/src/config/schemas/memory-v2.ts +32 -1
  273. package/src/config/schemas/memory.ts +4 -0
  274. package/src/config/schemas/services.ts +15 -12
  275. package/src/config/seed-inference-profiles.ts +195 -134
  276. package/src/contacts/contact-store.ts +0 -61
  277. package/src/context/window-manager.ts +191 -5
  278. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +79 -0
  279. package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
  280. package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
  281. package/src/daemon/approval-generators.ts +23 -29
  282. package/src/daemon/config-watcher.ts +2 -0
  283. package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
  284. package/src/daemon/conversation-agent-loop.ts +127 -97
  285. package/src/daemon/conversation-error.ts +21 -0
  286. package/src/daemon/conversation-lifecycle.ts +46 -5
  287. package/src/daemon/conversation-process.ts +36 -19
  288. package/src/daemon/conversation-runtime-assembly.ts +14 -5
  289. package/src/daemon/conversation-slash.ts +175 -23
  290. package/src/daemon/conversation-store.ts +17 -10
  291. package/src/daemon/conversation-surfaces.ts +76 -12
  292. package/src/daemon/conversation-tool-setup.ts +24 -14
  293. package/src/daemon/conversation.ts +48 -9
  294. package/src/daemon/external-plugins-bootstrap.ts +18 -8
  295. package/src/daemon/guardian-action-generators.ts +7 -22
  296. package/src/daemon/handlers/config-model.ts +8 -126
  297. package/src/daemon/handlers/config-slack-channel.ts +10 -7
  298. package/src/daemon/handlers/config-vercel.ts +3 -1
  299. package/src/daemon/handlers/skills.ts +84 -5
  300. package/src/daemon/history-repair.ts +33 -6
  301. package/src/daemon/host-app-control-proxy.ts +44 -19
  302. package/src/daemon/host-bash-proxy.ts +85 -158
  303. package/src/daemon/host-browser-proxy.ts +96 -35
  304. package/src/daemon/host-proxy-base.ts +13 -1
  305. package/src/daemon/host-proxy-preactivation.ts +25 -1
  306. package/src/daemon/identity-helpers.ts +19 -0
  307. package/src/daemon/lifecycle.ts +42 -43
  308. package/src/daemon/meet-host-supervisor.ts +15 -15
  309. package/src/daemon/memory-v2-startup.ts +9 -2
  310. package/src/daemon/message-protocol.ts +6 -0
  311. package/src/daemon/message-types/bookmarks.ts +18 -0
  312. package/src/daemon/message-types/conversations.ts +12 -9
  313. package/src/daemon/message-types/messages.ts +9 -1
  314. package/src/daemon/message-types/sync.ts +60 -0
  315. package/src/daemon/pkb-reminder-builder.test.ts +54 -13
  316. package/src/daemon/pkb-reminder-builder.ts +21 -7
  317. package/src/daemon/process-message.ts +56 -23
  318. package/src/daemon/server.ts +23 -18
  319. package/src/daemon/shutdown-handlers.ts +0 -2
  320. package/src/daemon/tool-setup-types.ts +9 -0
  321. package/src/daemon/tool-side-effects.ts +6 -4
  322. package/src/daemon/wake-target-adapter.ts +11 -0
  323. package/src/export/transcript-formatter.ts +61 -2
  324. package/src/filing/filing-service.ts +40 -53
  325. package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
  326. package/src/heartbeat/heartbeat-run-store.ts +2 -1
  327. package/src/heartbeat/heartbeat-service.ts +148 -127
  328. package/src/home/__tests__/feed-types.test.ts +63 -131
  329. package/src/home/__tests__/feed-writer.test.ts +77 -278
  330. package/src/home/__tests__/post-connect-feed.test.ts +9 -12
  331. package/src/home/feed-types.ts +19 -73
  332. package/src/home/feed-writer.ts +25 -156
  333. package/src/home/post-connect-feed.ts +1 -3
  334. package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
  335. package/src/ipc/__tests__/email-ipc.test.ts +506 -0
  336. package/src/ipc/__tests__/exit-helper.test.ts +104 -0
  337. package/src/ipc/__tests__/streaming-client.test.ts +237 -0
  338. package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
  339. package/src/ipc/assistant-server.ts +55 -6
  340. package/src/ipc/cli-client.ts +370 -50
  341. package/src/ipc/routes/db-proxy-transaction.ts +151 -0
  342. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
  343. package/src/ipc/skill-routes/events.ts +30 -3
  344. package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
  345. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
  346. package/src/live-voice/live-voice-session-manager.ts +11 -4
  347. package/src/live-voice/live-voice-session.ts +14 -6
  348. package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
  349. package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
  350. package/src/memory/__tests__/conversation-types.test.ts +36 -0
  351. package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
  352. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
  353. package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
  354. package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
  355. package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
  356. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
  357. package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
  358. package/src/memory/bookmark-crud.ts +179 -0
  359. package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
  360. package/src/memory/context-search/agent-protocol.ts +5 -1
  361. package/src/memory/context-search/agent-runner.ts +60 -85
  362. package/src/memory/context-search/limits.ts +1 -4
  363. package/src/memory/context-search/search.ts +23 -113
  364. package/src/memory/context-search/sources/conversations.ts +18 -6
  365. package/src/memory/context-search/sources/memory-v2.ts +39 -14
  366. package/src/memory/context-search/sources/memory.ts +7 -0
  367. package/src/memory/context-search/sources/workspace.ts +13 -10
  368. package/src/memory/context-search/types.ts +1 -1
  369. package/src/memory/conversation-bootstrap.ts +11 -0
  370. package/src/memory/conversation-crud.ts +312 -10
  371. package/src/memory/conversation-queries.ts +9 -5
  372. package/src/memory/conversation-title-service.ts +1 -0
  373. package/src/memory/conversation-types.ts +16 -0
  374. package/src/memory/db-init.ts +14 -0
  375. package/src/memory/embedding-backend.ts +2 -1
  376. package/src/memory/embedding-runtime-manager.ts +1 -2
  377. package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
  378. package/src/memory/graph/conversation-graph-memory.ts +76 -5
  379. package/src/memory/graph/extraction.ts +4 -0
  380. package/src/memory/graph/graph-memory-state-store.ts +16 -3
  381. package/src/memory/graph/tool-handlers.ts +17 -7
  382. package/src/memory/graph/tools.ts +44 -5
  383. package/src/memory/indexer.ts +17 -0
  384. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +13 -15
  385. package/src/memory/jobs/embed-concept-page.ts +45 -9
  386. package/src/memory/jobs-store.ts +51 -1
  387. package/src/memory/jobs-worker.ts +52 -3
  388. package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
  389. package/src/memory/llm-request-log-source-local.ts +26 -0
  390. package/src/memory/llm-request-log-source.ts +97 -0
  391. package/src/memory/llm-request-log-store.ts +1 -1
  392. package/src/memory/memory-retrospective-constants.ts +13 -0
  393. package/src/memory/memory-retrospective-enqueue.ts +114 -0
  394. package/src/memory/memory-retrospective-job.ts +351 -0
  395. package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
  396. package/src/memory/memory-retrospective-state.ts +162 -0
  397. package/src/memory/memory-retrospective-trigger-check.ts +91 -0
  398. package/src/memory/memory-v2-activation-log-store.ts +49 -5
  399. package/src/memory/memory-v2-concept-frequency.ts +4 -0
  400. package/src/memory/message-content.ts +38 -1
  401. package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
  402. package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
  403. package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
  404. package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
  405. package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
  406. package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
  407. package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
  408. package/src/memory/migrations/242-message-bookmarks.ts +38 -0
  409. package/src/memory/migrations/243-provider-connections.ts +68 -0
  410. package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
  411. package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
  412. package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
  413. package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
  414. package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
  415. package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
  416. package/src/memory/migrations/index.ts +7 -0
  417. package/src/memory/published-pages-store.ts +16 -0
  418. package/src/memory/schema/bookmarks.ts +38 -0
  419. package/src/memory/schema/conversations.ts +2 -0
  420. package/src/memory/schema/index.ts +2 -0
  421. package/src/memory/schema/inference.ts +29 -0
  422. package/src/memory/schema/memory-core.ts +9 -0
  423. package/src/memory/search/semantic.ts +1 -4
  424. package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
  425. package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
  426. package/src/memory/v2/__tests__/activation.test.ts +11 -4
  427. package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
  428. package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
  429. package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
  430. package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
  431. package/src/memory/v2/__tests__/injection.test.ts +628 -10
  432. package/src/memory/v2/__tests__/migration.test.ts +7 -3
  433. package/src/memory/v2/__tests__/page-index.test.ts +277 -0
  434. package/src/memory/v2/__tests__/page-store.test.ts +14 -1
  435. package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
  436. package/src/memory/v2/__tests__/qdrant.test.ts +72 -0
  437. package/src/memory/v2/__tests__/reranker.test.ts +4 -4
  438. package/src/memory/v2/__tests__/router.test.ts +516 -0
  439. package/src/memory/v2/__tests__/sim.test.ts +45 -1
  440. package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
  441. package/src/memory/v2/__tests__/static-context.test.ts +7 -22
  442. package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
  443. package/src/memory/v2/activation-store.ts +34 -5
  444. package/src/memory/v2/activation.ts +40 -27
  445. package/src/memory/v2/backfill-jobs.ts +17 -84
  446. package/src/memory/v2/consolidation-job.ts +85 -78
  447. package/src/memory/v2/frontmatter-sweep.ts +91 -0
  448. package/src/memory/v2/injection.ts +440 -109
  449. package/src/memory/v2/migration.ts +117 -20
  450. package/src/memory/v2/page-index.ts +191 -0
  451. package/src/memory/v2/page-store.ts +3 -0
  452. package/src/memory/v2/prompts/consolidation.ts +9 -7
  453. package/src/memory/v2/prompts/router.ts +192 -0
  454. package/src/memory/v2/qdrant.ts +100 -87
  455. package/src/memory/v2/reranker.ts +14 -7
  456. package/src/memory/v2/router.ts +322 -0
  457. package/src/memory/v2/sim.ts +25 -12
  458. package/src/memory/v2/skill-store.ts +118 -29
  459. package/src/memory/v2/static-context.ts +16 -9
  460. package/src/memory/v2/sweep-job.ts +122 -96
  461. package/src/memory/v2/types.ts +10 -6
  462. package/src/memory/validation.ts +13 -0
  463. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
  464. package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
  465. package/src/notifications/__tests__/signal-registry.test.ts +17 -0
  466. package/src/notifications/adapters/platform.ts +171 -0
  467. package/src/notifications/conversation-pairing.ts +2 -2
  468. package/src/notifications/copy-composer.ts +15 -0
  469. package/src/notifications/destination-resolver.ts +21 -0
  470. package/src/notifications/emit-signal.ts +28 -1
  471. package/src/notifications/home-feed-side-effect.ts +111 -0
  472. package/src/notifications/signal.ts +5 -0
  473. package/src/permissions/checker.ts +12 -0
  474. package/src/permissions/ipc-risk-types.ts +2 -0
  475. package/src/plugin-api/index.ts +13 -0
  476. package/src/plugin-api/package.json +12 -0
  477. package/src/plugin-api/types.ts +62 -0
  478. package/src/plugins/defaults/injectors.ts +19 -3
  479. package/src/plugins/external-plugin-loader.ts +294 -0
  480. package/src/plugins/types.ts +46 -30
  481. package/src/plugins/user-loader.ts +64 -41
  482. package/src/proactive-artifact/job.test.ts +12 -4
  483. package/src/proactive-artifact/job.ts +4 -0
  484. package/src/proactive-artifact/trigger-state.test.ts +9 -0
  485. package/src/proactive-artifact/trigger-state.ts +4 -0
  486. package/src/prompts/__tests__/system-prompt.test.ts +105 -0
  487. package/src/prompts/system-prompt.ts +22 -1
  488. package/src/prompts/update-bulletin-job.ts +61 -73
  489. package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
  490. package/src/providers/__tests__/inference.test.ts +288 -0
  491. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  492. package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
  493. package/src/providers/__tests__/retry-callsite.test.ts +14 -32
  494. package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
  495. package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
  496. package/src/providers/anthropic/client.ts +95 -26
  497. package/src/providers/call-site-routing.ts +94 -16
  498. package/src/providers/connection-resolution.ts +163 -0
  499. package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
  500. package/src/providers/inference/adapter-factory.ts +173 -0
  501. package/src/providers/inference/auth.ts +112 -0
  502. package/src/providers/inference/backfill.ts +196 -0
  503. package/src/providers/inference/connections.ts +356 -0
  504. package/src/providers/inference/resolve-auth.ts +65 -0
  505. package/src/providers/model-catalog.ts +104 -6
  506. package/src/providers/openai/responses-provider.ts +4 -2
  507. package/src/providers/provider-env-vars.ts +17 -7
  508. package/src/providers/provider-secret-catalog.ts +49 -30
  509. package/src/providers/provider-send-message.ts +41 -20
  510. package/src/providers/registry.ts +143 -159
  511. package/src/providers/retry.ts +18 -10
  512. package/src/providers/search-provider-catalog.ts +121 -0
  513. package/src/runtime/AGENTS.md +18 -5
  514. package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
  515. package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
  516. package/src/runtime/actor-trust-resolver.ts +32 -10
  517. package/src/runtime/agent-wake.ts +35 -6
  518. package/src/runtime/assistant-event-hub.ts +3 -85
  519. package/src/runtime/auth/route-policy.ts +303 -8
  520. package/src/runtime/auth/same-actor.ts +2 -0
  521. package/src/runtime/background-job-runner.ts +339 -0
  522. package/src/runtime/btw-sidechain.ts +1 -0
  523. package/src/runtime/http-router.ts +36 -1
  524. package/src/runtime/http-server.ts +31 -5
  525. package/src/runtime/http-types.ts +2 -0
  526. package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
  527. package/src/runtime/middleware/request-logger.ts +62 -1
  528. package/src/runtime/pre-first-message-gate.ts +83 -0
  529. package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
  530. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
  531. package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
  532. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
  533. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
  534. package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
  535. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
  536. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
  537. package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
  538. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
  539. package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
  540. package/src/runtime/routes/acp-routes.ts +10 -8
  541. package/src/runtime/routes/app-management-routes.ts +228 -3
  542. package/src/runtime/routes/approval-routes.ts +0 -18
  543. package/src/runtime/routes/audit-routes.ts +43 -0
  544. package/src/runtime/routes/auth-routes.ts +72 -0
  545. package/src/runtime/routes/avatar-routes.ts +273 -20
  546. package/src/runtime/routes/backup-routes.ts +406 -2
  547. package/src/runtime/routes/bookmark-routes.ts +154 -0
  548. package/src/runtime/routes/channel-verification-routes.ts +2 -1
  549. package/src/runtime/routes/contact-routes.ts +0 -160
  550. package/src/runtime/routes/conversation-cli-routes.ts +192 -0
  551. package/src/runtime/routes/conversation-management-routes.ts +30 -43
  552. package/src/runtime/routes/conversation-query-routes.ts +334 -86
  553. package/src/runtime/routes/conversation-routes.ts +31 -10
  554. package/src/runtime/routes/conversations-import-routes.ts +229 -0
  555. package/src/runtime/routes/credential-routes.ts +540 -0
  556. package/src/runtime/routes/debug-routes.ts +2 -2
  557. package/src/runtime/routes/document-pdf-renderer.ts +5 -1
  558. package/src/runtime/routes/domain-routes.ts +167 -0
  559. package/src/runtime/routes/email-routes.ts +603 -0
  560. package/src/runtime/routes/errors.ts +2 -2
  561. package/src/runtime/routes/events-routes.ts +192 -0
  562. package/src/runtime/routes/home-feed-routes.ts +6 -78
  563. package/src/runtime/routes/host-app-control-routes.ts +44 -2
  564. package/src/runtime/routes/host-browser-routes.ts +103 -22
  565. package/src/runtime/routes/http-adapter.ts +2 -0
  566. package/src/runtime/routes/identity-routes.ts +5 -0
  567. package/src/runtime/routes/image-generation-routes.ts +99 -0
  568. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
  569. package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
  570. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
  571. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
  572. package/src/runtime/routes/index.ts +36 -0
  573. package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
  574. package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
  575. package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
  576. package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
  577. package/src/runtime/routes/inference-send-routes.ts +115 -0
  578. package/src/runtime/routes/integrations/twilio.ts +1 -0
  579. package/src/runtime/routes/mcp-auth-routes.ts +283 -9
  580. package/src/runtime/routes/memory-v2-routes.ts +13 -398
  581. package/src/runtime/routes/notification-routes.ts +2 -0
  582. package/src/runtime/routes/oauth-apps.ts +112 -7
  583. package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
  584. package/src/runtime/routes/oauth-connect-routes.ts +67 -5
  585. package/src/runtime/routes/oauth-providers.ts +298 -8
  586. package/src/runtime/routes/platform-routes.ts +336 -0
  587. package/src/runtime/routes/playground/inject-failures.ts +2 -1
  588. package/src/runtime/routes/playground/reset-circuit.ts +2 -1
  589. package/src/runtime/routes/playground/state.ts +2 -1
  590. package/src/runtime/routes/publish-routes.ts +221 -0
  591. package/src/runtime/routes/schedule-routes.ts +82 -0
  592. package/src/runtime/routes/sequence-routes.ts +291 -0
  593. package/src/runtime/routes/settings-routes.ts +2 -10
  594. package/src/runtime/routes/skills-routes.ts +31 -1
  595. package/src/runtime/routes/stt-routes.ts +240 -3
  596. package/src/runtime/routes/surface-action-routes.ts +43 -7
  597. package/src/runtime/routes/tts-routes.ts +67 -0
  598. package/src/runtime/routes/types.ts +32 -0
  599. package/src/runtime/routes/user-routes-cli.ts +243 -0
  600. package/src/runtime/routes/webhook-routes.ts +165 -0
  601. package/src/runtime/sync/resource-sync-events.ts +25 -0
  602. package/src/runtime/sync/sync-publisher.test.ts +105 -0
  603. package/src/runtime/sync/sync-publisher.ts +21 -0
  604. package/src/schedule/scheduler.ts +200 -123
  605. package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
  606. package/src/security/secret-patterns.ts +3 -0
  607. package/src/sequence/engine.ts +38 -40
  608. package/src/subagent/manager.ts +20 -15
  609. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
  610. package/src/tools/browser/browser-execution.ts +15 -4
  611. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
  612. package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
  613. package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
  614. package/src/tools/browser/cdp-client/factory.ts +66 -5
  615. package/src/tools/browser/runtime-check.ts +77 -0
  616. package/src/tools/memory/register.test.ts +3 -3
  617. package/src/tools/memory/register.ts +9 -1
  618. package/src/tools/network/__tests__/web-search.test.ts +156 -0
  619. package/src/tools/network/web-search.ts +280 -37
  620. package/src/tools/permission-checker.ts +13 -5
  621. package/src/tools/subagent/spawn.ts +3 -3
  622. package/src/tools/terminal/shell.ts +44 -0
  623. package/src/usage/attribution.ts +3 -2
  624. package/src/util/pricing.ts +86 -160
  625. package/src/watcher/__tests__/engine.test.ts +301 -0
  626. package/src/watcher/constants.ts +7 -0
  627. package/src/watcher/engine.ts +90 -90
  628. package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
  629. package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
  630. package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
  631. package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
  632. package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
  633. package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
  634. package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
  635. package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
  636. package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
  637. package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
  638. package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
  639. package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
  640. package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
  641. package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
  642. package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
  643. package/src/workspace/migrations/registry.ts +22 -0
  644. package/src/workspace/migrations/runner.ts +13 -2
  645. package/src/workspace/migrations/types.ts +13 -3
  646. package/src/workspace/provider-commit-message-generator.ts +3 -2
  647. package/src/__tests__/context-search-pkb-source.test.ts +0 -498
  648. package/src/__tests__/credentials-cli.test.ts +0 -1225
  649. package/src/__tests__/memory-admin-recall.test.ts +0 -213
  650. package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
  651. package/src/cli/commands/__tests__/email-download.test.ts +0 -260
  652. package/src/cli/commands/__tests__/email-list.test.ts +0 -216
  653. package/src/cli/commands/__tests__/email-register.test.ts +0 -186
  654. package/src/cli/commands/__tests__/email-send.test.ts +0 -416
  655. package/src/cli/commands/__tests__/email-status.test.ts +0 -185
  656. package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
  657. package/src/cli/commands/__tests__/routes.test.ts +0 -562
  658. package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
  659. package/src/cli/commands/autonomy.ts +0 -365
  660. package/src/cli/commands/memory.ts +0 -424
  661. package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
  662. package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
  663. package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
  664. package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
  665. package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
  666. package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
  667. package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
  668. package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
  669. package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
  670. package/src/cli/lib/daemon-avatar-client.ts +0 -37
  671. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
  672. package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
  673. package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
  674. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
  675. package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
  676. package/src/home/__tests__/emit-feed-event.test.ts +0 -169
  677. package/src/home/__tests__/feed-population-integration.test.ts +0 -312
  678. package/src/home/__tests__/feed-scheduler.test.ts +0 -222
  679. package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
  680. package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
  681. package/src/home/__tests__/rollup-producer.test.ts +0 -507
  682. package/src/home/assistant-feed-authoring.ts +0 -135
  683. package/src/home/emit-feed-event.ts +0 -169
  684. package/src/home/feed-scheduler.ts +0 -281
  685. package/src/home/platform-gmail-digest.ts +0 -163
  686. package/src/home/rewrite-command-preview.ts +0 -66
  687. package/src/home/rewrite-feed-title.ts +0 -58
  688. package/src/home/rollup-producer.ts +0 -426
  689. package/src/memory/admin.ts +0 -326
  690. package/src/memory/context-search/sources/pkb.ts +0 -476
  691. package/src/memory/graph/compaction.ts +0 -299
  692. /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
@@ -449,6 +449,10 @@ export const ROUTES: RouteDefinition[] = [
449
449
  "Returns runtime health including version, disk, memory, CPU, and migration status.",
450
450
  tags: ["system"],
451
451
  responseBody: detailedHealthSchema,
452
+ // Clients (notably the macOS app) poll this every few seconds; the
453
+ // first handful of 200s confirm the route works and every line after
454
+ // is just noise. Non-2xx still logs.
455
+ logging: { silenceSuccessAfter: 5 },
452
456
  },
453
457
  {
454
458
  operationId: "healthz",
@@ -461,6 +465,7 @@ export const ROUTES: RouteDefinition[] = [
461
465
  "Alias for /v1/health. Returns runtime health including version, disk, memory, CPU, and migration status.",
462
466
  tags: ["system"],
463
467
  responseBody: detailedHealthSchema,
468
+ logging: { silenceSuccessAfter: 5 },
464
469
  },
465
470
  {
466
471
  operationId: "identity",
@@ -0,0 +1,99 @@
1
+ import { getConfig } from "../../config/loader.js";
2
+ import { resolveImageGenCredentials } from "../../media/image-credentials.js";
3
+ import {
4
+ generateImage,
5
+ mapImageGenError,
6
+ providerForModel,
7
+ } from "../../media/image-service.js";
8
+ import { BadRequestError, InternalError, UnprocessableEntityError } from "./errors.js";
9
+ import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
10
+
11
+ // ---------------------------------------------------------------------------
12
+ // Handler
13
+ // ---------------------------------------------------------------------------
14
+
15
+ async function handleImageGenerationGenerate(
16
+ args: RouteHandlerArgs,
17
+ ): Promise<unknown> {
18
+ const { prompt, mode, sourceImages, model, variants } = args.body ?? {};
19
+
20
+ // Validate prompt
21
+ if (typeof prompt !== "string" || !prompt.trim()) {
22
+ throw new BadRequestError("prompt must be a non-empty string");
23
+ }
24
+
25
+ // Validate / default mode
26
+ const resolvedMode: "generate" | "edit" =
27
+ mode === "edit" ? "edit" : "generate";
28
+
29
+ // Validate edit mode requirements
30
+ if (
31
+ resolvedMode === "edit" &&
32
+ (!sourceImages ||
33
+ !Array.isArray(sourceImages) ||
34
+ (sourceImages as unknown[]).length === 0)
35
+ ) {
36
+ throw new BadRequestError("Edit mode requires at least one source image");
37
+ }
38
+
39
+ // Resolve config
40
+ const config = getConfig();
41
+ const svc = config.services["image-generation"];
42
+
43
+ // Derive provider from explicit model override when supplied
44
+ const provider = providerForModel(model, svc.provider);
45
+
46
+ // Resolve credentials
47
+ const { credentials, errorHint } = await resolveImageGenCredentials({
48
+ provider,
49
+ mode: svc.mode,
50
+ });
51
+
52
+ if (!credentials) {
53
+ throw new UnprocessableEntityError(
54
+ errorHint ?? "No credentials available for image generation",
55
+ );
56
+ }
57
+
58
+ // Clamp variants to 1-4
59
+ const clampedVariants = Math.max(1, Math.min(Number(variants) || 1, 4));
60
+
61
+ // Generate image
62
+ try {
63
+ const result = await generateImage(provider, credentials, {
64
+ prompt,
65
+ mode: resolvedMode,
66
+ sourceImages: sourceImages as
67
+ | Array<{ mimeType: string; dataBase64: string }>
68
+ | undefined,
69
+ model: (model as string | undefined) ?? svc.model,
70
+ variants: clampedVariants,
71
+ });
72
+
73
+ return {
74
+ images: result.images,
75
+ text: result.text,
76
+ resolvedModel: result.resolvedModel,
77
+ };
78
+ } catch (error) {
79
+ const errorMessage = mapImageGenError(provider, error);
80
+ throw new InternalError(errorMessage);
81
+ }
82
+ }
83
+
84
+ // ---------------------------------------------------------------------------
85
+ // Route definitions
86
+ // ---------------------------------------------------------------------------
87
+
88
+ export const ROUTES: RouteDefinition[] = [
89
+ {
90
+ operationId: "image_generation_generate",
91
+ endpoint: "image-generation/generate",
92
+ method: "POST",
93
+ summary: "Generate or edit images using AI",
94
+ description:
95
+ "Calls the configured image-generation provider (Gemini or OpenAI) to produce one or more images.",
96
+ tags: ["image-generation"],
97
+ handler: handleImageGenerationGenerate,
98
+ },
99
+ ];
@@ -1,4 +1,9 @@
1
- import { describe, expect, mock, test } from "bun:test";
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
+
3
+ const deliveredChannelReplies: Array<{
4
+ callbackUrl: string;
5
+ payload: Record<string, unknown>;
6
+ }> = [];
2
7
 
3
8
  mock.module("../../../util/logger.js", () => ({
4
9
  getLogger: () =>
@@ -20,6 +25,19 @@ mock.module("../../../memory/delivery-status.js", () => ({
20
25
  recordProcessingFailure: () => {},
21
26
  }));
22
27
 
28
+ mock.module("../../gateway-client.js", () => ({
29
+ deliverChannelReply: async (
30
+ callbackUrl: string,
31
+ payload: Record<string, unknown>,
32
+ ) => {
33
+ deliveredChannelReplies.push({ callbackUrl, payload });
34
+ return { ok: true };
35
+ },
36
+ }));
37
+
38
+ mock.module("../channel-delivery-routes.js", () => ({
39
+ deliverReplyViaCallback: async () => {},
40
+ }));
23
41
 
24
42
  import type { TrustContext } from "../../../daemon/trust-context.js";
25
43
  import {
@@ -31,6 +49,7 @@ import type { MessageProcessor } from "../../http-types.js";
31
49
  import {
32
50
  isBoundGuardianActor,
33
51
  processChannelMessageInBackground,
52
+ shouldStartSlackThinkingStatusForText,
34
53
  } from "./background-dispatch.js";
35
54
 
36
55
  describe("isBoundGuardianActor", () => {
@@ -152,3 +171,120 @@ describe("processChannelMessageInBackground — slack thread mapping", () => {
152
171
  clearThreadTs(conversationId);
153
172
  });
154
173
  });
174
+
175
+ describe("Slack thinking status timing", () => {
176
+ const trustCtx: TrustContext = {
177
+ trustClass: "guardian",
178
+ guardianExternalUserId: "guardian-1",
179
+ requesterExternalUserId: "guardian-1",
180
+ } as unknown as TrustContext;
181
+
182
+ const flush = (): Promise<void> =>
183
+ new Promise((resolve) => setTimeout(resolve, 10));
184
+
185
+ beforeEach(() => {
186
+ deliveredChannelReplies.length = 0;
187
+ });
188
+
189
+ test("recognizes only deliverable text as a Slack thinking-status trigger", () => {
190
+ expect(shouldStartSlackThinkingStatusForText("")).toBe(false);
191
+ expect(shouldStartSlackThinkingStatusForText(" ")).toBe(false);
192
+ expect(shouldStartSlackThinkingStatusForText("<")).toBe(false);
193
+ expect(shouldStartSlackThinkingStatusForText("<no_response")).toBe(false);
194
+ expect(shouldStartSlackThinkingStatusForText("<no_response/>")).toBe(false);
195
+ expect(shouldStartSlackThinkingStatusForText(" <no_response /> ")).toBe(
196
+ false,
197
+ );
198
+ expect(shouldStartSlackThinkingStatusForText("Real response.")).toBe(true);
199
+ expect(
200
+ shouldStartSlackThinkingStatusForText("<no_response/>\nReal response."),
201
+ ).toBe(true);
202
+ });
203
+
204
+ test("does not set Slack thinking status for no_response text deltas", async () => {
205
+ const conversationId = "conv-no-response-status";
206
+ const channelId = "C-NO-RESPONSE";
207
+ const threadTs = "1700000000.000003";
208
+
209
+ const processMessage: MessageProcessor = async (
210
+ _conversationId,
211
+ _content,
212
+ _attachmentIds,
213
+ options,
214
+ ) => {
215
+ options?.onEvent?.({
216
+ type: "assistant_text_delta",
217
+ text: "<no_response/>",
218
+ conversationId,
219
+ });
220
+ return { messageId: "user-msg-no-response" };
221
+ };
222
+
223
+ processChannelMessageInBackground({
224
+ processMessage,
225
+ conversationId,
226
+ eventId: "evt-no-response-status",
227
+ content: "ambient channel chatter",
228
+ sourceChannel: "slack",
229
+ sourceInterface: "slack",
230
+ externalChatId: channelId,
231
+ trustCtx,
232
+ metadataHints: [],
233
+ replyCallbackUrl: `https://example.test/deliver/slack?channel=${channelId}&threadTs=${threadTs}`,
234
+ });
235
+
236
+ await flush();
237
+
238
+ expect(deliveredChannelReplies).toEqual([]);
239
+ });
240
+
241
+ test("sets and clears Slack thinking status after real assistant text starts", async () => {
242
+ const conversationId = "conv-real-response-status";
243
+ const channelId = "C-REAL-RESPONSE";
244
+ const threadTs = "1700000000.000004";
245
+
246
+ const processMessage: MessageProcessor = async (
247
+ _conversationId,
248
+ _content,
249
+ _attachmentIds,
250
+ options,
251
+ ) => {
252
+ options?.onEvent?.({
253
+ type: "assistant_text_delta",
254
+ text: "<",
255
+ conversationId,
256
+ });
257
+ expect(deliveredChannelReplies).toEqual([]);
258
+
259
+ options?.onEvent?.({
260
+ type: "assistant_text_delta",
261
+ text: "b>Working on it.",
262
+ conversationId,
263
+ });
264
+ return { messageId: "user-msg-real-response" };
265
+ };
266
+
267
+ processChannelMessageInBackground({
268
+ processMessage,
269
+ conversationId,
270
+ eventId: "evt-real-response-status",
271
+ content: "please respond",
272
+ sourceChannel: "slack",
273
+ sourceInterface: "slack",
274
+ externalChatId: channelId,
275
+ trustCtx,
276
+ metadataHints: [],
277
+ replyCallbackUrl: `https://example.test/deliver/slack?channel=${channelId}&threadTs=${threadTs}`,
278
+ });
279
+
280
+ await flush();
281
+
282
+ const statuses = deliveredChannelReplies.map((entry) => {
283
+ const status = entry.payload.assistantThreadStatus as
284
+ | { status?: string }
285
+ | undefined;
286
+ return status?.status;
287
+ });
288
+ expect(statuses).toEqual(["is thinking...", ""]);
289
+ });
290
+ });
@@ -9,6 +9,7 @@
9
9
  */
10
10
  import type { ChannelId, InterfaceId } from "../../../channels/types.js";
11
11
  import { findGuardianForChannel } from "../../../contacts/contact-store.js";
12
+ import type { ServerMessage } from "../../../daemon/message-protocol.js";
12
13
  import type { TrustContext } from "../../../daemon/trust-context.js";
13
14
  import { updateDeliveredSegmentCount } from "../../../memory/delivery-channels.js";
14
15
  import { linkMessage } from "../../../memory/delivery-crud.js";
@@ -135,13 +136,12 @@ export function processChannelMessageInBackground(
135
136
  )
136
137
  : undefined;
137
138
 
138
- // Set Slack Assistants API "is thinking..." status indicator
139
- const clearSlackThinkingStatus = shouldEmitSlackReaction(
139
+ const slackThinkingStatus = createSlackThinkingStatusController({
140
140
  sourceChannel,
141
141
  replyCallbackUrl,
142
- )
143
- ? setSlackThinkingStatus(replyCallbackUrl!, externalChatId, assistantId)
144
- : undefined;
142
+ chatId: externalChatId,
143
+ assistantId,
144
+ });
145
145
  const stopApprovalWatcher = replyCallbackUrl
146
146
  ? startPendingApprovalPromptWatcher({
147
147
  conversationId,
@@ -226,6 +226,12 @@ export function processChannelMessageInBackground(
226
226
  ...(cmdIntent ? { commandIntent: cmdIntent } : {}),
227
227
  ...(slackRuntimeContextNotice ? { slackRuntimeContextNotice } : {}),
228
228
  ...(slackInbound ? { slackInbound } : {}),
229
+ ...(slackThinkingStatus
230
+ ? {
231
+ onEvent: (msg: ServerMessage) =>
232
+ slackThinkingStatus.observeEvent(msg),
233
+ }
234
+ : {}),
229
235
  },
230
236
  sourceChannel,
231
237
  sourceInterface,
@@ -274,7 +280,7 @@ export function processChannelMessageInBackground(
274
280
  recordProcessingFailure(eventId, err);
275
281
  } finally {
276
282
  stopTypingHeartbeat?.();
277
- clearSlackThinkingStatus?.();
283
+ slackThinkingStatus?.stop();
278
284
  stopApprovalWatcher?.();
279
285
  stopTcApprovalNotifier?.();
280
286
  }
@@ -341,7 +347,36 @@ function startTelegramTypingHeartbeat(
341
347
  // Slack Assistants API thinking status indicator
342
348
  // ---------------------------------------------------------------------------
343
349
 
344
- function shouldEmitSlackReaction(
350
+ type SlackThinkingStatusController = {
351
+ observeEvent: (msg: ServerMessage) => void;
352
+ stop: () => void;
353
+ };
354
+
355
+ const NO_RESPONSE_RE = /^\s*<no_response\s*\/?>\s*$/i;
356
+ const NO_RESPONSE_INLINE_RE = /<no_response\s*\/?>/gi;
357
+ const NO_RESPONSE_SENTINEL_FORMS = [
358
+ "<no_response/>",
359
+ "<no_response />",
360
+ "<no_response>",
361
+ ] as const;
362
+
363
+ function isPotentialNoResponsePrefix(text: string): boolean {
364
+ const lower = text.toLowerCase();
365
+ return NO_RESPONSE_SENTINEL_FORMS.some((sentinel) =>
366
+ sentinel.startsWith(lower),
367
+ );
368
+ }
369
+
370
+ export function shouldStartSlackThinkingStatusForText(text: string): boolean {
371
+ const trimmed = text.trim();
372
+ if (trimmed.length === 0) return false;
373
+ if (NO_RESPONSE_RE.test(trimmed)) return false;
374
+ if (isPotentialNoResponsePrefix(trimmed)) return false;
375
+
376
+ return trimmed.replace(NO_RESPONSE_INLINE_RE, "").trim().length > 0;
377
+ }
378
+
379
+ function shouldEmitSlackThinkingStatus(
345
380
  sourceChannel: ChannelId,
346
381
  replyCallbackUrl?: string,
347
382
  ): boolean {
@@ -353,6 +388,51 @@ function shouldEmitSlackReaction(
353
388
  }
354
389
  }
355
390
 
391
+ function createSlackThinkingStatusController(params: {
392
+ sourceChannel: ChannelId;
393
+ replyCallbackUrl?: string;
394
+ chatId: string;
395
+ assistantId?: string;
396
+ }): SlackThinkingStatusController | undefined {
397
+ const { sourceChannel, replyCallbackUrl, chatId, assistantId } = params;
398
+ if (
399
+ !replyCallbackUrl ||
400
+ !shouldEmitSlackThinkingStatus(sourceChannel, replyCallbackUrl)
401
+ ) {
402
+ return undefined;
403
+ }
404
+ const callbackUrl = replyCallbackUrl;
405
+
406
+ let stopped = false;
407
+ let clearSlackThinkingStatus: (() => void) | undefined;
408
+ let observedAssistantText = "";
409
+
410
+ const start = (): void => {
411
+ if (stopped || clearSlackThinkingStatus) return;
412
+ clearSlackThinkingStatus = setSlackThinkingStatus(
413
+ callbackUrl,
414
+ chatId,
415
+ assistantId,
416
+ );
417
+ };
418
+
419
+ return {
420
+ observeEvent(msg) {
421
+ if (stopped || clearSlackThinkingStatus) return;
422
+ if (msg.type !== "assistant_text_delta") return;
423
+
424
+ observedAssistantText += msg.text;
425
+ if (shouldStartSlackThinkingStatusForText(observedAssistantText)) {
426
+ start();
427
+ }
428
+ },
429
+ stop() {
430
+ stopped = true;
431
+ clearSlackThinkingStatus?.();
432
+ },
433
+ };
434
+ }
435
+
356
436
  const SLACK_THINKING_MAX_DURATION_MS = 120_000;
357
437
 
358
438
  /**
@@ -0,0 +1,156 @@
1
+ import { beforeEach, describe, expect, mock, test } from "bun:test";
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // Mocks — must be set up before importing the module under test
5
+ // ---------------------------------------------------------------------------
6
+
7
+ let mockDeliveryScopedRequests: { id: string }[] = [];
8
+ let mockIdentityRequests: { id: string }[] = [];
9
+ let routeGuardianReplyCalls: unknown[] = [];
10
+ let deliverChannelReplyCalls: unknown[][] = [];
11
+
12
+ mock.module("../../../memory/canonical-guardian-store.js", () => ({
13
+ listPendingCanonicalGuardianRequestsByDestinationChat: () =>
14
+ mockDeliveryScopedRequests,
15
+ listCanonicalGuardianRequests: () => mockIdentityRequests,
16
+ }));
17
+
18
+ mock.module("../../../util/logger.js", () => ({
19
+ getLogger: () => ({
20
+ debug: () => {},
21
+ info: () => {},
22
+ warn: () => {},
23
+ error: () => {},
24
+ }),
25
+ }));
26
+
27
+ mock.module("../../gateway-client.js", () => ({
28
+ deliverChannelReply: (url: unknown, payload: unknown, token: unknown) => {
29
+ deliverChannelReplyCalls.push([url, payload, token]);
30
+ return Promise.resolve({ ok: true });
31
+ },
32
+ }));
33
+
34
+ mock.module("../../guardian-reply-router.js", () => ({
35
+ routeGuardianReply: (ctx: unknown) => {
36
+ routeGuardianReplyCalls.push(ctx);
37
+ return Promise.resolve({
38
+ consumed: false,
39
+ decisionApplied: false,
40
+ type: "not_consumed",
41
+ });
42
+ },
43
+ }));
44
+
45
+ // Import after mocks are installed
46
+ const { handleGuardianReplyIntercept } =
47
+ await import("./guardian-reply-intercept.js");
48
+
49
+ // ---------------------------------------------------------------------------
50
+ // Helpers
51
+ // ---------------------------------------------------------------------------
52
+
53
+ function makeParams(
54
+ overrides: Partial<Parameters<typeof handleGuardianReplyIntercept>[0]> = {},
55
+ ) {
56
+ return {
57
+ isDuplicate: false,
58
+ trimmedContent: "hello",
59
+ hasCallbackData: false,
60
+ callbackData: undefined,
61
+ rawSenderId: "user-42",
62
+ canonicalSenderId: "user-42",
63
+ canonicalAssistantId: "self",
64
+ sourceChannel: "slack" as const,
65
+ conversationExternalId: "chat-123",
66
+ conversationId: "conv-abc",
67
+ eventId: "evt-1",
68
+ replyCallbackUrl: "https://gateway/reply",
69
+ trustClass: "guardian",
70
+ guardianPrincipalId: "principal-1",
71
+ approvalConversationGenerator: undefined,
72
+ ...overrides,
73
+ };
74
+ }
75
+
76
+ // ---------------------------------------------------------------------------
77
+ // Tests
78
+ // ---------------------------------------------------------------------------
79
+
80
+ describe("handleGuardianReplyIntercept", () => {
81
+ beforeEach(() => {
82
+ mockDeliveryScopedRequests = [];
83
+ mockIdentityRequests = [];
84
+ routeGuardianReplyCalls = [];
85
+ deliverChannelReplyCalls = [];
86
+ });
87
+
88
+ test("passes empty pendingRequestIds when Slack guardian sends message in non-delivery chat", async () => {
89
+ // No delivery-scoped requests for this chat
90
+ mockDeliveryScopedRequests = [];
91
+ // Identity-based lookup would find a pending request in a different chat
92
+ mockIdentityRequests = [{ id: "identity-req" }];
93
+
94
+ await handleGuardianReplyIntercept(makeParams({ sourceChannel: "slack" }));
95
+
96
+ expect(routeGuardianReplyCalls).toHaveLength(1);
97
+ const ctx = routeGuardianReplyCalls[0] as Record<string, unknown>;
98
+ // Must be [] (empty array), NOT undefined — blocks identity fallback
99
+ expect(ctx.pendingRequestIds).toEqual([]);
100
+ });
101
+
102
+ test("preserves identity fallback for non-Slack channels when no deliveries exist", async () => {
103
+ // No delivery-scoped requests for this chat
104
+ mockDeliveryScopedRequests = [];
105
+ mockIdentityRequests = [{ id: "identity-req" }];
106
+
107
+ await handleGuardianReplyIntercept(
108
+ makeParams({ sourceChannel: "telegram" }),
109
+ );
110
+
111
+ expect(routeGuardianReplyCalls).toHaveLength(1);
112
+ const ctx = routeGuardianReplyCalls[0] as Record<string, unknown>;
113
+ // Must be undefined — identity-based fallback stays active
114
+ expect(ctx.pendingRequestIds).toBeUndefined();
115
+ });
116
+
117
+ test("includes identity-unioned pendingRequestIds when Slack guardian is in delivery chat", async () => {
118
+ mockDeliveryScopedRequests = [{ id: "delivered-req" }];
119
+ mockIdentityRequests = [
120
+ { id: "delivered-req" },
121
+ { id: "identity-only-req" },
122
+ ];
123
+
124
+ await handleGuardianReplyIntercept(makeParams({ sourceChannel: "slack" }));
125
+
126
+ expect(routeGuardianReplyCalls).toHaveLength(1);
127
+ const ctx = routeGuardianReplyCalls[0] as Record<string, unknown>;
128
+ const ids = ctx.pendingRequestIds as string[];
129
+ expect(ids).toContain("delivered-req");
130
+ expect(ids).toContain("identity-only-req");
131
+ });
132
+
133
+ test("skips intercept for non-guardian trust class", async () => {
134
+ const result = await handleGuardianReplyIntercept(
135
+ makeParams({ trustClass: "unknown" }),
136
+ );
137
+
138
+ expect(routeGuardianReplyCalls).toHaveLength(0);
139
+ expect(result).toEqual({
140
+ response: null,
141
+ skipApprovalInterception: false,
142
+ });
143
+ });
144
+
145
+ test("skips intercept when replyCallbackUrl is missing", async () => {
146
+ const result = await handleGuardianReplyIntercept(
147
+ makeParams({ replyCallbackUrl: undefined }),
148
+ );
149
+
150
+ expect(routeGuardianReplyCalls).toHaveLength(0);
151
+ expect(result).toEqual({
152
+ response: null,
153
+ skipApprovalInterception: false,
154
+ });
155
+ });
156
+ });
@@ -101,8 +101,22 @@ export async function handleGuardianReplyIntercept(
101
101
  // When delivery-scoped matches exist, union them with any identity-
102
102
  // based pending requests so that requests without delivery rows (e.g.
103
103
  // tool_approval requests created inline) are not silently excluded.
104
- // Pass undefined (not []) when there are zero combined results so the
105
- // router's own identity-based fallback stays active.
104
+ //
105
+ // On Slack, when no delivery-scoped results exist for the current
106
+ // chat, pass [] (empty array) instead of undefined. This prevents the
107
+ // router's identity-based fallback from intercepting unrelated
108
+ // messages in other channels/threads — a cross-chat hijacking vector
109
+ // unique to Slack where a single guardian is active in many threaded
110
+ // contexts. Explicit callbacks (apr:<id>:<action>) and request codes
111
+ // still work cross-chat because they carry specific request
112
+ // identifiers and bypass the pendingRequests list.
113
+ //
114
+ // Non-Slack channels (Telegram, WhatsApp) keep undefined so the
115
+ // identity-based fallback stays active. On those channels, delivery
116
+ // rows are created asynchronously (fire-and-forget .then()) so the
117
+ // guardian can reply before the row is persisted. Cross-chat
118
+ // contamination is unlikely there because each chat is a distinct
119
+ // conversation with no thread concept.
106
120
  const deliveryScopedPendingRequests =
107
121
  listPendingCanonicalGuardianRequestsByDestinationChat(
108
122
  sourceChannel,
@@ -121,6 +135,10 @@ export async function handleGuardianReplyIntercept(
121
135
  deliveryIds.add(r.id);
122
136
  }
123
137
  pendingRequestIds = [...deliveryIds];
138
+ } else if (sourceChannel === "slack") {
139
+ // Block identity-based fallback on Slack to prevent cross-chat
140
+ // NL/free-text interception. See comment above for rationale.
141
+ pendingRequestIds = [];
124
142
  }
125
143
 
126
144
  const routerResult = await routeGuardianReply({
@@ -168,13 +186,13 @@ export async function handleGuardianReplyIntercept(
168
186
  }
169
187
 
170
188
  return {
171
- response: ({
189
+ response: {
172
190
  accepted: true,
173
191
  duplicate: false,
174
192
  eventId,
175
193
  canonicalRouter: routerResult.type,
176
194
  requestId: routerResult.requestId,
177
- }),
195
+ },
178
196
  skipApprovalInterception: false,
179
197
  };
180
198
  }