@vellumai/assistant 0.11.3 → 0.11.4-dev.202608190019.b94dbf2

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 (596) hide show
  1. package/AGENTS.md +9 -3
  2. package/ARCHITECTURE.md +32 -10
  3. package/docs/architecture/memory.md +43 -5
  4. package/docs/architecture/security.md +96 -152
  5. package/docs/architecture/turn-actor.md +70 -0
  6. package/docs/browser-use-architecture-phase2.md +128 -56
  7. package/docs/flux-turn-detection-spike.md +248 -0
  8. package/docs/guardian-request-flow.md +35 -0
  9. package/docs/stt-provider-onboarding.md +3 -1
  10. package/knip.json +3 -0
  11. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
  12. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
  13. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
  14. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
  15. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +60 -0
  16. package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
  17. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
  18. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
  19. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
  20. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
  21. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +60 -0
  22. package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
  23. package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +34 -0
  24. package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +166 -1
  25. package/node_modules/@vellumai/gateway-client/src/index.ts +2 -0
  26. package/node_modules/@vellumai/service-contracts/package.json +1 -0
  27. package/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
  28. package/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
  29. package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
  30. package/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +60 -0
  31. package/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
  32. package/openapi.yaml +289 -113
  33. package/package.json +1 -1
  34. package/scripts/voice-ttft-spike.ts +3 -3
  35. package/scripts/write-plugin-api-shim.ts +10 -0
  36. package/src/__tests__/app-compiler.test.ts +38 -3
  37. package/src/__tests__/app-control-flow.test.ts +1 -0
  38. package/src/__tests__/approval-routes-http.test.ts +2 -2
  39. package/src/__tests__/assistant-feature-flag-guard.test.ts +25 -3
  40. package/src/__tests__/attachments-store.test.ts +21 -12
  41. package/src/__tests__/byok-default-profile-ensure.test.ts +17 -0
  42. package/src/__tests__/call-setup-flow-name-capture.test.ts +0 -1
  43. package/src/__tests__/call-site-routing-provider.test.ts +1 -1
  44. package/src/__tests__/channel-availability-routes.test.ts +14 -1
  45. package/src/__tests__/channel-capabilities-dedupe.test.ts +214 -0
  46. package/src/__tests__/channel-delivery-store.test.ts +14 -14
  47. package/src/__tests__/channel-inbound-disk-pressure.test.ts +4 -4
  48. package/src/__tests__/channel-setup-panel-ack.test.ts +1 -1
  49. package/src/__tests__/checker.test.ts +20 -314
  50. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +6 -2
  51. package/src/__tests__/compaction-events.test.ts +8 -10
  52. package/src/__tests__/config-loader-backfill.test.ts +3 -3
  53. package/src/__tests__/config-schema.test.ts +25 -10
  54. package/src/__tests__/context-search-memory-v2-source.test.ts +0 -1
  55. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +8 -11
  56. package/src/__tests__/conversation-agent-loop-overflow.test.ts +8 -11
  57. package/src/__tests__/conversation-agent-loop.test.ts +32 -21
  58. package/src/__tests__/conversation-attachments.test.ts +0 -1
  59. package/src/__tests__/conversation-attention-store.test.ts +63 -0
  60. package/src/__tests__/conversation-confirmation-signals.test.ts +112 -0
  61. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +0 -4
  62. package/src/__tests__/conversation-fork-crud.test.ts +69 -0
  63. package/src/__tests__/conversation-fork-referential.test.ts +67 -0
  64. package/src/__tests__/conversation-fork-retrospective.test.ts +24 -0
  65. package/src/__tests__/conversation-load-history-repair.test.ts +209 -0
  66. package/src/__tests__/conversation-notifiers-provenance.test.ts +59 -0
  67. package/src/__tests__/conversation-queue.test.ts +154 -4
  68. package/src/__tests__/conversation-routes-disk-view.test.ts +1 -1
  69. package/src/__tests__/conversation-routes-enabled-plugins.test.ts +1 -1
  70. package/src/__tests__/conversation-routes-guardian-reply.test.ts +9 -9
  71. package/src/__tests__/conversation-routes-hidden-queue.test.ts +1 -1
  72. package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -1
  73. package/src/__tests__/conversation-runtime-assembly.test.ts +187 -102
  74. package/src/__tests__/conversation-runtime-workspace.test.ts +14 -10
  75. package/src/__tests__/conversation-slash-queue.test.ts +3 -0
  76. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +1 -0
  77. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +1 -0
  78. package/src/__tests__/conversation-surfaces-app-control.test.ts +1 -0
  79. package/src/__tests__/conversation-surfaces-app-open.test.ts +1 -1
  80. package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -1
  81. package/src/__tests__/conversation-surfaces-history-restored-completion.test.ts +21 -14
  82. package/src/__tests__/conversation-surfaces-queued-emit.test.ts +1 -0
  83. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1 -0
  84. package/src/__tests__/conversation-surfaces-standalone.test.ts +1 -0
  85. package/src/__tests__/conversation-surfaces-state-update.test.ts +1 -1
  86. package/src/__tests__/conversation-surfaces-table-action.test.ts +1 -1
  87. package/src/__tests__/conversation-surfaces-task-progress.test.ts +1 -1
  88. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +1 -1
  89. package/src/__tests__/conversation-tool-setup-attribution.test.ts +1 -1
  90. package/src/__tests__/credential-prompt-route.test.ts +7 -10
  91. package/src/__tests__/credential-security-invariants.test.ts +1 -0
  92. package/src/__tests__/cu-unified-flow.test.ts +1 -0
  93. package/src/__tests__/custom-profile-ensure.test.ts +5 -1
  94. package/src/__tests__/default-plugin-names-guard.test.ts +12 -1
  95. package/src/__tests__/discord-access-request-privacy.test.ts +5 -1
  96. package/src/__tests__/discord-requester-notice-privacy.test.ts +3 -3
  97. package/src/__tests__/document-append-idempotency.test.ts +233 -0
  98. package/src/__tests__/document-sync-tags.test.ts +0 -75
  99. package/src/__tests__/dynamic-skill-background-guard.test.ts +0 -2
  100. package/src/__tests__/edit-propagation.test.ts +107 -11
  101. package/src/__tests__/file-ops-service.test.ts +163 -30
  102. package/src/__tests__/filesystem-tools.test.ts +23 -24
  103. package/src/__tests__/gateway-only-guard.test.ts +2 -5
  104. package/src/__tests__/helpers/gateway-classify-mock.ts +27 -6
  105. package/src/__tests__/helpers/mock-actor-context.ts +49 -0
  106. package/src/__tests__/helpers/mock-conversation.ts +13 -1
  107. package/src/__tests__/host-file-read-tool.test.ts +16 -19
  108. package/src/__tests__/http-user-message-parity.test.ts +1 -1
  109. package/src/__tests__/init-feature-flag-overrides.test.ts +49 -0
  110. package/src/__tests__/injector-chain.test.ts +63 -41
  111. package/src/__tests__/injector-disk-pressure.test.ts +11 -23
  112. package/src/__tests__/inline-skill-load-permissions.test.ts +47 -36
  113. package/src/__tests__/llm-context-resolution.test.ts +73 -1
  114. package/src/__tests__/llm-schema.test.ts +5 -2
  115. package/src/__tests__/managed-skill-lifecycle.test.ts +7 -0
  116. package/src/__tests__/mcp-list-plugin-servers.test.ts +250 -0
  117. package/src/__tests__/media-generate-image.test.ts +131 -21
  118. package/src/__tests__/memory-retrieval-hook.test.ts +100 -7
  119. package/src/__tests__/messages-read-boundary-guard.test.ts +134 -0
  120. package/src/__tests__/mtime-cache.test.ts +3 -1
  121. package/src/__tests__/non-member-access-request.test.ts +0 -20
  122. package/src/__tests__/outbound-slack-persistence.test.ts +40 -1
  123. package/src/__tests__/platform-bash-auto-approve.test.ts +0 -4
  124. package/src/__tests__/plugin-api-store-credential.test.ts +261 -0
  125. package/src/__tests__/plugin-api-webhook-url.test.ts +10 -7
  126. package/src/__tests__/plugin-disabled-state.test.ts +2 -0
  127. package/src/__tests__/plugin-effective-enabled-set.test.ts +55 -3
  128. package/src/__tests__/plugin-execution-context.test.ts +73 -0
  129. package/src/__tests__/plugin-import-boundary-guard.test.ts +5 -1
  130. package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +7 -4
  131. package/src/__tests__/plugin-secret-pattern-contribution.test.ts +1 -1
  132. package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +14 -7
  133. package/src/__tests__/provider-commit-message-generator.test.ts +20 -0
  134. package/src/__tests__/proxy-approval-callback.test.ts +1 -0
  135. package/src/__tests__/qdrant-manager.test.ts +14 -1
  136. package/src/__tests__/reaction-persistence.test.ts +200 -7
  137. package/src/__tests__/require-fresh-approval.test.ts +0 -4
  138. package/src/__tests__/risk-classification-boundary-guard.test.ts +115 -0
  139. package/src/__tests__/run-conversation-turn-persistence.test.ts +460 -105
  140. package/src/__tests__/run-due-schedules.test.ts +21 -0
  141. package/src/__tests__/scaffold-managed-skill-tool.test.ts +187 -18
  142. package/src/__tests__/schedule-routes.test.ts +23 -0
  143. package/src/__tests__/schedule-store.test.ts +17 -0
  144. package/src/__tests__/scoped-approval-grants.test.ts +11 -6
  145. package/src/__tests__/secret-ingress-channel.test.ts +0 -1
  146. package/src/__tests__/secret-ingress-http.test.ts +1 -1
  147. package/src/__tests__/send-endpoint-busy.test.ts +3 -3
  148. package/src/__tests__/skills.test.ts +32 -0
  149. package/src/__tests__/slack-edit-ordering-characterization.test.ts +0 -1
  150. package/src/__tests__/starter-task-flow.test.ts +5 -4
  151. package/src/__tests__/subagent-call-site-routing.test.ts +31 -19
  152. package/src/__tests__/subagent-fork-prompt-role.test.ts +1 -1
  153. package/src/__tests__/subagent-spawn-and-await.test.ts +18 -17
  154. package/src/__tests__/subagent-tool-gate-mode.test.ts +1 -1
  155. package/src/__tests__/subagent-tools.test.ts +81 -101
  156. package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +1 -0
  157. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -1
  158. package/src/__tests__/tool-executor-lifecycle-events.test.ts +132 -5
  159. package/src/__tests__/tool-executor.test.ts +68 -39
  160. package/src/__tests__/turn-events-store.test.ts +43 -0
  161. package/src/__tests__/ui-choice-copy-surfaces.test.ts +1 -1
  162. package/src/__tests__/ui-shape-teaching.test.ts +33 -0
  163. package/src/__tests__/ui-visual-surface.test.ts +1 -1
  164. package/src/__tests__/ui-voice-picker-surface.test.ts +128 -0
  165. package/src/__tests__/ui-work-result-surface.test.ts +1 -1
  166. package/src/__tests__/user-plugin-loader.test.ts +3 -1
  167. package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
  168. package/src/__tests__/visible-app-context.test.ts +16 -9
  169. package/src/__tests__/voice-config-update.test.ts +40 -0
  170. package/src/__tests__/voice-scoped-grant-consumer.test.ts +5 -3
  171. package/src/__tests__/voice-session-bridge.test.ts +85 -29
  172. package/src/__tests__/worker-entrypoint-guards.test.ts +54 -0
  173. package/src/__tests__/worker-plugin-surface.test.ts +77 -0
  174. package/src/__tests__/workspace-migration-142-consolidate-voice-front-door.test.ts +158 -0
  175. package/src/__tests__/workspace-migration-143-repair-deprecated-codex-model-id.test.ts +133 -0
  176. package/src/__tests__/workspace-migration-144-convert-stranded-subscription-openai-profiles.test.ts +316 -0
  177. package/src/__tests__/workspace-migration-145-collapse-profile-bindings-to-entries.test.ts +325 -0
  178. package/src/__tests__/workspace-migration-146-repair-retired-fireworks-deepseek-flash-model-id.test.ts +235 -0
  179. package/src/acp/__tests__/acp-claude-oauth.test.ts +10 -2
  180. package/src/acp/__tests__/auth-required.test.ts +161 -0
  181. package/src/acp/acp-claude-oauth.ts +19 -2
  182. package/src/acp/agent-process.test.ts +100 -0
  183. package/src/acp/agent-process.ts +29 -26
  184. package/src/acp/auth-required.ts +102 -0
  185. package/src/acp/session-manager.test.ts +119 -0
  186. package/src/acp/session-manager.ts +76 -3
  187. package/src/api/events/acp-auth-required.ts +55 -0
  188. package/src/api/events/host-file.ts +2 -2
  189. package/src/api/index.ts +7 -0
  190. package/src/api/surfaces.ts +12 -3
  191. package/src/apps/app-store.ts +3 -0
  192. package/src/bundler/package-resolver.ts +2 -30
  193. package/src/calls/__tests__/voice-session-bridge.test.ts +194 -11
  194. package/src/calls/__tests__/voice-triage-escalate.test.ts +102 -0
  195. package/src/calls/call-controller.ts +19 -3
  196. package/src/calls/call-setup-flow.ts +0 -1
  197. package/src/calls/media-stream-stt-session.ts +15 -0
  198. package/src/calls/voice-session-bridge.ts +115 -41
  199. package/src/calls/voice-triage-escalate.ts +105 -2
  200. package/src/channels/__tests__/plugin-channel-declarations.test.ts +161 -0
  201. package/src/channels/config.ts +13 -0
  202. package/src/channels/plugin-channel-declarations.ts +108 -0
  203. package/src/channels/types.ts +30 -0
  204. package/src/cli/AGENTS.md +5 -2
  205. package/src/cli/bundled-modules.ts +29 -0
  206. package/src/cli/commands/credentials.help.ts +2 -2
  207. package/src/cli/commands/db/repair.ts +4 -8
  208. package/src/cli/commands/domain.ts +6 -3
  209. package/src/cli/commands/email.ts +6 -3
  210. package/src/cli/commands/inference-providers.ts +1 -1
  211. package/src/cli/commands/keys.ts +8 -3
  212. package/src/cli/commands/mcp.help.ts +13 -4
  213. package/src/cli/commands/mcp.ts +9 -0
  214. package/src/cli/commands/memory/__tests__/memory-v2.test.ts +57 -7
  215. package/src/cli/commands/memory/__tests__/memory-v3.test.ts +128 -5
  216. package/src/cli/commands/memory/index.help.ts +84 -28
  217. package/src/cli/commands/memory/index.ts +2 -0
  218. package/src/cli/commands/memory/memory-v2.ts +58 -54
  219. package/src/cli/commands/memory/memory-v3.ts +64 -0
  220. package/src/cli/commands/memory/memory-validate.ts +18 -0
  221. package/src/cli/commands/plugins.ts +85 -36
  222. package/src/cli/commands/schedules.ts +35 -1
  223. package/src/cli/commands/stt.help.ts +27 -2
  224. package/src/cli/commands/trust.ts +3 -14
  225. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +39 -0
  226. package/src/cli/lib/bundled-marketplace.json +14 -1
  227. package/src/cli/lib/upgrade-plugin.ts +42 -0
  228. package/src/config/__tests__/balanced-model-experiment.test.ts +278 -0
  229. package/src/config/__tests__/default-profile-catalog.test.ts +34 -2
  230. package/src/config/__tests__/default-provider.test.ts +6 -1
  231. package/src/config/__tests__/profile-materialization.test.ts +75 -19
  232. package/src/config/assistant-feature-flags.ts +36 -15
  233. package/src/config/balanced-model-experiment.ts +35 -0
  234. package/src/config/bundled-skills/acp/SKILL.md +6 -7
  235. package/src/config/bundled-skills/document-editor/SKILL.md +2 -2
  236. package/src/config/bundled-skills/document-editor/TOOLS.json +2 -2
  237. package/src/config/bundled-skills/image-studio/SKILL.md +5 -4
  238. package/src/config/bundled-skills/image-studio/TOOLS.json +1 -1
  239. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +101 -0
  240. package/src/config/bundled-skills/media-processing/services/preprocess.ts +14 -4
  241. package/src/config/bundled-skills/settings/TOOLS.json +3 -3
  242. package/src/config/bundled-skills/settings/tools/navigate-settings-tab.test.ts +65 -0
  243. package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +7 -1
  244. package/src/config/bundled-skills/settings/tools/shared.ts +16 -0
  245. package/src/config/bundled-skills/settings/tools/voice-config-update.ts +19 -1
  246. package/src/config/bundled-skills/skill-management/TOOLS.json +9 -3
  247. package/src/config/bundled-skills/subagent/SKILL.md +17 -12
  248. package/src/config/bundled-skills/subagent/TOOLS.json +4 -4
  249. package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +22 -1
  250. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +9 -2
  251. package/src/config/call-site-defaults.ts +11 -5
  252. package/src/config/default-profile-catalog.ts +179 -16
  253. package/src/config/default-profile-names.ts +4 -1
  254. package/src/config/default-provider-resolution.ts +4 -0
  255. package/src/config/feature-flag-registry.json +12 -12
  256. package/src/config/llm-context-resolution.ts +11 -3
  257. package/src/config/llm-resolver.ts +28 -1
  258. package/src/config/profile-materialization.ts +70 -22
  259. package/src/config/schemas/__tests__/live-voice.test.ts +107 -4
  260. package/src/config/schemas/call-site-catalog.ts +4 -4
  261. package/src/config/schemas/live-voice.ts +57 -23
  262. package/src/config/schemas/llm.ts +59 -32
  263. package/src/config/schemas/mcp.ts +23 -0
  264. package/src/config/schemas/plugin-updates.ts +6 -2
  265. package/src/config/schemas/stt.ts +1 -0
  266. package/src/config/skills.ts +9 -2
  267. package/src/context/outbound-sanitize.ts +96 -1
  268. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +1 -1
  269. package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +82 -0
  270. package/src/daemon/conversation-agent-loop-handlers.ts +15 -10
  271. package/src/daemon/conversation-agent-loop.ts +31 -19
  272. package/src/daemon/conversation-messaging.ts +5 -1
  273. package/src/daemon/conversation-notifiers.ts +20 -10
  274. package/src/daemon/conversation-process.ts +20 -6
  275. package/src/daemon/conversation-runtime-assembly.ts +12 -6
  276. package/src/daemon/conversation-store.ts +14 -4
  277. package/src/daemon/conversation-surfaces.ts +75 -26
  278. package/src/daemon/conversation-tool-setup.ts +3 -6
  279. package/src/daemon/conversation.ts +154 -51
  280. package/src/daemon/doordash-steps.ts +2 -2
  281. package/src/daemon/lifecycle.ts +14 -1
  282. package/src/daemon/mcp-reload-service.ts +36 -6
  283. package/src/daemon/process-message.ts +13 -26
  284. package/src/daemon/providers-setup.ts +6 -3
  285. package/src/daemon/trust-context-types.ts +29 -0
  286. package/src/daemon/trust-context.ts +12 -7
  287. package/src/daemon/wake-conversation-ops.ts +3 -2
  288. package/src/daemon/windows-compiled-entry.ts +4 -0
  289. package/src/documents/document-store.ts +143 -240
  290. package/src/hooks/hook-loader.ts +3 -3
  291. package/src/hooks/registry.ts +103 -45
  292. package/src/hooks/types.ts +5 -0
  293. package/src/inbound/__tests__/oauth-callback-url.test.ts +83 -0
  294. package/src/inbound/oauth-callback-url.ts +61 -0
  295. package/src/ipc/gateway-client.test.ts +1 -1
  296. package/src/ipc/gateway-client.ts +14 -21
  297. package/src/ipc/gateway-flag-listener.ts +17 -3
  298. package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +1 -104
  299. package/src/live-voice/__tests__/live-voice-events.test.ts +7 -8
  300. package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +1050 -0
  301. package/src/live-voice/__tests__/live-voice-metrics.test.ts +115 -8
  302. package/src/live-voice/__tests__/live-voice-photo.test.ts +100 -0
  303. package/src/live-voice/__tests__/live-voice-progress.test.ts +60 -194
  304. package/src/live-voice/__tests__/live-voice-stt.test.ts +14 -0
  305. package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +29 -0
  306. package/src/live-voice/__tests__/live-voice-tts-session.test.ts +0 -483
  307. package/src/live-voice/__tests__/live-voice-vad.test.ts +0 -16
  308. package/src/live-voice/__tests__/progress-narration.test.ts +214 -0
  309. package/src/live-voice/live-voice-archive.ts +2 -0
  310. package/src/live-voice/live-voice-manager.ts +16 -3
  311. package/src/live-voice/live-voice-metrics.ts +57 -32
  312. package/src/live-voice/live-voice-photo.ts +1 -2
  313. package/src/live-voice/live-voice-session.ts +598 -323
  314. package/src/live-voice/progress-narration.ts +277 -0
  315. package/src/live-voice/protocol.ts +21 -1
  316. package/src/live-voice/windows-compiled-live-voice.ts +4 -0
  317. package/src/mcp/__tests__/effective-config.test.ts +238 -0
  318. package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
  319. package/src/mcp/__tests__/mcp-oauth-client-registration.test.ts +200 -0
  320. package/src/mcp/__tests__/mcp-oauth-provider.test.ts +9 -9
  321. package/src/mcp/__tests__/plugin-server-credential-isolation.test.ts +95 -0
  322. package/src/mcp/client.ts +16 -11
  323. package/src/mcp/effective-config.ts +113 -0
  324. package/src/mcp/manager.ts +11 -6
  325. package/src/mcp/mcp-auth-orchestrator.ts +13 -22
  326. package/src/mcp/mcp-oauth-provider.ts +205 -240
  327. package/src/monitoring/__tests__/plugin-auto-update.test.ts +166 -3
  328. package/src/monitoring/control.ts +1 -0
  329. package/src/monitoring/db-integrity-sample.ts +4 -5
  330. package/src/monitoring/plugin-auto-update.ts +128 -24
  331. package/src/notifications/AGENTS.md +2 -0
  332. package/src/notifications/approval-card-data.ts +33 -0
  333. package/src/notifications/signal.ts +1 -0
  334. package/src/permissions/AGENTS.md +16 -0
  335. package/src/permissions/checker.test.ts +75 -122
  336. package/src/permissions/checker.ts +44 -560
  337. package/src/permissions/confirmation-guardian-request.test.ts +15 -11
  338. package/src/permissions/confirmation-guardian-request.ts +2 -2
  339. package/src/permissions/prompter.ts +1 -5
  340. package/src/permissions/question-guardian-request.test.ts +14 -6
  341. package/src/permissions/question-guardian-request.ts +1 -2
  342. package/src/persistence/attachments-store.ts +8 -1
  343. package/src/persistence/bookmark-crud.ts +3 -7
  344. package/src/persistence/conversation-attention-store.ts +16 -45
  345. package/src/persistence/conversation-crud.ts +33 -4
  346. package/src/persistence/conversation-lineage.ts +9 -0
  347. package/src/persistence/conversation-queries.ts +182 -52
  348. package/src/persistence/delivery-crud.ts +150 -36
  349. package/src/persistence/embeddings/qdrant-manager.ts +84 -49
  350. package/src/persistence/external-conversation-store.ts +32 -4
  351. package/src/persistence/llm-request-log-store.ts +4 -10
  352. package/src/persistence/llm-usage-store.ts +8 -3
  353. package/src/persistence/message-reads.test.ts +197 -0
  354. package/src/persistence/message-reads.ts +211 -0
  355. package/src/persistence/migrations/360-add-document-workspace-path.ts +5 -14
  356. package/src/persistence/migrations/366-chatgpt-subscription-row-identity.test.ts +120 -0
  357. package/src/persistence/migrations/366-chatgpt-subscription-row-identity.ts +62 -0
  358. package/src/persistence/real-user-turn-filter.ts +27 -3
  359. package/src/persistence/schema/documents.ts +4 -4
  360. package/src/persistence/steps.ts +9 -0
  361. package/src/plugin-api/__tests__/oauth-callback-url-export.test.ts +29 -0
  362. package/src/plugin-api/constants.ts +8 -0
  363. package/src/plugin-api/conversation-turn.ts +195 -5
  364. package/src/plugin-api/index.ts +38 -6
  365. package/src/plugin-api/resolve-credential.ts +3 -2
  366. package/src/plugin-api/store-credential.ts +146 -0
  367. package/src/plugin-api/vision-support.test.ts +1 -1
  368. package/src/plugin-api/webhook-url.ts +13 -11
  369. package/src/plugins/__tests__/mcp-servers.test.ts +371 -0
  370. package/src/plugins/defaults/main.ts +21 -7
  371. package/src/plugins/defaults/memory/AGENTS.md +15 -3
  372. package/src/plugins/defaults/memory/__tests__/buffer-format.test.ts +204 -0
  373. package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +72 -0
  374. package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +4 -1
  375. package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +4 -1
  376. package/src/plugins/defaults/memory/__tests__/memory-tier-boundary-guard.test.ts +0 -1
  377. package/src/plugins/defaults/memory/buffer-format.ts +165 -0
  378. package/src/plugins/defaults/memory/context-search/sources/conversations.ts +6 -0
  379. package/src/plugins/defaults/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +77 -0
  380. package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +24 -6
  381. package/src/plugins/defaults/memory/graph/image-ref-utils.ts +3 -0
  382. package/src/plugins/defaults/memory/graph/tool-handlers.ts +1 -30
  383. package/src/plugins/defaults/memory/graph-topology/pending-buffer.test.ts +34 -0
  384. package/src/plugins/defaults/memory/graph-topology/pending-buffer.ts +17 -24
  385. package/src/plugins/defaults/memory/hooks/post-compact.ts +1 -4
  386. package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +53 -5
  387. package/src/plugins/defaults/memory/indexer.ts +3 -1
  388. package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +19 -7
  389. package/src/plugins/defaults/memory/memory-retrospective-job.ts +4 -4
  390. package/src/plugins/defaults/memory/src/__tests__/memory-v3-gate-stats.test.ts +281 -0
  391. package/src/plugins/defaults/memory/src/memory-v2-routes.ts +12 -10
  392. package/src/plugins/defaults/memory/src/memory-v3-routes.ts +207 -0
  393. package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +147 -0
  394. package/src/plugins/defaults/memory/substrate/__tests__/consolidation-prompt-flag-gating-guard.test.ts +8 -0
  395. package/src/plugins/defaults/memory/substrate/__tests__/edge-index.test.ts +0 -30
  396. package/src/plugins/defaults/memory/substrate/__tests__/ingest.test.ts +73 -1
  397. package/src/plugins/defaults/memory/substrate/__tests__/page-index.test.ts +37 -0
  398. package/src/plugins/defaults/memory/substrate/__tests__/page-links.test.ts +208 -0
  399. package/src/plugins/defaults/memory/substrate/__tests__/prompts-consolidation.test.ts +158 -1
  400. package/src/plugins/defaults/memory/substrate/__tests__/static-context.test.ts +195 -58
  401. package/src/plugins/defaults/memory/substrate/consolidation-job.ts +93 -24
  402. package/src/plugins/defaults/memory/substrate/edge-index.ts +0 -31
  403. package/src/plugins/defaults/memory/substrate/ingest.ts +59 -0
  404. package/src/plugins/defaults/memory/substrate/page-index.ts +35 -8
  405. package/src/plugins/defaults/memory/substrate/page-links.ts +133 -0
  406. package/src/plugins/defaults/memory/substrate/page-store.ts +10 -0
  407. package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +124 -34
  408. package/src/plugins/defaults/memory/substrate/skill-content.ts +8 -1
  409. package/src/plugins/defaults/memory/substrate/static-context.ts +160 -33
  410. package/src/plugins/defaults/memory/substrate/sweep-job.ts +2 -4
  411. package/src/plugins/defaults/memory/v1/graph/extraction.ts +3 -1
  412. package/src/plugins/defaults/memory/v3/__tests__/injection.test.ts +18 -0
  413. package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +66 -1
  414. package/src/plugins/defaults/memory/v3/card.ts +9 -9
  415. package/src/plugins/defaults/memory/v3/core-set.test.ts +7 -0
  416. package/src/plugins/defaults/memory/v3/core-set.ts +5 -1
  417. package/src/plugins/defaults/memory/v3/edge.ts +13 -57
  418. package/src/plugins/defaults/memory/v3/injector.ts +8 -0
  419. package/src/plugins/defaults/memory/v3/prune.ts +2 -0
  420. package/src/plugins/defaults/memory/v3/selection-log-store.ts +2 -0
  421. package/src/plugins/defaults/memory/v3/shadow-plugin.ts +23 -9
  422. package/src/plugins/defaults/memory/worker-control.ts +1 -0
  423. package/src/plugins/defaults/memory/worker.ts +6 -3
  424. package/src/plugins/defaults/worker-entrypoints.ts +3 -0
  425. package/src/plugins/external-plugin-loader.ts +47 -0
  426. package/src/plugins/mcp-servers.ts +361 -0
  427. package/src/plugins/mtime-cache.ts +37 -46
  428. package/src/plugins/pipeline.ts +14 -7
  429. package/src/plugins/plugin-execution-context.ts +35 -11
  430. package/src/plugins/worker-plugin-surface.ts +33 -0
  431. package/src/prompts/templates/system-sections.ts +0 -7
  432. package/src/providers/__tests__/connection-model-compat.test.ts +1 -1
  433. package/src/providers/__tests__/context-overflow-error.test.ts +24 -0
  434. package/src/providers/__tests__/dispatch-connection-routing.test.ts +214 -2
  435. package/src/providers/__tests__/preflight-resolved-config.test.ts +57 -0
  436. package/src/providers/__tests__/retry-callsite.test.ts +25 -2
  437. package/src/providers/anthropic/__tests__/pause-turn-continuation.test.ts +170 -0
  438. package/src/providers/anthropic/client.ts +332 -241
  439. package/src/providers/call-site-routing.ts +30 -3
  440. package/src/providers/connection-resolution.ts +194 -11
  441. package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +4 -0
  442. package/src/providers/inference/adapter-factory.ts +3 -0
  443. package/src/providers/inference/auth.ts +6 -0
  444. package/src/providers/inference/connection-availability.ts +24 -2
  445. package/src/providers/inference/connections.ts +2 -0
  446. package/src/providers/model-catalog.ts +3 -3
  447. package/src/providers/model-intents.ts +28 -8
  448. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +163 -40
  449. package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +125 -2
  450. package/src/providers/openai/chat-completions-provider.ts +133 -36
  451. package/src/providers/openai/codex-models.ts +2 -1
  452. package/src/providers/provider-send-message.ts +32 -3
  453. package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +433 -0
  454. package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +625 -0
  455. package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +34 -0
  456. package/src/providers/speech-to-text/__tests__/resolve.test.ts +285 -6
  457. package/src/providers/speech-to-text/deepgram-flux-frames.ts +395 -0
  458. package/src/providers/speech-to-text/deepgram-flux-realtime.ts +679 -0
  459. package/src/providers/speech-to-text/provider-catalog.ts +99 -8
  460. package/src/providers/speech-to-text/resolve.ts +25 -2
  461. package/src/routes/control.ts +1 -0
  462. package/src/routes/route-host-client.ts +1 -0
  463. package/src/routes/route-host-protocol.ts +7 -0
  464. package/src/routes/worker.ts +48 -15
  465. package/src/runtime/AGENTS.md +16 -17
  466. package/src/runtime/access-request-helper.ts +9 -12
  467. package/src/runtime/agent-wake.ts +18 -15
  468. package/src/runtime/effective-capabilities.test.ts +43 -0
  469. package/src/runtime/effective-capabilities.ts +27 -0
  470. package/src/runtime/guardian-reply-router.ts +6 -2
  471. package/src/runtime/pre-first-message-gate.ts +4 -0
  472. package/src/runtime/routes/__tests__/acp-claude-auth-routes.test.ts +12 -4
  473. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +522 -2
  474. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +52 -0
  475. package/src/runtime/routes/__tests__/default-provider-routes.test.ts +61 -0
  476. package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +44 -0
  477. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +102 -1
  478. package/src/runtime/routes/__tests__/plugins-routes.test.ts +132 -35
  479. package/src/runtime/routes/__tests__/schedule-routes-disarm-reason.test.ts +215 -0
  480. package/src/runtime/routes/__tests__/stt-routes.test.ts +25 -0
  481. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +55 -6
  482. package/src/runtime/routes/__tests__/user-route-dispatcher-host.test.ts +52 -1
  483. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +133 -1
  484. package/src/runtime/routes/channel-availability-routes.ts +32 -14
  485. package/src/runtime/routes/channel-route-shared.ts +0 -6
  486. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +6 -6
  487. package/src/runtime/routes/conversation-list-routes.ts +181 -23
  488. package/src/runtime/routes/conversation-management-routes.ts +17 -12
  489. package/src/runtime/routes/conversation-query-routes.ts +40 -27
  490. package/src/runtime/routes/conversation-routes.ts +43 -29
  491. package/src/runtime/routes/credential-prompt-routes.ts +4 -7
  492. package/src/runtime/routes/credential-routes.ts +26 -82
  493. package/src/runtime/routes/default-provider-routes.ts +15 -0
  494. package/src/runtime/routes/documents-routes.ts +3 -222
  495. package/src/runtime/routes/inbound-message-handler.ts +21 -45
  496. package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +0 -1
  497. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -9
  498. package/src/runtime/routes/inbound-stages/admission-policy.ts +1 -17
  499. package/src/runtime/routes/inbound-stages/bootstrap-intercept.test.ts +0 -1
  500. package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +2 -3
  501. package/src/runtime/routes/inbound-stages/edit-intercept.ts +101 -79
  502. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +0 -1
  503. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +12 -7
  504. package/src/runtime/routes/inbound-stages/reaction-intercept.test.ts +91 -8
  505. package/src/runtime/routes/inbound-stages/reaction-intercept.ts +72 -79
  506. package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +2 -3
  507. package/src/runtime/routes/inference-profiles-routes.ts +20 -11
  508. package/src/runtime/routes/inference-provider-connection-routes.ts +77 -15
  509. package/src/runtime/routes/log-export-routes.ts +3 -0
  510. package/src/runtime/routes/mcp-auth-routes.ts +148 -57
  511. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +2 -0
  512. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +3 -0
  513. package/src/runtime/routes/playground/inject-failures.ts +2 -2
  514. package/src/runtime/routes/playground/reset-circuit.ts +1 -1
  515. package/src/runtime/routes/plugins-routes.ts +38 -8
  516. package/src/runtime/routes/schedule-routes.ts +94 -7
  517. package/src/runtime/routes/settings-routes.ts +6 -6
  518. package/src/runtime/routes/stt-routes.ts +31 -25
  519. package/src/runtime/routes/surface-action-routes.ts +20 -19
  520. package/src/runtime/routes/surface-conversation-resolver.ts +3 -0
  521. package/src/runtime/routes/user-route-dispatcher.ts +69 -15
  522. package/src/runtime/routes/user-route-import.ts +108 -0
  523. package/src/runtime/routes/user-route-resolution.ts +18 -1
  524. package/src/runtime/routes/workspace-routes.ts +0 -9
  525. package/src/runtime/routes/workspace-utils.ts +3 -13
  526. package/src/runtime/services/conversation-serializer.ts +7 -2
  527. package/src/schedule/__tests__/plugin-schedule-declarations.test.ts +68 -5
  528. package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +81 -0
  529. package/src/schedule/plugin-schedule-availability.ts +58 -0
  530. package/src/schedule/plugin-schedule-declarations.ts +23 -27
  531. package/src/schedule/plugin-schedule-reconciler.ts +12 -3
  532. package/src/schedule/schedule-store.ts +5 -1
  533. package/src/schedule/scheduler.ts +9 -4
  534. package/src/schedule/worker-control.ts +1 -0
  535. package/src/schedule/worker.ts +6 -0
  536. package/src/security/oauth2.ts +6 -22
  537. package/src/stt/__tests__/daemon-batch-transcriber.test.ts +22 -0
  538. package/src/stt/__tests__/types.test.ts +94 -0
  539. package/src/stt/daemon-batch-transcriber.ts +10 -0
  540. package/src/stt/stt-stream-session.ts +8 -4
  541. package/src/stt/types.ts +103 -0
  542. package/src/subagent/__tests__/consult-prompt.test.ts +26 -15
  543. package/src/subagent/consult-context.ts +11 -11
  544. package/src/subagent/consult-prompt.ts +26 -35
  545. package/src/subagent/manager.ts +21 -40
  546. package/src/subagent/notify.ts +7 -1
  547. package/src/subagent/types.ts +15 -12
  548. package/src/tools/__tests__/tool-input-schemas.test.ts +7 -7
  549. package/src/tools/acp/spawn.test.ts +97 -0
  550. package/src/tools/acp/spawn.ts +38 -4
  551. package/src/tools/credentials/ref-parse.ts +35 -0
  552. package/src/tools/credentials/resolve.ts +4 -10
  553. package/src/tools/credentials/store.ts +168 -0
  554. package/src/tools/document/document-tool.ts +12 -3
  555. package/src/tools/executor.ts +53 -15
  556. package/src/tools/filesystem/read.ts +27 -10
  557. package/src/tools/host-filesystem/read.ts +27 -15
  558. package/src/tools/network/url-safety.ts +9 -16
  559. package/src/tools/permission-checker.ts +43 -52
  560. package/src/tools/registry.ts +2 -1
  561. package/src/tools/shared/filesystem/file-ops-service.ts +63 -35
  562. package/src/tools/shared/filesystem/legacy-read-args.ts +22 -0
  563. package/src/tools/shared/filesystem/types.ts +5 -5
  564. package/src/tools/skills/scaffold-managed.ts +25 -7
  565. package/src/tools/subagent/spawn.ts +28 -88
  566. package/src/tools/tool-types.ts +26 -13
  567. package/src/tools/types.ts +6 -6
  568. package/src/tools/ui-surface/surface-shape-docs.ts +12 -1
  569. package/src/tools/workflows/run-workflow.ts +1 -2
  570. package/src/tts/__tests__/reasoning-tag-filter.test.ts +78 -0
  571. package/src/tts/reasoning-tag-filter.ts +89 -0
  572. package/src/util/__tests__/worker-process-command.test.ts +37 -0
  573. package/src/util/logger.ts +16 -0
  574. package/src/util/think-tag-stream.ts +95 -0
  575. package/src/util/worker-process.ts +37 -4
  576. package/src/windows-compiled-cli.ts +32 -0
  577. package/src/windows-compiled-entry.ts +4 -0
  578. package/src/windows-compiled-logger.ts +6 -0
  579. package/src/windows-compiled-worker-entry.ts +29 -0
  580. package/src/workspace/byok-default-profile-ensure.ts +76 -24
  581. package/src/workspace/custom-profile-ensure.ts +4 -24
  582. package/src/workspace/migrations/142-consolidate-voice-front-door.ts +70 -0
  583. package/src/workspace/migrations/143-repair-deprecated-codex-model-id.ts +134 -0
  584. package/src/workspace/migrations/144-convert-stranded-subscription-openai-profiles.ts +265 -0
  585. package/src/workspace/migrations/145-collapse-profile-bindings-to-entries.ts +328 -0
  586. package/src/workspace/migrations/146-repair-retired-fireworks-deepseek-flash-model-id.ts +195 -0
  587. package/src/workspace/migrations/__tests__/141-stt-english-default-to-multilingual.test.ts +0 -10
  588. package/src/workspace/migrations/registry.ts +10 -0
  589. package/src/workspace/provider-commit-message-generator.ts +7 -5
  590. package/src/__tests__/document-workspace-file.test.ts +0 -467
  591. package/src/live-voice/__tests__/front-decision.test.ts +0 -645
  592. package/src/live-voice/front-decision.ts +0 -476
  593. package/src/permissions/ipc-risk-types.ts +0 -143
  594. package/src/permissions/risk-types.ts +0 -76
  595. package/src/subagent/__tests__/consult-transcript.test.ts +0 -184
  596. package/src/subagent/consult-transcript.ts +0 -90
