@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
@@ -8,11 +8,8 @@ import { beforeEach, describe, expect, mock, test } from "bun:test";
8
8
 
9
9
  import { Minimatch } from "minimatch";
10
10
 
11
- import type {
12
- AgentEvent,
13
- CheckpointDecision,
14
- CheckpointInfo,
15
- } from "../agent/loop.js";
11
+ import { CompactionCircuit } from "../agent/compaction-circuit.js";
12
+ import type { AgentEvent } from "../agent/loop.js";
16
13
  import type { ServerMessage } from "../daemon/message-protocol.js";
17
14
  import type { ConfirmationStateChanged } from "../daemon/message-types/messages.js";
18
15
  import type { Message, ProviderResponse } from "../providers/types.js";
@@ -200,6 +197,7 @@ mock.module("../memory/llm-usage-store.js", () => ({
200
197
 
201
198
  mock.module("../agent/loop.js", () => ({
202
199
  AgentLoop: class {
200
+ compactionCircuit = new CompactionCircuit("test-conv");
203
201
  constructor() {}
204
202
  getToolTokenBudget() {
205
203
  return 0;
@@ -213,11 +211,6 @@ mock.module("../agent/loop.js", () => ({
213
211
  async run(
214
212
  _messages: Message[],
215
213
  _onEvent: (event: AgentEvent) => void,
216
- _signal?: AbortSignal,
217
- _requestId?: string,
218
- _onCheckpoint?: (
219
- checkpoint: CheckpointInfo,
220
- ) => CheckpointDecision | Promise<CheckpointDecision>,
221
214
  ): Promise<Message[]> {
222
215
  return [];
223
216
  }
@@ -279,9 +272,9 @@ function makeConversation(
279
272
  conversationId,
280
273
  makeProvider(),
281
274
  "system prompt",
282
- 4096,
283
275
  sendToClient ?? (() => {}),
284
276
  process.env.VELLUM_WORKSPACE_DIR!,
277
+ { maxTokens: 4096 },
285
278
  );
286
279
  }
287
280
 
@@ -181,8 +181,9 @@ function makeIdleSession(opts?: {
181
181
  runAgentLoop: async (
182
182
  _content: string,
183
183
  _messageId: string,
184
- onEvent: (msg: ServerMessage) => void,
184
+ options?: { onEvent?: (msg: ServerMessage) => void },
185
185
  ) => {
186
+ const onEvent = options?.onEvent ?? (() => {});
186
187
  onEvent({ type: "assistant_text_delta", text: "Hello!" });
187
188
  onEvent({ type: "message_complete", conversationId: "test-session" });
188
189
  processing = false;
@@ -246,8 +247,9 @@ function makeConfirmationEmittingSession(opts?: {
246
247
  runAgentLoop: async (
247
248
  _content: string,
248
249
  _messageId: string,
249
- onEvent: (msg: ServerMessage) => void,
250
+ options?: { onEvent?: (msg: ServerMessage) => void },
250
251
  ) => {
252
+ const onEvent = options?.onEvent ?? (() => {});
251
253
  // Simulate PermissionPrompter.prompt(): self-register in pendingInteractions
252
254
  // before emitting the SSE event (registration no longer happens via broadcastMessage).
253
255
  pendingInteractions.register(reqId, {
@@ -111,6 +111,21 @@ describe("formatSseFrame", () => {
111
111
  const frame = formatSseFrame(baseEvent);
112
112
  expect(frame.endsWith("\n\n")).toBe(true);
113
113
  });
114
+
115
+ test("seq lands in the JSON payload (envelope) when set, never in SSE id", () => {
116
+ const event: AssistantEvent = {
117
+ ...baseEvent,
118
+ id: "uuid-event-id",
119
+ seq: 42,
120
+ };
121
+ const frame = formatSseFrame(event);
122
+ // SSE wire id is always the UUID -- replay cursor is decoupled from
123
+ // the SSE protocol and lives on the envelope only.
124
+ const idLine = frame.split("\n").find((l) => l.startsWith("id: "))!;
125
+ expect(idLine).toBe("id: uuid-event-id");
126
+ // seq is on the envelope; consumers read it from the JSON payload.
127
+ expect(frame).toContain('"seq":42');
128
+ });
114
129
  });
115
130
 
116
131
  // ── Heartbeat tests ───────────────────────────────────────────────────────────
@@ -12,7 +12,7 @@ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
12
12
  // Test-scoped config state
13
13
  // ---------------------------------------------------------------------------
14
14
 
15
- const DECLARED_FLAG_ID = "email-channel";
15
+ const DECLARED_FLAG_ID = "a2a-channel";
16
16
  const DECLARED_FLAG_KEY = DECLARED_FLAG_ID;
17
17
 
18
18
  const { isAssistantFeatureFlagEnabled } =
@@ -56,7 +56,7 @@ describe("isAssistantFeatureFlagEnabled", () => {
56
56
 
57
57
  test("missing persisted value falls back to defaults registry defaultEnabled", () => {
58
58
  // No explicit config at all — should fall back to defaults registry
59
- // which has defaultEnabled: false for email-channel
59
+ // which has defaultEnabled: false for a2a-channel
60
60
  const config = {} as any;
61
61
 
62
62
  expect(isAssistantFeatureFlagEnabled(DECLARED_FLAG_KEY, config)).toBe(
@@ -6,10 +6,6 @@ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
6
6
 
7
7
  let mockGeminiKey: string | undefined = "test-gemini-key";
8
8
 
9
- const mkdirSyncFn = mock(() => {});
10
- const writeFileSyncFn = mock(() => {});
11
- const renameSyncFn = mock(() => {});
12
-
13
9
  let logInfoCalls: Array<[unknown, string]> = [];
14
10
  let logErrorCalls: Array<[unknown, string]> = [];
15
11
 
@@ -79,16 +75,6 @@ mock.module("pino-pretty", () => ({
79
75
  default: () => ({ write: () => true }),
80
76
  }));
81
77
 
82
- mock.module("node:fs", () => ({
83
- mkdirSync: mkdirSyncFn,
84
- writeFileSync: writeFileSyncFn,
85
- renameSync: renameSyncFn,
86
- }));
87
-
88
- mock.module("node:crypto", () => ({
89
- randomUUID: () => "00000000-0000-0000-0000-000000000000",
90
- }));
91
-
92
78
  mock.module("@google/genai", () => ({
93
79
  GoogleGenAI: class {
94
80
  models = {
@@ -105,14 +91,14 @@ mock.module("@google/genai", () => ({
105
91
  }));
106
92
 
107
93
  // Import after all mocks are set up
108
- import { generateAndSaveAvatar } from "../tools/system/avatar-generator.js";
94
+ import { generateAvatarImage } from "../tools/system/avatar-generator.js";
109
95
 
110
96
  // ---------------------------------------------------------------------------
111
97
  // Helpers
112
98
  // ---------------------------------------------------------------------------
113
99
 
114
100
  function executeAvatar(description: string) {
115
- return generateAndSaveAvatar(description);
101
+ return generateAvatarImage(description);
116
102
  }
117
103
 
118
104
  /** Standard successful Gemini generateContent response. */
@@ -135,8 +121,6 @@ function geminiContentResponse() {
135
121
  };
136
122
  }
137
123
 
138
- const expectedAvatarPath = `${process.env.VELLUM_WORKSPACE_DIR}/data/avatar/avatar-image.png`;
139
-
140
124
  // ---------------------------------------------------------------------------
141
125
  // Tests
142
126
  // ---------------------------------------------------------------------------
@@ -147,9 +131,6 @@ describe("avatar E2E integration", () => {
147
131
 
148
132
  beforeEach(() => {
149
133
  mockGeminiKey = "test-gemini-key";
150
- mkdirSyncFn.mockClear();
151
- writeFileSyncFn.mockClear();
152
- renameSyncFn.mockClear();
153
134
  geminiGenerateContentFn.mockClear();
154
135
 
155
136
  logInfoCalls = [];
@@ -174,29 +155,18 @@ describe("avatar E2E integration", () => {
174
155
  // 1. Local Gemini success
175
156
  // -----------------------------------------------------------------------
176
157
 
177
- test("local Gemini success — file written, correct content, success message", async () => {
158
+ test("local Gemini success — returns PNG bytes and success message", async () => {
178
159
  const result = await executeAvatar("a friendly robot");
179
160
 
180
161
  // Verify success message
181
162
  expect(result.isError).toBe(false);
182
163
  expect(result.content).toContain("Avatar updated");
183
164
 
184
- // Verify file was written
185
- expect(mkdirSyncFn).toHaveBeenCalledTimes(1);
186
- expect(writeFileSyncFn).toHaveBeenCalledTimes(1);
187
- expect(renameSyncFn).toHaveBeenCalledTimes(1);
188
-
189
- // Verify rename target is the expected avatar path
190
- expect((renameSyncFn.mock.calls[0] as unknown[])[1]).toBe(
191
- expectedAvatarPath,
192
- );
193
-
194
- // Verify the written buffer content matches the base64 data
195
- const writtenBuffer = (
196
- writeFileSyncFn.mock.calls[0] as unknown[]
197
- )[1] as Buffer;
165
+ // Verify the returned buffer content matches the base64 data. Persistence
166
+ // is the caller's job (the route routes these bytes through the store).
198
167
  const expectedBuffer = Buffer.from("iVBORw0KGgoAAAANSUhEUg==", "base64");
199
- expect(writtenBuffer.equals(expectedBuffer)).toBe(true);
168
+ expect(result.pngBuffer).not.toBeNull();
169
+ expect(result.pngBuffer?.equals(expectedBuffer)).toBe(true);
200
170
 
201
171
  // Verify Gemini was called
202
172
  expect(geminiGenerateContentFn).toHaveBeenCalledTimes(1);
@@ -12,10 +12,6 @@ const generateAvatarFn = mock(async () => {
12
12
  return mockRouterResult;
13
13
  });
14
14
 
15
- const mkdirSyncFn = mock(() => {});
16
- const writeFileSyncFn = mock(() => {});
17
- const renameSyncFn = mock(() => {});
18
-
19
15
  // ---------------------------------------------------------------------------
20
16
  // Mock modules — before importing module under test
21
17
  // ---------------------------------------------------------------------------
@@ -33,56 +29,51 @@ mock.module("../util/logger.js", () => ({
33
29
  }),
34
30
  }));
35
31
 
36
- mock.module("node:fs", () => ({
37
- mkdirSync: mkdirSyncFn,
38
- writeFileSync: writeFileSyncFn,
39
- renameSync: renameSyncFn,
40
- }));
41
-
42
32
  // Import after mocking
43
- import { generateAndSaveAvatar } from "../tools/system/avatar-generator.js";
33
+ import { generateAvatarImage } from "../tools/system/avatar-generator.js";
44
34
 
45
35
  // ---------------------------------------------------------------------------
46
36
  // Helpers
47
37
  // ---------------------------------------------------------------------------
48
38
 
39
+ const PNG_BASE64 = "iVBORw0KGgoAAAANSUhEUg==";
40
+
49
41
  function successResult() {
50
42
  return {
51
- imageBase64: "iVBORw0KGgoAAAANSUhEUg==",
43
+ imageBase64: PNG_BASE64,
52
44
  mimeType: "image/png",
53
45
  };
54
46
  }
55
47
 
56
48
  function executeAvatar(description: string) {
57
- return generateAndSaveAvatar(description);
49
+ return generateAvatarImage(description);
58
50
  }
59
51
 
60
52
  // ---------------------------------------------------------------------------
61
53
  // Tests
62
54
  // ---------------------------------------------------------------------------
63
55
 
64
- describe("generateAndSaveAvatar", () => {
56
+ describe("generateAvatarImage", () => {
65
57
  beforeEach(() => {
66
58
  mockRouterResult = successResult();
67
59
  mockRouterError = undefined;
68
60
  generateAvatarFn.mockClear();
69
- mkdirSyncFn.mockClear();
70
- writeFileSyncFn.mockClear();
71
- renameSyncFn.mockClear();
72
61
  });
73
62
 
74
- test("successful generation writes PNG and returns success message", async () => {
63
+ test("successful generation returns PNG bytes and success message", async () => {
75
64
  const result = await executeAvatar("a friendly purple cat");
76
65
 
77
66
  expect(result.isError).toBe(false);
78
67
  expect(result.content).toContain("Avatar updated");
68
+ expect(result.pngBuffer).toEqual(Buffer.from(PNG_BASE64, "base64"));
79
69
  expect(generateAvatarFn).toHaveBeenCalledTimes(1);
80
70
  });
81
71
 
82
- test("empty description returns error", async () => {
72
+ test("empty description returns error and no buffer", async () => {
83
73
  const result = await executeAvatar("");
84
74
 
85
75
  expect(result.isError).toBe(true);
76
+ expect(result.pngBuffer).toBeNull();
86
77
  expect(result.content).toContain("description is required");
87
78
  expect(generateAvatarFn).not.toHaveBeenCalled();
88
79
  });
@@ -93,6 +84,7 @@ describe("generateAndSaveAvatar", () => {
93
84
  const result = await executeAvatar("a cat");
94
85
 
95
86
  expect(result.isError).toBe(true);
87
+ expect(result.pngBuffer).toBeNull();
96
88
  expect(result.content).toContain("No image data returned");
97
89
  });
98
90
 
@@ -104,31 +96,9 @@ describe("generateAndSaveAvatar", () => {
104
96
  const result = await executeAvatar("a cat");
105
97
 
106
98
  expect(result.isError).toBe(true);
99
+ expect(result.pngBuffer).toBeNull();
107
100
  expect(result.content).toContain(
108
101
  "Image generation failed: Network timeout",
109
102
  );
110
103
  });
111
-
112
- test("atomic write — file is written to .tmp then renamed", async () => {
113
- await executeAvatar("a friendly cat");
114
-
115
- const expectedPath = `${process.env.VELLUM_WORKSPACE_DIR}/data/avatar/avatar-image.png`;
116
-
117
- // Verify mkdirSync was called for the directory
118
- expect(mkdirSyncFn).toHaveBeenCalledTimes(1);
119
- expect((mkdirSyncFn.mock.calls[0] as unknown[])[1]).toEqual({
120
- recursive: true,
121
- });
122
-
123
- // Verify writeFileSync writes to a unique tmp path
124
- expect(writeFileSyncFn).toHaveBeenCalledTimes(1);
125
- const tmpPath = (writeFileSyncFn.mock.calls[0] as unknown[])[0] as string;
126
- expect(tmpPath).toStartWith(expectedPath + ".");
127
- expect(tmpPath).toEndWith(".tmp");
128
-
129
- // Verify renameSync moves tmp to final path
130
- expect(renameSyncFn).toHaveBeenCalledTimes(1);
131
- expect((renameSyncFn.mock.calls[0] as unknown[])[0]).toBe(tmpPath);
132
- expect((renameSyncFn.mock.calls[0] as unknown[])[1]).toBe(expectedPath);
133
- });
134
104
  });
@@ -4,7 +4,10 @@ import { SYNC_TAGS } from "../daemon/message-types/sync.js";
4
4
  import type { AssistantEvent } from "../runtime/assistant-event.js";
5
5
  import { assistantEventHub } from "../runtime/assistant-event-hub.js";
6
6
  import { ROUTES as AVATAR_ROUTES } from "../runtime/routes/avatar-routes.js";
7
- import { publishIdentityChanged } from "../runtime/sync/resource-sync-events.js";
7
+ import {
8
+ publishIdentityChanged,
9
+ publishIdentityIntroChanged,
10
+ } from "../runtime/sync/resource-sync-events.js";
8
11
 
9
12
  async function waitFor(predicate: () => boolean): Promise<void> {
10
13
  const deadline = Date.now() + 500;
@@ -49,7 +52,7 @@ describe("avatar and identity sync events", () => {
49
52
  }
50
53
  });
51
54
 
52
- test("identity changes emit legacy identity event and sync tag", async () => {
55
+ test("identity changes emit legacy identity event and identity sync tags", async () => {
53
56
  const received: AssistantEvent[] = [];
54
57
  const subscription = assistantEventHub.subscribe({
55
58
  type: "process",
@@ -78,7 +81,29 @@ describe("avatar and identity sync events", () => {
78
81
  });
79
82
  expect(received[1].message).toEqual({
80
83
  type: "sync_changed",
81
- tags: [SYNC_TAGS.assistantIdentity],
84
+ tags: [SYNC_TAGS.assistantIdentity, SYNC_TAGS.assistantIdentityIntro],
85
+ });
86
+ } finally {
87
+ subscription.dispose();
88
+ }
89
+ });
90
+
91
+ test("identity intro changes emit only the identity intro sync tag", async () => {
92
+ const received: AssistantEvent[] = [];
93
+ const subscription = assistantEventHub.subscribe({
94
+ type: "process",
95
+ callback: (event) => {
96
+ received.push(event);
97
+ },
98
+ });
99
+
100
+ try {
101
+ publishIdentityIntroChanged();
102
+ await waitFor(() => received.length === 1);
103
+
104
+ expect(received[0].message).toEqual({
105
+ type: "sync_changed",
106
+ tags: [SYNC_TAGS.assistantIdentityIntro],
82
107
  });
83
108
  } finally {
84
109
  subscription.dispose();
@@ -2,7 +2,6 @@ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
2
2
 
3
3
  import type { WakeOptions } from "../runtime/agent-wake.js";
4
4
  import type { BackgroundTool } from "../tools/background-tool-registry.js";
5
- import type { Tool } from "../tools/types.js";
6
5
 
7
6
  // ── Mock modules ────────────────────────────────────────────────────────────
8
7
 
@@ -88,6 +87,8 @@ mock.module("../tools/background-tool-registry.js", () => ({
88
87
 
89
88
  // ── Imports (after mocks) ───────────────────────────────────────────────────
90
89
 
90
+ import { shellTool } from "../tools/terminal/shell.js";
91
+
91
92
  const baseContext = {
92
93
  workingDir: process.env.VELLUM_WORKSPACE_DIR ?? "/tmp",
93
94
  conversationId: "conv-bg-test",
@@ -117,9 +118,7 @@ function waitForWake(
117
118
  }
118
119
 
119
120
  describe("bash tool background mode", () => {
120
- let shellTool: Tool;
121
-
122
- beforeEach(async () => {
121
+ beforeEach(() => {
123
122
  mockWakeAgentForOpportunity.mockClear();
124
123
  mockRegisterBackgroundTool.mockClear();
125
124
  mockRemoveBackgroundTool.mockClear();
@@ -128,9 +127,6 @@ describe("bash tool background mode", () => {
128
127
  mockIsBackgroundToolLimitReached.mockClear();
129
128
  mockIsBackgroundToolLimitReached.mockReturnValue(false);
130
129
  registeredTools.length = 0;
131
-
132
- const mod = await import("../tools/terminal/shell.js");
133
- shellTool = mod.shellTool;
134
130
  });
135
131
 
136
132
  afterEach(() => {
@@ -131,16 +131,12 @@ import type { RouteHandlerArgs } from "../runtime/routes/types.js";
131
131
  function makeMockProvider(
132
132
  onSendMessage?: (
133
133
  messages: unknown[],
134
- tools: unknown[],
135
- systemPrompt: string | undefined,
136
- options: SendMessageOptions | undefined,
134
+ options?: SendMessageOptions,
137
135
  ) => Promise<ProviderResponse>,
138
136
  ) {
139
137
  const defaultSendMessage = async (
140
138
  _messages: unknown[],
141
- _tools: unknown[],
142
- _systemPrompt: string | undefined,
143
- options: SendMessageOptions | undefined,
139
+ options?: SendMessageOptions,
144
140
  ): Promise<ProviderResponse> => {
145
141
  options?.onEvent?.({ type: "text_delta", text: "hello" });
146
142
  return {
@@ -299,8 +295,7 @@ describe("POST /v1/btw", () => {
299
295
 
300
296
  expect(provider.sendMessage).toHaveBeenCalledTimes(1);
301
297
 
302
- const [messages, tools, systemPrompt, options] =
303
- provider.sendMessage.mock.calls[0];
298
+ const [messages, options] = provider.sendMessage.mock.calls[0];
304
299
 
305
300
  expect(messages).toHaveLength(3);
306
301
  expect(messages[0]).toEqual({
@@ -316,8 +311,8 @@ describe("POST /v1/btw", () => {
316
311
  content: [{ type: "text", text: "my question" }],
317
312
  });
318
313
 
319
- expect(tools).toEqual(MOCK_TOOLS);
320
- expect(systemPrompt).toBe(MOCK_SYSTEM_PROMPT);
314
+ expect(options!.tools).toEqual(MOCK_TOOLS);
315
+ expect(options!.systemPrompt).toBe(MOCK_SYSTEM_PROMPT);
321
316
  // Persona is resolved internally now; btw-routes no longer plumbs
322
317
  // it through to buildSystemPrompt.
323
318
  expect(mockBuildSystemPrompt).toHaveBeenCalledWith({
@@ -341,7 +336,7 @@ describe("POST /v1/btw", () => {
341
336
  await readStream(result as ReadableStream<Uint8Array>);
342
337
 
343
338
  expect(provider.sendMessage).toHaveBeenCalledTimes(1);
344
- const [, , , options] = provider.sendMessage.mock.calls[0];
339
+ const [, options] = provider.sendMessage.mock.calls[0];
345
340
  expect(options!.config!.callSite).toBe("emptyStateGreeting");
346
341
  });
347
342
 
@@ -357,7 +352,7 @@ describe("POST /v1/btw", () => {
357
352
  await readStream(result as ReadableStream<Uint8Array>);
358
353
 
359
354
  expect(provider.sendMessage).toHaveBeenCalledTimes(1);
360
- const [, , , options] = provider.sendMessage.mock.calls[0];
355
+ const [, options] = provider.sendMessage.mock.calls[0];
361
356
  expect(options!.config!.callSite).toBe("identityIntro");
362
357
  });
363
358
 
@@ -314,7 +314,7 @@ describe("addPointerMessage", () => {
314
314
  ensureConversation(convId);
315
315
  // Add a user message with guardian provenance metadata
316
316
  await addMessage(convId, "user", "hello", {
317
- provenanceTrustClass: "guardian",
317
+ metadata: { provenanceTrustClass: "guardian" },
318
318
  });
319
319
 
320
320
  let processorCalled = false;
@@ -331,7 +331,7 @@ describe("addPointerMessage", () => {
331
331
  ensureConversation(convId);
332
332
  // Add a user message with trusted_contact provenance metadata
333
333
  await addMessage(convId, "user", "hello", {
334
- provenanceTrustClass: "trusted_contact",
334
+ metadata: { provenanceTrustClass: "trusted_contact" },
335
335
  });
336
336
 
337
337
  let processorCalled = false;
@@ -346,7 +346,9 @@ describe("addPointerMessage", () => {
346
346
  test("unknown provenance trust class does not grant trusted audience", () => {
347
347
  const convId = "conv-ptr-unknown-provenance";
348
348
  ensureConversation(convId);
349
- addMessage(convId, "user", "hello", { provenanceTrustClass: "unknown" });
349
+ addMessage(convId, "user", "hello", {
350
+ metadata: { provenanceTrustClass: "unknown" },
351
+ });
350
352
 
351
353
  const processorCalled = { value: false };
352
354
  setPointerMessageProcessor(async () => {
@@ -58,7 +58,7 @@ function makeProvider(
58
58
  ): Provider {
59
59
  return {
60
60
  name,
61
- async sendMessage(_messages, _tools, _systemPrompt, options) {
61
+ async sendMessage(_messages: Message[], options?: SendMessageOptions) {
62
62
  onCall(options);
63
63
  return makeResponse(name);
64
64
  },
@@ -118,10 +118,7 @@ describe("CallSiteRoutingProvider", () => {
118
118
  );
119
119
 
120
120
  const response = await wrapped.sendMessage(
121
- DUMMY_MESSAGES,
122
- undefined,
123
- undefined,
124
- // No callSite — must hit default even though `memoryRetrieval` is
121
+ DUMMY_MESSAGES, // No callSite — must hit default even though `memoryRetrieval` is
125
122
  // configured for openai.
126
123
  { config: {} },
127
124
  );
@@ -154,7 +151,7 @@ describe("CallSiteRoutingProvider", () => {
154
151
  makeConnectionHook({ "openai-conn": altProvider }),
155
152
  );
156
153
 
157
- await wrapped.sendMessage(DUMMY_MESSAGES, undefined, undefined, {
154
+ await wrapped.sendMessage(DUMMY_MESSAGES, {
158
155
  config: { callSite: "memoryRetrieval" },
159
156
  });
160
157
 
@@ -190,12 +187,9 @@ describe("CallSiteRoutingProvider", () => {
190
187
  makeConnectionHook({ "openai-conn": altProvider }),
191
188
  );
192
189
 
193
- const response = await wrapped.sendMessage(
194
- DUMMY_MESSAGES,
195
- undefined,
196
- undefined,
197
- { config: { callSite: "memoryRetrieval" } },
198
- );
190
+ const response = await wrapped.sendMessage(DUMMY_MESSAGES, {
191
+ config: { callSite: "memoryRetrieval" },
192
+ });
199
193
 
200
194
  expect(calls.default).toBe(0);
201
195
  expect(calls.alt).toBe(1);
@@ -229,12 +223,9 @@ describe("CallSiteRoutingProvider", () => {
229
223
  async () => null,
230
224
  );
231
225
 
232
- const response = await wrapped.sendMessage(
233
- DUMMY_MESSAGES,
234
- undefined,
235
- undefined,
236
- { config: { callSite: "memoryRetrieval" } },
237
- );
226
+ const response = await wrapped.sendMessage(DUMMY_MESSAGES, {
227
+ config: { callSite: "memoryRetrieval" },
228
+ });
238
229
 
239
230
  expect(calls.default).toBe(1);
240
231
  expect(response.model).toBe("anthropic");
@@ -265,7 +256,7 @@ describe("CallSiteRoutingProvider", () => {
265
256
 
266
257
  let caught: unknown;
267
258
  try {
268
- await wrapped.sendMessage(DUMMY_MESSAGES, undefined, undefined, {
259
+ await wrapped.sendMessage(DUMMY_MESSAGES, {
269
260
  config: { callSite: "memoryRetrieval" },
270
261
  });
271
262
  } catch (err) {
@@ -301,12 +292,9 @@ describe("CallSiteRoutingProvider", () => {
301
292
  makeConnectionHook({ "openai-conn": altProvider }),
302
293
  );
303
294
 
304
- const response = await wrapped.sendMessage(
305
- DUMMY_MESSAGES,
306
- undefined,
307
- undefined,
308
- { config: { callSite: "memoryRetrieval" } },
309
- );
295
+ const response = await wrapped.sendMessage(DUMMY_MESSAGES, {
296
+ config: { callSite: "memoryRetrieval" },
297
+ });
310
298
 
311
299
  // actualProvider must reflect the alternative, not the default, so that
312
300
  // loop.ts / emitUsage / llm_call_finished log and bill the correct
@@ -346,12 +334,9 @@ describe("CallSiteRoutingProvider", () => {
346
334
  makeConnectionHook({ "openai-conn": altProvider }),
347
335
  );
348
336
 
349
- const response = await wrapped.sendMessage(
350
- DUMMY_MESSAGES,
351
- undefined,
352
- undefined,
353
- { config: { callSite: "memoryRetrieval" } },
354
- );
337
+ const response = await wrapped.sendMessage(DUMMY_MESSAGES, {
338
+ config: { callSite: "memoryRetrieval" },
339
+ });
355
340
 
356
341
  expect(response.actualProvider).toBe("openai-via-proxy");
357
342
  });
@@ -368,12 +353,9 @@ describe("CallSiteRoutingProvider", () => {
368
353
  makeConnectionHook({}),
369
354
  );
370
355
 
371
- const response = await wrapped.sendMessage(
372
- DUMMY_MESSAGES,
373
- undefined,
374
- undefined,
375
- { config: { callSite: "memoryRetrieval" } },
376
- );
356
+ const response = await wrapped.sendMessage(DUMMY_MESSAGES, {
357
+ config: { callSite: "memoryRetrieval" },
358
+ });
377
359
 
378
360
  // No alternative was resolved — actualProvider should stay unset.
379
361
  expect(response.actualProvider).toBeUndefined();
@@ -434,7 +416,7 @@ describe("CallSiteRoutingProvider", () => {
434
416
  );
435
417
 
436
418
  expect(wrapped.name).toBe("anthropic"); // idle → default
437
- await wrapped.sendMessage(DUMMY_MESSAGES, undefined, undefined, {
419
+ await wrapped.sendMessage(DUMMY_MESSAGES, {
438
420
  config: { callSite: "memoryRetrieval" },
439
421
  });
440
422
  expect(namesDuringCall).toEqual(["openai"]); // mid-call → routed provider
@@ -511,10 +493,10 @@ describe("CallSiteRoutingProvider", () => {
511
493
  );
512
494
 
513
495
  // Start both calls concurrently (do not await yet).
514
- const callA = wrapped.sendMessage(DUMMY_MESSAGES, undefined, undefined, {
496
+ const callA = wrapped.sendMessage(DUMMY_MESSAGES, {
515
497
  config: { callSite: "memoryRetrieval" }, // → openai
516
498
  });
517
- const callB = wrapped.sendMessage(DUMMY_MESSAGES, undefined, undefined, {
499
+ const callB = wrapped.sendMessage(DUMMY_MESSAGES, {
518
500
  config: { callSite: "conversationTitle" }, // → fireworks
519
501
  });
520
502
 
@@ -963,6 +963,7 @@ describe("createVellumCatalogProvider", () => {
963
963
  expect(slim!.kind).toBe("catalog");
964
964
  expect(slim!.origin).toBe("vellum");
965
965
  expect(slim!.status).toBe("available");
966
+ expect(slim!.category).toBe("knowledge");
966
967
  });
967
968
 
968
969
  test("toSlimSkill returns null for unknown skill", async () => {