@vellumai/assistant 0.8.6 → 0.8.7

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 (891) hide show
  1. package/AGENTS.md +4 -4
  2. package/Dockerfile +1 -0
  3. package/bun.lock +11 -2
  4. package/docker-entrypoint.sh +8 -6
  5. package/docs/plugins.md +63 -28
  6. package/examples/plugins/echo/register.ts +4 -7
  7. package/knip.json +1 -0
  8. package/node_modules/@vellumai/environments/bun.lock +24 -0
  9. package/node_modules/@vellumai/environments/package.json +18 -0
  10. package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +95 -0
  11. package/node_modules/@vellumai/environments/src/index.ts +11 -0
  12. package/node_modules/@vellumai/environments/src/seeds.ts +73 -0
  13. package/node_modules/@vellumai/environments/src/types.ts +70 -0
  14. package/node_modules/@vellumai/environments/tsconfig.json +20 -0
  15. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +11 -0
  16. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +3 -4
  17. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +6 -2
  18. package/openapi.yaml +3735 -353
  19. package/package.json +7 -3
  20. package/scripts/generate-openapi.ts +20 -13
  21. package/src/__tests__/agent-loop-callsite-precedence.test.ts +42 -80
  22. package/src/__tests__/agent-loop-exit-reason.test.ts +240 -39
  23. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +141 -0
  24. package/src/__tests__/agent-loop-override-profile.test.ts +19 -32
  25. package/src/__tests__/agent-loop-provider-error-recording.test.ts +6 -4
  26. package/src/__tests__/agent-loop-thinking.test.ts +17 -12
  27. package/src/__tests__/agent-loop.test.ts +207 -341
  28. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +4 -2
  29. package/src/__tests__/agent-wake-override-profile.test.ts +22 -40
  30. package/src/__tests__/anthropic-provider.test.ts +201 -55
  31. package/src/__tests__/app-builder-skill-instructions.test.ts +22 -0
  32. package/src/__tests__/app-control-flow.test.ts +5 -0
  33. package/src/__tests__/approval-cascade.test.ts +4 -11
  34. package/src/__tests__/approval-routes-http.test.ts +4 -2
  35. package/src/__tests__/assistant-event.test.ts +15 -0
  36. package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
  37. package/src/__tests__/avatar-e2e.test.ts +7 -37
  38. package/src/__tests__/avatar-generator.test.ts +12 -42
  39. package/src/__tests__/avatar-identity-sync.test.ts +28 -3
  40. package/src/__tests__/background-shell-bash.test.ts +3 -7
  41. package/src/__tests__/btw-routes.test.ts +7 -12
  42. package/src/__tests__/call-pointer-messages.test.ts +5 -3
  43. package/src/__tests__/call-site-routing-provider.test.ts +22 -40
  44. package/src/__tests__/catalog-files.test.ts +1 -0
  45. package/src/__tests__/channel-approval-routes.test.ts +48 -20
  46. package/src/__tests__/channel-approvals.test.ts +3 -1
  47. package/src/__tests__/channel-invite-transport.test.ts +1 -5
  48. package/src/__tests__/channel-readiness-routes.test.ts +0 -4
  49. package/src/__tests__/channel-readiness-slack-remote.test.ts +2 -7
  50. package/src/__tests__/channel-retry-sweep.test.ts +71 -79
  51. package/src/__tests__/circuit-breaker-pipeline.test.ts +3 -3
  52. package/src/__tests__/clawhub-files.test.ts +1 -0
  53. package/src/__tests__/compaction-events.test.ts +5 -17
  54. package/src/__tests__/compaction-pipeline.test.ts +1 -1
  55. package/src/__tests__/compaction-timeout-recovery.test.ts +37 -48
  56. package/src/__tests__/compaction-trail-store.test.ts +1 -79
  57. package/src/__tests__/compactor-image-manifest-trust.test.ts +112 -0
  58. package/src/__tests__/computer-use-tools.test.ts +2 -2
  59. package/src/__tests__/config-watcher.test.ts +28 -0
  60. package/src/__tests__/context-search-agent-runner.test.ts +6 -3
  61. package/src/__tests__/context-token-estimator.test.ts +34 -0
  62. package/src/__tests__/context-window-manager-compact-retry.test.ts +291 -0
  63. package/src/__tests__/conversation-abort-tool-results.test.ts +14 -7
  64. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +3 -2
  65. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +12 -27
  66. package/src/__tests__/conversation-agent-loop-overflow.test.ts +430 -90
  67. package/src/__tests__/conversation-agent-loop.test.ts +581 -62
  68. package/src/__tests__/conversation-analysis-routes.test.ts +1 -3
  69. package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
  70. package/src/__tests__/conversation-clear-safety.test.ts +20 -10
  71. package/src/__tests__/conversation-confirmation-signals.test.ts +15 -45
  72. package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
  73. package/src/__tests__/conversation-disk-view.test.ts +10 -17
  74. package/src/__tests__/conversation-fork-crud.test.ts +86 -172
  75. package/src/__tests__/conversation-fork-route.test.ts +16 -14
  76. package/src/__tests__/conversation-init.benchmark.test.ts +6 -6
  77. package/src/__tests__/conversation-lifecycle.test.ts +3 -2
  78. package/src/__tests__/conversation-load-history-repair.test.ts +3 -2
  79. package/src/__tests__/conversation-load-history-stripped.test.ts +1 -1
  80. package/src/__tests__/conversation-message-sync-tags.test.ts +3 -4
  81. package/src/__tests__/conversation-pairing.test.ts +34 -4
  82. package/src/__tests__/conversation-pre-run-repair.test.ts +1 -1
  83. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -0
  84. package/src/__tests__/conversation-process-callsite.test.ts +27 -30
  85. package/src/__tests__/conversation-provider-retry-repair.test.ts +53 -44
  86. package/src/__tests__/conversation-queue.test.ts +270 -164
  87. package/src/__tests__/conversation-routes-disk-view.test.ts +3 -2
  88. package/src/__tests__/conversation-routes-guardian-reply.test.ts +2 -2
  89. package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -2
  90. package/src/__tests__/conversation-runtime-assembly.test.ts +20 -22
  91. package/src/__tests__/conversation-runtime-workspace.test.ts +19 -1
  92. package/src/__tests__/conversation-slash-queue.test.ts +37 -31
  93. package/src/__tests__/conversation-slash-unknown.test.ts +13 -15
  94. package/src/__tests__/conversation-speed-override.test.ts +8 -22
  95. package/src/__tests__/conversation-stream-state.test.ts +484 -0
  96. package/src/__tests__/conversation-surfaces-action-delivery.test.ts +6 -15
  97. package/src/__tests__/conversation-surfaces-app-control.test.ts +32 -4
  98. package/src/__tests__/conversation-surfaces-state-update.test.ts +5 -2
  99. package/src/__tests__/conversation-surfaces-table-action.test.ts +6 -15
  100. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +23 -11
  101. package/src/__tests__/conversation-unread-route.test.ts +14 -2
  102. package/src/__tests__/conversation-usage.test.ts +0 -2
  103. package/src/__tests__/conversation-wipe.test.ts +1 -1
  104. package/src/__tests__/conversation-workspace-cache-state.test.ts +3 -1
  105. package/src/__tests__/conversation-workspace-injection.test.ts +48 -22
  106. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +27 -7
  107. package/src/__tests__/credential-execution-tools.test.ts +1 -2
  108. package/src/__tests__/credential-security-invariants.test.ts +0 -1
  109. package/src/__tests__/cross-provider-web-search.test.ts +6 -2
  110. package/src/__tests__/cu-unified-flow.test.ts +26 -1
  111. package/src/__tests__/db-schedule-syntax-migration.test.ts +11 -0
  112. package/src/__tests__/disk-pressure-guard.test.ts +66 -0
  113. package/src/__tests__/disk-pressure-routes.test.ts +9 -2
  114. package/src/__tests__/dm-persistence.test.ts +7 -2
  115. package/src/__tests__/dynamic-page-surface.test.ts +68 -0
  116. package/src/__tests__/edit-propagation.test.ts +1 -2
  117. package/src/__tests__/empty-response-pipeline.test.ts +127 -5
  118. package/src/__tests__/filing-service.test.ts +2 -2
  119. package/src/__tests__/first-greeting.test.ts +55 -14
  120. package/src/__tests__/gemini-inline-media.test.ts +78 -0
  121. package/src/__tests__/gemini-provider.test.ts +351 -28
  122. package/src/__tests__/guardian-routing-state.test.ts +60 -71
  123. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +9 -7
  124. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  125. package/src/__tests__/heartbeat-service.test.ts +2 -1
  126. package/src/__tests__/history-repair-hook.test.ts +161 -0
  127. package/src/__tests__/history-repair-observability.test.ts +1 -1
  128. package/src/__tests__/history-repair.test.ts +2 -1
  129. package/src/__tests__/host-app-control-proxy.test.ts +2 -0
  130. package/src/__tests__/host-cu-proxy.test.ts +2 -0
  131. package/src/__tests__/host-file-edit-tool.test.ts +4 -2
  132. package/src/__tests__/host-file-proxy.test.ts +31 -0
  133. package/src/__tests__/host-file-read-tool.test.ts +4 -2
  134. package/src/__tests__/host-file-write-tool.test.ts +9 -3
  135. package/src/__tests__/host-proxy-preactivation.test.ts +53 -14
  136. package/src/__tests__/host-shell-tool.test.ts +9 -4
  137. package/src/__tests__/http-user-message-parity.test.ts +2 -2
  138. package/src/__tests__/identity-intro-cache.test.ts +35 -14
  139. package/src/__tests__/inbound-slack-persistence.test.ts +7 -2
  140. package/src/__tests__/injector-background-turn.test.ts +1 -1
  141. package/src/__tests__/injector-chain.test.ts +1 -1
  142. package/src/__tests__/injector-disk-pressure.test.ts +1 -1
  143. package/src/__tests__/injector-document-comments.test.ts +1 -1
  144. package/src/__tests__/injector-pkb-v2-silenced.test.ts +1 -1
  145. package/src/__tests__/injector-v3-suppression.test.ts +220 -0
  146. package/src/__tests__/list-messages-attachments.test.ts +7 -8
  147. package/src/__tests__/list-messages-hidden-metadata.test.ts +17 -15
  148. package/src/__tests__/list-messages-page-latest.test.ts +0 -1
  149. package/src/__tests__/list-messages-tool-merge.test.ts +36 -6
  150. package/src/__tests__/llm-call-pipeline.test.ts +21 -15
  151. package/src/__tests__/llm-request-log-turn-query.test.ts +42 -86
  152. package/src/__tests__/llm-resolver.test.ts +23 -47
  153. package/src/__tests__/llm-usage-store.test.ts +45 -0
  154. package/src/__tests__/log-export-routes.test.ts +59 -0
  155. package/src/__tests__/managed-skill-lifecycle.test.ts +1 -8
  156. package/src/__tests__/mcp-auth-routes.test.ts +15 -10
  157. package/src/__tests__/mcp-health-check.test.ts +18 -13
  158. package/src/__tests__/memory-retrieval-pipeline.test.ts +1 -1
  159. package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
  160. package/src/__tests__/messaging-send-tool.test.ts +8 -4
  161. package/src/__tests__/migration-export-http.test.ts +12 -12
  162. package/src/__tests__/migration-import-commit-http.test.ts +8 -8
  163. package/src/__tests__/migration-import-preflight-http.test.ts +7 -7
  164. package/src/__tests__/migration-validate-http.test.ts +3 -3
  165. package/src/__tests__/native-web-search.test.ts +14 -20
  166. package/src/__tests__/notification-decision-identity.test.ts +9 -18
  167. package/src/__tests__/notification-decision-recipient-context.test.ts +3 -6
  168. package/src/__tests__/oauth-commands-routes.test.ts +1 -1
  169. package/src/__tests__/onboarding-template-contract.test.ts +10 -0
  170. package/src/__tests__/openai-provider.test.ts +66 -70
  171. package/src/__tests__/openai-responses-provider.test.ts +21 -77
  172. package/src/__tests__/outbound-slack-persistence.test.ts +2 -1
  173. package/src/__tests__/overflow-reduce-pipeline.test.ts +2 -4
  174. package/src/__tests__/parallel-tool.benchmark.test.ts +24 -36
  175. package/src/__tests__/persistence-pipeline.test.ts +15 -26
  176. package/src/__tests__/persistence-secret-redaction.test.ts +2 -1
  177. package/src/__tests__/pipeline-runner.test.ts +2 -3
  178. package/src/__tests__/plugin-bootstrap.test.ts +51 -25
  179. package/src/__tests__/plugin-route-contribution.test.ts +6 -16
  180. package/src/__tests__/plugin-skill-contribution.test.ts +7 -17
  181. package/src/__tests__/plugin-tool-contribution.test.ts +10 -26
  182. package/src/__tests__/plugin-types.test.ts +7 -14
  183. package/src/__tests__/prechat-onboarding-contract.test.ts +23 -0
  184. package/src/__tests__/process-message-background-slack.test.ts +17 -16
  185. package/src/__tests__/process-message-display-content.test.ts +30 -42
  186. package/src/__tests__/provider-commit-message-generator.test.ts +19 -14
  187. package/src/__tests__/provider-error-scenarios.test.ts +7 -6
  188. package/src/__tests__/provider-platform-proxy-integration.test.ts +3 -8
  189. package/src/__tests__/provider-send-message-override-profile.test.ts +9 -25
  190. package/src/__tests__/provider-streaming.benchmark.test.ts +12 -22
  191. package/src/__tests__/provider-usage-tracking.test.ts +0 -6
  192. package/src/__tests__/ratelimit.test.ts +9 -4
  193. package/src/__tests__/relay-server.test.ts +20 -13
  194. package/src/__tests__/retry-openrouter-only-normalization.test.ts +5 -8
  195. package/src/__tests__/retry-thinking-tool-choice.test.ts +10 -13
  196. package/src/__tests__/retry-verbosity-normalization.test.ts +5 -8
  197. package/src/__tests__/runtime-events-sse-reconnect.test.ts +353 -0
  198. package/src/__tests__/schedule-routes.test.ts +80 -10
  199. package/src/__tests__/schedule-store.test.ts +67 -0
  200. package/src/__tests__/schedule-tools.test.ts +125 -0
  201. package/src/__tests__/secret-ingress-http.test.ts +2 -2
  202. package/src/__tests__/secret-prompt-log-hygiene.test.ts +11 -7
  203. package/src/__tests__/secret-prompter-channel-fallback.test.ts +11 -9
  204. package/src/__tests__/secret-response-routing.test.ts +13 -11
  205. package/src/__tests__/send-endpoint-busy.test.ts +2 -1
  206. package/src/__tests__/shell-observability.test.ts +249 -0
  207. package/src/__tests__/skill-feature-flags-integration.test.ts +11 -11
  208. package/src/__tests__/skill-feature-flags.test.ts +6 -6
  209. package/src/__tests__/skill-load-feature-flag.test.ts +10 -10
  210. package/src/__tests__/skills-files-catalog-fallback.test.ts +10 -0
  211. package/src/__tests__/skillssh-files.test.ts +1 -0
  212. package/src/__tests__/starter-task-flow.test.ts +6 -6
  213. package/src/__tests__/strip-memory-injections.test.ts +102 -14
  214. package/src/__tests__/subagent-call-site-routing.test.ts +2 -2
  215. package/src/__tests__/suggestion-routes.test.ts +3 -3
  216. package/src/__tests__/sync-message-contract.test.ts +19 -16
  217. package/src/__tests__/system-prompt.test.ts +54 -0
  218. package/src/__tests__/terminal-tools.test.ts +3 -24
  219. package/src/__tests__/thread-backfill.test.ts +4 -9
  220. package/src/__tests__/title-generate-pipeline.test.ts +1 -1
  221. package/src/__tests__/token-estimate-pipeline.test.ts +2 -4
  222. package/src/__tests__/tool-error-pipeline.test.ts +2 -2
  223. package/src/__tests__/tool-execute-pipeline.test.ts +1 -1
  224. package/src/__tests__/tool-preview-lifecycle.test.ts +13 -11
  225. package/src/__tests__/tool-result-truncate-pipeline.test.ts +9 -12
  226. package/src/__tests__/tool-result-truncation.test.ts +3 -1
  227. package/src/__tests__/tools-audio-read.test.ts +113 -0
  228. package/src/__tests__/turn-boundary-resolution.test.ts +44 -84
  229. package/src/__tests__/turn-events-store.test.ts +11 -7
  230. package/src/__tests__/voice-scoped-grant-consumer.test.ts +8 -6
  231. package/src/__tests__/voice-session-bridge.test.ts +13 -7
  232. package/src/acp/__tests__/prepare-agent-env.test.ts +143 -31
  233. package/src/acp/prepare-agent-env.ts +52 -11
  234. package/src/agent/compaction-circuit.ts +140 -0
  235. package/src/agent/loop.ts +409 -85
  236. package/src/api/README.md +19 -17
  237. package/src/api/constants/tool-execution.ts +21 -0
  238. package/src/api/events/assistant-activity-state.ts +75 -0
  239. package/src/api/events/assistant-outbound-attachment.ts +25 -27
  240. package/src/api/events/assistant-text-delta.ts +6 -8
  241. package/src/api/events/assistant-turn-start.ts +5 -7
  242. package/src/api/events/avatar-updated.ts +24 -0
  243. package/src/api/events/compaction-circuit-closed.ts +26 -0
  244. package/src/api/events/compaction-circuit-open.ts +28 -0
  245. package/src/api/events/confirmation-request.ts +114 -0
  246. package/src/api/events/contact-request.ts +33 -0
  247. package/src/api/events/conversation-error.ts +77 -0
  248. package/src/api/events/conversation-list-invalidated.ts +38 -0
  249. package/src/api/events/conversation-title-updated.ts +24 -0
  250. package/src/api/events/disk-pressure-status-changed.ts +61 -0
  251. package/src/api/events/document-comment-created.ts +24 -28
  252. package/src/api/events/document-comment-deleted.ts +6 -8
  253. package/src/api/events/document-comment-reopened.ts +6 -8
  254. package/src/api/events/document-comment-resolved.ts +8 -10
  255. package/src/api/events/document-editor-update.ts +27 -0
  256. package/src/api/events/error.ts +32 -0
  257. package/src/api/events/generation-cancelled.ts +4 -6
  258. package/src/api/events/generation-handoff.ts +13 -15
  259. package/src/api/events/home-feed-updated.ts +26 -0
  260. package/src/api/events/identity-changed.ts +32 -0
  261. package/src/api/events/interaction-resolved.ts +50 -0
  262. package/src/api/events/message-complete.ts +10 -12
  263. package/src/api/events/message-dequeued.ts +21 -0
  264. package/src/api/events/message-queued-deleted.ts +23 -0
  265. package/src/api/events/message-queued.ts +22 -0
  266. package/src/api/events/message-request-complete.ts +29 -0
  267. package/src/api/events/navigate-settings.ts +20 -0
  268. package/src/api/events/notification-intent.ts +33 -0
  269. package/src/api/events/open-url.ts +6 -8
  270. package/src/api/events/question-request.ts +67 -0
  271. package/src/api/events/relationship-state-updated.ts +4 -6
  272. package/src/api/events/secret-request.ts +42 -0
  273. package/src/api/events/subagent-event.ts +79 -0
  274. package/src/api/events/subagent-spawned.ts +40 -0
  275. package/src/api/events/subagent-status-changed.ts +65 -0
  276. package/src/api/events/sync-changed.ts +29 -0
  277. package/src/api/events/tool-result.ts +129 -0
  278. package/src/api/events/tool-use-start.ts +8 -10
  279. package/src/api/events/turn-profile-auto-routed.ts +28 -0
  280. package/src/api/events/ui-surface-complete.ts +30 -0
  281. package/src/api/events/ui-surface-dismiss.ts +22 -0
  282. package/src/api/events/ui-surface-show.ts +67 -0
  283. package/src/api/events/ui-surface-update.ts +26 -0
  284. package/src/api/events/usage-update.ts +34 -0
  285. package/src/api/events/user-message-echo.ts +35 -0
  286. package/src/api/index.ts +354 -0
  287. package/src/api/requests/dictation.ts +45 -0
  288. package/src/api/responses/disk-pressure-status.ts +26 -0
  289. package/src/api/responses/home.ts +217 -0
  290. package/src/api/responses/llm-context-response.ts +2 -0
  291. package/src/api/responses/memory-v3-selection-log.ts +50 -0
  292. package/src/api/responses/subagent-detail.ts +48 -0
  293. package/src/approvals/guardian-decision-primitive.ts +7 -15
  294. package/src/approvals/guardian-request-resolvers.ts +6 -9
  295. package/src/avatar/__tests__/avatar-manifest.test.ts +236 -0
  296. package/src/avatar/__tests__/avatar-store.test.ts +193 -0
  297. package/src/avatar/avatar-manifest.ts +195 -0
  298. package/src/avatar/avatar-store.ts +113 -0
  299. package/src/avatar/traits-png-sync.ts +8 -2
  300. package/src/background-wake/next-wake.test.ts +31 -1
  301. package/src/background-wake/next-wake.ts +4 -1
  302. package/src/calls/call-conversation-messages.ts +6 -4
  303. package/src/calls/guardian-action-sweep.ts +6 -4
  304. package/src/calls/relay-server.ts +12 -8
  305. package/src/calls/voice-session-bridge.ts +13 -27
  306. package/src/cli/commands/__tests__/memory-v3.test.ts +245 -0
  307. package/src/cli/commands/avatar.ts +17 -11
  308. package/src/cli/commands/conversations.ts +15 -1
  309. package/src/cli/commands/db/__tests__/repair.test.ts +540 -0
  310. package/src/cli/commands/db/__tests__/status.test.ts +253 -0
  311. package/src/cli/commands/db/format.ts +48 -0
  312. package/src/cli/commands/db/index.ts +29 -0
  313. package/src/cli/commands/db/repair-step-conversation-backfill.ts +345 -0
  314. package/src/cli/commands/db/repair-step-integrity.ts +146 -0
  315. package/src/cli/commands/db/repair-steps.ts +164 -0
  316. package/src/cli/commands/db/repair.ts +141 -0
  317. package/src/cli/commands/db/status.ts +366 -0
  318. package/src/cli/commands/memory-v3.ts +159 -445
  319. package/src/cli/lib/cli-colors.ts +24 -6
  320. package/src/cli/program.ts +4 -5
  321. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  322. package/src/config/assistant-feature-flags.ts +2 -2
  323. package/src/config/bundled-skills/app-builder/SKILL.md +14 -3
  324. package/src/config/bundled-skills/media-processing/services/reduce.ts +6 -9
  325. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +7 -2
  326. package/src/config/bundled-skills/schedule/SKILL.md +1 -1
  327. package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
  328. package/src/config/call-site-defaults.ts +2 -7
  329. package/src/config/feature-flag-registry.json +25 -9
  330. package/src/config/schemas/__tests__/memory-v2.test.ts +1 -226
  331. package/src/config/schemas/call-site-catalog.ts +8 -15
  332. package/src/config/schemas/llm.ts +2 -3
  333. package/src/config/schemas/memory-lifecycle.ts +24 -0
  334. package/src/config/schemas/memory-v2.ts +0 -253
  335. package/src/config/schemas/memory-v3.ts +39 -0
  336. package/src/config/schemas/memory.ts +6 -1
  337. package/src/config/schemas/timeouts.ts +3 -1
  338. package/src/context/compactor.ts +54 -31
  339. package/src/context/token-estimator.ts +19 -0
  340. package/src/context/tool-result-truncation.ts +1 -43
  341. package/src/context/window-manager.ts +138 -20
  342. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +2 -2
  343. package/src/daemon/__tests__/web-search-status-text.test.ts +10 -6
  344. package/src/daemon/approval-generators.ts +4 -4
  345. package/src/daemon/config-watcher.ts +7 -1
  346. package/src/daemon/conversation-agent-loop-handlers.ts +225 -88
  347. package/src/daemon/conversation-agent-loop.ts +284 -584
  348. package/src/daemon/conversation-error.ts +7 -7
  349. package/src/daemon/conversation-history.ts +22 -6
  350. package/src/daemon/conversation-launch.ts +4 -8
  351. package/src/daemon/conversation-lifecycle.ts +10 -38
  352. package/src/daemon/conversation-messaging.ts +1 -3
  353. package/src/daemon/conversation-notifiers.ts +7 -5
  354. package/src/daemon/conversation-process.ts +100 -79
  355. package/src/daemon/conversation-runtime-assembly.ts +47 -21
  356. package/src/daemon/conversation-store.ts +6 -5
  357. package/src/daemon/conversation-surfaces.ts +55 -69
  358. package/src/daemon/conversation-tool-setup.ts +3 -0
  359. package/src/daemon/conversation.ts +91 -126
  360. package/src/daemon/daemon-skill-host.ts +2 -6
  361. package/src/daemon/disk-pressure-guard.ts +35 -29
  362. package/src/daemon/external-plugins-bootstrap.ts +46 -24
  363. package/src/daemon/first-greeting.ts +26 -4
  364. package/src/daemon/guardian-action-generators.ts +2 -2
  365. package/src/daemon/handlers/conversations.ts +6 -22
  366. package/src/daemon/handlers/shared.ts +4 -0
  367. package/src/daemon/handlers/skills.ts +15 -14
  368. package/src/daemon/host-app-control-proxy.ts +54 -1
  369. package/src/daemon/host-cu-proxy.ts +46 -22
  370. package/src/daemon/host-file-proxy.ts +25 -1
  371. package/src/daemon/host-proxy-preactivation.ts +25 -6
  372. package/src/daemon/lifecycle.ts +28 -55
  373. package/src/daemon/message-protocol.ts +2 -3
  374. package/src/daemon/message-provenance.ts +49 -0
  375. package/src/daemon/message-types/contacts.ts +3 -20
  376. package/src/daemon/message-types/conversations.ts +13 -111
  377. package/src/daemon/message-types/documents.ts +3 -9
  378. package/src/daemon/message-types/home.ts +4 -17
  379. package/src/daemon/message-types/integrations.ts +2 -6
  380. package/src/daemon/message-types/messages.ts +28 -343
  381. package/src/daemon/message-types/notifications.ts +2 -32
  382. package/src/daemon/message-types/settings.ts +3 -8
  383. package/src/daemon/message-types/skills.ts +2 -0
  384. package/src/daemon/message-types/surfaces.ts +2 -0
  385. package/src/daemon/message-types/sync.ts +12 -25
  386. package/src/daemon/message-types/workspace.ts +3 -11
  387. package/src/daemon/process-message.ts +49 -46
  388. package/src/daemon/server.ts +12 -0
  389. package/src/daemon/tool-side-effects.ts +10 -7
  390. package/src/daemon/trust-context.ts +13 -0
  391. package/src/daemon/wake-target-adapter.ts +11 -1
  392. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -1
  393. package/src/heartbeat/heartbeat-run-store.ts +31 -0
  394. package/src/heartbeat/heartbeat-service.ts +16 -0
  395. package/src/home/feature-gate.ts +22 -0
  396. package/src/home/feed-types.ts +36 -221
  397. package/src/ipc/__tests__/email-ipc.test.ts +0 -9
  398. package/src/ipc/routes/__tests__/route-adapter.test.ts +244 -0
  399. package/src/ipc/routes/route-adapter.ts +45 -6
  400. package/src/ipc/skill-routes/__tests__/memory.test.ts +18 -9
  401. package/src/ipc/skill-routes/__tests__/providers.test.ts +10 -10
  402. package/src/ipc/skill-routes/__tests__/registries.test.ts +28 -18
  403. package/src/ipc/skill-routes/memory.ts +26 -13
  404. package/src/ipc/skill-routes/providers.ts +5 -6
  405. package/src/ipc/skill-routes/registries.ts +13 -61
  406. package/src/live-voice/__tests__/live-voice-archive.test.ts +24 -11
  407. package/src/memory/__tests__/conversation-queries.test.ts +192 -8
  408. package/src/memory/__tests__/db-maintenance.test.ts +128 -0
  409. package/src/memory/__tests__/jobs-store-job-classes.test.ts +5 -4
  410. package/src/memory/__tests__/memory-retrospective-job.test.ts +10 -6
  411. package/src/memory/__tests__/memory-v3-selections-migration.test.ts +103 -0
  412. package/src/memory/context-search/agent-runner.ts +2 -4
  413. package/src/memory/conversation-crud.ts +39 -8
  414. package/src/memory/conversation-queries.ts +78 -22
  415. package/src/memory/db-init.ts +8 -0
  416. package/src/memory/db-maintenance.ts +18 -2
  417. package/src/memory/graph/consolidation.ts +8 -11
  418. package/src/memory/graph/conversation-graph-memory.ts +41 -8
  419. package/src/memory/graph/extraction.ts +6 -9
  420. package/src/memory/graph/narrative.ts +2 -2
  421. package/src/memory/graph/pattern-scan.ts +2 -2
  422. package/src/memory/graph/retriever.ts +20 -26
  423. package/src/memory/graph/tools.ts +4 -4
  424. package/src/memory/job-handlers/conversation-starters.ts +32 -32
  425. package/src/memory/job-handlers/summarization.ts +1 -2
  426. package/src/memory/jobs-store.ts +3 -1
  427. package/src/memory/jobs-worker.ts +51 -39
  428. package/src/memory/llm-request-log-source-clickhouse.ts +5 -31
  429. package/src/memory/llm-request-log-source-local.ts +0 -11
  430. package/src/memory/llm-request-log-source.ts +9 -25
  431. package/src/memory/llm-request-log-store.ts +0 -41
  432. package/src/memory/llm-usage-store.ts +10 -0
  433. package/src/memory/memory-marker.ts +17 -0
  434. package/src/memory/memory-retrospective-job.ts +6 -2
  435. package/src/memory/memory-v2-activation-log-store.ts +1 -83
  436. package/src/memory/migrations/267-llm-usage-events-add-assistant-version.ts +46 -0
  437. package/src/memory/migrations/268-add-memory-v3-selections.ts +28 -0
  438. package/src/memory/migrations/269-schedule-script-timeout.ts +11 -0
  439. package/src/memory/migrations/270-messages-role-created-at-index.ts +18 -0
  440. package/src/memory/migrations/__tests__/267-llm-usage-events-add-assistant-version.test.ts +117 -0
  441. package/src/memory/migrations/index.ts +4 -0
  442. package/src/memory/schema/infrastructure.ts +11 -0
  443. package/src/memory/v2/__tests__/consolidation-job.test.ts +124 -0
  444. package/src/memory/v2/__tests__/migration.test.ts +11 -3
  445. package/src/memory/v2/__tests__/page-index.test.ts +37 -1
  446. package/src/memory/v2/__tests__/router.test.ts +14 -4
  447. package/src/memory/v2/__tests__/sweep-job.test.ts +6 -5
  448. package/src/memory/v2/backfill-jobs.ts +6 -0
  449. package/src/memory/v2/consolidation-job.ts +89 -9
  450. package/src/memory/v2/migration.ts +5 -3
  451. package/src/memory/v2/page-index.ts +11 -0
  452. package/src/memory/v2/router.ts +8 -11
  453. package/src/memory/v2/sweep-job.ts +8 -11
  454. package/src/memory/v2/types.ts +1 -0
  455. package/src/memory/v3/__tests__/assign.test.ts +242 -0
  456. package/src/memory/v3/__tests__/capabilities.test.ts +118 -0
  457. package/src/memory/v3/__tests__/core.test.ts +39 -0
  458. package/src/memory/v3/__tests__/fixtures/eval-turns.json +36 -0
  459. package/src/memory/v3/__tests__/fixtures/live-turns.json +37 -0
  460. package/src/memory/v3/__tests__/health.test.ts +203 -0
  461. package/src/memory/v3/__tests__/live-integration.test.ts +330 -0
  462. package/src/memory/v3/__tests__/maintain-job.test.ts +288 -0
  463. package/src/memory/v3/__tests__/needle.test.ts +107 -0
  464. package/src/memory/v3/__tests__/orchestrate.test.ts +400 -0
  465. package/src/memory/v3/__tests__/reconcile.test.ts +274 -0
  466. package/src/memory/v3/__tests__/render-injection.test.ts +61 -0
  467. package/src/memory/v3/__tests__/router.test.ts +260 -0
  468. package/src/memory/v3/__tests__/selection-log-store.test.ts +179 -0
  469. package/src/memory/v3/__tests__/selector.test.ts +404 -0
  470. package/src/memory/v3/__tests__/shadow-plugin.test.ts +414 -0
  471. package/src/memory/v3/__tests__/snapshot.test.ts +168 -0
  472. package/src/memory/v3/__tests__/tree.test.ts +192 -0
  473. package/src/memory/v3/__tests__/types.test.ts +54 -0
  474. package/src/memory/v3/__tests__/working-set-eviction.test.ts +106 -0
  475. package/src/memory/v3/__tests__/working-set-skeleton.test.ts +44 -0
  476. package/src/memory/v3/assign.ts +268 -0
  477. package/src/memory/v3/capabilities.ts +124 -0
  478. package/src/memory/v3/core.ts +26 -0
  479. package/src/memory/v3/data/README.md +84 -0
  480. package/src/memory/v3/data/assignments.json +5 -0
  481. package/src/memory/v3/data/core.json +1 -0
  482. package/src/memory/v3/data/leaves/domain-a/topic-x.md +9 -0
  483. package/src/memory/v3/data/leaves/domain-a/topic-y.md +9 -0
  484. package/src/memory/v3/data/leaves/domain-b/topic-z.md +9 -0
  485. package/src/memory/v3/health.ts +0 -0
  486. package/src/memory/v3/maintain-job.ts +314 -0
  487. package/src/memory/v3/needle.ts +115 -0
  488. package/src/memory/v3/orchestrate.ts +114 -0
  489. package/src/memory/v3/page-content.ts +34 -0
  490. package/src/memory/v3/provider-blocks.ts +16 -0
  491. package/src/memory/v3/reconcile.ts +523 -0
  492. package/src/memory/v3/render-injection.ts +32 -0
  493. package/src/memory/v3/router.ts +184 -0
  494. package/src/memory/v3/selection-log-store.ts +84 -0
  495. package/src/memory/v3/selector.ts +211 -0
  496. package/src/memory/v3/shadow-plugin.ts +379 -0
  497. package/src/memory/v3/snapshot.ts +209 -0
  498. package/src/memory/v3/tree.ts +174 -0
  499. package/src/memory/v3/types.ts +46 -60
  500. package/src/memory/v3/working-set.ts +88 -0
  501. package/src/messaging/providers/slack/render-transcript.test.ts +1 -1
  502. package/src/messaging/providers/slack/render-transcript.ts +2 -2
  503. package/src/messaging/style-analyzer.ts +8 -11
  504. package/src/notifications/conversation-pairing.ts +8 -6
  505. package/src/notifications/decision-engine.ts +10 -13
  506. package/src/notifications/preference-extractor.ts +11 -14
  507. package/src/permissions/prompter.ts +42 -36
  508. package/src/permissions/question-prompter.test.ts +35 -26
  509. package/src/permissions/question-prompter.ts +6 -10
  510. package/src/plugin-api/index.ts +2 -0
  511. package/src/plugin-api/types.ts +25 -3
  512. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +93 -0
  513. package/src/plugins/defaults/circuit-breaker/package.json +15 -0
  514. package/src/plugins/defaults/circuit-breaker/register.ts +39 -0
  515. package/src/plugins/defaults/compaction/middlewares/compaction.ts +25 -0
  516. package/src/plugins/defaults/compaction/package.json +15 -0
  517. package/src/plugins/defaults/compaction/register.ts +35 -0
  518. package/src/plugins/defaults/compaction/terminal.ts +73 -0
  519. package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +22 -0
  520. package/src/plugins/defaults/empty-response/package.json +15 -0
  521. package/src/plugins/defaults/empty-response/register.ts +28 -0
  522. package/src/plugins/defaults/empty-response/terminal.ts +106 -0
  523. package/src/plugins/defaults/history-repair/hooks/user-prompt-submit.ts +35 -0
  524. package/src/plugins/defaults/history-repair/package.json +15 -0
  525. package/src/plugins/defaults/history-repair/register.ts +24 -0
  526. package/src/{daemon/history-repair.ts → plugins/defaults/history-repair/terminal.ts} +48 -35
  527. package/src/plugins/defaults/index.ts +29 -40
  528. package/src/plugins/defaults/injectors/package.json +15 -0
  529. package/src/plugins/defaults/{injectors.ts → injectors/register.ts} +14 -38
  530. package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +17 -0
  531. package/src/plugins/defaults/llm-call/package.json +15 -0
  532. package/src/plugins/defaults/{llm-call.ts → llm-call/register.ts} +6 -38
  533. package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +17 -0
  534. package/src/plugins/defaults/memory-retrieval/package.json +15 -0
  535. package/src/plugins/defaults/{memory-retrieval.ts → memory-retrieval/register.ts} +10 -48
  536. package/src/plugins/defaults/{overflow-reduce.ts → overflow-reduce/middlewares/overflowReduce.ts} +18 -77
  537. package/src/plugins/defaults/overflow-reduce/package.json +15 -0
  538. package/src/plugins/defaults/overflow-reduce/register.ts +42 -0
  539. package/src/plugins/defaults/persistence/middlewares/persistence.ts +19 -0
  540. package/src/plugins/defaults/persistence/package.json +15 -0
  541. package/src/plugins/defaults/persistence/register.ts +38 -0
  542. package/src/plugins/defaults/persistence/terminal.ts +83 -0
  543. package/src/plugins/defaults/title-generate/package.json +15 -0
  544. package/src/plugins/defaults/title-generate/register.ts +35 -0
  545. package/src/plugins/defaults/title-generate/terminal.ts +31 -0
  546. package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +23 -0
  547. package/src/plugins/defaults/token-estimate/package.json +15 -0
  548. package/src/plugins/defaults/token-estimate/register.ts +34 -0
  549. package/src/plugins/defaults/token-estimate/terminal.ts +40 -0
  550. package/src/plugins/defaults/tool-error/middlewares/toolError.ts +21 -0
  551. package/src/plugins/defaults/tool-error/package.json +15 -0
  552. package/src/plugins/defaults/tool-error/register.ts +35 -0
  553. package/src/plugins/defaults/tool-error/terminal.ts +47 -0
  554. package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +23 -0
  555. package/src/plugins/defaults/tool-execute/package.json +15 -0
  556. package/src/plugins/defaults/{tool-execute.ts → tool-execute/register.ts} +8 -46
  557. package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +23 -0
  558. package/src/plugins/defaults/tool-result-truncate/package.json +15 -0
  559. package/src/plugins/defaults/tool-result-truncate/register.ts +35 -0
  560. package/src/plugins/defaults/tool-result-truncate/terminal.ts +113 -0
  561. package/src/plugins/defaults/tool-result-truncate/types.ts +22 -0
  562. package/src/plugins/external-plugin-loader.ts +2 -2
  563. package/src/plugins/pipeline.ts +0 -12
  564. package/src/plugins/types.ts +51 -90
  565. package/src/plugins/user-loader.ts +4 -3
  566. package/src/proactive-artifact/aux-message-injector.ts +0 -1
  567. package/src/proactive-artifact/job.test.ts +20 -8
  568. package/src/proactive-artifact/job.ts +3 -1
  569. package/src/prompts/sections.ts +20 -7
  570. package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +2 -2
  571. package/src/prompts/templates/BOOTSTRAP.md +5 -1
  572. package/src/prompts/templates/system-sections.ts +6 -0
  573. package/src/providers/__tests__/retry-callsite.test.ts +25 -25
  574. package/src/providers/__tests__/satellite-connection-routing.test.ts +7 -21
  575. package/src/providers/anthropic/client.ts +24 -5
  576. package/src/providers/call-site-routing.ts +1 -9
  577. package/src/providers/gemini/client.ts +152 -34
  578. package/src/providers/gemini/inline-media.ts +74 -0
  579. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +0 -2
  580. package/src/providers/openai/chat-completions-provider.ts +1 -4
  581. package/src/providers/openai/responses-provider.ts +1 -4
  582. package/src/providers/openrouter/client.ts +1 -6
  583. package/src/providers/provider-send-message.ts +6 -6
  584. package/src/providers/ratelimit.ts +1 -9
  585. package/src/providers/retry.ts +0 -5
  586. package/src/providers/types.ts +11 -2
  587. package/src/providers/usage-tracking.ts +1 -9
  588. package/src/runtime/__tests__/agent-wake.test.ts +131 -26
  589. package/src/runtime/__tests__/background-job-runner.test.ts +1 -3
  590. package/src/runtime/agent-wake.ts +93 -18
  591. package/src/runtime/assistant-event-hub.ts +2 -2
  592. package/src/runtime/auth/__tests__/guard-tests.test.ts +75 -109
  593. package/src/runtime/auth/__tests__/route-policy.test.ts +153 -170
  594. package/src/runtime/auth/route-policy.ts +42 -1079
  595. package/src/runtime/background-job-runner.ts +1 -4
  596. package/src/runtime/btw-sidechain.ts +3 -1
  597. package/src/runtime/channel-approvals.ts +3 -14
  598. package/src/runtime/channel-invite-transport.ts +5 -6
  599. package/src/runtime/channel-readiness-service.ts +2 -5
  600. package/src/runtime/channel-retry-sweep.ts +12 -16
  601. package/src/runtime/conversation-stream-state.ts +294 -0
  602. package/src/runtime/http-router.ts +19 -22
  603. package/src/runtime/http-types.ts +12 -6
  604. package/src/runtime/invite-instruction-generator.ts +3 -3
  605. package/src/runtime/pending-interactions.ts +2 -2
  606. package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +565 -0
  607. package/src/runtime/routes/__tests__/content-source-routes.test.ts +4 -4
  608. package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +62 -32
  609. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +237 -0
  610. package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -22
  611. package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +7 -2
  612. package/src/runtime/routes/__tests__/sanity-routes.test.ts +6 -6
  613. package/src/runtime/routes/__tests__/stt-routes.test.ts +3 -3
  614. package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +5 -2
  615. package/src/runtime/routes/__tests__/tts-routes.test.ts +3 -3
  616. package/src/runtime/routes/acp-routes.test.ts +97 -75
  617. package/src/runtime/routes/acp-routes.ts +29 -6
  618. package/src/runtime/routes/app-management-routes.ts +97 -24
  619. package/src/runtime/routes/app-routes.ts +25 -5
  620. package/src/runtime/routes/approval-routes.ts +16 -4
  621. package/src/runtime/routes/attachment-routes.ts +25 -1
  622. package/src/runtime/routes/audio-routes.ts +1 -0
  623. package/src/runtime/routes/audit-routes.ts +5 -0
  624. package/src/runtime/routes/auth-routes.ts +5 -0
  625. package/src/runtime/routes/avatar-routes.ts +238 -59
  626. package/src/runtime/routes/background-tool-routes.ts +9 -0
  627. package/src/runtime/routes/background-wake-routes.ts +13 -3
  628. package/src/runtime/routes/backup-routes.ts +45 -0
  629. package/src/runtime/routes/bookmark-routes.ts +13 -0
  630. package/src/runtime/routes/brain-graph-routes.ts +9 -0
  631. package/src/runtime/routes/browser-routes.ts +5 -0
  632. package/src/runtime/routes/browser-tabs-routes.ts +5 -0
  633. package/src/runtime/routes/btw-routes.ts +5 -1
  634. package/src/runtime/routes/cache-routes.ts +13 -0
  635. package/src/runtime/routes/call-routes.ts +21 -10
  636. package/src/runtime/routes/channel-availability-routes.ts +5 -1
  637. package/src/runtime/routes/channel-readiness-routes.ts +37 -4
  638. package/src/runtime/routes/channel-route-definitions.ts +21 -0
  639. package/src/runtime/routes/channel-verification-routes.ts +21 -0
  640. package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +9 -2
  641. package/src/runtime/routes/client-routes.ts +9 -0
  642. package/src/runtime/routes/consolidation-routes.ts +13 -5
  643. package/src/runtime/routes/contact-prompt-routes.ts +9 -0
  644. package/src/runtime/routes/contact-routes.ts +90 -23
  645. package/src/runtime/routes/content-source-routes.ts +5 -1
  646. package/src/runtime/routes/conversation-analysis-routes.ts +5 -1
  647. package/src/runtime/routes/conversation-attention-routes.ts +5 -0
  648. package/src/runtime/routes/conversation-cli-routes.ts +54 -7
  649. package/src/runtime/routes/conversation-compaction-routes.ts +54 -25
  650. package/src/runtime/routes/conversation-list-routes.ts +81 -12
  651. package/src/runtime/routes/conversation-management-routes.ts +57 -14
  652. package/src/runtime/routes/conversation-query-routes.ts +88 -41
  653. package/src/runtime/routes/conversation-routes.ts +74 -19
  654. package/src/runtime/routes/conversation-starter-routes.ts +22 -13
  655. package/src/runtime/routes/conversations-import-routes.ts +6 -1
  656. package/src/runtime/routes/credential-prompt-routes.ts +5 -0
  657. package/src/runtime/routes/credential-routes.ts +25 -6
  658. package/src/runtime/routes/debug-bash-routes.ts +5 -0
  659. package/src/runtime/routes/debug-routes.ts +11 -2
  660. package/src/runtime/routes/defer-routes.ts +13 -0
  661. package/src/runtime/routes/diagnostics-routes.ts +37 -46
  662. package/src/runtime/routes/disk-pressure-routes.ts +17 -31
  663. package/src/runtime/routes/document-comments-routes.ts +46 -27
  664. package/src/runtime/routes/documents-routes.ts +21 -10
  665. package/src/runtime/routes/domain-routes.ts +61 -28
  666. package/src/runtime/routes/email-routes.ts +33 -0
  667. package/src/runtime/routes/events-routes.ts +114 -9
  668. package/src/runtime/routes/filing-routes.ts +9 -4
  669. package/src/runtime/routes/gateway-log-routes.ts +5 -0
  670. package/src/runtime/routes/global-search-routes.ts +53 -50
  671. package/src/runtime/routes/group-routes.ts +21 -5
  672. package/src/runtime/routes/guardian-action-routes.ts +9 -0
  673. package/src/runtime/routes/guardian-approval-interception.ts +0 -31
  674. package/src/runtime/routes/heartbeat-routes.ts +25 -9
  675. package/src/runtime/routes/home-feed-routes.ts +23 -19
  676. package/src/runtime/routes/home-state-routes.ts +8 -40
  677. package/src/runtime/routes/host-app-control-routes.ts +5 -0
  678. package/src/runtime/routes/host-bash-routes.ts +5 -0
  679. package/src/runtime/routes/host-browser-routes.ts +13 -0
  680. package/src/runtime/routes/host-cu-routes.ts +5 -0
  681. package/src/runtime/routes/host-file-routes.ts +26 -6
  682. package/src/runtime/routes/host-transfer-routes.ts +13 -2
  683. package/src/runtime/routes/http-adapter.ts +1 -2
  684. package/src/runtime/routes/identity-intro-cache.ts +17 -6
  685. package/src/runtime/routes/identity-routes.ts +12 -2
  686. package/src/runtime/routes/image-generation-routes.ts +5 -0
  687. package/src/runtime/routes/inbound-message-handler.ts +15 -11
  688. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +0 -12
  689. package/src/runtime/routes/inbound-stages/background-dispatch.ts +15 -19
  690. package/src/runtime/routes/inference-profile-session-routes.ts +13 -3
  691. package/src/runtime/routes/inference-provider-connection-routes.ts +21 -5
  692. package/src/runtime/routes/inference-send-routes.ts +11 -11
  693. package/src/runtime/routes/integrations/a2a.ts +30 -7
  694. package/src/runtime/routes/integrations/slack/channel.ts +19 -3
  695. package/src/runtime/routes/integrations/slack/share.ts +9 -2
  696. package/src/runtime/routes/integrations/telegram.ts +28 -9
  697. package/src/runtime/routes/integrations/twilio.ts +35 -7
  698. package/src/runtime/routes/integrations/vercel.ts +3 -3
  699. package/src/runtime/routes/internal-oauth-routes.ts +5 -0
  700. package/src/runtime/routes/internal-twilio-routes.ts +13 -0
  701. package/src/runtime/routes/llm-call-sites-routes.ts +39 -4
  702. package/src/runtime/routes/log-export-routes.ts +28 -10
  703. package/src/runtime/routes/mcp-auth-routes.ts +25 -0
  704. package/src/runtime/routes/memory-item-routes.ts +21 -10
  705. package/src/runtime/routes/memory-v2-routes.ts +90 -36
  706. package/src/runtime/routes/memory-v3-routes.ts +273 -407
  707. package/src/runtime/routes/migration-rollback-routes.ts +5 -1
  708. package/src/runtime/routes/migration-routes.ts +29 -0
  709. package/src/runtime/routes/notification-routes.ts +17 -1
  710. package/src/runtime/routes/oauth-apps.ts +33 -11
  711. package/src/runtime/routes/oauth-commands-routes.ts +37 -14
  712. package/src/runtime/routes/oauth-connect-routes.ts +9 -0
  713. package/src/runtime/routes/oauth-lifecycle-routes.ts +5 -1
  714. package/src/runtime/routes/oauth-providers.ts +35 -10
  715. package/src/runtime/routes/platform-routes.ts +21 -0
  716. package/src/runtime/routes/playground/__tests__/force-compact.test.ts +3 -2
  717. package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +37 -16
  718. package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +7 -3
  719. package/src/runtime/routes/playground/__tests__/state.test.ts +10 -3
  720. package/src/runtime/routes/playground/force-compact.ts +1 -1
  721. package/src/runtime/routes/playground/helpers.ts +0 -1
  722. package/src/runtime/routes/playground/inject-failures.ts +13 -8
  723. package/src/runtime/routes/playground/reset-circuit.ts +14 -9
  724. package/src/runtime/routes/playground/seed-conversation.ts +1 -1
  725. package/src/runtime/routes/playground/seeded-conversations.ts +3 -3
  726. package/src/runtime/routes/playground/state.ts +4 -3
  727. package/src/runtime/routes/plugins-routes.ts +22 -19
  728. package/src/runtime/routes/profiler-routes.ts +17 -4
  729. package/src/runtime/routes/ps-routes.ts +5 -0
  730. package/src/runtime/routes/publish-routes.ts +13 -3
  731. package/src/runtime/routes/question-routes.ts +5 -0
  732. package/src/runtime/routes/recording-routes.ts +25 -12
  733. package/src/runtime/routes/rename-conversation-routes.ts +5 -0
  734. package/src/runtime/routes/sanity-routes.ts +9 -2
  735. package/src/runtime/routes/schedule-routes.ts +137 -47
  736. package/src/runtime/routes/secret-routes.ts +17 -4
  737. package/src/runtime/routes/sequence-routes.ts +33 -0
  738. package/src/runtime/routes/settings-routes.ts +65 -19
  739. package/src/runtime/routes/skills-routes.ts +133 -69
  740. package/src/runtime/routes/slack-channel-routes.ts +5 -0
  741. package/src/runtime/routes/stt-routes.ts +13 -6
  742. package/src/runtime/routes/subagents-routes.ts +24 -18
  743. package/src/runtime/routes/suggest-trust-rule-routes.ts +7 -2
  744. package/src/runtime/routes/surface-action-routes.ts +9 -0
  745. package/src/runtime/routes/surface-content-routes.ts +10 -2
  746. package/src/runtime/routes/task-routes.ts +37 -0
  747. package/src/runtime/routes/telemetry-routes.ts +9 -0
  748. package/src/runtime/routes/trace-event-routes.ts +42 -1
  749. package/src/runtime/routes/trust-rules-routes.ts +5 -0
  750. package/src/runtime/routes/tts-routes.ts +13 -6
  751. package/src/runtime/routes/types.ts +17 -8
  752. package/src/runtime/routes/ui-request-routes.ts +5 -0
  753. package/src/runtime/routes/upgrade-broadcast-routes.ts +5 -0
  754. package/src/runtime/routes/usage-routes.ts +71 -3
  755. package/src/runtime/routes/user-routes-cli.ts +9 -0
  756. package/src/runtime/routes/user-routes.ts +5 -1
  757. package/src/runtime/routes/wake-conversation-routes.ts +5 -0
  758. package/src/runtime/routes/watcher-routes.ts +21 -0
  759. package/src/runtime/routes/webhook-routes.ts +9 -0
  760. package/src/runtime/routes/wipe-conversation-routes.ts +5 -0
  761. package/src/runtime/routes/work-items-routes.ts +47 -19
  762. package/src/runtime/routes/workspace-commit-routes.ts +5 -0
  763. package/src/runtime/routes/workspace-routes.test.ts +42 -0
  764. package/src/runtime/routes/workspace-routes.ts +120 -9
  765. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -4
  766. package/src/runtime/services/analyze-conversation.ts +3 -6
  767. package/src/runtime/services/conversation-serializer.ts +24 -2
  768. package/src/runtime/sync/resource-sync-events.ts +16 -2
  769. package/src/runtime/sync/sync-publisher.ts +2 -2
  770. package/src/schedule/run-script.ts +28 -3
  771. package/src/schedule/schedule-store.ts +8 -0
  772. package/src/schedule/scheduler.ts +3 -1
  773. package/src/signals/user-message.ts +5 -8
  774. package/src/skills/catalog-files.ts +4 -1
  775. package/src/skills/clawhub-files.ts +2 -0
  776. package/src/skills/skillssh-files.ts +2 -0
  777. package/src/subagent/manager.ts +3 -6
  778. package/src/telemetry/types.ts +26 -0
  779. package/src/telemetry/usage-telemetry-reporter.test.ts +138 -1
  780. package/src/telemetry/usage-telemetry-reporter.ts +31 -0
  781. package/src/tools/acp/spawn.test.ts +88 -38
  782. package/src/tools/apps/definitions.ts +8 -4
  783. package/src/tools/ask-question/ask-question-tool.test.ts +120 -105
  784. package/src/tools/ask-question/ask-question-tool.ts +85 -90
  785. package/src/tools/computer-use/definitions.ts +28 -24
  786. package/src/tools/credential-execution/make-authenticated-request.ts +56 -51
  787. package/src/tools/credential-execution/manage-secure-command-tool.ts +2 -2
  788. package/src/tools/credential-execution/run-authenticated-command.ts +82 -77
  789. package/src/tools/credentials/vault.ts +112 -111
  790. package/src/tools/execution-target.ts +1 -1
  791. package/src/tools/execution-timeout.ts +3 -4
  792. package/src/tools/filesystem/edit.ts +45 -42
  793. package/src/tools/filesystem/list.ts +33 -30
  794. package/src/tools/filesystem/read.ts +54 -35
  795. package/src/tools/filesystem/write.ts +34 -31
  796. package/src/tools/host-filesystem/edit.ts +44 -42
  797. package/src/tools/host-filesystem/read.ts +49 -35
  798. package/src/tools/host-filesystem/transfer.ts +121 -108
  799. package/src/tools/host-filesystem/write.ts +33 -31
  800. package/src/tools/host-terminal/host-shell.ts +50 -48
  801. package/src/tools/memory/register.ts +23 -24
  802. package/src/tools/network/web-fetch.ts +49 -46
  803. package/src/tools/network/web-search.ts +16 -13
  804. package/src/tools/registry.ts +39 -16
  805. package/src/tools/schedule/create.ts +11 -0
  806. package/src/tools/schedule/update.ts +16 -0
  807. package/src/tools/shared/filesystem/audio-read.ts +122 -0
  808. package/src/tools/shared/filesystem/image-read.ts +1 -1
  809. package/src/tools/skills/execute.ts +34 -31
  810. package/src/tools/skills/load.ts +29 -23
  811. package/src/tools/subagent/notify-parent.ts +35 -32
  812. package/src/tools/system/avatar-generator.ts +13 -22
  813. package/src/tools/system/request-permission.ts +30 -27
  814. package/src/tools/terminal/shell.ts +190 -61
  815. package/src/tools/tool-defaults.ts +20 -9
  816. package/src/tools/tool-manifest.ts +4 -4
  817. package/src/tools/types.ts +74 -23
  818. package/src/tools/ui-surface/definitions.ts +69 -9
  819. package/src/usage/types.ts +10 -0
  820. package/src/util/errors.ts +2 -2
  821. package/src/util/map-limit.ts +27 -0
  822. package/src/util/platform.ts +15 -12
  823. package/src/work-items/work-item-runner.ts +7 -2
  824. package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +7 -20
  825. package/src/workspace/migrations/092-backfill-v3-leaves.ts +169 -0
  826. package/src/workspace/migrations/093-backfill-leaf-ids.ts +144 -0
  827. package/src/workspace/migrations/094-seed-avatar-manifest.ts +155 -0
  828. package/src/workspace/migrations/__tests__/094-seed-avatar-manifest.test.ts +136 -0
  829. package/src/workspace/migrations/__tests__/backfill-leaf-ids.test.ts +175 -0
  830. package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +124 -0
  831. package/src/workspace/migrations/registry.ts +6 -0
  832. package/src/workspace/provider-commit-message-generator.ts +15 -17
  833. package/tsconfig.json +4 -1
  834. package/src/__tests__/history-repair-pipeline.test.ts +0 -396
  835. package/src/cli/commands/__tests__/memory-v3-render.test.ts +0 -340
  836. package/src/cli/commands/memory-v3-render.ts +0 -491
  837. package/src/daemon/message-types/disk-pressure.ts +0 -9
  838. package/src/email/feature-gate.ts +0 -23
  839. package/src/memory/v3/__tests__/coactivation-store.test.ts +0 -422
  840. package/src/memory/v3/__tests__/consolidation-job.test.ts +0 -466
  841. package/src/memory/v3/__tests__/coretrieval-seed.test.ts +0 -270
  842. package/src/memory/v3/__tests__/edge-learning-job.test.ts +0 -324
  843. package/src/memory/v3/__tests__/edges.test.ts +0 -706
  844. package/src/memory/v3/__tests__/filter.test.ts +0 -560
  845. package/src/memory/v3/__tests__/gate.test.ts +0 -637
  846. package/src/memory/v3/__tests__/index-composition.test.ts +0 -291
  847. package/src/memory/v3/__tests__/loop.test.ts +0 -775
  848. package/src/memory/v3/__tests__/retriever.test.ts +0 -226
  849. package/src/memory/v3/__tests__/scouts.test.ts +0 -489
  850. package/src/memory/v3/__tests__/shadow-diff.test.ts +0 -225
  851. package/src/memory/v3/__tests__/shadow-middleware.test.ts +0 -398
  852. package/src/memory/v3/__tests__/system-prompts.test.ts +0 -154
  853. package/src/memory/v3/__tests__/traversal.test.ts +0 -508
  854. package/src/memory/v3/__tests__/tree-index.test.ts +0 -280
  855. package/src/memory/v3/__tests__/tree-store.test.ts +0 -529
  856. package/src/memory/v3/__tests__/tree-walk.test.ts +0 -784
  857. package/src/memory/v3/__tests__/validate.test.ts +0 -277
  858. package/src/memory/v3/auto-edges.ts +0 -223
  859. package/src/memory/v3/coactivation-store.ts +0 -124
  860. package/src/memory/v3/consolidation-job.ts +0 -323
  861. package/src/memory/v3/coretrieval-seed.ts +0 -240
  862. package/src/memory/v3/edge-learning-job.ts +0 -160
  863. package/src/memory/v3/edges.ts +0 -286
  864. package/src/memory/v3/filter.ts +0 -286
  865. package/src/memory/v3/gate.ts +0 -349
  866. package/src/memory/v3/index-composition.ts +0 -126
  867. package/src/memory/v3/llm-capture.ts +0 -46
  868. package/src/memory/v3/loop.ts +0 -430
  869. package/src/memory/v3/maintenance.ts +0 -144
  870. package/src/memory/v3/prompt-context.ts +0 -33
  871. package/src/memory/v3/prompts/consolidation.ts +0 -458
  872. package/src/memory/v3/prompts/system-prompts.ts +0 -196
  873. package/src/memory/v3/retriever.ts +0 -33
  874. package/src/memory/v3/scouts.ts +0 -431
  875. package/src/memory/v3/shadow-diff.ts +0 -287
  876. package/src/memory/v3/shadow-middleware.ts +0 -347
  877. package/src/memory/v3/traversal.ts +0 -211
  878. package/src/memory/v3/tree-index.ts +0 -237
  879. package/src/memory/v3/tree-store.ts +0 -394
  880. package/src/memory/v3/tree-walk.ts +0 -356
  881. package/src/memory/v3/validate.ts +0 -323
  882. package/src/plugins/defaults/circuit-breaker.ts +0 -141
  883. package/src/plugins/defaults/compaction.ts +0 -141
  884. package/src/plugins/defaults/empty-response.ts +0 -124
  885. package/src/plugins/defaults/history-repair.ts +0 -83
  886. package/src/plugins/defaults/persistence.ts +0 -146
  887. package/src/plugins/defaults/title-generate.ts +0 -90
  888. package/src/plugins/defaults/token-estimate.ts +0 -101
  889. package/src/plugins/defaults/tool-error.ts +0 -119
  890. package/src/plugins/defaults/tool-result-truncate.ts +0 -84
  891. package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +0 -35
