@vellumai/assistant 0.8.3 → 0.8.5

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 (665) hide show
  1. package/ARCHITECTURE.md +2 -2
  2. package/docker-entrypoint.sh +0 -1
  3. package/docs/browser-use-architecture-phase2.md +1 -1
  4. package/knip.json +2 -1
  5. package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
  6. package/openapi.yaml +1492 -100
  7. package/package.json +1 -1
  8. package/src/__tests__/agent-loop-exit-reason.test.ts +4 -5
  9. package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
  10. package/src/__tests__/agent-loop.test.ts +88 -3
  11. package/src/__tests__/anthropic-provider.test.ts +302 -33
  12. package/src/__tests__/approval-cascade.test.ts +1 -1
  13. package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
  14. package/src/__tests__/assistant-feature-flags-integration.test.ts +3 -3
  15. package/src/__tests__/audit-log-rotation.test.ts +70 -16
  16. package/src/__tests__/background-workers-disk-pressure.test.ts +4 -3
  17. package/src/__tests__/btw-routes.test.ts +2 -3
  18. package/src/__tests__/call-controller.test.ts +0 -1
  19. package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
  20. package/src/__tests__/channel-delivery-store.test.ts +193 -0
  21. package/src/__tests__/channel-guardian.test.ts +3 -3
  22. package/src/__tests__/channel-reply-delivery.test.ts +284 -5
  23. package/src/__tests__/channel-retry-sweep.test.ts +274 -1
  24. package/src/__tests__/checker.test.ts +6 -15
  25. package/src/__tests__/compaction-events.test.ts +2 -1
  26. package/src/__tests__/compactor-call-site-logging.test.ts +214 -0
  27. package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
  28. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +5 -11
  29. package/src/__tests__/computer-use-tools.test.ts +2 -4
  30. package/src/__tests__/config-watcher.test.ts +1 -1
  31. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
  32. package/src/__tests__/context-token-estimator.test.ts +91 -1
  33. package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
  34. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -1
  35. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +55 -4
  36. package/src/__tests__/conversation-agent-loop-overflow.test.ts +228 -8
  37. package/src/__tests__/conversation-agent-loop.test.ts +188 -129
  38. package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -5
  39. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
  40. package/src/__tests__/conversation-clean-command.test.ts +137 -0
  41. package/src/__tests__/conversation-clear-safety.test.ts +25 -25
  42. package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
  43. package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
  44. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  45. package/src/__tests__/conversation-error.test.ts +31 -0
  46. package/src/__tests__/conversation-fork-crud.test.ts +324 -0
  47. package/src/__tests__/conversation-lifecycle.test.ts +53 -12
  48. package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
  49. package/src/__tests__/conversation-load-history-stripped.test.ts +279 -0
  50. package/src/__tests__/conversation-pairing.test.ts +2 -2
  51. package/src/__tests__/conversation-process-callsite.test.ts +1 -1
  52. package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -1
  53. package/src/__tests__/conversation-queue.test.ts +1 -1
  54. package/src/__tests__/conversation-routes-disk-view.test.ts +109 -0
  55. package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -0
  56. package/src/__tests__/conversation-runtime-assembly.test.ts +264 -81
  57. package/src/__tests__/conversation-seed-composer.test.ts +66 -4
  58. package/src/__tests__/conversation-skill-tools.test.ts +2 -5
  59. package/src/__tests__/conversation-slash-commands.test.ts +36 -8
  60. package/src/__tests__/conversation-slash-queue.test.ts +1 -1
  61. package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
  62. package/src/__tests__/conversation-speed-override.test.ts +1 -1
  63. package/src/__tests__/conversation-store.test.ts +1 -1
  64. package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
  65. package/src/__tests__/conversation-sync-tags.test.ts +99 -32
  66. package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -1
  67. package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
  68. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
  69. package/src/__tests__/credential-execution-feature-gates.test.ts +9 -7
  70. package/src/__tests__/credential-execution-tools.test.ts +6 -6
  71. package/src/__tests__/credential-security-invariants.test.ts +7 -0
  72. package/src/__tests__/credential-vault-unit.test.ts +2 -2
  73. package/src/__tests__/cu-unified-flow.test.ts +10 -1
  74. package/src/__tests__/dm-backfill.test.ts +64 -0
  75. package/src/__tests__/dm-persistence.test.ts +33 -0
  76. package/src/__tests__/document-find-replace.test.ts +501 -0
  77. package/src/__tests__/dynamic-page-surface.test.ts +2 -2
  78. package/src/__tests__/email-html-renderer.test.ts +12 -0
  79. package/src/__tests__/first-greeting.test.ts +23 -2
  80. package/src/__tests__/gateway-flag-listener.test.ts +237 -0
  81. package/src/__tests__/gemini-provider.test.ts +78 -0
  82. package/src/__tests__/guardian-dispatch.test.ts +0 -1
  83. package/src/__tests__/guardian-outbound-http.test.ts +7 -5
  84. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  85. package/src/__tests__/headless-browser-navigate.test.ts +172 -0
  86. package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
  87. package/src/__tests__/heartbeat-service.test.ts +4 -0
  88. package/src/__tests__/host-bash-proxy.test.ts +6 -0
  89. package/src/__tests__/host-browser-proxy.test.ts +10 -0
  90. package/src/__tests__/host-cu-proxy.test.ts +8 -1
  91. package/src/__tests__/host-file-proxy.test.ts +8 -1
  92. package/src/__tests__/host-shell-tool.test.ts +1 -1
  93. package/src/__tests__/host-transfer-proxy.test.ts +8 -1
  94. package/src/__tests__/identity-routes.test.ts +57 -0
  95. package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
  96. package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
  97. package/src/__tests__/injector-chain.test.ts +2 -0
  98. package/src/__tests__/injector-document-comments.test.ts +378 -0
  99. package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
  100. package/src/__tests__/list-messages-attachments.test.ts +21 -17
  101. package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
  102. package/src/__tests__/list-messages-page-latest.test.ts +130 -14
  103. package/src/__tests__/list-messages-tool-merge.test.ts +77 -17
  104. package/src/__tests__/llm-context-normalization.test.ts +0 -2
  105. package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
  106. package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
  107. package/src/__tests__/llm-resolver.test.ts +161 -9
  108. package/src/__tests__/llm-usage-store.test.ts +66 -0
  109. package/src/__tests__/log-export-routes.test.ts +99 -2
  110. package/src/__tests__/logger.test.ts +89 -0
  111. package/src/__tests__/mcp-abort-signal.test.ts +2 -2
  112. package/src/__tests__/media-generate-image.test.ts +31 -0
  113. package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
  114. package/src/__tests__/message-queue-steer.test.ts +114 -0
  115. package/src/__tests__/model-intents.test.ts +2 -4
  116. package/src/__tests__/notification-guardian-path.test.ts +0 -1
  117. package/src/__tests__/onboarding-template-contract.test.ts +1 -1
  118. package/src/__tests__/openai-provider.test.ts +151 -0
  119. package/src/__tests__/openai-responses-provider.test.ts +118 -16
  120. package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
  121. package/src/__tests__/pending-interactions-resolved-event.test.ts +189 -0
  122. package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
  123. package/src/__tests__/platform.test.ts +2 -5
  124. package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
  125. package/src/__tests__/plugin-bootstrap.test.ts +2 -2
  126. package/src/__tests__/plugin-source-watcher.test.ts +302 -0
  127. package/src/__tests__/plugin-tool-contribution.test.ts +13 -6
  128. package/src/__tests__/plugin-types.test.ts +3 -2
  129. package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
  130. package/src/__tests__/pricing.test.ts +12 -0
  131. package/src/__tests__/process-message-background-slack.test.ts +1 -51
  132. package/src/__tests__/process-message-display-content.test.ts +21 -16
  133. package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
  134. package/src/__tests__/registry.test.ts +2 -8
  135. package/src/__tests__/require-fresh-approval.test.ts +2 -2
  136. package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
  137. package/src/__tests__/server-history-render.test.ts +83 -4
  138. package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
  139. package/src/__tests__/skill-feature-flags.test.ts +2 -2
  140. package/src/__tests__/skill-projection-feature-flag.test.ts +4 -7
  141. package/src/__tests__/skill-projection.benchmark.test.ts +2 -6
  142. package/src/__tests__/skill-tool-factory.test.ts +1 -1
  143. package/src/__tests__/steer-tool-repair.test.ts +249 -0
  144. package/src/__tests__/subagent-notify-parent.test.ts +1 -1
  145. package/src/__tests__/suggestion-routes.test.ts +1 -0
  146. package/src/__tests__/sync-message-contract.test.ts +59 -0
  147. package/src/__tests__/system-prompt.test.ts +161 -124
  148. package/src/__tests__/terminal-tools.test.ts +12 -2
  149. package/src/__tests__/thinking-block-replay.test.ts +113 -0
  150. package/src/__tests__/thread-backfill.test.ts +370 -22
  151. package/src/__tests__/tool-approval-handler.test.ts +1 -5
  152. package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
  153. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
  154. package/src/__tests__/tool-executor-lifecycle-events.test.ts +15 -5
  155. package/src/__tests__/tool-executor.test.ts +89 -53
  156. package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
  157. package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
  158. package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
  159. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
  160. package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
  161. package/src/__tests__/twilio-routes.test.ts +1 -1
  162. package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
  163. package/src/__tests__/usage-routes.test.ts +3 -0
  164. package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
  165. package/src/__tests__/web-fetch.test.ts +2 -2
  166. package/src/__tests__/workspace-git-service.test.ts +94 -10
  167. package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
  168. package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
  169. package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
  170. package/src/acp/prepare-agent-env.ts +78 -0
  171. package/src/acp/session-manager.ts +1 -1
  172. package/src/agent/attachments.ts +1 -0
  173. package/src/agent/loop.ts +65 -20
  174. package/src/api/README.md +5 -0
  175. package/src/api/index.ts +4 -0
  176. package/src/api/package.json +10 -0
  177. package/src/background-wake/background-wake-routes.test.ts +233 -0
  178. package/src/background-wake/next-wake.test.ts +289 -0
  179. package/src/background-wake/next-wake.ts +172 -0
  180. package/src/background-wake/runtime-registry.ts +24 -0
  181. package/src/browser/operations.ts +15 -0
  182. package/src/cli/commands/__tests__/browser.test.ts +23 -5
  183. package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
  184. package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
  185. package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
  186. package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
  187. package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
  188. package/src/cli/commands/__tests__/memory-v2.test.ts +10 -12
  189. package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
  190. package/src/cli/commands/browser.ts +247 -0
  191. package/src/cli/commands/conversations.ts +128 -1
  192. package/src/cli/commands/domain.ts +91 -41
  193. package/src/cli/commands/inference-providers.ts +147 -1
  194. package/src/cli/commands/inference.ts +93 -40
  195. package/src/cli/commands/memory-v2-compare-render.ts +115 -0
  196. package/src/cli/commands/memory-v2.ts +483 -0
  197. package/src/cli/commands/memory-v3-render.ts +344 -0
  198. package/src/cli/commands/memory-v3.ts +316 -0
  199. package/src/cli/commands/notifications.ts +24 -2
  200. package/src/cli/program.ts +2 -0
  201. package/src/cli/utils/conversation-id.ts +17 -5
  202. package/src/config/assistant-feature-flags.ts +21 -9
  203. package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
  204. package/src/config/bundled-skills/document-editor/SKILL.md +124 -0
  205. package/src/config/bundled-skills/document-editor/TOOLS.json +258 -0
  206. package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
  207. package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
  208. package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
  209. package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
  210. package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
  211. package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
  212. package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
  213. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
  214. package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
  215. package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
  216. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
  217. package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
  218. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
  219. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
  220. package/src/config/bundled-skills/schedule/SKILL.md +8 -0
  221. package/src/config/bundled-tool-registry.ts +24 -12
  222. package/src/config/call-site-defaults.ts +20 -0
  223. package/src/config/feature-flag-registry.json +115 -3
  224. package/src/config/llm-resolver.ts +16 -2
  225. package/src/config/schemas/__tests__/memory-v2.test.ts +217 -1
  226. package/src/config/schemas/call-site-catalog.ts +35 -0
  227. package/src/config/schemas/llm.ts +14 -0
  228. package/src/config/schemas/memory-v2.ts +294 -1
  229. package/src/config/schemas/memory.ts +2 -1
  230. package/src/context/compactor.ts +60 -1
  231. package/src/context/token-estimator.ts +47 -4
  232. package/src/context/window-manager.ts +25 -0
  233. package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
  234. package/src/conversations/message-consolidation.ts +404 -0
  235. package/src/credential-health/credential-health-service.ts +34 -19
  236. package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -1
  237. package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
  238. package/src/daemon/__tests__/meet-manifest-loader.test.ts +1 -1
  239. package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
  240. package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
  241. package/src/daemon/conversation-agent-loop-handlers.ts +155 -36
  242. package/src/daemon/conversation-agent-loop.ts +307 -88
  243. package/src/daemon/conversation-error.ts +31 -1
  244. package/src/daemon/conversation-lifecycle.ts +149 -118
  245. package/src/daemon/conversation-messaging.ts +3 -0
  246. package/src/daemon/conversation-process.ts +273 -0
  247. package/src/daemon/conversation-queue-manager.ts +14 -0
  248. package/src/daemon/conversation-runtime-assembly.ts +145 -84
  249. package/src/daemon/conversation-slash.ts +37 -5
  250. package/src/daemon/conversation-surfaces.ts +45 -2
  251. package/src/daemon/conversation-tool-setup.ts +70 -3
  252. package/src/daemon/conversation-usage.ts +2 -0
  253. package/src/daemon/conversation.ts +54 -32
  254. package/src/daemon/disk-pressure-guard.ts +14 -2
  255. package/src/daemon/first-greeting.ts +10 -0
  256. package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
  257. package/src/daemon/handlers/config-a2a.ts +160 -0
  258. package/src/daemon/handlers/config-model.test.ts +2 -0
  259. package/src/daemon/handlers/conversations.ts +90 -3
  260. package/src/daemon/handlers/shared.ts +92 -29
  261. package/src/daemon/host-bash-proxy.ts +1 -1
  262. package/src/daemon/host-browser-proxy.ts +5 -5
  263. package/src/daemon/host-cu-proxy.ts +5 -5
  264. package/src/daemon/host-file-proxy.ts +5 -5
  265. package/src/daemon/host-proxy-base.ts +4 -4
  266. package/src/daemon/host-transfer-proxy.ts +11 -11
  267. package/src/daemon/lifecycle.ts +40 -23
  268. package/src/daemon/meet-manifest-loader.ts +1 -7
  269. package/src/daemon/message-protocol.ts +4 -0
  270. package/src/daemon/message-types/conversations.ts +14 -9
  271. package/src/daemon/message-types/document-comments.ts +50 -0
  272. package/src/daemon/message-types/home.ts +1 -13
  273. package/src/daemon/message-types/messages.ts +66 -7
  274. package/src/daemon/message-types/surfaces.ts +3 -1
  275. package/src/daemon/message-types/sync.ts +14 -0
  276. package/src/daemon/message-types/web-activity.ts +57 -0
  277. package/src/daemon/plugin-source-watcher.ts +135 -3
  278. package/src/daemon/process-message.ts +69 -12
  279. package/src/daemon/shutdown-handlers.ts +24 -5
  280. package/src/daemon/switch-inference-profile-tool.ts +52 -0
  281. package/src/daemon/tool-setup-types.ts +13 -0
  282. package/src/daemon/trust-context.ts +6 -0
  283. package/src/documents/document-comments-store.test.ts +338 -0
  284. package/src/documents/document-comments-store.ts +237 -0
  285. package/src/documents/document-store.ts +202 -0
  286. package/src/events/relationship-state-updated.ts +25 -0
  287. package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -2
  288. package/src/heartbeat/heartbeat-service.ts +1 -0
  289. package/src/home/__tests__/suggested-prompts.test.ts +33 -2
  290. package/src/home/feed-types.ts +6 -1
  291. package/src/home/home-content-refresh.ts +52 -0
  292. package/src/home/home-greeting-cache.ts +69 -0
  293. package/src/home/home-greeting.ts +85 -0
  294. package/src/home/suggested-prompts.ts +168 -9
  295. package/src/ipc/gateway-flag-listener.ts +123 -0
  296. package/src/ipc/skill-routes/registries.ts +8 -12
  297. package/src/memory/__tests__/db-async-query.test.ts +165 -0
  298. package/src/memory/__tests__/db-maintenance.test.ts +115 -0
  299. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +241 -0
  300. package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
  301. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
  302. package/src/memory/__tests__/memory-retrospective-job.test.ts +327 -6
  303. package/src/memory/auto-analysis-enqueue.ts +5 -1
  304. package/src/memory/conversation-crud.ts +191 -100
  305. package/src/memory/conversation-starters-cadence.ts +3 -1
  306. package/src/memory/conversation-title-service.ts +19 -3
  307. package/src/memory/db-async-query.ts +214 -0
  308. package/src/memory/db-init.ts +26 -0
  309. package/src/memory/db-maintenance.ts +30 -21
  310. package/src/memory/delivery-crud.ts +41 -0
  311. package/src/memory/delivery-status.ts +141 -15
  312. package/src/memory/external-conversation-store.ts +32 -1
  313. package/src/memory/graph/bootstrap.ts +8 -1
  314. package/src/memory/graph/capability-seed.ts +7 -3
  315. package/src/memory/graph/conversation-graph-memory.ts +100 -17
  316. package/src/memory/graph/extraction.ts +1 -5
  317. package/src/memory/graph/graph-search.ts +7 -1
  318. package/src/memory/indexer.ts +28 -18
  319. package/src/memory/job-handlers/cleanup.ts +76 -18
  320. package/src/memory/job-handlers/conversation-starters.ts +1 -4
  321. package/src/memory/jobs/embed-pkb-file.ts +6 -1
  322. package/src/memory/jobs-store.ts +14 -0
  323. package/src/memory/jobs-worker.ts +68 -15
  324. package/src/memory/llm-request-log-source-clickhouse.ts +42 -2
  325. package/src/memory/llm-request-log-source-local.ts +7 -0
  326. package/src/memory/llm-request-log-source.ts +9 -2
  327. package/src/memory/llm-request-log-store.ts +43 -1
  328. package/src/memory/llm-usage-store.ts +24 -0
  329. package/src/memory/memory-retrospective-constants.ts +28 -0
  330. package/src/memory/memory-retrospective-enqueue.ts +11 -3
  331. package/src/memory/memory-retrospective-job.ts +413 -18
  332. package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
  333. package/src/memory/memory-v2-activation-log-store.ts +41 -14
  334. package/src/memory/migrations/100-core-tables.ts +1 -0
  335. package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
  336. package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
  337. package/src/memory/migrations/253-document-comments.ts +47 -0
  338. package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
  339. package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
  340. package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
  341. package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
  342. package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
  343. package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
  344. package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
  345. package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
  346. package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
  347. package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
  348. package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
  349. package/src/memory/migrations/index.ts +34 -0
  350. package/src/memory/migrations/registry.ts +58 -0
  351. package/src/memory/onboarding-events-store.ts +7 -0
  352. package/src/memory/schema/calls.ts +1 -0
  353. package/src/memory/schema/conversations.ts +3 -0
  354. package/src/memory/schema/infrastructure.ts +22 -0
  355. package/src/memory/tool-usage-store.ts +36 -8
  356. package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
  357. package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
  358. package/src/memory/v2/__tests__/harness-metrics.test.ts +74 -0
  359. package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
  360. package/src/memory/v2/__tests__/harness-replay-input.test.ts +225 -0
  361. package/src/memory/v2/__tests__/harness-runner.test.ts +109 -0
  362. package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
  363. package/src/memory/v2/__tests__/injection.test.ts +158 -112
  364. package/src/memory/v2/__tests__/page-index.test.ts +365 -1
  365. package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
  366. package/src/memory/v2/__tests__/router.test.ts +660 -4
  367. package/src/memory/v2/consolidation-job.ts +14 -0
  368. package/src/memory/v2/harness/compare.ts +57 -0
  369. package/src/memory/v2/harness/metrics.ts +124 -0
  370. package/src/memory/v2/harness/oracle.ts +145 -0
  371. package/src/memory/v2/harness/replay-input.ts +224 -0
  372. package/src/memory/v2/harness/retriever.ts +74 -0
  373. package/src/memory/v2/harness/router-retriever.ts +43 -0
  374. package/src/memory/v2/harness/runner.ts +106 -0
  375. package/src/memory/v2/harness/trace.ts +58 -0
  376. package/src/memory/v2/injection-events.ts +101 -0
  377. package/src/memory/v2/injection.ts +42 -25
  378. package/src/memory/v2/page-index.ts +209 -7
  379. package/src/memory/v2/page-store.ts +18 -0
  380. package/src/memory/v2/prompts/router.ts +26 -1
  381. package/src/memory/v2/qdrant.ts +14 -2
  382. package/src/memory/v2/router.ts +369 -62
  383. package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
  384. package/src/memory/v3/__tests__/consolidation-job.test.ts +468 -0
  385. package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
  386. package/src/memory/v3/__tests__/edges.test.ts +563 -0
  387. package/src/memory/v3/__tests__/filter.test.ts +512 -0
  388. package/src/memory/v3/__tests__/gate.test.ts +574 -0
  389. package/src/memory/v3/__tests__/index-composition.test.ts +233 -0
  390. package/src/memory/v3/__tests__/loop.test.ts +530 -0
  391. package/src/memory/v3/__tests__/retriever.test.ts +226 -0
  392. package/src/memory/v3/__tests__/scouts.test.ts +440 -0
  393. package/src/memory/v3/__tests__/shadow-middleware.test.ts +312 -0
  394. package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
  395. package/src/memory/v3/__tests__/traversal.test.ts +469 -0
  396. package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
  397. package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
  398. package/src/memory/v3/__tests__/tree-walk.test.ts +707 -0
  399. package/src/memory/v3/__tests__/validate.test.ts +245 -0
  400. package/src/memory/v3/auto-edges.ts +223 -0
  401. package/src/memory/v3/coactivation-store.ts +124 -0
  402. package/src/memory/v3/consolidation-job.ts +323 -0
  403. package/src/memory/v3/edge-learning-job.ts +160 -0
  404. package/src/memory/v3/edges.ts +249 -0
  405. package/src/memory/v3/filter.ts +281 -0
  406. package/src/memory/v3/gate.ts +334 -0
  407. package/src/memory/v3/index-composition.ts +113 -0
  408. package/src/memory/v3/llm-capture.ts +46 -0
  409. package/src/memory/v3/loop.ts +382 -0
  410. package/src/memory/v3/maintenance.ts +144 -0
  411. package/src/memory/v3/prompt-context.ts +33 -0
  412. package/src/memory/v3/prompts/consolidation.ts +458 -0
  413. package/src/memory/v3/prompts/system-prompts.ts +196 -0
  414. package/src/memory/v3/retriever.ts +33 -0
  415. package/src/memory/v3/scouts.ts +420 -0
  416. package/src/memory/v3/shadow-middleware.ts +305 -0
  417. package/src/memory/v3/traversal.ts +206 -0
  418. package/src/memory/v3/tree-index.ts +237 -0
  419. package/src/memory/v3/tree-store.ts +394 -0
  420. package/src/memory/v3/tree-walk.ts +351 -0
  421. package/src/memory/v3/types.ts +65 -0
  422. package/src/memory/v3/validate.ts +300 -0
  423. package/src/messaging/providers/index.ts +7 -1
  424. package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
  425. package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
  426. package/src/messaging/providers/slack/adapter.ts +178 -25
  427. package/src/messaging/providers/slack/api.test.ts +54 -0
  428. package/src/messaging/providers/slack/api.ts +119 -3
  429. package/src/messaging/providers/slack/client.ts +12 -0
  430. package/src/messaging/providers/slack/deep-link.ts +20 -1
  431. package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
  432. package/src/messaging/providers/slack/message-metadata.ts +156 -0
  433. package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
  434. package/src/messaging/providers/slack/render-transcript.ts +176 -49
  435. package/src/messaging/providers/slack/send.test.ts +77 -0
  436. package/src/messaging/providers/slack/send.ts +8 -2
  437. package/src/messaging/providers/slack/types.ts +14 -0
  438. package/src/notifications/__tests__/emit-signal-home-feed.test.ts +4 -1
  439. package/src/notifications/__tests__/home-feed-side-effect.test.ts +116 -54
  440. package/src/notifications/adapters/macos.ts +18 -1
  441. package/src/notifications/adapters/platform.ts +1 -1
  442. package/src/notifications/conversation-seed-composer.ts +14 -2
  443. package/src/notifications/decision-engine.ts +1 -4
  444. package/src/notifications/deferred-emit.ts +135 -0
  445. package/src/notifications/emit-signal.ts +38 -50
  446. package/src/notifications/home-feed-side-effect.ts +60 -30
  447. package/src/oauth/connect-orchestrator.ts +3 -0
  448. package/src/oauth/credential-token-resolver.ts +2 -0
  449. package/src/oauth/manual-token-connection.ts +19 -0
  450. package/src/oauth/oauth-store.ts +12 -0
  451. package/src/oauth/seed-providers.ts +22 -0
  452. package/src/permissions/prompter.ts +8 -5
  453. package/src/permissions/question-prompter.ts +5 -2
  454. package/src/permissions/secret-prompter.ts +6 -3
  455. package/src/plugin-api/index.ts +4 -0
  456. package/src/plugin-api/types.ts +7 -33
  457. package/src/plugins/defaults/index.ts +6 -0
  458. package/src/plugins/defaults/injectors.ts +100 -20
  459. package/src/plugins/external-plugin-loader.ts +5 -68
  460. package/src/plugins/types.ts +11 -16
  461. package/src/proactive-artifact/aux-message-injector.ts +17 -4
  462. package/src/prompts/__tests__/system-prompt.test.ts +46 -2
  463. package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
  464. package/src/prompts/normalize-onboarding.ts +40 -0
  465. package/src/prompts/persona-resolver.ts +36 -21
  466. package/src/prompts/sections.ts +69 -19
  467. package/src/prompts/system-prompt.ts +118 -216
  468. package/src/prompts/template-detection.ts +37 -0
  469. package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
  470. package/src/prompts/templates/BOOTSTRAP.md +10 -2
  471. package/src/prompts/templates/VOICE.md +3 -0
  472. package/src/prompts/templates/system-sections.ts +281 -9
  473. package/src/providers/__tests__/connection-model-compat.test.ts +234 -0
  474. package/src/providers/__tests__/retry-callsite.test.ts +85 -5
  475. package/src/providers/anthropic/client.ts +159 -66
  476. package/src/providers/call-site-routing.ts +14 -2
  477. package/src/providers/connection-model-compat.ts +38 -0
  478. package/src/providers/connection-resolution.ts +16 -2
  479. package/src/providers/fireworks/client.ts +20 -2
  480. package/src/providers/gemini/client.ts +49 -6
  481. package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
  482. package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
  483. package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
  484. package/src/providers/inference/adapter-factory.ts +18 -1
  485. package/src/providers/inference/auth.ts +3 -3
  486. package/src/providers/inference/codex-token-refresh.ts +128 -0
  487. package/src/providers/inference/resolve-auth.ts +49 -6
  488. package/src/providers/minimax/client.ts +106 -0
  489. package/src/providers/model-catalog.ts +91 -1
  490. package/src/providers/model-intents.ts +1 -1
  491. package/src/providers/openai/chat-completions-provider.ts +63 -23
  492. package/src/providers/openai/codex-models.ts +18 -0
  493. package/src/providers/openai/responses-provider.ts +86 -23
  494. package/src/providers/openrouter/client.ts +5 -1
  495. package/src/providers/provider-send-message.ts +7 -1
  496. package/src/providers/retry.ts +34 -3
  497. package/src/providers/thinking-config.ts +26 -1
  498. package/src/providers/types.ts +25 -0
  499. package/src/providers/usage-tracking.ts +2 -0
  500. package/src/runtime/AGENTS.md +2 -2
  501. package/src/runtime/__tests__/agent-wake.test.ts +214 -0
  502. package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
  503. package/src/runtime/agent-wake.ts +152 -56
  504. package/src/runtime/assistant-event-hub.ts +76 -6
  505. package/src/runtime/auth/route-policy.ts +43 -3
  506. package/src/runtime/background-job-runner.ts +26 -0
  507. package/src/runtime/btw-sidechain.ts +0 -6
  508. package/src/runtime/channel-reply-delivery.ts +182 -47
  509. package/src/runtime/channel-retry-sweep.ts +141 -16
  510. package/src/runtime/http-types.ts +7 -6
  511. package/src/runtime/migrations/vbundle-builder.ts +10 -3
  512. package/src/runtime/pending-interactions.ts +50 -8
  513. package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
  514. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +161 -1
  515. package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
  516. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +290 -0
  517. package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
  518. package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
  519. package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
  520. package/src/runtime/routes/acp-routes.test.ts +255 -6
  521. package/src/runtime/routes/acp-routes.ts +8 -1
  522. package/src/runtime/routes/approval-routes.ts +4 -1
  523. package/src/runtime/routes/avatar-routes.ts +10 -10
  524. package/src/runtime/routes/background-wake-routes.ts +188 -0
  525. package/src/runtime/routes/browser-tabs-routes.ts +200 -0
  526. package/src/runtime/routes/btw-routes.ts +0 -6
  527. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
  528. package/src/runtime/routes/content-source-routes.ts +78 -0
  529. package/src/runtime/routes/conversation-cli-routes.ts +147 -2
  530. package/src/runtime/routes/conversation-list-routes.ts +12 -4
  531. package/src/runtime/routes/conversation-management-routes.ts +77 -20
  532. package/src/runtime/routes/conversation-query-routes.ts +196 -31
  533. package/src/runtime/routes/conversation-routes.ts +472 -425
  534. package/src/runtime/routes/conversation-starter-routes.ts +6 -3
  535. package/src/runtime/routes/disk-pressure-routes.ts +1 -1
  536. package/src/runtime/routes/document-comments-routes.ts +287 -0
  537. package/src/runtime/routes/documents-routes.ts +33 -0
  538. package/src/runtime/routes/domain-routes.ts +60 -10
  539. package/src/runtime/routes/email-routes.ts +5 -2
  540. package/src/runtime/routes/events-routes.ts +54 -10
  541. package/src/runtime/routes/group-routes.ts +24 -8
  542. package/src/runtime/routes/home-feed-routes.ts +6 -3
  543. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  544. package/src/runtime/routes/host-browser-routes.ts +17 -2
  545. package/src/runtime/routes/host-cu-routes.ts +2 -2
  546. package/src/runtime/routes/identity-routes.ts +21 -0
  547. package/src/runtime/routes/inbound-message-handler.ts +288 -58
  548. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
  549. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
  550. package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
  551. package/src/runtime/routes/index.ts +20 -4
  552. package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
  553. package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
  554. package/src/runtime/routes/inference-provider-connection-routes.ts +63 -7
  555. package/src/runtime/routes/integrations/a2a.ts +60 -1
  556. package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
  557. package/src/runtime/routes/log-export-routes.ts +39 -0
  558. package/src/runtime/routes/memory-item-routes.ts +8 -3
  559. package/src/runtime/routes/memory-v2-routes.ts +427 -0
  560. package/src/runtime/routes/memory-v3-routes.ts +316 -0
  561. package/src/runtime/routes/migration-routes.ts +21 -24
  562. package/src/runtime/routes/notification-routes.ts +19 -2
  563. package/src/runtime/routes/plugins-routes.ts +337 -0
  564. package/src/runtime/routes/question-routes.ts +4 -1
  565. package/src/runtime/routes/rename-conversation-routes.ts +6 -2
  566. package/src/runtime/routes/sanity-routes.ts +159 -0
  567. package/src/runtime/routes/secret-routes.ts +25 -5
  568. package/src/runtime/routes/settings-routes.ts +12 -11
  569. package/src/runtime/routes/slack-channel-routes.ts +188 -0
  570. package/src/runtime/routes/workspace-routes.ts +25 -10
  571. package/src/runtime/services/conversation-serializer.ts +30 -4
  572. package/src/runtime/sync/resource-sync-events.ts +106 -38
  573. package/src/runtime/sync/sync-publisher.test.ts +49 -0
  574. package/src/runtime/sync/sync-publisher.ts +2 -1
  575. package/src/runtime/verification-outbound-actions.ts +73 -1
  576. package/src/schedule/integration-status.ts +3 -1
  577. package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
  578. package/src/security/oauth2-device-code.ts +307 -0
  579. package/src/security/oauth2.ts +26 -9
  580. package/src/security/secure-keys.ts +5 -0
  581. package/src/skills/catalog-install.ts +6 -2
  582. package/src/telemetry/types.ts +12 -0
  583. package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
  584. package/src/telemetry/usage-telemetry-reporter.ts +1 -0
  585. package/src/tools/acp/spawn.test.ts +119 -0
  586. package/src/tools/acp/spawn.ts +15 -2
  587. package/src/tools/apps/definitions.ts +2 -8
  588. package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
  589. package/src/tools/ask-question/ask-question-tool.ts +38 -45
  590. package/src/tools/browser/__tests__/pinned-tabs.test.ts +150 -0
  591. package/src/tools/browser/browser-execution.ts +106 -0
  592. package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
  593. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
  594. package/src/tools/browser/cdp-client/__tests__/types.test.ts +4 -0
  595. package/src/tools/browser/cdp-client/cdp-inspect-client.ts +22 -0
  596. package/src/tools/browser/cdp-client/extension-cdp-client.ts +42 -2
  597. package/src/tools/browser/cdp-client/factory.ts +171 -4
  598. package/src/tools/browser/cdp-client/local-cdp-client.ts +21 -0
  599. package/src/tools/browser/cdp-client/types.ts +101 -0
  600. package/src/tools/browser/pinned-tabs.ts +146 -0
  601. package/src/tools/computer-use/definitions.ts +22 -78
  602. package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
  603. package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
  604. package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
  605. package/src/tools/credentials/vault.ts +3 -9
  606. package/src/tools/document/document-comment-tool.test.ts +379 -0
  607. package/src/tools/document/document-comment-tool.ts +156 -0
  608. package/src/tools/document/document-tool.ts +187 -2
  609. package/src/tools/execution-target.ts +21 -23
  610. package/src/tools/executor.ts +6 -1
  611. package/src/tools/filesystem/edit.ts +3 -9
  612. package/src/tools/filesystem/list.ts +3 -9
  613. package/src/tools/filesystem/read.ts +3 -9
  614. package/src/tools/filesystem/write.ts +3 -9
  615. package/src/tools/host-filesystem/edit.ts +3 -9
  616. package/src/tools/host-filesystem/read.ts +3 -9
  617. package/src/tools/host-filesystem/transfer.ts +3 -9
  618. package/src/tools/host-filesystem/write.ts +3 -9
  619. package/src/tools/host-terminal/host-shell.ts +3 -9
  620. package/src/tools/mcp/mcp-tool-factory.ts +1 -8
  621. package/src/tools/memory/register.test.ts +1 -1
  622. package/src/tools/memory/register.ts +4 -9
  623. package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
  624. package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
  625. package/src/tools/network/domain-normalize.ts +17 -0
  626. package/src/tools/network/web-fetch.ts +216 -73
  627. package/src/tools/network/web-search.ts +216 -98
  628. package/src/tools/registry.ts +7 -23
  629. package/src/tools/schema-transforms.ts +1 -1
  630. package/src/tools/skills/execute.ts +3 -9
  631. package/src/tools/skills/load.ts +3 -9
  632. package/src/tools/skills/skill-tool-factory.ts +1 -8
  633. package/src/tools/subagent/notify-parent.ts +3 -9
  634. package/src/tools/system/request-permission.ts +3 -9
  635. package/src/tools/terminal/safe-env.ts +3 -2
  636. package/src/tools/terminal/shell.ts +3 -9
  637. package/src/tools/tool-approval-handler.ts +19 -12
  638. package/src/tools/tool-defaults.ts +94 -0
  639. package/src/tools/types.ts +31 -98
  640. package/src/tools/ui-surface/definitions.ts +9 -23
  641. package/src/types/onboarding-context.ts +4 -0
  642. package/src/usage/pricing.ts +23 -0
  643. package/src/usage/types.ts +12 -0
  644. package/src/util/__tests__/favicon.test.ts +84 -0
  645. package/src/util/favicon.ts +40 -0
  646. package/src/util/logger.ts +16 -7
  647. package/src/util/platform.ts +7 -7
  648. package/src/util/sqlite3-runtime.ts +65 -0
  649. package/src/workspace/git-service.ts +75 -4
  650. package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
  651. package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
  652. package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
  653. package/src/workspace/migrations/registry.ts +4 -0
  654. package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
  655. package/src/__tests__/message-complete-display-id.test.ts +0 -175
  656. package/src/config/bundled-skills/document/SKILL.md +0 -54
  657. package/src/config/bundled-skills/document/TOOLS.json +0 -106
  658. package/src/daemon/seed-files.ts +0 -18
  659. package/src/prompts/cache-boundary.ts +0 -8
  660. package/src/runtime/routes/interface-routes.ts +0 -43
  661. /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
  662. /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
  663. /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
  664. /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
  665. /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