@@ -103,6 +103,7 @@ mock.module("../daemon/date-context.js", () => ({
103
103
  formatTurnTimestamp: () => FIXED_TURN_TIMESTAMP,
104
104
  }));
105
105
 
106
+ import type { SurfaceDataByType } from "../api/surfaces.js";
106
107
  import { resolveCallSiteConfig } from "../config/llm-resolver.js";
107
108
  import { LLMSchema } from "../config/schemas/llm.js";
108
109
  import { REFUSAL_FALLBACK_TEXT } from "../context/refusal-quarantine.js";
@@ -136,7 +137,7 @@ import {
136
137
  stripInjectionsForCompaction,
137
138
  stripNowScratchpad,
138
139
  } from "../daemon/conversation-runtime-assembly.js";
139
- import type { SurfaceData, SurfaceType } from "../daemon/message-protocol.js";
140
+ import type { SurfaceStateEntry } from "../daemon/conversation-surface-state.js";
140
141
  import { buildPkbReminder } from "../daemon/pkb-reminder-builder.js";
141
142
  import type { TrustContext } from "../daemon/trust-context-types.js";
142
143
  import {
@@ -161,6 +162,7 @@ import { wrapUntrustedContent } from "../security/untrusted-content.js";
161
162
  import { getSubagentManager } from "../subagent/index.js";
162
163
  import type { SubagentState } from "../subagent/types.js";
163
164
  import { getWorkspacePromptPath } from "../util/platform.js";
165
+ import { asConversation } from "./helpers/mock-conversation.js";
164
166
 
165
167
  // `applyRuntimeInjections` self-resolves the Slack active-thread focus block by
166
168
  // reading the live conversation's persisted message rows, so the schema must
@@ -215,27 +217,30 @@ function seedActiveSurfaceConversation(
215
217
  conversationId: string,
216
218
  workspaceText: string,
217
219
  surfaceId: string,
218
- data: SurfaceData,
220
+ data: SurfaceDataByType["dynamic_page"],
219
221
  channelCapabilities?: ChannelCapabilities,
220
222
  commandIntent?: { type: string; payload?: string; languageCode?: string },
221
223
  currentTurnTemporalSnapshot?: {
222
224
  clientTimezone: string | null;
225
+ timeSinceLastMessage: string | null;
223
226
  },
224
227
  ): void {
225
- setConversation(conversationId, {
228
+ setConversation(
226
229
  conversationId,
227
- workingDir: "/sandbox",
228
- workspaceTopLevelContext: workspaceText,
229
- workspaceTopLevelDirty: false,
230
- currentActiveSurfaceId: surfaceId,
231
- surfaceState: new Map<
232
- string,
233
- { surfaceType: SurfaceType; data: SurfaceData }
234
- >([[surfaceId, { surfaceType: "dynamic_page", data }]]),
235
- channelCapabilities: channelCapabilities ?? undefined,
236
- commandIntent,
237
- currentTurnTemporalSnapshot,
238
- } as never);
230
+ asConversation({
231
+ conversationId,
232
+ workingDir: "/sandbox",
233
+ workspaceTopLevelContext: workspaceText,
234
+ workspaceTopLevelDirty: false,
235
+ currentActiveSurfaceId: surfaceId,
236
+ surfaceState: new Map<string, SurfaceStateEntry>([
237
+ [surfaceId, { surfaceType: "dynamic_page", data }],
238
+ ]),
239
+ channelCapabilities: channelCapabilities ?? undefined,
240
+ commandIntent,
241
+ currentTurnTemporalSnapshot,
242
+ }),
243
+ );
239
244
  }
240
245
 
241
246
  function clearWorkspaceContext(): void {
@@ -252,15 +257,18 @@ function seedChannelCapabilitiesConversation(
252
257
  caps: ChannelCapabilities | null,
253
258
  transportHints?: string[],
254
259
  ): void {
255
- setConversation("runtime-assembly-fallback", {
256
- conversationId: "runtime-assembly-fallback",
257
- workingDir: "/sandbox",
258
- workspaceTopLevelContext: "",
259
- workspaceTopLevelDirty: false,
260
- surfaceState: new Map(),
261
- channelCapabilities: caps ?? undefined,
262
- transportHints,
263
- } as never);
260
+ setConversation(
261
+ "runtime-assembly-fallback",
262
+ asConversation({
263
+ conversationId: "runtime-assembly-fallback",
264
+ workingDir: "/sandbox",
265
+ workspaceTopLevelContext: "",
266
+ workspaceTopLevelDirty: false,
267
+ surfaceState: new Map(),
268
+ channelCapabilities: caps ?? undefined,
269
+ transportHints,
270
+ }),
271
+ );
264
272
  }
265
273
 
266
274
  // ---------------------------------------------------------------------------
@@ -986,6 +994,7 @@ describe("applyRuntimeInjections — injection mode", () => {
986
994
  { type: "start" },
987
995
  {
988
996
  clientTimezone: null,
997
+ timeSinceLastMessage: null,
989
998
  },
990
999
  );
991
1000
  });
@@ -1023,15 +1032,18 @@ describe("applyRuntimeInjections — injection mode", () => {
1023
1032
  // rehydration-order tests in conversation-lifecycle.test.ts). background-turn
1024
1033
  // fires only for a background/scheduled live conversation, so register one
1025
1034
  // under the turn's conversation id.
1026
- setConversation("injection-mode-conv", {
1027
- conversationId: "injection-mode-conv",
1028
- workingDir: "/sandbox",
1029
- workspaceTopLevelContext: "",
1030
- workspaceTopLevelDirty: false,
1031
- surfaceState: new Map(),
1032
- channelCapabilities,
1033
- conversationType: "background",
1034
- } as never);
1035
+ setConversation(
1036
+ "injection-mode-conv",
1037
+ asConversation({
1038
+ conversationId: "injection-mode-conv",
1039
+ workingDir: "/sandbox",
1040
+ workspaceTopLevelContext: "",
1041
+ workspaceTopLevelDirty: false,
1042
+ surfaceState: new Map(),
1043
+ channelCapabilities,
1044
+ conversationType: "background",
1045
+ }),
1046
+ );
1035
1047
 
1036
1048
  const { blocks } = await applyRuntimeInjections(baseMessages, fullOptions);
1037
1049
 
@@ -2227,20 +2239,24 @@ describe("applyRuntimeInjections with unifiedTurnContext", () => {
2227
2239
  // context (so the injector sources the interface label to match
2228
2240
  // `sampleOptions.interfaceName`).
2229
2241
  function seedTemporalSnapshot(): void {
2230
- setConversation("runtime-assembly-fallback", {
2231
- conversationId: "runtime-assembly-fallback",
2232
- workingDir: "/sandbox",
2233
- workspaceTopLevelContext: "",
2234
- workspaceTopLevelDirty: false,
2235
- surfaceState: new Map(),
2236
- currentTurnTemporalSnapshot: {
2237
- clientTimezone: null,
2238
- },
2239
- currentTurnInterfaceContext: {
2240
- userMessageInterface: "macos",
2241
- assistantMessageInterface: "macos",
2242
- },
2243
- } as never);
2242
+ setConversation(
2243
+ "runtime-assembly-fallback",
2244
+ asConversation({
2245
+ conversationId: "runtime-assembly-fallback",
2246
+ workingDir: "/sandbox",
2247
+ workspaceTopLevelContext: "",
2248
+ workspaceTopLevelDirty: false,
2249
+ surfaceState: new Map(),
2250
+ currentTurnTemporalSnapshot: {
2251
+ clientTimezone: null,
2252
+ timeSinceLastMessage: null,
2253
+ },
2254
+ currentTurnInterfaceContext: {
2255
+ userMessageInterface: "macos",
2256
+ assistantMessageInterface: "macos",
2257
+ },
2258
+ }),
2259
+ );
2244
2260
  }
2245
2261
 
2246
2262
  test("injects the turn-context block when the inputs are provided", async () => {
@@ -2327,17 +2343,20 @@ describe("applyRuntimeInjections timezone resolution", () => {
2327
2343
  clientTimezone: string | null,
2328
2344
  timeSinceLastMessage: string | null = null,
2329
2345
  ): void {
2330
- setConversation("runtime-assembly-fallback", {
2331
- conversationId: "runtime-assembly-fallback",
2332
- workingDir: "/sandbox",
2333
- workspaceTopLevelContext: "",
2334
- workspaceTopLevelDirty: false,
2335
- surfaceState: new Map(),
2336
- currentTurnTemporalSnapshot: {
2337
- clientTimezone,
2338
- timeSinceLastMessage,
2339
- },
2340
- } as never);
2346
+ setConversation(
2347
+ "runtime-assembly-fallback",
2348
+ asConversation({
2349
+ conversationId: "runtime-assembly-fallback",
2350
+ workingDir: "/sandbox",
2351
+ workspaceTopLevelContext: "",
2352
+ workspaceTopLevelDirty: false,
2353
+ surfaceState: new Map(),
2354
+ currentTurnTemporalSnapshot: {
2355
+ clientTimezone,
2356
+ timeSinceLastMessage,
2357
+ },
2358
+ }),
2359
+ );
2341
2360
  }
2342
2361
 
2343
2362
  function injectedText(result: { messages: Message[] }): string {
@@ -2491,20 +2510,24 @@ describe("applyRuntimeInjections blocks.unifiedTurnContext", () => {
2491
2510
  // context (so the injector sources the interface label to match
2492
2511
  // `sampleOptions.interfaceName`).
2493
2512
  function seedTemporalSnapshot(): void {
2494
- setConversation("runtime-assembly-fallback", {
2495
- conversationId: "runtime-assembly-fallback",
2496
- workingDir: "/sandbox",
2497
- workspaceTopLevelContext: "",
2498
- workspaceTopLevelDirty: false,
2499
- surfaceState: new Map(),
2500
- currentTurnTemporalSnapshot: {
2501
- clientTimezone: null,
2502
- },
2503
- currentTurnInterfaceContext: {
2504
- userMessageInterface: "macos",
2505
- assistantMessageInterface: "macos",
2506
- },
2507
- } as never);
2513
+ setConversation(
2514
+ "runtime-assembly-fallback",
2515
+ asConversation({
2516
+ conversationId: "runtime-assembly-fallback",
2517
+ workingDir: "/sandbox",
2518
+ workspaceTopLevelContext: "",
2519
+ workspaceTopLevelDirty: false,
2520
+ surfaceState: new Map(),
2521
+ currentTurnTemporalSnapshot: {
2522
+ clientTimezone: null,
2523
+ timeSinceLastMessage: null,
2524
+ },
2525
+ currentTurnInterfaceContext: {
2526
+ userMessageInterface: "macos",
2527
+ assistantMessageInterface: "macos",
2528
+ },
2529
+ }),
2530
+ );
2508
2531
  }
2509
2532
 
2510
2533
  test("captures unifiedTurnContext when tail is a user message", async () => {
@@ -2688,15 +2711,18 @@ describe("applyRuntimeInjections — subagent status", () => {
2688
2711
  // a fallback fake carrying that delegation for the seeded children to
2689
2712
  // surface.
2690
2713
  beforeEach(() => {
2691
- setConversation(FALLBACK_CONVERSATION_ID, {
2692
- conversationId: FALLBACK_CONVERSATION_ID,
2693
- workingDir: "/sandbox",
2694
- workspaceTopLevelContext: "",
2695
- workspaceTopLevelDirty: false,
2696
- surfaceState: new Map(),
2697
- getSubagentChildren: () =>
2698
- getSubagentManager().getChildrenOf(FALLBACK_CONVERSATION_ID),
2699
- } as never);
2714
+ setConversation(
2715
+ FALLBACK_CONVERSATION_ID,
2716
+ asConversation({
2717
+ conversationId: FALLBACK_CONVERSATION_ID,
2718
+ workingDir: "/sandbox",
2719
+ workspaceTopLevelContext: "",
2720
+ workspaceTopLevelDirty: false,
2721
+ surfaceState: new Map(),
2722
+ getSubagentChildren: () =>
2723
+ getSubagentManager().getChildrenOf(FALLBACK_CONVERSATION_ID),
2724
+ }),
2725
+ );
2700
2726
  });
2701
2727
 
2702
2728
  afterEach(() => {
@@ -2750,14 +2776,17 @@ describe("applyRuntimeInjections — subagent status", () => {
2750
2776
 
2751
2777
  test("skips subagent status when the conversation is itself a subagent", async () => {
2752
2778
  // GIVEN the live conversation is itself a subagent (no nesting)
2753
- setConversation("runtime-assembly-fallback", {
2754
- conversationId: "runtime-assembly-fallback",
2755
- workingDir: "/sandbox",
2756
- workspaceTopLevelContext: "",
2757
- workspaceTopLevelDirty: false,
2758
- surfaceState: new Map(),
2759
- isSubagent: true,
2760
- } as never);
2779
+ setConversation(
2780
+ "runtime-assembly-fallback",
2781
+ asConversation({
2782
+ conversationId: "runtime-assembly-fallback",
2783
+ workingDir: "/sandbox",
2784
+ workspaceTopLevelContext: "",
2785
+ workspaceTopLevelDirty: false,
2786
+ surfaceState: new Map(),
2787
+ isSubagent: true,
2788
+ }),
2789
+ );
2761
2790
  // AND a child is registered under its id
2762
2791
  seedSubagentChild(
2763
2792
  "runtime-assembly-fallback",
@@ -3995,6 +4024,59 @@ describe("Slack channel chronological rendering — multi-thread", () => {
3995
4024
  expect(allText).not.toContain("private guardian-only context");
3996
4025
  });
3997
4026
 
4027
+ // Slack builds provider history from rows rather than `this.messages`, so a
4028
+ // guardian card dropped only at `Conversation.loadFromDb` would still reach
4029
+ // the model here -- the channel the incident happened on.
4030
+ test("loadSlackChronologicalContext drops guardian card rows", () => {
4031
+ const caps: ChannelCapabilities = {
4032
+ channel: "slack",
4033
+ dashboardCapable: false,
4034
+ supportsDynamicUi: false,
4035
+ supportsVoiceInput: false,
4036
+ chatType: "channel",
4037
+ };
4038
+ const cardRow: MessageRow = {
4039
+ id: "m-card",
4040
+ conversationId: "conv-1",
4041
+ role: "assistant",
4042
+ content: [
4043
+ {
4044
+ type: "ui_surface",
4045
+ surfaceId: "tool-approval-req-1",
4046
+ surfaceType: "card",
4047
+ title: "Tool Approval",
4048
+ data: {},
4049
+ display: "inline",
4050
+ },
4051
+ { type: "text", text: "Tool Approval card body" },
4052
+ ],
4053
+ createdAt: 1700000035_000,
4054
+ metadata: null,
4055
+ clientMessageId: null,
4056
+ finalized: 1,
4057
+ } as MessageRow;
4058
+ const rows: MessageRow[] = [
4059
+ userRow({
4060
+ id: "asked",
4061
+ createdAt: 1700000030_000,
4062
+ text: "please run it",
4063
+ slackMeta: buildSlackMeta({ channelTs: T2, displayName: "carol" }),
4064
+ }),
4065
+ cardRow,
4066
+ ];
4067
+
4068
+ const result = loadSlackChronologicalContext("conv-1", caps, {
4069
+ loader: () => rows,
4070
+ trustClass: "guardian",
4071
+ });
4072
+
4073
+ expect(result).not.toBeNull();
4074
+ const renderedText = JSON.stringify(result!.messages);
4075
+ expect(renderedText).toContain("please run it");
4076
+ expect(renderedText).not.toContain("Tool Approval card body");
4077
+ expect(renderedText).not.toContain("tool-approval-req-1");
4078
+ });
4079
+
3998
4080
  test("loadSlackChronologicalContext preserves summary and filters by Slack watermark", () => {
3999
4081
  const caps: ChannelCapabilities = {
4000
4082
  channel: "slack",
@@ -4317,19 +4399,22 @@ describe("Slack channel chronological rendering — multi-thread", () => {
4317
4399
  )
4318
4400
  .run();
4319
4401
  }
4320
- setConversation("runtime-assembly-fallback", {
4321
- conversationId: "runtime-assembly-fallback",
4322
- workingDir: "/sandbox",
4323
- workspaceTopLevelContext: "",
4324
- workspaceTopLevelDirty: false,
4325
- surfaceState: new Map(),
4326
- channelCapabilities: caps,
4327
- trustContext: { trustClass: "guardian" },
4328
- slackContextCompactionWatermarkTs:
4329
- compaction.slackContextCompactionWatermarkTs ?? null,
4330
- contextCompactedMessageCount:
4331
- compaction.contextCompactedMessageCount ?? 0,
4332
- } as never);
4402
+ setConversation(
4403
+ "runtime-assembly-fallback",
4404
+ asConversation({
4405
+ conversationId: "runtime-assembly-fallback",
4406
+ workingDir: "/sandbox",
4407
+ workspaceTopLevelContext: "",
4408
+ workspaceTopLevelDirty: false,
4409
+ surfaceState: new Map(),
4410
+ channelCapabilities: caps,
4411
+ trustContext: { trustClass: "guardian", sourceChannel: "vellum" },
4412
+ slackContextCompactionWatermarkTs:
4413
+ compaction.slackContextCompactionWatermarkTs ?? null,
4414
+ contextCompactedMessageCount:
4415
+ compaction.contextCompactedMessageCount ?? 0,
4416
+ }),
4417
+ );
4333
4418
  }
4334
4419
 
4335
4420
  // Re-run a Slack-channel turn through the public assembly path. The
@@ -9,6 +9,7 @@ import { applyRuntimeInjections } from "../daemon/conversation-runtime-assembly.
9
9
  import type { SurfaceData, SurfaceType } from "../daemon/message-protocol.js";
10
10
  import { registerDefaultPluginInjectors } from "../plugins/defaults/index.js";
11
11
  import type { Message } from "../providers/types.js";
12
+ import { asConversation } from "./helpers/mock-conversation.js";
12
13
 
13
14
  // Populate the injector registry with the default plugins' injectors the way
14
15
  // bootstrap does in production, so `applyRuntimeInjections` walks a non-empty
@@ -33,16 +34,19 @@ const FALLBACK_CONVERSATION_ID = "runtime-assembly-fallback";
33
34
  // injectors resolve their blocks from it (the orchestrator no longer threads
34
35
  // workspace or active-surface content as options).
35
36
  function registerFallbackConversation(fields: Record<string, unknown>): void {
36
- setConversation(FALLBACK_CONVERSATION_ID, {
37
- conversationId: FALLBACK_CONVERSATION_ID,
38
- workingDir: "/sandbox",
39
- // Non-dirty empty workspace by default so the workspace-context injector
40
- // skips both the filesystem rescan and the DB refresh unless a test
41
- // explicitly seeds a block via `workspaceTopLevelContext`.
42
- workspaceTopLevelContext: "",
43
- workspaceTopLevelDirty: false,
44
- ...fields,
45
- } as never);
37
+ setConversation(
38
+ FALLBACK_CONVERSATION_ID,
39
+ asConversation({
40
+ conversationId: FALLBACK_CONVERSATION_ID,
41
+ workingDir: "/sandbox",
42
+ // Non-dirty empty workspace by default so the workspace-context injector
43
+ // skips both the filesystem rescan and the DB refresh unless a test
44
+ // explicitly seeds a block via `workspaceTopLevelContext`.
45
+ workspaceTopLevelContext: "",
46
+ workspaceTopLevelDirty: false,
47
+ ...fields,
48
+ }),
49
+ );
46
50
  }
47
51
 
48
52
  // Seed the live conversation registry with a pre-rendered top-level block. The
@@ -62,6 +62,9 @@ mock.module("../persistence/conversation-crud.js", () => ({
62
62
  getLastUserTimestampBefore: () => 0,
63
63
  reserveMessage: mock(async () => ({ id: "msg-reserve" })),
64
64
  updateMessageContent: mock(() => {}),
65
+ // The drain records the snapshot-stream anchor after each echo. Mocked so a
66
+ // sink that stamps seqs (the hub) cannot send the real recorder to SQLite.
67
+ recordConversationPersistedSeq: () => {},
65
68
  }));
66
69
 
67
70
  mock.module("../persistence/conversation-queries.js", () => ({
@@ -43,6 +43,7 @@ function makeContext(sent: AssistantEvent[] = []): Conversation & {
43
43
  return asConversation({
44
44
  conversationId: "conv-1",
45
45
  sendToClient: (msg: AssistantEvent) => sent.push(msg),
46
+ emit: (msg: AssistantEvent) => sent.push(msg),
46
47
  pendingSurfaceActions: new Map<string, { surfaceType: SurfaceType }>(),
47
48
  lastSurfaceAction: new Map<
48
49
  string,
@@ -69,6 +69,7 @@ function makeContext(
69
69
  return {
70
70
  conversationId,
71
71
  sendToClient: (msg: AssistantEvent) => sent.push(msg),
72
+ emit: (msg: AssistantEvent) => sent.push(msg),
72
73
  pendingSurfaceActions: new Map<string, { surfaceType: SurfaceType }>(),
73
74
  lastSurfaceAction: new Map<
74
75
  string,
@@ -97,6 +97,7 @@ function buildMockContext(
97
97
  } as Conversation["currentTurnAuthContext"])
98
98
  : undefined,
99
99
  sendToClient: () => {},
100
+ emit: () => {},
100
101
  pendingSurfaceActions: new Map(),
101
102
  lastSurfaceAction: new Map(),
102
103
  surfaceState: new Map(),
@@ -29,7 +29,7 @@ function makeContext(
29
29
  channelCapabilities:
30
30
  options.channelCapabilities &&
31
31
  mockChannelCapabilities(options.channelCapabilities),
32
- sendToClient: (msg) => sent.push(msg),
32
+ emit: (msg) => sent.push(msg),
33
33
  pendingSurfaceActions: new Map<string, { surfaceType: SurfaceType }>(),
34
34
  lastSurfaceAction: new Map<
35
35
  string,
@@ -57,7 +57,7 @@ import { asConversation } from "./helpers/mock-conversation.js";
57
57
  function makeContext(sent: AssistantEvent[] = []): Conversation {
58
58
  return asConversation({
59
59
  conversationId: "conv-persist-1",
60
- sendToClient: (msg) => sent.push(msg),
60
+ emit: (msg) => sent.push(msg),
61
61
  pendingSurfaceActions: new Map<string, { surfaceType: SurfaceType }>(),
62
62
  lastSurfaceAction: new Map<
63
63
  string,
@@ -124,13 +124,17 @@ type EnqueueResult = { queued: boolean; requestId: string; rejected?: boolean };
124
124
 
125
125
  function makeContext(
126
126
  enqueueResult: EnqueueResult = { queued: false, requestId: "req-1" },
127
- overrides: { trustContext?: TrustContext; queueDepth?: number } = {},
127
+ overrides: {
128
+ trustContext?: TrustContext;
129
+ queueDepth?: number;
130
+ emit?: (msg: AssistantEvent) => void;
131
+ } = {},
128
132
  ): Conversation & { enqueuedContents: string[] } {
129
133
  const enqueuedContents: string[] = [];
130
134
  return asConversation({
131
135
  conversationId: CONVERSATION_ID,
132
136
  trustContext: overrides.trustContext ?? GUARDIAN_TRUST,
133
- sendToClient: () => {},
137
+ emit: overrides.emit ?? (() => {}),
134
138
  pendingSurfaceActions: new Map<string, { surfaceType: SurfaceType }>(),
135
139
  lastSurfaceAction: new Map<
136
140
  string,
@@ -885,11 +889,12 @@ describe("surface completion when the persisted write does not land", () => {
885
889
  test("a ui_dismiss completion whose write throws stays retryable", async () => {
886
890
  const surfaceId = "surface-dismiss-persist-throws-1";
887
891
  seedSurfaceRow(surfaceId, "choice");
888
- const ctx = makeContext();
889
892
  const sentToClient: AssistantEvent[] = [];
890
- ctx.sendToClient = (msg) => {
891
- sentToClient.push(msg);
892
- };
893
+ const ctx = makeContext(undefined, {
894
+ emit: (msg) => {
895
+ sentToClient.push(msg);
896
+ },
897
+ });
893
898
  seedAnsweredSurface(ctx, surfaceId);
894
899
  persistError = new Error("database is locked");
895
900
 
@@ -919,11 +924,12 @@ describe("surface completion when the persisted write does not land", () => {
919
924
  test("a ui_dismiss completion that lands clears the live state", async () => {
920
925
  const surfaceId = "surface-dismiss-persist-lands-1";
921
926
  seedSurfaceRow(surfaceId, "choice");
922
- const ctx = makeContext();
923
927
  const sentToClient: AssistantEvent[] = [];
924
- ctx.sendToClient = (msg) => {
925
- sentToClient.push(msg);
926
- };
928
+ const ctx = makeContext(undefined, {
929
+ emit: (msg) => {
930
+ sentToClient.push(msg);
931
+ },
932
+ });
927
933
  seedAnsweredSurface(ctx, surfaceId);
928
934
 
929
935
  const result = await surfaceProxyResolver(ctx, "ui_dismiss", {
@@ -942,11 +948,12 @@ describe("surface completion when the persisted write does not land", () => {
942
948
  test("a ui_dismiss with no recorded action clears the live state even when the write throws", async () => {
943
949
  const surfaceId = "surface-dismiss-no-action-1";
944
950
  seedSurfaceRow(surfaceId, "card");
945
- const ctx = makeContext();
946
951
  const sentToClient: AssistantEvent[] = [];
947
- ctx.sendToClient = (msg) => {
948
- sentToClient.push(msg);
949
- };
952
+ const ctx = makeContext(undefined, {
953
+ emit: (msg) => {
954
+ sentToClient.push(msg);
955
+ },
956
+ });
950
957
  ctx.pendingSurfaceActions.set(surfaceId, { surfaceType: "card" });
951
958
  ctx.surfaceState.set(surfaceId, { surfaceType: "card", data: {} });
952
959
  persistError = new Error("database is locked");
@@ -22,6 +22,7 @@ function makeQueuedContext(): Conversation {
22
22
  return asConversation({
23
23
  conversationId: CONV_ID,
24
24
  sendToClient: () => {},
25
+ emit: () => {},
25
26
  pendingSurfaceActions: new Map<string, { surfaceType: SurfaceType }>(),
26
27
  lastSurfaceAction: new Map<
27
28
  string,
@@ -65,6 +65,7 @@ function createMockContext(
65
65
  })
66
66
  : undefined,
67
67
  sendToClient: (msg: AssistantEvent) => sentMessages.push(msg),
68
+ emit: (msg: AssistantEvent) => sentMessages.push(msg),
68
69
  pendingSurfaceActions: new Map(),
69
70
  lastSurfaceAction: new Map(),
70
71
  surfaceState: new Map(),
@@ -53,6 +53,7 @@ function createMockContext(
53
53
  })
54
54
  : undefined,
55
55
  sendToClient: (msg: AssistantEvent) => sentMessages.push(msg),
56
+ emit: (msg: AssistantEvent) => sentMessages.push(msg),
56
57
  pendingSurfaceActions: new Map(),
57
58
  lastSurfaceAction: new Map(),
58
59
  surfaceState: new Map(),
@@ -26,7 +26,7 @@ function makeContext(opts?: { sent?: AssistantEvent[] }): Conversation & {
26
26
 
27
27
  return asConversation({
28
28
  conversationId: "test-session",
29
- sendToClient: (msg) => sent.push(msg),
29
+ emit: (msg) => sent.push(msg),
30
30
  pendingSurfaceActions: new Map<string, { surfaceType: SurfaceType }>(),
31
31
  lastSurfaceAction: new Map<
32
32
  string,
@@ -49,7 +49,7 @@ function makeContext(): Conversation & {
49
49
 
50
50
  return asConversation({
51
51
  conversationId: "test-convo",
52
- sendToClient: (msg) => sentMessages.push(msg),
52
+ emit: (msg) => sentMessages.push(msg),
53
53
  pendingSurfaceActions: new Map<string, { surfaceType: SurfaceType }>(),
54
54
  lastSurfaceAction: new Map<
55
55
  string,
@@ -26,7 +26,7 @@ function makeContext(
26
26
  conversationId: "session-1",
27
27
  channelCapabilities:
28
28
  channelCapabilities && mockChannelCapabilities(channelCapabilities),
29
- sendToClient: (msg) => sent.push(msg),
29
+ emit: (msg) => sent.push(msg),
30
30
  pendingSurfaceActions: new Map<string, { surfaceType: SurfaceType }>(),
31
31
  lastSurfaceAction: new Map<
32
32
  string,
@@ -94,7 +94,7 @@ function makeCtx(overrides: Partial<Conversation> = {}): Conversation {
94
94
  workingDir: "/tmp/test",
95
95
  getTurnActorPrincipalId: () => undefined,
96
96
  abortController: null,
97
- sendToClient: mock(() => {}),
97
+ emit: mock(() => {}),
98
98
  pendingSurfaceActions: new Map(),
99
99
  lastSurfaceAction: new Map(),
100
100
  surfaceState: new Map(),
@@ -101,7 +101,7 @@ function makeCtx(overrides: Partial<Conversation> = {}): Conversation {
101
101
  workingDir: "/tmp/test",
102
102
  getTurnActorPrincipalId: () => undefined,
103
103
  abortController: null,
104
- sendToClient: mock(() => {}),
104
+ emit: mock(() => {}),
105
105
  pendingSurfaceActions: new Map(),
106
106
  lastSurfaceAction: new Map(),
107
107
  surfaceState: new Map(),