@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
@@ -1881,3 +1881,179 @@ describe("schedule_delete tool", () => {
1881
1881
  expect(result.content).toContain("Schedule not found");
1882
1882
  });
1883
1883
  });
1884
+
1885
+ // ── model-input schema validation (LUM-2853) ────────────────────────
1886
+
1887
+ describe("schedule tools — model-input schema validation", () => {
1888
+ beforeEach(() => {
1889
+ getRawDb().run("DELETE FROM cron_runs");
1890
+ getRawDb().run("DELETE FROM cron_jobs");
1891
+ });
1892
+
1893
+ test("schedule_create rejects a mistyped field instead of persisting it", async () => {
1894
+ const result = await executeScheduleCreate(
1895
+ {
1896
+ name: "Bad timezone",
1897
+ expression: "0 9 * * *",
1898
+ message: "hi",
1899
+ timezone: 42,
1900
+ },
1901
+ ctx,
1902
+ );
1903
+
1904
+ expect(result.isError).toBe(true);
1905
+ expect(result.content).toContain(
1906
+ 'Invalid input for tool "schedule_create"',
1907
+ );
1908
+ expect(result.content).toContain("timezone");
1909
+ const count = getRawDb()
1910
+ .query("SELECT COUNT(*) as n FROM cron_jobs")
1911
+ .get() as { n: number };
1912
+ expect(count.n).toBe(0);
1913
+ });
1914
+
1915
+ test("schedule_create rejects a non-integer retry policy", async () => {
1916
+ const result = await executeScheduleCreate(
1917
+ {
1918
+ name: "Bad retries",
1919
+ expression: "0 9 * * *",
1920
+ message: "hi",
1921
+ max_retries: "five",
1922
+ },
1923
+ ctx,
1924
+ );
1925
+
1926
+ expect(result.isError).toBe(true);
1927
+ expect(result.content).toContain("max_retries");
1928
+ });
1929
+
1930
+ test("schedule_create rejects an unknown syntax value instead of persisting it", async () => {
1931
+ const result = await executeScheduleCreate(
1932
+ {
1933
+ name: "Bad syntax",
1934
+ expression: "0 9 * * *",
1935
+ syntax: "daily",
1936
+ message: "hi",
1937
+ },
1938
+ ctx,
1939
+ );
1940
+
1941
+ expect(result.isError).toBe(true);
1942
+ expect(result.content).toContain("syntax");
1943
+ });
1944
+
1945
+ test("schedule_create treats explicit null as an omitted optional", async () => {
1946
+ const result = await executeScheduleCreate(
1947
+ {
1948
+ name: "Null tolerance",
1949
+ expression: "0 9 * * *",
1950
+ message: "hi",
1951
+ timezone: null,
1952
+ enabled: null,
1953
+ quiet: null,
1954
+ },
1955
+ ctx,
1956
+ );
1957
+
1958
+ expect(result.isError).toBeFalsy();
1959
+ expect(result.content).toContain("Enabled: true");
1960
+ });
1961
+
1962
+ test("schedule_create keeps the bespoke error for a non-string mode", async () => {
1963
+ const result = await executeScheduleCreate(
1964
+ {
1965
+ name: "Bad mode",
1966
+ expression: "0 9 * * *",
1967
+ message: "hi",
1968
+ mode: 42,
1969
+ },
1970
+ ctx,
1971
+ );
1972
+
1973
+ expect(result.isError).toBe(true);
1974
+ expect(result.content).toContain("mode must be one of");
1975
+ });
1976
+
1977
+ test("schedule_create passes unknown keys through (loose schema)", async () => {
1978
+ const result = await executeScheduleCreate(
1979
+ {
1980
+ name: "Loose keys",
1981
+ expression: "0 9 * * *",
1982
+ message: "hi",
1983
+ activity: "creating a schedule",
1984
+ },
1985
+ ctx,
1986
+ );
1987
+
1988
+ expect(result.isError).toBeFalsy();
1989
+ });
1990
+
1991
+ test("schedule_update rejects a mistyped field", async () => {
1992
+ const create = await executeScheduleCreate(
1993
+ { name: "To update", expression: "0 9 * * *", message: "hi" },
1994
+ ctx,
1995
+ );
1996
+ expect(create.isError).toBeFalsy();
1997
+ const jobId = (
1998
+ getRawDb().query("SELECT id FROM cron_jobs").get() as { id: string }
1999
+ ).id;
2000
+
2001
+ const result = await executeScheduleUpdate(
2002
+ { job_id: jobId, max_retries: 2.5 },
2003
+ ctx,
2004
+ );
2005
+
2006
+ expect(result.isError).toBe(true);
2007
+ expect(result.content).toContain(
2008
+ 'Invalid input for tool "schedule_update"',
2009
+ );
2010
+ expect(result.content).toContain("max_retries");
2011
+ });
2012
+
2013
+ test("schedule_update still clears timezone with an explicit null", async () => {
2014
+ const create = await executeScheduleCreate(
2015
+ {
2016
+ name: "Tz clear",
2017
+ expression: "0 9 * * *",
2018
+ message: "hi",
2019
+ timezone: "America/Los_Angeles",
2020
+ },
2021
+ ctx,
2022
+ );
2023
+ expect(create.isError).toBeFalsy();
2024
+ const jobId = (
2025
+ getRawDb().query("SELECT id FROM cron_jobs").get() as { id: string }
2026
+ ).id;
2027
+
2028
+ const result = await executeScheduleUpdate(
2029
+ { job_id: jobId, timezone: null },
2030
+ ctx,
2031
+ );
2032
+
2033
+ expect(result.isError).toBeFalsy();
2034
+ const row = getRawDb()
2035
+ .query("SELECT timezone FROM cron_jobs WHERE id = ?")
2036
+ .get(jobId) as { timezone: string | null };
2037
+ expect(row.timezone).toBeNull();
2038
+ });
2039
+
2040
+ test("schedule_list rejects a mistyped enabled_only and tolerates null", async () => {
2041
+ const bad = await executeScheduleList({ enabled_only: "yes" }, ctx);
2042
+ expect(bad.isError).toBe(true);
2043
+ expect(bad.content).toContain('Invalid input for tool "schedule_list"');
2044
+
2045
+ const ok = await executeScheduleList(
2046
+ { enabled_only: null, job_id: null },
2047
+ ctx,
2048
+ );
2049
+ expect(ok.isError).toBeFalsy();
2050
+ });
2051
+
2052
+ test("schedule_delete rejects a mistyped job_id", async () => {
2053
+ const result = await executeScheduleDelete({ job_id: 42 }, ctx);
2054
+ expect(result.isError).toBe(true);
2055
+ expect(result.content).toContain(
2056
+ 'Invalid input for tool "schedule_delete"',
2057
+ );
2058
+ });
2059
+ });
@@ -1,7 +1,7 @@
1
1
  import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  import type { SecretRequestEvent } from "../api/events/secret-request.js";