@@ -74,8 +74,10 @@ function makeTarget(): WakeTarget {
74
74
  return {
75
75
  conversationId: "conv-wake-callsite",
76
76
  agentLoop: {
77
- run: (async (messages: Message[]) =>
78
- messages) as WakeTarget["agentLoop"]["run"],
77
+ run: (async (messages: Message[]) => ({
78
+ history: messages,
79
+ exitReason: null,
80
+ })) as WakeTarget["agentLoop"]["run"],
79
81
  },
80
82
  getMessages: () => history,
81
83
  pushMessage: (msg) => {
@@ -48,7 +48,7 @@ mock.module("../config/loader.js", () => ({
48
48
  }),
49
49
  }));
50
50
 
51
- import type { AgentEvent } from "../agent/loop.js";
51
+ import type { AgentEvent, AgentLoopRunOptions } from "../agent/loop.js";
52
52
  import { LLMSchema } from "../config/schemas/llm.js";
53
53
  import { RetryProvider } from "../providers/retry.js";
54
54
  import type {
@@ -65,13 +65,7 @@ import {
65
65
 
66
66
  interface RunArgs {
67
67
  messages: Message[];
68
- signal: AbortSignal | undefined;
69
- requestId: string | undefined;
70
- onCheckpoint: unknown;
71
- callSite: unknown;
72
- turnContext: unknown;
73
- overrideProfile: string | undefined;
74
- effectiveMaxInputTokens: number | undefined;
68
+ options: AgentLoopRunOptions | undefined;
75
69
  }
76
70
 
77
71
  function makeTarget(): {
@@ -90,26 +84,15 @@ function makeTarget(): {
90
84
  run: (async (
91
85
  messages: Message[],
92
86
  _onEvent: (event: AgentEvent) => void | Promise<void>,
93
- signal?: AbortSignal,
94
- requestId?: string,
95
- onCheckpoint?: unknown,
96
- callSite?: unknown,
97
- turnContext?: unknown,
98
- overrideProfile?: string,
99
- effectiveMaxInputTokens?: number,
87
+ options?: AgentLoopRunOptions,
100
88
  ) => {
101
89
  runArgs.push({
102
90
  messages: [...messages],
103
- signal,
104
- requestId,
105
- onCheckpoint,
106
- callSite,
107
- turnContext,
108
- overrideProfile,
109
- effectiveMaxInputTokens,
91
+ options,
110
92
  });
111
93
  // Return the input verbatim → silent no-op (no assistant tail).
112
- return messages;
94
+ // Wake never yields at a checkpoint, so the pause-reason is null.
95
+ return { history: messages, exitReason: null };
113
96
  }) as WakeTarget["agentLoop"]["run"],
114
97
  },
115
98
  getMessages: () => history,
@@ -167,18 +150,17 @@ describe("wakeAgentForOpportunity — overrideProfile forwarding", () => {
167
150
 
168
151
  expect(result.invoked).toBe(true);
169
152
  expect(runArgs).toHaveLength(1);
170
- // The 8th positional argument (after messages, onEvent, signal,
171
- // requestId, onCheckpoint, callSite, turnContext) is overrideProfile.
172
- expect(runArgs[0]!.overrideProfile).toBe("frontier");
173
- // The 6th positional argument is callSite. Wakes resume a user-facing
174
- // conversation, so route through the same `mainAgent` call site as a
175
- // normal user turn — without it the resolver and routing layers would
176
- // short-circuit and silently drop both the call-site config and the
177
- // pinned override profile.
178
- expect(runArgs[0]!.callSite).toBe("mainAgent");
179
- expect(runArgs[0]!.effectiveMaxInputTokens).toBe(150000);
153
+ expect(runArgs[0]!.options?.overrideProfile).toBe("frontier");
154
+ // Wakes resume a user-facing conversation, so route through the same
155
+ // `mainAgent` call site as a normal user turn — without it the resolver
156
+ // and routing layers would short-circuit and silently drop both the
157
+ // call-site config and the pinned override profile.
158
+ expect(runArgs[0]!.options?.callSite).toBe("mainAgent");
159
+ expect(runArgs[0]!.options?.resolveContextWindow?.().maxInputTokens).toBe(
160
+ 150000,
161
+ );
180
162
  // Sanity: the wake-source tag still propagates as requestId.
181
- expect(runArgs[0]!.requestId).toBe("wake:scheduler");
163
+ expect(runArgs[0]!.options?.requestId).toBe("wake:scheduler");
182
164
  });
183
165
 
184
166
  test("passes undefined overrideProfile when the conversation has no pinned profile, but still forwards mainAgent callSite", async () => {
@@ -195,13 +177,15 @@ describe("wakeAgentForOpportunity — overrideProfile forwarding", () => {
195
177
  );
196
178
 
197
179
  expect(runArgs).toHaveLength(1);
198
- expect(runArgs[0]!.overrideProfile).toBeUndefined();
180
+ expect(runArgs[0]!.options?.overrideProfile).toBeUndefined();
199
181
  // Even without an override profile, we still need callSite="mainAgent"
200
182
  // so the resolver picks up `llm.callSites.mainAgent` config (model,
201
183
  // maxTokens, effort, etc.). Otherwise the wake silently runs under
202
184
  // workspace defaults regardless of any per-call-site configuration.
203
- expect(runArgs[0]!.callSite).toBe("mainAgent");
204
- expect(runArgs[0]!.effectiveMaxInputTokens).toBeGreaterThan(0);
185
+ expect(runArgs[0]!.options?.callSite).toBe("mainAgent");
186
+ expect(
187
+ runArgs[0]!.options?.resolveContextWindow?.().maxInputTokens,
188
+ ).toBeGreaterThan(0);
205
189
  });
206
190
  });
207
191
 
@@ -221,7 +205,7 @@ describe("wakeAgentForOpportunity — resolver actually engages", () => {
221
205
  ): Provider {
222
206
  return {
223
207
  name,
224
- async sendMessage(_messages, _tools, _systemPrompt, options) {
208
+ async sendMessage(_messages: Message[], options?: SendMessageOptions) {
225
209
  onCall(options);
226
210
  const response: ProviderResponse = {
227
211
  content: [{ type: "text", text: "ok" }],
@@ -267,8 +251,6 @@ describe("wakeAgentForOpportunity — resolver actually engages", () => {
267
251
  // `callSite` and `overrideProfile` are both set (see `agent/loop.ts`).
268
252
  await wrapped.sendMessage(
269
253
  [{ role: "user", content: [{ type: "text", text: "hi" }] }],
270
- undefined,
271
- undefined,
272
254
  { config: { callSite: "mainAgent", overrideProfile: "frontier" } },
273
255
  );
274
256
 
@@ -180,7 +180,9 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
180
180
  // System prompt cache control
181
181
  // -----------------------------------------------------------------------
182
182
  test("system prompt has cache_control ephemeral with 1h TTL", async () => {
183
- await provider.sendMessage([userMsg("Hi")], undefined, "You are helpful.");
183
+ await provider.sendMessage([userMsg("Hi")], {
184
+ systemPrompt: "You are helpful.",
185
+ });
184
186
 
185
187
  const system = lastStreamParams!.system as Array<{
186
188
  type: string;
@@ -198,7 +200,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
198
200
  });
199
201
 
200
202
  test("sends disabled thinking config natively", async () => {
201
- await provider.sendMessage([userMsg("Hi")], undefined, undefined, {
203
+ await provider.sendMessage([userMsg("Hi")], {
202
204
  config: { thinking: { type: "disabled" } },
203
205
  });
204
206
 
@@ -230,7 +232,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
230
232
  test("renders the system prompt as a single 1h-cached block", async () => {
231
233
  const prompt = "You are a helpful assistant.";
232
234
 
233
- await provider.sendMessage([userMsg("Hi")], undefined, prompt);
235
+ await provider.sendMessage([userMsg("Hi")], { systemPrompt: prompt });
234
236
 
235
237
  const system = lastStreamParams!.system as Array<{
236
238
  type: string;
@@ -251,7 +253,10 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
251
253
  toolUseMsg("tu_1", "bash"),
252
254
  toolResultMsg("tu_1", "output"),
253
255
  ];
254
- await provider.sendMessage(messages, sampleTools, prompt);
256
+ await provider.sendMessage(messages, {
257
+ tools: sampleTools,
258
+ systemPrompt: prompt,
259
+ });
255
260
 
256
261
  const system = lastStreamParams!.system as Array<{
257
262
  type: string;
@@ -291,7 +296,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
291
296
  // Tool cache control
292
297
  // -----------------------------------------------------------------------
293
298
  test("only last tool definition includes cache_control", async () => {
294
- await provider.sendMessage([userMsg("Hi")], sampleTools);
299
+ await provider.sendMessage([userMsg("Hi")], { tools: sampleTools });
295
300
 
296
301
  const tools = lastStreamParams!.tools as Array<{
297
302
  name: string;
@@ -308,7 +313,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
308
313
  });
309
314
 
310
315
  test("single tool gets cache_control", async () => {
311
- await provider.sendMessage([userMsg("Hi")], [sampleTools[0]]);
316
+ await provider.sendMessage([userMsg("Hi")], { tools: [sampleTools[0]] });
312
317
 
313
318
  const tools = lastStreamParams!.tools as Array<{
314
319
  name: string;
@@ -409,14 +414,9 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
409
414
  // per call with content that changes every time. Caching the turn-start
410
415
  // block would create unused entries — `disableTurnStartCache: true`
411
416
  // opts out.
412
- await provider.sendMessage(
413
- [userMsg("Pick relevant pages")],
414
- undefined,
415
- undefined,
416
- {
417
- config: { disableTurnStartCache: true },
418
- },
419
- );
417
+ await provider.sendMessage([userMsg("Pick relevant pages")], {
418
+ config: { disableTurnStartCache: true },
419
+ });
420
420
 
421
421
  const sent = lastStreamParams!.messages as Array<{
422
422
  role: string;
@@ -458,6 +458,128 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
458
458
  }
459
459
  });
460
460
 
461
+ // -----------------------------------------------------------------------
462
+ // mutableLatestUserMessage — volatile trailing user message cache anchor
463
+ // -----------------------------------------------------------------------
464
+ test("mutableLatestUserMessage: first-of-turn skips the volatile turn-start anchor and anchors the previous stable user message", async () => {
465
+ // The latest user message carries per-turn-volatile content (e.g. an
466
+ // injected memory block). The long-TTL anchor must move off it onto the
467
+ // most recent stable user message so the cached prefix stays reusable.
468
+ const messages: Message[] = [
469
+ userMsg("Turn 1"),
470
+ assistantMsg("Response 1"),
471
+ userMsg("Turn 2 (volatile)"),
472
+ ];
473
+ await provider.sendMessage(messages, {
474
+ config: { mutableLatestUserMessage: true },
475
+ });
476
+
477
+ const sent = lastStreamParams!.messages as Array<{
478
+ role: string;
479
+ content: Array<{
480
+ type: string;
481
+ text: string;
482
+ cache_control?: { type: string; ttl?: string };
483
+ }>;
484
+ }>;
485
+ const userMessages = sent.filter((m) => m.role === "user");
486
+
487
+ // Latest (turn-start) user message gets NO long-TTL breakpoint — it's volatile.
488
+ const latest = userMessages[userMessages.length - 1];
489
+ for (const block of latest.content) {
490
+ expect(block.cache_control).toBeUndefined();
491
+ }
492
+
493
+ // Previous stable user message (Turn 1) becomes the primary anchor.
494
+ const prev = userMessages[userMessages.length - 2];
495
+ const prevLast = prev.content[prev.content.length - 1];
496
+ expect(prevLast.cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
497
+ });
498
+
499
+ test("mutableLatestUserMessage absent: breakpoint placement is byte-identical to default behavior (v2 regression guard)", async () => {
500
+ const messages: Message[] = [
501
+ userMsg("Turn 1"),
502
+ assistantMsg("Response 1"),
503
+ userMsg("Turn 2"),
504
+ ];
505
+ await provider.sendMessage(messages);
506
+
507
+ const sent = lastStreamParams!.messages as Array<{
508
+ role: string;
509
+ content: Array<{
510
+ type: string;
511
+ cache_control?: { type: string; ttl?: string };
512
+ }>;
513
+ }>;
514
+ const userMessages = sent.filter((m) => m.role === "user");
515
+
516
+ // Current-turn (latest) anchor keeps 1h.
517
+ const latest = userMessages[userMessages.length - 1];
518
+ const latestLast = latest.content[latest.content.length - 1];
519
+ expect(latestLast.cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
520
+ // Previous-turn anchor keeps 1h.
521
+ const prev = userMessages[userMessages.length - 2];
522
+ const prevLast = prev.content[prev.content.length - 1];
523
+ expect(prevLast.cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
524
+ });
525
+
526
+ test("mutableLatestUserMessage: during a tool-use loop placement is unchanged (block is fixed within the turn)", async () => {
527
+ // Turn-start is not the last message (tool_result follows), so the
528
+ // turn-start block is fixed for the rest of the turn — the flag must not
529
+ // move the anchor.
530
+ const messages: Message[] = [
531
+ userMsg("Turn 1"),
532
+ assistantMsg("Response 1"),
533
+ userMsg("Turn 2"),
534
+ toolUseMsg("tu_1", "bash"),
535
+ toolResultMsg("tu_1", "output"),
536
+ ];
537
+ await provider.sendMessage(messages, {
538
+ config: { mutableLatestUserMessage: true },
539
+ });
540
+
541
+ const sent = lastStreamParams!.messages as Array<{
542
+ role: string;
543
+ content: Array<{
544
+ type: string;
545
+ cache_control?: { type: string; ttl?: string };
546
+ }>;
547
+ }>;
548
+
549
+ // Turn-start (Turn 2, index 2) still gets the 1h anchor — within a tool-use
550
+ // loop the block is fixed, so the volatile-latest flag must not move it.
551
+ const turn2 = sent[2];
552
+ const turn2Last = turn2.content[turn2.content.length - 1];
553
+ expect(turn2Last.cache_control).toEqual({ type: "ephemeral", ttl: "1h" });
554
+ });
555
+
556
+ test("mutableLatestUserMessage: first turn with no previous user message does not throw and applies no long-TTL anchor", async () => {
557
+ await provider.sendMessage([userMsg("First ever turn (volatile)")], {
558
+ config: { mutableLatestUserMessage: true },
559
+ });
560
+
561
+ const sent = lastStreamParams!.messages as Array<{
562
+ role: string;
563
+ content: Array<{
564
+ type: string;
565
+ cache_control?: { type: string; ttl?: string };
566
+ }>;
567
+ }>;
568
+ // Only user message is volatile and there is no prior stable one, so no
569
+ // long-TTL breakpoint lands on any user message — graceful, no throw.
570
+ const lastBlock = sent[0].content[sent[0].content.length - 1];
571
+ expect(lastBlock.cache_control).toBeUndefined();
572
+ });
573
+
574
+ test("mutableLatestUserMessage is not forwarded to the Anthropic API", async () => {
575
+ await provider.sendMessage([userMsg("Hi")], {
576
+ config: { mutableLatestUserMessage: true },
577
+ });
578
+ expect(
579
+ (lastStreamParams as Record<string, unknown>).mutableLatestUserMessage,
580
+ ).toBeUndefined();
581
+ });
582
+
461
583
  // -----------------------------------------------------------------------
462
584
  // Negative: assistant messages never get cache_control
463
585
  // -----------------------------------------------------------------------
@@ -1537,7 +1659,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
1537
1659
  { kind: "blockStop" },
1538
1660
  ];
1539
1661
  const emitted: string[] = [];
1540
- await provider.sendMessage([userMsg("Hi")], undefined, undefined, {
1662
+ await provider.sendMessage([userMsg("Hi")], {
1541
1663
  onEvent: (event) => {
1542
1664
  if (event.type === "text_delta") emitted.push(event.text);
1543
1665
  },
@@ -1554,7 +1676,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
1554
1676
  { kind: "blockStop" },
1555
1677
  ];
1556
1678
  const emitted: string[] = [];
1557
- await provider.sendMessage([userMsg("Hi")], undefined, undefined, {
1679
+ await provider.sendMessage([userMsg("Hi")], {
1558
1680
  onEvent: (event) => {
1559
1681
  if (event.type === "text_delta") emitted.push(event.text);
1560
1682
  },
@@ -1569,7 +1691,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
1569
1691
  { kind: "blockStop" },
1570
1692
  ];
1571
1693
  const emitted: string[] = [];
1572
- await provider.sendMessage([userMsg("Hi")], undefined, undefined, {
1694
+ await provider.sendMessage([userMsg("Hi")], {
1573
1695
  onEvent: (event) => {
1574
1696
  if (event.type === "text_delta") emitted.push(event.text);
1575
1697
  },
@@ -1586,7 +1708,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
1586
1708
  { kind: "blockStop" },
1587
1709
  ];
1588
1710
  const emitted: string[] = [];
1589
- await provider.sendMessage([userMsg("Hi")], undefined, undefined, {
1711
+ await provider.sendMessage([userMsg("Hi")], {
1590
1712
  onEvent: (event) => {
1591
1713
  if (event.type === "text_delta") emitted.push(event.text);
1592
1714
  },
@@ -1605,7 +1727,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
1605
1727
  { kind: "blockStop" },
1606
1728
  ];
1607
1729
  const emitted: string[] = [];
1608
- await provider.sendMessage([userMsg("Hi")], undefined, undefined, {
1730
+ await provider.sendMessage([userMsg("Hi")], {
1609
1731
  onEvent: (event) => {
1610
1732
  if (event.type === "text_delta") emitted.push(event.text);
1611
1733
  },
@@ -1622,7 +1744,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
1622
1744
  { kind: "blockStop" },
1623
1745
  ];
1624
1746
  const emitted: string[] = [];
1625
- await provider.sendMessage([userMsg("Hi")], undefined, undefined, {
1747
+ await provider.sendMessage([userMsg("Hi")], {
1626
1748
  onEvent: (event) => {
1627
1749
  if (event.type === "text_delta") emitted.push(event.text);
1628
1750
  },
@@ -1640,7 +1762,7 @@ describe("AnthropicProvider — Cache-Control Characterization", () => {
1640
1762
  { kind: "blockStop" },
1641
1763
  ];
1642
1764
  const emitted: string[] = [];
1643
- await provider.sendMessage([userMsg("Hi")], undefined, undefined, {
1765
+ await provider.sendMessage([userMsg("Hi")], {
1644
1766
  onEvent: (event) => {
1645
1767
  if (event.type === "text_delta") emitted.push(event.text);
1646
1768
  },
@@ -2120,11 +2242,10 @@ describe("AnthropicProvider — Managed Proxy Fallback", () => {
2120
2242
  baseURL: "https://platform.example.com/v1/runtime-proxy/anthropic",
2121
2243
  });
2122
2244
 
2123
- await provider.sendMessage(
2124
- [userMsg("Hi")],
2125
- sampleTools,
2126
- "You are helpful.",
2127
- );
2245
+ await provider.sendMessage([userMsg("Hi")], {
2246
+ tools: sampleTools,
2247
+ systemPrompt: "You are helpful.",
2248
+ });
2128
2249
 
2129
2250
  // System prompt cache control
2130
2251
  const system = lastStreamParams!.system as Array<{
@@ -2224,13 +2345,16 @@ describe("AnthropicProvider — Haiku Model Gating", () => {
2224
2345
  });
2225
2346
 
2226
2347
  test("max_tokens defaults to 8192 for Haiku", async () => {
2227
- await provider.sendMessage([userMsg("Hi")], undefined, "You are helpful.");
2348
+ await provider.sendMessage([userMsg("Hi")], {
2349
+ systemPrompt: "You are helpful.",
2350
+ });
2228
2351
 
2229
2352
  expect(lastStreamParams!.max_tokens).toBe(8192);
2230
2353
  });
2231
2354
 
2232
2355
  test("caller max_tokens is clamped to 8192 for Haiku", async () => {
2233
- await provider.sendMessage([userMsg("Hi")], undefined, "You are helpful.", {
2356
+ await provider.sendMessage([userMsg("Hi")], {
2357
+ systemPrompt: "You are helpful.",
2234
2358
  config: { max_tokens: 64000 },
2235
2359
  });
2236
2360
 
@@ -2238,7 +2362,8 @@ describe("AnthropicProvider — Haiku Model Gating", () => {
2238
2362
  });
2239
2363
 
2240
2364
  test("caller max_tokens below 8192 is preserved for Haiku", async () => {
2241
- await provider.sendMessage([userMsg("Hi")], undefined, "You are helpful.", {
2365
+ await provider.sendMessage([userMsg("Hi")], {
2366
+ systemPrompt: "You are helpful.",
2242
2367
  config: { max_tokens: 128 },
2243
2368
  });
2244
2369
 
@@ -2250,18 +2375,18 @@ describe("AnthropicProvider — Haiku Model Gating", () => {
2250
2375
  "sk-ant-test",
2251
2376
  "claude-sonnet-4-6",
2252
2377
  );
2253
- await sonnetProvider.sendMessage(
2254
- [userMsg("Hi")],
2255
- undefined,
2256
- "You are helpful.",
2257
- { config: { max_tokens: 200 } },
2258
- );
2378
+ await sonnetProvider.sendMessage([userMsg("Hi")], {
2379
+ systemPrompt: "You are helpful.",
2380
+ config: { max_tokens: 200 },
2381
+ });
2259
2382
 
2260
2383
  expect(lastStreamParams!.max_tokens).toBe(200);
2261
2384
  });
2262
2385
 
2263
2386
  test("cache_control omits ttl for Haiku", async () => {
2264
- await provider.sendMessage([userMsg("Hi")], undefined, "You are helpful.");
2387
+ await provider.sendMessage([userMsg("Hi")], {
2388
+ systemPrompt: "You are helpful.",
2389
+ });
2265
2390
 
2266
2391
  const system = lastStreamParams!.system as Array<{
2267
2392
  cache_control?: { type: string; ttl?: string };
@@ -2271,7 +2396,9 @@ describe("AnthropicProvider — Haiku Model Gating", () => {
2271
2396
  });
2272
2397
 
2273
2398
  test("betas array is empty for Haiku (no extended cache TTL)", async () => {
2274
- await provider.sendMessage([userMsg("Hi")], undefined, "You are helpful.");
2399
+ await provider.sendMessage([userMsg("Hi")], {
2400
+ systemPrompt: "You are helpful.",
2401
+ });
2275
2402
 
2276
2403
  // When betas is empty, the non-beta stream path is used, so no betas
2277
2404
  // field should appear in lastStreamParams.
@@ -2279,7 +2406,8 @@ describe("AnthropicProvider — Haiku Model Gating", () => {
2279
2406
  });
2280
2407
 
2281
2408
  test("effort is stripped for Haiku even when provided in config", async () => {
2282
- await provider.sendMessage([userMsg("Hi")], undefined, "You are helpful.", {
2409
+ await provider.sendMessage([userMsg("Hi")], {
2410
+ systemPrompt: "You are helpful.",
2283
2411
  config: { effort: "high" },
2284
2412
  });
2285
2413
 
@@ -2291,12 +2419,10 @@ describe("AnthropicProvider — Haiku Model Gating", () => {
2291
2419
  "sk-ant-test",
2292
2420
  "claude-sonnet-4-6",
2293
2421
  );
2294
- await sonnetProvider.sendMessage(
2295
- [userMsg("Hi")],
2296
- undefined,
2297
- "You are helpful.",
2298
- { config: { effort: "none" } },
2299
- );
2422
+ await sonnetProvider.sendMessage([userMsg("Hi")], {
2423
+ systemPrompt: "You are helpful.",
2424
+ config: { effort: "none" },
2425
+ });
2300
2426
 
2301
2427
  // mergedOutputConfig is empty when effort is "none" and no other
2302
2428
  // output_config fields were supplied, so output_config is not attached
@@ -2323,7 +2449,9 @@ describe("OpenRouterProvider — Anthropic dispatch", () => {
2323
2449
  "or-key",
2324
2450
  "anthropic/claude-sonnet-4.6",
2325
2451
  );
2326
- await provider.sendMessage([userMsg("hi")], undefined, "You are helpful.");
2452
+ await provider.sendMessage([userMsg("hi")], {
2453
+ systemPrompt: "You are helpful.",
2454
+ });
2327
2455
 
2328
2456
  expect(lastConstructorArgs).toMatchObject({
2329
2457
  apiKey: null,
@@ -2358,7 +2486,7 @@ describe("OpenRouterProvider — Anthropic dispatch", () => {
2358
2486
  "or-key",
2359
2487
  "anthropic/claude-sonnet-4.6",
2360
2488
  );
2361
- await provider.sendMessage([userMsg("hi")], undefined, undefined, {
2489
+ await provider.sendMessage([userMsg("hi")], {
2362
2490
  config: { thinking: { type: "adaptive" } },
2363
2491
  });
2364
2492
 
@@ -2375,7 +2503,7 @@ describe("OpenRouterProvider — Anthropic dispatch", () => {
2375
2503
  "or-key",
2376
2504
  "anthropic/claude-sonnet-4.6",
2377
2505
  );
2378
- await provider.sendMessage([userMsg("hi")], undefined, undefined, {
2506
+ await provider.sendMessage([userMsg("hi")], {
2379
2507
  config: { thinking: { type: "disabled" } },
2380
2508
  });
2381
2509
 
@@ -2390,7 +2518,7 @@ describe("OpenRouterProvider — Anthropic dispatch", () => {
2390
2518
  "or-key",
2391
2519
  "anthropic/claude-sonnet-4.6",
2392
2520
  );
2393
- await provider.sendMessage([userMsg("hi")], undefined, undefined, {
2521
+ await provider.sendMessage([userMsg("hi")], {
2394
2522
  config: {
2395
2523
  usageAttributionHeaders: {
2396
2524
  "Vellum-Organization-Id": "org-123",
@@ -2418,7 +2546,7 @@ describe("OpenRouterProvider — Anthropic dispatch", () => {
2418
2546
  // Default model is non-Anthropic, but the request overrides with an
2419
2547
  // Anthropic model — dispatch must honour the request-level model.
2420
2548
  const provider = new OpenRouterProvider("or-key", "x-ai/grok-4");
2421
- await provider.sendMessage([userMsg("hi")], undefined, undefined, {
2549
+ await provider.sendMessage([userMsg("hi")], {
2422
2550
  config: { model: "anthropic/claude-haiku-4.5" },
2423
2551
  });
2424
2552
 
@@ -2488,7 +2616,10 @@ describe("AnthropicProvider — thinking block send-time filtering", () => {
2488
2616
  userMsg("And what is 3+3?"),
2489
2617
  ];
2490
2618
 
2491
- await provider.sendMessage(messages, sampleTools, "system");
2619
+ await provider.sendMessage(messages, {
2620
+ tools: sampleTools,
2621
+ systemPrompt: "system",
2622
+ });
2492
2623
  expect(lastStreamParams).toBeTruthy();
2493
2624
 
2494
2625
  const sent = lastStreamParams!.messages as Anthropic.MessageParam[];
@@ -2514,7 +2645,10 @@ describe("AnthropicProvider — thinking block send-time filtering", () => {
2514
2645
  userMsg("And what is 3+3?"),
2515
2646
  ];
2516
2647
 
2517
- await provider.sendMessage(messages, sampleTools, "system");
2648
+ await provider.sendMessage(messages, {
2649
+ tools: sampleTools,
2650
+ systemPrompt: "system",
2651
+ });
2518
2652
  expect(lastStreamParams).toBeTruthy();
2519
2653
 
2520
2654
  const sent = lastStreamParams!.messages as Anthropic.MessageParam[];
@@ -2540,7 +2674,10 @@ describe("AnthropicProvider — thinking block send-time filtering", () => {
2540
2674
  toolResultMsg("tu-1", "file contents here"),
2541
2675
  ];
2542
2676
 
2543
- await provider.sendMessage(messages, sampleTools, "system");
2677
+ await provider.sendMessage(messages, {
2678
+ tools: sampleTools,
2679
+ systemPrompt: "system",
2680
+ });
2544
2681
  expect(lastStreamParams).toBeTruthy();
2545
2682
 
2546
2683
  const sent = lastStreamParams!.messages as Anthropic.MessageParam[];
@@ -2573,7 +2710,10 @@ describe("AnthropicProvider — thinking block send-time filtering", () => {
2573
2710
  toolResultMsg("tu-2", "file contents"),
2574
2711
  ];
2575
2712
 
2576
- await provider.sendMessage(messages, sampleTools, "system");
2713
+ await provider.sendMessage(messages, {
2714
+ tools: sampleTools,
2715
+ systemPrompt: "system",
2716
+ });
2577
2717
  expect(lastStreamParams).toBeTruthy();
2578
2718
 
2579
2719
  const sent = lastStreamParams!.messages as Anthropic.MessageParam[];
@@ -2610,7 +2750,10 @@ describe("AnthropicProvider — thinking block send-time filtering", () => {
2610
2750
  userMsg("What did you conclude?"),
2611
2751
  ];
2612
2752
 
2613
- await provider.sendMessage(messages, sampleTools, "system");
2753
+ await provider.sendMessage(messages, {
2754
+ tools: sampleTools,
2755
+ systemPrompt: "system",
2756
+ });
2614
2757
  expect(lastStreamParams).toBeTruthy();
2615
2758
 
2616
2759
  const sent = lastStreamParams!.messages as Anthropic.MessageParam[];
@@ -2648,7 +2791,10 @@ describe("AnthropicProvider — thinking block send-time filtering", () => {
2648
2791
  toolResultMsg("tu-b", "result b"),
2649
2792
  ];
2650
2793
 
2651
- await provider.sendMessage(messages, sampleTools, "system");
2794
+ await provider.sendMessage(messages, {
2795
+ tools: sampleTools,
2796
+ systemPrompt: "system",
2797
+ });
2652
2798
  expect(lastStreamParams).toBeTruthy();
2653
2799
 
2654
2800
  const sent = lastStreamParams!.messages as Anthropic.MessageParam[];
@@ -0,0 +1,22 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { describe, expect, test } from "bun:test";
3
+
4
+ describe("app-builder skill instructions", () => {
5
+ test("uses non-CLI UI confirmation for optional profile switch", async () => {
6
+ const skillText = await readFile(
7
+ new URL("../config/bundled-skills/app-builder/SKILL.md", import.meta.url),
8
+ "utf8",
9
+ );
10
+ const preflightStart = skillText.indexOf("### 0. Preflight");
11
+ const preflightEnd = skillText.indexOf("### 1. Gather Requirements");
12
+ const preflight = skillText.slice(preflightStart, preflightEnd);
13
+
14
+ expect(preflight).not.toContain("assistant ui confirm --message");
15
+ expect(preflight).toContain("Use the `ui_show` tool");
16
+ expect(preflight).toContain('surface_type: "confirmation"');
17
+ expect(preflight).toContain("await_action: true");
18
+ expect(preflight).toContain(
19
+ "Do not call the shell command `assistant ui confirm`",
20
+ );
21
+ });
22
+ });
@@ -131,6 +131,11 @@ function buildContext(
131
131
  ): SurfaceConversationContext {
132
132
  return {
133
133
  conversationId,
134
+ trustContext: {
135
+ sourceChannel: "vellum",
136
+ trustClass: "guardian",
137
+ guardianPrincipalId: "user-1",
138
+ },
134
139
  traceEmitter: { emit: () => {} },
135
140
  sendToClient: () => {},
136
141
  pendingSurfaceActions: new Map(),