@vellumai/assistant 0.10.12 → 0.11.0-staging.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 (776) hide show
  1. package/AGENTS.md +1 -1
  2. package/ARCHITECTURE.md +4 -5
  3. package/README.md +1 -1
  4. package/docs/architecture/memory.md +60 -23
  5. package/docs/error-handling.md +3 -3
  6. package/docs/guardian-request-flow.md +112 -0
  7. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
  8. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
  9. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
  10. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
  11. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
  12. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts +28 -0
  13. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/app.d.ts.map +1 -1
  14. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts +2 -2
  15. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.d.ts.map +1 -1
  16. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/index.js.map +1 -1
  17. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts +2 -0
  18. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/dist/events/message.d.ts.map +1 -1
  19. package/node_modules/@vellumai/gateway-client/node_modules/@slack/types/package.json +1 -1
  20. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
  21. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
  22. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
  23. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
  24. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
  25. package/node_modules/@vellumai/gateway-client/package.json +1 -1
  26. package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +6 -0
  27. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +34 -0
  28. package/node_modules/@vellumai/service-contracts/package.json +1 -0
  29. package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +9 -1
  30. package/node_modules/@vellumai/service-contracts/src/__tests__/secret-detection.test.ts +449 -0
  31. package/node_modules/@vellumai/service-contracts/src/channels.ts +1 -0
  32. package/node_modules/@vellumai/service-contracts/src/secret-detection.ts +468 -0
  33. package/openapi.yaml +246 -10
  34. package/package.json +2 -2
  35. package/src/__tests__/acp-session.test.ts +3 -3
  36. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +3 -0
  37. package/src/__tests__/anthropic-provider.test.ts +40 -0
  38. package/src/__tests__/approval-cascade.test.ts +5 -5
  39. package/src/__tests__/approval-routes-http.test.ts +3 -3
  40. package/src/__tests__/ask-question-resolver.test.ts +207 -0
  41. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +16 -16
  42. package/src/__tests__/assistant-event-hub-targeted.test.ts +13 -11
  43. package/src/__tests__/assistant-event-hub.test.ts +13 -11
  44. package/src/__tests__/assistant-event.test.ts +12 -9
  45. package/src/__tests__/assistant-feature-flag-guard.test.ts +3 -3
  46. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +1 -1
  47. package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -58
  48. package/src/__tests__/assistant-stream-state.test.ts +17 -7
  49. package/src/__tests__/avatar-identity-sync.test.ts +3 -3
  50. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
  51. package/src/__tests__/call-conversation-messages.test.ts +134 -18
  52. package/src/__tests__/call-start-guardian-guard.test.ts +27 -0
  53. package/src/__tests__/channel-approvals.test.ts +0 -27
  54. package/src/__tests__/channel-guardian.test.ts +85 -512
  55. package/src/__tests__/channel-readiness-slack-remote.test.ts +151 -3
  56. package/src/__tests__/channel-retry-sweep.test.ts +88 -1
  57. package/src/__tests__/channel-setup-panel-ack.test.ts +12 -9
  58. package/src/__tests__/chat-reveal-guard-priming.test.ts +31 -34
  59. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +2 -2
  60. package/src/__tests__/compaction-events.test.ts +8 -8
  61. package/src/__tests__/config-loader-platform-defaults.test.ts +54 -28
  62. package/src/__tests__/config-model-image-provider.test.ts +20 -0
  63. package/src/__tests__/config-schema-memory-substrate.test.ts +306 -0
  64. package/src/__tests__/config-schema.test.ts +14 -2
  65. package/src/__tests__/config-set-platform-guard.test.ts +11 -12
  66. package/src/__tests__/config-sounds-sync.test.ts +4 -4
  67. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +5 -0
  68. package/src/__tests__/context-search-memory-source.test.ts +1 -1
  69. package/src/__tests__/context-search-memory-v2-source.test.ts +6 -6
  70. package/src/__tests__/context-token-estimator.test.ts +54 -1
  71. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +12 -3
  72. package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +13 -4
  73. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +4 -4
  74. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -1
  75. package/src/__tests__/conversation-agent-loop-overflow.test.ts +22 -13
  76. package/src/__tests__/conversation-agent-loop.test.ts +39 -30
  77. package/src/__tests__/conversation-confirmation-signals.test.ts +14 -14
  78. package/src/__tests__/conversation-evictor.test.ts +49 -0
  79. package/src/__tests__/conversation-fork-crud.test.ts +1 -1
  80. package/src/__tests__/conversation-history-web-search.test.ts +1 -1
  81. package/src/__tests__/conversation-key-store-disk-view.test.ts +5 -5
  82. package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +5 -5
  83. package/src/__tests__/conversation-message-sync-tags.test.ts +4 -4
  84. package/src/__tests__/conversation-queue.test.ts +81 -81
  85. package/src/__tests__/conversation-routes-enabled-plugins.test.ts +8 -1
  86. package/src/__tests__/conversation-routes-hidden-queue.test.ts +8 -1
  87. package/src/__tests__/conversation-routes-slash-commands.test.ts +10 -1
  88. package/src/__tests__/conversation-runtime-assembly.test.ts +29 -2
  89. package/src/__tests__/conversation-slash-queue.test.ts +11 -11
  90. package/src/__tests__/conversation-slash-unknown.test.ts +2 -2
  91. package/src/__tests__/conversation-speed-override.test.ts +2 -2
  92. package/src/__tests__/conversation-summarize-route.test.ts +9 -0
  93. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +18 -16
  94. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +17 -17
  95. package/src/__tests__/conversation-surfaces-app-open.test.ts +7 -4
  96. package/src/__tests__/conversation-surfaces-data-persist.test.ts +7 -7
  97. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +9 -9
  98. package/src/__tests__/conversation-surfaces-standalone.test.ts +12 -12
  99. package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
  100. package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -3
  101. package/src/__tests__/conversation-surfaces-task-progress.test.ts +46 -46
  102. package/src/__tests__/conversation-sync-tags.test.ts +5 -5
  103. package/src/__tests__/conversation-wait-for-idle.test.ts +2 -2
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
  105. package/src/__tests__/conversation-workspace-injection.test.ts +0 -3
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -3
  107. package/src/__tests__/copy-composer-tc-templates.test.ts +3 -131
  108. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  109. package/src/__tests__/daemon-assistant-events.test.ts +14 -15
  110. package/src/__tests__/db-test-helpers.ts +13 -27
  111. package/src/__tests__/disk-pressure-routes.test.ts +12 -3
  112. package/src/__tests__/document-tool-security.test.ts +95 -0
  113. package/src/__tests__/drain-kick-guard.test.ts +232 -0
  114. package/src/__tests__/dynamic-skill-background-guard.test.ts +19 -6
  115. package/src/__tests__/emit-event-signal.test.ts +5 -6
  116. package/src/__tests__/encrypted-store-test-helpers.ts +10 -20
  117. package/src/__tests__/events-tail-route.test.ts +6 -4
  118. package/src/__tests__/feature-flag-test-helpers.ts +10 -20
  119. package/src/__tests__/file-edit-tool.test.ts +24 -4
  120. package/src/__tests__/file-list-tool.test.ts +2 -1
  121. package/src/__tests__/file-read-tool.test.ts +62 -10
  122. package/src/__tests__/file-write-tool.test.ts +24 -5
  123. package/src/__tests__/followup-tools.test.ts +58 -0
  124. package/src/__tests__/gateway-threshold-reader-mock.ts +99 -0
  125. package/src/__tests__/graph-extraction-event-date.test.ts +1 -1
  126. package/src/__tests__/guardian-question-mode.test.ts +42 -3
  127. package/src/__tests__/guardian-reply-router-answer-mode.test.ts +283 -0
  128. package/src/__tests__/guardian-vellum-destination-pinning.test.ts +221 -0
  129. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  130. package/src/__tests__/heartbeat-service.test.ts +1 -0
  131. package/src/__tests__/helpers/native-web-search-harness.ts +10 -10
  132. package/src/__tests__/host-browser-proxy.test.ts +1 -1
  133. package/src/__tests__/host-file-edit-tool.test.ts +3 -3
  134. package/src/__tests__/host-file-read-tool.test.ts +2 -2
  135. package/src/__tests__/host-file-write-tool.test.ts +7 -3
  136. package/src/__tests__/host-shell-tool.test.ts +17 -5
  137. package/src/__tests__/host-transfer-pending-interactions.test.ts +8 -8
  138. package/src/__tests__/image-credentials.test.ts +65 -8
  139. package/src/__tests__/injection-block.test.ts +4 -4
  140. package/src/__tests__/injector-chain.test.ts +1 -1
  141. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  142. package/src/__tests__/injector-registry-order-guard.test.ts +4 -9
  143. package/src/__tests__/injector-v3-suppression.test.ts +6 -4
  144. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +27 -28
  145. package/src/__tests__/list-messages-page-latest.test.ts +2 -2
  146. package/src/__tests__/llm-usage-store.test.ts +67 -4
  147. package/src/__tests__/log-redact.test.ts +18 -0
  148. package/src/__tests__/managed-profile-guard.test.ts +27 -0
  149. package/src/__tests__/managed-skill-lifecycle.test.ts +2 -2
  150. package/src/__tests__/media-generate-image.test.ts +62 -11
  151. package/src/__tests__/memory-identity-context-parity.test.ts +1 -1
  152. package/src/__tests__/memory-jobs-worker-lanes.test.ts +9 -1
  153. package/src/__tests__/memory-retrieval-hook.test.ts +4 -4
  154. package/src/__tests__/notification-decision-strategy.test.ts +115 -11
  155. package/src/__tests__/notification-deep-link.test.ts +12 -12
  156. package/src/__tests__/notification-vellum-adapter.test.ts +8 -8
  157. package/src/__tests__/outbound-slack-persistence.test.ts +8 -8
  158. package/src/__tests__/path-policy.test.ts +315 -0
  159. package/src/__tests__/pending-interactions-resolved-event.test.ts +6 -6
  160. package/src/__tests__/persistence-layering-guard.test.ts +2 -2
  161. package/src/__tests__/pkb-autoinject.test.ts +1 -1
  162. package/src/__tests__/platform-bash-auto-approve.test.ts +1 -0
  163. package/src/__tests__/plugin-event-hub-facade.test.ts +22 -15
  164. package/src/__tests__/plugin-import-boundary-guard.test.ts +15 -15
  165. package/src/__tests__/processing-flag-persist-failure.test.ts +0 -4
  166. package/src/__tests__/provider-platform-proxy-integration.test.ts +0 -1
  167. package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
  168. package/src/__tests__/request-secret-standalone-channel-gate.test.ts +5 -5
  169. package/src/__tests__/require-fresh-approval.test.ts +38 -38
  170. package/src/__tests__/run-due-schedules.test.ts +72 -1
  171. package/src/__tests__/runtime-events-sse-parity.test.ts +11 -10
  172. package/src/__tests__/runtime-events-sse.test.ts +1 -1
  173. package/src/__tests__/schedule-routes.test.ts +44 -5
  174. package/src/__tests__/schedule-store.test.ts +3 -3
  175. package/src/__tests__/schedule-tools.test.ts +176 -0
  176. package/src/__tests__/secret-prompt-log-hygiene.test.ts +3 -3
  177. package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -3
  178. package/src/__tests__/secret-response-routing.test.ts +3 -3
  179. package/src/__tests__/secret-routes-platform-proxy.test.ts +4 -7
  180. package/src/__tests__/secret-scanner.test.ts +36 -0
  181. package/src/__tests__/send-endpoint-busy.test.ts +7 -7
  182. package/src/__tests__/slack-required-scopes-mirror.test.ts +81 -0
  183. package/src/__tests__/starter-task-flow.test.ts +6 -3
  184. package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
  185. package/src/__tests__/subagent-disposal.test.ts +40 -11
  186. package/src/__tests__/subagent-fork-notifications.test.ts +4 -4
  187. package/src/__tests__/subagent-fork-prompt-role.test.ts +3 -3
  188. package/src/__tests__/subagent-fork-spawn.test.ts +4 -4
  189. package/src/__tests__/subagent-manager-notify.test.ts +73 -14
  190. package/src/__tests__/subagent-notify-parent.test.ts +48 -4
  191. package/src/__tests__/subagent-spawn-and-await.test.ts +62 -14
  192. package/src/__tests__/subagent-tools.test.ts +64 -0
  193. package/src/__tests__/sync-message-contract.test.ts +3 -3
  194. package/src/__tests__/terminal-tools.test.ts +12 -3
  195. package/src/__tests__/test-preload.ts +9 -0
  196. package/src/__tests__/tool-approval-handler.test.ts +583 -43
  197. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +7 -4
  198. package/src/__tests__/tool-executor.test.ts +116 -0
  199. package/src/__tests__/tool-grant-request-escalation.test.ts +5 -0
  200. package/src/__tests__/tool-preview-lifecycle.test.ts +32 -29
  201. package/src/__tests__/tool-result-metadata-plumbing.test.ts +5 -5
  202. package/src/__tests__/tool-start-timestamp.test.ts +4 -4
  203. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -22
  204. package/src/__tests__/ui-choice-copy-surfaces.test.ts +13 -13
  205. package/src/__tests__/ui-work-result-surface.test.ts +3 -3
  206. package/src/__tests__/voice-scoped-grant-consumer.test.ts +6 -6
  207. package/src/__tests__/voice-session-bridge.test.ts +44 -44
  208. package/src/__tests__/workspace-migration-134-image-generation-mode-to-provider.test.ts +284 -0
  209. package/src/__tests__/workspace-policy.test.ts +399 -0
  210. package/src/acp/__tests__/client-handler.test.ts +3 -3
  211. package/src/acp/__tests__/session-manager-persistence.test.ts +10 -10
  212. package/src/acp/__tests__/session-manager-resume.test.ts +7 -7
  213. package/src/acp/client-handler.ts +3 -3
  214. package/src/acp/session-manager.ts +8 -8
  215. package/src/api/events/subagent-event.ts +2 -2
  216. package/src/api/responses/memory-v2-activation-log.ts +2 -2
  217. package/src/approvals/AGENTS.md +2 -0
  218. package/src/approvals/guardian-request-resolvers.ts +118 -24
  219. package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
  220. package/src/calls/__tests__/voice-session-bridge.test.ts +158 -4
  221. package/src/calls/__tests__/voice-triage-escalate.test.ts +3 -4
  222. package/src/calls/call-controller.ts +27 -27
  223. package/src/calls/call-conversation-messages.ts +58 -18
  224. package/src/calls/voice-control-protocol.ts +56 -0
  225. package/src/calls/voice-session-bridge.ts +156 -58
  226. package/src/calls/voice-triage-escalate.ts +2 -3
  227. package/src/channels/config.ts +8 -0
  228. package/src/channels/types.ts +1 -0
  229. package/src/cli/commands/config.ts +49 -13
  230. package/src/cli/commands/memory/index.help.ts +4 -2
  231. package/src/cli/commands/memory/memory-retrospective.ts +5 -0
  232. package/src/cli/lib/bundled-marketplace.json +12 -0
  233. package/src/cli.ts +2 -109
  234. package/src/config/__tests__/deployment-context-defaults.test.ts +9 -0
  235. package/src/config/__tests__/substrate-twin-shadowing.test.ts +191 -0
  236. package/src/config/assistant-feature-flags.ts +1 -1
  237. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +13 -7
  238. package/src/config/feature-flag-cache.ts +6 -16
  239. package/src/config/feature-flag-registry.json +14 -30
  240. package/src/config/loader.ts +7 -1
  241. package/src/config/memory-tier.ts +15 -10
  242. package/src/config/memory-v3-gate.test.ts +278 -1
  243. package/src/config/memory-v3-gate.ts +88 -26
  244. package/src/config/raw-config-utils.ts +1 -1
  245. package/src/config/schemas/__tests__/live-voice.test.ts +27 -16
  246. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  247. package/src/config/schemas/live-voice.ts +33 -7
  248. package/src/config/schemas/llm.ts +1 -0
  249. package/src/config/schemas/memory-retrospective.ts +13 -0
  250. package/src/config/schemas/memory-substrate.ts +183 -0
  251. package/src/config/schemas/memory-v2.ts +3 -2
  252. package/src/config/schemas/memory-v3.ts +11 -4
  253. package/src/config/schemas/memory.ts +35 -1
  254. package/src/config/schemas/services.ts +10 -2
  255. package/src/config/substrate-twin-shadowing.ts +195 -0
  256. package/src/config/webhook-routing.ts +67 -0
  257. package/src/context/compactor.ts +10 -3
  258. package/src/context/token-estimator.ts +21 -0
  259. package/src/daemon/__tests__/channel-ui-capability.test.ts +85 -0
  260. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +3 -3
  261. package/src/daemon/__tests__/embedding-reconcile.test.ts +3 -3
  262. package/src/daemon/__tests__/inference-profile-notification.test.ts +3 -6
  263. package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -5
  264. package/src/daemon/__tests__/web-search-status-text.test.ts +2 -2
  265. package/src/daemon/channel-ui-capability.ts +70 -1
  266. package/src/daemon/conversation-agent-loop-handlers.ts +4 -4
  267. package/src/daemon/conversation-agent-loop.ts +12 -5
  268. package/src/daemon/conversation-evictor.ts +26 -4
  269. package/src/daemon/conversation-launch.ts +11 -14
  270. package/src/daemon/conversation-messaging.ts +14 -14
  271. package/src/daemon/conversation-notifiers.ts +2 -2
  272. package/src/daemon/conversation-process.ts +133 -21
  273. package/src/daemon/conversation-queue-manager.ts +7 -7
  274. package/src/daemon/conversation-runtime-assembly.ts +16 -0
  275. package/src/daemon/conversation-store.ts +11 -3
  276. package/src/daemon/conversation-surfaces.ts +4 -4
  277. package/src/daemon/conversation-tool-setup.ts +13 -7
  278. package/src/daemon/conversation-usage.ts +12 -11
  279. package/src/daemon/conversation.ts +38 -15
  280. package/src/daemon/disk-pressure-guard.ts +5 -12
  281. package/src/daemon/embedding-reconcile.ts +14 -9
  282. package/src/daemon/handlers/config-channels.ts +40 -134
  283. package/src/daemon/handlers/config-model.ts +15 -7
  284. package/src/daemon/handlers/conversations.ts +4 -2
  285. package/src/daemon/handlers/shared.ts +29 -0
  286. package/src/daemon/host-proxy-base.ts +4 -4
  287. package/src/daemon/lifecycle.ts +13 -0
  288. package/src/daemon/message-protocol.ts +8 -144
  289. package/src/daemon/message-types/computer-use.ts +0 -12
  290. package/src/daemon/message-types/conversations.ts +9 -345
  291. package/src/daemon/message-types/host-app-control.ts +0 -9
  292. package/src/daemon/message-types/host-browser.ts +0 -7
  293. package/src/daemon/message-types/host-ui-snapshot.ts +0 -7
  294. package/src/daemon/message-types/messages.ts +0 -48
  295. package/src/daemon/message-types/notifications.ts +0 -7
  296. package/src/daemon/message-types/skills.ts +0 -5
  297. package/src/daemon/message-types/surfaces.ts +0 -9
  298. package/src/daemon/message-types/sync.ts +0 -2
  299. package/src/daemon/process-message.ts +5 -5
  300. package/src/daemon/skill-memory-refresh.ts +5 -5
  301. package/src/daemon/tool-side-effects.ts +13 -13
  302. package/src/daemon/trust-context.ts +1 -1
  303. package/src/daemon/wake-conversation-ops.ts +4 -4
  304. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +100 -7
  305. package/src/heartbeat/__tests__/heartbeat-service.test.ts +67 -0
  306. package/src/heartbeat/heartbeat-run-store.ts +81 -4
  307. package/src/heartbeat/heartbeat-service.ts +32 -1
  308. package/src/home/__tests__/feed-writer.test.ts +7 -7
  309. package/src/home/__tests__/home-content-refresh.test.ts +3 -0
  310. package/src/home/__tests__/suggested-prompts.test.ts +1 -0
  311. package/src/home/feed-writer.ts +6 -13
  312. package/src/home/home-content-refresh.ts +6 -9
  313. package/src/home/relationship-state-writer.ts +5 -12
  314. package/src/home/suggested-prompts-cache.ts +6 -19
  315. package/src/ipc/__tests__/events-publish-client.test.ts +67 -0
  316. package/src/ipc/events-publish-client.ts +44 -0
  317. package/src/ipc/routes/__tests__/conversation-sync-ipc-routes.test.ts +2 -2
  318. package/src/ipc/routes/__tests__/events-ipc-routes.test.ts +38 -9
  319. package/src/ipc/routes/events-ipc-routes.ts +11 -31
  320. package/src/live-voice/__tests__/front-decision.test.ts +4 -176
  321. package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +276 -68
  322. package/src/live-voice/__tests__/live-voice-events.test.ts +6 -3
  323. package/src/live-voice/__tests__/live-voice-progress.test.ts +185 -46
  324. package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +24 -59
  325. package/src/live-voice/__tests__/live-voice-tts-session.test.ts +38 -54
  326. package/src/live-voice/__tests__/live-voice-vad.test.ts +218 -422
  327. package/src/live-voice/front-decision.ts +5 -155
  328. package/src/live-voice/live-voice-metrics.ts +4 -1
  329. package/src/live-voice/live-voice-session.ts +650 -333
  330. package/src/live-voice/progress-phrases.ts +17 -0
  331. package/src/live-voice/protocol.ts +15 -0
  332. package/src/media/app-icon-generator.ts +15 -8
  333. package/src/media/avatar-router.ts +9 -5
  334. package/src/media/image-credentials.ts +42 -10
  335. package/src/media/image-service.ts +1 -13
  336. package/src/media/types.ts +26 -3
  337. package/src/notifications/AGENTS.md +2 -0
  338. package/src/notifications/__tests__/broadcaster.test.ts +95 -0
  339. package/src/notifications/adapters/macos.ts +3 -3
  340. package/src/notifications/broadcaster.ts +57 -0
  341. package/src/notifications/copy-composer.ts +0 -15
  342. package/src/notifications/decision-engine.ts +21 -22
  343. package/src/notifications/guardian-question-mode.ts +57 -2
  344. package/src/notifications/home-feed-side-effect.ts +4 -0
  345. package/src/notifications/signal.ts +6 -4
  346. package/src/notifications/trusted-contact-payloads.ts +3 -4
  347. package/src/notifications/vellum-card-affinity.ts +39 -0
  348. package/src/oauth/AGENTS.md +1 -1
  349. package/src/permissions/channel-permission-query.test.ts +69 -0
  350. package/src/permissions/channel-permission-query.ts +73 -1
  351. package/src/permissions/checker.test.ts +85 -9
  352. package/src/permissions/checker.ts +17 -22
  353. package/src/permissions/confirmation-guardian-request.test.ts +2 -2
  354. package/src/permissions/confirmation-guardian-request.ts +2 -2
  355. package/src/permissions/gateway-threshold-reader.test.ts +224 -17
  356. package/src/permissions/gateway-threshold-reader.ts +82 -10
  357. package/src/permissions/ipc-risk-types.ts +8 -0
  358. package/src/permissions/prompter.ts +5 -5
  359. package/src/permissions/question-guardian-request.test.ts +222 -0
  360. package/src/permissions/question-guardian-request.ts +179 -0
  361. package/src/permissions/question-prompter.test.ts +8 -8
  362. package/src/permissions/question-prompter.ts +18 -0
  363. package/src/permissions/secret-prompter.ts +2 -4
  364. package/src/permissions/workspace-policy.ts +236 -34
  365. package/src/persistence/__tests__/lifecycle-quiesce.test.ts +82 -0
  366. package/src/persistence/__tests__/message-content-file.test.ts +58 -3
  367. package/src/persistence/conversation-crud.ts +93 -0
  368. package/src/persistence/conversation-key-store.ts +63 -0
  369. package/src/persistence/db-async-query.ts +1 -1
  370. package/src/persistence/db-singleton.ts +14 -27
  371. package/src/persistence/delivery-crud.ts +45 -0
  372. package/src/persistence/embeddings/embedding-backend.ts +2 -1
  373. package/src/persistence/embeddings/embedding-identity.ts +7 -3
  374. package/src/persistence/job-utils.ts +32 -27
  375. package/src/persistence/jobs-store.ts +92 -3
  376. package/src/persistence/lifecycle-quiesce.ts +80 -0
  377. package/src/persistence/llm-usage-store.ts +45 -8
  378. package/src/persistence/message-content-file.ts +4 -4
  379. package/src/persistence/migrations/336-move-memory-v2-activation-logs-to-memory-db.ts +1 -1
  380. package/src/persistence/migrations/351-schedule-skill-script-handoff.ts +39 -0
  381. package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.test.ts +83 -0
  382. package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.ts +36 -0
  383. package/src/persistence/migrations/353-add-llm-usage-conversation-type.test.ts +110 -0
  384. package/src/persistence/migrations/353-add-llm-usage-conversation-type.ts +49 -0
  385. package/src/persistence/schema/infrastructure.ts +11 -0
  386. package/src/persistence/steps.ts +7 -1
  387. package/src/plugin-api/__tests__/publish-event-forwarding.test.ts +113 -0
  388. package/src/plugin-api/__tests__/publish-event.test.ts +57 -0
  389. package/src/plugin-api/conversation-turn.ts +4 -4
  390. package/src/plugin-api/event-hub-facade.ts +15 -6
  391. package/src/plugin-api/index.ts +10 -4
  392. package/src/plugin-api/publish-event.ts +36 -0
  393. package/src/plugins/AGENTS.md +2 -0
  394. package/src/plugins/defaults/compaction/window-manager.ts +9 -0
  395. package/src/plugins/defaults/index.ts +9 -13
  396. package/src/plugins/defaults/memory/AGENTS.md +775 -0
  397. package/src/plugins/defaults/memory/__tests__/capability-seed-embed-gate.test.ts +186 -0
  398. package/src/plugins/defaults/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +1 -1
  399. package/src/plugins/defaults/memory/__tests__/indexer-tier-dispatch.test.ts +129 -0
  400. package/src/plugins/defaults/memory/__tests__/jobs-worker-quiesce-gate.test.ts +91 -0
  401. package/src/plugins/defaults/memory/__tests__/jobs-worker-v1-graph-substrate-noop.test.ts +342 -0
  402. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +9 -1
  403. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +36 -1
  404. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-sweep-defer.test.ts +9 -1
  405. package/src/plugins/defaults/memory/__tests__/memory-log-stores-degraded.test.ts +2 -2
  406. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +44 -10
  407. package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +151 -10
  408. package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1155 -0
  409. package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
  410. package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -3
  411. package/src/plugins/defaults/memory/__tests__/tools-delete-memory-page.test.ts +1 -1
  412. package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +71 -35
  413. package/src/plugins/defaults/memory/context-search/sources/memory.ts +5 -1
  414. package/src/plugins/defaults/memory/fork-conversation-memory.ts +4 -4
  415. package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +80 -10
  416. package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +1 -1
  417. package/src/plugins/defaults/memory/graph/capability-seed.ts +24 -10
  418. package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +123 -49
  419. package/src/plugins/defaults/memory/graph/graph-search.ts +6 -118
  420. package/src/plugins/defaults/memory/graph/in-context-tracker.test.ts +173 -0
  421. package/src/plugins/defaults/memory/graph/in-context-tracker.ts +109 -0
  422. package/src/plugins/defaults/memory/graph/store.ts +1 -0
  423. package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +1 -1
  424. package/src/plugins/defaults/memory/graph/tool-handlers.ts +5 -2
  425. package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +1 -1
  426. package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +6 -9
  427. package/src/plugins/defaults/memory/hooks/__tests__/user-prompt-submit.test.ts +30 -16
  428. package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +18 -14
  429. package/src/plugins/defaults/memory/indexer.ts +146 -89
  430. package/src/plugins/defaults/memory/injectors.ts +86 -41
  431. package/src/plugins/defaults/memory/job-handlers.ts +130 -39
  432. package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +2 -2
  433. package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +22 -10
  434. package/src/plugins/defaults/memory/jobs-worker.ts +279 -208
  435. package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +4 -2
  436. package/src/plugins/defaults/memory/memory-retrospective-job.ts +40 -3
  437. package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +99 -11
  438. package/src/plugins/defaults/memory/src/__tests__/memory-v2-routes.test.ts +5 -3
  439. package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +3 -4
  440. package/src/plugins/defaults/memory/src/memory-graph-routes.ts +2 -1
  441. package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +7 -5
  442. package/src/plugins/defaults/memory/src/memory-item-routes.ts +51 -19
  443. package/src/plugins/defaults/memory/src/memory-v2-routes.ts +31 -20
  444. package/src/plugins/defaults/memory/startup.ts +58 -21
  445. package/src/plugins/defaults/memory/substrate/__tests__/boot-maintenance.test.ts +335 -0
  446. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/cli-command-store.test.ts +14 -8
  447. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-job.test.ts +51 -21
  448. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/edge-index.test.ts +1 -1
  449. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/frontmatter-sweep.test.ts +3 -3
  450. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-index.test.ts +1 -1
  451. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-store.test.ts +1 -1
  452. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/prompts-consolidation.test.ts +2 -2
  453. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/qdrant.test.ts +23 -14
  454. package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +262 -0
  455. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sim.test.ts +9 -12
  456. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-content.test.ts +2 -2
  457. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-store.test.ts +9 -9
  458. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sparse-bm25.test.ts +12 -5
  459. package/src/plugins/defaults/memory/substrate/__tests__/spread.test.ts +276 -0
  460. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/static-context.test.ts +17 -8
  461. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sweep-job.test.ts +9 -9
  462. package/src/plugins/defaults/memory/{v3/substrate/memory-v2-startup.ts → substrate/boot-maintenance.ts} +43 -24
  463. package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-store.ts +13 -8
  464. package/src/plugins/defaults/memory/{v3/substrate → substrate}/consolidation-job.ts +51 -27
  465. package/src/plugins/defaults/memory/{v3/substrate → substrate}/constants.ts +1 -0
  466. package/src/plugins/defaults/memory/{v3/substrate → substrate}/edge-index.ts +28 -9
  467. package/src/plugins/defaults/memory/{v3/substrate → substrate}/frontmatter-sweep.ts +14 -7
  468. package/src/plugins/defaults/memory/{v3/substrate → substrate}/injected-block-slugs.ts +9 -3
  469. package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-index.ts +29 -10
  470. package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-store.ts +35 -12
  471. package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/consolidation.ts +14 -8
  472. package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/sweep.ts +4 -1
  473. package/src/plugins/defaults/memory/{v3/substrate → substrate}/qdrant.ts +96 -36
  474. package/src/plugins/defaults/memory/substrate/reembed-job.ts +54 -0
  475. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sim.ts +26 -15
  476. package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-content.ts +1 -1
  477. package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-store.ts +13 -8
  478. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sparse-bm25.ts +27 -10
  479. package/src/plugins/defaults/memory/substrate/spread.ts +165 -0
  480. package/src/plugins/defaults/memory/{v3/substrate → substrate}/static-context.ts +12 -7
  481. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sweep-job.ts +20 -15
  482. package/src/plugins/defaults/memory/substrate/tuning.ts +93 -0
  483. package/src/plugins/defaults/memory/{v3/substrate → substrate}/types.ts +7 -4
  484. package/src/plugins/defaults/memory/tools.test.ts +1 -1
  485. package/src/plugins/defaults/memory/tools.ts +1 -1
  486. package/src/plugins/defaults/memory/v1/README.md +5 -0
  487. package/src/plugins/defaults/memory/{__tests__ → v1/__tests__}/filing-jobs.test.ts +4 -4
  488. package/src/plugins/defaults/memory/{filing-jobs.ts → v1/filing-jobs.ts} +3 -3
  489. package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.test.ts +68 -6
  490. package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.ts +40 -21
  491. package/src/plugins/defaults/memory/{graph → v1/graph}/consolidation.ts +14 -14
  492. package/src/plugins/defaults/memory/{graph → v1/graph}/decay.test.ts +1 -1
  493. package/src/plugins/defaults/memory/{graph → v1/graph}/decay.ts +3 -3
  494. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction-job.ts +5 -5
  495. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.test.ts +1 -1
  496. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.ts +20 -14
  497. package/src/plugins/defaults/memory/{graph → v1/graph}/graph-search.test.ts +3 -3
  498. package/src/plugins/defaults/memory/v1/graph/graph-search.ts +123 -0
  499. package/src/plugins/defaults/memory/{graph → v1/graph}/injection.test.ts +1 -118
  500. package/src/plugins/defaults/memory/{graph → v1/graph}/injection.ts +9 -111
  501. package/src/plugins/defaults/memory/{graph → v1/graph}/narrative.ts +6 -6
  502. package/src/plugins/defaults/memory/{graph → v1/graph}/pattern-scan.ts +5 -5
  503. package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.test.ts +135 -42
  504. package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.ts +40 -22
  505. package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.test.ts +1 -1
  506. package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.ts +1 -1
  507. package/src/plugins/defaults/memory/{graph → v1/graph}/serendipity.ts +1 -1
  508. package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.test.ts +1 -1
  509. package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.ts +1 -1
  510. package/src/plugins/defaults/memory/{identity-context.ts → v1/identity-context.ts} +4 -4
  511. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/backfill.ts +6 -6
  512. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.test.ts +6 -6
  513. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.ts +6 -6
  514. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/index-maintenance.ts +8 -8
  515. package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.test.ts +7 -7
  516. package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.ts +5 -5
  517. package/src/plugins/defaults/memory/{pkb → v1/pkb}/autoinject.ts +1 -1
  518. package/src/plugins/defaults/memory/{pkb → v1/pkb}/context.ts +2 -2
  519. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.test.ts +3 -3
  520. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.ts +2 -2
  521. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.test.ts +3 -3
  522. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.ts +2 -2
  523. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.test.ts +3 -3
  524. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.ts +6 -6
  525. package/src/plugins/defaults/memory/{pkb → v1/pkb}/types.ts +3 -5
  526. package/src/plugins/defaults/memory/{pkb-schedule.ts → v1/pkb-schedule.ts} +2 -2
  527. package/src/plugins/defaults/memory/{search/semantic.ts → v1/semantic-search.ts} +1 -1
  528. package/src/plugins/defaults/memory/v2/__tests__/activation-store.test.ts +1 -1
  529. package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +11 -274
  530. package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +9 -131
  531. package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -1
  532. package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -1
  533. package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
  534. package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +14 -10
  535. package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +7 -5
  536. package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +12 -6
  537. package/src/plugins/defaults/memory/{memory-v2-activation-log-store.ts → v2/activation-log-store.ts} +2 -2
  538. package/src/plugins/defaults/memory/v2/activation-store.ts +22 -8
  539. package/src/plugins/defaults/memory/v2/activation.ts +30 -163
  540. package/src/plugins/defaults/memory/v2/backfill-jobs.ts +7 -54
  541. package/src/plugins/defaults/memory/{memory-v2-concept-frequency.ts → v2/concept-frequency.ts} +3 -3
  542. package/src/plugins/defaults/memory/v2/harness/oracle.ts +1 -1
  543. package/src/plugins/defaults/memory/v2/harness/replay-input.ts +2 -2
  544. package/src/plugins/defaults/memory/v2/harness/retriever.ts +1 -1
  545. package/src/plugins/defaults/memory/v2/injection.ts +36 -26
  546. package/src/plugins/defaults/memory/v2/migration.ts +2 -2
  547. package/src/plugins/defaults/memory/{rerank-local.ts → v2/rerank-local.ts} +44 -18
  548. package/src/plugins/defaults/memory/v2/reranker.ts +29 -11
  549. package/src/plugins/defaults/memory/v2/router.ts +38 -15
  550. package/src/plugins/defaults/memory/v3/__tests__/candidate-match.test.ts +5 -3
  551. package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +21 -8
  552. package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +1 -1
  553. package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +1 -1
  554. package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +4 -1
  555. package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +181 -3
  556. package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +3 -0
  557. package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +14 -5
  558. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +40 -50
  559. package/src/plugins/defaults/memory/v3/__tests__/tuning-profile.test.ts +1 -0
  560. package/src/plugins/defaults/memory/v3/candidate-match.ts +2 -2
  561. package/src/plugins/defaults/memory/v3/capabilities.ts +6 -4
  562. package/src/plugins/defaults/memory/v3/card.ts +25 -9
  563. package/src/plugins/defaults/memory/v3/edge.ts +52 -18
  564. package/src/plugins/defaults/memory/v3/gate.ts +4 -4
  565. package/src/plugins/defaults/memory/v3/injector.ts +10 -3
  566. package/src/plugins/defaults/memory/v3/maintain-job.ts +3 -3
  567. package/src/plugins/defaults/memory/v3/orchestrate.ts +100 -18
  568. package/src/plugins/defaults/memory/v3/page-content.ts +26 -10
  569. package/src/plugins/defaults/memory/v3/prune.ts +40 -16
  570. package/src/plugins/defaults/memory/v3/selection-log-store.ts +34 -12
  571. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +9 -13
  572. package/src/plugins/defaults/memory/v3/span-query.test.ts +86 -0
  573. package/src/plugins/defaults/memory/v3/span-query.ts +71 -0
  574. package/src/plugins/defaults/memory/v3/tuning-profile.ts +3 -0
  575. package/src/plugins/defaults/memory/v3/types.ts +4 -1
  576. package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +2 -2
  577. package/src/plugins/defaults/memory/validation.ts +1 -1
  578. package/src/plugins/defaults/memory/worker.ts +2 -1
  579. package/src/plugins/defaults/platform-hosted/__tests__/reengage.test.ts +104 -12
  580. package/src/plugins/defaults/platform-hosted/routes/reengage.ts +104 -12
  581. package/src/plugins/types.ts +2 -2
  582. package/src/providers/__tests__/registry-native-web-search.test.ts +47 -2
  583. package/src/providers/anthropic/client.ts +15 -6
  584. package/src/providers/content-block-schema.ts +26 -0
  585. package/src/providers/inference/__tests__/connections-credential-normalize.test.ts +87 -0
  586. package/src/providers/inference/adapter-factory.ts +6 -0
  587. package/src/providers/inference/connections.ts +30 -14
  588. package/src/providers/model-catalog.ts +77 -0
  589. package/src/providers/openai/__tests__/chat-completions-input-audio.test.ts +260 -0
  590. package/src/providers/openai/chat-completions-provider.ts +65 -17
  591. package/src/providers/openai/input-audio.ts +76 -0
  592. package/src/providers/openrouter/client.ts +0 -2
  593. package/src/providers/platform-proxy/constants.ts +4 -0
  594. package/src/providers/poolside/client.ts +42 -0
  595. package/src/providers/registry.ts +40 -8
  596. package/src/providers/retry.ts +2 -0
  597. package/src/providers/types.ts +39 -1
  598. package/src/providers/vercel-ai-gateway/client.ts +0 -2
  599. package/src/runtime/AGENTS.md +7 -5
  600. package/src/runtime/__tests__/question-request-guardian-bridge.test.ts +173 -0
  601. package/src/runtime/__tests__/question-resolution.test.ts +111 -0
  602. package/src/runtime/access-request-helper.ts +7 -15
  603. package/src/runtime/assistant-event-hub.ts +43 -31
  604. package/src/runtime/assistant-event-publish-options.ts +31 -0
  605. package/src/runtime/assistant-event.ts +19 -30
  606. package/src/runtime/assistant-stream-state.ts +4 -4
  607. package/src/runtime/channel-approvals.ts +0 -25
  608. package/src/runtime/channel-readiness-service.ts +99 -40
  609. package/src/runtime/channel-retry-sweep.ts +38 -15
  610. package/src/runtime/confirmation-request-guardian-bridge.ts +4 -0
  611. package/src/runtime/guardian-reply-router.ts +108 -0
  612. package/src/runtime/http-server.ts +8 -0
  613. package/src/runtime/http-types.ts +2 -2
  614. package/src/runtime/process-role.ts +42 -0
  615. package/src/runtime/question-request-guardian-bridge.ts +184 -0
  616. package/src/runtime/question-resolution.ts +153 -0
  617. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +6 -2
  618. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -1
  619. package/src/runtime/routes/acp-routes.ts +2 -2
  620. package/src/runtime/routes/bookmark-routes.ts +3 -15
  621. package/src/runtime/routes/canned-message-complete.ts +2 -2
  622. package/src/runtime/routes/consolidation-routes.ts +8 -2
  623. package/src/runtime/routes/conversation-list-routes.ts +3 -19
  624. package/src/runtime/routes/conversation-management-routes.ts +1 -5
  625. package/src/runtime/routes/conversation-query-routes.ts +52 -8
  626. package/src/runtime/routes/conversation-routes.ts +36 -22
  627. package/src/runtime/routes/credential-request-routes.ts +0 -1
  628. package/src/runtime/routes/filing-routes.ts +7 -7
  629. package/src/runtime/routes/global-search-routes.ts +1 -1
  630. package/src/runtime/routes/guardian-approval-prompt.ts +2 -2
  631. package/src/runtime/routes/image-generation-routes.ts +12 -9
  632. package/src/runtime/routes/inbound-message-handler.ts +17 -0
  633. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +50 -0
  634. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +19 -0
  635. package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -4
  636. package/src/runtime/routes/inbound-stages/inbound-content-prep.test.ts +129 -0
  637. package/src/runtime/routes/inbound-stages/inbound-content-prep.ts +141 -9
  638. package/src/runtime/routes/index.ts +2 -0
  639. package/src/runtime/routes/lifecycle-routes.ts +199 -0
  640. package/src/runtime/routes/platform-routes.ts +3 -8
  641. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +7 -7
  642. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +5 -5
  643. package/src/runtime/routes/question-routes.ts +34 -87
  644. package/src/runtime/routes/secret-routes.ts +11 -1
  645. package/src/runtime/routes/settings-routes.ts +8 -18
  646. package/src/runtime/routes/upgrade-broadcast-routes.ts +4 -5
  647. package/src/runtime/routes/workspace-routes.test.ts +7 -4
  648. package/src/runtime/slack-reply-session.test.ts +12 -12
  649. package/src/runtime/slack-reply-session.ts +17 -17
  650. package/src/runtime/sync/sync-publisher.test.ts +7 -5
  651. package/src/runtime/tool-grant-request-helper.ts +4 -0
  652. package/src/schedule/schedule-store.ts +70 -0
  653. package/src/schedule/scheduler.ts +27 -0
  654. package/src/security/AGENTS.md +1 -1
  655. package/src/security/credential-key.ts +17 -0
  656. package/src/security/secret-ingress.ts +14 -105
  657. package/src/security/secret-patterns.ts +8 -139
  658. package/src/security/secret-scanner.ts +8 -3
  659. package/src/security/store-path-override.ts +6 -16
  660. package/src/sequence/store.ts +8 -0
  661. package/src/signals/emit-event.ts +5 -10
  662. package/src/signals/event-stream.ts +20 -10
  663. package/src/subagent/manager.ts +76 -25
  664. package/src/subagent/notify.ts +8 -0
  665. package/src/subagent/types.ts +13 -3
  666. package/src/telegram/__tests__/webhook-health.test.ts +442 -0
  667. package/src/telegram/webhook-health.ts +478 -0
  668. package/src/telemetry/AGENTS.md +6 -0
  669. package/src/telemetry/memory-corpus-size.test.ts +129 -0
  670. package/src/telemetry/memory-corpus-size.ts +184 -0
  671. package/src/telemetry/memory-tier-reporter.test.ts +67 -2
  672. package/src/telemetry/memory-tier-reporter.ts +30 -3
  673. package/src/tools/__tests__/document-tool-input-schemas.test.ts +103 -0
  674. package/src/tools/__tests__/followup-call-acp-tool-input-schemas.test.ts +125 -0
  675. package/src/tools/__tests__/schedule-tool-input-schemas.test.ts +83 -0
  676. package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +116 -0
  677. package/src/tools/__tests__/tool-input-schemas.test.ts +192 -0
  678. package/src/tools/__tests__/tool-schema-drift-harness.ts +142 -0
  679. package/src/tools/acp/abort.ts +21 -1
  680. package/src/tools/acp/context.ts +5 -5
  681. package/src/tools/acp/spawn.test.ts +15 -5
  682. package/src/tools/acp/spawn.ts +26 -3
  683. package/src/tools/acp/status.ts +20 -1
  684. package/src/tools/acp/steer.test.ts +20 -0
  685. package/src/tools/acp/steer.ts +23 -2
  686. package/src/tools/ask-question/ask-question-tool.test.ts +65 -0
  687. package/src/tools/ask-question/ask-question-tool.ts +68 -92
  688. package/src/tools/browser/browser-screencast.ts +6 -6
  689. package/src/tools/calls/call-end.ts +24 -3
  690. package/src/tools/calls/call-start.ts +35 -11
  691. package/src/tools/calls/call-status.ts +20 -1
  692. package/src/tools/document/document-comment-tool.test.ts +49 -0
  693. package/src/tools/document/document-comment-tool.ts +45 -6
  694. package/src/tools/document/document-tool.ts +142 -24
  695. package/src/tools/executor.ts +27 -13
  696. package/src/tools/filesystem/edit.ts +62 -60
  697. package/src/tools/filesystem/list.ts +36 -29
  698. package/src/tools/filesystem/read.ts +56 -39
  699. package/src/tools/filesystem/write.ts +44 -38
  700. package/src/tools/followups/followup_create.ts +41 -12
  701. package/src/tools/followups/followup_list.ts +34 -6
  702. package/src/tools/followups/followup_resolve.ts +26 -4
  703. package/src/tools/host-filesystem/edit.ts +50 -60
  704. package/src/tools/host-filesystem/read.ts +45 -39
  705. package/src/tools/host-filesystem/write.ts +31 -36
  706. package/src/tools/host-terminal/host-shell.ts +76 -62
  707. package/src/tools/policy-context.ts +27 -10
  708. package/src/tools/schedule/create.ts +76 -33
  709. package/src/tools/schedule/delete.ts +21 -2
  710. package/src/tools/schedule/list.ts +25 -3
  711. package/src/tools/schedule/update.ts +105 -48
  712. package/src/tools/shared/filesystem/path-policy.ts +246 -40
  713. package/src/tools/shared/zod-tool-schema.ts +117 -0
  714. package/src/tools/subagent/abort.ts +12 -4
  715. package/src/tools/subagent/consult-deadline.ts +9 -3
  716. package/src/tools/subagent/message.ts +21 -5
  717. package/src/tools/subagent/notify-parent.ts +44 -23
  718. package/src/tools/subagent/read.ts +15 -4
  719. package/src/tools/subagent/resolve.ts +26 -4
  720. package/src/tools/subagent/spawn.ts +37 -13
  721. package/src/tools/subagent/status.ts +12 -4
  722. package/src/tools/system/request-permission.ts +35 -26
  723. package/src/tools/terminal/shell.ts +68 -55
  724. package/src/tools/tool-approval-handler.ts +327 -53
  725. package/src/tools/tool-input-schemas.ts +85 -0
  726. package/src/tools/tool-types.ts +7 -0
  727. package/src/tools/types.ts +8 -0
  728. package/src/tools/workflows/manage-workflows.ts +30 -2
  729. package/src/tools/workflows/run-workflow.test.ts +54 -2
  730. package/src/tools/workflows/run-workflow.ts +32 -4
  731. package/src/util/fs-symlinks.ts +30 -0
  732. package/src/util/log-redact.ts +7 -3
  733. package/src/vellum-assistant-namespace.d.ts +80 -0
  734. package/src/watcher/watcher-store.ts +8 -0
  735. package/src/workflows/leaf-runner.test.ts +104 -2
  736. package/src/workflows/leaf-runner.ts +31 -6
  737. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +2 -2
  738. package/src/workspace/migrations/134-image-generation-mode-to-provider.ts +128 -0
  739. package/src/workspace/migrations/135-copy-substrate-tunables.ts +248 -0
  740. package/src/workspace/migrations/__tests__/135-copy-substrate-tunables.test.ts +446 -0
  741. package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +2 -2
  742. package/src/workspace/migrations/registry.ts +4 -0
  743. package/src/__tests__/memory-retrieval-budget.test.ts +0 -49
  744. package/src/__tests__/secret-patterns.test.ts +0 -27
  745. package/src/config/__tests__/proc-to-skills.test.ts +0 -21
  746. package/src/config/memory-tier.test.ts +0 -44
  747. package/src/daemon/message-types/acp.ts +0 -20
  748. package/src/daemon/message-types/apps.ts +0 -11
  749. package/src/daemon/message-types/background-tools.ts +0 -14
  750. package/src/daemon/message-types/bookmarks.ts +0 -13
  751. package/src/daemon/message-types/contacts.ts +0 -13
  752. package/src/daemon/message-types/document-comments.ts +0 -14
  753. package/src/daemon/message-types/documents.ts +0 -13
  754. package/src/daemon/message-types/home.ts +0 -15
  755. package/src/daemon/message-types/host-bash.ts +0 -12
  756. package/src/daemon/message-types/host-cu.ts +0 -10
  757. package/src/daemon/message-types/host-file.ts +0 -12
  758. package/src/daemon/message-types/host-transfer.ts +0 -12
  759. package/src/daemon/message-types/integrations.ts +0 -90
  760. package/src/daemon/message-types/memory.ts +0 -10
  761. package/src/daemon/message-types/schedules.ts +0 -14
  762. package/src/daemon/message-types/settings.ts +0 -17
  763. package/src/daemon/message-types/subagents.ts +0 -63
  764. package/src/daemon/message-types/upgrades.ts +0 -14
  765. package/src/daemon/message-types/workflows.ts +0 -25
  766. package/src/daemon/message-types/workspace.ts +0 -137
  767. package/src/live-voice/ack-phrases.ts +0 -58
  768. package/src/plugins/defaults/memory/retrieval-budget.ts +0 -29
  769. package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +0 -69
  770. package/src/plugins/defaults/memory/v3/gate-flag.ts +0 -20
  771. package/src/plugins/defaults/memory/v3/substrate/__tests__/memory-v2-startup.test.ts +0 -86
  772. package/src/plugins/defaults/memory/v3/substrate/memory-v2-startup.test.ts +0 -205
  773. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/concept-page-frontmatter-schema.test.ts +0 -0
  774. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-prompt-flag-gating-guard.test.ts +0 -0
  775. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/injected-block-slugs.test.ts +0 -0
  776. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-content.ts +0 -0