4
- import type { ServerMessage } from "../daemon/message-protocol.js";
4
+ import type { AssistantEvent } from "../api/index.js";
5
5
  import { setConfig } from "./helpers/set-config.js";
6
6
 
7
7
  // Capture all logger calls so we can verify secret values never appear
@@ -30,9 +30,9 @@ mock.module("../util/logger.js", () => ({
30
30
  }));
31
31
 
32
32
  // Capture broadcastMessage calls
33
- const broadcastedMessages: ServerMessage[] = [];
33
+ const broadcastedMessages: AssistantEvent[] = [];
34
34
  mock.module("../runtime/assistant-event-hub.js", () => ({
35
- broadcastMessage: (msg: ServerMessage) => {
35
+ broadcastMessage: (msg: AssistantEvent) => {
36
36
  broadcastedMessages.push(msg);
37
37
  },
38
38
  }));
@@ -1,7 +1,7 @@
1
1
  import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  import type { SecretRequestEvent } from "../api/events/secret-request.js";
4
- import type { ServerMessage } from "../daemon/message-protocol.js";
4
+ import type { AssistantEvent } from "../api/index.js";
5
5
  import { setConfig } from "./helpers/set-config.js";
6
6
 
7
7
  // Use a tiny timeout so the setTimeout branch fires quickly in tests
@@ -25,9 +25,9 @@ mock.module("../util/logger.js", () => ({
25
25
  }),
26
26
  }));
