@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
@@ -11,6 +11,7 @@ import {
11
11
  createAssistantMessage,
12
12
  createUserMessage,
13
13
  } from "../agent/message-types.js";
14
+ import type { AssistantEvent } from "../api/index.js";
14
15
  import { listPendingRequestsByScopeOrEmpty } from "../channels/gateway-guardian-requests.js";
15
16
  import {
16
17
  parseChannelId,
@@ -56,10 +57,7 @@ import {
56
57
  } from "./conversation-slash.js";
57
58
  import { getModelInfo } from "./handlers/config-model.js";
58
59
  import { preactivateHostProxySkills } from "./host-proxy-preactivation.js";
59
- import type {
60
- ServerMessage,
61
- UserMessageAttachment,
62
- } from "./message-protocol.js";
60
+ import type { UserMessageAttachment } from "./message-protocol.js";
63
61
  import { buildTransportHints } from "./transport-hints.js";
64
62
  import { resolveVerificationSessionIntent } from "./verification-session-intent.js";
65
63
 
@@ -192,7 +190,7 @@ export function formatCleanResult(result: CleanResult): string {
192
190
  /** Build a model_info event with fresh config data. */
193
191
  export async function buildModelInfoEvent(
194
192
  conversationId?: string,
195
- ): Promise<ServerMessage> {
193
+ ): Promise<AssistantEvent> {
196
194
  return { type: "model_info", conversationId, ...(await getModelInfo()) };
197
195
  }
198
196
 
@@ -438,13 +436,15 @@ function repairPendingToolUseBlocks(conversation: Conversation): void {
438
436
 
439
437
  /**
440
438
  * Restore drained messages to the front of the queue, in their original
441
- * order, when another turn (e.g. a barged-in voice turn woken by the idle
442
- * transition) owns the processing lock. The lock holder's own finally block
443
- * re-drains the queue. A steered drain also re-arms `pendingSteerRepair` so
444
- * the re-drain promotes the steered head on its own instead of batching it
445
- * with tails; the tool-use repair it re-triggers is idempotent.
439
+ * order, when the drain cannot run them: another turn (e.g. a barged-in
440
+ * voice turn woken by the idle transition) owns the processing lock, or the
441
+ * dispatch threw before the turn took over. The next drain trigger (the lock
442
+ * holder's own finally block, or `kickQueueDrain`'s retry) picks them back
443
+ * up. A steered drain also re-arms `pendingSteerRepair` so the re-drain
444
+ * promotes the steered head on its own instead of batching it with tails;
445
+ * the tool-use repair it re-triggers is idempotent.
446
446
  */
447
- function requeueOnLockContention(
447
+ function requeueDrainedMessages(
448
448
  conversation: Conversation,
449
449
  messages: QueuedMessage[],
450
450
  steered: boolean,
@@ -493,7 +493,9 @@ export async function drainQueue(
493
493
  if (!next) {
494
494
  return;
495
495
  }
496
- return drainSingleMessage(conversation, next, reason, true);
496
+ return dispatchDrainWithRestore(conversation, [next], true, () =>
497
+ drainSingleMessage(conversation, next, reason, true),
498
+ );
497
499
  }
498
500
 
499
501
  const batch = await buildPassthroughBatch(conversation);
@@ -505,12 +507,122 @@ export async function drainQueue(
505
507
  if (!next) {
506
508
  return;
507
509
  }
508
- return drainSingleMessage(conversation, next, reason);
510
+ return dispatchDrainWithRestore(conversation, [next], false, () =>
511
+ drainSingleMessage(conversation, next, reason),
512
+ );
509
513
  }
510
514
  if (batch.length === 1) {
511
- return drainSingleMessage(conversation, batch[0], reason);
515
+ return dispatchDrainWithRestore(conversation, batch, false, () =>
516
+ drainSingleMessage(conversation, batch[0], reason),
517
+ );
518
+ }
519
+ return dispatchDrainWithRestore(conversation, batch, false, () =>
520
+ drainBatch(conversation, batch, reason),
521
+ );
522
+ }
523
+
524
+ /**
525
+ * Errors that already triggered a queue restore on their way up. Drains
526
+ * recurse (a dropped message's error path re-drains the remaining queue), so
527
+ * without the marker an inner dispatch failure would also restore the outer
528
+ * dispatch's messages — resurrecting a message whose sender was already told
529
+ * it failed.
530
+ */
531
+ const restoredDrainErrors = new WeakSet<object>();
532
+
533
+ /**
534
+ * Run a drain dispatch whose messages are already removed from the queue,
535
+ * restoring them to the front if the dispatch throws. `drainQueue` pops
536
+ * messages before the throw-prone turn-start steps (slash resolution,
537
+ * per-turn context application), so without the restore a retry would skip
538
+ * the failed message entirely: it drains the NEXT item, succeeds, and the
539
+ * removed message is silently lost with no `queue_drain_failed` event.
540
+ */
541
+ async function dispatchDrainWithRestore(
542
+ conversation: Conversation,
543
+ messages: QueuedMessage[],
544
+ steered: boolean,
545
+ dispatch: () => Promise<void>,
546
+ ): Promise<void> {
547
+ try {
548
+ return await dispatch();
549
+ } catch (err) {
550
+ const alreadyRestored =
551
+ typeof err === "object" && err !== null && restoredDrainErrors.has(err);
552
+ if (!alreadyRestored) {
553
+ if (typeof err === "object" && err !== null) {
554
+ restoredDrainErrors.add(err);
555
+ }
556
+ requeueDrainedMessages(
557
+ conversation,
558
+ messages,
559
+ steered,
560
+ "Requeueing drained messages: drain dispatch threw",
561
+ );
562
+ }
563
+ throw err;
564
+ }
565
+ }
566
+
567
+ /**
568
+ * Fire-and-forget entry point for drain triggers that sit outside the drain
569
+ * promise chain (the agent loop's `finally`, route handlers releasing the
570
+ * processing lock). `drainQueue` is async — batch building awaits slash
571
+ * resolution and can throw — and nothing re-triggers a drain whose promise
572
+ * rejects: the queued messages would sit stranded until an unrelated later
573
+ * turn completes. This wrapper never rejects. A failed drain is retried
574
+ * once — `dispatchDrainWithRestore` has already returned any popped
575
+ * messages to the queue head, so the retry retries the same messages. If
576
+ * the retry also fails, every queued sender is notified so the stall is
577
+ * visible to the user instead of silent, and the messages remain queued
578
+ * for the next drain trigger.
579
+ *
580
+ * `origin` names the triggering site for log correlation.
581
+ */
582
+ export async function kickQueueDrain(
583
+ conversation: Conversation,
584
+ reason: QueueDrainReason = "loop_complete",
585
+ origin?: string,
586
+ ): Promise<void> {
587
+ try {
588
+ await drainQueue(conversation, reason);
589
+ return;
590
+ } catch (err) {
591
+ log.error(
592
+ {
593
+ err,
594
+ conversationId: conversation.conversationId,
595
+ reason,
596
+ origin,
597
+ queueDepth: conversation.queue.length,
598
+ },
599
+ "drainQueue rejected; retrying once",
600
+ );
601
+ }
602
+ try {
603
+ await drainQueue(conversation, reason);
604
+ } catch (err) {
605
+ log.error(
606
+ {
607
+ err,
608
+ conversationId: conversation.conversationId,
609
+ reason,
610
+ origin,
611
+ queueDepth: conversation.queue.length,
612
+ },
613
+ "drainQueue retry rejected; queued messages remain stranded until the next drain trigger",
614
+ );
615
+ for (const queued of conversation.queue.snapshot()) {
616
+ queued.onEvent({
617
+ type: "error",
618
+ conversationId: conversation.conversationId,
619
+ requestId: queued.requestId,
620
+ message:
621
+ "The assistant couldn't start your queued message due to an internal error. The message is still queued and will be retried after the next reply; you can also cancel and resend it.",
622
+ category: "queue_drain_failed",
623
+ });
624
+ }
512
625
  }
513
- return drainBatch(conversation, batch, reason);
514
626
  }
515
627
 
516
628
  async function drainSingleMessage(
@@ -526,7 +638,7 @@ async function drainSingleMessage(
526
638
  // requeue below stays as the TOCTOU backstop for a lock taken after
527
639
  // this check.
528
640
  if (conversation.isProcessing()) {
529
- requeueOnLockContention(
641
+ requeueDrainedMessages(
530
642
  conversation,
531
643
  [next],
532
644
  steered,
@@ -952,7 +1064,7 @@ async function drainSingleMessage(
952
1064
  // Another turn took the lock between this drain's dequeue and its
953
1065
  // persist. The message is still valid — requeue it at the front and
954
1066
  // stop; the lock holder's own finally re-drains the queue.
955
- requeueOnLockContention(
1067
+ requeueDrainedMessages(
956
1068
  conversation,
957
1069
  [next],
958
1070
  steered,
@@ -1110,7 +1222,7 @@ async function drainBatch(
1110
1222
  // The head persist-busy requeue below stays as the TOCTOU backstop.
1111
1223
  // Steered drains never batch, so there is no steer promotion to restore.
1112
1224
  if (conversation.isProcessing()) {
1113
- requeueOnLockContention(
1225
+ requeueDrainedMessages(
1114
1226
  conversation,
1115
1227
  batch,
1116
1228
  false,
@@ -1329,7 +1441,7 @@ async function drainBatch(
1329
1441
  // whole batch is still valid — requeue it at the front in order
1330
1442
  // and stop; the lock holder's finally re-drains the queue.
1331
1443
  conversation.preactivatedSkillIds = undefined;
1332
- requeueOnLockContention(
1444
+ requeueDrainedMessages(
1333
1445
  conversation,
1334
1446
  batch,
1335
1447
  false,
@@ -1503,7 +1615,7 @@ async function drainBatch(
1503
1615
  const successfulEventSinks = Array.from(
1504
1616
  new Set(successfulBatch.map((qm) => qm.onEvent)),
1505
1617
  );
1506
- const fanOutOnEvent = (msg: ServerMessage) => {
1618
+ const fanOutOnEvent = (msg: AssistantEvent) => {
1507
1619
  for (const onEvent of successfulEventSinks) {
1508
1620
  onEvent(msg);
1509
1621
  }
@@ -1567,7 +1679,7 @@ async function drainBatch(
1567
1679
  export interface ProcessMessageOptions {
1568
1680
  content: string;
1569
1681
  attachments: UserMessageAttachment[];
1570
- onEvent?: (msg: ServerMessage) => void;
1682
+ onEvent?: (msg: AssistantEvent) => void;
1571
1683
  requestId?: string;
1572
1684
  activeSurfaceId?: string;
1573
1685
  currentPage?: string;
@@ -5,6 +5,7 @@
5
5
  * agent loop is in flight.
6
6
  */
7
7
 
8
+ import type { AssistantEvent } from "../api/index.js";
8
9
  import type {
9
10
  TurnChannelContext,
10
11
  TurnInterfaceContext,
@@ -12,7 +13,6 @@ import type {
12
13
  import type { AuthContext } from "../runtime/auth/types.js";
13
14
  import { getLogger } from "../util/logger.js";
14
15
  import type {
15
- ServerMessage,
16
16
  UserMessageAttachment,
17
17
  } from "./message-protocol.js";
18
18
  import type { ConversationTransportMetadata } from "./message-types/conversations.js";
@@ -23,7 +23,7 @@ export interface QueuedMessage {
23
23
  content: string;
24
24
  attachments: UserMessageAttachment[];
25
25
  requestId: string;
26
- onEvent: (msg: ServerMessage) => void;
26
+ onEvent: (msg: AssistantEvent) => void;
27
27
  activeSurfaceId?: string;
28
28
  currentPage?: string;
29
29
  metadata?: Record<string, unknown>;
@@ -156,7 +156,7 @@ export class MessageQueue {
156
156
  */
157
157
  shiftN(count: number): QueuedMessage[] {
158
158
  const n = Math.min(Math.max(0, count), this.items.length);
159
- if (n === 0) return [];
159
+ if (n === 0) {return [];}
160
160
  const removed = this.items.splice(0, n);
161
161
  for (const item of removed) {
162
162
  this.currentBytes -= estimateItemBytes(item);
@@ -188,8 +188,8 @@ export class MessageQueue {
188
188
  */
189
189
  promoteToHead(requestId: string): QueuedMessage | undefined {
190
190
  const idx = this.items.findIndex((m) => m.requestId === requestId);
191
- if (idx === -1) return undefined;
192
- if (idx === 0) return this.items[0]; // already at head
191
+ if (idx === -1) {return undefined;}
192
+ if (idx === 0) {return this.items[0];} // already at head
193
193
  const [promoted] = this.items.splice(idx, 1);
194
194
  this.items.unshift(promoted);
195
195
  return promoted;
@@ -201,7 +201,7 @@ export class MessageQueue {
201
201
  */
202
202
  removeByRequestId(requestId: string): QueuedMessage | undefined {
203
203
  const idx = this.items.findIndex((m) => m.requestId === requestId);
204
- if (idx === -1) return undefined;
204
+ if (idx === -1) {return undefined;}
205
205
  const [removed] = this.items.splice(idx, 1);
206
206
  this.currentBytes -= estimateItemBytes(removed);
207
207
  return removed;
@@ -220,7 +220,7 @@ function estimateItemBytes(item: QueuedMessage): number {
220
220
  let bytes = item.content.length * 2; // JS strings are UTF-16
221
221
  for (const a of item.attachments) {
222
222
  bytes += a.data.length * 2;
223
- if (a.extractedText) bytes += a.extractedText.length * 2;
223
+ if (a.extractedText) {bytes += a.extractedText.length * 2;}
224
224
  }
225
225
  // Include transport metadata in the estimate so large transport
226
226
  // payloads (e.g. hostHomeDir, hostUsername) count against the budget.
@@ -74,6 +74,7 @@ import { resolveCapabilities } from "../runtime/capabilities.js";
74
74
  import type { SubagentState } from "../subagent/types.js";
75
75
  import { TERMINAL_STATUSES } from "../subagent/types.js";
76
76
  import { canonicalizeInboundIdentity } from "../util/canonicalize-identity.js";
77
+ import { channelSupportsInlineOptions } from "./channel-ui-capability.js";
77
78
  import { findConversationOrSubagent } from "./conversation-registry.js";
78
79
  import type { SurfaceShowPair } from "./conversation-surfaces.js";
79
80
  import { canonicalizeTimeZone, formatTurnTimestamp } from "./date-context.js";
@@ -97,6 +98,13 @@ export interface ChannelCapabilities {
97
98
  dashboardCapable: boolean;
98
99
  /** Whether the channel supports dynamic UI surfaces (ui_show / ui_update). */
99
100
  supportsDynamicUi: boolean;
101
+ /**
102
+ * Whether the channel's adapter can render inline tappable options — approval
103
+ * buttons and (next) question option pickers. Distinct from `supportsDynamicUi`:
104
+ * a text-only channel can render inline buttons without dynamic UI. Optional;
105
+ * absent is treated as `false`.
106
+ */
107
+ supportsInlineOptions?: boolean;
100
108
  /** Whether the channel supports voice/microphone input. */
101
109
  supportsVoiceInput: boolean;
102
110
  /** The client OS/interface identifier (e.g. "macos", "ios", "web"). */
@@ -282,6 +290,7 @@ export function resolveChannelCapabilities(
282
290
  channel,
283
291
  dashboardCapable: supportsDesktopUi,
284
292
  supportsDynamicUi: supportsDesktopUi || iface === "web",
293
+ supportsInlineOptions: channelSupportsInlineOptions(channel),
285
294
  supportsVoiceInput: supportsDesktopUi,
286
295
  clientOS: iface ?? undefined,
287
296
  chatType: resolvedChatType,
@@ -296,6 +305,7 @@ export function resolveChannelCapabilities(
296
305
  channel,
297
306
  dashboardCapable: false,
298
307
  supportsDynamicUi: false,
308
+ supportsInlineOptions: channelSupportsInlineOptions(channel),
299
309
  supportsVoiceInput: false,
300
310
  chatType: resolvedChatType,
301
311
  };
@@ -304,6 +314,7 @@ export function resolveChannelCapabilities(
304
314
  channel,
305
315
  dashboardCapable: false,
306
316
  supportsDynamicUi: false,
317
+ supportsInlineOptions: channelSupportsInlineOptions(channel),
307
318
  supportsVoiceInput: false,
308
319
  chatType: resolvedChatType,
309
320
  };
@@ -974,6 +985,11 @@ function placeholderForBlockType(type: ContentBlock["type"]): string | null {
974
985
  case "tool_result":
975
986
  case "web_search_tool_result":
976
987
  return "[tool result]";
988
+ // Surfaces normally ride with a `_surfaceFallback` text sibling that
989
+ // supplies the line, so this label is reached only by legacy rows that
990
+ // carry a bare card — better than rendering an empty transcript line.
991
+ case "ui_surface":
992
+ return "[card]";
977
993
  case "thinking":
978
994
  case "redacted_thinking":
979
995
  case "text":
@@ -118,6 +118,9 @@ export async function getOrCreateConversation(
118
118
  (conversation.isStale() && !conversation.isProcessing())
119
119
  ) {
120
120
  if (conversation) {
121
+ // Stale rebuild: the conversation id lives on, so abort in-flight
122
+ // children but keep terminal subagent results readable for the
123
+ // retention window.
121
124
  getSubagentManager().abortAllForParent(conversationId);
122
125
  conversation.dispose();
123
126
  }
@@ -247,12 +250,15 @@ export async function getOrCreateConversation(
247
250
  * deleted conversation and trip FK constraints.
248
251
  */
249
252
  export function destroyActiveConversation(conversationId: string): void {
253
+ // Subagent teardown is keyed by parent id, not the live instance — an
254
+ // evicted parent still retains its terminal children, and deleting the
255
+ // conversation must take their records with it.
256
+ getSubagentManager().disposeAllForParent(conversationId);
250
257
  const conversation = findConversation(conversationId);
251
258
  if (!conversation) {
252
259
  return;
253
260
  }
254
261
  removeFromEvictor(conversationId);
255
- getSubagentManager().abortAllForParent(conversationId);
256
262
  conversation.dispose();
257
263
  deleteConversation(conversationId);
258
264
  deleteConversationOptions(conversationId);
@@ -277,10 +283,12 @@ export function stopConversations(): void {
277
283
  */
278
284
  export function clearAllActiveConversations(): number {
279
285
  const count = conversationCount();
280
- const subagentManager = getSubagentManager();
286
+ // Dispose subagents across ALL parents, not just the in-memory ones — an
287
+ // evicted parent still retains its terminal children, and clear-all must
288
+ // take their records with it.
289
+ getSubagentManager().disposeAllForAllParents();
281
290
  for (const id of conversationIds()) {
282
291
  removeFromEvictor(id);
283
- subagentManager.abortAllForParent(id);
284
292
  }
285
293
  for (const conversation of allConversations()) {
286
294
  conversation.dispose();
@@ -2,6 +2,7 @@ import { v4 as uuid, v7 as uuidv7 } from "uuid";
2
2
  import { z } from "zod";
3
3
 
4
4
  import { SurfaceActionSchema } from "../api/events/ui-surface-show.js";
5
+ import type { AssistantEvent } from "../api/index.js";
5
6
  import {
6
7
  CardSurfaceDataSchema,
7
8
  ChoiceSurfaceDataSchema,
@@ -76,7 +77,6 @@ import type {
76
77
  DynamicPagePreview,
77
78
  DynamicPageSurfaceData,
78
79
  FormSurfaceData,
79
- ServerMessage,
80
80
  SurfaceAction,
81
81
  SurfaceData,
82
82
  SurfaceType,
@@ -818,7 +818,7 @@ export interface SurfaceConversationContext {
818
818
  channel: string;
819
819
  supportsDynamicUi: boolean;
820
820
  };
821
- sendToClient(msg: ServerMessage): void;
821
+ sendToClient(msg: AssistantEvent): void;
822
822
  pendingSurfaceActions: Map<string, { surfaceType: SurfaceType }>;
823
823
  lastSurfaceAction: Map<
824
824
  string,
@@ -2001,7 +2001,7 @@ export async function handleSurfaceAction(
2001
2001
  // Pass conversationId so events without an inline conversationId (e.g.
2002
2002
  // text_delta) are published with the correct conversation scope and
2003
2003
  // reach the SSE subscriber filtered to this conversation.
2004
- const onEvent = (msg: ServerMessage) =>
2004
+ const onEvent = (msg: AssistantEvent) =>
2005
2005
  broadcastMessage(msg, ctx.conversationId);
2006
2006
 
2007
2007
  const result = ctx.enqueueMessage({
@@ -2228,7 +2228,7 @@ export async function handleSurfaceAction(
2228
2228
  // Pass conversationId so events without an inline conversationId (e.g.
2229
2229
  // text_delta) are published with the correct conversation scope and
2230
2230
  // reach the SSE subscriber filtered to this conversation.
2231
- const onEvent = (msg: ServerMessage) =>
2231
+ const onEvent = (msg: AssistantEvent) =>
2232
2232
  broadcastMessage(msg, ctx.conversationId);
2233
2233
 
2234
2234
  log.info(
@@ -6,12 +6,14 @@
6
6
  * keeping the constructor body focused on wiring.
7
7
  */
8
8
 
9
+ import type { AssistantEvent } from "../api/index.js";
9
10
  import {
10
11
  type HostProxyCapability,
11
12
  supportsHostProxy,
12
13
  } from "../channels/types.js";
13
14
  import { getIsPlatform } from "../config/env-registry.js";
14
15
  import { getConfig } from "../config/loader.js";
16
+ import { isMemoryEnabled } from "../config/memory-v3-gate.js";
15
17
  import type { PermissionPrompter } from "../permissions/prompter.js";
16
18
  import type { SecretPrompter } from "../permissions/secret-prompter.js";
17
19
  import { getBindingByConversation } from "../persistence/external-conversation-store.js";
@@ -62,7 +64,10 @@ import {
62
64
  type UsageAttributionSnapshot,
63
65
  } from "../usage/attribution.js";
64
66
  import { getLogger } from "../util/logger.js";
65
- import { conversationSupportsDynamicUi } from "./channel-ui-capability.js";
67
+ import {
68
+ conversationSupportsDynamicUi,
69
+ conversationSupportsGuardianQuestionCards,
70
+ } from "./channel-ui-capability.js";
66
71
  import type { Conversation } from "./conversation.js";
67
72
  import { projectSkillTools } from "./conversation-skill-tools.js";
68
73
  import {
@@ -73,7 +78,6 @@ import {
73
78
  isDoordashCommand,
74
79
  markDoordashStepInProgress,
75
80
  } from "./doordash-steps.js";
76
- import type { ServerMessage } from "./message-protocol.js";
77
81
  import { runPostExecutionSideEffects } from "./tool-side-effects.js";
78
82
  import { FALLBACK_TURN_TRUST, resolveTrustClass } from "./trust-context.js";
79
83
 
@@ -176,8 +180,8 @@ export function getEffectiveEnabledPluginSet(conv: {
176
180
  // ── read-only pass classification ────────────────────────────────────
177
181
 
178
182
  /**
179
- * The ONLY tools allowed in a read-only subagent pass (the live-voice background
180
- * continuation, `subagentDenySideEffects`). This is a strict fail-safe allowlist
183
+ * The ONLY tools allowed in a read-only subagent pass
184
+ * (`subagentDenySideEffects`). This is a strict fail-safe allowlist
181
185
  * of tools known to be read-only. Everything else is refused, because:
182
186
  * - A side-effect denylist is inherently incomplete — low-risk core mutators
183
187
  * (`remember`, `notify_parent`, `computer_use_*`, `delete_memory_page`, …) are
@@ -391,8 +395,8 @@ export function createToolExecutor(
391
395
  enabledPluginSet: effectiveEnabledPluginSet,
392
396
  sendToClient: (msg) => {
393
397
  // Tool context's sendToClient uses a loose { type: string; [key: string]: unknown }
394
- // signature, but at runtime these are always ServerMessage instances.
395
- ctx.sendToClient(msg as ServerMessage);
398
+ // signature, but at runtime these are always AssistantEvent instances.
399
+ ctx.sendToClient(msg as AssistantEvent);
396
400
  if (msg.type === "ui_surface_show") {
397
401
  // The tool-context sendToClient signature is loose, so the show
398
402
  // message's fields are untyped here; map them through the same
@@ -423,6 +427,8 @@ export function createToolExecutor(
423
427
  // channels that can't render dynamic surfaces (Telegram, SMS) instead of
424
428
  // emitting one the channel silently drops.
425
429
  supportsDynamicUi: conversationSupportsDynamicUi(ctx),
430
+ supportsGuardianQuestionCards:
431
+ conversationSupportsGuardianQuestionCards(ctx),
426
432
  proxyToolResolver: (
427
433
  toolName: string,
428
434
  proxyInput: Record<string, unknown>,
@@ -717,7 +723,7 @@ export function isToolActiveForContext(
717
723
  }
718
724
  if (name === "remember") {
719
725
  try {
720
- return getConfig().memory?.enabled !== false;
726
+ return isMemoryEnabled(getConfig());
721
727
  } catch {
722
728
  return true;
723
729
  }
@@ -1,3 +1,4 @@
1
+ import type { AssistantEvent } from "../api/index.js";
1
2
  import { getConfig } from "../config/loader.js";
2
3
  import { updateConversationUsage } from "../persistence/conversation-crud.js";
3
4
  import { recordUsageEvent } from "../persistence/llm-usage-store.js";
@@ -16,7 +17,7 @@ import {
16
17
  resolvePricingForUsageWithOverrides,
17
18
  usesAnthropicPricingRules,
18
19
  } from "../util/pricing.js";
19
- import type { ServerMessage, UsageStats } from "./message-protocol.js";
20
+ import type { UsageStats } from "./message-protocol.js";
20
21
 
21
22
  const log = getLogger("conversation-usage");
22
23
 
@@ -27,12 +28,12 @@ export interface UsageContext {
27
28
  }
28
29
 
29
30
  function normalizeTokenCount(value: number | null | undefined): number {
30
- if (typeof value !== "number" || !Number.isFinite(value)) return 0;
31
+ if (typeof value !== "number" || !Number.isFinite(value)) {return 0;}
31
32
  return Math.max(value, 0);
32
33
  }
33
34
 
34
35
  function asRecord(value: unknown): Record<string, unknown> | null {
35
- if (typeof value !== "object" || value == null) return null;
36
+ if (typeof value !== "object" || value == null) {return null;}
36
37
  return value as Record<string, unknown>;
37
38
  }
38
39
 
@@ -42,7 +43,7 @@ function extractAnthropicCacheCreationFromResponse(
42
43
  const rawResponse = asRecord(response);
43
44
  const usage = asRecord(rawResponse?.usage);
44
45
  const cacheCreation = asRecord(usage?.cache_creation);
45
- if (!cacheCreation) return null;
46
+ if (!cacheCreation) {return null;}
46
47
 
47
48
  return {
48
49
  ephemeral_5m_input_tokens: normalizeTokenCount(
@@ -64,7 +65,7 @@ function extractAnthropicCacheCreation(
64
65
 
65
66
  for (const response of responses) {
66
67
  const details = extractAnthropicCacheCreationFromResponse(response);
67
- if (!details) continue;
68
+ if (!details) {continue;}
68
69
  foundDetails = true;
69
70
  ephemeral5mInputTokens += normalizeTokenCount(
70
71
  details.ephemeral_5m_input_tokens,
@@ -74,7 +75,7 @@ function extractAnthropicCacheCreation(
74
75
  );
75
76
  }
76
77
 
77
- if (!foundDetails) return null;
78
+ if (!foundDetails) {return null;}
78
79
 
79
80
  return {
80
81
  ephemeral_5m_input_tokens: ephemeral5mInputTokens,
@@ -96,8 +97,8 @@ function extractAnthropicSpeed(
96
97
  for (const response of responses) {
97
98
  const rec = asRecord(response);
98
99
  const usage = asRecord(rec?.usage);
99
- if (usage?.speed === "fast") return "fast";
100
- if (usage?.speed === "standard") foundStandard = true;
100
+ if (usage?.speed === "fast") {return "fast";}
101
+ if (usage?.speed === "standard") {foundStandard = true;}
101
102
  }
102
103
  return foundStandard ? "standard" : null;
103
104
  }
@@ -143,7 +144,7 @@ function resolveAttribution(
143
144
  | null
144
145
  | undefined,
145
146
  ): UsageAttributionSnapshot | null {
146
- if (attribution == null) return null;
147
+ if (attribution == null) {return null;}
147
148
  return isUsageAttributionSnapshot(attribution)
148
149
  ? attribution
149
150
  : resolveUsageAttribution(attribution);
@@ -154,7 +155,7 @@ export function recordUsage(
154
155
  inputTokens: number,
155
156
  outputTokens: number,
156
157
  model: string,
157
- onEvent: (msg: ServerMessage) => void,
158
+ onEvent: (msg: AssistantEvent) => void,
158
159
  actor: UsageActor,
159
160
  requestId: string | null = null,
160
161
  cacheCreationInputTokens = 0,
@@ -165,7 +166,7 @@ export function recordUsage(
165
166
  attribution?: UsageAttributionInput | UsageAttributionSnapshot | null,
166
167
  cronRunId: string | null = null,
167
168
  ): void {
168
- if (inputTokens <= 0 && outputTokens <= 0) return;
169
+ if (inputTokens <= 0 && outputTokens <= 0) {return;}
169
170
 
170
171
  const normalizedCacheCreationInputTokens = normalizeTokenCount(
171
172
  cacheCreationInputTokens,