@vellumai/assistant 0.8.8 → 0.8.9-staging.2

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 (360) hide show
  1. package/ARCHITECTURE.md +6 -6
  2. package/bun.lock +2 -2
  3. package/examples/plugins/echo/README.md +61 -60
  4. package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
  5. package/examples/plugins/echo/hooks/stop.ts +16 -0
  6. package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
  7. package/examples/plugins/echo/package.json +1 -2
  8. package/examples/plugins/echo/src/emit.ts +19 -0
  9. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
  10. package/openapi.yaml +235 -6
  11. package/package.json +2 -2
  12. package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
  13. package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
  14. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
  15. package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
  16. package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
  17. package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
  18. package/src/__tests__/agent-loop-thinking.test.ts +36 -20
  19. package/src/__tests__/agent-loop.test.ts +441 -96
  20. package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
  21. package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
  22. package/src/__tests__/anthropic-provider.test.ts +1 -1
  23. package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
  24. package/src/__tests__/app-control-flow.test.ts +1 -1
  25. package/src/__tests__/app-dir-path-guard.test.ts +1 -0
  26. package/src/__tests__/app-executors.test.ts +132 -0
  27. package/src/__tests__/approval-cascade.test.ts +5 -4
  28. package/src/__tests__/approval-routes-http.test.ts +4 -1
  29. package/src/__tests__/background-workers-disk-pressure.test.ts +1 -1
  30. package/src/__tests__/channel-approval-routes.test.ts +1 -1
  31. package/src/__tests__/channel-approvals.test.ts +1 -1
  32. package/src/__tests__/compaction-circuit.test.ts +258 -0
  33. package/src/__tests__/compaction-direct.test.ts +132 -0
  34. package/src/__tests__/compaction-events.test.ts +5 -5
  35. package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
  36. package/src/__tests__/context-overflow-reducer.test.ts +1 -1
  37. package/src/__tests__/conversation-abort-tool-results.test.ts +6 -4
  38. package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
  39. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
  40. package/src/__tests__/conversation-agent-loop-overflow.test.ts +142 -218
  41. package/src/__tests__/conversation-agent-loop.test.ts +297 -586
  42. package/src/__tests__/conversation-clean-command.test.ts +5 -2
  43. package/src/__tests__/conversation-confirmation-signals.test.ts +5 -4
  44. package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
  45. package/src/__tests__/conversation-history-web-search.test.ts +1 -1
  46. package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -4
  47. package/src/__tests__/conversation-process-callsite.test.ts +14 -14
  48. package/src/__tests__/conversation-provider-retry-repair.test.ts +70 -65
  49. package/src/__tests__/conversation-queue.test.ts +9 -9
  50. package/src/__tests__/conversation-runtime-assembly.test.ts +923 -231
  51. package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
  52. package/src/__tests__/conversation-slash-queue.test.ts +6 -4
  53. package/src/__tests__/conversation-slash-unknown.test.ts +6 -4
  54. package/src/__tests__/conversation-speed-override.test.ts +10 -9
  55. package/src/__tests__/conversation-starter-routes.test.ts +14 -6
  56. package/src/__tests__/conversation-workspace-cache-state.test.ts +23 -20
  57. package/src/__tests__/conversation-workspace-injection.test.ts +68 -6
  58. package/src/__tests__/conversation-workspace-tool-tracking.test.ts +14 -11
  59. package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
  60. package/src/__tests__/credential-security-invariants.test.ts +0 -1
  61. package/src/__tests__/db-acp-history.test.ts +101 -0
  62. package/src/__tests__/dynamic-page-surface.test.ts +31 -0
  63. package/src/__tests__/empty-response-hook.test.ts +1 -1
  64. package/src/__tests__/file-write-tool.test.ts +63 -0
  65. package/src/__tests__/gateway-only-guard.test.ts +12 -2
  66. package/src/__tests__/guardian-grant-minting.test.ts +1 -1
  67. package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
  68. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
  69. package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
  70. package/src/__tests__/heartbeat-service.test.ts +1 -0
  71. package/src/__tests__/history-repair-hook.test.ts +1 -1
  72. package/src/__tests__/host-app-control-routes.test.ts +1 -1
  73. package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
  74. package/src/__tests__/inference-profile-reaper.test.ts +62 -0
  75. package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
  76. package/src/__tests__/injector-background-turn.test.ts +13 -23
  77. package/src/__tests__/injector-chain.test.ts +268 -44
  78. package/src/__tests__/injector-disk-pressure.test.ts +210 -52
  79. package/src/__tests__/injector-document-comments.test.ts +97 -114
  80. package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
  81. package/src/__tests__/injector-v3-suppression.test.ts +4 -4
  82. package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
  83. package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
  84. package/src/__tests__/memory-retrieval-hook.test.ts +131 -26
  85. package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
  86. package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
  87. package/src/__tests__/plugin-api-shim.test.ts +6 -9
  88. package/src/__tests__/plugin-bootstrap.test.ts +12 -23
  89. package/src/__tests__/plugin-registry.test.ts +3 -49
  90. package/src/__tests__/plugin-types.test.ts +0 -70
  91. package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
  92. package/src/__tests__/reaction-persistence.test.ts +1 -1
  93. package/src/__tests__/send-endpoint-busy.test.ts +4 -1
  94. package/src/__tests__/skill-feature-flags-integration.test.ts +33 -0
  95. package/src/__tests__/steer-tool-repair.test.ts +1 -1
  96. package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
  97. package/src/__tests__/subagent-detail.test.ts +25 -7
  98. package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
  99. package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
  100. package/src/__tests__/subagent-manager-notify.test.ts +1 -3
  101. package/src/__tests__/subagent-notify-parent.test.ts +1 -3
  102. package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
  103. package/src/__tests__/title-generate-hook.test.ts +1 -1
  104. package/src/__tests__/tool-error-hook.test.ts +1 -1
  105. package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
  106. package/src/__tests__/user-plugin-loader.test.ts +54 -286
  107. package/src/acp/__tests__/agent-process.test.ts +161 -0
  108. package/src/acp/__tests__/client-handler.test.ts +40 -0
  109. package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
  110. package/src/acp/__tests__/helpers/exec-file-stub.ts +106 -0
  111. package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
  112. package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
  113. package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
  114. package/src/acp/agent-process.ts +61 -1
  115. package/src/acp/auto-install.test.ts +280 -0
  116. package/src/acp/auto-install.ts +232 -0
  117. package/src/acp/client-handler.ts +31 -0
  118. package/src/acp/feature-gate.test.ts +48 -0
  119. package/src/acp/feature-gate.ts +34 -0
  120. package/src/acp/prepare-agent-env.ts +80 -27
  121. package/src/acp/resolve-agent.test.ts +225 -9
  122. package/src/acp/resolve-agent.ts +122 -17
  123. package/src/acp/resume-hint.ts +23 -0
  124. package/src/acp/session-manager.ts +507 -73
  125. package/src/agent/compaction-circuit.ts +60 -102
  126. package/src/agent/loop.ts +414 -248
  127. package/src/api/responses/conversation-message.ts +14 -1
  128. package/src/approvals/guardian-request-resolvers.ts +1 -1
  129. package/src/background-wake/next-wake.ts +1 -0
  130. package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
  131. package/src/cli/commands/plugins.ts +43 -37
  132. package/src/cli/lib/__tests__/install-from-github.test.ts +429 -111
  133. package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
  134. package/src/cli/lib/__tests__/plugin-details.test.ts +372 -0
  135. package/src/cli/lib/__tests__/plugin-marketplace.test.ts +220 -0
  136. package/src/cli/lib/__tests__/search-plugins.test.ts +226 -32
  137. package/src/cli/lib/install-from-github.ts +464 -55
  138. package/src/cli/lib/plugin-catalog-cache.ts +84 -0
  139. package/src/cli/lib/plugin-details.ts +409 -0
  140. package/src/cli/lib/plugin-marketplace.ts +197 -0
  141. package/src/cli/lib/search-plugins.ts +195 -29
  142. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  143. package/src/config/acp-defaults.test.ts +10 -0
  144. package/src/config/acp-defaults.ts +6 -0
  145. package/src/config/bundled-skills/acp/SKILL.md +85 -33
  146. package/src/config/bundled-skills/acp/TOOLS.json +4 -4
  147. package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
  148. package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
  149. package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
  150. package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
  151. package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
  152. package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
  153. package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -0
  154. package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
  155. package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
  156. package/src/config/bundled-tool-registry.ts +4 -0
  157. package/src/config/call-site-defaults.ts +0 -2
  158. package/src/config/feature-flag-registry.json +15 -6
  159. package/src/config/schemas/call-site-catalog.ts +0 -14
  160. package/src/config/schemas/heartbeat.ts +9 -0
  161. package/src/config/schemas/llm.ts +0 -2
  162. package/src/context/compactor.ts +22 -4
  163. package/src/context/strip-injections.ts +8 -2
  164. package/src/context/window-manager.ts +27 -13
  165. package/src/daemon/conversation-agent-loop-handlers.ts +10 -35
  166. package/src/daemon/conversation-agent-loop.ts +175 -1055
  167. package/src/daemon/conversation-lifecycle.ts +11 -255
  168. package/src/daemon/conversation-process.ts +8 -136
  169. package/src/daemon/conversation-registry.ts +159 -0
  170. package/src/daemon/conversation-runtime-assembly.ts +293 -392
  171. package/src/daemon/conversation-store.ts +9 -90
  172. package/src/daemon/conversation-surfaces.ts +24 -8
  173. package/src/daemon/conversation-workspace.ts +17 -0
  174. package/src/daemon/conversation.ts +404 -57
  175. package/src/daemon/disk-pressure-policy.ts +0 -1
  176. package/src/daemon/external-plugins-bootstrap.ts +14 -19
  177. package/src/daemon/handlers/conversations.ts +3 -1
  178. package/src/daemon/handlers/skills.ts +4 -1
  179. package/src/daemon/host-proxy-preactivation.ts +1 -3
  180. package/src/daemon/lifecycle.ts +21 -7
  181. package/src/daemon/server.ts +2 -0
  182. package/src/daemon/wake-conversation-ops.ts +269 -0
  183. package/src/embedded/plugin-api.ts +2 -2
  184. package/src/export/__tests__/transcript-formatter.test.ts +5 -0
  185. package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
  186. package/src/heartbeat/heartbeat-run-store.ts +23 -1
  187. package/src/heartbeat/heartbeat-service.ts +26 -0
  188. package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
  189. package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
  190. package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
  191. package/src/ipc/skill-routes/memory.ts +4 -2
  192. package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
  193. package/src/memory/conversation-crud.ts +29 -19
  194. package/src/memory/conversation-starter-checkpoints.ts +1 -0
  195. package/src/memory/db-init.ts +2 -0
  196. package/src/memory/job-handlers/conversation-starters.ts +13 -2
  197. package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
  198. package/src/memory/jobs-worker.ts +25 -1
  199. package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
  200. package/src/memory/migrations/index.ts +1 -0
  201. package/src/memory/schema/acp.ts +4 -0
  202. package/src/memory/v2/__tests__/consolidation-job.test.ts +3 -3
  203. package/src/memory/v2/consolidation-job.ts +13 -4
  204. package/src/plugin-api/constants.ts +4 -0
  205. package/src/plugin-api/index.ts +6 -5
  206. package/src/plugin-api/types.ts +75 -0
  207. package/src/plugins/defaults/compaction/compact.ts +59 -0
  208. package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +7 -7
  209. package/src/plugins/defaults/compaction/manager-store.ts +57 -0
  210. package/src/plugins/defaults/compaction/package.json +1 -2
  211. package/src/plugins/defaults/empty-response/package.json +0 -1
  212. package/src/plugins/defaults/history-repair/package.json +0 -1
  213. package/src/plugins/defaults/index.ts +135 -26
  214. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
  215. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +184 -74
  216. package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
  217. package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
  218. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
  219. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/assign.test.ts +4 -4
  220. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +9 -6
  221. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/maintain-job.test.ts +5 -5
  222. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/orchestrate.test.ts +8 -5
  223. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/reconcile.test.ts +2 -2
  224. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/render-injection.test.ts +1 -1
  225. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/router.test.ts +10 -5
  226. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +8 -8
  227. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selector.test.ts +5 -5
  228. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/shadow-plugin.test.ts +16 -17
  229. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -2
  230. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/assign.ts +9 -5
  231. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/capabilities.ts +5 -2
  232. package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
  233. package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
  234. package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
  235. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/maintain-job.ts +15 -8
  236. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/orchestrate.ts +2 -2
  237. package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
  238. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/page-content.ts +2 -2
  239. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/provider-blocks.ts +1 -1
  240. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/reconcile.ts +7 -3
  241. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +1 -1
  242. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/router.ts +5 -5
  243. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selection-log-store.ts +4 -4
  244. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selector.ts +7 -7
  245. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/shadow-plugin.ts +32 -94
  246. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/tree.ts +1 -1
  247. package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/types.ts +1 -1
  248. package/src/plugins/defaults/title-generate/package.json +0 -1
  249. package/src/plugins/defaults/tool-error/package.json +0 -1
  250. package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
  251. package/src/plugins/pipeline.ts +6 -293
  252. package/src/plugins/registry.ts +9 -37
  253. package/src/plugins/types.ts +76 -381
  254. package/src/plugins/user-loader.ts +30 -127
  255. package/src/prompts/__tests__/system-prompt.test.ts +6 -0
  256. package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +35 -3
  257. package/src/runtime/__tests__/agent-wake.test.ts +555 -691
  258. package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
  259. package/src/runtime/agent-wake.ts +108 -209
  260. package/src/runtime/assistant-event-hub.ts +1 -1
  261. package/src/runtime/channel-approvals.ts +1 -1
  262. package/src/runtime/interactive-ui.ts +1 -1
  263. package/src/runtime/routes/__tests__/acp-routes.test.ts +315 -55
  264. package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
  265. package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
  266. package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
  267. package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
  268. package/src/runtime/routes/acp-routes.test.ts +89 -25
  269. package/src/runtime/routes/acp-routes.ts +81 -29
  270. package/src/runtime/routes/approval-routes.ts +1 -1
  271. package/src/runtime/routes/browser-routes.ts +1 -1
  272. package/src/runtime/routes/browser-tabs-routes.ts +6 -10
  273. package/src/runtime/routes/conversation-cli-routes.ts +1 -1
  274. package/src/runtime/routes/conversation-list-routes.ts +1 -1
  275. package/src/runtime/routes/conversation-query-routes.ts +1 -1
  276. package/src/runtime/routes/conversation-routes.ts +28 -2
  277. package/src/runtime/routes/conversation-starter-routes.ts +13 -7
  278. package/src/runtime/routes/conversations-import-routes.ts +24 -7
  279. package/src/runtime/routes/host-app-control-routes.ts +1 -1
  280. package/src/runtime/routes/host-cu-routes.ts +1 -1
  281. package/src/runtime/routes/identity-routes.ts +18 -3
  282. package/src/runtime/routes/inbound-message-handler.ts +1 -1
  283. package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
  284. package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
  285. package/src/runtime/routes/memory-v3-routes.ts +16 -6
  286. package/src/runtime/routes/playground/helpers.ts +1 -1
  287. package/src/runtime/routes/plugins-routes.ts +337 -35
  288. package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
  289. package/src/runtime/routes/work-items-routes.ts +2 -4
  290. package/src/runtime/services/conversation-serializer.ts +1 -1
  291. package/src/signals/cancel.ts +2 -4
  292. package/src/subagent/manager.ts +21 -5
  293. package/src/tools/acp/context.ts +20 -0
  294. package/src/tools/acp/list-agents.test.ts +8 -2
  295. package/src/tools/acp/spawn.test.ts +176 -195
  296. package/src/tools/acp/spawn.ts +37 -172
  297. package/src/tools/acp/steer.test.ts +105 -8
  298. package/src/tools/acp/steer.ts +48 -17
  299. package/src/tools/apps/executors.ts +166 -50
  300. package/src/tools/filesystem/write.ts +34 -0
  301. package/src/tools/subagent/spawn.ts +2 -4
  302. package/src/tools/ui-surface/definitions.ts +25 -5
  303. package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
  304. package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
  305. package/docs/plugins.md +0 -832
  306. package/examples/plugins/echo/register.ts +0 -143
  307. package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
  308. package/src/__tests__/compaction-pipeline.test.ts +0 -210
  309. package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
  310. package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -667
  311. package/src/__tests__/pipeline-runner.test.ts +0 -554
  312. package/src/__tests__/plugin-external-api.test.ts +0 -68
  313. package/src/daemon/wake-target-adapter.ts +0 -253
  314. package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
  315. package/src/plugins/defaults/circuit-breaker/package.json +0 -15
  316. package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
  317. package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
  318. package/src/plugins/defaults/compaction/register.ts +0 -35
  319. package/src/plugins/defaults/compaction/terminal.ts +0 -73
  320. package/src/plugins/defaults/empty-response/register.ts +0 -23
  321. package/src/plugins/defaults/history-repair/register.ts +0 -24
  322. package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
  323. package/src/plugins/defaults/overflow-reduce/package.json +0 -15
  324. package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
  325. package/src/plugins/defaults/title-generate/register.ts +0 -35
  326. package/src/plugins/defaults/tool-error/register.ts +0 -23
  327. package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
  328. package/src/plugins/external-api.ts +0 -104
  329. package/src/proactive-artifact/aux-message-injector.ts +0 -97
  330. package/src/proactive-artifact/decision.test.ts +0 -226
  331. package/src/proactive-artifact/decision.ts +0 -165
  332. package/src/proactive-artifact/index.ts +0 -7
  333. package/src/proactive-artifact/job.test.ts +0 -962
  334. package/src/proactive-artifact/job.ts +0 -372
  335. package/src/proactive-artifact/message-copy.ts +0 -58
  336. package/src/proactive-artifact/trigger-state.test.ts +0 -286
  337. package/src/proactive-artifact/trigger-state.ts +0 -123
  338. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/capabilities.test.ts +0 -0
  339. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/core.test.ts +0 -0
  340. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
  341. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
  342. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/health.test.ts +0 -0
  343. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/needle.test.ts +0 -0
  344. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/provider-blocks.test.ts +0 -0
  345. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/snapshot.test.ts +0 -0
  346. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/tree.test.ts +0 -0
  347. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
  348. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
  349. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/core.ts +0 -0
  350. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
  351. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
  352. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
  353. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
  354. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
  355. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
  356. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/health.ts +0 -0
  357. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +0 -0
  358. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/needle.ts +0 -0
  359. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/snapshot.ts +0 -0
  360. /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +0 -0