@@ -0,0 +1,85 @@
1
+ import { describe, expect, test } from "bun:test";
2
+
3
+ import {
4
+ channelSupportsGuardianQuestionCards,
5
+ channelSupportsInlineOptions,
6
+ conversationSupportsGuardianQuestionCards,
7
+ } from "../channel-ui-capability.js";
8
+
9
+ // Single source of truth for which channels' adapters can render inline
10
+ // tappable options. `resolveChannelCapabilities` populates
11
+ // `ChannelCapabilities.supportsInlineOptions` from this, and the approval
12
+ // delivery path reads it directly (retiring the old RICH_APPROVAL_CHANNELS set).
13
+ describe("channelSupportsInlineOptions", () => {
14
+ test("true for channels with an inline-button adapter", () => {
15
+ expect(channelSupportsInlineOptions("telegram")).toBe(true);
16
+ expect(channelSupportsInlineOptions("whatsapp")).toBe(true);
17
+ expect(channelSupportsInlineOptions("slack")).toBe(true);
18
+ });
19
+
20
+ test("false for the app and text/voice-only channels", () => {
21
+ expect(channelSupportsInlineOptions("vellum")).toBe(false);
22
+ expect(channelSupportsInlineOptions("phone")).toBe(false);
23
+ expect(channelSupportsInlineOptions("email")).toBe(false);
24
+ });
25
+
26
+ test("false for unknown and empty channel ids", () => {
27
+ expect(channelSupportsInlineOptions("")).toBe(false);
28
+ expect(channelSupportsInlineOptions("mystery")).toBe(false);
29
+ });
30
+ });
31
+
32
+ // Strict subset of the inline-options channels: only channels with a
33
+ // notification adapter that renders card actions can receive a parked
34
+ // ask_question as a guardian-request card. WhatsApp renders approval buttons
35
+ // on direct sends but has no notification adapter, so it must stay false —
36
+ // parking a question for it would hang the turn with no card ever delivered.
37
+ describe("channelSupportsGuardianQuestionCards", () => {
38
+ test("true only for channels with a card-rendering notification adapter", () => {
39
+ expect(channelSupportsGuardianQuestionCards("telegram")).toBe(true);
40
+ expect(channelSupportsGuardianQuestionCards("slack")).toBe(true);
41
+ });
42
+
43
+ test("false for whatsapp (approval buttons but no notification adapter)", () => {
44
+ expect(channelSupportsGuardianQuestionCards("whatsapp")).toBe(false);
45
+ });
46
+
47
+ test("false for the app, voice, unknown, and empty ids", () => {
48
+ expect(channelSupportsGuardianQuestionCards("vellum")).toBe(false);
49
+ expect(channelSupportsGuardianQuestionCards("phone")).toBe(false);
50
+ expect(channelSupportsGuardianQuestionCards("")).toBe(false);
51
+ expect(channelSupportsGuardianQuestionCards("mystery")).toBe(false);
52
+ });
53
+ });
54
+
55
+ describe("conversationSupportsGuardianQuestionCards", () => {
56
+ test("reads the channel from per-turn capabilities, then the structural fallback", () => {
57
+ expect(
58
+ conversationSupportsGuardianQuestionCards({
59
+ currentTurnChannelCapabilities: {
60
+ supportsDynamicUi: false,
61
+ channel: "telegram",
62
+ },
63
+ }),
64
+ ).toBe(true);
65
+ expect(
66
+ conversationSupportsGuardianQuestionCards({
67
+ channelCapabilities: { supportsDynamicUi: false, channel: "slack" },
68
+ }),
69
+ ).toBe(true);
70
+ });
71
+
72
+ test("false when the channel is card-less or unknown", () => {
73
+ expect(
74
+ conversationSupportsGuardianQuestionCards({
75
+ channelCapabilities: { supportsDynamicUi: false, channel: "whatsapp" },
76
+ }),
77
+ ).toBe(false);
78
+ expect(
79
+ conversationSupportsGuardianQuestionCards({
80
+ channelCapabilities: { supportsDynamicUi: true },
81
+ }),
82
+ ).toBe(false);
83
+ expect(conversationSupportsGuardianQuestionCards({})).toBe(false);
84
+ });
85
+ });
@@ -126,7 +126,7 @@ const { createSurfaceMutex, handleSurfaceAction } =
126
126
  type SurfaceConversationContext =
