@getpaseo/server 0.1.62 → 0.1.65

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 (590) hide show
  1. package/README.md +4 -0
  2. package/dist/server/client/daemon-client-runtime-metrics.d.ts +6 -6
  3. package/dist/server/client/daemon-client-runtime-metrics.d.ts.map +1 -1
  4. package/dist/server/client/daemon-client-transport-types.d.ts +15 -13
  5. package/dist/server/client/daemon-client-transport-types.d.ts.map +1 -1
  6. package/dist/server/client/daemon-client-websocket-transport.d.ts +3 -2
  7. package/dist/server/client/daemon-client-websocket-transport.d.ts.map +1 -1
  8. package/dist/server/client/daemon-client-websocket-transport.js +9 -8
  9. package/dist/server/client/daemon-client-websocket-transport.js.map +1 -1
  10. package/dist/server/client/daemon-client.d.ts +88 -56
  11. package/dist/server/client/daemon-client.d.ts.map +1 -1
  12. package/dist/server/client/daemon-client.js +264 -111
  13. package/dist/server/client/daemon-client.js.map +1 -1
  14. package/dist/server/client/terminal-stream-router.d.ts +24 -0
  15. package/dist/server/client/terminal-stream-router.d.ts.map +1 -0
  16. package/dist/server/client/terminal-stream-router.js +100 -0
  17. package/dist/server/client/terminal-stream-router.js.map +1 -0
  18. package/dist/server/server/agent/activity-curator.d.ts +6 -3
  19. package/dist/server/server/agent/activity-curator.d.ts.map +1 -1
  20. package/dist/server/server/agent/activity-curator.js +45 -138
  21. package/dist/server/server/agent/activity-curator.js.map +1 -1
  22. package/dist/server/server/agent/agent-loading.d.ts.map +1 -1
  23. package/dist/server/server/agent/agent-loading.js +5 -3
  24. package/dist/server/server/agent/agent-loading.js.map +1 -1
  25. package/dist/server/server/agent/agent-manager.d.ts +46 -31
  26. package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
  27. package/dist/server/server/agent/agent-manager.js +457 -419
  28. package/dist/server/server/agent/agent-manager.js.map +1 -1
  29. package/dist/server/server/agent/agent-metadata-generator.d.ts +6 -11
  30. package/dist/server/server/agent/agent-metadata-generator.d.ts.map +1 -1
  31. package/dist/server/server/agent/agent-metadata-generator.js +3 -85
  32. package/dist/server/server/agent/agent-metadata-generator.js.map +1 -1
  33. package/dist/server/server/agent/agent-projections.d.ts +4 -6
  34. package/dist/server/server/agent/agent-projections.d.ts.map +1 -1
  35. package/dist/server/server/agent/agent-projections.js +59 -65
  36. package/dist/server/server/agent/agent-projections.js.map +1 -1
  37. package/dist/server/server/agent/agent-response-loop.d.ts +4 -4
  38. package/dist/server/server/agent/agent-response-loop.d.ts.map +1 -1
  39. package/dist/server/server/agent/agent-response-loop.js +58 -45
  40. package/dist/server/server/agent/agent-response-loop.js.map +1 -1
  41. package/dist/server/server/agent/agent-sdk-types.d.ts +58 -41
  42. package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -1
  43. package/dist/server/server/agent/agent-sdk-types.js.map +1 -1
  44. package/dist/server/server/agent/agent-storage.d.ts +2 -2
  45. package/dist/server/server/agent/agent-storage.d.ts.map +1 -1
  46. package/dist/server/server/agent/agent-storage.js +29 -36
  47. package/dist/server/server/agent/agent-storage.js.map +1 -1
  48. package/dist/server/server/agent/agent-stream-coalescer.d.ts +7 -7
  49. package/dist/server/server/agent/agent-stream-coalescer.d.ts.map +1 -1
  50. package/dist/server/server/agent/agent-stream-coalescer.js +1 -1
  51. package/dist/server/server/agent/agent-stream-coalescer.js.map +1 -1
  52. package/dist/server/server/agent/agent-timeline-store-types.d.ts +10 -10
  53. package/dist/server/server/agent/agent-timeline-store-types.d.ts.map +1 -1
  54. package/dist/server/server/agent/agent-timeline-store.d.ts +2 -2
  55. package/dist/server/server/agent/agent-timeline-store.d.ts.map +1 -1
  56. package/dist/server/server/agent/agent-timeline-store.js +103 -85
  57. package/dist/server/server/agent/agent-timeline-store.js.map +1 -1
  58. package/dist/server/server/agent/foreground-run-state.d.ts +50 -0
  59. package/dist/server/server/agent/foreground-run-state.d.ts.map +1 -0
  60. package/dist/server/server/agent/foreground-run-state.js +162 -0
  61. package/dist/server/server/agent/foreground-run-state.js.map +1 -0
  62. package/dist/server/server/agent/mcp-server.d.ts +5 -3
  63. package/dist/server/server/agent/mcp-server.d.ts.map +1 -1
  64. package/dist/server/server/agent/mcp-server.js +282 -234
  65. package/dist/server/server/agent/mcp-server.js.map +1 -1
  66. package/dist/server/server/agent/mcp-shared.d.ts +9 -2
  67. package/dist/server/server/agent/mcp-shared.d.ts.map +1 -1
  68. package/dist/server/server/agent/mcp-shared.js +9 -1
  69. package/dist/server/server/agent/mcp-shared.js.map +1 -1
  70. package/dist/server/server/agent/model-resolver.d.ts +2 -2
  71. package/dist/server/server/agent/model-resolver.d.ts.map +1 -1
  72. package/dist/server/server/agent/model-resolver.js +9 -5
  73. package/dist/server/server/agent/model-resolver.js.map +1 -1
  74. package/dist/server/server/agent/prompt-attachments.d.ts +4 -3
  75. package/dist/server/server/agent/prompt-attachments.d.ts.map +1 -1
  76. package/dist/server/server/agent/prompt-attachments.js +43 -4
  77. package/dist/server/server/agent/prompt-attachments.js.map +1 -1
  78. package/dist/server/server/agent/provider-launch-config.d.ts +28 -17
  79. package/dist/server/server/agent/provider-launch-config.d.ts.map +1 -1
  80. package/dist/server/server/agent/provider-launch-config.js +20 -9
  81. package/dist/server/server/agent/provider-launch-config.js.map +1 -1
  82. package/dist/server/server/agent/provider-manifest.d.ts.map +1 -1
  83. package/dist/server/server/agent/provider-manifest.js +7 -0
  84. package/dist/server/server/agent/provider-manifest.js.map +1 -1
  85. package/dist/server/server/agent/provider-registry.d.ts +4 -2
  86. package/dist/server/server/agent/provider-registry.d.ts.map +1 -1
  87. package/dist/server/server/agent/provider-registry.js +24 -21
  88. package/dist/server/server/agent/provider-registry.js.map +1 -1
  89. package/dist/server/server/agent/provider-snapshot-manager.d.ts +6 -5
  90. package/dist/server/server/agent/provider-snapshot-manager.d.ts.map +1 -1
  91. package/dist/server/server/agent/provider-snapshot-manager.js +40 -31
  92. package/dist/server/server/agent/provider-snapshot-manager.js.map +1 -1
  93. package/dist/server/server/agent/providers/acp-agent.d.ts +49 -13
  94. package/dist/server/server/agent/providers/acp-agent.d.ts.map +1 -1
  95. package/dist/server/server/agent/providers/acp-agent.js +404 -261
  96. package/dist/server/server/agent/providers/acp-agent.js.map +1 -1
  97. package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts +2 -0
  98. package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts.map +1 -1
  99. package/dist/server/server/agent/providers/claude/sidechain-tracker.js +47 -45
  100. package/dist/server/server/agent/providers/claude/sidechain-tracker.js.map +1 -1
  101. package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts +2 -2
  102. package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts.map +1 -1
  103. package/dist/server/server/agent/providers/claude/task-notification-tool-call.js +10 -5
  104. package/dist/server/server/agent/providers/claude/task-notification-tool-call.js.map +1 -1
  105. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.d.ts.map +1 -1
  106. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js +11 -2
  107. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js.map +1 -1
  108. package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts +2 -2
  109. package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts.map +1 -1
  110. package/dist/server/server/agent/providers/claude/tool-call-mapper.js +83 -206
  111. package/dist/server/server/agent/providers/claude/tool-call-mapper.js.map +1 -1
  112. package/dist/server/server/agent/providers/claude-agent.d.ts +20 -8
  113. package/dist/server/server/agent/providers/claude-agent.d.ts.map +1 -1
  114. package/dist/server/server/agent/providers/claude-agent.js +654 -554
  115. package/dist/server/server/agent/providers/claude-agent.js.map +1 -1
  116. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.d.ts +2 -2
  117. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.d.ts.map +1 -1
  118. package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts +2 -2
  119. package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts.map +1 -1
  120. package/dist/server/server/agent/providers/codex/tool-call-mapper.js +174 -185
  121. package/dist/server/server/agent/providers/codex/tool-call-mapper.js.map +1 -1
  122. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +62 -13
  123. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -1
  124. package/dist/server/server/agent/providers/codex-app-server-agent.js +873 -646
  125. package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -1
  126. package/dist/server/server/agent/providers/codex-rollout-timeline.d.ts +2 -2
  127. package/dist/server/server/agent/providers/codex-rollout-timeline.d.ts.map +1 -1
  128. package/dist/server/server/agent/providers/codex-rollout-timeline.js +58 -47
  129. package/dist/server/server/agent/providers/codex-rollout-timeline.js.map +1 -1
  130. package/dist/server/server/agent/providers/copilot-acp-agent.d.ts +2 -2
  131. package/dist/server/server/agent/providers/copilot-acp-agent.d.ts.map +1 -1
  132. package/dist/server/server/agent/providers/diagnostic-utils.d.ts +3 -3
  133. package/dist/server/server/agent/providers/diagnostic-utils.d.ts.map +1 -1
  134. package/dist/server/server/agent/providers/diagnostic-utils.js +82 -9
  135. package/dist/server/server/agent/providers/diagnostic-utils.js.map +1 -1
  136. package/dist/server/server/agent/providers/generic-acp-agent.d.ts +2 -2
  137. package/dist/server/server/agent/providers/generic-acp-agent.d.ts.map +1 -1
  138. package/dist/server/server/agent/providers/mock-load-test-agent.d.ts +6 -2
  139. package/dist/server/server/agent/providers/mock-load-test-agent.d.ts.map +1 -1
  140. package/dist/server/server/agent/providers/mock-load-test-agent.js +294 -113
  141. package/dist/server/server/agent/providers/mock-load-test-agent.js.map +1 -1
  142. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.d.ts +1 -1
  143. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.d.ts.map +1 -1
  144. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.js +94 -2
  145. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.js.map +1 -1
  146. package/dist/server/server/agent/providers/opencode/tool-call-mapper.d.ts +2 -2
  147. package/dist/server/server/agent/providers/opencode/tool-call-mapper.d.ts.map +1 -1
  148. package/dist/server/server/agent/providers/opencode/tool-call-mapper.js +24 -115
  149. package/dist/server/server/agent/providers/opencode/tool-call-mapper.js.map +1 -1
  150. package/dist/server/server/agent/providers/opencode-agent.d.ts +104 -3
  151. package/dist/server/server/agent/providers/opencode-agent.d.ts.map +1 -1
  152. package/dist/server/server/agent/providers/opencode-agent.js +786 -503
  153. package/dist/server/server/agent/providers/opencode-agent.js.map +1 -1
  154. package/dist/server/server/agent/providers/pi-direct-agent.d.ts +1 -0
  155. package/dist/server/server/agent/providers/pi-direct-agent.d.ts.map +1 -1
  156. package/dist/server/server/agent/providers/pi-direct-agent.js +109 -140
  157. package/dist/server/server/agent/providers/pi-direct-agent.js.map +1 -1
  158. package/dist/server/server/agent/providers/provider-runner.d.ts +27 -0
  159. package/dist/server/server/agent/providers/provider-runner.d.ts.map +1 -0
  160. package/dist/server/server/agent/providers/provider-runner.js +80 -0
  161. package/dist/server/server/agent/providers/provider-runner.js.map +1 -0
  162. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.d.ts.map +1 -1
  163. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.js +3 -1
  164. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.js.map +1 -1
  165. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts +9 -6
  166. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts.map +1 -1
  167. package/dist/server/server/agent/providers/tool-call-detail-primitives.js +102 -73
  168. package/dist/server/server/agent/providers/tool-call-detail-primitives.js.map +1 -1
  169. package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts +4 -2
  170. package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts.map +1 -1
  171. package/dist/server/server/agent/providers/tool-call-mapper-utils.js +31 -0
  172. package/dist/server/server/agent/providers/tool-call-mapper-utils.js.map +1 -1
  173. package/dist/server/server/agent/stt-manager.d.ts.map +1 -1
  174. package/dist/server/server/agent/stt-manager.js +63 -53
  175. package/dist/server/server/agent/stt-manager.js.map +1 -1
  176. package/dist/server/server/agent/timeline-projection.d.ts +27 -11
  177. package/dist/server/server/agent/timeline-projection.d.ts.map +1 -1
  178. package/dist/server/server/agent/timeline-projection.js +70 -15
  179. package/dist/server/server/agent/timeline-projection.js.map +1 -1
  180. package/dist/server/server/agent/tts-manager.d.ts.map +1 -1
  181. package/dist/server/server/agent/tts-manager.js +1 -0
  182. package/dist/server/server/agent/tts-manager.js.map +1 -1
  183. package/dist/server/server/agent-attention-policy.d.ts +2 -2
  184. package/dist/server/server/agent-attention-policy.d.ts.map +1 -1
  185. package/dist/server/server/auth.d.ts +25 -0
  186. package/dist/server/server/auth.d.ts.map +1 -0
  187. package/dist/server/server/auth.js +93 -0
  188. package/dist/server/server/auth.js.map +1 -0
  189. package/dist/server/server/bootstrap.d.ts +7 -5
  190. package/dist/server/server/bootstrap.d.ts.map +1 -1
  191. package/dist/server/server/bootstrap.js +550 -485
  192. package/dist/server/server/bootstrap.js.map +1 -1
  193. package/dist/server/server/chat/chat-service.d.ts +1 -1
  194. package/dist/server/server/chat/chat-service.d.ts.map +1 -1
  195. package/dist/server/server/chat/chat-service.js +3 -3
  196. package/dist/server/server/chat/chat-service.js.map +1 -1
  197. package/dist/server/server/checkout-diff-manager.d.ts +2 -2
  198. package/dist/server/server/checkout-diff-manager.d.ts.map +1 -1
  199. package/dist/server/server/checkout-git-utils.d.ts +5 -3
  200. package/dist/server/server/checkout-git-utils.d.ts.map +1 -1
  201. package/dist/server/server/checkout-git-utils.js +1 -2
  202. package/dist/server/server/checkout-git-utils.js.map +1 -1
  203. package/dist/server/server/config.d.ts.map +1 -1
  204. package/dist/server/server/config.js +79 -39
  205. package/dist/server/server/config.js.map +1 -1
  206. package/dist/server/server/connection-offer.d.ts +2 -2
  207. package/dist/server/server/connection-offer.d.ts.map +1 -1
  208. package/dist/server/server/daemon-config-store.d.ts +5 -3
  209. package/dist/server/server/daemon-config-store.d.ts.map +1 -1
  210. package/dist/server/server/daemon-config-store.js +26 -0
  211. package/dist/server/server/daemon-config-store.js.map +1 -1
  212. package/dist/server/server/daemon-keypair.d.ts +2 -2
  213. package/dist/server/server/daemon-keypair.d.ts.map +1 -1
  214. package/dist/server/server/editor-targets.d.ts +4 -4
  215. package/dist/server/server/editor-targets.d.ts.map +1 -1
  216. package/dist/server/server/editor-targets.js +11 -15
  217. package/dist/server/server/editor-targets.js.map +1 -1
  218. package/dist/server/server/exports.d.ts +10 -4
  219. package/dist/server/server/exports.d.ts.map +1 -1
  220. package/dist/server/server/exports.js +7 -4
  221. package/dist/server/server/exports.js.map +1 -1
  222. package/dist/server/server/file-download/token-store.d.ts +4 -4
  223. package/dist/server/server/file-download/token-store.d.ts.map +1 -1
  224. package/dist/server/server/file-explorer/service.d.ts +10 -0
  225. package/dist/server/server/file-explorer/service.d.ts.map +1 -1
  226. package/dist/server/server/file-explorer/service.js +38 -4
  227. package/dist/server/server/file-explorer/service.js.map +1 -1
  228. package/dist/server/server/index.js +25 -18
  229. package/dist/server/server/index.js.map +1 -1
  230. package/dist/server/server/logger.d.ts +4 -4
  231. package/dist/server/server/logger.d.ts.map +1 -1
  232. package/dist/server/server/logger.js +41 -21
  233. package/dist/server/server/logger.js.map +1 -1
  234. package/dist/server/server/loop/rpc-schemas.d.ts +52 -52
  235. package/dist/server/server/loop-service.d.ts +13 -12
  236. package/dist/server/server/loop-service.d.ts.map +1 -1
  237. package/dist/server/server/loop-service.js +22 -18
  238. package/dist/server/server/loop-service.js.map +1 -1
  239. package/dist/server/server/package-version.d.ts +2 -2
  240. package/dist/server/server/package-version.d.ts.map +1 -1
  241. package/dist/server/server/package-version.js +19 -17
  242. package/dist/server/server/package-version.js.map +1 -1
  243. package/dist/server/server/pagination/cursor.d.ts +16 -0
  244. package/dist/server/server/pagination/cursor.d.ts.map +1 -0
  245. package/dist/server/server/pagination/cursor.js +62 -0
  246. package/dist/server/server/pagination/cursor.js.map +1 -0
  247. package/dist/server/server/pagination/sortable-pager.d.ts +24 -0
  248. package/dist/server/server/pagination/sortable-pager.d.ts.map +1 -0
  249. package/dist/server/server/pagination/sortable-pager.js +68 -0
  250. package/dist/server/server/pagination/sortable-pager.js.map +1 -0
  251. package/dist/server/server/pairing-offer.d.ts +2 -2
  252. package/dist/server/server/pairing-offer.d.ts.map +1 -1
  253. package/dist/server/server/paseo-env.d.ts +9 -0
  254. package/dist/server/server/paseo-env.d.ts.map +1 -0
  255. package/dist/server/server/paseo-env.js +70 -0
  256. package/dist/server/server/paseo-env.js.map +1 -0
  257. package/dist/server/server/paseo-worktree-archive-service.d.ts +7 -5
  258. package/dist/server/server/paseo-worktree-archive-service.d.ts.map +1 -1
  259. package/dist/server/server/paseo-worktree-archive-service.js +70 -62
  260. package/dist/server/server/paseo-worktree-archive-service.js.map +1 -1
  261. package/dist/server/server/paseo-worktree-service.d.ts +13 -0
  262. package/dist/server/server/paseo-worktree-service.d.ts.map +1 -1
  263. package/dist/server/server/paseo-worktree-service.js +72 -3
  264. package/dist/server/server/paseo-worktree-service.js.map +1 -1
  265. package/dist/server/server/persisted-config.d.ts +87 -62
  266. package/dist/server/server/persisted-config.d.ts.map +1 -1
  267. package/dist/server/server/persisted-config.js +13 -4
  268. package/dist/server/server/persisted-config.js.map +1 -1
  269. package/dist/server/server/persistence-hooks.d.ts +8 -9
  270. package/dist/server/server/persistence-hooks.d.ts.map +1 -1
  271. package/dist/server/server/persistence-hooks.js +4 -12
  272. package/dist/server/server/persistence-hooks.js.map +1 -1
  273. package/dist/server/server/pid-lock.js.map +1 -1
  274. package/dist/server/server/push/push-service.d.ts.map +1 -1
  275. package/dist/server/server/push/push-service.js +1 -3
  276. package/dist/server/server/push/push-service.js.map +1 -1
  277. package/dist/server/server/relay-transport.d.ts +8 -8
  278. package/dist/server/server/relay-transport.d.ts.map +1 -1
  279. package/dist/server/server/relay-transport.js +43 -20
  280. package/dist/server/server/relay-transport.js.map +1 -1
  281. package/dist/server/server/resolve-worktree-creation-intent.d.ts +0 -10
  282. package/dist/server/server/resolve-worktree-creation-intent.d.ts.map +1 -1
  283. package/dist/server/server/resolve-worktree-creation-intent.js +1 -45
  284. package/dist/server/server/resolve-worktree-creation-intent.js.map +1 -1
  285. package/dist/server/server/schedule/service.d.ts.map +1 -1
  286. package/dist/server/server/schedule/service.js +2 -2
  287. package/dist/server/server/schedule/service.js.map +1 -1
  288. package/dist/server/server/script-health-monitor.d.ts.map +1 -1
  289. package/dist/server/server/script-health-monitor.js +7 -6
  290. package/dist/server/server/script-health-monitor.js.map +1 -1
  291. package/dist/server/server/script-proxy.js +1 -1
  292. package/dist/server/server/script-proxy.js.map +1 -1
  293. package/dist/server/server/script-status-projection.d.ts +10 -5
  294. package/dist/server/server/script-status-projection.d.ts.map +1 -1
  295. package/dist/server/server/script-status-projection.js +66 -47
  296. package/dist/server/server/script-status-projection.js.map +1 -1
  297. package/dist/server/server/server-id.d.ts +4 -4
  298. package/dist/server/server/server-id.d.ts.map +1 -1
  299. package/dist/server/server/session.d.ts +64 -65
  300. package/dist/server/server/session.d.ts.map +1 -1
  301. package/dist/server/server/session.js +1356 -1734
  302. package/dist/server/server/session.js.map +1 -1
  303. package/dist/server/server/speech/audio.js +1 -1
  304. package/dist/server/server/speech/audio.js.map +1 -1
  305. package/dist/server/server/speech/providers/local/config.d.ts +6 -6
  306. package/dist/server/server/speech/providers/local/config.d.ts.map +1 -1
  307. package/dist/server/server/speech/providers/local/config.js +41 -16
  308. package/dist/server/server/speech/providers/local/config.js.map +1 -1
  309. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.d.ts +2 -2
  310. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.d.ts.map +1 -1
  311. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.js +42 -19
  312. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.js.map +1 -1
  313. package/dist/server/server/speech/providers/local/runtime.d.ts +4 -4
  314. package/dist/server/server/speech/providers/local/runtime.d.ts.map +1 -1
  315. package/dist/server/server/speech/providers/local/runtime.js +108 -77
  316. package/dist/server/server/speech/providers/local/runtime.js.map +1 -1
  317. package/dist/server/server/speech/providers/local/sherpa/model-catalog.d.ts +2 -2
  318. package/dist/server/server/speech/providers/local/sherpa/model-catalog.d.ts.map +1 -1
  319. package/dist/server/server/speech/providers/local/sherpa/model-catalog.js +1 -4
  320. package/dist/server/server/speech/providers/local/sherpa/model-catalog.js.map +1 -1
  321. package/dist/server/server/speech/providers/local/sherpa/model-downloader.d.ts +2 -2
  322. package/dist/server/server/speech/providers/local/sherpa/model-downloader.d.ts.map +1 -1
  323. package/dist/server/server/speech/providers/local/sherpa/model-downloader.js +19 -19
  324. package/dist/server/server/speech/providers/local/sherpa/model-downloader.js.map +1 -1
  325. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.d.ts +28 -7
  326. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.d.ts.map +1 -1
  327. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js.map +1 -1
  328. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.d.ts +23 -4
  329. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.d.ts.map +1 -1
  330. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.js +35 -28
  331. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.js.map +1 -1
  332. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-loader.d.ts +5 -5
  333. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-loader.d.ts.map +1 -1
  334. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.d.ts +7 -7
  335. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.d.ts.map +1 -1
  336. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js +5 -0
  337. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js.map +1 -1
  338. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.d.ts.map +1 -1
  339. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js +3 -1
  340. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js.map +1 -1
  341. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.d.ts +2 -2
  342. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.d.ts.map +1 -1
  343. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js +3 -1
  344. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js.map +1 -1
  345. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.d.ts.map +1 -1
  346. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.js +10 -4
  347. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.js.map +1 -1
  348. package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.d.ts +2 -2
  349. package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.d.ts.map +1 -1
  350. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.d.ts +2 -2
  351. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.d.ts.map +1 -1
  352. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.js +4 -1
  353. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.js.map +1 -1
  354. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.d.ts +2 -2
  355. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.d.ts.map +1 -1
  356. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.js +18 -11
  357. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.js.map +1 -1
  358. package/dist/server/server/speech/providers/openai/config.d.ts +2 -2
  359. package/dist/server/server/speech/providers/openai/config.d.ts.map +1 -1
  360. package/dist/server/server/speech/providers/openai/config.js +58 -31
  361. package/dist/server/server/speech/providers/openai/config.js.map +1 -1
  362. package/dist/server/server/speech/providers/openai/realtime-transcription-session.d.ts.map +1 -1
  363. package/dist/server/server/speech/providers/openai/realtime-transcription-session.js +2 -2
  364. package/dist/server/server/speech/providers/openai/realtime-transcription-session.js.map +1 -1
  365. package/dist/server/server/speech/providers/openai/runtime.d.ts +4 -4
  366. package/dist/server/server/speech/providers/openai/runtime.d.ts.map +1 -1
  367. package/dist/server/server/speech/providers/openai/runtime.js +37 -32
  368. package/dist/server/server/speech/providers/openai/runtime.js.map +1 -1
  369. package/dist/server/server/speech/providers/openai/stt.d.ts.map +1 -1
  370. package/dist/server/server/speech/providers/openai/stt.js +4 -3
  371. package/dist/server/server/speech/providers/openai/stt.js.map +1 -1
  372. package/dist/server/server/speech/providers/openai/tts.d.ts.map +1 -1
  373. package/dist/server/server/speech/providers/openai/tts.js +3 -2
  374. package/dist/server/server/speech/providers/openai/tts.js.map +1 -1
  375. package/dist/server/server/speech/speech-config-resolver.d.ts.map +1 -1
  376. package/dist/server/server/speech/speech-config-resolver.js +46 -17
  377. package/dist/server/server/speech/speech-config-resolver.js.map +1 -1
  378. package/dist/server/server/speech/speech-provider.d.ts +2 -2
  379. package/dist/server/server/speech/speech-provider.d.ts.map +1 -1
  380. package/dist/server/server/speech/speech-runtime.d.ts +6 -6
  381. package/dist/server/server/speech/speech-runtime.d.ts.map +1 -1
  382. package/dist/server/server/speech/speech-runtime.js +17 -17
  383. package/dist/server/server/speech/speech-runtime.js.map +1 -1
  384. package/dist/server/server/speech/speech-types.d.ts +2 -2
  385. package/dist/server/server/speech/speech-types.d.ts.map +1 -1
  386. package/dist/server/server/speech/turn-detection-provider.d.ts +2 -2
  387. package/dist/server/server/speech/turn-detection-provider.d.ts.map +1 -1
  388. package/dist/server/server/utils/diff-highlighter.d.ts +0 -3
  389. package/dist/server/server/utils/diff-highlighter.d.ts.map +1 -1
  390. package/dist/server/server/utils/diff-highlighter.js +67 -66
  391. package/dist/server/server/utils/diff-highlighter.js.map +1 -1
  392. package/dist/server/server/voice/voice-turn-controller.d.ts.map +1 -1
  393. package/dist/server/server/voice/voice-turn-controller.js +1 -0
  394. package/dist/server/server/voice/voice-turn-controller.js.map +1 -1
  395. package/dist/server/server/voice-types.d.ts +2 -2
  396. package/dist/server/server/voice-types.d.ts.map +1 -1
  397. package/dist/server/server/websocket-server.d.ts +34 -22
  398. package/dist/server/server/websocket-server.d.ts.map +1 -1
  399. package/dist/server/server/websocket-server.js +360 -205
  400. package/dist/server/server/websocket-server.js.map +1 -1
  401. package/dist/server/server/workspace-directory.d.ts +69 -0
  402. package/dist/server/server/workspace-directory.d.ts.map +1 -0
  403. package/dist/server/server/workspace-directory.js +229 -0
  404. package/dist/server/server/workspace-directory.js.map +1 -0
  405. package/dist/server/server/workspace-git-metadata.d.ts +2 -2
  406. package/dist/server/server/workspace-git-metadata.d.ts.map +1 -1
  407. package/dist/server/server/workspace-git-metadata.js +2 -32
  408. package/dist/server/server/workspace-git-metadata.js.map +1 -1
  409. package/dist/server/server/workspace-git-service.d.ts +8 -4
  410. package/dist/server/server/workspace-git-service.d.ts.map +1 -1
  411. package/dist/server/server/workspace-git-service.js +163 -115
  412. package/dist/server/server/workspace-git-service.js.map +1 -1
  413. package/dist/server/server/workspace-reconciliation-service.d.ts +5 -4
  414. package/dist/server/server/workspace-reconciliation-service.d.ts.map +1 -1
  415. package/dist/server/server/workspace-reconciliation-service.js +82 -82
  416. package/dist/server/server/workspace-reconciliation-service.js.map +1 -1
  417. package/dist/server/server/workspace-registry-bootstrap.d.ts.map +1 -1
  418. package/dist/server/server/workspace-registry-bootstrap.js +40 -33
  419. package/dist/server/server/workspace-registry-bootstrap.js.map +1 -1
  420. package/dist/server/server/workspace-registry-model.d.ts +19 -6
  421. package/dist/server/server/workspace-registry-model.d.ts.map +1 -1
  422. package/dist/server/server/workspace-registry-model.js +35 -21
  423. package/dist/server/server/workspace-registry-model.js.map +1 -1
  424. package/dist/server/server/workspace-registry.d.ts +2 -2
  425. package/dist/server/server/workspace-script-runtime-store.d.ts +2 -2
  426. package/dist/server/server/workspace-script-runtime-store.d.ts.map +1 -1
  427. package/dist/server/server/workspace-service-env.js +3 -3
  428. package/dist/server/server/workspace-service-env.js.map +1 -1
  429. package/dist/server/server/worktree-bootstrap.d.ts +4 -4
  430. package/dist/server/server/worktree-bootstrap.d.ts.map +1 -1
  431. package/dist/server/server/worktree-bootstrap.js +101 -69
  432. package/dist/server/server/worktree-bootstrap.js.map +1 -1
  433. package/dist/server/server/worktree-core.d.ts +2 -0
  434. package/dist/server/server/worktree-core.d.ts.map +1 -1
  435. package/dist/server/server/worktree-core.js.map +1 -1
  436. package/dist/server/server/worktree-errors.d.ts +1 -1
  437. package/dist/server/server/worktree-errors.d.ts.map +1 -1
  438. package/dist/server/server/worktree-errors.js +1 -4
  439. package/dist/server/server/worktree-errors.js.map +1 -1
  440. package/dist/server/server/worktree-session.d.ts +54 -27
  441. package/dist/server/server/worktree-session.d.ts.map +1 -1
  442. package/dist/server/server/worktree-session.js +95 -44
  443. package/dist/server/server/worktree-session.js.map +1 -1
  444. package/dist/server/services/github-service.d.ts +1 -7
  445. package/dist/server/services/github-service.d.ts.map +1 -1
  446. package/dist/server/services/github-service.js +123 -143
  447. package/dist/server/services/github-service.js.map +1 -1
  448. package/dist/server/shared/agent-attention-notification.d.ts +9 -8
  449. package/dist/server/shared/agent-attention-notification.d.ts.map +1 -1
  450. package/dist/server/shared/agent-attention-notification.js +27 -17
  451. package/dist/server/shared/agent-attention-notification.js.map +1 -1
  452. package/dist/server/shared/binary-frames/file-transfer.d.ts +56 -0
  453. package/dist/server/shared/binary-frames/file-transfer.d.ts.map +1 -0
  454. package/dist/server/shared/binary-frames/file-transfer.js +108 -0
  455. package/dist/server/shared/binary-frames/file-transfer.js.map +1 -0
  456. package/dist/server/shared/binary-frames/index.d.ts +3 -0
  457. package/dist/server/shared/binary-frames/index.d.ts.map +1 -0
  458. package/dist/server/shared/binary-frames/index.js +3 -0
  459. package/dist/server/shared/binary-frames/index.js.map +1 -0
  460. package/dist/server/shared/{terminal-stream-protocol.d.ts → binary-frames/terminal.d.ts} +4 -4
  461. package/dist/server/shared/binary-frames/terminal.d.ts.map +1 -0
  462. package/dist/server/shared/{terminal-stream-protocol.js → binary-frames/terminal.js} +2 -2
  463. package/dist/server/shared/binary-frames/terminal.js.map +1 -0
  464. package/dist/server/shared/client-capabilities.d.ts +5 -0
  465. package/dist/server/shared/client-capabilities.d.ts.map +1 -0
  466. package/dist/server/shared/client-capabilities.js +4 -0
  467. package/dist/server/shared/client-capabilities.js.map +1 -0
  468. package/dist/server/shared/connection-offer.d.ts +8 -0
  469. package/dist/server/shared/connection-offer.d.ts.map +1 -1
  470. package/dist/server/shared/connection-offer.js +35 -0
  471. package/dist/server/shared/connection-offer.js.map +1 -1
  472. package/dist/server/shared/daemon-endpoints.d.ts +18 -3
  473. package/dist/server/shared/daemon-endpoints.d.ts.map +1 -1
  474. package/dist/server/shared/daemon-endpoints.js +82 -8
  475. package/dist/server/shared/daemon-endpoints.js.map +1 -1
  476. package/dist/server/shared/host-connection-schema.d.ts +23 -0
  477. package/dist/server/shared/host-connection-schema.d.ts.map +1 -0
  478. package/dist/server/shared/host-connection-schema.js +9 -0
  479. package/dist/server/shared/host-connection-schema.js.map +1 -0
  480. package/dist/server/shared/messages.d.ts +25073 -3453
  481. package/dist/server/shared/messages.d.ts.map +1 -1
  482. package/dist/server/shared/messages.js +152 -36
  483. package/dist/server/shared/messages.js.map +1 -1
  484. package/dist/server/shared/tool-call-display.d.ts +2 -2
  485. package/dist/server/shared/tool-call-display.d.ts.map +1 -1
  486. package/dist/server/terminal/terminal-manager-factory.d.ts +7 -0
  487. package/dist/server/terminal/terminal-manager-factory.d.ts.map +1 -0
  488. package/dist/server/terminal/terminal-manager-factory.js +13 -0
  489. package/dist/server/terminal/terminal-manager-factory.js.map +1 -0
  490. package/dist/server/terminal/terminal-manager.d.ts +7 -1
  491. package/dist/server/terminal/terminal-manager.d.ts.map +1 -1
  492. package/dist/server/terminal/terminal-manager.js +15 -4
  493. package/dist/server/terminal/terminal-manager.js.map +1 -1
  494. package/dist/server/terminal/terminal-output-coalescer.d.ts +6 -6
  495. package/dist/server/terminal/terminal-output-coalescer.d.ts.map +1 -1
  496. package/dist/server/terminal/terminal-session-controller.d.ts +63 -0
  497. package/dist/server/terminal/terminal-session-controller.d.ts.map +1 -0
  498. package/dist/server/terminal/terminal-session-controller.js +615 -0
  499. package/dist/server/terminal/terminal-session-controller.js.map +1 -0
  500. package/dist/server/terminal/terminal-ts-loader.mjs +20 -0
  501. package/dist/server/terminal/terminal-worker-process.d.ts +2 -0
  502. package/dist/server/terminal/terminal-worker-process.d.ts.map +1 -0
  503. package/dist/server/terminal/terminal-worker-process.js +221 -0
  504. package/dist/server/terminal/terminal-worker-process.js.map +1 -0
  505. package/dist/server/terminal/terminal-worker-protocol.d.ts +113 -0
  506. package/dist/server/terminal/terminal-worker-protocol.d.ts.map +1 -0
  507. package/dist/server/terminal/terminal-worker-protocol.js +2 -0
  508. package/dist/server/terminal/terminal-worker-protocol.js.map +1 -0
  509. package/dist/server/terminal/terminal.d.ts +10 -2
  510. package/dist/server/terminal/terminal.d.ts.map +1 -1
  511. package/dist/server/terminal/terminal.js +79 -28
  512. package/dist/server/terminal/terminal.js.map +1 -1
  513. package/dist/server/terminal/worker-terminal-manager.d.ts +19 -0
  514. package/dist/server/terminal/worker-terminal-manager.d.ts.map +1 -0
  515. package/dist/server/terminal/worker-terminal-manager.js +466 -0
  516. package/dist/server/terminal/worker-terminal-manager.js.map +1 -0
  517. package/dist/server/utils/checkout-git.d.ts +13 -12
  518. package/dist/server/utils/checkout-git.d.ts.map +1 -1
  519. package/dist/server/utils/checkout-git.js +351 -281
  520. package/dist/server/utils/checkout-git.js.map +1 -1
  521. package/dist/server/utils/directory-suggestions.d.ts.map +1 -1
  522. package/dist/server/utils/directory-suggestions.js +22 -34
  523. package/dist/server/utils/directory-suggestions.js.map +1 -1
  524. package/dist/server/utils/executable.d.ts +1 -14
  525. package/dist/server/utils/executable.d.ts.map +1 -1
  526. package/dist/server/utils/executable.js +13 -49
  527. package/dist/server/utils/executable.js.map +1 -1
  528. package/dist/server/utils/github-remote.d.ts +13 -0
  529. package/dist/server/utils/github-remote.d.ts.map +1 -0
  530. package/dist/server/utils/github-remote.js +128 -0
  531. package/dist/server/utils/github-remote.js.map +1 -0
  532. package/dist/server/utils/paseo-config-file.d.ts +30 -0
  533. package/dist/server/utils/paseo-config-file.d.ts.map +1 -0
  534. package/dist/server/utils/paseo-config-file.js +90 -0
  535. package/dist/server/utils/paseo-config-file.js.map +1 -0
  536. package/dist/server/utils/paseo-config-schema.d.ts +290 -0
  537. package/dist/server/utils/paseo-config-schema.d.ts.map +1 -0
  538. package/dist/server/utils/paseo-config-schema.js +60 -0
  539. package/dist/server/utils/paseo-config-schema.js.map +1 -0
  540. package/dist/server/utils/process-tree.d.ts +25 -0
  541. package/dist/server/utils/process-tree.d.ts.map +1 -0
  542. package/dist/server/utils/process-tree.js +96 -0
  543. package/dist/server/utils/process-tree.js.map +1 -0
  544. package/dist/server/utils/project-icon.d.ts.map +1 -1
  545. package/dist/server/utils/project-icon.js +84 -109
  546. package/dist/server/utils/project-icon.js.map +1 -1
  547. package/dist/server/utils/promise-timeout.d.ts +2 -2
  548. package/dist/server/utils/promise-timeout.d.ts.map +1 -1
  549. package/dist/server/utils/run-git-command.d.ts +3 -1
  550. package/dist/server/utils/run-git-command.d.ts.map +1 -1
  551. package/dist/server/utils/run-git-command.js +10 -1
  552. package/dist/server/utils/run-git-command.js.map +1 -1
  553. package/dist/server/utils/script-hostname.d.ts +2 -2
  554. package/dist/server/utils/script-hostname.d.ts.map +1 -1
  555. package/dist/server/utils/spawn.d.ts +10 -3
  556. package/dist/server/utils/spawn.d.ts.map +1 -1
  557. package/dist/server/utils/spawn.js +30 -5
  558. package/dist/server/utils/spawn.js.map +1 -1
  559. package/dist/server/utils/windows-command.d.ts +15 -0
  560. package/dist/server/utils/windows-command.d.ts.map +1 -0
  561. package/dist/server/utils/windows-command.js +41 -0
  562. package/dist/server/utils/windows-command.js.map +1 -0
  563. package/dist/server/utils/worktree-metadata.d.ts +44 -0
  564. package/dist/server/utils/worktree-metadata.d.ts.map +1 -1
  565. package/dist/server/utils/worktree-metadata.js +58 -0
  566. package/dist/server/utils/worktree-metadata.js.map +1 -1
  567. package/dist/server/utils/worktree.d.ts +23 -8
  568. package/dist/server/utils/worktree.d.ts.map +1 -1
  569. package/dist/server/utils/worktree.js +81 -63
  570. package/dist/server/utils/worktree.js.map +1 -1
  571. package/dist/src/server/pid-lock.js.map +1 -1
  572. package/package.json +17 -21
  573. package/dist/server/server/agent/llm-openai.d.ts +0 -7
  574. package/dist/server/server/agent/llm-openai.d.ts.map +0 -1
  575. package/dist/server/server/agent/llm-openai.js +0 -8
  576. package/dist/server/server/agent/llm-openai.js.map +0 -1
  577. package/dist/server/server/agent/orchestrator.d.ts +0 -12
  578. package/dist/server/server/agent/orchestrator.d.ts.map +0 -1
  579. package/dist/server/server/agent/orchestrator.js +0 -12
  580. package/dist/server/server/agent/orchestrator.js.map +0 -1
  581. package/dist/server/server/types.d.ts +0 -5
  582. package/dist/server/server/types.d.ts.map +0 -1
  583. package/dist/server/server/types.js +0 -3
  584. package/dist/server/server/types.js.map +0 -1
  585. package/dist/server/server/workspace-registry.test-helpers.d.ts +0 -37
  586. package/dist/server/server/workspace-registry.test-helpers.d.ts.map +0 -1
  587. package/dist/server/server/workspace-registry.test-helpers.js +0 -121
  588. package/dist/server/server/workspace-registry.test-helpers.js.map +0 -1
  589. package/dist/server/shared/terminal-stream-protocol.d.ts.map +0 -1
  590. package/dist/server/shared/terminal-stream-protocol.js.map +0 -1