@@ -1,128 +1,12 @@
1
- import { execFile } from "node:child_process";
1
+ import { basename } from "node:path";
2
2
 
3
+ import { resolveAgentWithAutoInstall } from "../../acp/auto-install.js";
3
4
  import { getAcpSessionManager } from "../../acp/index.js";
4
5
  import { prepareAgentEnv } from "../../acp/prepare-agent-env.js";
5
- import { resolveAcpAgent } from "../../acp/resolve-agent.js";
6
- import { DEFAULT_AGENT_NPM_PACKAGES } from "../../config/acp-defaults.js";
7
- import { getLogger } from "../../util/logger.js";
6
+ import { formatResolveFailure } from "../../acp/resolve-agent.js";
7
+ import { claudeResumeHint } from "../../acp/resume-hint.js";
8
8
  import type { ToolContext, ToolExecutionResult } from "../types.js";
9
-
10
- const log = getLogger("acp:spawn");
11
-
12
- /** Per-call timeout for `npm` probes. Best-effort: timeouts are non-fatal. */
13
- const NPM_PROBE_TIMEOUT_MS = 5_000;
14
-
15
- /**
16
- * Cache of resolved version-check outcomes — including `null` for "skipped" —
17
- * keyed by command. Lives for the process lifetime so retries don't reprobe.
18
- */
19
- const adapterVersionCache = new Map<string, AdapterVersionInfo | null>();
20
-
21
- interface AdapterVersionInfo {
22
- outdated: true;
23
- installed: string;
24
- latest: string;
25
- packageName: string;
26
- }
27
-
28
- /**
29
- * Run `execFile` with an AbortController-driven timeout. Returns the stdout
30
- * on success; throws on error or timeout. Caller treats any throw as a
31
- * best-effort skip.
32
- */
33
- function execFileWithTimeout(
34
- command: string,
35
- args: string[],
36
- timeoutMs: number,
37
- ): Promise<string> {
38
- return new Promise((resolve, reject) => {
39
- const controller = new AbortController();
40
- const timer = setTimeout(() => controller.abort(), timeoutMs);
41
- execFile(
42
- command,
43
- args,
44
- { signal: controller.signal, encoding: "utf8" },
45
- (err, stdout) => {
46
- clearTimeout(timer);
47
- if (err) {
48
- reject(err);
49
- return;
50
- }
51
- resolve(stdout);
52
- },
53
- );
54
- });
55
- }
56
-
57
- /**
58
- * Checks if the globally-installed ACP adapter for `command` is outdated.
59
- * Best-effort: any error or timeout returns `null` (skipped). Unknown
60
- * commands also return `null`. Results are cached per-command for the
61
- * process lifetime.
62
- *
63
- * Note: `npm ls -g` doesn't see Homebrew/tarball installs, so a "not found"
64
- * here doesn't mean the binary is missing — it just means we can't compare
65
- * versions. The caller must NEVER block the spawn on this result.
66
- */
67
- async function checkAdapterVersion(
68
- command: string,
69
- ): Promise<AdapterVersionInfo | null> {
70
- if (adapterVersionCache.has(command)) {
71
- return adapterVersionCache.get(command) ?? null;
72
- }
73
-
74
- const packageName = DEFAULT_AGENT_NPM_PACKAGES[command];
75
- if (!packageName) {
76
- adapterVersionCache.set(command, null);
77
- return null;
78
- }
79
-
80
- try {
81
- const [installedRaw, latestRaw] = await Promise.all([
82
- execFileWithTimeout(
83
- "npm",
84
- ["ls", "-g", "--json", packageName],
85
- NPM_PROBE_TIMEOUT_MS,
86
- ),
87
- execFileWithTimeout(
88
- "npm",
89
- ["view", packageName, "version"],
90
- NPM_PROBE_TIMEOUT_MS,
91
- ),
92
- ]);
93
-
94
- const installed =
95
- JSON.parse(installedRaw)?.dependencies?.[packageName]?.version;
96
- const latest = latestRaw.trim();
97
-
98
- if (!installed || !latest || installed === latest) {
99
- adapterVersionCache.set(command, null);
100
- return null;
101
- }
102
-
103
- log.info({ installed, latest, packageName }, "ACP adapter is outdated");
104
- const info: AdapterVersionInfo = {
105
- outdated: true,
106
- installed,
107
- latest,
108
- packageName,
109
- };
110
- adapterVersionCache.set(command, info);
111
- return info;
112
- } catch (err) {
113
- log.warn(
114
- { err, packageName },
115
- "Failed to check ACP adapter version (best-effort, skipping)",
116
- );
117
- adapterVersionCache.set(command, null);
118
- return null;
119
- }
120
- }
121
-
122
- /** @internal — exposed for tests only. */
123
- export function _resetAdapterVersionCacheForTests(): void {
124
- adapterVersionCache.clear();
125
- }
9
+ import { getSendToClient } from "./context.js";
126
10
 
