@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
@@ -14,14 +14,26 @@
14
14
  import { createRequire } from "node:module";
15
15
  import { afterAll, beforeEach, describe, expect, mock, test } from "bun:test";
16
16
 
17
+ import { CompactionCircuit } from "../agent/compaction-circuit.js";
17
18
  import type {
18
19
  AgentEvent,
19
- CheckpointDecision,
20
- CheckpointInfo,
20
+ AgentLoopRunOptions,
21
+ AgentLoopRunResult,
22
+ MidLoopCompaction,
21
23
  } from "../agent/loop.js";
22
24
  import type { LLMConfig } from "../config/schemas/llm.js";
25
+ import type { ContextWindowResult } from "../context/window-manager.js";
23
26
  import type { ServerMessage } from "../daemon/message-protocol.js";
27
+ import { defaultCompactionTerminal } from "../plugins/defaults/compaction/terminal.js";
24
28
  import { resetPluginRegistryAndRegisterDefaults } from "../plugins/defaults/index.js";
29
+ import { DEFAULT_TIMEOUTS, runPipeline } from "../plugins/pipeline.js";
30
+ import { getMiddlewaresFor } from "../plugins/registry.js";
31
+ import type {
32
+ CompactionArgs,
33
+ CompactionResult,
34
+ TurnContext,
35
+ } from "../plugins/types.js";
36
+ import { PluginTimeoutError } from "../plugins/types.js";
25
37
  import type { ContentBlock, Message } from "../providers/types.js";
26
38
 