27
27
 
28
- let broadcastMessages: ServerMessage[] = [];
28
+ let broadcastMessages: AssistantEvent[] = [];
29
29
  mock.module("../runtime/assistant-event-hub.js", () => ({
30
- broadcastMessage: (msg: ServerMessage) => broadcastMessages.push(msg),
30
+ broadcastMessage: (msg: AssistantEvent) => broadcastMessages.push(msg),
31
31
  }));
32
32
 
33
33
  // Use a real Map so SecretPrompter can store and retrieve promptResolve/promptReject callbacks.
@@ -1,12 +1,12 @@
1
1
  import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  import type { SecretRequestEvent } from "../api/events/secret-request.js";
4
- import type { ServerMessage } from "../daemon/message-protocol.js";
4
+ import type { AssistantEvent } from "../api/index.js";
5
5
  import type { SecretPromptResult } from "../permissions/secret-prompt-types.js";
6
6
 
7
- let broadcastedMessages: ServerMessage[] = [];
7
+ let broadcastedMessages: AssistantEvent[] = [];
8
8
  mock.module("../runtime/assistant-event-hub.js", () => ({
9
- broadcastMessage: (msg: ServerMessage) => broadcastedMessages.push(msg),
9
+ broadcastMessage: (msg: AssistantEvent) => broadcastedMessages.push(msg),
10
10
  }));
11
11
 
12
12
  // Use a real Map so SecretPrompter can store and retrieve promptResolve/promptReject callbacks.