127
11
  export async function executeAcpSpawn(
128
12
  input: Record<string, unknown>,
@@ -135,34 +19,11 @@ export async function executeAcpSpawn(
135
19
  return { content: '"task" is required.', isError: true };
136
20
  }
137
21
 
138
- const resolved = resolveAcpAgent(agent);
139
- if (!resolved.ok) {
140
- switch (resolved.reason) {
141
- case "acp_disabled":
142
- return { content: resolved.hint, isError: true };
143
- case "unknown_agent":
144
- return {
145
- content: `Unknown agent "${agent}". Available: ${resolved.available.join(
146
- ", ",
147
- )}.`,
148
- isError: true,
149
- };
150
- case "binary_not_found":
151
- return {
152
- content: `${resolved.command} is not on PATH. ${resolved.hint}`,
153
- isError: true,
154
- };
155
- default: {
156
- const _exhaustive: never = resolved;
157
- throw new Error(
158
- `Unexpected acp resolver reason: ${(_exhaustive as { reason: string }).reason}`,
159
- );
160
- }
161
- }
162
- }
163
- const sendToClient = context.sendToClient as
164
- | ((msg: { type: string; [key: string]: unknown }) => void)
165
- | undefined;
22
+ // Pure precondition: check for a connected client BEFORE any side effects
23
+ // (auto-install mutates the host via a `bun` global install and can block
24
+ // for up to the install timeout). Without a client the spawn cannot
25
+ // succeed anyway.
26
+ const sendToClient = getSendToClient(context);
166
27
  if (!sendToClient) {
167
28
  return {
168
29
  content: "No client connected - cannot spawn ACP agent.",
@@ -170,6 +31,17 @@ export async function executeAcpSpawn(
170
31
  };
171
32
  }
172
33
 
34
+ // Resolve the agent, silently auto-installing a missing allowlisted
35
+ // adapter binary (see acp/auto-install.ts). Shared with the HTTP route.
36
+ const { resolved, autoInstalledPackage, failureMessage } =
37
+ await resolveAgentWithAutoInstall(agent);
38
+ if (failureMessage) {
39
+ return { content: failureMessage, isError: true };
40
+ }
41
+ if (!resolved.ok) {
42
+ return { content: formatResolveFailure(agent, resolved), isError: true };
43
+ }
44
+
173
45
  // Inject required env vars and preflight via the shared helper. Mirrors
174
46
  // the HTTP route at `runtime/routes/acp-routes.ts:spawnSession` — both
175
47
  // call sites MUST go through `prepareAgentEnv` before `manager.spawn`,
@@ -184,10 +56,6 @@ export async function executeAcpSpawn(
184
56
  return { content: msg, isError: true };
185
57
  }
186
58
 
187
- // Best-effort version check — never blocks the spawn. If outdated, we
188
- // append a non-blocking warning to the success payload.
189
- const versionInfo = await checkAdapterVersion(agentConfig.command);
190
-
191
59
  try {
192
60
  const manager = getAcpSessionManager();
193
61
  const cwd = (input.cwd as string) || context.workingDir;
@@ -197,17 +65,21 @@ export async function executeAcpSpawn(
197
65
  task,
198
66
  cwd,
199
67
  context.conversationId,
200
- sendToClient as (msg: unknown) => void,
68
+ sendToClient,
201
69
  );
202
70
 
203
- // `claude --resume <id>` is Claude Code-specific (the claude-agent-acp
204
- // adapter binary). Other adapters resume differently or not at all,
205
- // so the hint is gated by the resolved binary, not the agent id —
206
- // this stays correct when a user aliases an id to a different binary.
207
- const resumeHint =
208
- agentConfig.command === "claude-agent-acp"
209
- ? ` To resume this session later, run: cd ${cwd} && claude --resume ${protocolSessionId}`
210
- : "";
71
+ // Claude Code-only resume hint; empty for other adapters. Keyed off the
72
+ // resolved command basename (always the real adapter binary). See
73
+ // acp/resume-hint.ts for the gating rationale.
74
+ const hint = claudeResumeHint(
75
+ basename(agentConfig.command),
76
+ cwd,
77
+ protocolSessionId,
78
+ );
79
+ const resumeHint = hint ? ` ${hint}` : "";
80
+ const installNote = autoInstalledPackage
81
+ ? ` Installed ${autoInstalledPackage} automatically.`
82
+ : "";
211
83
  const payload = JSON.stringify({
212
84
  acpSessionId,
213
85
  protocolSessionId,
@@ -216,18 +88,11 @@ export async function executeAcpSpawn(
216
88
  status: "running",
217
89
  message:
218
90
  `ACP agent "${agent}" spawned (session: ${protocolSessionId}). ` +
219
- `Results stream back via SSE. You will be notified when it completes.${resumeHint}`,
91
+ `Results stream back via SSE. You will be notified when it completes.` +
92
+ `${installNote}${resumeHint}`,
220
93
  });
221
94
 
222
- let content = payload;
223
- if (versionInfo) {
224
- content +=
225
- `\n\nNote: ${versionInfo.packageName} is outdated ` +
226
- `(installed: ${versionInfo.installed}, latest: ${versionInfo.latest}). ` +
227
- `To update, run: npm install -g ${versionInfo.packageName}@${versionInfo.latest}`;
228
- }
229
-
230
- return { content, isError: false };
95
+ return { content: payload, isError: false };
231
96
  } catch (err) {
232
97
  const msg =
233
98
  err instanceof Error
@@ -7,6 +7,7 @@ interface SteerCall {
7
7
  instruction: string;
8
8
  }
9
9
 
10
+ // Direct steer (no connected client -> no resume fallback).
10
11
  const steerCalls: SteerCall[] = [];
11
12
  const defaultSteer = (acpSessionId: string, instruction: string) => {
12
13
  steerCalls.push({ acpSessionId, instruction });
@@ -15,6 +16,13 @@ const defaultSteer = (acpSessionId: string, instruction: string) => {
15
16
  let steerImpl: (acpSessionId: string, instruction: string) => Promise<void> =
16
17
  defaultSteer;
17
18
 
19
+ // steerOrResume (connected client path).
20
+ const steerOrResumeCalls: Array<SteerCall & { send: unknown }> = [];
21
+ let steerOrResumeImpl: (
22
+ acpSessionId: string,
23
+ instruction: string,
24
+ ) => Promise<{ resumed: boolean }> = async () => ({ resumed: false });
25
+
18
26
  // Spread the real module's exports so transitive importers that pull other
19
27
  // names from `../../acp/index.js` still resolve at parse time. Bun's `mock.module` is
20
28
  // process-global and returns *exactly* the keys the factory returns.
@@ -24,35 +32,50 @@ mock.module("../../acp/index.js", () => ({
24
32
  getAcpSessionManager: () => ({
25
33
  steer: (acpSessionId: string, instruction: string) =>
26
34
  steerImpl(acpSessionId, instruction),
35
+ steerOrResume: (
36
+ acpSessionId: string,
37
+ instruction: string,
38
+ send: unknown,
39
+ ) => {
40
+ steerOrResumeCalls.push({ acpSessionId, instruction, send });
41
+ return steerOrResumeImpl(acpSessionId, instruction);
42
+ },
27
43
  }),
28
44
  }));
29
45
 
30
46
  const { executeAcpSteer } = await import("./steer.js");
31
47
 
32
- function makeContext(): ToolContext {
48
+ function makeContext(opts?: { withClient?: boolean }): ToolContext {
33
49
  return {
34
50
  workingDir: "/tmp",
35
51
  conversationId: "conv-test",
36
52
  trustClass: "guardian",
37
- };
53
+ ...(opts?.withClient ? { sendToClient: () => {} } : {}),
54
+ } as ToolContext;
38
55
  }
39
56
 
40
57
  beforeEach(() => {
41
58
  steerCalls.length = 0;
59
+ steerOrResumeCalls.length = 0;
42
60
  steerImpl = defaultSteer;
61
+ steerOrResumeImpl = async () => ({ resumed: false });
43
62
  });
44
63
 
45
64
  describe("executeAcpSteer", () => {
46
- test("happy path: returns steered status and forwards args to manager", async () => {
65
+ test("happy path: returns steered status and forwards args to steerOrResume", async () => {
47
66
  const result = await executeAcpSteer(
48
67
  { acp_session_id: "acp-123", instruction: "stop, do X instead" },
49
- makeContext(),
68
+ makeContext({ withClient: true }),
50
69
  );
51
70
 
52
71
  expect(result.isError).toBe(false);
53
- expect(steerCalls).toEqual([
54
- { acpSessionId: "acp-123", instruction: "stop, do X instead" },
55
- ]);
72
+ expect(steerOrResumeCalls).toHaveLength(1);
73
+ expect(steerOrResumeCalls[0]).toMatchObject({
74
+ acpSessionId: "acp-123",
75
+ instruction: "stop, do X instead",
76
+ });
77
+ expect(typeof steerOrResumeCalls[0]!.send).toBe("function");
78
+ expect(steerCalls).toEqual([]);
56
79
 
57
80
  const parsed = JSON.parse(result.content as string);
58
81
  expect(parsed).toEqual({
@@ -71,6 +94,7 @@ describe("executeAcpSteer", () => {
71
94
  expect(result.isError).toBe(true);
72
95
  expect(result.content).toContain('"instruction" is required');
73
96
  expect(steerCalls).toEqual([]);
97
+ expect(steerOrResumeCalls).toEqual([]);
74
98
  });
75
99
 
76
100
  test("missing acp_session_id returns isError", async () => {
@@ -82,9 +106,23 @@ describe("executeAcpSteer", () => {
82
106
  expect(result.isError).toBe(true);
83
107
  expect(result.content).toContain('"acp_session_id" is required');
84
108
  expect(steerCalls).toEqual([]);
109
+ expect(steerOrResumeCalls).toEqual([]);
110
+ });
111
+
112
+ test("no connected client: steers directly and never resumes", async () => {
113
+ const result = await executeAcpSteer(
114
+ { acp_session_id: "acp-direct", instruction: "redirect" },
115
+ makeContext(),
116
+ );
117
+
118
+ expect(result.isError).toBe(false);
119
+ expect(steerCalls).toEqual([
120
+ { acpSessionId: "acp-direct", instruction: "redirect" },
121
+ ]);
122
+ expect(steerOrResumeCalls).toEqual([]);
85
123
  });
86
124
 
87
- test("manager.steer throwing 'session not found' surfaces the error", async () => {
125
+ test("'session not found' without a connected client surfaces the error", async () => {
88
126
  steerImpl = () =>
89
127
  Promise.reject(new Error('ACP session "acp-x" not found'));
90
128
 
@@ -96,5 +134,64 @@ describe("executeAcpSteer", () => {
96
134
  expect(result.isError).toBe(true);
97
135
  expect(result.content).toContain('Could not steer ACP session "acp-x"');
98
136
  expect(result.content).toContain("not found");
137
+ expect(steerOrResumeCalls).toEqual([]);
138
+ });
139
+
140
+ test("resumed session reports the resumed flag and message", async () => {
141
+ steerOrResumeImpl = async () => ({ resumed: true });
142
+
143
+ const result = await executeAcpSteer(
144
+ { acp_session_id: "acp-gone", instruction: "keep going" },
145
+ makeContext({ withClient: true }),
146
+ );
147
+
148
+ expect(result.isError).toBe(false);
149
+ expect(steerOrResumeCalls).toHaveLength(1);
150
+
151
+ const parsed = JSON.parse(result.content as string);
152
+ expect(parsed).toEqual({
153
+ acpSessionId: "acp-gone",
154
+ status: "steered",
155
+ resumed: true,
156
+ message:
157
+ "Session was resumed from history; new instruction is now running.",
158
+ });
159
+ });
160
+
161
+ test("resume failure returns its actionable error message", async () => {
162
+ steerOrResumeImpl = () =>
163
+ Promise.reject(
164
+ new Error(
165
+ 'ACP session "acp-legacy" was recorded before resume support (no working directory persisted) and cannot be resumed. Spawn a new session instead.',
166
+ ),
167
+ );
168
+
169
+ const result = await executeAcpSteer(
170
+ { acp_session_id: "acp-legacy", instruction: "more work" },
171
+ makeContext({ withClient: true }),
172
+ );
173
+
174
+ expect(result.isError).toBe(true);
175
+ expect(result.content).toContain(
176
+ 'Could not steer ACP session "acp-legacy"',
177
+ );
178
+ expect(result.content).toContain("recorded before resume support");
179
+ });
180
+
181
+ test("plain steer errors surface unchanged", async () => {
182
+ steerOrResumeImpl = () =>
183
+ Promise.reject(
184
+ new Error(
185
+ 'ACP session "acp-init" is not running (status: initializing)',
186
+ ),
187
+ );
188
+
189
+ const result = await executeAcpSteer(
190
+ { acp_session_id: "acp-init", instruction: "redirect" },
191
+ makeContext({ withClient: true }),
192
+ );
193
+
194
+ expect(result.isError).toBe(true);
195
+ expect(result.content).toContain("is not running");
99
196
  });
100
197
  });
@@ -1,9 +1,10 @@
1
1
  import { getAcpSessionManager } from "../../acp/index.js";
2
2
  import type { ToolContext, ToolExecutionResult } from "../types.js";
3
+ import { getSendToClient } from "./context.js";
3
4
 
4
5
  export async function executeAcpSteer(
5
6
  input: Record<string, unknown>,
6
- _context: ToolContext,
7
+ context: ToolContext,
7
8
  ): Promise<ToolExecutionResult> {
8
9
  const acpSessionId = input.acp_session_id as string;
9
10
  if (!acpSessionId) {
@@ -15,24 +16,54 @@ export async function executeAcpSteer(
15
16
  return { content: '"instruction" is required.', isError: true };
16
17
  }
17
18
 
18
- try {
19
- const manager = getAcpSessionManager();
20
- await manager.steer(acpSessionId, instruction);
19
+ const manager = getAcpSessionManager();
20
+ const sendToClient = getSendToClient(context);
21
21
 
22
- return {
23
- content: JSON.stringify({
24
- acpSessionId,
25
- status: "steered",
26
- message:
27
- "Interrupted in-flight prompt; new instruction is now running.",
28
- }),
29
- isError: false,
30
- };
22
+ try {
23
+ if (!sendToClient) {
24
+ // Without a connected client there is no one to receive a resumed
25
+ // session's events, so skip the transparent resume fallback and
26
+ // steer the in-memory session only.
27
+ await manager.steer(acpSessionId, instruction);
28
+ return steeredResult(acpSessionId, { resumed: false });
29
+ }
30
+ // Sessions no longer in memory (completed, or lost to a daemon
31
+ // restart) are transparently resumed from persisted history and the
32
+ // instruction fired in the same call. Failure messages carry the
33
+ // actionable hint (e.g. "recorded before resume support", agent
34
+ // capability missing).
35
+ const { resumed } = await manager.steerOrResume(
36
+ acpSessionId,
37
+ instruction,
38
+ sendToClient,
39
+ );
40
+ return steeredResult(acpSessionId, { resumed });
31
41
  } catch (err) {
32
42
  const msg = err instanceof Error ? err.message : String(err);
33
- return {
34
- content: `Could not steer ACP session "${acpSessionId}": ${msg}`,
35
- isError: true,
36
- };
43
+ return steerError(acpSessionId, msg);
37
44
  }
38
45
  }
46
+
47
+ function steeredResult(
48
+ acpSessionId: string,
49
+ opts: { resumed: boolean },
50
+ ): ToolExecutionResult {
51
+ return {
52
+ content: JSON.stringify({
53
+ acpSessionId,
54
+ status: "steered",
55
+ ...(opts.resumed ? { resumed: true } : {}),
56
+ message: opts.resumed
57
+ ? "Session was resumed from history; new instruction is now running."
58
+ : "Interrupted in-flight prompt; new instruction is now running.",
59
+ }),
60
+ isError: false,
61
+ };
62
+ }
63
+
64
+ function steerError(acpSessionId: string, msg: string): ToolExecutionResult {
65
+ return {
66
+ content: `Could not steer ACP session "${acpSessionId}": ${msg}`,
67
+ isError: true,
68
+ };
69
+ }