@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
@@ -41,7 +41,7 @@ import {
41
41
  type SlackMessageMetadata,
42
42
  writeSlackMetadata,
43
43
  } from "../messaging/providers/slack/message-metadata.js";
44
- import { defaultPersistenceTerminal } from "../plugins/defaults/persistence.js";
44
+ import { defaultPersistenceTerminal } from "../plugins/defaults/persistence/terminal.js";
45
45
  import { DEFAULT_TIMEOUTS, runPipeline } from "../plugins/pipeline.js";
46
46
  import { getMiddlewaresFor } from "../plugins/registry.js";
47
47
  import type {
@@ -67,7 +67,10 @@ import {
67
67
  cleanAssistantContent,
68
68
  drainDirectiveDisplayBuffer,
69
69
  } from "./assistant-attachments.js";
70
- import type { AgentLoopConversationContext } from "./conversation-agent-loop.js";
70
+ import type {
71
+ AgentLoopConversationContext,
72
+ AssistantSurface,
73
+ } from "./conversation-agent-loop.js";
71
74
  import {
72
75
  buildConversationErrorMessage,
73
76
  classifyConversationError,
@@ -87,9 +90,15 @@ import type {
87
90
  WebSearchMetadata,
88
91
  WebSearchResultItem,
89
92
  } from "./message-types/web-activity.js";
93
+ import { FALLBACK_TURN_TRUST } from "./trust-context.js";
90
94
 
91
95
  const log = getLogger("agent-loop-handlers");
92
96
 
97
+ // ── Partial-persistence tunables ─────────────────────────────────────
98
+ // Debounce for mid-turn `updateContent` writes from text deltas.
99
+ // Indexer + projector still fire ONLY at `handleMessageComplete`.
100
+ const PARTIAL_PERSIST_DEBOUNCE_MS = 1000;
101
+
93
102
  /**
94
103
  * Build a {@link TurnContext} from the handler's deps for pipeline logging
95
104
  * and plugin attribution.
@@ -110,11 +119,10 @@ function buildHandlerTurnContext(deps: EventHandlerDeps): TurnContext {
110
119
  requestId: deps.reqId,
111
120
  conversationId: deps.ctx.conversationId,
112
121
  turnIndex: deps.ctx.turnCount,
113
- trust: deps.ctx.currentTurnTrustContext ??
114
- deps.ctx.trustContext ?? {
115
- sourceChannel: "vellum",
116
- trustClass: "unknown",
117
- },
122
+ trust:
123
+ deps.ctx.currentTurnTrustContext ??
124
+ deps.ctx.trustContext ??
125
+ FALLBACK_TURN_TRUST,
118
126
  };
119
127
  }
120
128
 
@@ -185,7 +193,6 @@ export interface EventHandlerState {
185
193
  readonly toolContentBlockToolNames: Map<number, string>;
186
194
  readonly directiveWarnings: string[];
187
195
  readonly toolUseIdToName: Map<string, string>;
188
- currentTurnToolNames: string[];
189
196
  /** Sticky for the whole run: this turn created/refreshed an app. */
190
197
  appBuildToolUsedThisRun: boolean;
191
198
  /** Tracks whether the first text delta has been emitted this turn for activity state transitions. */
@@ -239,6 +246,12 @@ export interface EventHandlerState {
239
246
  readonly serverToolStartedAt: Map<string, number>;
240
247
  /** Original input from server_tool_start, keyed by tool_use_id, so the complete handler can read the query. */
241
248
  readonly serverToolInputs: Map<string, Record<string, unknown>>;
249
+ /** Active debounce timer for partial persistence; `undefined` when idle. */
250
+ pendingPartialFlushTimer: ReturnType<typeof setTimeout> | undefined;
251
+ /** In-flight partial flush write awaited at finalize to avoid overwrite races. */
252
+ pendingPartialFlushPromise: Promise<void> | undefined;
253
+ /** Running mirror of the in-flight assistant message's content. */
254
+ currentMessageContent: ContentBlock[];
242
255
  }
243
256
 
244
257
  /** Immutable context shared across event handlers within a single agent loop run. */
@@ -285,7 +298,6 @@ export function createEventHandlerState(): EventHandlerState {
285
298
  toolContentBlockToolNames: new Map(),
286
299
  directiveWarnings: [],
287
300
  toolUseIdToName: new Map(),
288
- currentTurnToolNames: [],
289
301
  appBuildToolUsedThisRun: false,
290
302
  firstTextDeltaEmitted: false,
291
303
  firstThinkingDeltaEmitted: false,
@@ -299,9 +311,119 @@ export function createEventHandlerState(): EventHandlerState {
299
311
  turnStartedAt: Date.now(),
300
312
  serverToolStartedAt: new Map(),
301
313
  serverToolInputs: new Map(),
314
+ pendingPartialFlushTimer: undefined,
315
+ pendingPartialFlushPromise: undefined,
316
+ currentMessageContent: [],
302
317
  };
303
318
  }
304
319
 
320
+ // ── Partial-persistence helpers ──────────────────────────────────────
321
+
322
+ /** Canonical persisted-content build: clean → append surfaces → redact. */
323
+ function buildPersistedAssistantContent(
324
+ rawBlocks: readonly ContentBlock[],
325
+ surfaces: readonly AssistantSurface[],
326
+ ): ContentBlock[] {
327
+ const { cleanedContent } = cleanAssistantContent(rawBlocks);
328
+ const cleaned = cleanedContent as ContentBlock[];
329
+ const withSurfaces: ContentBlock[] = [...cleaned];
330
+ for (const surface of surfaces) {
331
+ withSurfaces.push({
332
+ type: "ui_surface",
333
+ surfaceId: surface.surfaceId,
334
+ surfaceType: surface.surfaceType,
335
+ title: surface.title,
336
+ data: surface.data,
337
+ actions: surface.actions,
338
+ display: surface.display,
339
+ ...(surface.persistent ? { persistent: true } : {}),
340
+ ...(surface.toolCallId ? { toolCallId: surface.toolCallId } : {}),
341
+ } as unknown as ContentBlock);
342
+ }
343
+ return withSurfaces.map((block) => {
344
+ if (block.type === "text") {
345
+ const tb = block as Extract<ContentBlock, { type: "text" }>;
346
+ return { ...tb, text: redactSecrets(tb.text) };
347
+ }
348
+ return block;
349
+ });
350
+ }
351
+
352
+ /** Append a streamed text chunk to `state.currentMessageContent`, fusing into tail text block. */
353
+ function appendTextToCurrentMessage(
354
+ state: EventHandlerState,
355
+ text: string,
356
+ ): void {
357
+ if (text.length === 0) return;
358
+ const tail = state.currentMessageContent.at(-1);
359
+ if (tail && tail.type === "text") {
360
+ tail.text = tail.text + text;
361
+ } else {
362
+ state.currentMessageContent.push({ type: "text", text });
363
+ }
364
+ }
365
+
366
+ /** Reset partial-persist accumulator and any pending flush state. Idempotent. */
367
+ function resetPartialPersistAccumulator(state: EventHandlerState): void {
368
+ if (state.pendingPartialFlushTimer !== undefined) {
369
+ clearTimeout(state.pendingPartialFlushTimer);
370
+ state.pendingPartialFlushTimer = undefined;
371
+ }
372
+ state.currentMessageContent = [];
373
+ state.pendingPartialFlushPromise = undefined;
374
+ }
375
+
376
+ /** Flush `state.currentMessageContent` to the row via the persistence pipeline. */
377
+ async function flushAccumulatedContent(
378
+ state: EventHandlerState,
379
+ deps: EventHandlerDeps,
380
+ ): Promise<void> {
381
+ const messageId = state.lastAssistantMessageId;
382
+ if (messageId === undefined) return;
383
+ if (state.currentMessageContent.length === 0) return;
384
+
385
+ const built = buildPersistedAssistantContent(state.currentMessageContent, []);
386
+ const contentJson = JSON.stringify(built);
387
+
388
+ try {
389
+ await runPipeline<PersistArgs, PersistResult>(
390
+ "persistence",
391
+ getMiddlewaresFor("persistence"),
392
+ defaultPersistenceTerminal,
393
+ {
394
+ op: "updateContent",
395
+ messageId,
396
+ content: contentJson,
397
+ },
398
+ buildHandlerTurnContext(deps),
399
+ DEFAULT_TIMEOUTS.persistence,
400
+ );
401
+ } catch (err) {
402
+ deps.rlog.warn(
403
+ { err, messageId },
404
+ "partial flush of accumulated assistant content failed; finalize at message_complete will recover",
405
+ );
406
+ }
407
+ }
408
+
409
+ /** Schedule a debounced partial flush. First-scheduled wins; no-op when timer pending. */
410
+ function schedulePartialFlush(
411
+ state: EventHandlerState,
412
+ deps: EventHandlerDeps,
413
+ ): void {
414
+ if (state.pendingPartialFlushTimer !== undefined) return;
415
+ state.pendingPartialFlushTimer = setTimeout(() => {
416
+ state.pendingPartialFlushTimer = undefined;
417
+ const flushPromise = flushAccumulatedContent(state, deps);
418
+ state.pendingPartialFlushPromise = flushPromise;
419
+ void flushPromise.finally(() => {
420
+ if (state.pendingPartialFlushPromise === flushPromise) {
421
+ state.pendingPartialFlushPromise = undefined;
422
+ }
423
+ });
424
+ }, PARTIAL_PERSIST_DEBOUNCE_MS);
425
+ }
426
+
305
427
  // ── Shared Helper ────────────────────────────────────────────────────
306
428
 
307
429
  // providerNameOverride should be supplied when the caller already knows the
@@ -545,6 +667,12 @@ export async function handleLlmCallStarted(
545
667
  )) as PersistReserveResult;
546
668
  state.lastAssistantMessageId = reserveResult.message.id;
547
669
  state.assistantRowAwaitingFinalization = true;
670
+ // Fresh row → fresh accumulator. If an earlier (failed) LLM call
671
+ // within the same run left partial state behind, the
672
+ // `assistantRowAwaitingFinalization` cleanup above already deleted
673
+ // the orphan row, so the accumulator content would point at a
674
+ // non-existent id. Reset here so the new row starts from zero.
675
+ resetPartialPersistAccumulator(state);
548
676
  deps.onEvent({
549
677
  type: "assistant_turn_start",
550
678
  messageId: reserveResult.message.id,
@@ -568,13 +696,10 @@ function handleTextDelta(
568
696
  if (drained.emitText.length > 0) {
569
697
  if (!state.firstTextDeltaEmitted) {
570
698
  state.firstTextDeltaEmitted = true;
571
- deps.ctx.emitActivityState(
572
- "streaming",
573
- "first_text_delta",
574
- "assistant_turn",
575
- deps.reqId,
576
- "Thinking",
577
- );
699
+ deps.ctx.emitActivityState("streaming", "first_text_delta", {
700
+ requestId: deps.reqId,
701
+ statusText: "Thinking",
702
+ });
578
703
  }
579
704
  deps.onEvent({
580
705
  type: "assistant_text_delta",
@@ -583,6 +708,10 @@ function handleTextDelta(
583
708
  messageId: state.lastAssistantMessageId,
584
709
  });
585
710
  if (deps.shouldGenerateTitle) state.firstAssistantText += drained.emitText;
711
+ // Mirror the drained delta into state.currentMessageContent so partial
712
+ // flushes mid-turn see the same content the user is watching live.
713
+ appendTextToCurrentMessage(state, drained.emitText);
714
+ schedulePartialFlush(state, deps);
586
715
  }
587
716
  }
588
717
 
@@ -603,13 +732,10 @@ function handleThinkingDelta(
603
732
  // assistantStatusText for every assistant_activity_state event.
604
733
  if (lastToolName) {
605
734
  const statusText = `Processing ${friendlyToolName(lastToolName)} results`;
606
- deps.ctx.emitActivityState(
607
- "thinking",
608
- "thinking_delta",
609
- "assistant_turn",
610
- deps.reqId,
735
+ deps.ctx.emitActivityState("thinking", "thinking_delta", {
736
+ requestId: deps.reqId,
611
737
  statusText,
612
- );
738
+ });
613
739
  }
614
740
  }
615
741
  if (!deps.ctx.streamThinking) return;
@@ -628,7 +754,6 @@ export function handleToolUse(
628
754
  event: Extract<AgentEvent, { type: "tool_use" }>,
629
755
  ): void {
630
756
  state.toolUseIdToName.set(event.id, event.name);
631
- state.currentTurnToolNames.push(event.name);
632
757
  if (event.name === "app_create" || event.name === "app_refresh") {
633
758
  state.appBuildToolUsedThisRun = true;
634
759
  }
@@ -636,13 +761,10 @@ export function handleToolUse(
636
761
  state.currentToolUseId = event.id;
637
762
  state.currentTurnToolUseIds.push(event.id);
638
763
  const statusText = computeToolUseStatusText(event.name, event.input);
639
- deps.ctx.emitActivityState(
640
- "tool_running",
641
- "tool_use_start",
642
- "assistant_turn",
643
- deps.reqId,
764
+ deps.ctx.emitActivityState("tool_running", "tool_use_start", {
765
+ requestId: deps.reqId,
644
766
  statusText,
645
- );
767
+ });
646
768
  deps.onEvent({
647
769
  type: "tool_use_start",
648
770
  toolName: event.name,
@@ -666,13 +788,10 @@ export function handleToolUsePreviewStart(
666
788
  messageId: state.lastAssistantMessageId,
667
789
  });
668
790
  const statusText = `Preparing ${friendlyToolName(event.toolName)}...`;
669
- deps.ctx.emitActivityState(
670
- "tool_running",
671
- "preview_start",
672
- "assistant_turn",
673
- deps.reqId,
791
+ deps.ctx.emitActivityState("tool_running", "preview_start", {
792
+ requestId: deps.reqId,
674
793
  statusText,
675
- );
794
+ });
676
795
  }
677
796
 
678
797
  function handleToolOutputChunk(
@@ -860,13 +979,10 @@ export function handleToolResult(
860
979
  const statusText = `Processing ${friendlyToolName(
861
980
  state.lastCompletedToolName ?? "",
862
981
  )} results`;
863
- deps.ctx.emitActivityState(
864
- "thinking",
865
- "tool_result_received",
866
- "assistant_turn",
867
- deps.reqId,
982
+ deps.ctx.emitActivityState("thinking", "tool_result_received", {
983
+ requestId: deps.reqId,
868
984
  statusText,
869
- );
985
+ });
870
986
 
871
987
  // Once all tools for this turn have completed, annotate the persisted
872
988
  // assistant message with timing and confirmation metadata.
@@ -998,6 +1114,7 @@ function annotatePersistedAssistantMessage(
998
1114
  actions: surface.actions,
999
1115
  display: surface.display,
1000
1116
  ...(surface.persistent ? { persistent: true } : {}),
1117
+ ...(surface.toolCallId ? { toolCallId: surface.toolCallId } : {}),
1001
1118
  } as unknown as ContentBlock);
1002
1119
  }
1003
1120
  modified = true;
@@ -1145,6 +1262,29 @@ export async function handleMessageComplete(
1145
1262
  // Reset per-turn tool tracking for the new turn.
1146
1263
  state.currentTurnToolUseIds = [];
1147
1264
 
1265
+ // Cancel any pending debounced partial flush and await an already
1266
+ // in-flight one before the authoritative `updateContent` below.
1267
+ // Without the timer-clear, a timer that fires during this handler
1268
+ // could double-write (idempotent in content but wastes a write) or
1269
+ // race ahead of the indexer/projector and serve a stale snapshot.
1270
+ // Without the await, a partial pipeline call that was dispatched a
1271
+ // moment before this handler can settle AFTER the final write and
1272
+ // overwrite the authoritative row.
1273
+ if (state.pendingPartialFlushTimer !== undefined) {
1274
+ clearTimeout(state.pendingPartialFlushTimer);
1275
+ state.pendingPartialFlushTimer = undefined;
1276
+ }
1277
+ if (state.pendingPartialFlushPromise !== undefined) {
1278
+ try {
1279
+ await state.pendingPartialFlushPromise;
1280
+ } catch {
1281
+ // The partial flush swallows its own pipeline errors via
1282
+ // `rlog.warn`; the `try`/`catch` here is defensive against
1283
+ // future changes that might surface them.
1284
+ }
1285
+ state.pendingPartialFlushPromise = undefined;
1286
+ }
1287
+
1148
1288
  // Flush any remaining directive display buffer
1149
1289
  if (state.pendingDirectiveDisplayBuffer.length > 0) {
1150
1290
  deps.onEvent({
@@ -1215,13 +1355,14 @@ export async function handleMessageComplete(
1215
1355
  state.pendingToolResults.clear();
1216
1356
  }
1217
1357
 
1218
- // Clean assistant content and accumulate directives
1219
- const {
1220
- cleanedContent,
1221
- directives: msgDirectives,
1222
- warnings: msgWarnings,
1223
- } = cleanAssistantContent(event.message.content);
1224
- const cleanedBlocks = cleanedContent as ContentBlock[];
1358
+ // Accumulate directives + warnings from the assistant content for
1359
+ // downstream attachment processing. `cleanAssistantContent` is also
1360
+ // called inside {@link buildPersistedAssistantContent} below; running
1361
+ // it here separately is the cheapest way to keep the directive
1362
+ // side-effects local to this handler while letting the shared helper
1363
+ // own the persisted-content shape.
1364
+ const { directives: msgDirectives, warnings: msgWarnings } =
1365
+ cleanAssistantContent(event.message.content);
1225
1366
  state.accumulatedDirectives.push(...msgDirectives);
1226
1367
  state.directiveWarnings.push(...msgWarnings);
1227
1368
  if (msgDirectives.length > 0) {
@@ -1243,31 +1384,14 @@ export async function handleMessageComplete(
1243
1384
  // are applied in handleToolResult after all tools for the turn complete,
1244
1385
  // then the persisted message is updated via updateMessageContent.
1245
1386
 
1246
- // Build content with UI surfaces
1247
- const contentWithSurfaces: ContentBlock[] = [...cleanedBlocks];
1248
- for (const surface of deps.ctx.currentTurnSurfaces) {
1249
- contentWithSurfaces.push({
1250
- type: "ui_surface",
1251
- surfaceId: surface.surfaceId,
1252
- surfaceType: surface.surfaceType,
1253
- title: surface.title,
1254
- data: surface.data,
1255
- actions: surface.actions,
1256
- display: surface.display,
1257
- ...(surface.persistent ? { persistent: true } : {}),
1258
- } as unknown as ContentBlock);
1259
- }
1260
-
1261
- // Redact known-pattern secrets from assistant text blocks before they are
1262
- // written to durable storage. Non-text blocks (images, UI surfaces) pass
1263
- // through unchanged. The live model history retains the original values.
1264
- const contentForPersistence = contentWithSurfaces.map((block) => {
1265
- if (block.type === "text") {
1266
- const tb = block as Extract<ContentBlock, { type: "text" }>;
1267
- return { ...tb, text: redactSecrets(tb.text) };
1268
- }
1269
- return block;
1270
- });
1387
+ // Build the canonical persisted content (cleaned + surfaces +
1388
+ // redacted) via the shared helper. The partial-persist flush uses
1389
+ // the same helper with `surfaces=[]` so a mid-turn snapshot lands in
1390
+ // the same shape as the finalize.
1391
+ const contentForPersistence = buildPersistedAssistantContent(
1392
+ event.message.content as ContentBlock[],
1393
+ deps.ctx.currentTurnSurfaces,
1394
+ );
1271
1395
 
1272
1396
  // The row was reserved at `llm_call_started` (with channel metadata
1273
1397
  // stamped at that point) and `state.lastAssistantMessageId` carries its
@@ -1296,6 +1420,9 @@ export async function handleMessageComplete(
1296
1420
  DEFAULT_TIMEOUTS.persistence,
1297
1421
  );
1298
1422
  state.assistantRowAwaitingFinalization = false;
1423
+ // Reset the partial-persist mirror so subsequent calls in this turn
1424
+ // start with an empty running view.
1425
+ state.currentMessageContent = [];
1299
1426
 
1300
1427
  // ── Indexing + attention projection (restored from the pre-B3 `add` path) ──
1301
1428
  // `reserveMessage` + `updateMessageContent` are CRUD-only: they don't run
@@ -1419,8 +1546,10 @@ export async function handleMessageComplete(
1419
1546
 
1420
1547
  deps.ctx.currentTurnSurfaces = [];
1421
1548
 
1422
- // Emit trace event
1423
- const charCount = cleanedBlocks
1549
+ // Emit trace event. Char count is computed from the cleaned +
1550
+ // redacted text blocks (UI surface blocks filtered out via the
1551
+ // type guard) — same shape as what was just persisted.
1552
+ const charCount = contentForPersistence
1424
1553
  .filter(
1425
1554
  (b): b is Extract<ContentBlock, { type: "text" }> => b.type === "text",
1426
1555
  )
@@ -1636,13 +1765,10 @@ export async function dispatchAgentEvent(
1636
1765
  const query =
1637
1766
  typeof event.input.query === "string" ? event.input.query : "";
1638
1767
  const statusText = formatSearchStatusText(event.name, query);
1639
- deps.ctx.emitActivityState(
1640
- "tool_running",
1641
- "tool_use_start",
1642
- "assistant_turn",
1643
- deps.reqId,
1768
+ deps.ctx.emitActivityState("tool_running", "tool_use_start", {
1769
+ requestId: deps.reqId,
1644
1770
  statusText,
1645
- );
1771
+ });
1646
1772
  state.serverToolStartedAt.set(event.toolUseId, Date.now());
1647
1773
  state.serverToolInputs.set(event.toolUseId, event.input);
1648
1774
  deps.onEvent({
@@ -1656,13 +1782,10 @@ export async function dispatchAgentEvent(
1656
1782
  break;
1657
1783
  }
1658
1784
  case "server_tool_complete": {
1659
- deps.ctx.emitActivityState(
1660
- "streaming",
1661
- "tool_result_received",
1662
- "assistant_turn",
1663
- deps.reqId,
1664
- "Thinking",
1665
- );
1785
+ deps.ctx.emitActivityState("streaming", "tool_result_received", {
1786
+ requestId: deps.reqId,
1787
+ statusText: "Thinking",
1788
+ });
1666
1789
 
1667
1790
  // Prefer `resolvedInput` (Anthropic's accumulated server-tool input,
1668
1791
  // populated on content_block_stop) over the input captured at
@@ -1736,6 +1859,20 @@ export async function dispatchAgentEvent(
1736
1859
  });
1737
1860
  break;
1738
1861
  }
1862
+ case "context_compacting":
1863
+ deps.ctx.emitActivityState("thinking", "context_compacting", {
1864
+ requestId: deps.reqId,
1865
+ statusText: "Compacting context",
1866
+ });
1867
+ break;
1868
+ case "compaction_circuit_open":
1869
+ case "compaction_circuit_closed":
1870
+ // Circuit-breaker transitions are already in wire-contract shape
1871
+ // (a subset of ServerMessage), so forward them to the client sink
1872
+ // unchanged. They drive the client's "auto-compaction paused"
1873
+ // banner.
1874
+ deps.onEvent(event);
1875
+ break;
1739
1876
  case "error":
1740
1877
  handleError(state, deps, event);
1741
1878
  break;