@vellumai/assistant 0.10.12 → 0.11.0-staging.2

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 (809) 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 +264 -14
  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__/app-conversation-ids-backfill.test.ts +33 -2
  39. package/src/__tests__/app-conversation-ids.test.ts +204 -0
  40. package/src/__tests__/approval-cascade.test.ts +5 -5
  41. package/src/__tests__/approval-routes-http.test.ts +3 -3
  42. package/src/__tests__/ask-question-resolver.test.ts +207 -0
  43. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +16 -16
  44. package/src/__tests__/assistant-event-hub-targeted.test.ts +13 -11
  45. package/src/__tests__/assistant-event-hub.test.ts +13 -11
  46. package/src/__tests__/assistant-event.test.ts +12 -9
  47. package/src/__tests__/assistant-feature-flag-guard.test.ts +3 -3
  48. package/src/__tests__/assistant-feature-flag-guardrails.test.ts +1 -1
  49. package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -58
  50. package/src/__tests__/assistant-stream-state.test.ts +17 -7
  51. package/src/__tests__/avatar-identity-sync.test.ts +3 -3
  52. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -0
  53. package/src/__tests__/call-conversation-messages.test.ts +134 -18
  54. package/src/__tests__/call-start-guardian-guard.test.ts +27 -0
  55. package/src/__tests__/channel-approvals.test.ts +0 -27
  56. package/src/__tests__/channel-guardian.test.ts +85 -512
  57. package/src/__tests__/channel-readiness-slack-remote.test.ts +151 -3
  58. package/src/__tests__/channel-retry-sweep.test.ts +88 -1
  59. package/src/__tests__/channel-setup-panel-ack.test.ts +12 -9
  60. package/src/__tests__/chat-reveal-guard-priming.test.ts +31 -34
  61. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +2 -2
  62. package/src/__tests__/compaction-events.test.ts +8 -8
  63. package/src/__tests__/config-loader-platform-defaults.test.ts +54 -28
  64. package/src/__tests__/config-model-image-provider.test.ts +20 -0
  65. package/src/__tests__/config-schema-memory-substrate.test.ts +306 -0
  66. package/src/__tests__/config-schema.test.ts +14 -2
  67. package/src/__tests__/config-set-platform-guard.test.ts +11 -12
  68. package/src/__tests__/config-sounds-sync.test.ts +4 -4
  69. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +5 -0
  70. package/src/__tests__/context-search-memory-source.test.ts +1 -1
  71. package/src/__tests__/context-search-memory-v2-source.test.ts +6 -6
  72. package/src/__tests__/context-token-estimator.test.ts +54 -1
  73. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +12 -3
  74. package/src/__tests__/conversation-agent-loop-fatal-cleanup.test.ts +13 -4
  75. package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +4 -4
  76. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -1
  77. package/src/__tests__/conversation-agent-loop-overflow.test.ts +22 -13
  78. package/src/__tests__/conversation-agent-loop.test.ts +39 -30
  79. package/src/__tests__/conversation-confirmation-signals.test.ts +14 -14
  80. package/src/__tests__/conversation-evictor.test.ts +49 -0
  81. package/src/__tests__/conversation-fork-crud.test.ts +1 -1
  82. package/src/__tests__/conversation-group-tools.test.ts +279 -0
  83. package/src/__tests__/conversation-history-web-search.test.ts +1 -1
  84. package/src/__tests__/conversation-key-store-disk-view.test.ts +5 -5
  85. package/src/__tests__/conversation-lineage.test.ts +235 -0
  86. package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +5 -5
  87. package/src/__tests__/conversation-message-sync-tags.test.ts +4 -4
  88. package/src/__tests__/conversation-queue.test.ts +81 -81
  89. package/src/__tests__/conversation-routes-enabled-plugins.test.ts +8 -1
  90. package/src/__tests__/conversation-routes-hidden-queue.test.ts +8 -1
  91. package/src/__tests__/conversation-routes-slash-commands.test.ts +10 -1
  92. package/src/__tests__/conversation-runtime-assembly.test.ts +29 -2
  93. package/src/__tests__/conversation-slash-queue.test.ts +11 -11
  94. package/src/__tests__/conversation-slash-unknown.test.ts +2 -2
  95. package/src/__tests__/conversation-speed-override.test.ts +2 -2
  96. package/src/__tests__/conversation-summarize-route.test.ts +9 -0
  97. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +18 -16
  98. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +17 -17
  99. package/src/__tests__/conversation-surfaces-app-open.test.ts +7 -4
  100. package/src/__tests__/conversation-surfaces-data-persist.test.ts +7 -7
  101. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +9 -9
  102. package/src/__tests__/conversation-surfaces-standalone.test.ts +12 -12
  103. package/src/__tests__/conversation-surfaces-state-update.test.ts +8 -5
  104. package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -3
  105. package/src/__tests__/conversation-surfaces-task-progress.test.ts +46 -46
  106. package/src/__tests__/conversation-sync-tags.test.ts +5 -5
  107. package/src/__tests__/conversation-wait-for-idle.test.ts +2 -2
  108. package/src/__tests__/conversation-workspace-cache-state.test.ts +0 -4
  109. package/src/__tests__/conversation-workspace-injection.test.ts +0 -3
  110. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -3
  111. package/src/__tests__/copy-composer-tc-templates.test.ts +3 -131
  112. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  113. package/src/__tests__/daemon-assistant-events.test.ts +14 -15
  114. package/src/__tests__/db-test-helpers.ts +13 -27
  115. package/src/__tests__/disk-pressure-routes.test.ts +12 -3
  116. package/src/__tests__/document-tool-security.test.ts +95 -0
  117. package/src/__tests__/drain-kick-guard.test.ts +232 -0
  118. package/src/__tests__/dynamic-skill-background-guard.test.ts +19 -6
  119. package/src/__tests__/emit-event-signal.test.ts +5 -6
  120. package/src/__tests__/encrypted-store-test-helpers.ts +10 -20
  121. package/src/__tests__/events-tail-route.test.ts +6 -4
  122. package/src/__tests__/feature-flag-test-helpers.ts +10 -20
  123. package/src/__tests__/file-edit-tool.test.ts +24 -4
  124. package/src/__tests__/file-list-tool.test.ts +2 -1
  125. package/src/__tests__/file-read-tool.test.ts +62 -10
  126. package/src/__tests__/file-write-tool.test.ts +24 -5
  127. package/src/__tests__/followup-tools.test.ts +58 -0
  128. package/src/__tests__/gateway-threshold-reader-mock.ts +99 -0
  129. package/src/__tests__/graph-extraction-event-date.test.ts +1 -1
  130. package/src/__tests__/guardian-question-mode.test.ts +42 -3
  131. package/src/__tests__/guardian-reply-router-answer-mode.test.ts +283 -0
  132. package/src/__tests__/guardian-vellum-destination-pinning.test.ts +221 -0
  133. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  134. package/src/__tests__/heartbeat-service.test.ts +1 -0
  135. package/src/__tests__/helpers/native-web-search-harness.ts +10 -10
  136. package/src/__tests__/host-browser-proxy.test.ts +1 -1
  137. package/src/__tests__/host-file-edit-tool.test.ts +3 -3
  138. package/src/__tests__/host-file-read-tool.test.ts +2 -2
  139. package/src/__tests__/host-file-write-tool.test.ts +7 -3
  140. package/src/__tests__/host-shell-tool.test.ts +17 -5
  141. package/src/__tests__/host-transfer-pending-interactions.test.ts +8 -8
  142. package/src/__tests__/image-credentials.test.ts +65 -8
  143. package/src/__tests__/injection-block.test.ts +4 -4
  144. package/src/__tests__/injector-chain.test.ts +1 -1
  145. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  146. package/src/__tests__/injector-registry-order-guard.test.ts +4 -9
  147. package/src/__tests__/injector-v3-suppression.test.ts +6 -4
  148. package/src/__tests__/lifecycle-memory-v2-seed.test.ts +27 -28
  149. package/src/__tests__/list-messages-page-latest.test.ts +2 -2
  150. package/src/__tests__/llm-usage-store.test.ts +67 -4
  151. package/src/__tests__/log-redact.test.ts +18 -0
  152. package/src/__tests__/managed-profile-guard.test.ts +27 -0
  153. package/src/__tests__/managed-skill-lifecycle.test.ts +2 -2
  154. package/src/__tests__/media-generate-image.test.ts +62 -11
  155. package/src/__tests__/memory-identity-context-parity.test.ts +1 -1
  156. package/src/__tests__/memory-jobs-worker-lanes.test.ts +9 -1
  157. package/src/__tests__/memory-retrieval-hook.test.ts +4 -4
  158. package/src/__tests__/notification-decision-strategy.test.ts +115 -11
  159. package/src/__tests__/notification-deep-link.test.ts +12 -12
  160. package/src/__tests__/notification-vellum-adapter.test.ts +8 -8
  161. package/src/__tests__/outbound-slack-persistence.test.ts +8 -8
  162. package/src/__tests__/path-policy.test.ts +315 -0
  163. package/src/__tests__/pending-interactions-resolved-event.test.ts +6 -6
  164. package/src/__tests__/persistence-layering-guard.test.ts +2 -2
  165. package/src/__tests__/pkb-autoinject.test.ts +1 -1
  166. package/src/__tests__/platform-bash-auto-approve.test.ts +1 -0
  167. package/src/__tests__/platform-callback-registration.test.ts +10 -10
  168. package/src/__tests__/plugin-event-hub-facade.test.ts +22 -15
  169. package/src/__tests__/plugin-import-boundary-guard.test.ts +15 -15
  170. package/src/__tests__/processing-flag-persist-failure.test.ts +0 -4
  171. package/src/__tests__/provider-platform-proxy-integration.test.ts +0 -1
  172. package/src/__tests__/rebuild-index-graph-nodes.test.ts +1 -1
  173. package/src/__tests__/request-secret-standalone-channel-gate.test.ts +5 -5
  174. package/src/__tests__/require-fresh-approval.test.ts +38 -38
  175. package/src/__tests__/resolve-app-id.test.ts +32 -0
  176. package/src/__tests__/run-due-schedules.test.ts +72 -1
  177. package/src/__tests__/runtime-events-sse-parity.test.ts +11 -10
  178. package/src/__tests__/runtime-events-sse.test.ts +1 -1
  179. package/src/__tests__/schedule-routes.test.ts +44 -5
  180. package/src/__tests__/schedule-store.test.ts +3 -3
  181. package/src/__tests__/schedule-tools.test.ts +176 -0
  182. package/src/__tests__/secret-prompt-log-hygiene.test.ts +3 -3
  183. package/src/__tests__/secret-prompter-channel-fallback.test.ts +3 -3
  184. package/src/__tests__/secret-response-routing.test.ts +3 -3
  185. package/src/__tests__/secret-routes-platform-proxy.test.ts +4 -7
  186. package/src/__tests__/secret-scanner.test.ts +36 -0
  187. package/src/__tests__/send-endpoint-busy.test.ts +7 -7
  188. package/src/__tests__/slack-required-scopes-mirror.test.ts +81 -0
  189. package/src/__tests__/starter-task-flow.test.ts +26 -3
  190. package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
  191. package/src/__tests__/subagent-disposal.test.ts +40 -11
  192. package/src/__tests__/subagent-fork-notifications.test.ts +4 -4
  193. package/src/__tests__/subagent-fork-prompt-role.test.ts +3 -3
  194. package/src/__tests__/subagent-fork-spawn.test.ts +4 -4
  195. package/src/__tests__/subagent-manager-notify.test.ts +73 -14
  196. package/src/__tests__/subagent-notify-parent.test.ts +48 -4
  197. package/src/__tests__/subagent-spawn-and-await.test.ts +62 -14
  198. package/src/__tests__/subagent-tools.test.ts +64 -0
  199. package/src/__tests__/sync-message-contract.test.ts +3 -3
  200. package/src/__tests__/terminal-tools.test.ts +12 -3
  201. package/src/__tests__/test-preload.ts +9 -0
  202. package/src/__tests__/tool-approval-handler.test.ts +587 -43
  203. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +7 -4
  204. package/src/__tests__/tool-executor.test.ts +116 -0
  205. package/src/__tests__/tool-grant-request-escalation.test.ts +5 -0
  206. package/src/__tests__/tool-preview-lifecycle.test.ts +32 -29
  207. package/src/__tests__/tool-result-metadata-plumbing.test.ts +5 -5
  208. package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
  209. package/src/__tests__/tool-start-timestamp.test.ts +4 -4
  210. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -22
  211. package/src/__tests__/ui-choice-copy-surfaces.test.ts +13 -13
  212. package/src/__tests__/ui-work-result-surface.test.ts +3 -3
  213. package/src/__tests__/voice-scoped-grant-consumer.test.ts +6 -6
  214. package/src/__tests__/voice-session-bridge.test.ts +44 -44
  215. package/src/__tests__/workspace-migration-134-image-generation-mode-to-provider.test.ts +284 -0
  216. package/src/__tests__/workspace-policy.test.ts +482 -2
  217. package/src/acp/__tests__/client-handler.test.ts +3 -3
  218. package/src/acp/__tests__/session-manager-persistence.test.ts +10 -10
  219. package/src/acp/__tests__/session-manager-resume.test.ts +7 -7
  220. package/src/acp/client-handler.ts +3 -3
  221. package/src/acp/session-manager.ts +8 -8
  222. package/src/api/events/subagent-event.ts +2 -2
  223. package/src/api/responses/memory-v2-activation-log.ts +2 -2
  224. package/src/api/responses/subagent-detail.ts +13 -0
  225. package/src/approvals/AGENTS.md +2 -0
  226. package/src/approvals/guardian-request-resolvers.ts +118 -24
  227. package/src/apps/app-store.ts +95 -4
  228. package/src/calls/__tests__/voice-control-protocol.test.ts +57 -0
  229. package/src/calls/__tests__/voice-session-bridge.test.ts +229 -7
  230. package/src/calls/__tests__/voice-triage-escalate.test.ts +3 -4
  231. package/src/calls/call-controller.ts +27 -27
  232. package/src/calls/call-conversation-messages.ts +58 -18
  233. package/src/calls/voice-control-protocol.ts +56 -0
  234. package/src/calls/voice-session-bridge.ts +178 -65
  235. package/src/calls/voice-triage-escalate.ts +2 -3
  236. package/src/channels/config.ts +8 -0
  237. package/src/channels/types.ts +1 -0
  238. package/src/cli/commands/config.ts +49 -13
  239. package/src/cli/commands/memory/index.help.ts +4 -2
  240. package/src/cli/commands/memory/memory-retrospective.ts +5 -0
  241. package/src/cli/commands/webhooks.help.ts +9 -4
  242. package/src/cli/lib/bundled-marketplace.json +12 -0
  243. package/src/cli.ts +2 -109
  244. package/src/config/__tests__/deployment-context-defaults.test.ts +9 -0
  245. package/src/config/__tests__/substrate-twin-shadowing.test.ts +191 -0
  246. package/src/config/assistant-feature-flags.ts +1 -1
  247. package/src/config/bundled-skills/conversation-groups/SKILL.md +29 -0
  248. package/src/config/bundled-skills/conversation-groups/TOOLS.json +58 -0
  249. package/src/config/bundled-skills/conversation-groups/tools/group-create.ts +12 -0
  250. package/src/config/bundled-skills/conversation-groups/tools/group-list.ts +12 -0
  251. package/src/config/bundled-skills/conversation-groups/tools/move-to-group.ts +12 -0
  252. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +13 -7
  253. package/src/config/bundled-skills/schedule/SKILL.md +2 -0
  254. package/src/config/feature-flag-cache.ts +6 -16
  255. package/src/config/feature-flag-registry.json +14 -38
  256. package/src/config/loader.ts +7 -1
  257. package/src/config/memory-tier.ts +15 -10
  258. package/src/config/memory-v3-gate.test.ts +278 -1
  259. package/src/config/memory-v3-gate.ts +88 -26
  260. package/src/config/raw-config-utils.ts +1 -1
  261. package/src/config/schemas/__tests__/live-voice.test.ts +27 -16
  262. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  263. package/src/config/schemas/live-voice.ts +33 -7
  264. package/src/config/schemas/llm.ts +1 -0
  265. package/src/config/schemas/memory-retrospective.ts +13 -0
  266. package/src/config/schemas/memory-substrate.ts +183 -0
  267. package/src/config/schemas/memory-v2.ts +3 -2
  268. package/src/config/schemas/memory-v3.ts +11 -4
  269. package/src/config/schemas/memory.ts +35 -1
  270. package/src/config/schemas/services.ts +10 -2
  271. package/src/config/substrate-twin-shadowing.ts +195 -0
  272. package/src/config/webhook-routing.ts +67 -0
  273. package/src/context/compactor.ts +10 -3
  274. package/src/context/token-estimator.ts +21 -0
  275. package/src/daemon/__tests__/channel-ui-capability.test.ts +85 -0
  276. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +3 -3
  277. package/src/daemon/__tests__/embedding-reconcile.test.ts +3 -3
  278. package/src/daemon/__tests__/inference-profile-notification.test.ts +3 -6
  279. package/src/daemon/__tests__/native-web-search-metadata.test.ts +5 -5
  280. package/src/daemon/__tests__/web-search-status-text.test.ts +2 -2
  281. package/src/daemon/channel-ui-capability.ts +70 -1
  282. package/src/daemon/conversation-agent-loop-handlers.ts +4 -4
  283. package/src/daemon/conversation-agent-loop.ts +12 -5
  284. package/src/daemon/conversation-evictor.ts +26 -4
  285. package/src/daemon/conversation-launch.ts +11 -14
  286. package/src/daemon/conversation-lineage.ts +76 -0
  287. package/src/daemon/conversation-messaging.ts +14 -14
  288. package/src/daemon/conversation-notifiers.ts +2 -2
  289. package/src/daemon/conversation-process.ts +133 -21
  290. package/src/daemon/conversation-queue-manager.ts +7 -7
  291. package/src/daemon/conversation-runtime-assembly.ts +16 -0
  292. package/src/daemon/conversation-store.ts +11 -3
  293. package/src/daemon/conversation-surfaces.ts +8 -14
  294. package/src/daemon/conversation-tool-setup.ts +13 -7
  295. package/src/daemon/conversation-usage.ts +12 -11
  296. package/src/daemon/conversation.ts +38 -15
  297. package/src/daemon/disk-pressure-guard.ts +5 -12
  298. package/src/daemon/embedding-reconcile.ts +14 -9
  299. package/src/daemon/handlers/config-channels.ts +40 -134
  300. package/src/daemon/handlers/config-model.ts +15 -7
  301. package/src/daemon/handlers/conversations.ts +4 -2
  302. package/src/daemon/handlers/shared.ts +29 -0
  303. package/src/daemon/host-proxy-base.ts +4 -4
  304. package/src/daemon/lifecycle.ts +13 -0
  305. package/src/daemon/message-protocol.ts +8 -144
  306. package/src/daemon/message-types/computer-use.ts +0 -12
  307. package/src/daemon/message-types/conversations.ts +9 -345
  308. package/src/daemon/message-types/host-app-control.ts +0 -9
  309. package/src/daemon/message-types/host-browser.ts +0 -7
  310. package/src/daemon/message-types/host-ui-snapshot.ts +0 -7
  311. package/src/daemon/message-types/messages.ts +0 -48
  312. package/src/daemon/message-types/notifications.ts +0 -7
  313. package/src/daemon/message-types/skills.ts +0 -5
  314. package/src/daemon/message-types/surfaces.ts +0 -9
  315. package/src/daemon/message-types/sync.ts +0 -2
  316. package/src/daemon/process-message.ts +5 -5
  317. package/src/daemon/skill-memory-refresh.ts +5 -5
  318. package/src/daemon/tool-side-effects.ts +32 -16
  319. package/src/daemon/trust-context.ts +1 -1
  320. package/src/daemon/wake-conversation-ops.ts +4 -4
  321. package/src/heartbeat/__tests__/heartbeat-run-store.test.ts +100 -7
  322. package/src/heartbeat/__tests__/heartbeat-service.test.ts +67 -0
  323. package/src/heartbeat/heartbeat-run-store.ts +81 -4
  324. package/src/heartbeat/heartbeat-service.ts +32 -1
  325. package/src/home/__tests__/feed-writer.test.ts +7 -7
  326. package/src/home/__tests__/home-content-refresh.test.ts +3 -0
  327. package/src/home/__tests__/suggested-prompts.test.ts +1 -0
  328. package/src/home/feed-writer.ts +6 -13
  329. package/src/home/home-content-refresh.ts +6 -9
  330. package/src/home/relationship-state-writer.ts +5 -12
  331. package/src/home/suggested-prompts-cache.ts +6 -19
  332. package/src/ipc/__tests__/events-publish-client.test.ts +67 -0
  333. package/src/ipc/events-publish-client.ts +44 -0
  334. package/src/ipc/routes/__tests__/conversation-sync-ipc-routes.test.ts +2 -2
  335. package/src/ipc/routes/__tests__/events-ipc-routes.test.ts +38 -9
  336. package/src/ipc/routes/events-ipc-routes.ts +11 -31
  337. package/src/live-voice/__tests__/front-decision.test.ts +4 -176
  338. package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +276 -68
  339. package/src/live-voice/__tests__/live-voice-continuation-fork-hydration.test.ts +286 -0
  340. package/src/live-voice/__tests__/live-voice-events.test.ts +6 -3
  341. package/src/live-voice/__tests__/live-voice-progress.test.ts +185 -46
  342. package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +24 -59
  343. package/src/live-voice/__tests__/live-voice-tts-session.test.ts +38 -54
  344. package/src/live-voice/__tests__/live-voice-vad.test.ts +1154 -636
  345. package/src/live-voice/front-decision.ts +5 -155
  346. package/src/live-voice/live-voice-metrics.ts +4 -1
  347. package/src/live-voice/live-voice-session.ts +1288 -439
  348. package/src/live-voice/progress-phrases.ts +17 -0
  349. package/src/live-voice/protocol.ts +15 -0
  350. package/src/media/app-icon-generator.ts +15 -8
  351. package/src/media/avatar-router.ts +9 -5
  352. package/src/media/image-credentials.ts +42 -10
  353. package/src/media/image-service.ts +1 -13
  354. package/src/media/types.ts +26 -3
  355. package/src/notifications/AGENTS.md +2 -0
  356. package/src/notifications/__tests__/broadcaster.test.ts +95 -0
  357. package/src/notifications/adapters/macos.ts +3 -3
  358. package/src/notifications/broadcaster.ts +57 -0
  359. package/src/notifications/copy-composer.ts +0 -15
  360. package/src/notifications/decision-engine.ts +21 -22
  361. package/src/notifications/guardian-question-mode.ts +57 -2
  362. package/src/notifications/home-feed-side-effect.ts +4 -0
  363. package/src/notifications/signal.ts +6 -4
  364. package/src/notifications/trusted-contact-payloads.ts +3 -4
  365. package/src/notifications/vellum-card-affinity.ts +39 -0
  366. package/src/oauth/AGENTS.md +1 -1
  367. package/src/permissions/channel-permission-query.test.ts +69 -0
  368. package/src/permissions/channel-permission-query.ts +73 -1
  369. package/src/permissions/checker.test.ts +298 -15
  370. package/src/permissions/checker.ts +102 -36
  371. package/src/permissions/confirmation-guardian-request.test.ts +2 -2
  372. package/src/permissions/confirmation-guardian-request.ts +2 -2
  373. package/src/permissions/gateway-threshold-reader.test.ts +224 -17
  374. package/src/permissions/gateway-threshold-reader.ts +82 -10
  375. package/src/permissions/ipc-risk-types.ts +8 -0
  376. package/src/permissions/prompter.ts +5 -5
  377. package/src/permissions/question-guardian-request.test.ts +222 -0
  378. package/src/permissions/question-guardian-request.ts +179 -0
  379. package/src/permissions/question-prompter.test.ts +8 -8
  380. package/src/permissions/question-prompter.ts +18 -0
  381. package/src/permissions/secret-prompter.ts +2 -4
  382. package/src/permissions/workspace-policy.ts +269 -34
  383. package/src/persistence/__tests__/lifecycle-quiesce.test.ts +82 -0
  384. package/src/persistence/__tests__/message-content-file.test.ts +58 -3
  385. package/src/persistence/conversation-crud.ts +93 -0
  386. package/src/persistence/conversation-key-store.ts +63 -0
  387. package/src/persistence/conversation-parent.ts +27 -0
  388. package/src/persistence/db-async-query.ts +1 -1
  389. package/src/persistence/db-singleton.ts +14 -27
  390. package/src/persistence/delivery-crud.ts +45 -0
  391. package/src/persistence/embeddings/embedding-backend.ts +2 -1
  392. package/src/persistence/embeddings/embedding-identity.ts +7 -3
  393. package/src/persistence/job-utils.ts +32 -27
  394. package/src/persistence/jobs-store.ts +92 -3
  395. package/src/persistence/lifecycle-quiesce.ts +80 -0
  396. package/src/persistence/llm-usage-store.ts +45 -8
  397. package/src/persistence/message-content-file.ts +4 -4
  398. package/src/persistence/migrations/336-move-memory-v2-activation-logs-to-memory-db.ts +1 -1
  399. package/src/persistence/migrations/351-schedule-skill-script-handoff.ts +39 -0
  400. package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.test.ts +83 -0
  401. package/src/persistence/migrations/352-drop-schedule-skill-script-handoff.ts +36 -0
  402. package/src/persistence/migrations/353-add-llm-usage-conversation-type.test.ts +110 -0
  403. package/src/persistence/migrations/353-add-llm-usage-conversation-type.ts +49 -0
  404. package/src/persistence/migrations/354-backfill-app-conversation-lineage.ts +41 -0
  405. package/src/persistence/schema/infrastructure.ts +11 -0
  406. package/src/persistence/steps.ts +9 -1
  407. package/src/plugin-api/__tests__/publish-event-forwarding.test.ts +113 -0
  408. package/src/plugin-api/__tests__/publish-event.test.ts +57 -0
  409. package/src/plugin-api/conversation-turn.ts +4 -4
  410. package/src/plugin-api/event-hub-facade.ts +15 -6
  411. package/src/plugin-api/index.ts +10 -4
  412. package/src/plugin-api/publish-event.ts +36 -0
  413. package/src/plugins/AGENTS.md +2 -0
  414. package/src/plugins/defaults/compaction/window-manager.ts +9 -0
  415. package/src/plugins/defaults/index.ts +9 -13
  416. package/src/plugins/defaults/memory/AGENTS.md +775 -0
  417. package/src/plugins/defaults/memory/__tests__/capability-seed-embed-gate.test.ts +186 -0
  418. package/src/plugins/defaults/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +1 -1
  419. package/src/plugins/defaults/memory/__tests__/indexer-tier-dispatch.test.ts +129 -0
  420. package/src/plugins/defaults/memory/__tests__/jobs-worker-quiesce-gate.test.ts +91 -0
  421. package/src/plugins/defaults/memory/__tests__/jobs-worker-v1-graph-substrate-noop.test.ts +342 -0
  422. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +9 -1
  423. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +36 -1
  424. package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-sweep-defer.test.ts +9 -1
  425. package/src/plugins/defaults/memory/__tests__/memory-log-stores-degraded.test.ts +2 -2
  426. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +44 -10
  427. package/src/plugins/defaults/memory/__tests__/memory-retrospective-sweep.test.ts +151 -10
  428. package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +1155 -0
  429. package/src/plugins/defaults/memory/__tests__/memory-v2-activation-log-store.test.ts +1 -1
  430. package/src/plugins/defaults/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -3
  431. package/src/plugins/defaults/memory/__tests__/tools-delete-memory-page.test.ts +1 -1
  432. package/src/plugins/defaults/memory/context-search/sources/memory-v2.ts +71 -35
  433. package/src/plugins/defaults/memory/context-search/sources/memory.ts +5 -1
  434. package/src/plugins/defaults/memory/fork-conversation-memory.ts +4 -4
  435. package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +80 -10
  436. package/src/plugins/defaults/memory/graph/__tests__/handle-remember-v2.test.ts +1 -1
  437. package/src/plugins/defaults/memory/graph/capability-seed.ts +24 -10
  438. package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +123 -49
  439. package/src/plugins/defaults/memory/graph/graph-search.ts +6 -118
  440. package/src/plugins/defaults/memory/graph/in-context-tracker.test.ts +173 -0
  441. package/src/plugins/defaults/memory/graph/in-context-tracker.ts +109 -0
  442. package/src/plugins/defaults/memory/graph/store.ts +1 -0
  443. package/src/plugins/defaults/memory/graph/tool-handlers.test.ts +1 -1
  444. package/src/plugins/defaults/memory/graph/tool-handlers.ts +5 -2
  445. package/src/plugins/defaults/memory/graph-topology/__tests__/build-memory-graph.test.ts +1 -1
  446. package/src/plugins/defaults/memory/graph-topology/build-memory-graph.ts +6 -9
  447. package/src/plugins/defaults/memory/hooks/__tests__/user-prompt-submit.test.ts +30 -16
  448. package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +18 -14
  449. package/src/plugins/defaults/memory/indexer.ts +146 -89
  450. package/src/plugins/defaults/memory/injectors.ts +86 -41
  451. package/src/plugins/defaults/memory/job-handlers.ts +130 -39
  452. package/src/plugins/defaults/memory/jobs/__tests__/embed-concept-page.test.ts +2 -2
  453. package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +22 -10
  454. package/src/plugins/defaults/memory/jobs-worker.ts +279 -208
  455. package/src/plugins/defaults/memory/memory-retrospective-enqueue.ts +4 -2
  456. package/src/plugins/defaults/memory/memory-retrospective-job.ts +40 -3
  457. package/src/plugins/defaults/memory/memory-retrospective-sweep.ts +99 -11
  458. package/src/plugins/defaults/memory/src/__tests__/memory-v2-routes.test.ts +5 -3
  459. package/src/plugins/defaults/memory/src/__tests__/memory-v2-simulate-route.test.ts +3 -4
  460. package/src/plugins/defaults/memory/src/memory-graph-routes.ts +2 -1
  461. package/src/plugins/defaults/memory/src/memory-item-routes.test.ts +7 -5
  462. package/src/plugins/defaults/memory/src/memory-item-routes.ts +51 -19
  463. package/src/plugins/defaults/memory/src/memory-v2-routes.ts +31 -20
  464. package/src/plugins/defaults/memory/startup.ts +58 -21
  465. package/src/plugins/defaults/memory/substrate/__tests__/boot-maintenance.test.ts +335 -0
  466. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/cli-command-store.test.ts +14 -8
  467. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-job.test.ts +51 -21
  468. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/edge-index.test.ts +1 -1
  469. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/frontmatter-sweep.test.ts +3 -3
  470. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-index.test.ts +1 -1
  471. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/page-store.test.ts +1 -1
  472. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/prompts-consolidation.test.ts +2 -2
  473. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/qdrant.test.ts +23 -14
  474. package/src/plugins/defaults/memory/substrate/__tests__/reembed-job.test.ts +262 -0
  475. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sim.test.ts +9 -12
  476. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-content.test.ts +2 -2
  477. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/skill-store.test.ts +9 -9
  478. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sparse-bm25.test.ts +12 -5
  479. package/src/plugins/defaults/memory/substrate/__tests__/spread.test.ts +276 -0
  480. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/static-context.test.ts +17 -8
  481. package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/sweep-job.test.ts +9 -9
  482. package/src/plugins/defaults/memory/{v3/substrate/memory-v2-startup.ts → substrate/boot-maintenance.ts} +43 -24
  483. package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-store.ts +13 -8
  484. package/src/plugins/defaults/memory/{v3/substrate → substrate}/consolidation-job.ts +51 -27
  485. package/src/plugins/defaults/memory/{v3/substrate → substrate}/constants.ts +1 -0
  486. package/src/plugins/defaults/memory/{v3/substrate → substrate}/edge-index.ts +28 -9
  487. package/src/plugins/defaults/memory/{v3/substrate → substrate}/frontmatter-sweep.ts +14 -7
  488. package/src/plugins/defaults/memory/{v3/substrate → substrate}/injected-block-slugs.ts +9 -3
  489. package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-index.ts +29 -10
  490. package/src/plugins/defaults/memory/{v3/substrate → substrate}/page-store.ts +35 -12
  491. package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/consolidation.ts +14 -8
  492. package/src/plugins/defaults/memory/{v3/substrate → substrate}/prompts/sweep.ts +4 -1
  493. package/src/plugins/defaults/memory/{v3/substrate → substrate}/qdrant.ts +96 -36
  494. package/src/plugins/defaults/memory/substrate/reembed-job.ts +54 -0
  495. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sim.ts +26 -15
  496. package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-content.ts +1 -1
  497. package/src/plugins/defaults/memory/{v3/substrate → substrate}/skill-store.ts +13 -8
  498. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sparse-bm25.ts +27 -10
  499. package/src/plugins/defaults/memory/substrate/spread.ts +165 -0
  500. package/src/plugins/defaults/memory/{v3/substrate → substrate}/static-context.ts +12 -7
  501. package/src/plugins/defaults/memory/{v3/substrate → substrate}/sweep-job.ts +20 -15
  502. package/src/plugins/defaults/memory/substrate/tuning.ts +93 -0
  503. package/src/plugins/defaults/memory/{v3/substrate → substrate}/types.ts +7 -4
  504. package/src/plugins/defaults/memory/tools.test.ts +1 -1
  505. package/src/plugins/defaults/memory/tools.ts +1 -1
  506. package/src/plugins/defaults/memory/v1/README.md +5 -0
  507. package/src/plugins/defaults/memory/{__tests__ → v1/__tests__}/filing-jobs.test.ts +4 -4
  508. package/src/plugins/defaults/memory/{filing-jobs.ts → v1/filing-jobs.ts} +3 -3
  509. package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.test.ts +68 -6
  510. package/src/plugins/defaults/memory/{graph → v1/graph}/bootstrap.ts +40 -21
  511. package/src/plugins/defaults/memory/{graph → v1/graph}/consolidation.ts +14 -14
  512. package/src/plugins/defaults/memory/{graph → v1/graph}/decay.test.ts +1 -1
  513. package/src/plugins/defaults/memory/{graph → v1/graph}/decay.ts +3 -3
  514. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction-job.ts +5 -5
  515. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.test.ts +1 -1
  516. package/src/plugins/defaults/memory/{graph → v1/graph}/extraction.ts +20 -14
  517. package/src/plugins/defaults/memory/{graph → v1/graph}/graph-search.test.ts +3 -3
  518. package/src/plugins/defaults/memory/v1/graph/graph-search.ts +123 -0
  519. package/src/plugins/defaults/memory/{graph → v1/graph}/injection.test.ts +1 -118
  520. package/src/plugins/defaults/memory/{graph → v1/graph}/injection.ts +9 -111
  521. package/src/plugins/defaults/memory/{graph → v1/graph}/narrative.ts +6 -6
  522. package/src/plugins/defaults/memory/{graph → v1/graph}/pattern-scan.ts +5 -5
  523. package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.test.ts +135 -42
  524. package/src/plugins/defaults/memory/{graph → v1/graph}/retriever.ts +40 -22
  525. package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.test.ts +1 -1
  526. package/src/plugins/defaults/memory/{graph → v1/graph}/scoring.ts +1 -1
  527. package/src/plugins/defaults/memory/{graph → v1/graph}/serendipity.ts +1 -1
  528. package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.test.ts +1 -1
  529. package/src/plugins/defaults/memory/{graph → v1/graph}/triggers.ts +1 -1
  530. package/src/plugins/defaults/memory/{identity-context.ts → v1/identity-context.ts} +4 -4
  531. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/backfill.ts +6 -6
  532. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.test.ts +6 -6
  533. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/embedding.ts +6 -6
  534. package/src/plugins/defaults/memory/{job-handlers → v1/job-handlers}/index-maintenance.ts +8 -8
  535. package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.test.ts +7 -7
  536. package/src/plugins/defaults/memory/{jobs → v1/jobs}/embed-pkb-file.ts +5 -5
  537. package/src/plugins/defaults/memory/{pkb → v1/pkb}/autoinject.ts +1 -1
  538. package/src/plugins/defaults/memory/{pkb → v1/pkb}/context.ts +2 -2
  539. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.test.ts +3 -3
  540. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-index.ts +2 -2
  541. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.test.ts +3 -3
  542. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-reconcile.ts +2 -2
  543. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.test.ts +3 -3
  544. package/src/plugins/defaults/memory/{pkb → v1/pkb}/pkb-search.ts +6 -6
  545. package/src/plugins/defaults/memory/{pkb → v1/pkb}/types.ts +3 -5
  546. package/src/plugins/defaults/memory/{pkb-schedule.ts → v1/pkb-schedule.ts} +2 -2
  547. package/src/plugins/defaults/memory/{search/semantic.ts → v1/semantic-search.ts} +1 -1
  548. package/src/plugins/defaults/memory/v2/__tests__/activation-store.test.ts +1 -1
  549. package/src/plugins/defaults/memory/v2/__tests__/activation.test.ts +11 -274
  550. package/src/plugins/defaults/memory/v2/__tests__/backfill-jobs.test.ts +9 -131
  551. package/src/plugins/defaults/memory/v2/__tests__/harness-compare.test.ts +1 -1
  552. package/src/plugins/defaults/memory/v2/__tests__/harness-oracle.test.ts +1 -1
  553. package/src/plugins/defaults/memory/v2/__tests__/harness-replay-input.test.ts +1 -1
  554. package/src/plugins/defaults/memory/v2/__tests__/injection.test.ts +14 -10
  555. package/src/plugins/defaults/memory/v2/__tests__/reranker.test.ts +7 -5
  556. package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +12 -6
  557. package/src/plugins/defaults/memory/{memory-v2-activation-log-store.ts → v2/activation-log-store.ts} +2 -2
  558. package/src/plugins/defaults/memory/v2/activation-store.ts +22 -8
  559. package/src/plugins/defaults/memory/v2/activation.ts +30 -163
  560. package/src/plugins/defaults/memory/v2/backfill-jobs.ts +7 -54
  561. package/src/plugins/defaults/memory/{memory-v2-concept-frequency.ts → v2/concept-frequency.ts} +3 -3
  562. package/src/plugins/defaults/memory/v2/harness/oracle.ts +1 -1
  563. package/src/plugins/defaults/memory/v2/harness/replay-input.ts +2 -2
  564. package/src/plugins/defaults/memory/v2/harness/retriever.ts +1 -1
  565. package/src/plugins/defaults/memory/v2/injection.ts +36 -26
  566. package/src/plugins/defaults/memory/v2/migration.ts +2 -2
  567. package/src/plugins/defaults/memory/{rerank-local.ts → v2/rerank-local.ts} +44 -18
  568. package/src/plugins/defaults/memory/v2/reranker.ts +29 -11
  569. package/src/plugins/defaults/memory/v2/router.ts +38 -15
  570. package/src/plugins/defaults/memory/v3/__tests__/candidate-match.test.ts +5 -3
  571. package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +21 -8
  572. package/src/plugins/defaults/memory/v3/__tests__/edge.test.ts +1 -1
  573. package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +1 -1
  574. package/src/plugins/defaults/memory/v3/__tests__/maintain-job.test.ts +4 -1
  575. package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +181 -3
  576. package/src/plugins/defaults/memory/v3/__tests__/selection-log-store.test.ts +3 -0
  577. package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +14 -5
  578. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +40 -50
  579. package/src/plugins/defaults/memory/v3/__tests__/tuning-profile.test.ts +1 -0
  580. package/src/plugins/defaults/memory/v3/candidate-match.ts +2 -2
  581. package/src/plugins/defaults/memory/v3/capabilities.ts +6 -4
  582. package/src/plugins/defaults/memory/v3/card.ts +25 -9
  583. package/src/plugins/defaults/memory/v3/edge.ts +52 -18
  584. package/src/plugins/defaults/memory/v3/gate.ts +4 -4
  585. package/src/plugins/defaults/memory/v3/injector.ts +10 -3
  586. package/src/plugins/defaults/memory/v3/maintain-job.ts +3 -3
  587. package/src/plugins/defaults/memory/v3/orchestrate.ts +100 -18
  588. package/src/plugins/defaults/memory/v3/page-content.ts +26 -10
  589. package/src/plugins/defaults/memory/v3/prune.ts +40 -16
  590. package/src/plugins/defaults/memory/v3/selection-log-store.ts +34 -12
  591. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +9 -13
  592. package/src/plugins/defaults/memory/v3/span-query.test.ts +86 -0
  593. package/src/plugins/defaults/memory/v3/span-query.ts +71 -0
  594. package/src/plugins/defaults/memory/v3/tuning-profile.ts +3 -0
  595. package/src/plugins/defaults/memory/v3/types.ts +4 -1
  596. package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +2 -2
  597. package/src/plugins/defaults/memory/validation.ts +1 -1
  598. package/src/plugins/defaults/memory/worker.ts +2 -1
  599. package/src/plugins/defaults/platform-hosted/__tests__/reengage.test.ts +104 -12
  600. package/src/plugins/defaults/platform-hosted/routes/reengage.ts +104 -12
  601. package/src/plugins/types.ts +2 -2
  602. package/src/prompts/sections.ts +4 -16
  603. package/src/providers/__tests__/registry-native-web-search.test.ts +47 -2
  604. package/src/providers/anthropic/client.ts +15 -6
  605. package/src/providers/content-block-schema.ts +26 -0
  606. package/src/providers/inference/__tests__/connections-credential-normalize.test.ts +87 -0
  607. package/src/providers/inference/adapter-factory.ts +6 -0
  608. package/src/providers/inference/connections.ts +30 -14
  609. package/src/providers/model-catalog.ts +77 -0
  610. package/src/providers/openai/__tests__/chat-completions-input-audio.test.ts +260 -0
  611. package/src/providers/openai/chat-completions-provider.ts +65 -17
  612. package/src/providers/openai/input-audio.ts +76 -0
  613. package/src/providers/openrouter/client.ts +0 -2
  614. package/src/providers/platform-proxy/constants.ts +4 -0
  615. package/src/providers/poolside/client.ts +42 -0
  616. package/src/providers/registry.ts +40 -8
  617. package/src/providers/retry.ts +2 -0
  618. package/src/providers/types.ts +39 -1
  619. package/src/providers/vercel-ai-gateway/client.ts +0 -2
  620. package/src/runtime/AGENTS.md +7 -5
  621. package/src/runtime/__tests__/question-request-guardian-bridge.test.ts +173 -0
  622. package/src/runtime/__tests__/question-resolution.test.ts +111 -0
  623. package/src/runtime/access-request-helper.ts +7 -15
  624. package/src/runtime/assistant-event-hub.ts +43 -31
  625. package/src/runtime/assistant-event-publish-options.ts +31 -0
  626. package/src/runtime/assistant-event.ts +19 -30
  627. package/src/runtime/assistant-stream-state.ts +4 -4
  628. package/src/runtime/channel-approvals.ts +0 -25
  629. package/src/runtime/channel-readiness-service.ts +99 -40
  630. package/src/runtime/channel-retry-sweep.ts +38 -15
  631. package/src/runtime/confirmation-request-guardian-bridge.ts +4 -0
  632. package/src/runtime/guardian-reply-router.ts +108 -0
  633. package/src/runtime/http-server.ts +8 -0
  634. package/src/runtime/http-types.ts +2 -2
  635. package/src/runtime/process-role.ts +42 -0
  636. package/src/runtime/question-request-guardian-bridge.ts +184 -0
  637. package/src/runtime/question-resolution.ts +153 -0
  638. package/src/runtime/routes/__tests__/bookmark-routes.test.ts +6 -2
  639. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +1 -1
  640. package/src/runtime/routes/__tests__/subagents-routes.test.ts +250 -0
  641. package/src/runtime/routes/__tests__/webhook-routes.test.ts +201 -0
  642. package/src/runtime/routes/acp-routes.ts +2 -2
  643. package/src/runtime/routes/bookmark-routes.ts +3 -15
  644. package/src/runtime/routes/canned-message-complete.ts +2 -2
  645. package/src/runtime/routes/consolidation-routes.ts +8 -2
  646. package/src/runtime/routes/conversation-list-routes.ts +3 -19
  647. package/src/runtime/routes/conversation-management-routes.ts +1 -5
  648. package/src/runtime/routes/conversation-query-routes.ts +52 -8
  649. package/src/runtime/routes/conversation-routes.ts +36 -22
  650. package/src/runtime/routes/credential-request-routes.ts +0 -1
  651. package/src/runtime/routes/filing-routes.ts +7 -7
  652. package/src/runtime/routes/global-search-routes.ts +1 -1
  653. package/src/runtime/routes/guardian-approval-prompt.ts +2 -2
  654. package/src/runtime/routes/image-generation-routes.ts +12 -9
  655. package/src/runtime/routes/inbound-message-handler.ts +17 -0
  656. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +50 -0
  657. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +19 -0
  658. package/src/runtime/routes/inbound-stages/background-dispatch.ts +4 -4
  659. package/src/runtime/routes/inbound-stages/inbound-content-prep.test.ts +129 -0
  660. package/src/runtime/routes/inbound-stages/inbound-content-prep.ts +141 -9
  661. package/src/runtime/routes/index.ts +2 -0
  662. package/src/runtime/routes/lifecycle-routes.ts +199 -0
  663. package/src/runtime/routes/platform-routes.ts +3 -8
  664. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +7 -7
  665. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +5 -5
  666. package/src/runtime/routes/question-routes.ts +34 -87
  667. package/src/runtime/routes/secret-routes.ts +11 -1
  668. package/src/runtime/routes/settings-routes.ts +8 -18
  669. package/src/runtime/routes/subagents-routes.ts +35 -8
  670. package/src/runtime/routes/upgrade-broadcast-routes.ts +4 -5
  671. package/src/runtime/routes/webhook-routes.ts +89 -30
  672. package/src/runtime/routes/workspace-routes.test.ts +7 -4
  673. package/src/runtime/slack-reply-session.test.ts +12 -12
  674. package/src/runtime/slack-reply-session.ts +17 -17
  675. package/src/runtime/sync/sync-publisher.test.ts +7 -5
  676. package/src/runtime/tool-grant-request-helper.ts +4 -0
  677. package/src/schedule/schedule-store.ts +70 -0
  678. package/src/schedule/scheduler.ts +27 -0
  679. package/src/security/AGENTS.md +1 -1
  680. package/src/security/credential-key.ts +17 -0
  681. package/src/security/secret-ingress.ts +14 -105
  682. package/src/security/secret-patterns.ts +8 -139
  683. package/src/security/secret-scanner.ts +8 -3
  684. package/src/security/store-path-override.ts +6 -16
  685. package/src/sequence/store.ts +8 -0
  686. package/src/signals/emit-event.ts +5 -10
  687. package/src/signals/event-stream.ts +20 -10
  688. package/src/subagent/manager.ts +76 -25
  689. package/src/subagent/notify.ts +8 -0
  690. package/src/subagent/types.ts +13 -3
  691. package/src/telegram/__tests__/webhook-health.test.ts +442 -0
  692. package/src/telegram/webhook-health.ts +478 -0
  693. package/src/telemetry/AGENTS.md +6 -0
  694. package/src/telemetry/memory-corpus-size.test.ts +129 -0
  695. package/src/telemetry/memory-corpus-size.ts +184 -0
  696. package/src/telemetry/memory-tier-reporter.test.ts +67 -2
  697. package/src/telemetry/memory-tier-reporter.ts +30 -3
  698. package/src/tools/__tests__/conversation-group-tool-input-schemas.test.ts +61 -0
  699. package/src/tools/__tests__/document-tool-input-schemas.test.ts +103 -0
  700. package/src/tools/__tests__/followup-call-acp-tool-input-schemas.test.ts +125 -0
  701. package/src/tools/__tests__/schedule-tool-input-schemas.test.ts +83 -0
  702. package/src/tools/__tests__/subagent-workflow-tool-input-schemas.test.ts +116 -0
  703. package/src/tools/__tests__/tool-input-schemas.test.ts +192 -0
  704. package/src/tools/__tests__/tool-schema-drift-harness.ts +142 -0
  705. package/src/tools/acp/abort.ts +21 -1
  706. package/src/tools/acp/context.ts +5 -5
  707. package/src/tools/acp/spawn.test.ts +15 -5
  708. package/src/tools/acp/spawn.ts +26 -3
  709. package/src/tools/acp/status.ts +20 -1
  710. package/src/tools/acp/steer.test.ts +20 -0
  711. package/src/tools/acp/steer.ts +23 -2
  712. package/src/tools/apps/resolve-app-id.ts +15 -3
  713. package/src/tools/ask-question/ask-question-tool.test.ts +65 -0
  714. package/src/tools/ask-question/ask-question-tool.ts +68 -92
  715. package/src/tools/browser/browser-screencast.ts +6 -6
  716. package/src/tools/calls/call-end.ts +24 -3
  717. package/src/tools/calls/call-start.ts +35 -11
  718. package/src/tools/calls/call-status.ts +20 -1
  719. package/src/tools/conversation-groups/group_create.ts +63 -0
  720. package/src/tools/conversation-groups/group_list.ts +20 -0
  721. package/src/tools/conversation-groups/group_shared.ts +52 -0
  722. package/src/tools/conversation-groups/move_to_group.ts +106 -0
  723. package/src/tools/document/document-comment-tool.test.ts +49 -0
  724. package/src/tools/document/document-comment-tool.ts +45 -6
  725. package/src/tools/document/document-tool.ts +142 -24
  726. package/src/tools/executor.ts +27 -13
  727. package/src/tools/filesystem/edit.ts +62 -60
  728. package/src/tools/filesystem/list.ts +36 -29
  729. package/src/tools/filesystem/read.ts +56 -39
  730. package/src/tools/filesystem/write.ts +44 -38
  731. package/src/tools/followups/followup_create.ts +41 -12
  732. package/src/tools/followups/followup_list.ts +34 -6
  733. package/src/tools/followups/followup_resolve.ts +26 -4
  734. package/src/tools/host-filesystem/edit.ts +50 -60
  735. package/src/tools/host-filesystem/read.ts +45 -39
  736. package/src/tools/host-filesystem/write.ts +31 -36
  737. package/src/tools/host-terminal/host-shell.ts +76 -62
  738. package/src/tools/policy-context.ts +27 -10
  739. package/src/tools/schedule/create.ts +76 -33
  740. package/src/tools/schedule/delete.ts +21 -2
  741. package/src/tools/schedule/list.ts +25 -3
  742. package/src/tools/schedule/update.ts +105 -48
  743. package/src/tools/shared/filesystem/path-policy.ts +246 -40
  744. package/src/tools/shared/zod-tool-schema.ts +117 -0
  745. package/src/tools/subagent/abort.ts +12 -4
  746. package/src/tools/subagent/consult-deadline.ts +9 -3
  747. package/src/tools/subagent/message.ts +21 -5
  748. package/src/tools/subagent/notify-parent.ts +44 -23
  749. package/src/tools/subagent/read.ts +15 -4
  750. package/src/tools/subagent/resolve.ts +26 -4
  751. package/src/tools/subagent/spawn.ts +37 -13
  752. package/src/tools/subagent/status.ts +12 -4
  753. package/src/tools/system/request-permission.ts +35 -26
  754. package/src/tools/terminal/shell.ts +68 -55
  755. package/src/tools/tool-approval-handler.ts +327 -53
  756. package/src/tools/tool-input-schemas.ts +85 -0
  757. package/src/tools/tool-types.ts +7 -0
  758. package/src/tools/types.ts +8 -0
  759. package/src/tools/workflows/manage-workflows.ts +30 -2
  760. package/src/tools/workflows/run-workflow.test.ts +54 -2
  761. package/src/tools/workflows/run-workflow.ts +32 -4
  762. package/src/util/fs-symlinks.ts +30 -0
  763. package/src/util/log-redact.ts +7 -3
  764. package/src/util/platform.ts +15 -0
  765. package/src/vellum-assistant-namespace.d.ts +80 -0
  766. package/src/watcher/watcher-store.ts +8 -0
  767. package/src/workflows/leaf-runner.test.ts +104 -2
  768. package/src/workflows/leaf-runner.ts +31 -6
  769. package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +2 -2
  770. package/src/workspace/migrations/134-image-generation-mode-to-provider.ts +128 -0
  771. package/src/workspace/migrations/135-copy-substrate-tunables.ts +248 -0
  772. package/src/workspace/migrations/__tests__/135-copy-substrate-tunables.test.ts +446 -0
  773. package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +2 -2
  774. package/src/workspace/migrations/registry.ts +4 -0
  775. package/tsconfig.plugin-api.json +1 -1
  776. package/src/__tests__/memory-retrieval-budget.test.ts +0 -49
  777. package/src/__tests__/secret-patterns.test.ts +0 -27
  778. package/src/config/__tests__/proc-to-skills.test.ts +0 -21
  779. package/src/config/memory-tier.test.ts +0 -44
  780. package/src/daemon/message-types/acp.ts +0 -20
  781. package/src/daemon/message-types/apps.ts +0 -11
  782. package/src/daemon/message-types/background-tools.ts +0 -14
  783. package/src/daemon/message-types/bookmarks.ts +0 -13
  784. package/src/daemon/message-types/contacts.ts +0 -13
  785. package/src/daemon/message-types/document-comments.ts +0 -14
  786. package/src/daemon/message-types/documents.ts +0 -13
  787. package/src/daemon/message-types/home.ts +0 -15
  788. package/src/daemon/message-types/host-bash.ts +0 -12
  789. package/src/daemon/message-types/host-cu.ts +0 -10
  790. package/src/daemon/message-types/host-file.ts +0 -12
  791. package/src/daemon/message-types/host-transfer.ts +0 -12
  792. package/src/daemon/message-types/integrations.ts +0 -90
  793. package/src/daemon/message-types/memory.ts +0 -10
  794. package/src/daemon/message-types/schedules.ts +0 -14
  795. package/src/daemon/message-types/settings.ts +0 -17
  796. package/src/daemon/message-types/subagents.ts +0 -63
  797. package/src/daemon/message-types/upgrades.ts +0 -14
  798. package/src/daemon/message-types/workflows.ts +0 -25
  799. package/src/daemon/message-types/workspace.ts +0 -137
  800. package/src/live-voice/ack-phrases.ts +0 -58
  801. package/src/plugins/defaults/memory/retrieval-budget.ts +0 -29
  802. package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +0 -69
  803. package/src/plugins/defaults/memory/v3/gate-flag.ts +0 -20
  804. package/src/plugins/defaults/memory/v3/substrate/__tests__/memory-v2-startup.test.ts +0 -86
  805. package/src/plugins/defaults/memory/v3/substrate/memory-v2-startup.test.ts +0 -205
  806. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/concept-page-frontmatter-schema.test.ts +0 -0
  807. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/consolidation-prompt-flag-gating-guard.test.ts +0 -0
  808. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/__tests__/injected-block-slugs.test.ts +0 -0
  809. /package/src/plugins/defaults/memory/{v3/substrate → substrate}/cli-command-content.ts +0 -0
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Resolution of a conversation's subagent lineage — the chain of forks that
3
+ * leads back to the user-visible thread a background run belongs to.
4
+ */
5
+
6
+ import { getPersistedParentConversationId } from "../persistence/conversation-parent.js";
7
+ import { findConversationOrSubagent } from "./conversation-registry.js";
8
+
9
+ /**
10
+ * Depth cap: a subagent chain deeper than this is a bug, not a hierarchy.
11
+ * Matches the fork-chain cap in the memory plugin's ancestor walk so the two
12
+ * conversation-ancestry walks agree on what counts as pathological.
13
+ */
14
+ export const MAX_LINEAGE_DEPTH = 16;
15
+
16
+ /**
17
+ * The spawner of a conversation: the in-memory registry's record, falling back
18
+ * to the persisted `parent_conversation_id` column. Returns `undefined` at the
19
+ * top of the chain.
20
+ *
21
+ * Both sources are consulted because residency is short-lived —
22
+ * `SubagentManager` drops a subagent's index entry the moment its run goes
23
+ * terminal, and the evictor sweeps idle top-level conversations — and because
24
+ * a resident instance does not necessarily carry the parentage its row does.
25
+ * The column is stamped at subagent bootstrap and outlives both.
26
+ *
27
+ * A failed durable read is swallowed: linking artifacts to a partial chain is
28
+ * better than failing the caller, which is always a best-effort side effect.
29
+ */
30
+ function parentOf(conversationId: string): string | undefined {
31
+ const resident = findConversationOrSubagent(conversationId);
32
+ if (resident?.parentConversationId) {
33
+ return resident.parentConversationId;
34
+ }
35
+ try {
36
+ return getPersistedParentConversationId(conversationId);
37
+ } catch {
38
+ return undefined;
39
+ }
40
+ }
41
+
42
+ /**
43
+ * The conversation itself plus every subagent ancestor above it, nearest
44
+ * first. A subagent Conversation records its spawner in the readonly
45
+ * `parentConversationId` set at construction (see subagent/manager.ts) and in
46
+ * the `parent_conversation_id` column written at bootstrap, so walking that
47
+ * chain reaches the user-visible thread a background run was forked from.
48
+ *
49
+ * Resident hops resolve through {@link findConversationOrSubagent}, because
50
+ * the seed is typically a background subagent and `SubagentManager` keeps live
51
+ * subagent conversations in their own index rather than the eviction-managed
52
+ * top-level store. Non-resident hops fall back to the durable column, so a
53
+ * link attempted after the run went terminal or the thread was evicted still
54
+ * reaches the user-visible ancestor.
55
+ *
56
+ * Never throws: a failed database read degrades to the chain resolved so far,
57
+ * which can therefore be shorter than the true ancestry. Bounded by
58
+ * {@link MAX_LINEAGE_DEPTH} and a visited set, so a cycle terminates.
59
+ */
60
+ export function resolveConversationLineage(conversationId: string): string[] {
61
+ const lineage = [conversationId];
62
+ const visited = new Set([conversationId]);
63
+
64
+ let current = conversationId;
65
+ while (lineage.length < MAX_LINEAGE_DEPTH) {
66
+ const parent = parentOf(current);
67
+ if (!parent || visited.has(parent)) {
68
+ break;
69
+ }
70
+ lineage.push(parent);
71
+ visited.add(parent);
72
+ current = parent;
73
+ }
74
+
75
+ return lineage;
76
+ }
@@ -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
  }
@@ -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();