@@ -5,10 +5,24 @@ import { AGENT_LIFECYCLE_STATUSES, } from "../../shared/agent-lifecycle.js";
5
5
  import { z } from "zod";
6
6
  import { InMemoryAgentTimelineStore, } from "./agent-timeline-store.js";
7
7
  import { AGENT_STREAM_COALESCE_DEFAULT_WINDOW_MS, AgentStreamCoalescer, } from "./agent-stream-coalescer.js";
8
+ import { ForegroundRunState } from "./foreground-run-state.js";
8
9
  import { getAgentProviderDefinition } from "./provider-manifest.js";
9
10
  const RELOAD_SESSION_CLOSE_TIMEOUT_MS = 3000;
10
11
  const INTERRUPT_SESSION_TIMEOUT_MS = 2000;
12
+ function formatProviderList(providers) {
13
+ return providers.length > 0 ? providers.join(", ") : "none";
14
+ }
11
15
  export { AGENT_LIFECYCLE_STATUSES };
16
+ function resolveInitialAttention(input) {
17
+ if (input == null || !input.requiresAttention) {
18
+ return { requiresAttention: false };
19
+ }
20
+ return {
21
+ requiresAttention: true,
22
+ attentionReason: input.attentionReason,
23
+ attentionTimestamp: new Date(input.attentionTimestamp),
24
+ };
25
+ }
12
26
  const SYSTEM_ERROR_PREFIX = "[System Error]";