@@ -90,13 +90,10 @@ mock.module("../tools/credentials/metadata-store.js", () => ({
90
90
 
91
91
  // `handleAddSecret` fires this detached when a managed-proxy credential lands —
92
92
  // a v2-memory side effect outside this suite's provider-registry scope. Stub it
93
- // to a no-op; its behavior is covered by memory-v2-startup.test.ts.
94
- mock.module(
95
- "../plugins/defaults/memory/v3/substrate/memory-v2-startup.js",
96
- () => ({
97
- maybeReseedCapabilitiesAfterManagedCredential: async () => {},
98
- }),
99
- );
93
+ // to a no-op; its behavior is covered by boot-maintenance.test.ts.
94
+ mock.module("../plugins/defaults/memory/substrate/boot-maintenance.js", () => ({
95
+ maybeReseedCapabilitiesAfterManagedCredential: async () => {},
96
+ }));
100
97
 
101
98
  // secret-routes evicts conversations after a credential change so the next turn
102
99
  // rebuilds against the new providers; count the calls to assert that happens.
@@ -8,6 +8,7 @@ import {
8
8
  import {
9
9
  _isPlaceholder,
10
10
  redactSecrets,
11
+ redactSecretsWith,
11
12
  scanText,
12
13
  type SecretMatch,
13
14
  } from "../security/secret-scanner.js";
@@ -433,6 +434,41 @@ describe("redaction", () => {
433
434
  });
434
435
  });
435
436
 
437
+ // ---------------------------------------------------------------------------
438
+ // PEM private-key body redaction — the scanner replaces the matched span in
439
+ // place, so the match must cover header→body→footer or the base64 body and
440
+ // END footer survive redaction (the header-only-matcher leak this fixes).
441
+ // Synthetic fake PEM material only — never a real key.
442
+ // ---------------------------------------------------------------------------
443
+ describe("private-key block redaction", () => {
444
+ const FAKE_PEM_BODY =
445
+ "MIIFAKEfakefakefakefakefakefakefakefakefake\n" +
446
+ "FAKEfakefakefakefakefakefakefakefakefake==";
447
+ const FULL_PEM_BLOCK = `-----BEGIN RSA PRIVATE KEY-----\n${FAKE_PEM_BODY}\n-----END RSA PRIVATE KEY-----`;
448
+
449
+ test("redactSecrets removes the whole block — body and footer, not just the header", () => {
450
+ const input = `here is the key:\n${FULL_PEM_BLOCK}\nuse it well`;
451
+ const result = redactSecrets(input);
452
+ expect(result).toContain('<redacted type="Private Key" />');
453
+ // The base64 body must not survive.
454
+ expect(result).not.toContain("MIIFAKE");
455
+ expect(result).not.toContain("FAKEfake");
456
+ // Header and footer must not survive either.
457
+ expect(result).not.toContain("-----BEGIN");
458
+ expect(result).not.toContain("-----END");
459
+ // Surrounding text is preserved.
460
+ expect(result).toContain("here is the key:");
461
+ expect(result).toContain("use it well");
462
+ });
463
+
464
+ test("redactSecretsWith removes the whole block", () => {
465
+ const result = redactSecretsWith(FULL_PEM_BLOCK, () => "[KEY]");
466
+ expect(result).toBe("[KEY]");
467
+ expect(result).not.toContain("MIIFAKE");
468
+ expect(result).not.toContain("-----END");
469
+ });
470
+ });
471
+
436
472
  // ---------------------------------------------------------------------------
437
473
  // Plugin-declared patterns (runtime registry)
438
474
  // ---------------------------------------------------------------------------
@@ -10,8 +10,8 @@ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
10
10
 
11
11
  mock.module("../config/env.js", () => ({ isHttpAuthDisabled: () => true }));
12
12
 
13
+ import type { AssistantEvent } from "../api/index.js";
13
14
  import type { Conversation } from "../daemon/conversation.js";
14
- import type { ServerMessage } from "../daemon/message-protocol.js";
15
15
  import {
16
16
  getConversationByKey,
17
17
  getOrCreateConversation,
@@ -97,10 +97,10 @@ mock.module(
97
97
  () => gatewayGuardianRequestsStoreBridge,
98
98
  );
99
99
 
100
+ import type { AssistantEventEnvelope } from "../api/index.js";
100
101
  import { __resetGuardianDeliveryCacheForTest } from "../contacts/guardian-delivery-reader.js";
101
102
  import { getDb } from "../persistence/db-connection.js";
102
103
  import { initializeDb } from "../persistence/db-init.js";
103
- import type { AssistantEvent } from "../runtime/assistant-event.js";
104
104
  import { RuntimeHttpServer } from "../runtime/http-server.js";
105
105
  import type { ApprovalConversationGenerator } from "../runtime/http-types.js";
106
106
  import * as pendingInteractions from "../runtime/pending-interactions.js";
@@ -143,7 +143,7 @@ function makeCompletingConversation(): Conversation {
143
143
  runAgentLoop: async (
144
144
  _content: string,
145
145
  _messageId: string,
146
- options?: { onEvent?: (msg: ServerMessage) => void },
146
+ options?: { onEvent?: (msg: AssistantEvent) => void },
147
147
  ) => {
148
148
  const onEvent = options?.onEvent ?? (() => {});
149
149
  onEvent({ type: "assistant_text_delta", text: "Hello!" });
@@ -162,7 +162,7 @@ function makeHangingConversation(): Conversation {
162
162
  const messages: unknown[] = [];
163
163
  const enqueuedMessages: Array<{
164
164
  content: string;
165
- onEvent?: (msg: ServerMessage) => void;
165
+ onEvent?: (msg: AssistantEvent) => void;
166
166
  requestId?: string;
167
167
  }> = [];
168
168
  return {
@@ -191,7 +191,7 @@ function makeHangingConversation(): Conversation {
191
191
  getQueueDepth: () => enqueuedMessages.length,
192
192
  enqueueMessage: (options: {
193
193
  content: string;
194
- onEvent?: (msg: ServerMessage) => void;
194
+ onEvent?: (msg: AssistantEvent) => void;
195
195
  requestId?: string;
196
196
  }) => {
197
197
  enqueuedMessages.push({
@@ -375,7 +375,7 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
375
375
  });
376
376
 
377
377
  test("publishes events to assistantEventHub when conversation is idle", async () => {
378
- const publishedEvents: AssistantEvent[] = [];
378
+ const publishedEvents: AssistantEventEnvelope[] = [];
379
379
 
380
380
  await startServer(() => makeCompletingConversation());
381
381
 
@@ -384,7 +384,7 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
384
384
  await import("../runtime/assistant-event-hub.js");
385
385
  routeEventHub.subscribe({
386
386
  type: "process",
387
- callback: (event: AssistantEvent) => {
387
+ callback: (event: AssistantEventEnvelope) => {
388
388
  publishedEvents.push(event);
389
389
  },
390
390
  });
@@ -0,0 +1,81 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { describe, expect, test } from "bun:test";
4
+
5
+ /**
6
+ * The required-scope list in `channel-readiness-service.ts` is a third copy of
7
+ * data owned by the Slack manifest — the web helper and the skill script hold
8
+ * the other two. Copies drift silently, and a stale list here would either miss
9
+ * a real gap or flag a scope the manifest stopped asking for, so pin it to the
10
+ * canonical source rather than trusting a comment to hold the line.
11
+ */
12
+ const REPO_ROOT = join(import.meta.dir, "..", "..", "..");
13
+
14
+ const MANIFEST_SOURCE = readFileSync(
15
+ join(REPO_ROOT, "skills/slack-app-setup/scripts/build-manifest.ts"),
16
+ "utf-8",
17
+ );
18
+ const READINESS_SOURCE = readFileSync(
19
+ join(import.meta.dir, "..", "runtime", "channel-readiness-service.ts"),
20
+ "utf-8",
21
+ );
22
+ const WEB_HELPER_SOURCE = readFileSync(
23
+ join(REPO_ROOT, "clients/web/src/utils/slack-manifest.ts"),
24
+ "utf-8",
25
+ );
26
+
27
+ /** Pull the quoted strings out of the array introduced by `opener`. */
28
+ function scopeArrayAfter(source: string, opener: string): string[] {
29
+ const start = source.indexOf(opener);
30
+ if (start === -1) {
31
+ throw new Error(`Not found: ${opener}`);
32
+ }
33
+ const from = start + opener.length;
34
+ const end = source.indexOf("]", from);
35
+ if (end === -1) {
36
+ throw new Error(`Unterminated array after: ${opener}`);
37
+ }
38
+ return [...source.slice(from, end).matchAll(/"([^"]+)"/g)].map((m) => m[1]);
39
+ }
40
+
41
+ const bot = scopeArrayAfter(MANIFEST_SOURCE, "bot: [");
42
+ const botOptional = scopeArrayAfter(MANIFEST_SOURCE, "bot_optional: [");
43
+ const required = scopeArrayAfter(
44
+ READINESS_SOURCE,
45
+ "const SLACK_REQUIRED_BOT_SCOPES = [",
46
+ );
47
+ const webBot = scopeArrayAfter(
48
+ WEB_HELPER_SOURCE,
49
+ "export const SLACK_MANIFEST_BOT_SCOPES = [",
50
+ );
51
+ const webBotOptional = scopeArrayAfter(
52
+ WEB_HELPER_SOURCE,
53
+ "const SLACK_MANIFEST_BOT_SCOPES_OPTIONAL = [",
54
+ );
55
+
56
+ describe("required Slack scopes stay in sync with the manifest", () => {
57
+ test("the manifest source parses into usable scope arrays", () => {
58
+ expect(bot.length).toBeGreaterThan(0);
59
+ expect(botOptional.length).toBeGreaterThan(0);
60
+ // Guards the extraction itself, and the manifest's own subset contract.
61
+ expect(botOptional.every((scope) => bot.includes(scope))).toBe(true);
62
+ });
63
+
64
+ test("readiness requires exactly the non-declinable bot scopes", () => {
65
+ const expected = bot.filter((scope) => !botOptional.includes(scope)).sort();
66
+
67
+ expect([...required].sort()).toEqual(expected);
68
+ });
69
+
70
+ test("readiness never demands a scope the workspace may decline", () => {
71
+ expect(required.filter((scope) => botOptional.includes(scope))).toEqual([]);
72
+ });
73
+
74
+ // The web helper is the third copy. Both mirrors are asserted to emit
75
+ // identical manifest JSON elsewhere, but that check lives in the web package
76
+ // and cannot see this one, so pin the scope arrays here too.
77
+ test("the web helper requests the same bot scopes as the skill script", () => {
78
+ expect([...webBot].sort()).toEqual([...bot].sort());
79
+ expect([...webBotOptional].sort()).toEqual([...botOptional].sort());
80
+ });
81
+ });
@@ -1,10 +1,13 @@
1
1
  import { describe, expect, mock, test } from "bun:test";
2
2
 
3
- import type { ServerMessage, SurfaceType } from "../daemon/message-protocol.js";
3
+ import type { AssistantEvent } from "../api/index.js";
4
+ import type {
5
+ SurfaceType,
6
+ } from "../daemon/message-protocol.js";
4
7
 
5
8
  mock.module("../apps/app-store.js", () => ({
6
9
  getApp: (id: string) => {
7
- if (id !== "test-app") return null;
10
+ if (id !== "test-app") {return null;}
8
11
  return {
9
12
  id,
10
13
  name: "Test App",
@@ -116,7 +119,7 @@ describe("starter task surface actions", () => {
116
119
  });
117
120
 
118
121
  test("app_open registers dynamic_page surface as action-capable", async () => {
119
- const sent: ServerMessage[] = [];
122
+ const sent: AssistantEvent[] = [];
120
123
  const ctx = makeContext();
121
124
  ctx.sendToClient = (msg) => sent.push(msg);
122
125
 
@@ -17,7 +17,7 @@
17
17
  */
18
18
  import { afterAll, describe, expect, mock, test } from "bun:test";
19
19
 
20
- import type { ServerMessage } from "../daemon/message-protocol.js";
20
+ import type { AssistantEvent } from "../api/index.js";
21
21
  import { getProvider as getProviderImport } from "../providers/registry.js";
22
22
  import { setConfig } from "./helpers/set-config.js";
23
23
 
@@ -42,7 +42,7 @@ class FakeConversation {
42
42
  provider: unknown,
43
43
  _systemPrompt: string,
44
44
  _maxTokens: number,
45
- _sendToClient: (msg: ServerMessage) => void,
45
+ _sendToClient: (msg: AssistantEvent) => void,
46
46
  ) {
47
47
  capturedProvider = provider;
48
48
  this.capturedState = {
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, test } from "bun:test";
2
2
 
3
- import type { ServerMessage } from "../daemon/message-protocol.js";
3
+ import type { AssistantEvent } from "../api/index.js";
4
4
  import { SubagentManager } from "../subagent/manager.js";
5
5
  import type { SubagentState } from "../subagent/types.js";
6
6
 
@@ -13,7 +13,7 @@ interface FakeManagedSubagent {
13
13
  role: string;
14
14
  content: Array<{ type: string; text: string }>;
15
15
  }>;
16
- sendToClient: (msg: ServerMessage) => void;
16
+ sendToClient: (msg: AssistantEvent) => void;
17
17
  persistUserMessage?: () => { id: string; deduplicated: boolean };
18
18
  runAgentLoop?: () => Promise<void>;
19
19
  enqueueMessage?: () => { rejected: boolean; queued: boolean };
@@ -25,7 +25,7 @@ interface FakeManagedSubagent {
25
25
  subagentDeniedToolNames: Set<string>;
26
26
  } | null;
27
27
  state: SubagentState;
28
- parentSendToClient: (msg: ServerMessage) => void;
28
+ parentSendToClient: (msg: AssistantEvent) => void;
29
29
  retainedUntil?: number;
30
30
  hadEnqueuedMessages?: boolean;
31
31
  }
@@ -34,6 +34,7 @@ interface FakeManagedSubagent {
34
34
  interface ManagerInternals {
35
35
  subagents: Map<string, FakeManagedSubagent>;
36
36
  parentToChildren: Map<string, Set<string>>;
37
+ labelIndex: Map<string, string>;
37
38
  runSubagent: (subagentId: string, objective: string) => Promise<void>;
38
39
  sweepTerminal: () => void;
39
40
  stopSweep: () => void;
@@ -60,7 +61,7 @@ function injectFakeSubagent(
60
61
  manager: SubagentManager,
61
62
  subagentId: string,
62
63
  state: SubagentState,
63
- parentSendToClient?: (msg: ServerMessage) => void,
64
+ parentSendToClient?: (msg: AssistantEvent) => void,
64
65
  conversation?: FakeManagedSubagent["conversation"],
65
66
  ): void {
66
67
  const internals = asInternals(manager);
@@ -77,6 +78,10 @@ function injectFakeSubagent(
77
78
  internals.parentToChildren.set(parentId, new Set());
78
79
  }
79
80
  internals.parentToChildren.get(parentId)!.add(subagentId);
81
+ internals.labelIndex.set(
82
+ `${parentId}:${state.config.label.toLowerCase().trim()}`,
83
+ subagentId,
84
+ );
80
85
  }
81
86
 
82
87
  function makeState(
@@ -210,12 +215,36 @@ describe("SubagentManager terminal disposal", () => {
210
215
  expect(manager.getState("sub-1")).toBeDefined();
211
216
 
212
217
  // Parent disposal should remove it.
213
- manager.abortAllForParent("parent-sess-1");
218
+ manager.disposeAllForParent("parent-sess-1");
214
219
 
215
220
  expect(manager.getState("sub-1")).toBeUndefined();
216
221
  expect(manager.getChildrenOf("parent-sess-1")).toHaveLength(0);
217
222
  });
218
223
 
224
+ test("parent cancel keeps a completed child readable within its retention window", () => {
225
+ const manager = new SubagentManager();
226
+ injectFakeSubagent(
227
+ manager,
228
+ "sub-done",
229
+ makeState("sub-done", { status: "completed" }),
230
+ undefined,
231
+ null, // conversation released, metadata retained
232
+ );
233
+ asInternals(manager).subagents.get("sub-done")!.retainedUntil =
234
+ Date.now() + 60_000;
235
+
236
+ // A user stop / idle eviction aborts in-flight children only.
237
+ manager.abortAllForParent("parent-sess-1");
238
+
239
+ // The completed child's result must remain resolvable by id and by label
240
+ // so the parent can still subagent_read it after the cancel.
241
+ expect(manager.getState("sub-done")?.status).toBe("completed");
242
+ expect(
243
+ manager.getByLabel("Test subagent", "parent-sess-1")?.config.id,
244
+ ).toBe("sub-done");
245
+ expect(manager.getChildrenOf("parent-sess-1")).toHaveLength(1);
246
+ });
247
+
219
248
  test("TTL sweep removes expired terminal entries but not active subagents", () => {
220
249
  const manager = new SubagentManager();
221
250
 
@@ -332,8 +361,8 @@ describe("SubagentManager terminal disposal", () => {
332
361
  describe("SubagentManager.abort usage", () => {
333
362
  test("emits the conversation's latest usage on abort, not zeros", () => {
334
363
  const manager = new SubagentManager();
335
- const sent: ServerMessage[] = [];
336
- const sender = (msg: ServerMessage) => sent.push(msg);
364
+ const sent: AssistantEvent[] = [];
365
+ const sender = (msg: AssistantEvent) => sent.push(msg);
337
366
 
338
367
  const subagentId = "sa-abort-usage";
339
368
  // state.usage starts at {0,0,0}; the live (fake) conversation has accrued
@@ -347,7 +376,7 @@ describe("SubagentManager.abort usage", () => {
347
376
  expect(aborted).toBe(true);
348
377
 
349
378
  const statusMsg = sent.find(
350
- (m): m is Extract<ServerMessage, { type: "subagent_status_changed" }> =>
379
+ (m): m is Extract<AssistantEvent, { type: "subagent_status_changed" }> =>
351
380
  m.type === "subagent_status_changed",
352
381
  );
353
382
  expect(statusMsg).toBeDefined();
@@ -365,8 +394,8 @@ describe("SubagentManager.abort usage", () => {
365
394
 
366
395
  test("keeps the last-known state.usage when the conversation was already released", () => {
367
396
  const manager = new SubagentManager();
368
- const sent: ServerMessage[] = [];
369
- const sender = (msg: ServerMessage) => sent.push(msg);
397
+ const sent: AssistantEvent[] = [];
398
+ const sender = (msg: AssistantEvent) => sent.push(msg);
370
399
 
371
400
  const subagentId = "sa-abort-no-conv";
372
401
  // No live conversation (released), but state carries a last-known usage —
@@ -381,7 +410,7 @@ describe("SubagentManager.abort usage", () => {
381
410
  });
382
411
 
383
412
  const statusMsg = sent.find(
384
- (m): m is Extract<ServerMessage, { type: "subagent_status_changed" }> =>
413
+ (m): m is Extract<AssistantEvent, { type: "subagent_status_changed" }> =>
385
414
  m.type === "subagent_status_changed",
386
415
  );
387
416
  expect(statusMsg!.usage).toEqual({
@@ -29,7 +29,7 @@ mock.module("../runtime/assistant-event-hub.js", () => ({
29
29
  broadcastMessage: () => {},
30
30
  }));
31
31
 
32
- import type { ServerMessage } from "../daemon/message-protocol.js";
32
+ import type { AssistantEvent } from "../api/index.js";
33
33
  import { SubagentManager } from "../subagent/manager.js";
34
34
  import type { SubagentState } from "../subagent/types.js";
35
35
 
@@ -42,7 +42,7 @@ interface FakeManagedSubagent {
42
42
  role: string;
43
43
  content: Array<{ type: string; text: string }>;
44
44
  }>;
45
- sendToClient: (msg: ServerMessage) => void;
45
+ sendToClient: (msg: AssistantEvent) => void;
46
46
  loadFromDb?: () => Promise<void>;
47
47
  persistUserMessage?: () => { id: string; deduplicated: boolean };
48
48
  runAgentLoop?: () => Promise<void>;
@@ -54,7 +54,7 @@ interface FakeManagedSubagent {
54
54
  subagentDeniedToolNames: Set<string>;
55
55
  } | null;
56
56
  state: SubagentState;
57
- parentSendToClient: (msg: ServerMessage) => void;
57
+ parentSendToClient: (msg: AssistantEvent) => void;
58
58
  }
59
59
 
60
60
  /** Type-safe accessor for SubagentManager's private internals via bracket notation. */
@@ -73,7 +73,7 @@ function injectFakeSubagent(
73
73
  manager: SubagentManager,
74
74
  subagentId: string,
75
75
  state: SubagentState,
76
- parentSendToClient?: (msg: ServerMessage) => void,
76
+ parentSendToClient?: (msg: AssistantEvent) => void,
77
77
  ): void {
78
78
  const fakeSession: FakeManagedSubagent["conversation"] = {
79
79
  abort: () => {},