@@ -59,7 +59,7 @@ import {
59
59
  unregisterPluginTools,
60
60
  } from "../tools/registry.js";
61
61
  import type {
62
- LoadedPluginTool,
62
+ LoadedTool,
63
63
  ToolContext,
64
64
  ToolExecutionResult,
65
65
  } from "../tools/types.js";
@@ -81,12 +81,13 @@ const fakeCtx: DaemonContext = {
81
81
 
82
82
  function makeFakeTool(
83
83
  name: string,
84
- extras: Partial<LoadedPluginTool> = {},
85
- ): LoadedPluginTool {
84
+ extras: Partial<LoadedTool> = {},
85
+ ): LoadedTool {
86
86
  return {
87
87
  name,
88
88
  description: `Fake ${name}`,
89
89
  defaultRiskLevel: RiskLevel.Low,
90
+ executionTarget: "sandbox",
90
91
  input_schema: { type: "object", properties: {}, required: [] },
91
92
  async execute(
92
93
  _input: Record<string, unknown>,
@@ -281,7 +282,7 @@ describe("registerPluginTools / unregisterPluginTools helpers", () => {
281
282
  expect(alias).toMatch(/^[a-zA-Z0-9_-]{1,64}$/);
282
283
  expect(alias.startsWith("Stripe_Link_CLI__")).toBe(true);
283
284
  expect(getTool(alias)).toBeDefined();
284
- expect(accepted[0]!.getDefinition().name).toBe(alias);
285
+ expect(accepted[0]!.name).toBe(alias);
285
286
 
286
287
  await accepted[0]!.execute(
287
288
  {},
@@ -320,12 +321,18 @@ describe("registerPluginTools / unregisterPluginTools helpers", () => {
320
321
  // ownerMcpServerId / ownerSkillBundled / ownerSkillVersionHash) so the
321
322
  // stamped tool cannot leak across namespaces or spoof bundled-skill
322
323
  // auto-allow.
323
- const spoofed = makeFakeTool("pt_spoof", {
324
+ //
325
+ // The narrow `ToolDefinition` shape doesn't expose these ownership
326
+ // fields, so the cast through `unknown` simulates a hostile or
327
+ // transpiled artifact that arrives with spoofed fields baked in —
328
+ // the bootstrap-side defense is the second layer that must hold.
329
+ const spoofed = {
330
+ ...makeFakeTool("pt_spoof"),
324
331
  origin: "skill",
325
332
  ownerSkillId: "some-other-skill",
326
333
  ownerSkillBundled: true,
327
334
  ownerSkillVersionHash: "deadbeef",
328
- });
335
+ } as unknown as LoadedTool;
329
336
  registerPluginTools("my-plugin", [spoofed]);
330
337
  const retrieved = getTool("pt_spoof");
331
338
  expect(retrieved?.origin).toBe("plugin");
@@ -46,7 +46,7 @@ import {
46
46
  type ToolResultTruncateResult,
47
47
  type TurnContext,
48
48
  } from "../plugins/types.js";
49
- import type { LoadedPluginTool } from "../tools/types.js";
49
+ import type { LoadedTool } from "../tools/types.js";
50
50
 
51
51
  const sampleTrust: TrustContext = {
52
52
  sourceChannel: "vellum",
@@ -207,10 +207,11 @@ describe("plugin core types", () => {
207
207
  },
208
208
  };
209
209
 
210
- const sampleTool: LoadedPluginTool = {
210
+ const sampleTool: LoadedTool = {
211
211
  name: "sample-tool",
212
212
  description: "Sample plugin tool",
213
213
  defaultRiskLevel: RiskLevel.Low,
214
+ executionTarget: "sandbox",
214
215
  input_schema: { type: "object", properties: {}, required: [] },
215
216
  async execute() {
216
217
  return { content: "ok", isError: false };
@@ -61,22 +61,43 @@ mock.module("../prompts/user-reference.js", () => ({
61
61
  resolveUserPronouns: () => null,
62
62
  }));
63
63
 
64
- const { buildSystemPrompt, SYSTEM_PROMPT_CACHE_BOUNDARY } =
65
- await import("../prompts/system-prompt.js");
64
+ // Stub persona-resolver so tests can dictate the slug `buildSystemPrompt`
65
+ // sees without writing contact rows to the test DB. User and channel
66
+ // persona content now flows through bundled sections that read files
67
+ // directly, so tests write the persona file under TEST_DIR rather than
68
+ // stubbing the content here.
69
+ const mockPersona: {
70
+ userSlug: string | null;
71
+ guardianPersona: string | null;
72
+ } = { userSlug: null, guardianPersona: null };
73
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
74
+ const realPersonaResolver = require("../prompts/persona-resolver.js");
75
+ mock.module("../prompts/persona-resolver.js", () => ({
76
+ ...realPersonaResolver,
77
+ resolveUserSlug: () => mockPersona.userSlug,
78
+ resolveGuardianPersona: () => mockPersona.guardianPersona,
79
+ }));
80
+
81
+ const { buildSystemPrompt } = await import("../prompts/system-prompt.js");
66
82
 
67
83
  /**
68
- * Extract the dynamic block (workspace-file content) from the full system prompt.
84
+ * Slice the assembled system prompt from the `# First-Run Ritual`
85
+ * marker through the end of the prompt, returning just the
86
+ * `13-bootstrap` section's rendered payload. Returns "" when the
87
+ * section isn't rendered (no BOOTSTRAP.md, `excludeBootstrap: true`,
88
+ * etc.).
69
89
  */
70
- function dynamicBlock(result: string): string {
71
- const boundaryIdx = result.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
72
- return boundaryIdx >= 0
73
- ? result.slice(boundaryIdx + SYSTEM_PROMPT_CACHE_BOUNDARY.length)
74
- : result;
90
+ function bootstrapBlock(result: string): string {
91
+ const ritualIdx = result.indexOf("# First-Run Ritual");
92
+ if (ritualIdx < 0) return "";
93
+ return result.slice(ritualIdx);
75
94
  }
76
95
 
77
96
  describe("pre-chat onboarding contract", () => {
78
97
  beforeEach(() => {
79
98
  mkdirSync(TEST_DIR, { recursive: true });
99
+ mockPersona.userSlug = null;
100
+ mockPersona.guardianPersona = null;
80
101
  });
81
102
 
82
103
  afterEach(() => {
@@ -87,6 +108,8 @@ describe("pre-chat onboarding contract", () => {
87
108
  "BOOTSTRAP.md",
88
109
  "BOOTSTRAP-REFERENCE.md",
89
110
  "UPDATES.md",
111
+ "users",
112
+ "channels",
90
113
  ]) {
91
114
  const p = join(TEST_DIR, name);
92
115
  if (existsSync(p)) rmSync(p, { recursive: true, force: true });
@@ -151,20 +174,20 @@ describe("pre-chat onboarding contract", () => {
151
174
  };
152
175
 
153
176
  const result = buildSystemPrompt({ onboardingContext: context });
154
- const dynamic = dynamicBlock(result);
177
+ const bootstrap = bootstrapBlock(result);
155
178
 
156
- expect(dynamic).toContain("## First-Run User Context");
157
- expect(dynamic).toContain(
179
+ expect(bootstrap).toContain("## First-Run User Context");
180
+ expect(bootstrap).toContain(
158
181
  "The user completed setup before this conversation.",
159
182
  );
160
- expect(dynamic).toContain("- Daily tools: Slack, Linear");
161
- expect(dynamic).toContain("- Common work: builds code, apps, or tools");
162
- expect(dynamic).toContain("- Name: Alex");
163
- expect(dynamic).toContain("- Chosen assistant name: Nova");
164
- expect(dynamic).toContain("Apply this context quietly.");
183
+ expect(bootstrap).toContain("- Daily tools: Slack, Linear");
184
+ expect(bootstrap).toContain("- Common work: builds code, apps, or tools");
185
+ expect(bootstrap).toContain("- Name: Alex");
186
+ expect(bootstrap).toContain("- Chosen assistant name: Nova");
187
+ expect(bootstrap).toContain("Apply this context quietly.");
165
188
 
166
189
  // Raw JSON must NOT be present
167
- expect(dynamic).not.toContain("```json");
190
+ expect(bootstrap).not.toContain("```json");
168
191
  });
169
192
 
170
193
  test("does NOT inject onboarding context when BOOTSTRAP.md does not exist", () => {
@@ -177,11 +200,11 @@ describe("pre-chat onboarding contract", () => {
177
200
  };
178
201
 
179
202
  const result = buildSystemPrompt({ onboardingContext: context });
180
- const dynamic = dynamicBlock(result);
203
+ const bootstrap = bootstrapBlock(result);
181
204
 
182
- expect(dynamic).not.toContain("## First-Run User Context");
183
- expect(dynamic).not.toContain("First-Run User Context");
184
- expect(dynamic).not.toContain("- Daily tools:");
205
+ expect(bootstrap).not.toContain("## First-Run User Context");
206
+ expect(bootstrap).not.toContain("First-Run User Context");
207
+ expect(bootstrap).not.toContain("- Daily tools:");
185
208
  });
186
209
 
187
210
  test("does NOT inject onboarding context when excludeBootstrap is true", () => {
@@ -200,10 +223,10 @@ describe("pre-chat onboarding contract", () => {
200
223
  onboardingContext: context,
201
224
  excludeBootstrap: true,
202
225
  });
203
- const dynamic = dynamicBlock(result);
226
+ const bootstrap = bootstrapBlock(result);
204
227
 
205
- expect(dynamic).not.toContain("## First-Run User Context");
206
- expect(dynamic).not.toContain("First-Run Ritual");
228
+ expect(bootstrap).not.toContain("## First-Run User Context");
229
+ expect(bootstrap).not.toContain("First-Run Ritual");
207
230
  });
208
231
 
209
232
  test("omits onboarding section when context is undefined", () => {
@@ -213,12 +236,12 @@ describe("pre-chat onboarding contract", () => {
213
236
  );
214
237
 
215
238
  const result = buildSystemPrompt({ onboardingContext: undefined });
216
- const dynamic = dynamicBlock(result);
239
+ const bootstrap = bootstrapBlock(result);
217
240
 
218
241
  // Bootstrap should still be present
219
- expect(dynamic).toContain("First-Run Ritual");
242
+ expect(bootstrap).toContain("First-Run Ritual");
220
243
  // But no onboarding context section
221
- expect(dynamic).not.toContain("## First-Run User Context");
244
+ expect(bootstrap).not.toContain("## First-Run User Context");
222
245
  });
223
246
 
224
247
  test("accepts all four personality tones", () => {
@@ -238,10 +261,10 @@ describe("pre-chat onboarding contract", () => {
238
261
  };
239
262
 
240
263
  const result = buildSystemPrompt({ onboardingContext: context });
241
- const dynamic = dynamicBlock(result);
264
+ const bootstrap = bootstrapBlock(result);
242
265
 
243
- expect(dynamic).toContain("## First-Run User Context");
244
- expect(dynamic).toContain(`- Preferred initial voice: ${tone}`);
266
+ expect(bootstrap).toContain("## First-Run User Context");
267
+ expect(bootstrap).toContain(`- Preferred initial voice: ${tone}`);
245
268
  }
246
269
  });
247
270
 
@@ -260,20 +283,20 @@ describe("pre-chat onboarding contract", () => {
260
283
  };
261
284
 
262
285
  const result = buildSystemPrompt({ onboardingContext: context });
263
- const dynamic = dynamicBlock(result);
286
+ const bootstrap = bootstrapBlock(result);
264
287
 
265
288
  // Should contain compact markdown lines
266
- expect(dynamic).toContain("## First-Run User Context");
267
- expect(dynamic).toContain("- Name: Jane");
268
- expect(dynamic).toContain("- Common work: plans and coordinates work");
269
- expect(dynamic).toContain("- Daily tools: Notion");
270
- expect(dynamic).toContain("- Chosen assistant name: Kit");
271
- expect(dynamic).toContain("- Preferred initial voice: warm");
289
+ expect(bootstrap).toContain("## First-Run User Context");
290
+ expect(bootstrap).toContain("- Name: Jane");
291
+ expect(bootstrap).toContain("- Common work: plans and coordinates work");
292
+ expect(bootstrap).toContain("- Daily tools: Notion");
293
+ expect(bootstrap).toContain("- Chosen assistant name: Kit");
294
+ expect(bootstrap).toContain("- Preferred initial voice: warm");
272
295
 
273
296
  // Must NOT contain JSON output
274
- expect(dynamic).not.toContain("```json");
297
+ expect(bootstrap).not.toContain("```json");
275
298
  const expectedJson = JSON.stringify(context, null, 2);
276
- expect(dynamic).not.toContain(expectedJson);
299
+ expect(bootstrap).not.toContain(expectedJson);
277
300
  });
278
301
 
279
302
  test("empty tools/tasks arrays result in no Daily tools / Common work lines", () => {
@@ -290,12 +313,12 @@ describe("pre-chat onboarding contract", () => {
290
313
  };
291
314
 
292
315
  const result = buildSystemPrompt({ onboardingContext: context });
293
- const dynamic = dynamicBlock(result);
316
+ const bootstrap = bootstrapBlock(result);
294
317
 
295
- expect(dynamic).toContain("## First-Run User Context");
296
- expect(dynamic).toContain("- Name: Alex");
297
- expect(dynamic).not.toContain("- Daily tools:");
298
- expect(dynamic).not.toContain("- Common work:");
318
+ expect(bootstrap).toContain("## First-Run User Context");
319
+ expect(bootstrap).toContain("- Name: Alex");
320
+ expect(bootstrap).not.toContain("- Daily tools:");
321
+ expect(bootstrap).not.toContain("- Common work:");
299
322
  });
300
323
 
301
324
  test("absent userName results in no Name line", () => {
@@ -311,16 +334,16 @@ describe("pre-chat onboarding contract", () => {
311
334
  };
312
335
 
313
336
  const result = buildSystemPrompt({ onboardingContext: context });
314
- const dynamic = dynamicBlock(result);
337
+ const bootstrap = bootstrapBlock(result);
315
338
 
316
- expect(dynamic).toContain("## First-Run User Context");
317
- expect(dynamic).not.toContain("- Name:");
339
+ expect(bootstrap).toContain("## First-Run User Context");
340
+ expect(bootstrap).not.toContain("- Name:");
318
341
  // Other fields should still be present
319
- expect(dynamic).toContain("- Daily tools: Slack");
320
- expect(dynamic).toContain(
342
+ expect(bootstrap).toContain("- Daily tools: Slack");
343
+ expect(bootstrap).toContain(
321
344
  "- Common work: writes docs, emails, or content",
322
345
  );
323
- expect(dynamic).toContain("- Preferred initial voice: warm");
346
+ expect(bootstrap).toContain("- Preferred initial voice: warm");
324
347
  });
325
348
  });
326
349
 
@@ -356,26 +379,26 @@ describe("pre-chat onboarding contract", () => {
356
379
  };
357
380
 
358
381
  const result = buildSystemPrompt({ onboardingContext: context });
359
- const dynamic = dynamicBlock(result);
382
+ const bootstrap = bootstrapBlock(result);
360
383
 
361
384
  // Heading is present
362
- expect(dynamic).toContain("## First-Run User Context");
385
+ expect(bootstrap).toContain("## First-Run User Context");
363
386
 
364
387
  // Normalized labels appear (capitalised tool names, human-readable task descriptions)
365
- expect(dynamic).toContain("- Daily tools: Slack, Notion, Linear");
366
- expect(dynamic).toContain("- Name: Alice");
367
- expect(dynamic).toContain("- Chosen assistant name: Pax");
368
- expect(dynamic).toContain("- Preferred initial voice: grounded");
388
+ expect(bootstrap).toContain("- Daily tools: Slack, Notion, Linear");
389
+ expect(bootstrap).toContain("- Name: Alice");
390
+ expect(bootstrap).toContain("- Chosen assistant name: Pax");
391
+ expect(bootstrap).toContain("- Preferred initial voice: grounded");
369
392
  // Common work descriptions are normalised from task IDs
370
- expect(dynamic).toContain("- Common work:");
371
-
372
- // No raw JSON anywhere in the dynamic block
373
- expect(dynamic).not.toContain("```json");
374
- expect(dynamic).not.toContain('"tools"');
375
- expect(dynamic).not.toContain('"tasks"');
376
- expect(dynamic).not.toContain('"tone"');
377
- expect(dynamic).not.toContain('"userName"');
378
- expect(dynamic).not.toContain('"assistantName"');
393
+ expect(bootstrap).toContain("- Common work:");
394
+
395
+ // No raw JSON anywhere in the bootstrap block
396
+ expect(bootstrap).not.toContain("```json");
397
+ expect(bootstrap).not.toContain('"tools"');
398
+ expect(bootstrap).not.toContain('"tasks"');
399
+ expect(bootstrap).not.toContain('"tone"');
400
+ expect(bootstrap).not.toContain('"userName"');
401
+ expect(bootstrap).not.toContain('"assistantName"');
379
402
  });
380
403
 
381
404
  test("without BOOTSTRAP.md, onboarding context does NOT appear in system prompt", () => {
@@ -389,15 +412,15 @@ describe("pre-chat onboarding contract", () => {
389
412
  };
390
413
 
391
414
  const result = buildSystemPrompt({ onboardingContext: context });
392
- const dynamic = dynamicBlock(result);
415
+ const bootstrap = bootstrapBlock(result);
393
416
 
394
417
  // Onboarding section must be absent
395
- expect(dynamic).not.toContain("## First-Run User Context");
396
- expect(dynamic).not.toContain("First-Run Ritual");
397
- expect(dynamic).not.toContain("- Daily tools:");
398
- expect(dynamic).not.toContain("- Name: Bob");
399
- expect(dynamic).not.toContain("- Chosen assistant name:");
400
- expect(dynamic).not.toContain("Apply this context quietly.");
418
+ expect(bootstrap).not.toContain("## First-Run User Context");
419
+ expect(bootstrap).not.toContain("First-Run Ritual");
420
+ expect(bootstrap).not.toContain("- Daily tools:");
421
+ expect(bootstrap).not.toContain("- Name: Bob");
422
+ expect(bootstrap).not.toContain("- Chosen assistant name:");
423
+ expect(bootstrap).not.toContain("Apply this context quietly.");
401
424
  });
402
425
 
403
426
  test("excludeBootstrap suppresses both bootstrap and onboarding sections", () => {
@@ -418,34 +441,38 @@ describe("pre-chat onboarding contract", () => {
418
441
  onboardingContext: context,
419
442
  excludeBootstrap: true,
420
443
  });
421
- const dynamic = dynamicBlock(result);
444
+ const bootstrap = bootstrapBlock(result);
422
445
 
423
446
  // Both bootstrap and onboarding must be suppressed
424
- expect(dynamic).not.toContain("First-Run Ritual");
425
- expect(dynamic).not.toContain("## First-Run User Context");
426
- expect(dynamic).not.toContain("- Daily tools:");
427
- expect(dynamic).not.toContain("- Name: Charlie");
428
- expect(dynamic).not.toContain("Apply this context quietly.");
447
+ expect(bootstrap).not.toContain("First-Run Ritual");
448
+ expect(bootstrap).not.toContain("## First-Run User Context");
449
+ expect(bootstrap).not.toContain("- Daily tools:");
450
+ expect(bootstrap).not.toContain("- Name: Charlie");
451
+ expect(bootstrap).not.toContain("Apply this context quietly.");
429
452
  });
430
453
 
431
454
  test("userPersona is included independently of onboarding context", () => {
432
- // No BOOTSTRAP.md — the durable persona path after bootstrap is deleted
433
- const personaContent =
434
- "# User Persona\n\nPrefers concise answers. Works in fintech.";
455
+ // No BOOTSTRAP.md — the durable persona path after bootstrap is deleted.
456
+ // User persona content now lives in `users/<slug>.md` and renders
457
+ // via the `10-user-persona` bundled section in the static prefix.
458
+ mkdirSync(join(TEST_DIR, "users"), { recursive: true });
459
+ writeFileSync(
460
+ join(TEST_DIR, "users", "default.md"),
461
+ "# User Persona\n\nPrefers concise answers. Works in fintech.",
462
+ );
435
463
 
436
464
  const result = buildSystemPrompt({
437
- userPersona: personaContent,
438
465
  // No onboardingContext — simulates post-onboarding conversation
439
466
  });
440
- const dynamic = dynamicBlock(result);
441
467
 
442
468
  // Persona content appears in prompt even without bootstrap or onboarding
443
- expect(dynamic).toContain("# User Persona");
444
- expect(dynamic).toContain("Prefers concise answers. Works in fintech.");
469
+ expect(result).toContain("# User Persona");
470
+ expect(result).toContain("Prefers concise answers. Works in fintech.");
445
471
 
446
472
  // No onboarding section should be present
447
- expect(dynamic).not.toContain("## First-Run User Context");
448
- expect(dynamic).not.toContain("First-Run Ritual");
473
+ const bootstrap = bootstrapBlock(result);
474
+ expect(bootstrap).not.toContain("## First-Run User Context");
475
+ expect(bootstrap).not.toContain("First-Run Ritual");
449
476
  });
450
477
 
451
478
  test("userPersona appears alongside onboarding context during first run", () => {
@@ -454,8 +481,14 @@ describe("pre-chat onboarding contract", () => {
454
481
  "# Bootstrap\n\nOnboarding flow.",
455
482
  );
456
483
 
457
- const personaContent =
458
- "# User Persona\n\nEarly-stage startup founder. Likes bullet points.";
484
+ // User persona file renders via the `10-user-persona` section
485
+ // and the First-Run Ritual + onboarding context render via the
486
+ // `13-bootstrap` section — both in the static prefix.
487
+ mkdirSync(join(TEST_DIR, "users"), { recursive: true });
488
+ writeFileSync(
489
+ join(TEST_DIR, "users", "default.md"),
490
+ "# User Persona\n\nEarly-stage startup founder. Likes bullet points.",
491
+ );
459
492
  const context: OnboardingContext = {
460
493
  tools: ["slack"],
461
494
  tasks: ["writing"],
@@ -464,17 +497,17 @@ describe("pre-chat onboarding contract", () => {
464
497
  };
465
498
 
466
499
  const result = buildSystemPrompt({
467
- userPersona: personaContent,
468
500
  onboardingContext: context,
469
501
  });
470
- const dynamic = dynamicBlock(result);
471
-
472
- // Both persona and onboarding context appear
473
- expect(dynamic).toContain("# User Persona");
474
- expect(dynamic).toContain("Likes bullet points.");
475
- expect(dynamic).toContain("## First-Run User Context");
476
- expect(dynamic).toContain("- Name: Dana");
477
- expect(dynamic).toContain("- Daily tools: Slack");
502
+ const bootstrap = bootstrapBlock(result);
503
+
504
+ // Both persona and onboarding context appear in the static prefix
505
+ // (`10-user-persona` and `13-bootstrap` respectively)
506
+ expect(result).toContain("# User Persona");
507
+ expect(result).toContain("Likes bullet points.");
508
+ expect(bootstrap).toContain("## First-Run User Context");
509
+ expect(bootstrap).toContain("- Name: Dana");
510
+ expect(bootstrap).toContain("- Daily tools: Slack");
478
511
  });
479
512
  });
480
513
  });
@@ -216,6 +216,17 @@ describe("resolvePricing", () => {
216
216
  expect(result.estimatedCostUsd).toBe(0.25 + 1.5);
217
217
  });
218
218
 
219
+ test("returns priced for gemini-3.1-flash-lite", () => {
220
+ const result = resolvePricing(
221
+ "gemini",
222
+ "gemini-3.1-flash-lite",
223
+ 1_000_000,
224
+ 1_000_000,
225
+ );
226
+ expect(result.pricingStatus).toBe("priced");
227
+ expect(result.estimatedCostUsd).toBe(0.25 + 1.5);
228
+ });
229
+
219
230
  test("prices gemini-2.5-pro at the low-context tier through 200k input tokens", () => {
220
231
  const result = resolvePricing(
221
232
  "gemini",
@@ -489,6 +500,7 @@ describe("resolvePricingForUsage", () => {
489
500
  const cases = [
490
501
  ["gemini-3-flash-preview", 0.05],
491
502
  ["gemini-3.1-flash-lite-preview", 0.025],
503
+ ["gemini-3.1-flash-lite", 0.025],
492
504
  ["gemini-2.5-flash", 0.03],
493
505
  ["gemini-2.5-flash-lite", 0.01],
494
506
  ["gemini-2.5-pro", 0.625],
@@ -95,7 +95,6 @@ type PersistUserMessageMock = ReturnType<
95
95
  type RunAgentLoopMock = ReturnType<
96
96
  typeof mock<(...args: unknown[]) => Promise<void>>
97
97
  >;
98
- type NoticeMock = ReturnType<typeof mock<(notice: string | undefined) => void>>;
99
98
  interface TestConversation {
100
99
  conversationId: string;
101
100
  trustContext: unknown;
@@ -123,13 +122,10 @@ interface TestConversation {
123
122
  estimatedCost: number;
124
123
  };
125
124
  persistUserMessage: PersistUserMessageMock;
126
- setSlackRuntimeContextNotice: NoticeMock;
127
125
  runAgentLoop: RunAgentLoopMock;
128
126
  updateClient: (sender: (...args: unknown[]) => void) => void;
129
127
  getCurrentSender: () => ((...args: unknown[]) => void) | undefined;
130
128
  __loopDeferred: Deferred<void>;
131
- __noticeCalls: Array<string | undefined>;
132
- __loopNotices: Array<string | undefined>;
133
129
  __clientSenders: Array<((...args: unknown[]) => void) | undefined>;
134
130
  }
135
131
 
@@ -171,11 +167,8 @@ async function waitForRunAgentLoopCall(): Promise<void> {
171
167
  function makeConversation(): TestConversation {
172
168
  let turnChannelContext: TurnChannelContext | null = null;
173
169
  let turnInterfaceContext: TurnInterfaceContext | null = null;
174
- let slackNotice: string | undefined;
175
170
  let currentSender: ((...args: unknown[]) => void) | undefined;
176
- const noticeCalls: Array<string | undefined> = [];
177
171
  const loopDeferred = createDeferred<void>();
178
- const loopNotices: Array<string | undefined> = [];
179
172
  const clientSenders: Array<((...args: unknown[]) => void) | undefined> = [];
180
173
  const messages: unknown[] = [];
181
174
 
@@ -223,12 +216,7 @@ function makeConversation(): TestConversation {
223
216
  _metadata?: Record<string, unknown>,
224
217
  ) => "persisted-user-message-id",
225
218
  ),
226
- setSlackRuntimeContextNotice: mock((notice: string | undefined) => {
227
- slackNotice = notice;
228
- noticeCalls.push(notice);
229
- }),
230
219
  runAgentLoop: mock(async (..._args: unknown[]) => {
231
- loopNotices.push(slackNotice);
232
220
  await loopDeferred.promise;
233
221
  }),
234
222
  updateClient: (sender: (...args: unknown[]) => void) => {
@@ -237,8 +225,6 @@ function makeConversation(): TestConversation {
237
225
  },
238
226
  getCurrentSender: () => currentSender,
239
227
  __loopDeferred: loopDeferred,
240
- __noticeCalls: noticeCalls,
241
- __loopNotices: loopNotices,
242
228
  __clientSenders: clientSenders,
243
229
  };
244
230
 
@@ -252,15 +238,13 @@ describe("processMessageInBackground Slack option propagation", () => {
252
238
  broadcastMessages.length = 0;
253
239
  });
254
240
 
255
- test("passes Slack inbound metadata to persistence and exposes the runtime notice during the loop", async () => {
241
+ test("passes Slack inbound metadata to persistence during background processing", async () => {
256
242
  const slackInbound = {
257
243
  channelId: "C0123CHANNEL",
258
244
  channelTs: "1700000001.111111",
259
245
  threadTs: "1700000000.000001",
260
246
  displayName: "Alice",
261
247
  };
262
- const notice =
263
- "Slack context note: this turn joined an existing thread. 2 earlier messages were backfilled.";
264
248
 
265
249
  const result = await processMessageInBackground(
266
250
  "conv-background-slack",
@@ -268,7 +252,6 @@ describe("processMessageInBackground Slack option propagation", () => {
268
252
  undefined,
269
253
  {
270
254
  slackInbound,
271
- slackRuntimeContextNotice: notice,
272
255
  },
273
256
  "slack",
274
257
  "slack",
@@ -280,43 +263,10 @@ describe("processMessageInBackground Slack option propagation", () => {
280
263
  slackInbound,
281
264
  });
282
265
  expect(activeConversation.runAgentLoop).toHaveBeenCalledTimes(1);
283
- expect(activeConversation.__loopNotices).toEqual([notice]);
284
266
 
285
267
  activeConversation.__loopDeferred.resolve();
286
268
  await activeConversation.__loopDeferred.promise;
287
269
  await Promise.resolve();
288
-
289
- expect(activeConversation.__noticeCalls).toEqual([notice, undefined]);
290
- });
291
-
292
- test("clears the Slack runtime notice after normal message processing", async () => {
293
- const notice =
294
- "Slack context note: this turn joined an existing thread. 2 earlier messages were backfilled.";
295
-
296
- const processing = processMessage(
297
- "conv-background-slack",
298
- "Reply from Slack",
299
- undefined,
300
- {
301
- slackRuntimeContextNotice: notice,
302
- isInteractive: true,
303
- },
304
- "slack",
305
- "slack",
306
- );
307
-
308
- await waitForRunAgentLoopCall();
309
-
310
- expect(activeConversation.runAgentLoop).toHaveBeenCalledTimes(1);
311
- expect(activeConversation.__loopNotices).toEqual([notice]);
312
-
313
- activeConversation.__loopDeferred.resolve();
314
- await expect(processing).resolves.toEqual({
315
- messageId: "persisted-user-message-id",
316
- });
317
-
318
- expect(activeConversation.__noticeCalls).toEqual([notice, undefined]);
319
- expect(activeConversation.__clientSenders).toHaveLength(2);
320
270
  });
321
271
 
322
272
  test("observes live agent events without replacing the broadcast emitter", async () => {