13
27
  function attachPersistenceCwd(handle, cwd) {
14
28
  if (!handle) {
@@ -17,28 +31,30 @@ function attachPersistenceCwd(handle, cwd) {
17
31
  return {
18
32
  ...handle,
19
33
  metadata: {
20
- ...(handle.metadata ?? {}),
34
+ ...handle.metadata,
21
35
  cwd,
22
36
  },
23
37
  };
24
38
  }
25
- const BUSY_STATUSES = ["initializing", "running"];
39
+ const BUSY_STATUSES = new Set(["initializing", "running"]);
26
40
  const AgentIdSchema = z.string().uuid();
27
41
  function isAgentBusy(status) {
28
- return BUSY_STATUSES.includes(status);
42
+ return BUSY_STATUSES.has(status);
29
43
  }
30
44
  function isTurnTerminalEvent(event) {
31
45
  return (event.type === "turn_completed" ||
32
46
  event.type === "turn_failed" ||
33
47
  event.type === "turn_canceled");
34
48
  }
49
+ function abortMessage(reason, fallbackMessage) {
50
+ if (typeof reason === "string")
51
+ return reason;
52
+ if (reason instanceof Error)
53
+ return reason.message;
54
+ return fallbackMessage;
55
+ }
35
56
  function createAbortError(signal, fallbackMessage) {
36
- const reason = signal?.reason;
37
- const message = typeof reason === "string"
38
- ? reason
39
- : reason instanceof Error
40
- ? reason.message
41
- : fallbackMessage;
57
+ const message = abortMessage(signal?.reason, fallbackMessage);
42
58
  return Object.assign(new Error(message), { name: "AbortError" });
43
59
  }
44
60
  function validateAgentId(agentId, source) {
@@ -55,14 +71,39 @@ function normalizeMessageId(messageId) {
55
71
  const trimmed = messageId.trim();
56
72
  return trimmed.length > 0 ? trimmed : undefined;
57
73
  }
74
+ function isDuplicateLegacyUserMessage(item, canonicalUserMessagesById) {
75
+ if (item.type !== "user_message") {
76
+ return false;
77
+ }
78
+ const eventMessageId = normalizeMessageId(item.messageId);
79
+ if (!eventMessageId) {
80
+ return false;
81
+ }
82
+ return canonicalUserMessagesById.get(eventMessageId) === item.text;
83
+ }
84
+ function buildExplicitTimelineSeedForRegister(now, options) {
85
+ const hasTimeline = Boolean(options?.timeline?.length);
86
+ const hasTimelineRows = Boolean(options?.timelineRows?.length);
87
+ const hasTimelineNextSeq = options?.timelineNextSeq !== undefined;
88
+ if (!hasTimeline && !hasTimelineRows && !hasTimelineNextSeq) {
89
+ return null;
90
+ }
91
+ return {
92
+ items: options?.timeline,
93
+ rows: options?.timelineRows,
94
+ nextSeq: options?.timelineNextSeq,
95
+ timestamp: (options?.updatedAt ?? options?.createdAt ?? now).toISOString(),
96
+ };
97
+ }
58
98
  export class AgentManager {
59
99
  constructor(options) {
60
100
  this.clients = new Map();
101
+ this.providerEnabled = new Map();
61
102
  this.agents = new Map();
62
103
  this.timelineStore = new InMemoryAgentTimelineStore();
63
104
  this.agentsAwaitingInitialSnapshotPersist = new Set();
64
105
  this.sessionEventTails = new Map();
65
- this.pendingForegroundRuns = new Map();
106
+ this.foregroundRuns = new ForegroundRunState();
66
107
  this.subscribers = new Set();
67
108
  this.previousStatuses = new Map();
68
109
  this.backgroundTasks = new Set();
@@ -84,17 +125,26 @@ export class AgentManager {
84
125
  this.notifyForegroundTurnWaiters(agentId, event);
85
126
  },
86
127
  });
87
- if (options?.clients) {
88
- for (const [provider, client] of Object.entries(options.clients)) {
89
- if (client) {
90
- this.registerClient(provider, client);
91
- }
92
- }
93
- }
128
+ this.updateProviderRegistry({
129
+ providerDefinitions: options.providerDefinitions ?? {},
130
+ clients: options.clients ?? {},
131
+ });
94
132
  }
95
133
  registerClient(provider, client) {
96
134
  this.clients.set(provider, client);
97
135
  }
136
+ updateProviderRegistry(input) {
137
+ for (const [provider, definition] of Object.entries(input.providerDefinitions)) {
138
+ if (definition) {
139
+ this.providerEnabled.set(provider, definition.enabled);
140
+ }
141
+ }
142
+ for (const [provider, client] of Object.entries(input.clients)) {
143
+ if (client) {
144
+ this.clients.set(provider, client);
145
+ }
146
+ }
147
+ }
98
148
  getRegisteredProviderIds() {
99
149
  return Array.from(this.clients.keys());
100
150
  }
@@ -148,7 +198,7 @@ export class AgentManager {
148
198
  }
149
199
  return (agent.lifecycle === "running" ||
150
200
  Boolean(agent.activeForegroundTurnId) ||
151
- this.hasPendingForegroundRun(agentId));
201
+ this.foregroundRuns.hasPendingRun(agentId));
152
202
  }
