@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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vellumai/assistant",
3
- "version": "0.8.3",
3
+ "version": "0.8.5",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -7,8 +7,8 @@
7
7
  * throw → catch-block fallback case).
8
8
  * 2. **Reason matches break site** — for each reachable break site, the
9
9
  * emitted reason is the one documented in `AgentLoopExitReason`.
10
- * 3. **Always the last AgentEvent of the run** — consumers can rely on
11
- * positional ordering to find it.
10
+ * 3. **Always the last AgentEvent of terminal runs** — consumers can rely on
11
+ * positional ordering to find it when a run reaches a terminal state.
12
12
  *
13
13
  * Sites not exercised here (`empty_response_exhausted`, `aborted_via_error`)
14
14
  * require deeper provider fakery and are best covered by integration tests
@@ -172,7 +172,7 @@ describe("AgentLoop exit-reason instrumentation", () => {
172
172
  expect(lastExitEvent(events)?.reason).toBe("yield_to_user");
173
173
  });
174
174
 
175
- test("emits 'checkpoint_yield' when onCheckpoint returns 'yield'", async () => {
175
+ test("does not emit agent_loop_exit when onCheckpoint yields control", async () => {
176
176
  const { provider } = createMockProvider([
177
177
  toolUseResponse("t1", "read_file", { path: "/a.txt" }),
178
178
  textResponse("never reached"),
@@ -198,8 +198,7 @@ describe("AgentLoop exit-reason instrumentation", () => {
198
198
  onCheckpoint,
199
199
  );
200
200
 
201
- expect(countExitEvents(events)).toBe(1);
202
- expect(lastExitEvent(events)?.reason).toBe("checkpoint_yield");
201
+ expect(countExitEvents(events)).toBe(0);
203
202
  });
204
203
 
205
204
  test("emits 'error' when provider throws an unhandled error", async () => {
@@ -257,7 +257,7 @@ const anthropicStub = { name: "anthropic" };
257
257
  mock.module("../providers/registry.js", () => ({
258
258
  getProvider: () => anthropicStub,
259
259
  listProviders: () => ["anthropic"],
260
- initializeProviders: () => {},
260
+ initializeProviders: async () => {},
261
261
  resolveProviderFromConnection: async () => anthropicStub,
262
262
  }));
263
263
 
@@ -181,6 +181,88 @@ describe("AgentLoop", () => {
181
181
  ]);
182
182
  });
183
183
 
184
+ test("re-resolves override profile before each provider call", async () => {
185
+ const toolCallId = "tool-1";
186
+ const { provider, calls } = createMockProvider([
187
+ toolUseResponse(toolCallId, "read_file", { path: "/tmp/test.txt" }),
188
+ textResponse("File contents received."),
189
+ ]);
190
+
191
+ let overrideProfile: string | undefined;
192
+ const toolExecutor = async () => {
193
+ overrideProfile = "quality-optimized";
194
+ return { content: "ok", isError: false };
195
+ };
196
+ const loop = new AgentLoop(
197
+ provider,
198
+ "system",
199
+ {},
200
+ dummyTools,
201
+ toolExecutor,
202
+ );
203
+
204
+ await loop.run(
205
+ [userMessage],
206
+ collectEvents([]),
207
+ undefined,
208
+ "req-1",
209
+ undefined,
210
+ "mainAgent",
211
+ undefined,
212
+ undefined,
213
+ undefined,
214
+ () => overrideProfile,
215
+ );
216
+
217
+ expect(calls).toHaveLength(2);
218
+ expect(calls[0].options?.config?.overrideProfile).toBeUndefined();
219
+ expect(calls[1].options?.config?.overrideProfile).toBe("quality-optimized");
220
+ });
221
+
222
+ test("re-resolves max input tokens before truncating tool results", async () => {
223
+ const toolCallId = "tool-1";
224
+ const toolOutput = "x".repeat(2_500);
225
+ const { provider, calls } = createMockProvider([
226
+ toolUseResponse(toolCallId, "read_file", { path: "/tmp/test.txt" }),
227
+ textResponse("File contents received."),
228
+ ]);
229
+
230
+ let maxInputTokens = 1_000;
231
+ const toolExecutor = async () => {
232
+ maxInputTokens = 10_000;
233
+ return { content: toolOutput, isError: false };
234
+ };
235
+ const loop = new AgentLoop(
236
+ provider,
237
+ "system",
238
+ {},
239
+ dummyTools,
240
+ toolExecutor,
241
+ );
242
+
243
+ await loop.run(
244
+ [userMessage],
245
+ collectEvents([]),
246
+ undefined,
247
+ "req-1",
248
+ undefined,
249
+ "mainAgent",
250
+ undefined,
251
+ undefined,
252
+ 1_000,
253
+ undefined,
254
+ () => maxInputTokens,
255
+ );
256
+
257
+ const secondCallMessages = calls[1].messages;
258
+ const lastMsg = secondCallMessages[secondCallMessages.length - 1];
259
+ const toolResultBlock = lastMsg.content.find(
260
+ (b): b is Extract<ContentBlock, { type: "tool_result" }> =>
261
+ b.type === "tool_result",
262
+ );
263
+ expect(toolResultBlock?.content).toBe(toolOutput);
264
+ });
265
+
184
266
  // 3. Multi-turn tool loop
185
267
  test("supports multi-turn tool execution", async () => {
186
268
  const { provider, calls } = createMockProvider([
@@ -470,7 +552,6 @@ describe("AgentLoop", () => {
470
552
  ).toBe(false);
471
553
  });
472
554
 
473
-
474
555
  // 9. Tool executor error results are forwarded correctly
475
556
  test("forwards tool error results to provider", async () => {
476
557
  const { provider, calls } = createMockProvider([
@@ -1767,7 +1848,9 @@ describe("AgentLoop", () => {
1767
1848
  ]);
1768
1849
 
1769
1850
  // message_complete emitted for tool_use response + retry text response (not the empty one)
1770
- const messageCompletes = events.filter((e) => e.type === "message_complete");
1851
+ const messageCompletes = events.filter(
1852
+ (e) => e.type === "message_complete",
1853
+ );
1771
1854
  expect(messageCompletes).toHaveLength(2);
1772
1855
  });
1773
1856
 
@@ -1883,7 +1966,9 @@ describe("AgentLoop", () => {
1883
1966
  expect(calls).toHaveLength(3);
1884
1967
 
1885
1968
  // message_complete: tool_use response + final empty response (retry exhausted)
1886
- const messageCompletes = events.filter((e) => e.type === "message_complete");
1969
+ const messageCompletes = events.filter(
1970
+ (e) => e.type === "message_complete",
1971
+ );
1887
1972
  expect(messageCompletes).toHaveLength(2);
1888
1973
 
1889
1974
  // The last assistant message in history is the empty one
@@ -1,5 +1,7 @@
1
1
  import { beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
+ import type { Anthropic } from "@anthropic-ai/sdk";
4
+
3
5
  import type { Message, ToolDefinition } from "../providers/types.js";
4
6
 
5
7
  // ---------------------------------------------------------------------------
@@ -100,7 +102,6 @@ mock.module("@anthropic-ai/sdk", () => ({
100
102
  }));
101
103
 
102
104
  // Import after mocking
103
- import { SYSTEM_PROMPT_CACHE_BOUNDARY } from "../prompts/system-prompt.js";
104
105
  import {
105
106
  AnthropicProvider,
106
107
  isPlaceholderSentinelText,
@@ -204,28 +205,30 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
204
205
  expect(lastStreamParams!.thinking).toEqual({ type: "disabled" });
205
206
  });
206
207
 
207
- test("splits system prompt into two cache blocks on boundary marker", async () => {
208
- const staticBlock = "You are a helpful assistant.";
209
- const dynamicBlock = "User workspace files here.";
210
- const prompt = staticBlock + SYSTEM_PROMPT_CACHE_BOUNDARY + dynamicBlock;
211
-
212
- await provider.sendMessage([userMsg("Hi")], undefined, prompt);
208
+ test("drops unsigned thinking blocks from prior assistant messages", async () => {
209
+ await provider.sendMessage([
210
+ userMsg("Hi"),
211
+ {
212
+ role: "assistant",
213
+ content: [
214
+ { type: "thinking", thinking: "non-native reasoning", signature: "" },
215
+ { type: "text", text: "I can help." },
216
+ ],
217
+ },
218
+ userMsg("Continue"),
219
+ ]);
213
220
 
214
- const system = lastStreamParams!.system as Array<{
215
- type: string;
216
- text: string;
217
- cache_control?: { type: string; ttl?: string };
221
+ const messages = lastStreamParams!.messages as Array<{
222
+ role: string;
223
+ content: Array<{ type: string; text?: string; thinking?: string }>;
218
224
  }>;
219
- expect(system).toHaveLength(2);
220
- expect(system[0].text).toBe(staticBlock);
221
- expect(system[0].cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
222
- expect(system[1].text).toBe(dynamicBlock);
223
- expect(system[1].cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
225
+ const assistant = messages.find((message) => message.role === "assistant");
226
+
227
+ expect(assistant?.content).toEqual([{ type: "text", text: "I can help." }]);
224
228
  });
225
229
 
226
- test("omits empty dynamic system block after cache boundary", async () => {
227
- const staticBlock = "You are a helpful assistant.";
228
- const prompt = staticBlock + SYSTEM_PROMPT_CACHE_BOUNDARY;
230
+ test("renders the system prompt as a single 1h-cached block", async () => {
231
+ const prompt = "You are a helpful assistant.";
229
232
 
230
233
  await provider.sendMessage([userMsg("Hi")], undefined, prompt);
231
234
 
@@ -235,16 +238,14 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
235
238
  cache_control?: { type: string; ttl?: string };
236
239
  }>;
237
240
  expect(system).toHaveLength(1);
238
- expect(system[0].text).toBe(staticBlock);
241
+ expect(system[0].text).toBe(prompt);
239
242
  expect(system[0].cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
240
243
  });
241
244
 
242
- test("drops static system block cache_control when total would exceed 4", async () => {
243
- const staticBlock = "You are a helpful assistant.";
244
- const dynamicBlock = "User workspace files here.";
245
- const prompt = staticBlock + SYSTEM_PROMPT_CACHE_BOUNDARY + dynamicBlock;
246
-
247
- // Boundary (2 system) + tools (1) + turn-start (1) + tail (1) = 5 → must cap at 4
245
+ test("applies the standard 4-breakpoint cache layout in a tool-use loop", async () => {
246
+ // system(1) + tools(1) + turn-start(1) + tail(1) = 4, the Anthropic
247
+ // per-request cap. All four breakpoints should be present.
248
+ const prompt = "You are a helpful assistant.";
248
249
  const messages: Message[] = [
249
250
  userMsg("Do something"),
250
251
  toolUseMsg("tu_1", "bash"),
@@ -257,13 +258,9 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
257
258
  text: string;
258
259
  cache_control?: { type: string; ttl?: string };
259
260
  }>;
260
- expect(system).toHaveLength(2);
261
- // Static block's cache_control dropped (small, cheap to re-read)
262
- expect(system[0].cache_control).toBeUndefined();
263
- // Dynamic block keeps its cache_control
264
- expect(system[1].cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
261
+ expect(system).toHaveLength(1);
262
+ expect(system[0].cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
265
263
 
266
- // Tools breakpoint still present
267
264
  const tools = lastStreamParams!.tools as Array<{
268
265
  cache_control?: { type: string; ttl?: string };
269
266
  }>;
@@ -272,7 +269,6 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
272
269
  ttl: "1h",
273
270
  });
274
271
 
275
- // Turn-start + tail breakpoints still present
276
272
  const sent = lastStreamParams!.messages as Array<{
277
273
  role: string;
278
274
  content: Array<{
@@ -408,6 +404,31 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
408
404
  expect(lastBlock.cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
409
405
  });
410
406
 
407
+ test("disableTurnStartCache suppresses the 1h breakpoint on the turn-starting user message", async () => {
408
+ // One-shot callers (e.g. the memory router) send a single user message
409
+ // per call with content that changes every time. Caching the turn-start
410
+ // block would create unused entries — `disableTurnStartCache: true`
411
+ // opts out.
412
+ await provider.sendMessage(
413
+ [userMsg("Pick relevant pages")],
414
+ undefined,
415
+ undefined,
416
+ {
417
+ config: { disableTurnStartCache: true },
418
+ },
419
+ );
420
+
421
+ const sent = lastStreamParams!.messages as Array<{
422
+ role: string;
423
+ content: Array<{
424
+ type: string;
425
+ cache_control?: { type: string; ttl?: string };
426
+ }>;
427
+ }>;
428
+ const lastBlock = sent[0].content[sent[0].content.length - 1];
429
+ expect(lastBlock.cache_control).toBeUndefined();
430
+ });
431
+
411
432
  test("previous-turn anchor is NOT applied during a tool-use loop", async () => {
412
433
  // When the request is mid tool-use (last msg is a tool_result), the
413
434
  // turn-start anchor already covers the long prefix, so we must not
@@ -2405,3 +2426,251 @@ describe("OpenRouterProvider — Anthropic dispatch", () => {
2405
2426
  expect(lastStreamParams!.model).toBe("anthropic/claude-haiku-4.5");
2406
2427
  });
2407
2428
  });
2429
+
2430
+ // ---------------------------------------------------------------------------
2431
+ // Thinking block send-time filtering
2432
+ // ---------------------------------------------------------------------------
2433
+
2434
+ describe("AnthropicProvider — thinking block send-time filtering", () => {
2435
+ let provider: AnthropicProvider;
2436
+
2437
+ beforeEach(() => {
2438
+ lastStreamParams = null;
2439
+ _lastStreamOptions = null;
2440
+ lastConstructorArgs = null;
2441
+ scriptedStream = null;
2442
+ provider = new AnthropicProvider("sk-ant-test", "claude-sonnet-4-6");
2443
+ });
2444
+
2445
+ function assistantThinkingMsg(
2446
+ thinking: string,
2447
+ signature: string,
2448
+ text: string,
2449
+ ): Message {
2450
+ return {
2451
+ role: "assistant",
2452
+ content: [
2453
+ { type: "thinking", thinking, signature },
2454
+ { type: "text", text },
2455
+ ],
2456
+ };
2457
+ }
2458
+
2459
+ function assistantThinkingToolUseMsg(
2460
+ thinking: string,
2461
+ signature: string,
2462
+ toolUseId: string,
2463
+ toolName: string,
2464
+ ): Message {
2465
+ return {
2466
+ role: "assistant",
2467
+ content: [
2468
+ { type: "thinking", thinking, signature },
2469
+ { type: "tool_use", id: toolUseId, name: toolName, input: {} },
2470
+ ],
2471
+ };
2472
+ }
2473
+
2474
+ function assistantRedactedThinkingMsg(data: string, text: string): Message {
2475
+ return {
2476
+ role: "assistant",
2477
+ content: [
2478
+ { type: "redacted_thinking", data },
2479
+ { type: "text", text },
2480
+ ],
2481
+ };
2482
+ }
2483
+
2484
+ test("strips thinking blocks from completed historical assistant turns", async () => {
2485
+ const messages: Message[] = [
2486
+ userMsg("What is 2+2?"),
2487
+ assistantThinkingMsg("let me think...", "sig-abc-old", "4"),
2488
+ userMsg("And what is 3+3?"),
2489
+ ];
2490
+
2491
+ await provider.sendMessage(messages, sampleTools, "system");
2492
+ expect(lastStreamParams).toBeTruthy();
2493
+
2494
+ const sent = lastStreamParams!.messages as Anthropic.MessageParam[];
2495
+ const assistantTurn = sent.find((m) => m.role === "assistant");
2496
+ expect(assistantTurn).toBeTruthy();
2497
+
2498
+ const blocks = assistantTurn!.content as Anthropic.ContentBlockParam[];
2499
+ const thinkingBlocks = blocks.filter(
2500
+ (b) => typeof b !== "string" && b.type === "thinking",
2501
+ );
2502
+ expect(thinkingBlocks).toHaveLength(0);
2503
+
2504
+ const textBlocks = blocks.filter(
2505
+ (b) => typeof b !== "string" && b.type === "text",
2506
+ );
2507
+ expect(textBlocks).toHaveLength(1);
2508
+ });
2509
+
2510
+ test("strips redacted_thinking blocks from completed historical turns", async () => {
2511
+ const messages: Message[] = [
2512
+ userMsg("What is 2+2?"),
2513
+ assistantRedactedThinkingMsg("encrypted-data-xyz", "4"),
2514
+ userMsg("And what is 3+3?"),
2515
+ ];
2516
+
2517
+ await provider.sendMessage(messages, sampleTools, "system");
2518
+ expect(lastStreamParams).toBeTruthy();
2519
+
2520
+ const sent = lastStreamParams!.messages as Anthropic.MessageParam[];
2521
+ const assistantTurn = sent.find((m) => m.role === "assistant");
2522
+ expect(assistantTurn).toBeTruthy();
2523
+
2524
+ const blocks = assistantTurn!.content as Anthropic.ContentBlockParam[];
2525
+ const redactedBlocks = blocks.filter(
2526
+ (b) => typeof b !== "string" && b.type === "redacted_thinking",
2527
+ );
2528
+ expect(redactedBlocks).toHaveLength(0);
2529
+ });
2530
+
2531
+ test("preserves thinking blocks in active tool-use continuation span", async () => {
2532
+ const messages: Message[] = [
2533
+ userMsg("Read the file"),
2534
+ assistantThinkingToolUseMsg(
2535
+ "I should read the file",
2536
+ "sig-valid-123",
2537
+ "tu-1",
2538
+ "file_read",
2539
+ ),
2540
+ toolResultMsg("tu-1", "file contents here"),
2541
+ ];
2542
+
2543
+ await provider.sendMessage(messages, sampleTools, "system");
2544
+ expect(lastStreamParams).toBeTruthy();
2545
+
2546
+ const sent = lastStreamParams!.messages as Anthropic.MessageParam[];
2547
+ const assistantTurn = sent.find((m) => m.role === "assistant");
2548
+ expect(assistantTurn).toBeTruthy();
2549
+
2550
+ const blocks = assistantTurn!.content as Anthropic.ContentBlockParam[];
2551
+ const thinkingBlocks = blocks.filter(
2552
+ (b) => typeof b !== "string" && b.type === "thinking",
2553
+ );
2554
+ expect(thinkingBlocks).toHaveLength(1);
2555
+ expect((thinkingBlocks[0] as { signature: string }).signature).toBe(
2556
+ "sig-valid-123",
2557
+ );
2558
+ });
2559
+
2560
+ test("strips historical thinking but preserves active continuation in same conversation", async () => {
2561
+ const messages: Message[] = [
2562
+ // Completed historical turn
2563
+ userMsg("What is 2+2?"),
2564
+ assistantThinkingMsg("old thinking", "sig-old-stale", "4"),
2565
+ // Active tool-use continuation
2566
+ userMsg("Now read the file"),
2567
+ assistantThinkingToolUseMsg(
2568
+ "current thinking",
2569
+ "sig-current-valid",
2570
+ "tu-2",
2571
+ "file_read",
2572
+ ),
2573
+ toolResultMsg("tu-2", "file contents"),
2574
+ ];
2575
+
2576
+ await provider.sendMessage(messages, sampleTools, "system");
2577
+ expect(lastStreamParams).toBeTruthy();
2578
+
2579
+ const sent = lastStreamParams!.messages as Anthropic.MessageParam[];
2580
+ const assistantTurns = sent.filter((m) => m.role === "assistant");
2581
+ expect(assistantTurns.length).toBeGreaterThanOrEqual(2);
2582
+
2583
+ // Historical turn: thinking stripped
2584
+ const historicalBlocks = assistantTurns[0]
2585
+ .content as Anthropic.ContentBlockParam[];
2586
+ const historicalThinking = historicalBlocks.filter(
2587
+ (b) => typeof b !== "string" && b.type === "thinking",
2588
+ );
2589
+ expect(historicalThinking).toHaveLength(0);
2590
+
2591
+ // Active turn: thinking preserved
2592
+ const activeBlocks = assistantTurns[1]
2593
+ .content as Anthropic.ContentBlockParam[];
2594
+ const activeThinking = activeBlocks.filter(
2595
+ (b) => typeof b !== "string" && b.type === "thinking",
2596
+ );
2597
+ expect(activeThinking).toHaveLength(1);
2598
+ expect((activeThinking[0] as { signature: string }).signature).toBe(
2599
+ "sig-current-valid",
2600
+ );
2601
+ });
2602
+
2603
+ test("uses placeholder when stripping thinking leaves assistant message empty", async () => {
2604
+ const messages: Message[] = [
2605
+ userMsg("Think about this"),
2606
+ {
2607
+ role: "assistant",
2608
+ content: [{ type: "thinking", thinking: "hmm...", signature: "sig-x" }],
2609
+ },
2610
+ userMsg("What did you conclude?"),
2611
+ ];
2612
+
2613
+ await provider.sendMessage(messages, sampleTools, "system");
2614
+ expect(lastStreamParams).toBeTruthy();
2615
+
2616
+ const sent = lastStreamParams!.messages as Anthropic.MessageParam[];
2617
+ const assistantTurn = sent.find((m) => m.role === "assistant");
2618
+ expect(assistantTurn).toBeTruthy();
2619
+
2620
+ const blocks = assistantTurn!.content as Anthropic.ContentBlockParam[];
2621
+ expect(blocks).toHaveLength(1);
2622
+ expect((blocks[0] as { type: string; text: string }).type).toBe("text");
2623
+ expect(
2624
+ isPlaceholderSentinelText((blocks[0] as { text: string }).text),
2625
+ ).toBe(true);
2626
+ });
2627
+
2628
+ test("multi-step tool-use chain preserves all thinking in the active span", async () => {
2629
+ const messages: Message[] = [
2630
+ // Completed historical turn
2631
+ userMsg("Hello"),
2632
+ assistantThinkingMsg("old thinking", "sig-old", "Hi there"),
2633
+ // Multi-step active tool-use chain
2634
+ userMsg("Do two things"),
2635
+ assistantThinkingToolUseMsg(
2636
+ "step 1 thinking",
2637
+ "sig-step1",
2638
+ "tu-a",
2639
+ "file_read",
2640
+ ),
2641
+ toolResultMsg("tu-a", "result a"),
2642
+ assistantThinkingToolUseMsg(
2643
+ "step 2 thinking",
2644
+ "sig-step2",
2645
+ "tu-b",
2646
+ "file_write",
2647
+ ),
2648
+ toolResultMsg("tu-b", "result b"),
2649
+ ];
2650
+
2651
+ await provider.sendMessage(messages, sampleTools, "system");
2652
+ expect(lastStreamParams).toBeTruthy();
2653
+
2654
+ const sent = lastStreamParams!.messages as Anthropic.MessageParam[];
2655
+
2656
+ // Collect all thinking blocks across all assistant messages
2657
+ const allThinking: Anthropic.ContentBlockParam[] = [];
2658
+ for (const m of sent) {
2659
+ if (m.role !== "assistant") continue;
2660
+ const blocks = m.content as Anthropic.ContentBlockParam[];
2661
+ for (const b of blocks) {
2662
+ if (typeof b !== "string" && b.type === "thinking") {
2663
+ allThinking.push(b);
2664
+ }
2665
+ }
2666
+ }
2667
+
2668
+ // Only the active span's thinking blocks should remain
2669
+ const signatures = allThinking.map(
2670
+ (b) => (b as { signature: string }).signature,
2671
+ );
2672
+ expect(signatures).not.toContain("sig-old");
2673
+ expect(signatures).toContain("sig-step1");
2674
+ expect(signatures).toContain("sig-step2");
2675
+ });
2676
+ });
@@ -50,7 +50,7 @@ mock.module("../memory/guardian-action-store.js", () => ({
50
50
 
51
51
  mock.module("../providers/registry.js", () => ({
52
52
  getProvider: () => ({ name: "mock-provider" }),
53
- initializeProviders: () => {},
53
+ initializeProviders: async () => {},
54
54
  }));
55
55
 
56
56
  mock.module("../config/loader.js", () => ({