27
39
  const conversationCrudRealSnapshot = {
@@ -291,7 +303,7 @@ mock.module("../daemon/date-context.js", () => ({
291
303
  formatTurnTimestamp: () => "2026-01-01 (Thursday) 00:00:00 +00:00 (UTC)",
292
304
  }));
293
305
 
294
- mock.module("../daemon/history-repair.js", () => ({
306
+ mock.module("../plugins/defaults/history-repair/terminal.js", () => ({
295
307
  repairHistory: (msgs: Message[]) => ({
296
308
  messages: msgs,
297
309
  stats: {
@@ -435,13 +447,153 @@ import {
435
447
  type AgentLoopRun = (
436
448
  messages: Message[],
437
449
  onEvent: (event: AgentEvent) => void,
438
- signal?: AbortSignal,
439
- requestId?: string,
440
- onCheckpoint?: (
441
- checkpoint: CheckpointInfo,
442
- ) => CheckpointDecision | Promise<CheckpointDecision>,
450
+ options?: AgentLoopRunOptions,
443
451
  ) => Promise<Message[]>;
444
452
 
453
+ /**
454
+ * Faithful re-implementation of `AgentLoop.compact()` for the mock loop: run
455
+ * the compaction pipeline against the supplied turn context (which carries the
456
+ * test's `contextWindowManager`), invoke the orchestrator-supplied hooks, and
457
+ * return the continuation history — or `null` on timeout/exhaustion so the
458
+ * caller yields "budget".
459
+ */
460
+ async function simulateInlineCompaction(
461
+ compaction: MidLoopCompaction,
462
+ history: Message[],
463
+ turnContext: TurnContext | undefined,
464
+ signal: AbortSignal | undefined,
465
+ onEvent: (event: AgentEvent) => void | Promise<void>,
466
+ compactionCircuit: CompactionCircuit,
467
+ ): Promise<Message[] | null> {
468
+ await onEvent({ type: "context_compacting" });
469
+ const { rawHistory, options } = compaction.prepare(history);
470
+ let result: CompactionResult;
471
+ try {
472
+ result = await runPipeline<CompactionArgs, CompactionResult>(
473
+ "compaction",
474
+ getMiddlewaresFor("compaction"),
475
+ (args) => defaultCompactionTerminal(args, turnContext as TurnContext),
476
+ { messages: rawHistory, signal, options },
477
+ turnContext as TurnContext,
478
+ DEFAULT_TIMEOUTS.compaction,
479
+ );
480
+ } catch (error) {
481
+ if (error instanceof PluginTimeoutError) {
482
+ await compactionCircuit.recordOutcome(
483
+ {
484
+ currentRequestId: turnContext?.requestId,
485
+ currentTurnTrustContext: turnContext?.trust,
486
+ turnCount: turnContext?.turnIndex ?? 0,
487
+ },
488
+ true,
489
+ onEvent,
490
+ );
491
+ return null;
492
+ }
493
+ throw error;
494
+ }
495
+ const compactResult = result as ContextWindowResult;
496
+ if (compactResult.summaryFailed !== undefined) {
497
+ await compactionCircuit.recordOutcome(
498
+ {
499
+ currentRequestId: turnContext?.requestId,
500
+ currentTurnTrustContext: turnContext?.trust,
501
+ turnCount: turnContext?.turnIndex ?? 0,
502
+ },
503
+ compactResult.summaryFailed,
504
+ onEvent,
505
+ );
506
+ }
507
+ if (compactResult.compacted) {
508
+ await compaction.applyResult(compactResult, rawHistory);
509
+ }
510
+ if (compactResult.exhausted ?? false) {
511
+ return null;
512
+ }
513
+ return compaction.reinject();
514
+ }
515
+
516
+ /**
517
+ * Adapt a `Message[]`-returning mock loop body into `run()`'s real result
518
+ * shape. Mirrors the production loop: the pause-reason carried back is
519
+ * whatever the most recent `onCheckpoint` call yielded with (null when it
520
+ * never yielded), so the orchestrator derives its yield bookkeeping the same
521
+ * way it does against the real loop.
522
+ */
523
+ const asAgentLoopRun = (
524
+ fn: AgentLoopRun,
525
+ compactionCircuit: CompactionCircuit,
526
+ ): ((
527
+ messages: Message[],
528
+ onEvent: (event: AgentEvent) => void | Promise<void>,
529
+ options?: AgentLoopRunOptions,
530
+ ) => Promise<AgentLoopRunResult>) => {
531
+ return async (messages, onEvent, options) => {
532
+ let exitReason: AgentLoopRunResult["exitReason"] = null;
533
+ let wrapped = options;
534
+ if (options?.onCheckpoint) {
535
+ const inner = options.onCheckpoint;
536
+ wrapped = {
537
+ ...options,
538
+ onCheckpoint: async (info) => {
539
+ // Handoff is offered first, mirroring the loop's ordering.
540
+ const decision = await inner(info);
541
+ if (decision !== "continue") {
542
+ exitReason = decision;
543
+ return decision;
544
+ }
545
+ // The mid-loop budget gate and inline compaction both live inside
546
+ // `AgentLoop.run`. Replicate them here — same formula, stubbed
547
+ // estimator, and the loop's own `compact()` ceremony — so these
548
+ // orchestrator tests drive the real escalation path now that the
549
+ // orchestrator's `onCheckpoint` is handoff-only and compaction
550
+ // runs inline rather than via an orchestrator re-entry loop.
551
+ const contextWindow = options.resolveContextWindow?.();
552
+ if (contextWindow?.overflowRecovery.enabled) {
553
+ const { maxInputTokens, overflowRecovery } = contextWindow;
554
+ const safetyMargin =
555
+ info.history.length > 50
556
+ ? Math.max(overflowRecovery.safetyMarginRatio, 0.15)
557
+ : overflowRecovery.safetyMarginRatio;
558
+ const preflightBudget = Math.floor(
559
+ maxInputTokens * (1 - safetyMargin),
560
+ );
561
+ const estimated =
562
+ typeof mockEstimateTokens === "function"
563
+ ? mockEstimateTokens(info.history)
564
+ : mockEstimateTokens;
565
+ if (estimated > preflightBudget * 0.85) {
566
+ // Mirror `AgentLoop.compact()`: when a compaction path is
567
+ // supplied, run it in place and continue; on timeout or
568
+ // exhaustion it returns null, so the loop yields "budget".
569
+ const compacted = options.compaction
570
+ ? await simulateInlineCompaction(
571
+ options.compaction,
572
+ info.history,
573
+ options.turnContext,
574
+ options.signal,
575
+ onEvent,
576
+ compactionCircuit,
577
+ )
578
+ : null;
579
+ if (compacted) {
580
+ exitReason = null;
581
+ return "continue";
582
+ }
583
+ exitReason = "budget";
584
+ return "budget";
585
+ }
586
+ }
587
+ exitReason = null;
588
+ return "continue";
589
+ },
590
+ };
591
+ }
592
+ const history = await fn(messages, onEvent, wrapped);
593
+ return { history, exitReason };
594
+ };
595
+ };
596
+
445
597
  function makeCtx(
446
598
  overrides?: Partial<AgentLoopConversationContext> & {
447
599
  agentLoopRun?: AgentLoopRun;
@@ -457,6 +609,8 @@ function makeCtx(
457
609
  },
458
610
  ]);
459
611
 
612
+ const compactionCircuit = new CompactionCircuit("test-conv");
613
+
460
614
  return {
461
615
  conversationId: "test-conv",
462
616
  messages: [
@@ -467,13 +621,14 @@ function makeCtx(
467
621
  currentRequestId: "test-req",
468
622
 
469
623
  agentLoop: {
470
- run: agentLoopRun,
624
+ run: asAgentLoopRun(agentLoopRun, compactionCircuit),
471
625
  getToolTokenBudget: () => 0,
472
626
  getResolvedTools: () => [],
473
627
  // Tests in this file don't exercise calibration, so returning
474
628
  // undefined is fine — the estimator falls back to the per-provider
475
629
  // aggregate key.
476
630
  getActiveModel: () => undefined,
631
+ compactionCircuit,
477
632
  } as unknown as AgentLoopConversationContext["agentLoop"],
478
633
  provider: {
479
634
  name: "mock-provider",
@@ -1449,13 +1604,7 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
1449
1604
  };
1450
1605
 
1451
1606
  let agentLoopCallCount = 0;
1452
- const agentLoopRun: AgentLoopRun = async (
1453
- messages,
1454
- onEvent,
1455
- _signal,
1456
- _requestId,
1457
- onCheckpoint,
1458
- ) => {
1607
+ const agentLoopRun: AgentLoopRun = async (messages, onEvent, options) => {
1459
1608
  // Prime the assistant row anchor — production code emits this from
1460
1609
  // `AgentLoop.run` just before `provider.sendMessage`.
1461
1610
  await onEvent({ type: "llm_call_started" });
@@ -1515,14 +1664,14 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
1515
1664
 
1516
1665
  // Call onCheckpoint — this should trigger the mid-loop budget check
1517
1666
  // which sees 170_000 > 161_500 and returns "yield"
1518
- if (onCheckpoint) {
1519
- const decision = await onCheckpoint({
1667
+ if (options?.onCheckpoint) {
1668
+ const decision = await options.onCheckpoint({
1520
1669
  turnIndex: 0,
1521
1670
  toolCount: 1,
1522
1671
  hasToolUse: true,
1523
1672
  history: withProgress,
1524
1673
  });
1525
- if (decision === "yield") {
1674
+ if (decision !== "continue") {
1526
1675
  // Agent loop stops when checkpoint yields
1527
1676
  return withProgress;
1528
1677
  }
@@ -1637,13 +1786,7 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
1637
1786
  let agentLoopCallCount = 0;
1638
1787
  let contextTooLargeEmitted = false;
1639
1788
 
1640
- const agentLoopRun: AgentLoopRun = async (
1641
- messages,
1642
- onEvent,
1643
- _signal,
1644
- _requestId,
1645
- onCheckpoint,
1646
- ) => {
1789
+ const agentLoopRun: AgentLoopRun = async (messages, onEvent, options) => {
1647
1790
  // Prime the assistant row anchor — production code emits this from
1648
1791
  // `AgentLoop.run` just before `provider.sendMessage`.
1649
1792
  await onEvent({ type: "llm_call_started" });
@@ -1692,14 +1835,14 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
1692
1835
  providerDurationMs: 100,
1693
1836
  });
1694
1837
 
1695
- if (onCheckpoint) {
1696
- const decision = await onCheckpoint({
1838
+ if (options?.onCheckpoint) {
1839
+ const decision = await options.onCheckpoint({
1697
1840
  turnIndex: i,
1698
1841
  toolCount: 1,
1699
1842
  hasToolUse: true,
1700
1843
  history: currentHistory,
1701
1844
  });
1702
- if (decision === "yield") {
1845
+ if (decision !== "continue") {
1703
1846
  return currentHistory;
1704
1847
  }
1705
1848
  }
@@ -1815,13 +1958,7 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
1815
1958
  };
1816
1959
 
1817
1960
  let agentLoopCallCount = 0;
1818
- const agentLoopRun: AgentLoopRun = async (
1819
- messages,
1820
- onEvent,
1821
- _signal,
1822
- _requestId,
1823
- onCheckpoint,
1824
- ) => {
1961
+ const agentLoopRun: AgentLoopRun = async (messages, onEvent, options) => {
1825
1962
  // Prime the assistant row anchor — production code emits this from
1826
1963
  // `AgentLoop.run` just before `provider.sendMessage`.
1827
1964
  await onEvent({ type: "llm_call_started" });
@@ -1879,14 +2016,14 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
1879
2016
  });
1880
2017
 
1881
2018
  // Always yield at checkpoint — simulates compaction not helping
1882
- if (onCheckpoint) {
1883
- const decision = await onCheckpoint({
2019
+ if (options?.onCheckpoint) {
2020
+ const decision = await options.onCheckpoint({
1884
2021
  turnIndex: 0,
1885
2022
  toolCount: 1,
1886
2023
  hasToolUse: true,
1887
2024
  history: withProgress,
1888
2025
  });
1889
- if (decision === "yield") {
2026
+ if (decision !== "continue") {
1890
2027
  return withProgress;
1891
2028
  }
1892
2029
  }
@@ -1917,9 +2054,15 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
1917
2054
  shouldCompact: () => ({ needed: false, estimatedTokens: 0 }),
1918
2055
  maybeCompact: async () => {
1919
2056
  compactionCallCount++;
1920
- // Compaction "succeeds" but doesn't actually shrink enough
2057
+ // Compaction's internal retry budget is exhausted — the
2058
+ // compactor itself ran maxAttempts passes and still couldn't
2059
+ // drop below the auto-threshold. `maybeCompact` surfaces this
2060
+ // via `exhausted: true` so the orchestrator escalates
2061
+ // straight to the convergence loop instead of looping on a
2062
+ // stuck compactor.
1921
2063
  return {
1922
2064
  compacted: true,
2065
+ exhausted: true,
1923
2066
  messages: [
1924
2067
  {
1925
2068
  role: "user" as const,
@@ -1944,14 +2087,20 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
1944
2087
 
1945
2088
  await runAgentLoopImpl(ctx, "hello", "msg-1", (msg) => events.push(msg));
1946
2089
 
1947
- // 1 initial auto-compact + 3 mid-loop compaction attempts = 4 total
1948
- expect(compactionCallCount).toBe(4);
2090
+ // 1 initial auto-compact + 1 mid-loop compaction = 2 total. The
2091
+ // first mid-loop call surfaces `exhausted: true`, so the
2092
+ // orchestrator escalates immediately without retrying maybeCompact
2093
+ // — the retry budget for the compactor itself lives inside
2094
+ // `ContextWindowManager.maybeCompact`.
2095
+ expect(compactionCallCount).toBe(2);
1949
2096
 
1950
- // Agent loop: 1 initial + 3 mid-loop re-entries + 1 convergence re-run = 5 calls
1951
- expect(agentLoopCallCount).toBe(5);
2097
+ // Agent loop: 1 initial + 1 convergence re-run = 2 calls. No
2098
+ // mid-loop re-entries because the orchestrator broke out on
2099
+ // `exhausted` before re-invoking the agent loop.
2100
+ expect(agentLoopCallCount).toBe(2);
1952
2101
 
1953
- // After exhausting mid-loop attempts, the convergence loop should
1954
- // have been triggered (contextTooLargeDetected set to true)
2102
+ // After the compactor exhausted itself, the convergence loop
2103
+ // should have been triggered (contextTooLargeDetected set to true)
1955
2104
  expect(convergenceReducerCalled).toBe(true);
1956
2105
  expect(setAgentLoopExitReasonOnLatestLogMock).toHaveBeenCalledWith(
1957
2106
  "test-conv",
@@ -1959,6 +2108,151 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
1959
2108
  );
1960
2109
  });
1961
2110
 
2111
+ // ── Test 8b ───────────────────────────────────────────────────────
2112
+ // Counterpart to Test 8: when a mid-loop `maybeCompact` returns
2113
+ // productive (`compacted: true`, no `exhausted` flag), the loop
2114
+ // compacts in place and continues the run itself — it never yields
2115
+ // "budget", so the orchestrator does not escalate to the convergence
2116
+ // loop. Mid-loop iteration is now wholly internal to `AgentLoop.run`;
2117
+ // the orchestrator only reacts to the binary `exhausted`/timeout
2118
+ // signal carried back as a "budget" exit.
2119
+ test("productive mid-loop compaction continues in place without escalating", async () => {
2120
+ const events: ServerMessage[] = [];
2121
+
2122
+ // Budget = 200_000 * 0.95 = 190_000
2123
+ // Mid-loop threshold = 190_000 * 0.85 = 161_500
2124
+ let estimateCallCount = 0;
2125
+ mockEstimateTokens = () => {
2126
+ estimateCallCount++;
2127
+ // Preflight: below budget.
2128
+ if (estimateCallCount === 1) return 100_000;
2129
+ // Every checkpoint estimate: above threshold — always trips the
2130
+ // yield. Simulates a long turn where each tool call's result
2131
+ // inflates the context past 85% even after a successful compaction.
2132
+ return 170_000;
2133
+ };
2134
+
2135
+ // A single tool round reaches one checkpoint; the in-loop budget
2136
+ // gate trips there and compaction runs in place. The loop continues
2137
+ // the run itself rather than handing control back, so the
2138
+ // orchestrator invokes `run()` exactly once.
2139
+ let agentLoopCallCount = 0;
2140
+ const agentLoopRun: AgentLoopRun = async (messages, onEvent, options) => {
2141
+ await onEvent({ type: "llm_call_started" });
2142
+ agentLoopCallCount++;
2143
+
2144
+ const withProgress: Message[] = [
2145
+ ...messages,
2146
+ {
2147
+ role: "assistant" as const,
2148
+ content: [
2149
+ { type: "text", text: `Tool call ${agentLoopCallCount}` },
2150
+ {
2151
+ type: "tool_use",
2152
+ id: `tu-${agentLoopCallCount}`,
2153
+ name: "bash",
2154
+ input: { command: "ls" },
2155
+ },
2156
+ ] as ContentBlock[],
2157
+ },
2158
+ {
2159
+ role: "user" as const,
2160
+ content: [
2161
+ {
2162
+ type: "tool_result",
2163
+ tool_use_id: `tu-${agentLoopCallCount}`,
2164
+ content: "output",
2165
+ is_error: false,
2166
+ },
2167
+ ] as ContentBlock[],
2168
+ },
2169
+ ];
2170
+
2171
+ onEvent({
2172
+ type: "message_complete",
2173
+ message: {
2174
+ role: "assistant",
2175
+ content: [
2176
+ { type: "text", text: `Tool call ${agentLoopCallCount}` },
2177
+ {
2178
+ type: "tool_use",
2179
+ id: `tu-${agentLoopCallCount}`,
2180
+ name: "bash",
2181
+ input: { command: "ls" },
2182
+ },
2183
+ ],
2184
+ },
2185
+ });
2186
+ onEvent({
2187
+ type: "usage",
2188
+ inputTokens: 100,
2189
+ outputTokens: 50,
2190
+ model: "test-model",
2191
+ providerDurationMs: 100,
2192
+ });
2193
+
2194
+ if (options?.onCheckpoint) {
2195
+ await options.onCheckpoint({
2196
+ turnIndex: 0,
2197
+ toolCount: 1,
2198
+ hasToolUse: true,
2199
+ history: withProgress,
2200
+ });
2201
+ }
2202
+
2203
+ return withProgress;
2204
+ };
2205
+
2206
+ // Compaction reports `estimatedInputTokens` well below the 161_500
2207
+ // threshold — the "compaction is productive" signal (no `exhausted`
2208
+ // flag) that lets the loop continue in place.
2209
+ let compactionCallCount = 0;
2210
+ const ctx = makeCtx({
2211
+ agentLoopRun,
2212
+ contextWindowManager: {
2213
+ shouldCompact: () => ({ needed: false, estimatedTokens: 0 }),
2214
+ maybeCompact: async () => {
2215
+ compactionCallCount++;
2216
+ return {
2217
+ compacted: true,
2218
+ messages: [
2219
+ {
2220
+ role: "user" as const,
2221
+ content: [{ type: "text", text: "Hello" }],
2222
+ },
2223
+ ] as Message[],
2224
+ compactedPersistedMessages: 5,
2225
+ summaryText: "Compaction summary",
2226
+ previousEstimatedInputTokens: 170_000,
2227
+ estimatedInputTokens: 100_000,
2228
+ maxInputTokens: 200_000,
2229
+ thresholdTokens: 160_000,
2230
+ compactedMessages: 10,
2231
+ summaryCalls: 1,
2232
+ summaryInputTokens: 500,
2233
+ summaryOutputTokens: 200,
2234
+ summaryModel: "mock-model",
2235
+ };
2236
+ },
2237
+ } as unknown as AgentLoopConversationContext["contextWindowManager"],
2238
+ });
2239
+
2240
+ await runAgentLoopImpl(ctx, "hello", "msg-1", (msg) => events.push(msg));
2241
+
2242
+ // 1 initial auto-compact + 1 productive mid-loop compaction. The
2243
+ // loop continues in place after compacting, so the orchestrator
2244
+ // never re-enters `run()` — it is invoked exactly once.
2245
+ expect(compactionCallCount).toBe(2);
2246
+ expect(agentLoopCallCount).toBe(1);
2247
+
2248
+ // No escalation to the convergence loop because the mid-loop
2249
+ // `maybeCompact` returned productive (no `exhausted` flag).
2250
+ expect(setAgentLoopExitReasonOnLatestLogMock).not.toHaveBeenCalledWith(
2251
+ "test-conv",
2252
+ "context_too_large",
2253
+ );
2254
+ });
2255
+
1962
2256
  // ── Test 9 ────────────────────────────────────────────────────────
1963
2257
  // When the convergence loop reruns the agent loop and it still yields
1964
2258
  // at checkpoint (yieldedForBudget), the loop must continue reducing
@@ -1979,13 +2273,7 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
1979
2273
  };
1980
2274
 
1981
2275
  let agentLoopCallCount = 0;
1982
- const agentLoopRun: AgentLoopRun = async (
1983
- messages,
1984
- onEvent,
1985
- _signal,
1986
- _requestId,
1987
- onCheckpoint,
1988
- ) => {
2276
+ const agentLoopRun: AgentLoopRun = async (messages, onEvent, options) => {
1989
2277
  // Prime the assistant row anchor — production code emits this from
1990
2278
  // `AgentLoop.run` just before `provider.sendMessage`.
1991
2279
  await onEvent({ type: "llm_call_started" });
@@ -2042,14 +2330,14 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
2042
2330
  });
2043
2331
 
2044
2332
  // Always yield at checkpoint — simulates reduction not helping enough
2045
- if (onCheckpoint) {
2046
- const decision = await onCheckpoint({
2333
+ if (options?.onCheckpoint) {
2334
+ const decision = await options.onCheckpoint({
2047
2335
  turnIndex: 0,
2048
2336
  toolCount: 1,
2049
2337
  hasToolUse: true,
2050
2338
  history: withProgress,
2051
2339
  });
2052
- if (decision === "yield") {
2340
+ if (decision !== "continue") {
2053
2341
  return withProgress;
2054
2342
  }
2055
2343
  }
@@ -2090,6 +2378,11 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
2090
2378
  agentLoopRun,
2091
2379
  contextWindowManager: {
2092
2380
  shouldCompact: () => ({ needed: false, estimatedTokens: 0 }),
2381
+ // Under the new architecture (Compaction Re-homing Arc, Bullet 1)
2382
+ // the retry budget lives inside `ContextWindowManager._maybeCompact`,
2383
+ // so a single daemon-level call represents the full manager retry
2384
+ // sequence. Signal `exhausted: true` immediately to escalate the
2385
+ // mid-loop to the convergence reducer.
2093
2386
  maybeCompact: async () => ({
2094
2387
  compacted: true,
2095
2388
  messages: [
@@ -2109,6 +2402,7 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
2109
2402
  summaryInputTokens: 500,
2110
2403
  summaryOutputTokens: 200,
2111
2404
  summaryModel: "mock-model",
2405
+ exhausted: true,
2112
2406
  }),
2113
2407
  } as unknown as AgentLoopConversationContext["contextWindowManager"],
2114
2408
  });
@@ -2119,8 +2413,10 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
2119
2413
  // once more after yieldedForBudget triggered re-entry
2120
2414
  expect(reducerCallCount).toBe(2);
2121
2415
 
2122
- // Agent loop: 1 initial + 3 mid-loop re-entries + 2 convergence re-runs = 6 calls
2123
- expect(agentLoopCallCount).toBe(6);
2416
+ // Agent loop: 1 initial + 2 convergence re-runs = 3 calls. The mid-loop
2417
+ // no longer drives daemon-level retries — the manager owns its retry
2418
+ // budget and signals exhaustion via the `exhausted` flag.
2419
+ expect(agentLoopCallCount).toBe(3);
2124
2420
  expect(setAgentLoopExitReasonOnLatestLogMock).toHaveBeenCalledWith(
2125
2421
  "test-conv",
2126
2422
  "context_too_large",
@@ -2320,13 +2616,7 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
2320
2616
  mockOverflowAction = "auto_compress_latest_turn";
2321
2617
 
2322
2618
  let agentLoopCallCount = 0;
2323
- const agentLoopRun: AgentLoopRun = async (
2324
- messages,
2325
- onEvent,
2326
- _signal,
2327
- _requestId,
2328
- onCheckpoint,
2329
- ) => {
2619
+ const agentLoopRun: AgentLoopRun = async (messages, onEvent, options) => {
2330
2620
  // Prime the assistant row anchor — production code emits this from
2331
2621
  // `AgentLoop.run` just before `provider.sendMessage`.
2332
2622
  await onEvent({ type: "llm_call_started" });
@@ -2383,14 +2673,14 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
2383
2673
  });
2384
2674
 
2385
2675
  // Every checkpoint yields — including the final auto_compress rerun.
2386
- if (onCheckpoint) {
2387
- const decision = await onCheckpoint({
2676
+ if (options?.onCheckpoint) {
2677
+ const decision = await options.onCheckpoint({
2388
2678
  turnIndex: 0,
2389
2679
  toolCount: 1,
2390
2680
  hasToolUse: true,
2391
2681
  history: withProgress,
2392
2682
  });
2393
- if (decision === "yield") {
2683
+ if (decision !== "continue") {
2394
2684
  return withProgress;
2395
2685
  }
2396
2686
  }
@@ -2398,32 +2688,82 @@ describe("session-agent-loop overflow recovery (JARVIS-110)", () => {
2398
2688
  return withProgress;
2399
2689
  };
2400
2690
 
2691
+ // `maybeCompact` is invoked through three distinct call sites:
2692
+ // 1. Start-of-turn compaction (no `force` option) — return a no-op
2693
+ // so the start-of-turn pass doesn't perturb state. The mock's
2694
+ // `shouldCompact` already returns `needed: false`, but the
2695
+ // orchestrator still invokes the compaction pipeline.
2696
+ // 2. Mid-loop after the initial agent-loop yield (`force: true`) —
2697
+ // must signal `exhausted: true` so the daemon escalates to the
2698
+ // convergence reducer instead of looping forever.
2699
+ // 3. auto_compress_latest_turn emergency compaction (`force: true`,
2700
+ // `minKeepRecentUserTurns: 0`) — succeeds and drops tokens below
2701
+ // threshold; the subsequent rerun yields again and is classified
2702
+ // as BUDGET_YIELD_UNRECOVERED.
2703
+ let forcedMaybeCompactCallCount = 0;
2401
2704
  const ctx = makeCtx({
2402
2705
  agentLoopRun,
2403
2706
  contextWindowManager: {
2404
2707
  shouldCompact: () => ({ needed: false, estimatedTokens: 0 }),
2405
- // The compaction pipeline (default terminal) routes through this
2406
- // for the emergency `auto_compress_latest_turn` path.
2407
- maybeCompact: async () => ({
2408
- compacted: true,
2409
- messages: [
2410
- {
2411
- role: "user" as const,
2412
- content: [{ type: "text", text: "compacted" }],
2413
- },
2414
- ] as Message[],
2415
- compactedPersistedMessages: 5,
2416
- summaryText: "Emergency summary",
2417
- previousEstimatedInputTokens: 170_000,
2418
- estimatedInputTokens: 90_000,
2419
- maxInputTokens: 200_000,
2420
- thresholdTokens: 160_000,
2421
- compactedMessages: 10,
2422
- summaryCalls: 1,
2423
- summaryInputTokens: 500,
2424
- summaryOutputTokens: 200,
2425
- summaryModel: "mock-model",
2426
- }),
2708
+ maybeCompact: async (
2709
+ _msgs: Message[],
2710
+ _signal: AbortSignal,
2711
+ opts?: { force?: boolean },
2712
+ ) => {
2713
+ // Start-of-turn calls pass no `force` option; route them to a
2714
+ // no-op so only the mid-loop and emergency paths drive the test.
2715
+ if (!opts?.force) {
2716
+ return { compacted: false };
2717
+ }
2718
+ forcedMaybeCompactCallCount++;
2719
+ if (forcedMaybeCompactCallCount === 1) {
2720
+ // Mid-loop call — under the new architecture (Compaction
2721
+ // Re-homing Arc, Bullet 1) the manager owns its own retry
2722
+ // budget; signal exhaustion to escalate to convergence.
2723
+ return {
2724
+ compacted: true,
2725
+ messages: [
2726
+ {
2727
+ role: "user" as const,
2728
+ content: [{ type: "text", text: "mid-loop compacted" }],
2729
+ },
2730
+ ] as Message[],
2731
+ compactedPersistedMessages: 5,
2732
+ summaryText: "Mid-loop summary",
2733
+ previousEstimatedInputTokens: 170_000,
2734
+ estimatedInputTokens: 165_000,
2735
+ maxInputTokens: 200_000,
2736
+ thresholdTokens: 160_000,
2737
+ compactedMessages: 10,
2738
+ summaryCalls: 1,
2739
+ summaryInputTokens: 500,
2740
+ summaryOutputTokens: 200,
2741
+ summaryModel: "mock-model",
2742
+ exhausted: true,
2743
+ };
2744
+ }
2745
+ // Emergency compaction call from auto_compress_latest_turn.
2746
+ return {
2747
+ compacted: true,
2748
+ messages: [
2749
+ {
2750
+ role: "user" as const,
2751
+ content: [{ type: "text", text: "compacted" }],
2752
+ },
2753
+ ] as Message[],
2754
+ compactedPersistedMessages: 5,
2755
+ summaryText: "Emergency summary",
2756
+ previousEstimatedInputTokens: 170_000,
2757
+ estimatedInputTokens: 90_000,
2758
+ maxInputTokens: 200_000,
2759
+ thresholdTokens: 160_000,
2760
+ compactedMessages: 10,
2761
+ summaryCalls: 1,
2762
+ summaryInputTokens: 500,
2763
+ summaryOutputTokens: 200,
2764
+ summaryModel: "mock-model",
2765
+ };
2766
+ },
2427
2767
  } as unknown as AgentLoopConversationContext["contextWindowManager"],
2428
2768
  });
2429
2769