153
203
  subscribe(callback, options) {
154
204
  const targetAgentId = options?.agentId == null ? null : validateAgentId(options.agentId, "subscribe");
@@ -187,9 +237,7 @@ export class AgentManager {
187
237
  listAgents() {
188
238
  return Array.from(this.agents.values())
189
239
  .filter((agent) => !agent.internal)
190
- .map((agent) => ({
191
- ...agent,
192
- }));
240
+ .map((agent) => Object.assign({}, agent));
193
241
  }
194
242
  async listPersistedAgents(options) {
195
243
  if (options?.provider) {
@@ -199,26 +247,32 @@ export class AgentManager {
199
247
  }
200
248
  return client.listPersistedAgents({ limit: options.limit });
201
249
  }
202
- const descriptors = [];
203
- for (const [provider, client] of this.clients.entries()) {
204
- if (!client.listPersistedAgents) {
205
- continue;
206
- }
250
+ const providerEntries = Array.from(this.clients.entries()).filter(([, client]) => !!client.listPersistedAgents);
251
+ const descriptorLists = await Promise.all(providerEntries.map(async ([provider, client]) => {
207
252
  try {
208
- const entries = await client.listPersistedAgents({
209
- limit: options?.limit,
210
- });
211
- descriptors.push(...entries);
253
+ return await client.listPersistedAgents({ limit: options?.limit });
212
254
  }
213
255
  catch (error) {
214
256
  this.logger.warn({ err: error, provider }, "Failed to list persisted agents for provider");
257
+ return [];
215
258
  }
216
- }
259
+ }));
260
+ const descriptors = descriptorLists.flat();
217
261
  const limit = options?.limit ?? 20;
218
262
  return descriptors
219
263
  .sort((a, b) => b.lastActivityAt.getTime() - a.lastActivityAt.getTime())
220
264
  .slice(0, limit);
221
265
  }
266
+ async findPersistedAgent(provider, sessionId) {
267
+ const client = this.requireClient(provider);
268
+ if (!client.listPersistedAgents) {
269
+ return null;
270
+ }
271
+ const descriptors = await client.listPersistedAgents({ limit: 200 });
272
+ return (descriptors.find((descriptor) => {
273
+ return (descriptor.sessionId === sessionId || descriptor.persistence.nativeHandle === sessionId);
274
+ }) ?? null);
275
+ }
222
276
  async listProviderAvailability() {
223
277
  const checks = Array.from(this.clients.keys()).map(async (provider) => {
224
278
  const client = this.clients.get(provider);
@@ -322,16 +376,15 @@ export class AgentManager {
322
376
  type: "http",
323
377
  url: `${this.mcpBaseUrl}?callerAgentId=${resolvedAgentId}`,
324
378
  },
325
- ...(config.mcpServers ?? {}),
379
+ ...config.mcpServers,
326
380
  },
327
381
  };
382
+ this.requireEnabledProvider(injectedConfig.provider);
328
383
  const normalizedConfig = await this.normalizeConfig(injectedConfig);
329
384
  const launchContext = this.buildLaunchContext(resolvedAgentId);
330
- const client = this.requireClient(normalizedConfig.provider);
331
- const available = await client.isAvailable();
332
- if (!available) {
333
- throw new Error(`Provider '${normalizedConfig.provider}' is not available. Please ensure the CLI is installed.`);
334
- }
385
+ const client = await this.requireAvailableClient({
386
+ provider: normalizedConfig.provider,
387
+ });
335
388
  const session = await client.createSession(normalizedConfig, launchContext);
336
389
  return this.registerSession(session, normalizedConfig, resolvedAgentId, {
337
390
  labels: options?.labels,
@@ -393,11 +446,7 @@ export class AgentManager {
393
446
  existing.unsubscribeSession();
394
447
  existing.unsubscribeSession = null;
395
448
  }
396
- for (const waiter of existing.foregroundTurnWaiters) {
397
- this.settleForegroundTurnWaiter(waiter);
398
- }
399
- existing.foregroundTurnWaiters.clear();
400
- this.settlePendingForegroundRun(agentId);
449
+ this.foregroundRuns.clearAgent(agentId, existing);
401
450
  await this.closeReloadedSession(existing.session, agentId);
402
451
  // Preserve existing labels and timeline during reload.
403
452
  return this.registerSession(session, normalizedConfig, agentId, {
@@ -443,10 +492,10 @@ export class AgentManager {
443
492
  try {
444
493
  return await Promise.race([
445
494
  operation,
446
- new Promise((resolve) => {
495
+ new Promise((resolvePromise) => {
447
496
  timer = setTimeout(() => {
448
497
  didTimeOut = true;
449
- resolve("timed_out");
498
+ resolvePromise("timed_out");
450
499
  }, options.timeoutMs);
451
500
  }),
452
501
  ]);
@@ -751,119 +800,88 @@ export class AgentManager {
751
800
  agentId,
752
801
  lifecycle: existingAgent.lifecycle,
753
802
  activeForegroundTurnId: existingAgent.activeForegroundTurnId,
754
- hasPendingForegroundRun: this.hasPendingForegroundRun(agentId),
803
+ hasPendingForegroundRun: this.foregroundRuns.hasPendingRun(agentId),
755
804
  promptType: typeof prompt === "string" ? "string" : "structured",
756
805
  hasRunOptions: Boolean(options),
757
806
  }, "streamAgent: requested");
758
- if (existingAgent.activeForegroundTurnId || this.hasPendingForegroundRun(agentId)) {
807
+ if (existingAgent.activeForegroundTurnId || this.foregroundRuns.hasPendingRun(agentId)) {
759
808
  this.logger.trace({
760
809
  agentId,
761
810
  lifecycle: existingAgent.lifecycle,
762
- hasPendingForegroundRun: this.hasPendingForegroundRun(agentId),
811
+ hasPendingForegroundRun: this.foregroundRuns.hasPendingRun(agentId),
763
812
  }, "streamAgent: rejected because a foreground run is already in flight");
764
813
  throw new Error(`Agent ${agentId} already has an active run`);
765
814
  }
766
815
  const agent = existingAgent;
767
816
  agent.pendingReplacement = false;
768
817
  agent.lastError = undefined;
769
- const self = this;
770
- const pendingRun = self.createPendingForegroundRun();
771
- self.pendingForegroundRuns.set(agentId, pendingRun);
772
- const streamForwarder = (async function* streamForwarder() {
818
+ const pendingRun = this.foregroundRuns.createPendingRun(agentId);
819
+ const streamForwarder = async function* streamForwarder() {
773
820
  let turnId;
774
- let waiter = null;
821
+ let turnStream = null;
775
822
  try {
776
823
  const result = await agent.session.startTurn(prompt, options);
777
824
  turnId = result.turnId;
778
825
  }
779
826
  catch (error) {
780
827
  const errorMsg = error instanceof Error ? error.message : "Failed to start turn";
781
- self.handleStreamEvent(agent, {
828
+ await this.handleStreamEvent(agent, {
782
829
  type: "turn_failed",
783
830
  provider: agent.provider,
784
831
  error: errorMsg,
785
832
  });
786
- self.finalizeForegroundTurn(agent);
833
+ this.finalizeForegroundTurn(agent);
834
+ this.foregroundRuns.settlePendingRun(agentId, pendingRun.token);
787
835
  throw error;
788
836
  }
789
837
  pendingRun.started = true;
790
838
  agent.activeForegroundTurnId = turnId;
791
839
  agent.lifecycle = "running";
792
- self.touchUpdatedAt(agent);
793
- self.emitState(agent);
794
- self.logger.trace({
840
+ this.touchUpdatedAt(agent);
841
+ this.emitState(agent);
842
+ this.logger.trace({
795
843
  agentId,
796
844
  lifecycle: agent.lifecycle,
797
845
  activeForegroundTurnId: agent.activeForegroundTurnId,
798
846
  }, "streamAgent: started");
799
- // Create a pushable queue for this foreground turn
800
- const queue = [];
801
- let queueResolve = null;
802
- let done = false;
803
- let resolveSettled;
804
- const settledPromise = new Promise((resolve) => {
805
- resolveSettled = resolve;
806
- });
807
- waiter = {
808
- turnId,
809
- settled: false,
810
- settledPromise,
811
- resolveSettled,
812
- callback: (event) => {
813
- queue.push(event);
814
- if (queueResolve) {
815
- queueResolve();
816
- queueResolve = null;
817
- }
818
- },
819
- };
820
- agent.foregroundTurnWaiters.add(waiter);
847
+ turnStream = this.foregroundRuns.createTurnStream(turnId);
848
+ this.foregroundRuns.addWaiter(agent, turnStream.waiter);
821
849
  try {
822
- while (!done) {
823
- while (queue.length > 0) {
824
- const event = queue.shift();
825
- yield event;
826
- if (isTurnTerminalEvent(event)) {
827
- done = true;
828
- break;
829
- }
830
- }
831
- if (!done && queue.length === 0) {
832
- if (waiter.settled) {
833
- break;
834
- }
835
- await new Promise((resolve) => {
836
- queueResolve = resolve;
837
- });
838
- }
850
+ for await (const event of turnStream.events(isTurnTerminalEvent)) {
851
+ yield event;
839
852
  }
840
853
  }
841
854
  finally {
842
- if (waiter) {
843
- agent.foregroundTurnWaiters.delete(waiter);
844
- self.settleForegroundTurnWaiter(waiter);
855
+ if (turnStream) {
856
+ this.foregroundRuns.deleteWaiter(agent, turnStream.waiter);
845
857
  }
846
- self.settlePendingForegroundRun(agentId, pendingRun.token);
858
+ this.foregroundRuns.settlePendingRun(agentId, pendingRun.token);
847
859
  if (!agent.activeForegroundTurnId) {
848
- await self.refreshRuntimeInfo(agent);
860
+ await this.refreshRuntimeInfo(agent);
849
861
  }
850
862
  }
851
- })();
863
+ }.call(this);
852
864
  return streamForwarder;
853
865
  }
854
866
  finalizeForegroundTurn(agent, turnId) {
855
867
  const mutableAgent = agent;
856
868
  if (turnId) {
857
- this.rememberFinalizedForegroundTurn(mutableAgent, turnId);
869
+ this.foregroundRuns.rememberFinalizedTurn(mutableAgent, turnId);
858
870
  }
859
871
  mutableAgent.activeForegroundTurnId = null;
860
872
  const terminalError = mutableAgent.lastError;
861
873
  const shouldHoldBusyForReplacement = mutableAgent.pendingReplacement && !terminalError;
862
- mutableAgent.lifecycle = shouldHoldBusyForReplacement
863
- ? "running"
864
- : terminalError
865
- ? "error"
866
- : "idle";
874
+ let nextLifecycle;
875
+ if (shouldHoldBusyForReplacement) {
876
+ nextLifecycle = "running";
877
+ }
878
+ else if (terminalError) {
879
+ nextLifecycle = "error";
880
+ }
881
+ else {
882
+ nextLifecycle = "idle";
883
+ }
884
+ mutableAgent.lifecycle = nextLifecycle;
867
885
  const persistenceHandle = mutableAgent.session.describePersistence() ??
868
886
  (mutableAgent.runtimeInfo?.sessionId
869
887
  ? { provider: mutableAgent.provider, sessionId: mutableAgent.runtimeInfo.sessionId }
@@ -886,7 +904,7 @@ export class AgentManager {
886
904
  const snapshot = this.requireAgent(agentId);
887
905
  if (snapshot.lifecycle !== "running" &&
888
906
  !snapshot.activeForegroundTurnId &&
889
- !this.hasPendingForegroundRun(agentId)) {
907
+ !this.foregroundRuns.hasPendingRun(agentId)) {
890
908
  return this.streamAgent(agentId, prompt, options);
891
909
  }
892
910
  const agent = this.requireSessionAgent(agentId);
@@ -894,36 +912,35 @@ export class AgentManager {
894
912
  agent.lifecycle = "running";
895
913
  this.touchUpdatedAt(agent);
896
914
  this.emitState(agent);
897
- const self = this;
898
- return (async function* replaceRunForwarder() {
915
+ return async function* replaceRunForwarder() {
899
916
  try {
900
- await self.cancelAgentRun(agentId);
901
- const nextRun = self.streamAgent(agentId, prompt, options);
917
+ await this.cancelAgentRun(agentId);
918
+ const nextRun = this.streamAgent(agentId, prompt, options);
902
919
  for await (const event of nextRun) {
903
920
  yield event;
904
921
  }
905
922
  }
906
923
  catch (error) {
907
- const latest = self.agents.get(agentId);
924
+ const latest = this.agents.get(agentId);
908
925
  if (latest) {
909
926
  const latestActive = latest;
910
927
  latestActive.pendingReplacement = false;
911
928
  if (!latestActive.activeForegroundTurnId && latestActive.lifecycle === "running") {
912
929
  latestActive.lifecycle = "idle";
913
- self.touchUpdatedAt(latestActive);
914
- self.emitState(latestActive);
930
+ this.touchUpdatedAt(latestActive);
931
+ this.emitState(latestActive);
915
932
  }
916
933
  }
917
934
  throw error;
918
935
  }
919
- })();
936
+ }.call(this);
920
937
  }
921
938
  async waitForAgentRunStart(agentId, options) {
922
939
  const snapshot = this.getAgent(agentId);
923
940
  if (!snapshot) {
924
941
  throw new Error(`Agent ${agentId} not found`);
925
942
  }
926
- const pendingRun = this.getPendingForegroundRun(agentId);
943
+ const pendingRun = this.foregroundRuns.getPendingRun(agentId);
927
944
  if ((snapshot.lifecycle === "running" || pendingRun?.started) && !snapshot.pendingReplacement) {
928
945
  return;
929
946
  }
@@ -933,7 +950,7 @@ export class AgentManager {
933
950
  if (options?.signal?.aborted) {
934
951
  throw createAbortError(options.signal, "wait_for_agent_start aborted");
935
952
  }
936
- await new Promise((resolve, reject) => {
953
+ await new Promise((resolvePromise, reject) => {
937
954
  if (options?.signal?.aborted) {
938
955
  reject(createAbortError(options.signal, "wait_for_agent_start aborted"));
939
956
  return;
@@ -962,7 +979,7 @@ export class AgentManager {
962
979
  };
963
980
  const finishOk = () => {
964
981
  cleanup();
965
- resolve();
982
+ resolvePromise();
966
983
  };
967
984
  const finishErr = (error) => {
968
985
  cleanup();
@@ -978,7 +995,7 @@ export class AgentManager {
978
995
  finishErr(new Error(`Agent ${agentId} not found`));
979
996
  return true;
980
997
  }
981
- const currentPendingRun = this.getPendingForegroundRun(agentId);
998
+ const currentPendingRun = this.foregroundRuns.getPendingRun(agentId);
982
999
  if ((current.lifecycle === "running" || currentPendingRun?.started) &&
983
1000
  !current.pendingReplacement) {
984
1001
  finishOk();
@@ -1032,7 +1049,7 @@ export class AgentManager {
1032
1049
  }
1033
1050
  async cancelAgentRun(agentId) {
1034
1051
  const agent = this.requireSessionAgent(agentId);
1035
- const pendingRun = this.getPendingForegroundRun(agentId);
1052
+ const pendingRun = this.foregroundRuns.getPendingRun(agentId);
1036
1053
  const foregroundTurnId = agent.activeForegroundTurnId;
1037
1054
  const hasForegroundTurn = Boolean(foregroundTurnId);
1038
1055
  const isAutonomousRunning = agent.lifecycle === "running" && !hasForegroundTurn && !pendingRun;
@@ -1045,19 +1062,19 @@ export class AgentManager {
1045
1062
  // Wait briefly for the event to propagate if there's an active foreground turn.
1046
1063
  if (foregroundTurnId) {
1047
1064
  const waiter = Array.from(agent.foregroundTurnWaiters).find((candidate) => candidate.turnId === foregroundTurnId);
1048
- const timeout = new Promise((resolve) => setTimeout(resolve, 2000));
1065
+ const timeout = new Promise((resolvePromise) => setTimeout(resolvePromise, 2000));
1049
1066
  if (waiter) {
1050
1067
  await Promise.race([waiter.settledPromise, timeout]);
1051
1068
  }
1052
1069
  else if (agent.activeForegroundTurnId === foregroundTurnId) {
1053
1070
  await Promise.race([
1054
- new Promise((resolve) => {
1071
+ new Promise((resolvePromise) => {
1055
1072
  const unsubscribe = this.subscribe((event) => {
1056
1073
  if (event.type === "agent_state" &&
1057
1074
  event.agent.id === agentId &&
1058
1075
  !event.agent.activeForegroundTurnId) {
1059
1076
  unsubscribe();
1060
- resolve();
1077
+ resolvePromise();
1061
1078
  }
1062
1079
  }, { agentId, replayState: false });
1063
1080
  }),
@@ -1073,7 +1090,7 @@ export class AgentManager {
1073
1090
  }
1074
1091
  }
1075
1092
  else if (pendingRun) {
1076
- const timeout = new Promise((resolve) => setTimeout(resolve, 2000));
1093
+ const timeout = new Promise((resolvePromise) => setTimeout(resolvePromise, 2000));
1077
1094
  await Promise.race([pendingRun.settledPromise, timeout]);
1078
1095
  }
1079
1096
  // If the foreground turn is still stuck after the timeout, force-dispatch a
@@ -1089,7 +1106,7 @@ export class AgentManager {
1089
1106
  });
1090
1107
  // The synthetic event unblocks the streamForwarder generator, whose finally
1091
1108
  // block settles the pending foreground run asynchronously. Wait for it.
1092
- const staleRun = this.getPendingForegroundRun(agentId);
1109
+ const staleRun = this.foregroundRuns.getPendingRun(agentId);
1093
1110
  if (staleRun && !staleRun.settled) {
1094
1111
  await staleRun.settledPromise;
1095
1112
  }
@@ -1179,7 +1196,7 @@ export class AgentManager {
1179
1196
  return null;
1180
1197
  }
1181
1198
  return {
1182
- text: chunks.reverse().join(""),
1199
+ text: chunks.toReversed().join(""),
1183
1200
  startsAtBeginning,
1184
1201
  };
1185
1202
  }
@@ -1226,7 +1243,7 @@ export class AgentManager {
1226
1243
  if (!snapshot) {
1227
1244
  throw new Error(`Agent ${agentId} not found`);
1228
1245
  }
1229
- const pendingForegroundRun = this.getPendingForegroundRun(agentId);
1246
+ const pendingForegroundRun = this.foregroundRuns.getPendingRun(agentId);
1230
1247
  const hasForegroundTurn = Boolean(snapshot.activeForegroundTurnId) || Boolean(pendingForegroundRun);
1231
1248
  const immediatePermission = this.peekPendingPermission(snapshot);
1232
1249
  if (immediatePermission) {
@@ -1256,7 +1273,7 @@ export class AgentManager {
1256
1273
  if (options?.signal?.aborted) {
1257
1274
  throw createAbortError(options.signal, "wait_for_agent aborted");
1258
1275
  }
1259
- return await new Promise((resolve, reject) => {
1276
+ return await new Promise((resolvePromise, reject) => {
1260
1277
  // Bug #1 Fix: Check abort signal AGAIN inside Promise constructor
1261
1278
  // to avoid race condition between pre-Promise check and abort listener registration
1262
1279
  if (options?.signal?.aborted) {
@@ -1302,11 +1319,12 @@ export class AgentManager {
1302
1319
  cleanup();
1303
1320
  void this.getLastAssistantMessage(agentId)
1304
1321
  .then((lastMessage) => {
1305
- resolve({
1322
+ resolvePromise({
1306
1323
  status: currentStatus,
1307
1324
  permission,
1308
1325
  lastMessage,
1309
1326
  });
1327
+ return;
1310
1328
  })
1311
1329
  .catch(reject);
1312
1330
  };
@@ -1368,31 +1386,57 @@ export class AgentManager {
1368
1386
  }
1369
1387
  const initialPersistedTitle = await this.resolveInitialPersistedTitle(resolvedAgentId, config);
1370
1388
  const now = new Date();
1371
- const explicitTimelineSeed = options?.timeline?.length ||
1372
- options?.timelineRows?.length ||
1373
- options?.timelineNextSeq !== undefined
1374
- ? {
1375
- items: options?.timeline,
1376
- rows: options?.timelineRows,
1377
- nextSeq: options?.timelineNextSeq,
1378
- timestamp: (options?.updatedAt ?? options?.createdAt ?? now).toISOString(),
1379
- }
1380
- : null;
1389
+ const { durableTimelineHasRows } = await this.initializeAgentTimelineForRegister({
1390
+ agentId: resolvedAgentId,
1391
+ now,
1392
+ options,
1393
+ });
1394
+ const managed = this.buildManagedAgentForRegister({
1395
+ resolvedAgentId,
1396
+ session,
1397
+ config,
1398
+ now,
1399
+ durableTimelineHasRows,
1400
+ options,
1401
+ });
1402
+ this.agents.set(resolvedAgentId, managed);
1403
+ // Initialize previousStatus to track transitions
1404
+ this.previousStatuses.set(resolvedAgentId, managed.lifecycle);
1405
+ await this.refreshRuntimeInfo(managed);
1406
+ await this.persistSnapshot(managed, {
1407
+ workspaceId: options?.workspaceId,
1408
+ title: initialPersistedTitle,
1409
+ });
1410
+ this.emitState(managed, { persist: false });
1411
+ await this.refreshSessionState(managed);
1412
+ managed.lifecycle = "idle";
1413
+ await this.persistSnapshot(managed, { workspaceId: options?.workspaceId });
1414
+ this.emitState(managed, { persist: false });
1415
+ this.subscribeToSession(managed);
1416
+ return { ...managed };
1417
+ }
1418
+ async initializeAgentTimelineForRegister(params) {
1419
+ const { agentId, now, options } = params;
1420
+ const explicitTimelineSeed = buildExplicitTimelineSeedForRegister(now, options);
1381
1421
  const shouldSeedFromDurable = !explicitTimelineSeed &&
1382
- !this.timelineStore.has(resolvedAgentId) &&
1422
+ !this.timelineStore.has(agentId) &&
1383
1423
  this.durableTimelineStore !== undefined;
1384
1424
  const durableTimelineSeed = shouldSeedFromDurable
1385
- ? await this.loadCommittedTimelineSeed(resolvedAgentId, now)
1425
+ ? await this.loadCommittedTimelineSeed(agentId, now)
1386
1426
  : null;
1387
1427
  const durableTimelineHasRows = durableTimelineSeed != null && (durableTimelineSeed.nextSeq ?? 1) > 1;
1388
1428
  const timelineSeed = explicitTimelineSeed ?? durableTimelineSeed;
1389
- if (timelineSeed || !this.timelineStore.has(resolvedAgentId)) {
1390
- this.timelineStore.initialize(resolvedAgentId, timelineSeed ?? { timestamp: now.toISOString() });
1429
+ if (timelineSeed || !this.timelineStore.has(agentId)) {
1430
+ this.timelineStore.initialize(agentId, timelineSeed ?? { timestamp: now.toISOString() });
1391
1431
  }
1392
1432
  if (options?.timelineRows?.length) {
1393
- this.enqueueDurableTimelineBulkInsert(resolvedAgentId, options.timelineRows);
1433
+ this.enqueueDurableTimelineBulkInsert(agentId, options.timelineRows);
1394
1434
  }
1395
- const managed = {
1435
+ return { durableTimelineHasRows };
1436
+ }
1437
+ buildManagedAgentForRegister(params) {
1438
+ const { resolvedAgentId, session, config, now, durableTimelineHasRows, options } = params;
1439
+ return {
1396
1440
  id: resolvedAgentId,
1397
1441
  provider: config.provider,
1398
1442
  cwd: config.cwd,
@@ -1418,33 +1462,10 @@ export class AgentManager {
1418
1462
  lastUserMessageAt: options?.lastUserMessageAt ?? null,
1419
1463
  lastUsage: options?.lastUsage,
1420
1464
  lastError: options?.lastError,
1421
- attention: options?.attention != null
1422
- ? options.attention.requiresAttention
1423
- ? {
1424
- requiresAttention: true,
1425
- attentionReason: options.attention.attentionReason,
1426
- attentionTimestamp: new Date(options.attention.attentionTimestamp),
1427
- }
1428
- : { requiresAttention: false }
1429
- : { requiresAttention: false },
1465
+ attention: resolveInitialAttention(options?.attention),
1430
1466
  internal: config.internal ?? false,
1431
1467
  labels: options?.labels ?? {},
1432
1468
  };
1433
- this.agents.set(resolvedAgentId, managed);
1434
- // Initialize previousStatus to track transitions
1435
- this.previousStatuses.set(resolvedAgentId, managed.lifecycle);
1436
- await this.refreshRuntimeInfo(managed);
1437
- await this.persistSnapshot(managed, {
1438
- workspaceId: options?.workspaceId,
1439
- title: initialPersistedTitle,
1440
- });
1441
- this.emitState(managed, { persist: false });
1442
- await this.refreshSessionState(managed);
1443
- managed.lifecycle = "idle";
1444
- await this.persistSnapshot(managed, { workspaceId: options?.workspaceId });
1445
- this.emitState(managed, { persist: false });
1446
- this.subscribeToSession(managed);
1447
- return { ...managed };
1448
1469
  }
1449
1470
  async loadCommittedTimelineSeed(agentId, now) {
1450
1471
  if (!this.durableTimelineStore) {
@@ -1463,17 +1484,13 @@ export class AgentManager {
1463
1484
  agent.unsubscribeSession();
1464
1485
  agent.unsubscribeSession = null;
1465
1486
  }
1466
- for (const waiter of agent.foregroundTurnWaiters) {
1467
- waiter.callback({
1468
- type: "turn_canceled",
1469
- provider: agent.provider,
1470
- reason: cancelReason,
1471
- turnId: waiter.turnId,
1472
- });
1473
- this.settleForegroundTurnWaiter(waiter);
1474
- }
1475
- agent.foregroundTurnWaiters.clear();
1476
- this.settlePendingForegroundRun(agent.id);
1487
+ this.foregroundRuns.cancelWaiters(agent, (turnId) => ({
1488
+ type: "turn_canceled",
1489
+ provider: agent.provider,
1490
+ reason: cancelReason,
1491
+ turnId,
1492
+ }));
1493
+ this.foregroundRuns.settlePendingRun(agent.id);
1477
1494
  return {
1478
1495
  ...agent,
1479
1496
  lifecycle: "closed",
@@ -1507,6 +1524,7 @@ export class AgentManager {
1507
1524
  return;
1508
1525
  }
1509
1526
  await this.dispatchSessionEvent(current, event);
1527
+ return;
1510
1528
  })
1511
1529
  .catch((err) => {
1512
1530
  this.logger.error({ err, agentId, eventType: event.type }, "Failed to process session event");
@@ -1521,70 +1539,14 @@ export class AgentManager {
1521
1539
  }
1522
1540
  async dispatchSessionEvent(agent, event) {
1523
1541
  const turnId = event.turnId;
1524
- const matchingWaiters = turnId == null
1525
- ? []
1526
- : Array.from(agent.foregroundTurnWaiters).filter((waiter) => waiter.turnId === turnId && !waiter.settled);
1542
+ const matchingWaiters = this.foregroundRuns.getMatchingWaiters(agent, turnId);
1527
1543
  const shouldNotifyWaiters = await this.handleStreamEvent(agent, event);
1528
1544
  if (!shouldNotifyWaiters) {
1529
1545
  return;
1530
1546
  }
1531
- for (const waiter of matchingWaiters) {
1532
- waiter.callback(event);
1533
- if (isTurnTerminalEvent(event)) {
1534
- this.settleForegroundTurnWaiter(waiter);
1535
- }
1536
- }
1537
- }
1538
- settleForegroundTurnWaiter(waiter) {
1539
- if (waiter.settled) {
1540
- return;
1541
- }
1542
- waiter.settled = true;
1543
- waiter.resolveSettled();
1544
- }
1545
- rememberFinalizedForegroundTurn(agent, turnId) {
1546
- agent.finalizedForegroundTurnIds.add(turnId);
1547
- if (agent.finalizedForegroundTurnIds.size <= 50) {
1548
- return;
1549
- }
1550
- const oldest = agent.finalizedForegroundTurnIds.values().next().value;
1551
- if (oldest) {
1552
- agent.finalizedForegroundTurnIds.delete(oldest);
1553
- }
1554
- }
1555
- createPendingForegroundRun() {
1556
- let resolveSettled;
1557
- const settledPromise = new Promise((resolve) => {
1558
- resolveSettled = resolve;
1547
+ this.foregroundRuns.notifyWaiters(matchingWaiters, event, {
1548
+ terminal: isTurnTerminalEvent(event),
1559
1549
  });
1560
- return {
1561
- token: randomUUID(),
1562
- started: false,
1563
- settled: false,
1564
- settledPromise,
1565
- resolveSettled,
1566
- };
1567
- }
1568
- getPendingForegroundRun(agentId) {
1569
- return this.pendingForegroundRuns.get(agentId) ?? null;
1570
- }
1571
- hasPendingForegroundRun(agentId) {
1572
- return this.pendingForegroundRuns.has(agentId);
1573
- }
1574
- settlePendingForegroundRun(agentId, token) {
1575
- const pendingRun = this.pendingForegroundRuns.get(agentId);
1576
- if (!pendingRun) {
1577
- return;
1578
- }
1579
- if (token && pendingRun.token !== token) {
1580
- return;
1581
- }
1582
- this.pendingForegroundRuns.delete(agentId);
1583
- if (pendingRun.settled) {
1584
- return;
1585
- }
1586
- pendingRun.settled = true;
1587
- pendingRun.resolveSettled();
1588
1550
  }
1589
1551
  async resolveInitialPersistedTitle(agentId, config) {
1590
1552
  const existing = await this.registry?.get(agentId);
@@ -1671,14 +1633,8 @@ export class AgentManager {
1671
1633
  if (event.type !== "timeline") {
1672
1634
  continue;
1673
1635
  }
1674
- if (event.item.type === "user_message") {
1675
- const eventMessageId = normalizeMessageId(event.item.messageId);
1676
- if (eventMessageId) {
1677
- const canonicalText = canonicalUserMessagesById.get(eventMessageId);
1678
- if (canonicalText === event.item.text) {
1679
- continue;
1680
- }
1681
- }
1636
+ if (isDuplicateLegacyUserMessage(event.item, canonicalUserMessagesById)) {
1637
+ continue;
1682
1638
  }
1683
1639
  this.recordTimeline(agent.id, event.item);
1684
1640
  }
@@ -1696,18 +1652,14 @@ export class AgentManager {
1696
1652
  if (!agent) {
1697
1653
  return;
1698
1654
  }
1699
- for (const waiter of agent.foregroundTurnWaiters) {
1700
- if (waiter.turnId === turnId && !waiter.settled) {
1701
- waiter.callback(event);
1702
- }
1703
- }
1655
+ this.foregroundRuns.notifyAgentWaiters(agent, event);
1704
1656
  }
1705
1657
  async handleStreamEvent(agent, event, options) {
1706
1658
  const eventTurnId = event.turnId;
1707
1659
  const isForegroundEvent = Boolean(eventTurnId && agent.activeForegroundTurnId === eventTurnId);
1708
1660
  if (eventTurnId &&
1709
1661
  isTurnTerminalEvent(event) &&
1710
- agent.finalizedForegroundTurnIds.has(eventTurnId)) {
1662
+ this.foregroundRuns.hasFinalizedTurn(agent, eventTurnId)) {
1711
1663
  return false;
1712
1664
  }
1713
1665
  // Only update timestamp for live events, not history replay
@@ -1718,185 +1670,240 @@ export class AgentManager {
1718
1670
  }
1719
1671
  this.agentStreamCoalescer.flushFor(agent.id);
1720
1672
  }
1721
- let shouldDispatchEvent = true;
1722
- let shouldNotifyWaiters = true;
1673
+ const flags = { shouldDispatchEvent: true, shouldNotifyWaiters: true };
1674
+ const dispatchPromise = this.dispatchStreamEventByType({
1675
+ agent,
1676
+ event,
1677
+ options,
1678
+ isForegroundEvent,
1679
+ eventTurnId,
1680
+ flags,
1681
+ });
1682
+ if (dispatchPromise) {
1683
+ await dispatchPromise;
1684
+ }
1685
+ if (!options?.fromHistory && isForegroundEvent && isTurnTerminalEvent(event)) {
1686
+ this.finalizeForegroundTurn(agent, eventTurnId);
1687
+ }
1688
+ if (!options?.fromHistory && flags.shouldDispatchEvent) {
1689
+ this.dispatchStream(agent.id, event);
1690
+ }
1691
+ return flags.shouldNotifyWaiters;
1692
+ }
1693
+ dispatchStreamEventByType(params) {
1694
+ const { agent, event, options, isForegroundEvent, eventTurnId, flags } = params;
1723
1695
  switch (event.type) {
1724
1696
  case "thread_started":
1725
- {
1726
- const previousSessionId = agent.persistence?.sessionId ?? null;
1727
- const handle = agent.session.describePersistence();
1728
- if (handle) {
1729
- agent.persistence = attachPersistenceCwd(handle, agent.cwd);
1730
- if (agent.persistence?.sessionId !== previousSessionId) {
1731
- this.emitState(agent);
1732
- }
1733
- }
1734
- void this.refreshRuntimeInfo(agent);
1735
- }
1736
- break;
1697
+ this.onStreamThreadStarted(agent);
1698
+ return undefined;
1737
1699
  case "usage_updated":
1738
1700
  agent.lastUsage = event.usage;
1739
1701
  this.emitState(agent);
1740
- break;
1741
- case "timeline":
1742
- {
1743
- // Skip provider-replayed user_message items during history hydration.
1744
- if (options?.fromHistory && event.item.type === "user_message") {
1745
- const eventMessageId = normalizeMessageId(event.item.messageId);
1746
- if (eventMessageId) {
1747
- const canonicalText = options?.canonicalUserMessagesById?.get(eventMessageId);
1748
- if (canonicalText === event.item.text) {
1749
- shouldDispatchEvent = false;
1750
- shouldNotifyWaiters = false;
1751
- break;
1752
- }
1753
- }
1754
- }
1755
- // Suppress user_message echoes for the active foreground turn.
1756
- if (!options?.fromHistory && event.item.type === "user_message" && isForegroundEvent) {
1757
- const eventMessageId = normalizeMessageId(event.item.messageId);
1758
- if (eventMessageId &&
1759
- (await this.hasCommittedUserMessageFromStores(agent.id, {
1760
- messageId: eventMessageId,
1761
- text: event.item.text,
1762
- }))) {
1763
- break;
1764
- }
1765
- }
1766
- if (options?.fromHistory) {
1767
- this.recordTimeline(agent.id, event.item);
1768
- shouldDispatchEvent = false;
1769
- shouldNotifyWaiters = false;
1770
- break;
1771
- }
1772
- this.recordAndDispatchTimelineItem(agent.id, event.item, event.provider, event.turnId);
1773
- if (event.item.type === "user_message") {
1774
- agent.lastUserMessageAt = new Date();
1775
- this.emitState(agent);
1776
- }
1777
- shouldDispatchEvent = false;
1778
- shouldNotifyWaiters = true;
1702
+ return undefined;
1703
+ case "mode_changed":
1704
+ agent.currentModeId = event.currentModeId;
1705
+ agent.availableModes = event.availableModes;
1706
+ if (agent.runtimeInfo) {
1707
+ agent.runtimeInfo = { ...agent.runtimeInfo, modeId: event.currentModeId };
1779
1708
  }
1780
- break;
1781
- case "turn_completed":
1782
- this.logger.trace({
1783
- agentId: agent.id,
1784
- lifecycle: agent.lifecycle,
1785
- activeForegroundTurnId: agent.activeForegroundTurnId,
1786
- eventTurnId,
1787
- }, "handleStreamEvent: turn_completed");
1788
- agent.lastUsage = event.usage;
1789
- agent.lastError = undefined;
1790
- // For autonomous turns (not foreground), transition to idle
1791
- // unless a replacement is pending (avoid idle flash during replace)
1792
- if (!isForegroundEvent && agent.lifecycle !== "idle" && !agent.pendingReplacement) {
1793
- agent.lifecycle = "idle";
1794
- this.emitState(agent);
1709
+ flags.shouldDispatchEvent = false;
1710
+ this.emitState(agent);
1711
+ return undefined;
1712
+ case "model_changed":
1713
+ agent.runtimeInfo = event.runtimeInfo;
1714
+ if (!agent.persistence && event.runtimeInfo.sessionId) {
1715
+ agent.persistence = attachPersistenceCwd({ provider: agent.provider, sessionId: event.runtimeInfo.sessionId }, agent.cwd);
1795
1716
  }
1796
- void this.refreshRuntimeInfo(agent);
1797
- break;
1717
+ agent.currentModeId = event.runtimeInfo.modeId ?? agent.currentModeId;
1718
+ flags.shouldDispatchEvent = false;
1719
+ this.emitState(agent);
1720
+ return undefined;
1721
+ case "thinking_option_changed":
1722
+ if (agent.runtimeInfo) {
1723
+ agent.runtimeInfo = {
1724
+ ...agent.runtimeInfo,
1725
+ thinkingOptionId: event.thinkingOptionId,
1726
+ };
1727
+ }
1728
+ flags.shouldDispatchEvent = false;
1729
+ this.emitState(agent);
1730
+ return undefined;
1731
+ case "timeline":
1732
+ return this.onStreamTimelineEvent({ agent, event, options, isForegroundEvent, flags });
1733
+ case "turn_completed":
1734
+ this.onStreamTurnCompleted({ agent, event, eventTurnId, isForegroundEvent });
1735
+ return undefined;
1798
1736
  case "turn_failed":
1799
- this.logger.warn({
1800
- agentId: agent.id,
1801
- lifecycle: agent.lifecycle,
1802
- activeForegroundTurnId: agent.activeForegroundTurnId,
1737
+ return this.onStreamTurnFailed({
1738
+ agent,
1739
+ event,
1803
1740
  eventTurnId,
1804
- error: event.error,
1805
- code: event.code,
1806
- diagnostic: event.diagnostic,
1807
- }, "handleStreamEvent: turn_failed");
1808
- // For autonomous turns, set error state directly
1809
- if (!isForegroundEvent) {
1810
- agent.lifecycle = "error";
1811
- }
1812
- agent.lastError = event.error;
1813
- await this.appendSystemErrorTimelineMessage(agent, event.provider, this.formatTurnFailedMessage(event), options);
1814
- for (const [requestId] of agent.pendingPermissions) {
1815
- agent.pendingPermissions.delete(requestId);
1816
- if (!options?.fromHistory) {
1817
- this.dispatchStream(agent.id, {
1818
- type: "permission_resolved",
1819
- provider: event.provider,
1820
- requestId,
1821
- resolution: { behavior: "deny", message: "Turn failed" },
1822
- });
1823
- }
1824
- }
1825
- if (!isForegroundEvent) {
1826
- this.emitState(agent);
1827
- }
1828
- break;
1741
+ isForegroundEvent,
1742
+ options,
1743
+ });
1829
1744
  case "turn_canceled":
1830
- this.logger.trace({
1831
- agentId: agent.id,
1832
- lifecycle: agent.lifecycle,
1833
- activeForegroundTurnId: agent.activeForegroundTurnId,
1834
- eventTurnId,
1835
- }, "handleStreamEvent: turn_canceled");
1836
- // For autonomous turns, transition to idle
1837
- // unless a replacement is pending (avoid idle flash during replace)
1838
- if (!isForegroundEvent && !agent.pendingReplacement) {
1839
- agent.lifecycle = "idle";
1840
- }
1841
- agent.lastError = undefined;
1842
- for (const [requestId] of agent.pendingPermissions) {
1843
- agent.pendingPermissions.delete(requestId);
1844
- if (!options?.fromHistory) {
1845
- this.dispatchStream(agent.id, {
1846
- type: "permission_resolved",
1847
- provider: event.provider,
1848
- requestId,
1849
- resolution: { behavior: "deny", message: "Interrupted" },
1850
- });
1851
- }
1852
- }
1853
- if (!isForegroundEvent) {
1854
- this.emitState(agent);
1855
- }
1856
- break;
1745
+ this.onStreamTurnCanceled({ agent, event, eventTurnId, isForegroundEvent, options });
1746
+ return undefined;
1857
1747
  case "turn_started":
1858
- this.logger.trace({
1859
- agentId: agent.id,
1860
- lifecycle: agent.lifecycle,
1861
- activeForegroundTurnId: agent.activeForegroundTurnId,
1862
- eventTurnId,
1863
- }, "handleStreamEvent: turn_started");
1864
- // For autonomous turn_started (no foreground match), set running
1865
- if (!isForegroundEvent) {
1866
- agent.lifecycle = "running";
1867
- this.emitState(agent);
1868
- }
1869
- break;
1748
+ this.onStreamTurnStarted({ agent, eventTurnId, isForegroundEvent });
1749
+ return undefined;
1870
1750
  case "permission_requested":
1871
- {
1872
- const hadPendingPermissions = agent.pendingPermissions.size > 0;
1873
- agent.pendingPermissions.set(event.request.id, event.request);
1874
- if (!hadPendingPermissions && !agent.internal) {
1875
- this.broadcastAgentAttention(agent, "permission");
1876
- }
1877
- }
1878
- this.emitState(agent);
1879
- break;
1751
+ this.onStreamPermissionRequested(agent, event);
1752
+ return undefined;
1880
1753
  case "permission_resolved":
1881
- agent.pendingPermissions.delete(event.requestId);
1882
- if (!options?.fromHistory && agent.inFlightPermissionResponses.has(event.requestId)) {
1883
- agent.bufferedPermissionResolutions.set(event.requestId, event);
1884
- shouldDispatchEvent = false;
1885
- break;
1886
- }
1887
- this.emitState(agent);
1888
- break;
1754
+ this.onStreamPermissionResolved({ agent, event, options, flags });
1755
+ return undefined;
1889
1756
  default:
1890
- break;
1757
+ return undefined;
1891
1758
  }
1892
- if (!options?.fromHistory && isForegroundEvent && isTurnTerminalEvent(event)) {
1893
- this.finalizeForegroundTurn(agent, eventTurnId);
1759
+ }
1760
+ onStreamThreadStarted(agent) {
1761
+ const previousSessionId = agent.persistence?.sessionId ?? null;
1762
+ const handle = agent.session.describePersistence();
1763
+ if (handle) {
1764
+ agent.persistence = attachPersistenceCwd(handle, agent.cwd);
1765
+ if (agent.persistence?.sessionId !== previousSessionId) {
1766
+ this.emitState(agent);
1767
+ }
1894
1768
  }
1895
- // Skip dispatching individual stream events during history replay.
1896
- if (!options?.fromHistory && shouldDispatchEvent) {
1897
- this.dispatchStream(agent.id, event);
1769
+ void this.refreshRuntimeInfo(agent);
1770
+ }
1771
+ async onStreamTimelineEvent(params) {
1772
+ const { agent, event, options, isForegroundEvent, flags } = params;
1773
+ // Skip provider-replayed user_message items during history hydration.
1774
+ if (options?.fromHistory && event.item.type === "user_message") {
1775
+ const eventMessageId = normalizeMessageId(event.item.messageId);
1776
+ if (eventMessageId) {
1777
+ const canonicalText = options?.canonicalUserMessagesById?.get(eventMessageId);
1778
+ if (canonicalText === event.item.text) {
1779
+ flags.shouldDispatchEvent = false;
1780
+ flags.shouldNotifyWaiters = false;
1781
+ return;
1782
+ }
1783
+ }
1784
+ }
1785
+ // Suppress user_message echoes for the active foreground turn.
1786
+ if (!options?.fromHistory && event.item.type === "user_message" && isForegroundEvent) {
1787
+ const eventMessageId = normalizeMessageId(event.item.messageId);
1788
+ if (eventMessageId &&
1789
+ (await this.hasCommittedUserMessageFromStores(agent.id, {
1790
+ messageId: eventMessageId,
1791
+ text: event.item.text,
1792
+ }))) {
1793
+ return;
1794
+ }
1795
+ }
1796
+ if (options?.fromHistory) {
1797
+ this.recordTimeline(agent.id, event.item);
1798
+ flags.shouldDispatchEvent = false;
1799
+ flags.shouldNotifyWaiters = false;
1800
+ return;
1801
+ }
1802
+ this.recordAndDispatchTimelineItem(agent.id, event.item, event.provider, event.turnId);
1803
+ if (event.item.type === "user_message") {
1804
+ agent.lastUserMessageAt = new Date();
1805
+ this.emitState(agent);
1806
+ }
1807
+ flags.shouldDispatchEvent = false;
1808
+ flags.shouldNotifyWaiters = true;
1809
+ }
1810
+ onStreamTurnCompleted(params) {
1811
+ const { agent, event, eventTurnId, isForegroundEvent } = params;
1812
+ this.logger.trace({
1813
+ agentId: agent.id,
1814
+ lifecycle: agent.lifecycle,
1815
+ activeForegroundTurnId: agent.activeForegroundTurnId,
1816
+ eventTurnId,
1817
+ }, "handleStreamEvent: turn_completed");
1818
+ agent.lastUsage = event.usage;
1819
+ agent.lastError = undefined;
1820
+ if (!isForegroundEvent && agent.lifecycle !== "idle" && !agent.pendingReplacement) {
1821
+ agent.lifecycle = "idle";
1822
+ this.emitState(agent);
1823
+ }
1824
+ void this.refreshRuntimeInfo(agent);
1825
+ }
1826
+ async onStreamTurnFailed(params) {
1827
+ const { agent, event, eventTurnId, isForegroundEvent, options } = params;
1828
+ this.logger.warn({
1829
+ agentId: agent.id,
1830
+ lifecycle: agent.lifecycle,
1831
+ activeForegroundTurnId: agent.activeForegroundTurnId,
1832
+ eventTurnId,
1833
+ error: event.error,
1834
+ code: event.code,
1835
+ diagnostic: event.diagnostic,
1836
+ }, "handleStreamEvent: turn_failed");
1837
+ if (!isForegroundEvent) {
1838
+ agent.lifecycle = "error";
1839
+ }
1840
+ agent.lastError = event.error;
1841
+ await this.appendSystemErrorTimelineMessage(agent, event.provider, this.formatTurnFailedMessage(event), options);
1842
+ this.resolvePendingPermissionsForAgent(agent, event.provider, options, "Turn failed");
1843
+ if (!isForegroundEvent) {
1844
+ this.emitState(agent);
1845
+ }
1846
+ }
1847
+ onStreamTurnCanceled(params) {
1848
+ const { agent, event, eventTurnId, isForegroundEvent, options } = params;
1849
+ this.logger.trace({
1850
+ agentId: agent.id,
1851
+ lifecycle: agent.lifecycle,
1852
+ activeForegroundTurnId: agent.activeForegroundTurnId,
1853
+ eventTurnId,
1854
+ }, "handleStreamEvent: turn_canceled");
1855
+ if (!isForegroundEvent && !agent.pendingReplacement) {
1856
+ agent.lifecycle = "idle";
1857
+ }
1858
+ agent.lastError = undefined;
1859
+ this.resolvePendingPermissionsForAgent(agent, event.provider, options, "Interrupted");
1860
+ if (!isForegroundEvent) {
1861
+ this.emitState(agent);
1862
+ }
1863
+ }
1864
+ onStreamTurnStarted(params) {
1865
+ const { agent, eventTurnId, isForegroundEvent } = params;
1866
+ this.logger.trace({
1867
+ agentId: agent.id,
1868
+ lifecycle: agent.lifecycle,
1869
+ activeForegroundTurnId: agent.activeForegroundTurnId,
1870
+ eventTurnId,
1871
+ }, "handleStreamEvent: turn_started");
1872
+ if (!isForegroundEvent) {
1873
+ agent.lifecycle = "running";
1874
+ this.emitState(agent);
1875
+ }
1876
+ }
1877
+ onStreamPermissionRequested(agent, event) {
1878
+ const hadPendingPermissions = agent.pendingPermissions.size > 0;
1879
+ agent.pendingPermissions.set(event.request.id, event.request);
1880
+ if (!hadPendingPermissions && !agent.internal) {
1881
+ this.broadcastAgentAttention(agent, "permission");
1882
+ }
1883
+ this.emitState(agent);
1884
+ }
1885
+ onStreamPermissionResolved(params) {
1886
+ const { agent, event, options, flags } = params;
1887
+ agent.pendingPermissions.delete(event.requestId);
1888
+ if (!options?.fromHistory && agent.inFlightPermissionResponses.has(event.requestId)) {
1889
+ agent.bufferedPermissionResolutions.set(event.requestId, event);
1890
+ flags.shouldDispatchEvent = false;
1891
+ return;
1892
+ }
1893
+ this.emitState(agent);
1894
+ }
1895
+ resolvePendingPermissionsForAgent(agent, provider, options, message) {
1896
+ for (const [requestId] of agent.pendingPermissions) {
1897
+ agent.pendingPermissions.delete(requestId);
1898
+ if (!options?.fromHistory) {
1899
+ this.dispatchStream(agent.id, {
1900
+ type: "permission_resolved",
1901
+ provider,
1902
+ requestId,
1903
+ resolution: { behavior: "deny", message },
1904
+ });
1905
+ }
1898
1906
  }
1899
- return shouldNotifyWaiters;
1900
1907
  }
1901
1908
  recordAndDispatchTimelineItem(agentId, item, provider, turnId) {
1902
1909
  const row = this.recordTimeline(agentId, item);
@@ -2102,12 +2109,12 @@ export class AgentManager {
2102
2109
  if (error instanceof Error &&
2103
2110
  "code" in error &&
2104
2111
  error.code === "ENOENT") {
2105
- throw new Error(`Working directory does not exist: ${normalized.cwd}`);
2112
+ throw new Error(`Working directory does not exist: ${normalized.cwd}`, { cause: error });
2106
2113
  }
2107
2114
  if (error instanceof Error) {
2108
2115
  throw error;
2109
2116
  }
2110
- throw new Error(`Failed to access working directory: ${normalized.cwd}`);
2117
+ throw new Error(`Failed to access working directory: ${normalized.cwd}`, { cause: error });
2111
2118
  }
2112
2119
  }
2113
2120
  if (typeof normalized.model === "string") {
@@ -2147,6 +2154,37 @@ export class AgentManager {
2147
2154
  },
2148
2155
  };
2149
2156
  }
2157
+ async requireAvailableClient(options) {
2158
+ const client = this.clients.get(options.provider);
2159
+ if (!client) {
2160
+ const configuredProviders = this.getConfiguredProviderIds();
2161
+ throw new Error(`Unknown provider '${options.provider}'. Configured providers: ${formatProviderList(configuredProviders)}.`);
2162
+ }
2163
+ let unavailableReason = null;
2164
+ try {
2165
+ const available = await client.isAvailable();
2166
+ if (available) {
2167
+ return client;
2168
+ }
2169
+ }
2170
+ catch (error) {
2171
+ unavailableReason = error instanceof Error ? error.message : String(error);
2172
+ }
2173
+ const availableProviders = (await this.listProviderAvailability())
2174
+ .filter((entry) => entry.available)
2175
+ .map((entry) => entry.provider);
2176
+ const providerList = formatProviderList(availableProviders);
2177
+ const reason = unavailableReason ? ` Reason: ${unavailableReason}.` : "";
2178
+ throw new Error(`Provider '${options.provider}' is not available.${reason} Available providers: ${providerList}. Use one of those providers, or install/configure '${options.provider}'.`);
2179
+ }
2180
+ requireEnabledProvider(provider) {
2181
+ if (this.providerEnabled.get(provider) === false) {
2182
+ throw new Error(`Provider '${provider}' is disabled`);
2183
+ }
2184
+ }
2185
+ getConfiguredProviderIds() {
2186
+ return Array.from(new Set([...this.providerEnabled.keys(), ...this.clients.keys()]));
2187
+ }
2150
2188
  requireClient(provider) {
2151
2189
  const client = this.clients.get(provider);
2152
2190
  if (!client) {