127
127
  import("../conversation-surfaces.js").SurfaceConversationContext;
128
128
  type TrustContext = import("../trust-context-types.js").TrustContext;
129
- type ServerMessage = import("../message-protocol.js").ServerMessage;
129
+ type AssistantEvent = import("../../api/index.js").AssistantEvent;
130
130
  type SurfaceType = import("../message-protocol.js").SurfaceType;
131
131
 
132
132
  // ── Harness reset helper ───────────────────────────────────────────
@@ -145,7 +145,7 @@ function resetProcessHarness(): void {
145
145
  // ── Surface-context harness ────────────────────────────────────────
146
146
 
147
147
  interface HarnessContext extends SurfaceConversationContext {
148
- sent: ServerMessage[];
148
+ sent: AssistantEvent[];
149
149
  enqueueCalls: Array<{ content: string }>;
150
150
  processCalls: Array<{ content: string }>;
151
151
  }
@@ -153,7 +153,7 @@ interface HarnessContext extends SurfaceConversationContext {
153
153
  function makeContext(
154
154
  overrides?: Partial<SurfaceConversationContext>,
155
155
  ): HarnessContext {
156
- const sent: ServerMessage[] = [];
156
+ const sent: AssistantEvent[] = [];
157
157
  const enqueueCalls: Array<{ content: string }> = [];
158
158
  const processCalls: Array<{ content: string }> = [];
159
159
 
@@ -24,7 +24,7 @@ const realMemoryV3Gate = {
24
24
  ...(await import("../../config/memory-v3-gate.js")),
25
25
  };
26
26
  const realV2Qdrant = {
27
- ...(await import("../../plugins/defaults/memory/v3/substrate/qdrant.js")),
27
+ ...(await import("../../plugins/defaults/memory/substrate/qdrant.js")),
28
28
  };
29
29
  const realSectionDenseStore = {
30
30
  ...(await import("../../plugins/defaults/memory/v3/section-dense-store.js")),
@@ -86,7 +86,7 @@ function makeDeps(opts: {
86
86
  : { provider: "gemini" as const, model: "m", dim: opts.probeDim },
87
87
  ),
88
88
  readConceptPageCollectionDim: mock(async () => {
89
- if (opts.committedDimError) throw opts.committedDimError;
89
+ if (opts.committedDimError) {throw opts.committedDimError;}
90
90
  return opts.committedDim ?? null;
91
91
  }),
92
92
  decideEmbeddingReconcile: mock(() => opts.decision),
@@ -360,7 +360,7 @@ async function withDefaultDepsMocks(opts: {
360
360
  realMemoryV3Gate.isMemoryV3Live,
361
361
  ),
362
362
  }));
363
- mock.module("../../plugins/defaults/memory/v3/substrate/qdrant.js", () => ({
363
+ mock.module("../../plugins/defaults/memory/substrate/qdrant.js", () => ({
364
364
  ...realV2Qdrant,
365
365
  ensureConceptPageCollection: delegate(
366
366
  spies.ensureConceptPageCollection,
@@ -42,12 +42,9 @@ mock.module("../../plugins/defaults/memory/memory-recall-log-store.js", () => ({
42
42
  backfillMemoryRecallLogMessageId: () => {},
43
43
  }));
44
44
 
45
- mock.module(
46
- "../../plugins/defaults/memory/memory-v2-activation-log-store.js",
47
- () => ({
48
- backfillMemoryV2ActivationMessageId: () => {},
49
- }),
50
- );
45
+ mock.module("../../plugins/defaults/memory/v2/activation-log-store.js", () => ({
46
+ backfillMemoryV2ActivationMessageId: () => {},
47
+ }));
51
48
 
52
49
  // ── Imports (after mocks) ────────────────────────────────────────────────────
53
50
  import type { AgentEvent } from "../../agent/loop.js";
@@ -29,6 +29,7 @@ mock.module("../../persistence/llm-request-log-store.js", () => ({
29
29
  }));
30
30
 
31
31
  // ── Imports (after mocks) ─────────────────────────────────────────────────────
32
+ import type { AssistantEvent } from "../../api/index.js";
32
33
  import { WEB_SEARCH_BACKEND_FAILURE_MESSAGE } from "../../tools/network/web-search-error.js";
33
34
  import type {
34
35
  EventHandlerDeps,
@@ -38,17 +39,16 @@ import {
38
39
  createEventHandlerState,
39
40
  dispatchAgentEvent,
40
41
  } from "../conversation-agent-loop-handlers.js";
41
- import type { ServerMessage } from "../message-protocol.js";
42
42
 
43
- type ToolResultEvent = Extract<ServerMessage, { type: "tool_result" }>;
43
+ type ToolResultEvent = Extract<AssistantEvent, { type: "tool_result" }>;
44
44
 
45
45
  // ── Helpers ───────────────────────────────────────────────────────────────────
46
46
 
47
47
  function createCollectorDeps(providerName = "anthropic"): {
48
48
  deps: EventHandlerDeps;
49
- events: ServerMessage[];
49
+ events: AssistantEvent[];
50
50
  } {
51
- const events: ServerMessage[] = [];
51
+ const events: AssistantEvent[] = [];
52
52
  const deps = {
53
53
  ctx: {
54
54
  conversationId: "conv-native-meta",
@@ -58,7 +58,7 @@ function createCollectorDeps(providerName = "anthropic"): {
58
58
  markWorkspaceTopLevelDirty: () => {},
59
59
  currentTurnSurfaces: [],
60
60
  } as unknown as EventHandlerDeps["ctx"],
61
- onEvent: (msg: ServerMessage) => events.push(msg),
61
+ onEvent: (msg: AssistantEvent) => events.push(msg),
62
62
  reqId: "req-native-meta",
63
63
  isFirstMessage: false,
64
64
  shouldGenerateTitle: false,
@@ -20,6 +20,7 @@ mock.module("../../persistence/llm-request-log-store.js", () => ({
20
20
  }));
21
21
 
22
22
  // ── Imports (after mocks) ─────────────────────────────────────────────────────
23
+ import type { AssistantEvent } from "../../api/index.js";
23
24
  import type {
24
25
  EventHandlerDeps,
25
26
  EventHandlerState,
@@ -30,7 +31,6 @@ import {
30
31
  formatFetchStatusText,
31
32
  formatSearchStatusText,
32
33
  } from "../conversation-agent-loop-handlers.js";
33
- import type { ServerMessage } from "../message-protocol.js";
34
34
 
35
35
  // ── Helpers ───────────────────────────────────────────────────────────────────
36
36
 
@@ -68,7 +68,7 @@ function createCollectorDeps(): {
68
68
  markWorkspaceTopLevelDirty: () => {},
69
69
  currentTurnSurfaces: [],
70
70
  } as unknown as EventHandlerDeps["ctx"],
71
- onEvent: (_msg: ServerMessage) => {},
71
+ onEvent: (_msg: AssistantEvent) => {},
72
72
  reqId: "req-status-text",
73
73
  isFirstMessage: false,
74
74
  shouldGenerateTitle: false,
@@ -8,8 +8,12 @@
8
8
  export interface DynamicUiCapabilityView {
9
9
  readonly currentTurnChannelCapabilities?: {
10
10
  readonly supportsDynamicUi: boolean;
11
+ readonly channel?: string;
12
+ };
13
+ readonly channelCapabilities?: {
14
+ readonly supportsDynamicUi: boolean;
15
+ readonly channel?: string;
11
16
  };
12
- readonly channelCapabilities?: { readonly supportsDynamicUi: boolean };
13
17
  }
14
18
 
15
19
  /**
@@ -30,3 +34,68 @@ export function conversationSupportsDynamicUi(
30
34
  conversation.channelCapabilities;
31
35
  return caps?.supportsDynamicUi !== false;
32
36
  }
37
+
38
+ /**
39
+ * Channels whose adapter can render inline tappable options — approval buttons
40
+ * today, question option pickers next. Single source of truth: `resolveChannelCapabilities`
41
+ * populates `ChannelCapabilities.supportsInlineOptions` from this, and the approval
42
+ * delivery path reads it directly, so no feature re-hardcodes its own channel set.
43
+ *
44
+ * Distinct from `supportsDynamicUi` (which gates the app's dynamic-UI surfaces): a
45
+ * text-only channel like Telegram renders inline buttons yet has no dynamic UI.
46
+ */
47
+ const INLINE_OPTIONS_CHANNELS: ReadonlySet<string> = new Set([
48
+ "telegram",
49
+ "whatsapp",
50
+ "slack",
51
+ ]);
52
+
53
+ /**
54
+ * Whether a channel's adapter can render inline tappable options. Pure
55
+ * set-membership on the canonical channel id (no normalization).
56
+ */
57
+ export function channelSupportsInlineOptions(channel: string): boolean {
58
+ return INLINE_OPTIONS_CHANNELS.has(channel);
59
+ }
60
+
61
+ /**
62
+ * Channels where a parked `ask_question` can be delivered as a guardian-request
63
+ * card with tappable answer options — i.e. channels with a notification
64
+ * adapter that renders card actions (`notifications/adapters/`). A strict
65
+ * subset of {@link INLINE_OPTIONS_CHANNELS}: WhatsApp renders approval buttons
66
+ * on direct sends but has no notification adapter yet, so parking a question
67
+ * for it would hang the turn with no card ever delivered.
68
+ *
69
+ * Gates BOTH the `ask_question` park decision (tool context) and the
70
+ * guardian-request promotion, so the two can never disagree. Onboarding a
71
+ * channel = add its notification adapter, then add it here.
72
+ */
73
+ const GUARDIAN_QUESTION_CARD_CHANNELS: ReadonlySet<string> = new Set([
74
+ "telegram",
75
+ "slack",
76
+ ]);
77
+
78
+ /**
79
+ * Whether a parked question can be delivered to this channel as a
80
+ * guardian-request card. Pure set-membership on the canonical channel id.
81
+ */
82
+ export function channelSupportsGuardianQuestionCards(channel: string): boolean {
83
+ return GUARDIAN_QUESTION_CARD_CHANNELS.has(channel);
84
+ }
85
+
86
+ /**
87
+ * Whether the conversation's current-turn channel can receive a parked
88
+ * question as a guardian-request card. Opt-in per channel: defaults to
89
+ * `false` when the channel is unknown. Prefers the per-turn capabilities,
90
+ * falling back to the structural channel capabilities.
91
+ */
92
+ export function conversationSupportsGuardianQuestionCards(
93
+ conversation: DynamicUiCapabilityView,
94
+ ): boolean {
95
+ const caps =
96
+ conversation.currentTurnChannelCapabilities ??
97
+ conversation.channelCapabilities;
98
+ return caps?.channel
99
+ ? channelSupportsGuardianQuestionCards(caps.channel)
100
+ : false;
101
+ }
@@ -11,6 +11,7 @@ import type pino from "pino";
11
11
  import { v4 as uuid } from "uuid";
12
12
 
13
13
  import type { AgentEvent } from "../agent/loop.js";
14
+ import type { AssistantEvent } from "../api/index.js";
14
15
  import type {
15
16
  TurnChannelContext,
16
17
  TurnInterfaceContext,
@@ -54,7 +55,7 @@ import { endSection, markSection } from "../persistence/slow-sync-log.js";
54
55
  import type { ContextWindowResult } from "../plugins/defaults/compaction/window-manager.js";
55
56
  import { indexMessageNow } from "../plugins/defaults/memory/indexer.js";
56
57
  import { backfillMemoryRecallLogMessageId } from "../plugins/defaults/memory/memory-recall-log-store.js";
57
- import { backfillMemoryV2ActivationMessageId } from "../plugins/defaults/memory/memory-v2-activation-log-store.js";
58
+ import { backfillMemoryV2ActivationMessageId } from "../plugins/defaults/memory/v2/activation-log-store.js";
58
59
  import { backfillMemoryV3SelectionMessageId } from "../plugins/defaults/memory/v3/shadow-plugin.js";
59
60
  import { resolveMediaSourceData } from "../providers/media-resolve.js";
60
61
  import type {
@@ -131,7 +132,6 @@ import {
131
132
  } from "./inflight-message-content.js";
132
133
  import type {
133
134
  CardSurfaceData,
134
- ServerMessage,
135
135
  SurfaceAction,
136
136
  UiSurfaceShow,
137
137
  } from "./message-protocol.js";
@@ -511,7 +511,7 @@ export interface EventHandlerState {
511
511
  /** Immutable context shared across event handlers within a single agent loop run. */
512
512
  export interface EventHandlerDeps {
513
513
  readonly ctx: Conversation;
514
- readonly onEvent: (msg: ServerMessage) => void;
514
+ readonly onEvent: (msg: AssistantEvent) => void;
515
515
  readonly reqId: string;
516
516
  readonly isFirstMessage: boolean;
517
517
  /** Whether the conversation title is replaceable — controls firstAssistantText accumulation for title generation. */
@@ -3309,7 +3309,7 @@ export async function dispatchAgentEvent(
3309
3309
  case "compaction_circuit_open":
3310
3310
  case "compaction_circuit_closed":
3311
3311
  // Circuit-breaker transitions are already in wire-contract shape
3312
- // (a subset of ServerMessage), so forward them to the client sink
3312
+ // (a subset of AssistantEvent), so forward them to the client sink
3313
3313
  // unchanged. They drive the client's "auto-compaction paused"
3314
3314
  // banner.
3315
3315
  deps.onEvent(event);
@@ -15,6 +15,7 @@ import type {
15
15
  CheckpointDecision,
16
16
  } from "../agent/loop.js";
17
17
  import { createAssistantMessage } from "../agent/message-types.js";
18
+ import type { AssistantEvent } from "../api/index.js";
18
19
  import type {
19
20
  ChannelId,
20
21
  InterfaceId,
@@ -116,7 +117,7 @@ import {
116
117
  registerInflightTurn,
117
118
  unregisterInflightTurn,
118
119
  } from "./inflight-turn-registry.js";
119
- import type { ServerMessage, UsageStats } from "./message-protocol.js";
120
+ import type { UsageStats } from "./message-protocol.js";
120
121
  import type { TrustContext } from "./trust-context-types.js";
121
122
  import { resolveTurnCallSite } from "./turn-call-site.js";
122
123
  import { runWithLatencySubSpans } from "./turn-latency-sub-spans.js";
@@ -240,7 +241,7 @@ export async function runAgentLoopImpl(
240
241
  ctx: Conversation,
241
242
  content: string,
242
243
  userMessageId: string,
243
- onEvent: (msg: ServerMessage) => void,
244
+ onEvent: (msg: AssistantEvent) => void,
244
245
  options?: {
245
246
  isInteractive?: boolean;
246
247
  isUserMessage?: boolean;
@@ -1669,7 +1670,13 @@ export async function runAgentLoopImpl(
1669
1670
  // the API, enabling stable prefix caching across turns. Compaction
1670
1671
  // consolidates when it summarizes old messages (cache miss is expected).
1671
1672
 
1672
- ctx.drainQueue(yieldedForHandoff ? "checkpoint_handoff" : "loop_complete");
1673
+ // kickDrainQueue never rejects — a drain failure here would otherwise be
1674
+ // an unhandled rejection that strands the queue with nothing left to
1675
+ // re-trigger it.
1676
+ void ctx.kickDrainQueue(
1677
+ yieldedForHandoff ? "checkpoint_handoff" : "loop_complete",
1678
+ "agent_loop_finally",
1679
+ );
1673
1680
  }
1674
1681
  }
1675
1682
 
@@ -1680,7 +1687,7 @@ function emitUsage(
1680
1687
  inputTokens: number,
1681
1688
  outputTokens: number,
1682
1689
  model: string,
1683
- onEvent: (msg: ServerMessage) => void,
1690
+ onEvent: (msg: AssistantEvent) => void,
1684
1691
  actor: UsageActor,
1685
1692
  requestId: string | null = null,
1686
1693
  cacheCreationInputTokens = 0,
@@ -1769,7 +1776,7 @@ export async function applyCompactionResult(
1769
1776
  summaryCallSite?: LLMCallSite;
1770
1777
  summaryOverrideProfile?: string | null;
1771
1778
  },
1772
- onEvent: (msg: ServerMessage) => void,
1779
+ onEvent: (msg: AssistantEvent) => void,
1773
1780
  reqId: string | null,
1774
1781
  options: {
1775
1782
  slackContextCompactionWatermarkTs?: string | null;
@@ -7,6 +7,7 @@ const log = getLogger("conversation-evictor");
7
7
  /** Minimal interface a conversation must satisfy to be evictable. */
8
8
  export interface EvictableConversation {
9
9
  isProcessing(): boolean;
10
+ hasQueuedMessages(): boolean;
10
11
  dispose(): void;
11
12
  }
12
13
 
@@ -63,7 +64,12 @@ export class ConversationEvictor {
63
64
  options?.sweepIntervalMs ?? DEFAULT_SWEEP_INTERVAL_MS;
64
65
  }
65
66
 
66
- /** Abort any subagents belonging to a conversation as it's evicted. */
67
+ /**
68
+ * Abort any in-flight subagents belonging to a conversation as it's evicted.
69
+ * Terminal subagent metadata is left readable — an evicted conversation is
70
+ * resumable from the database, and its next turn may still `subagent_read` a
71
+ * completed child's result.
72
+ */
67
73
  onEvict(conversationId: string): void {
68
74
  getSubagentManager().abortAllForParent(conversationId);
69
75
  }
@@ -125,10 +131,19 @@ export class ConversationEvictor {
125
131
  };
126
132
 
127
133
  // Phase 1: TTL eviction — remove conversations idle longer than ttlMs.
134
+ // A conversation with queued messages is not idle: the queue drains via an
135
+ // async dispatch after the current turn's `finally`, so `isProcessing()`
136
+ // can read false while a queued turn (e.g. a subagent completion wake) is
137
+ // still pending. Disposing in that gap would silently drop the queued
138
+ // messages.
128
139
  for (const [id, conversation] of this.conversations) {
129
140
  const lastAccessTime = this.lastAccess.get(id) ?? 0;
130
141
  if (now - lastAccessTime < this.ttlMs) continue;
131
- if (conversation.isProcessing() || this.shouldProtect(id)) {
142
+ if (
143
+ conversation.isProcessing() ||
144
+ conversation.hasQueuedMessages() ||
145
+ this.shouldProtect(id)
146
+ ) {
132
147
  result.skipped++;
133
148
  continue;
134
149
  }
@@ -202,8 +217,15 @@ export class ConversationEvictor {
202
217
  private idleConversationsByLru(): Array<[string, EvictableConversation]> {
203
218
  const idle: Array<[string, EvictableConversation, number]> = [];
204
219
  for (const [id, conversation] of this.conversations) {
205
- if (conversation.isProcessing()) continue;
206
- if (this.shouldProtect(id)) continue;
220
+ if (conversation.isProcessing()) {
221
+ continue;
222
+ }
223
+ if (conversation.hasQueuedMessages()) {
224
+ continue;
225
+ }
226
+ if (this.shouldProtect(id)) {
227
+ continue;
228
+ }
207
229
  idle.push([id, conversation, this.lastAccess.get(id) ?? 0]);
208
230
  }
209
231
  idle.sort((a, b) => a[2] - b[2]);
@@ -11,8 +11,7 @@ import { randomUUID } from "node:crypto";
11
11
 
12
12
  import { updateConversationTitle } from "../persistence/conversation-crud.js";
13
13
  import { getOrCreateConversation as getOrCreateConversationKey } from "../persistence/conversation-key-store.js";
14
- import { buildAssistantEvent } from "../runtime/assistant-event.js";
15
- import { assistantEventHub } from "../runtime/assistant-event-hub.js";
14
+ import { broadcastMessage } from "../runtime/assistant-event-hub.js";
16
15
  import { getLogger } from "../util/logger.js";
17
16
  import { getOrCreateConversation } from "./conversation-store.js";
18
17
  import { processMessageInBackground } from "./process-message.js";
@@ -72,19 +71,17 @@ export async function launchConversation(
72
71
  updateConversationTitle(conversationId, params.title, 0);
73
72
  }
74
73
 
75
- await assistantEventHub.publish(
76
- buildAssistantEvent(
77
- {
78
- type: "open_conversation",
79
- conversationId,
80
- ...(params.title ? { title: params.title } : {}),
81
- ...(params.anchorMessageId
82
- ? { anchorMessageId: params.anchorMessageId }
83
- : {}),
84
- ...(params.focus !== undefined ? { focus: params.focus } : {}),
85
- },
74
+ broadcastMessage(
75
+ {
76
+ type: "open_conversation",
86
77
  conversationId,
87
- ),
78
+ ...(params.title ? { title: params.title } : {}),
79
+ ...(params.anchorMessageId
80
+ ? { anchorMessageId: params.anchorMessageId }
81
+ : {}),
82
+ ...(params.focus !== undefined ? { focus: params.focus } : {}),
83
+ },
84
+ conversationId,
88
85
  );
89
86
 
90
87
  processMessageInBackground(conversationId, params.seedPrompt, {
@@ -16,6 +16,7 @@ import {
16
16
  } from "../agent/attachments.js";
17
17
  import { optimizeImageForTransport } from "../agent/image-optimize.js";
18
18
  import { createUserMessage } from "../agent/message-types.js";
19
+ import type { AssistantEvent } from "../api/index.js";
19
20
  import type {
20
21
  TurnChannelContext,
21
22
  TurnInterfaceContext,
@@ -64,7 +65,6 @@ import { withSqliteRetry } from "../util/sqlite-retry.js";
64
65
  import type { MessageQueue } from "./conversation-queue-manager.js";
65
66
  import type { SlackInboundMessageMetadata } from "./handlers/shared.js";
66
67
  import type {
67
- ServerMessage,
68
68
  UserMessageAttachment,
69
69
  } from "./message-protocol.js";
70
70
  import type { ConversationTransportMetadata } from "./message-types/conversations.js";
@@ -187,10 +187,10 @@ function resolveIngressSecretTarget(
187
187
  for (const detectedType of detectedTypes) {
188
188
  const normalizedType = normalizeIngressSecretTypeLabel(detectedType);
189
189
  const mapped = INGRESS_SECRET_TARGETS[normalizedType];
190
- if (!mapped) continue;
190
+ if (!mapped) {continue;}
191
191
  mappedTargets.set(`${mapped.service}:${mapped.field}`, mapped);
192
192
  }
193
- if (mappedTargets.size === 1) return mappedTargets.values().next().value!;
193
+ if (mappedTargets.size === 1) {return mappedTargets.values().next().value!;}
194
194
 
195
195
  return {
196
196
  service: "detected",
@@ -275,7 +275,7 @@ function computeReferenceImageDimensions(
275
275
  mediaType: string,
276
276
  ): { width: number; height: number } | null {
277
277
  const bytes = getAttachmentContent(attachmentId);
278
- if (!bytes) return null;
278
+ if (!bytes) {return null;}
279
279
  const optimized = optimizeImageForTransport(
280
280
  bytes.toString("base64"),
281
281
  mediaType,
@@ -330,7 +330,7 @@ function materializeUserAttachment(
330
330
  );
331
331
  return stored ? { kind: "stored", stored } : { kind: "transient" };
332
332
  }
333
- if (!a.data) return { kind: "rejected" };
333
+ if (!a.data) {return { kind: "rejected" };}
334
334
  const validation = validateAttachmentUpload(a.filename, a.mimeType);
335
335
  if (!validation.ok) {
336
336
  log.warn(
@@ -395,7 +395,7 @@ function referenceBlockForAttachment(
395
395
  function inlineBlockForAttachment(
396
396
  a: MessageAttachmentInput,
397
397
  ): ContentBlock | null {
398
- if (!a.data) return null;
398
+ if (!a.data) {return null;}
399
399
  return attachmentsToContentBlocks([a])[0] ?? null;
400
400
  }
401
401
 
@@ -431,7 +431,7 @@ function prepareUserAttachmentReferences(
431
431
  });
432
432
  continue;
433
433
  }
434
- if (outcome.kind === "rejected") continue;
434
+ if (outcome.kind === "rejected") {continue;}
435
435
  // transient: keep the upload by inlining its bytes (dropped only when the
436
436
  // recoverable failure left us with no bytes to inline).
437
437
  const inline = inlineBlockForAttachment(a);
@@ -450,24 +450,24 @@ function prepareUserAttachmentReferences(
450
450
  function extractTurnChannelContext(
451
451
  metadata?: Record<string, unknown>,
452
452
  ): TurnChannelContext | null {
453
- if (!metadata) return null;
453
+ if (!metadata) {return null;}
454
454
  const userMessageChannel = parseChannelId(metadata.userMessageChannel);
455
455
  const assistantMessageChannel = parseChannelId(
456
456
  metadata.assistantMessageChannel,
457
457
  );
458
- if (!userMessageChannel || !assistantMessageChannel) return null;
458
+ if (!userMessageChannel || !assistantMessageChannel) {return null;}
459
459
  return { userMessageChannel, assistantMessageChannel };
460
460
  }
461
461
 
462
462
  function extractTurnInterfaceContext(
463
463
  metadata?: Record<string, unknown>,
464
464
  ): TurnInterfaceContext | null {
465
- if (!metadata) return null;
465
+ if (!metadata) {return null;}
466
466
  const userMessageInterface = parseInterfaceId(metadata.userMessageInterface);
467
467
  const assistantMessageInterface = parseInterfaceId(
468
468
  metadata.assistantMessageInterface,
469
469
  );
470
- if (!userMessageInterface || !assistantMessageInterface) return null;
470
+ if (!userMessageInterface || !assistantMessageInterface) {return null;}
471
471
  return { userMessageInterface, assistantMessageInterface };
472
472
  }
473
473
 
@@ -530,7 +530,7 @@ export function buildSlackMetaForPersistence(params: {
530
530
  export interface EnqueueMessageOptions {
531
531
  content: string;
532
532
  attachments?: UserMessageAttachment[];
533
- onEvent?: (msg: ServerMessage) => void;
533
+ onEvent?: (msg: AssistantEvent) => void;
534
534
  requestId?: string;
535
535
  activeSurfaceId?: string;
536
536
  currentPage?: string;
@@ -890,7 +890,7 @@ export async function persistQueuedMessageBody(
890
890
  // though the store anchor was lost, then persist the corrected content.
891
891
  let repairedBlocks: ContentBlock[] | null = null;
892
892
  preparedAttachments.forEach((p, idx) => {
893
- if (!p.link) return;
893
+ if (!p.link) {return;}
894
894
  try {
895
895
  const scopedAttachmentId = linkAttachmentToMessage(
896
896
  persistedUserMessage.id,
@@ -982,7 +982,7 @@ export function redirectToSecurePrompt(
982
982
  conversationId,
983
983
  )
984
984
  .then(async (result): Promise<void> => {
985
- if (!result.value) return;
985
+ if (!result.value) {return;}
986
986
 
987
987
  const { setSecureKeyAsync } = await import("../security/secure-keys.js");
988
988
  const { upsertCredentialMetadata } =
@@ -8,6 +8,7 @@
8
8
  */
9
9
 
10
10
  import { createAssistantMessage } from "../agent/message-types.js";
11
+ import type { AssistantEvent } from "../api/index.js";
11
12
  import { buildCallCompletionMessage } from "../calls/call-conversation-messages.js";
12
13
  import {
13
14
  registerCallCompletionNotifier,
@@ -23,7 +24,6 @@ import {
23
24
  provenanceFromTrustContext,
24
25
  } from "../persistence/conversation-crud.js";
25
26
  import type { Message } from "../providers/types.js";
26
- import type { ServerMessage } from "./message-protocol.js";
27
27
  import type { TrustContext } from "./trust-context-types.js";
28
28
 
29
29
  /**
@@ -31,7 +31,7 @@ import type { TrustContext } from "./trust-context-types.js";
31
31
  * invocation time. Properties are read lazily from this reference.
32
32
  */
33
33
  export interface NotifierConversationContext {
34
- sendToClient: (msg: ServerMessage) => void;
34
+ sendToClient: (msg: AssistantEvent) => void;
35
35
  messages: Message[];
36
36
  trustContext?: TrustContext;
37
37
  }