@clinebot/core 0.0.37 → 0.0.38

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 (617) hide show
  1. package/README.md +11 -1
  2. package/dist/ClineCore.d.ts +18 -214
  3. package/dist/account/cline-account-service.d.ts +0 -1
  4. package/dist/account/index.d.ts +0 -1
  5. package/dist/account/rpc.d.ts +0 -1
  6. package/dist/account/types.d.ts +0 -1
  7. package/dist/auth/bounded-ttl-cache.d.ts +0 -1
  8. package/dist/auth/client.d.ts +0 -1
  9. package/dist/auth/cline.d.ts +0 -5
  10. package/dist/auth/codex.d.ts +0 -1
  11. package/dist/auth/oca.d.ts +0 -1
  12. package/dist/auth/server.d.ts +0 -1
  13. package/dist/auth/types.d.ts +0 -1
  14. package/dist/auth/utils.d.ts +0 -1
  15. package/dist/cline-core/automation.d.ts +34 -0
  16. package/dist/cline-core/runtime-services.d.ts +5 -0
  17. package/dist/cline-core/start-input.d.ts +10 -0
  18. package/dist/cline-core/telemetry.d.ts +10 -0
  19. package/dist/cline-core/types.d.ts +221 -0
  20. package/dist/cron/{cron-event-ingress.d.ts → events/cron-event-ingress.d.ts} +1 -2
  21. package/dist/cron/{cron-report-writer.d.ts → reports/cron-report-writer.d.ts} +1 -2
  22. package/dist/cron/{cron-materializer.d.ts → runner/cron-materializer.d.ts} +1 -2
  23. package/dist/cron/{cron-runner.d.ts → runner/cron-runner.d.ts} +6 -4
  24. package/dist/cron/{resource-limiter.d.ts → runner/resource-limiter.d.ts} +0 -1
  25. package/dist/cron/schedule/scheduler.d.ts +12 -0
  26. package/dist/cron/{cron-service.d.ts → service/cron-service.d.ts} +4 -5
  27. package/dist/cron/{schedule-command-service.d.ts → service/schedule-command-service.d.ts} +0 -1
  28. package/dist/cron/{schedule-service.d.ts → service/schedule-service.d.ts} +20 -22
  29. package/dist/cron/{cron-reconciler.d.ts → specs/cron-reconciler.d.ts} +1 -2
  30. package/dist/cron/{cron-spec-parser.d.ts → specs/cron-spec-parser.d.ts} +0 -1
  31. package/dist/cron/{cron-watcher.d.ts → specs/cron-watcher.d.ts} +0 -1
  32. package/dist/cron/{cron-schema.d.ts → store/cron-schema.d.ts} +0 -1
  33. package/dist/cron/{sqlite-cron-store.d.ts → store/sqlite-cron-store.d.ts} +12 -2
  34. package/dist/extensions/config/index.d.ts +4 -7
  35. package/dist/extensions/config/runtime-commands.d.ts +0 -1
  36. package/dist/extensions/config/skill-frontmatter-toggle.d.ts +11 -0
  37. package/dist/extensions/config/unified-config-file-watcher.d.ts +0 -1
  38. package/dist/extensions/config/user-instruction-config-loader.d.ts +0 -1
  39. package/dist/extensions/config/user-instruction-plugin.d.ts +25 -0
  40. package/dist/extensions/config/user-instruction-service.d.ts +23 -0
  41. package/dist/extensions/context/agentic-compaction.d.ts +0 -1
  42. package/dist/extensions/context/basic-compaction.d.ts +0 -1
  43. package/dist/extensions/context/compaction-shared.d.ts +0 -1
  44. package/dist/extensions/context/compaction.d.ts +0 -1
  45. package/dist/extensions/index.d.ts +0 -1
  46. package/dist/extensions/mcp/client.d.ts +0 -1
  47. package/dist/extensions/mcp/config-loader.d.ts +0 -1
  48. package/dist/extensions/mcp/index.d.ts +0 -1
  49. package/dist/extensions/mcp/manager.d.ts +0 -1
  50. package/dist/extensions/mcp/name-transform.d.ts +0 -1
  51. package/dist/extensions/mcp/policies.d.ts +0 -1
  52. package/dist/extensions/mcp/tools.d.ts +2 -3
  53. package/dist/extensions/mcp/types.d.ts +3 -4
  54. package/dist/extensions/plugin/plugin-config-loader.d.ts +0 -1
  55. package/dist/extensions/plugin/plugin-load-report.d.ts +0 -1
  56. package/dist/extensions/plugin/plugin-loader.d.ts +0 -1
  57. package/dist/extensions/plugin/plugin-module-import.d.ts +0 -1
  58. package/dist/extensions/plugin/plugin-sandbox.d.ts +0 -1
  59. package/dist/extensions/plugin/plugin-targeting.d.ts +0 -1
  60. package/dist/extensions/plugin-sandbox-bootstrap.js +1 -446
  61. package/dist/extensions/tools/constants.d.ts +0 -1
  62. package/dist/extensions/tools/definitions.d.ts +13 -14
  63. package/dist/extensions/tools/executors/apply-patch-parser.d.ts +0 -1
  64. package/dist/extensions/tools/executors/apply-patch.d.ts +0 -1
  65. package/dist/extensions/tools/executors/bash.d.ts +0 -1
  66. package/dist/extensions/tools/executors/editor.d.ts +0 -1
  67. package/dist/extensions/tools/executors/file-read.d.ts +0 -1
  68. package/dist/extensions/tools/executors/index.d.ts +0 -1
  69. package/dist/extensions/tools/executors/search.d.ts +0 -1
  70. package/dist/extensions/tools/executors/web-fetch.d.ts +0 -1
  71. package/dist/extensions/tools/helpers.d.ts +0 -1
  72. package/dist/extensions/tools/index.d.ts +2 -3
  73. package/dist/extensions/tools/model-tool-routing.d.ts +0 -1
  74. package/dist/extensions/tools/presets.d.ts +4 -5
  75. package/dist/extensions/tools/runtime.d.ts +0 -1
  76. package/dist/extensions/tools/schemas.d.ts +0 -1
  77. package/dist/extensions/tools/team/delegated-agent.d.ts +3 -4
  78. package/dist/extensions/tools/team/index.d.ts +0 -1
  79. package/dist/extensions/tools/team/multi-agent.d.ts +1 -2
  80. package/dist/extensions/tools/team/projections.d.ts +0 -1
  81. package/dist/extensions/tools/team/runtime.d.ts +0 -1
  82. package/dist/extensions/tools/team/spawn-agent-tool.d.ts +4 -5
  83. package/dist/extensions/tools/team/subagent-prompts.d.ts +0 -1
  84. package/dist/extensions/tools/team/team-tools.d.ts +7 -8
  85. package/dist/extensions/tools/types.d.ts +11 -12
  86. package/dist/hooks/checkpoint-hooks.d.ts +9 -2
  87. package/dist/hooks/hook-extension.d.ts +2 -0
  88. package/dist/{extensions/config/hooks-config-loader.d.ts → hooks/hook-file-config.d.ts} +1 -2
  89. package/dist/hooks/hook-file-hooks.d.ts +2 -2
  90. package/dist/hooks/index.d.ts +3 -1
  91. package/dist/hooks/subprocess-runner.d.ts +0 -1
  92. package/dist/hooks/subprocess.d.ts +0 -1
  93. package/dist/hub/{connect.d.ts → client/connect.d.ts} +1 -2
  94. package/dist/hub/{client.d.ts → client/index.d.ts} +41 -4
  95. package/dist/hub/{session-client.d.ts → client/session-client.d.ts} +41 -13
  96. package/dist/hub/{ui-client.d.ts → client/ui-client.d.ts} +1 -1
  97. package/dist/hub/daemon/entry.d.ts +1 -0
  98. package/dist/hub/daemon/entry.js +720 -0
  99. package/dist/hub/{daemon.d.ts → daemon/index.d.ts} +6 -3
  100. package/dist/hub/{runtime-handlers.d.ts → daemon/runtime-handlers.d.ts} +3 -2
  101. package/dist/hub/{start-shared-server.d.ts → daemon/start-shared-server.d.ts} +1 -2
  102. package/dist/hub/{defaults.d.ts → discovery/defaults.d.ts} +0 -1
  103. package/dist/hub/{discovery.d.ts → discovery/index.d.ts} +2 -1
  104. package/dist/hub/{workspace.d.ts → discovery/workspace.d.ts} +1 -2
  105. package/dist/hub/index.d.ts +28 -11
  106. package/dist/hub/index.js +484 -1061
  107. package/dist/hub/runtime-host/hub-runtime-host.d.ts +73 -0
  108. package/dist/{transports/remote.d.ts → hub/runtime-host/remote-runtime-host.d.ts} +1 -2
  109. package/dist/hub/{browser-websocket.d.ts → server/browser-websocket.d.ts} +1 -2
  110. package/dist/hub/{transport.d.ts → server/command-transport.d.ts} +0 -1
  111. package/dist/hub/server/handlers/approval-handlers.d.ts +17 -0
  112. package/dist/hub/server/handlers/capability-handlers.d.ts +12 -0
  113. package/dist/hub/server/handlers/client-handlers.d.ts +6 -0
  114. package/dist/hub/server/handlers/context.d.ts +56 -0
  115. package/dist/hub/server/handlers/run-handlers.d.ts +5 -0
  116. package/dist/hub/server/handlers/session-event-projector.d.ts +7 -0
  117. package/dist/hub/server/handlers/session-handlers.d.ts +20 -0
  118. package/dist/hub/server/hub-client-contributions.d.ts +19 -0
  119. package/dist/hub/server/hub-notifications.d.ts +7 -0
  120. package/dist/hub/server/hub-schedule-events.d.ts +2 -0
  121. package/dist/hub/server/hub-server-logging.d.ts +2 -0
  122. package/dist/hub/server/hub-server-options.d.ts +55 -0
  123. package/dist/hub/server/hub-server-transport.d.ts +34 -0
  124. package/dist/hub/server/hub-session-records.d.ts +8 -0
  125. package/dist/hub/server/hub-websocket-server.d.ts +6 -0
  126. package/dist/hub/server/index.d.ts +4 -0
  127. package/dist/hub/{native-transport.d.ts → server/native-transport.d.ts} +1 -2
  128. package/dist/index.d.ts +51 -41
  129. package/dist/index.js +214 -872
  130. package/dist/runtime/capabilities/index.d.ts +2 -0
  131. package/dist/runtime/capabilities/normalize-runtime-capabilities.d.ts +2 -0
  132. package/dist/runtime/capabilities/runtime-capabilities.d.ts +6 -0
  133. package/dist/runtime/config/agent-message-codec.d.ts +6 -0
  134. package/dist/runtime/{agent-runtime-config-builder.d.ts → config/agent-runtime-config-builder.d.ts} +12 -21
  135. package/dist/runtime/host/history.d.ts +18 -0
  136. package/dist/runtime/{host.d.ts → host/host.d.ts} +3 -4
  137. package/dist/runtime/host/local/agent-event-bridge.d.ts +29 -0
  138. package/dist/runtime/host/local/session-record.d.ts +6 -0
  139. package/dist/runtime/host/local/session-service-invoker.d.ts +4 -0
  140. package/dist/runtime/host/local/spawn-tool.d.ts +15 -0
  141. package/dist/runtime/host/local/user-files.d.ts +1 -0
  142. package/dist/runtime/host/local-runtime-host.d.ts +118 -0
  143. package/dist/{transports → runtime/host}/runtime-host-support.d.ts +3 -5
  144. package/dist/runtime/{runtime-host.d.ts → host/runtime-host.d.ts} +66 -31
  145. package/dist/runtime/{runtime-builder.d.ts → orchestration/runtime-builder.d.ts} +0 -1
  146. package/dist/runtime/{runtime-event-adapter.d.ts → orchestration/runtime-event-adapter.d.ts} +0 -1
  147. package/dist/runtime/{runtime-oauth-token-manager.d.ts → orchestration/runtime-oauth-token-manager.d.ts} +1 -2
  148. package/dist/runtime/{session-runtime-orchestrator.d.ts → orchestration/session-runtime-orchestrator.d.ts} +20 -63
  149. package/dist/runtime/{session-runtime.d.ts → orchestration/session-runtime.d.ts} +14 -12
  150. package/dist/runtime/{user-input-builder.d.ts → orchestration/user-input-builder.d.ts} +2 -11
  151. package/dist/runtime/{loop-detection.d.ts → safety/loop-detection.d.ts} +0 -1
  152. package/dist/runtime/{mistake-tracker.d.ts → safety/mistake-tracker.d.ts} +0 -1
  153. package/dist/runtime/{rules.d.ts → safety/rules.d.ts} +1 -2
  154. package/dist/runtime/{subprocess-sandbox.d.ts → tools/subprocess-sandbox.d.ts} +15 -1
  155. package/dist/runtime/{tool-approval.d.ts → tools/tool-approval.d.ts} +0 -1
  156. package/dist/runtime/turn-queue/pending-prompt-service.d.ts +64 -0
  157. package/dist/services/agent-events.d.ts +1 -2
  158. package/dist/services/config.d.ts +0 -1
  159. package/dist/services/global-settings.d.ts +27 -5
  160. package/dist/{llms → services/llms}/cline-recommended-models.d.ts +1 -2
  161. package/dist/{llms → services/llms}/configured-provider-registry.d.ts +0 -1
  162. package/dist/services/llms/handler-factory.d.ts +3 -0
  163. package/dist/{llms → services/llms}/provider-defaults.d.ts +2 -1
  164. package/dist/{llms → services/llms}/provider-settings.d.ts +5 -3
  165. package/dist/{llms → services/llms}/runtime-config.d.ts +0 -1
  166. package/dist/{llms → services/llms}/runtime-registry.d.ts +0 -1
  167. package/dist/{llms → services/llms}/runtime-types.d.ts +0 -1
  168. package/dist/services/local-runtime-bootstrap.d.ts +7 -9
  169. package/dist/services/plugin-tools.d.ts +0 -1
  170. package/dist/services/providers/local-provider-registry.d.ts +9 -10
  171. package/dist/services/providers/local-provider-service.d.ts +36 -3
  172. package/dist/services/providers/model-source.d.ts +3 -0
  173. package/dist/services/session-artifacts.d.ts +0 -1
  174. package/dist/services/session-data.d.ts +2 -3
  175. package/dist/services/session-telemetry.d.ts +0 -1
  176. package/dist/services/storage/file-team-store.d.ts +0 -1
  177. package/dist/services/storage/provider-settings-legacy-migration.d.ts +0 -1
  178. package/dist/services/storage/provider-settings-manager.d.ts +3 -4
  179. package/dist/services/storage/sqlite-session-store.d.ts +0 -1
  180. package/dist/services/storage/sqlite-team-store.d.ts +0 -1
  181. package/dist/services/storage/team-store.d.ts +0 -1
  182. package/dist/services/telemetry/ITelemetryAdapter.d.ts +0 -1
  183. package/dist/services/telemetry/OpenTelemetryAdapter.d.ts +0 -1
  184. package/dist/services/telemetry/OpenTelemetryProvider.d.ts +32 -1
  185. package/dist/services/telemetry/TelemetryLoggerSink.d.ts +0 -1
  186. package/dist/services/telemetry/TelemetryService.d.ts +0 -1
  187. package/dist/services/telemetry/core-events.d.ts +46 -3
  188. package/dist/services/telemetry/distinct-id.d.ts +0 -1
  189. package/dist/services/telemetry/index.d.ts +1 -2
  190. package/dist/services/telemetry/index.js +1 -0
  191. package/dist/services/usage.d.ts +10 -2
  192. package/dist/services/workspace/file-indexer.d.ts +0 -1
  193. package/dist/services/workspace/index.d.ts +0 -1
  194. package/dist/services/workspace/mention-enricher.d.ts +0 -1
  195. package/dist/{session → services/workspace}/workspace-manager.d.ts +0 -1
  196. package/dist/services/{workspace-manifest.d.ts → workspace/workspace-manifest.d.ts} +20 -5
  197. package/dist/services/workspace/workspace-telemetry.d.ts +18 -0
  198. package/dist/session/checkpoint-restore.d.ts +20 -0
  199. package/dist/session/{session-graph.d.ts → models/session-graph.d.ts} +2 -3
  200. package/dist/session/{session-manifest.d.ts → models/session-manifest.d.ts} +0 -1
  201. package/dist/session/{session-row.d.ts → models/session-row.d.ts} +2 -3
  202. package/dist/session/{file-session-service.d.ts → services/file-session-service.d.ts} +1 -2
  203. package/dist/session/{message-builder.d.ts → services/message-builder.d.ts} +7 -16
  204. package/dist/session/{persistence-service.d.ts → services/persistence-service.d.ts} +10 -11
  205. package/dist/session/{session-service.d.ts → services/session-service.d.ts} +4 -5
  206. package/dist/session/session-snapshot.d.ts +57 -0
  207. package/dist/session/session-versioning-service.d.ts +48 -0
  208. package/dist/session/{conversation-store.d.ts → stores/conversation-store.d.ts} +0 -1
  209. package/dist/session/{session-manifest-store.d.ts → stores/session-manifest-store.d.ts} +3 -4
  210. package/dist/session/{team-persistence-store.d.ts → stores/team-persistence-store.d.ts} +2 -3
  211. package/dist/session/team/index.d.ts +2 -0
  212. package/dist/session/{subagent-session-manager.d.ts → team/team-child-session-manager.d.ts} +7 -8
  213. package/dist/session/{session-team-coordination.d.ts → team/team-session-coordinator.d.ts} +3 -4
  214. package/dist/settings/index.d.ts +2 -0
  215. package/dist/settings/settings-service.d.ts +6 -0
  216. package/dist/settings/types.d.ts +42 -0
  217. package/dist/types/chat-schema.d.ts +24 -7
  218. package/dist/types/common.d.ts +0 -1
  219. package/dist/types/config.d.ts +2 -3
  220. package/dist/types/events.d.ts +8 -1
  221. package/dist/types/provider-settings.d.ts +2 -3
  222. package/dist/types/session.d.ts +22 -6
  223. package/dist/types/sessions.d.ts +0 -1
  224. package/dist/types/storage.d.ts +0 -1
  225. package/dist/types.d.ts +17 -14
  226. package/dist/version.d.ts +0 -1
  227. package/package.json +16 -12
  228. package/dist/ClineCore.d.ts.map +0 -1
  229. package/dist/account/cline-account-service.d.ts.map +0 -1
  230. package/dist/account/index.d.ts.map +0 -1
  231. package/dist/account/rpc.d.ts.map +0 -1
  232. package/dist/account/types.d.ts.map +0 -1
  233. package/dist/auth/bounded-ttl-cache.d.ts.map +0 -1
  234. package/dist/auth/client.d.ts.map +0 -1
  235. package/dist/auth/cline.d.ts.map +0 -1
  236. package/dist/auth/codex.d.ts.map +0 -1
  237. package/dist/auth/oca.d.ts.map +0 -1
  238. package/dist/auth/server.d.ts.map +0 -1
  239. package/dist/auth/types.d.ts.map +0 -1
  240. package/dist/auth/utils.d.ts.map +0 -1
  241. package/dist/cron/cron-event-ingress.d.ts.map +0 -1
  242. package/dist/cron/cron-materializer.d.ts.map +0 -1
  243. package/dist/cron/cron-reconciler.d.ts.map +0 -1
  244. package/dist/cron/cron-report-writer.d.ts.map +0 -1
  245. package/dist/cron/cron-runner.d.ts.map +0 -1
  246. package/dist/cron/cron-schema.d.ts.map +0 -1
  247. package/dist/cron/cron-service.d.ts.map +0 -1
  248. package/dist/cron/cron-spec-parser.d.ts.map +0 -1
  249. package/dist/cron/cron-watcher.d.ts.map +0 -1
  250. package/dist/cron/resource-limiter.d.ts.map +0 -1
  251. package/dist/cron/schedule-command-service.d.ts.map +0 -1
  252. package/dist/cron/schedule-service.d.ts.map +0 -1
  253. package/dist/cron/scheduler.d.ts +0 -68
  254. package/dist/cron/scheduler.d.ts.map +0 -1
  255. package/dist/cron/sqlite-cron-store.d.ts.map +0 -1
  256. package/dist/cron/sqlite-schedule-store.d.ts +0 -52
  257. package/dist/cron/sqlite-schedule-store.d.ts.map +0 -1
  258. package/dist/extensions/config/agent-config-loader.d.ts +0 -20
  259. package/dist/extensions/config/agent-config-loader.d.ts.map +0 -1
  260. package/dist/extensions/config/agent-config-parser.d.ts +0 -29
  261. package/dist/extensions/config/agent-config-parser.d.ts.map +0 -1
  262. package/dist/extensions/config/hooks-config-loader.d.ts.map +0 -1
  263. package/dist/extensions/config/index.d.ts.map +0 -1
  264. package/dist/extensions/config/runtime-commands.d.ts.map +0 -1
  265. package/dist/extensions/config/unified-config-file-watcher.d.ts.map +0 -1
  266. package/dist/extensions/config/user-instruction-config-loader.d.ts.map +0 -1
  267. package/dist/extensions/context/agentic-compaction.d.ts.map +0 -1
  268. package/dist/extensions/context/basic-compaction.d.ts.map +0 -1
  269. package/dist/extensions/context/compaction-shared.d.ts.map +0 -1
  270. package/dist/extensions/context/compaction.d.ts.map +0 -1
  271. package/dist/extensions/index.d.ts.map +0 -1
  272. package/dist/extensions/mcp/client.d.ts.map +0 -1
  273. package/dist/extensions/mcp/config-loader.d.ts.map +0 -1
  274. package/dist/extensions/mcp/index.d.ts.map +0 -1
  275. package/dist/extensions/mcp/manager.d.ts.map +0 -1
  276. package/dist/extensions/mcp/name-transform.d.ts.map +0 -1
  277. package/dist/extensions/mcp/policies.d.ts.map +0 -1
  278. package/dist/extensions/mcp/tools.d.ts.map +0 -1
  279. package/dist/extensions/mcp/types.d.ts.map +0 -1
  280. package/dist/extensions/plugin/plugin-config-loader.d.ts.map +0 -1
  281. package/dist/extensions/plugin/plugin-load-report.d.ts.map +0 -1
  282. package/dist/extensions/plugin/plugin-loader.d.ts.map +0 -1
  283. package/dist/extensions/plugin/plugin-module-import.d.ts.map +0 -1
  284. package/dist/extensions/plugin/plugin-sandbox.d.ts.map +0 -1
  285. package/dist/extensions/plugin/plugin-targeting.d.ts.map +0 -1
  286. package/dist/extensions/tools/constants.d.ts.map +0 -1
  287. package/dist/extensions/tools/definitions.d.ts.map +0 -1
  288. package/dist/extensions/tools/executors/apply-patch-parser.d.ts.map +0 -1
  289. package/dist/extensions/tools/executors/apply-patch.d.ts.map +0 -1
  290. package/dist/extensions/tools/executors/bash.d.ts.map +0 -1
  291. package/dist/extensions/tools/executors/editor.d.ts.map +0 -1
  292. package/dist/extensions/tools/executors/file-read.d.ts.map +0 -1
  293. package/dist/extensions/tools/executors/index.d.ts.map +0 -1
  294. package/dist/extensions/tools/executors/search.d.ts.map +0 -1
  295. package/dist/extensions/tools/executors/web-fetch.d.ts.map +0 -1
  296. package/dist/extensions/tools/helpers.d.ts.map +0 -1
  297. package/dist/extensions/tools/index.d.ts.map +0 -1
  298. package/dist/extensions/tools/model-tool-routing.d.ts.map +0 -1
  299. package/dist/extensions/tools/presets.d.ts.map +0 -1
  300. package/dist/extensions/tools/runtime.d.ts.map +0 -1
  301. package/dist/extensions/tools/schemas.d.ts.map +0 -1
  302. package/dist/extensions/tools/team/delegated-agent.d.ts.map +0 -1
  303. package/dist/extensions/tools/team/index.d.ts.map +0 -1
  304. package/dist/extensions/tools/team/multi-agent.d.ts.map +0 -1
  305. package/dist/extensions/tools/team/projections.d.ts.map +0 -1
  306. package/dist/extensions/tools/team/runtime.d.ts.map +0 -1
  307. package/dist/extensions/tools/team/spawn-agent-tool.d.ts.map +0 -1
  308. package/dist/extensions/tools/team/subagent-prompts.d.ts.map +0 -1
  309. package/dist/extensions/tools/team/team-tools.d.ts.map +0 -1
  310. package/dist/extensions/tools/types.d.ts.map +0 -1
  311. package/dist/hooks/checkpoint-hooks.d.ts.map +0 -1
  312. package/dist/hooks/hook-bridge.d.ts +0 -118
  313. package/dist/hooks/hook-bridge.d.ts.map +0 -1
  314. package/dist/hooks/hook-file-hooks.d.ts.map +0 -1
  315. package/dist/hooks/hook-registry.d.ts +0 -16
  316. package/dist/hooks/hook-registry.d.ts.map +0 -1
  317. package/dist/hooks/index.d.ts.map +0 -1
  318. package/dist/hooks/subprocess-runner.d.ts.map +0 -1
  319. package/dist/hooks/subprocess.d.ts.map +0 -1
  320. package/dist/hub/browser-websocket.d.ts.map +0 -1
  321. package/dist/hub/client.d.ts.map +0 -1
  322. package/dist/hub/connect.d.ts.map +0 -1
  323. package/dist/hub/daemon-entry.d.ts +0 -2
  324. package/dist/hub/daemon-entry.d.ts.map +0 -1
  325. package/dist/hub/daemon-entry.js +0 -1305
  326. package/dist/hub/daemon.d.ts.map +0 -1
  327. package/dist/hub/defaults.d.ts.map +0 -1
  328. package/dist/hub/discovery.d.ts.map +0 -1
  329. package/dist/hub/index.d.ts.map +0 -1
  330. package/dist/hub/native-transport.d.ts.map +0 -1
  331. package/dist/hub/runtime-handlers.d.ts.map +0 -1
  332. package/dist/hub/server.d.ts +0 -104
  333. package/dist/hub/server.d.ts.map +0 -1
  334. package/dist/hub/session-client.d.ts.map +0 -1
  335. package/dist/hub/start-shared-server.d.ts.map +0 -1
  336. package/dist/hub/transport.d.ts.map +0 -1
  337. package/dist/hub/ui-client.d.ts.map +0 -1
  338. package/dist/hub/workspace.d.ts.map +0 -1
  339. package/dist/index.d.ts.map +0 -1
  340. package/dist/llms/cline-recommended-models.d.ts.map +0 -1
  341. package/dist/llms/configured-provider-registry.d.ts.map +0 -1
  342. package/dist/llms/handler-factory.d.ts +0 -16
  343. package/dist/llms/handler-factory.d.ts.map +0 -1
  344. package/dist/llms/provider-defaults.d.ts.map +0 -1
  345. package/dist/llms/provider-settings.d.ts.map +0 -1
  346. package/dist/llms/runtime-config.d.ts.map +0 -1
  347. package/dist/llms/runtime-registry.d.ts.map +0 -1
  348. package/dist/llms/runtime-types.d.ts.map +0 -1
  349. package/dist/runtime/agent-config-adapter.d.ts +0 -148
  350. package/dist/runtime/agent-config-adapter.d.ts.map +0 -1
  351. package/dist/runtime/agent-runtime-config-builder.d.ts.map +0 -1
  352. package/dist/runtime/history.d.ts +0 -10
  353. package/dist/runtime/history.d.ts.map +0 -1
  354. package/dist/runtime/host.d.ts.map +0 -1
  355. package/dist/runtime/loop-detection.d.ts.map +0 -1
  356. package/dist/runtime/mistake-tracker.d.ts.map +0 -1
  357. package/dist/runtime/rules.d.ts.map +0 -1
  358. package/dist/runtime/runtime-builder.d.ts.map +0 -1
  359. package/dist/runtime/runtime-event-adapter.d.ts.map +0 -1
  360. package/dist/runtime/runtime-host.d.ts.map +0 -1
  361. package/dist/runtime/runtime-oauth-token-manager.d.ts.map +0 -1
  362. package/dist/runtime/session-runtime-orchestrator.d.ts.map +0 -1
  363. package/dist/runtime/session-runtime.d.ts.map +0 -1
  364. package/dist/runtime/subprocess-sandbox.d.ts.map +0 -1
  365. package/dist/runtime/tool-approval.d.ts.map +0 -1
  366. package/dist/runtime/user-input-builder.d.ts.map +0 -1
  367. package/dist/services/agent-events.d.ts.map +0 -1
  368. package/dist/services/config.d.ts.map +0 -1
  369. package/dist/services/global-settings.d.ts.map +0 -1
  370. package/dist/services/index.js +0 -28
  371. package/dist/services/local-runtime-bootstrap.d.ts.map +0 -1
  372. package/dist/services/plugin-tools.d.ts.map +0 -1
  373. package/dist/services/providers/local-provider-registry.d.ts.map +0 -1
  374. package/dist/services/providers/local-provider-service.d.ts.map +0 -1
  375. package/dist/services/session-artifacts.d.ts.map +0 -1
  376. package/dist/services/session-data.d.ts.map +0 -1
  377. package/dist/services/session-telemetry.d.ts.map +0 -1
  378. package/dist/services/storage/file-team-store.d.ts.map +0 -1
  379. package/dist/services/storage/provider-settings-legacy-migration.d.ts.map +0 -1
  380. package/dist/services/storage/provider-settings-manager.d.ts.map +0 -1
  381. package/dist/services/storage/sqlite-session-store.d.ts.map +0 -1
  382. package/dist/services/storage/sqlite-team-store.d.ts.map +0 -1
  383. package/dist/services/storage/team-store.d.ts.map +0 -1
  384. package/dist/services/telemetry/ITelemetryAdapter.d.ts.map +0 -1
  385. package/dist/services/telemetry/OpenTelemetryAdapter.d.ts.map +0 -1
  386. package/dist/services/telemetry/OpenTelemetryProvider.d.ts.map +0 -1
  387. package/dist/services/telemetry/TelemetryLoggerSink.d.ts.map +0 -1
  388. package/dist/services/telemetry/TelemetryService.d.ts.map +0 -1
  389. package/dist/services/telemetry/core-events.d.ts.map +0 -1
  390. package/dist/services/telemetry/distinct-id.d.ts.map +0 -1
  391. package/dist/services/telemetry/index.d.ts.map +0 -1
  392. package/dist/services/usage.d.ts.map +0 -1
  393. package/dist/services/workspace/file-indexer.d.ts.map +0 -1
  394. package/dist/services/workspace/index.d.ts.map +0 -1
  395. package/dist/services/workspace/mention-enricher.d.ts.map +0 -1
  396. package/dist/services/workspace-manifest.d.ts.map +0 -1
  397. package/dist/session/conversation-store.d.ts.map +0 -1
  398. package/dist/session/file-session-service.d.ts.map +0 -1
  399. package/dist/session/message-builder.d.ts.map +0 -1
  400. package/dist/session/persistence-service.d.ts.map +0 -1
  401. package/dist/session/session-graph.d.ts.map +0 -1
  402. package/dist/session/session-manifest-store.d.ts.map +0 -1
  403. package/dist/session/session-manifest.d.ts.map +0 -1
  404. package/dist/session/session-row.d.ts.map +0 -1
  405. package/dist/session/session-service.d.ts.map +0 -1
  406. package/dist/session/session-team-coordination.d.ts.map +0 -1
  407. package/dist/session/subagent-session-manager.d.ts.map +0 -1
  408. package/dist/session/team-persistence-store.d.ts.map +0 -1
  409. package/dist/session/workspace-manager.d.ts.map +0 -1
  410. package/dist/transports/hub.d.ts +0 -58
  411. package/dist/transports/hub.d.ts.map +0 -1
  412. package/dist/transports/local.d.ts +0 -119
  413. package/dist/transports/local.d.ts.map +0 -1
  414. package/dist/transports/remote.d.ts.map +0 -1
  415. package/dist/transports/runtime-host-support.d.ts.map +0 -1
  416. package/dist/types/chat-schema.d.ts.map +0 -1
  417. package/dist/types/common.d.ts.map +0 -1
  418. package/dist/types/config.d.ts.map +0 -1
  419. package/dist/types/events.d.ts.map +0 -1
  420. package/dist/types/provider-settings.d.ts.map +0 -1
  421. package/dist/types/session.d.ts.map +0 -1
  422. package/dist/types/sessions.d.ts.map +0 -1
  423. package/dist/types/storage.d.ts.map +0 -1
  424. package/dist/types.d.ts.map +0 -1
  425. package/dist/version.d.ts.map +0 -1
  426. package/src/ClineCore.ts +0 -1026
  427. package/src/account/cline-account-service.ts +0 -338
  428. package/src/account/index.ts +0 -24
  429. package/src/account/rpc.ts +0 -185
  430. package/src/account/types.ts +0 -108
  431. package/src/auth/bounded-ttl-cache.ts +0 -53
  432. package/src/auth/client.ts +0 -46
  433. package/src/auth/cline.ts +0 -724
  434. package/src/auth/codex.ts +0 -491
  435. package/src/auth/oca.ts +0 -588
  436. package/src/auth/server.ts +0 -265
  437. package/src/auth/types.ts +0 -110
  438. package/src/auth/utils.ts +0 -247
  439. package/src/cron/cron-event-ingress.ts +0 -357
  440. package/src/cron/cron-materializer.ts +0 -97
  441. package/src/cron/cron-reconciler.ts +0 -241
  442. package/src/cron/cron-report-writer.ts +0 -153
  443. package/src/cron/cron-runner.ts +0 -495
  444. package/src/cron/cron-schema.ts +0 -127
  445. package/src/cron/cron-service.ts +0 -163
  446. package/src/cron/cron-spec-parser.ts +0 -489
  447. package/src/cron/cron-watcher.ts +0 -102
  448. package/src/cron/index.ts +0 -15
  449. package/src/cron/resource-limiter.ts +0 -46
  450. package/src/cron/schedule-command-service.ts +0 -193
  451. package/src/cron/schedule-service.ts +0 -703
  452. package/src/cron/scheduler.ts +0 -772
  453. package/src/cron/sqlite-cron-store.ts +0 -1286
  454. package/src/cron/sqlite-schedule-store.ts +0 -708
  455. package/src/extensions/config/agent-config-loader.ts +0 -114
  456. package/src/extensions/config/agent-config-parser.ts +0 -198
  457. package/src/extensions/config/hooks-config-loader.ts +0 -117
  458. package/src/extensions/config/index.ts +0 -77
  459. package/src/extensions/config/runtime-commands.ts +0 -82
  460. package/src/extensions/config/unified-config-file-watcher.ts +0 -496
  461. package/src/extensions/config/user-instruction-config-loader.ts +0 -549
  462. package/src/extensions/context/agentic-compaction.ts +0 -131
  463. package/src/extensions/context/basic-compaction.ts +0 -300
  464. package/src/extensions/context/compaction-shared.ts +0 -459
  465. package/src/extensions/context/compaction.ts +0 -226
  466. package/src/extensions/index.ts +0 -18
  467. package/src/extensions/mcp/client.ts +0 -420
  468. package/src/extensions/mcp/config-loader.ts +0 -219
  469. package/src/extensions/mcp/index.ts +0 -42
  470. package/src/extensions/mcp/manager.ts +0 -260
  471. package/src/extensions/mcp/name-transform.ts +0 -33
  472. package/src/extensions/mcp/policies.ts +0 -47
  473. package/src/extensions/mcp/tools.ts +0 -47
  474. package/src/extensions/mcp/types.ts +0 -116
  475. package/src/extensions/plugin/plugin-config-loader.ts +0 -140
  476. package/src/extensions/plugin/plugin-load-report.ts +0 -20
  477. package/src/extensions/plugin/plugin-loader.ts +0 -220
  478. package/src/extensions/plugin/plugin-module-import.ts +0 -276
  479. package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +0 -662
  480. package/src/extensions/plugin/plugin-sandbox.ts +0 -586
  481. package/src/extensions/plugin/plugin-targeting.ts +0 -32
  482. package/src/extensions/tools/constants.ts +0 -37
  483. package/src/extensions/tools/definitions.ts +0 -738
  484. package/src/extensions/tools/executors/apply-patch-parser.ts +0 -520
  485. package/src/extensions/tools/executors/apply-patch.ts +0 -348
  486. package/src/extensions/tools/executors/bash.ts +0 -207
  487. package/src/extensions/tools/executors/editor.ts +0 -220
  488. package/src/extensions/tools/executors/file-read.ts +0 -135
  489. package/src/extensions/tools/executors/index.ts +0 -87
  490. package/src/extensions/tools/executors/search.ts +0 -470
  491. package/src/extensions/tools/executors/web-fetch.ts +0 -259
  492. package/src/extensions/tools/helpers.ts +0 -154
  493. package/src/extensions/tools/index.ts +0 -183
  494. package/src/extensions/tools/model-tool-routing.ts +0 -134
  495. package/src/extensions/tools/presets.ts +0 -190
  496. package/src/extensions/tools/runtime.ts +0 -261
  497. package/src/extensions/tools/schemas.ts +0 -343
  498. package/src/extensions/tools/team/delegated-agent.ts +0 -136
  499. package/src/extensions/tools/team/index.ts +0 -5
  500. package/src/extensions/tools/team/multi-agent.ts +0 -1845
  501. package/src/extensions/tools/team/projections.ts +0 -283
  502. package/src/extensions/tools/team/runtime.ts +0 -54
  503. package/src/extensions/tools/team/spawn-agent-tool.ts +0 -201
  504. package/src/extensions/tools/team/subagent-prompts.ts +0 -41
  505. package/src/extensions/tools/team/team-tools.ts +0 -902
  506. package/src/extensions/tools/types.ts +0 -354
  507. package/src/hooks/checkpoint-hooks.ts +0 -238
  508. package/src/hooks/hook-bridge.ts +0 -489
  509. package/src/hooks/hook-file-hooks.ts +0 -934
  510. package/src/hooks/hook-registry.ts +0 -257
  511. package/src/hooks/index.ts +0 -18
  512. package/src/hooks/subprocess-runner.ts +0 -196
  513. package/src/hooks/subprocess.ts +0 -469
  514. package/src/hub/browser-websocket.ts +0 -159
  515. package/src/hub/client.ts +0 -633
  516. package/src/hub/connect.ts +0 -156
  517. package/src/hub/daemon-entry.ts +0 -122
  518. package/src/hub/daemon.ts +0 -284
  519. package/src/hub/defaults.ts +0 -70
  520. package/src/hub/discovery.ts +0 -247
  521. package/src/hub/index.ts +0 -14
  522. package/src/hub/native-transport.ts +0 -31
  523. package/src/hub/runtime-handlers.ts +0 -141
  524. package/src/hub/server.ts +0 -2317
  525. package/src/hub/session-client.ts +0 -502
  526. package/src/hub/start-shared-server.ts +0 -61
  527. package/src/hub/transport.ts +0 -14
  528. package/src/hub/ui-client.ts +0 -126
  529. package/src/hub/workspace.ts +0 -19
  530. package/src/index.ts +0 -688
  531. package/src/llms/cline-recommended-models.ts +0 -167
  532. package/src/llms/configured-provider-registry.ts +0 -193
  533. package/src/llms/handler-factory.ts +0 -56
  534. package/src/llms/provider-defaults.ts +0 -653
  535. package/src/llms/provider-settings.ts +0 -310
  536. package/src/llms/runtime-config.ts +0 -43
  537. package/src/llms/runtime-registry.ts +0 -172
  538. package/src/llms/runtime-types.ts +0 -121
  539. package/src/runtime/agent-config-adapter.ts +0 -636
  540. package/src/runtime/agent-runtime-config-builder.ts +0 -205
  541. package/src/runtime/error-feedback.ts +0 -142
  542. package/src/runtime/history.ts +0 -374
  543. package/src/runtime/host.ts +0 -222
  544. package/src/runtime/index.ts +0 -23
  545. package/src/runtime/loop-detection.ts +0 -162
  546. package/src/runtime/mistake-tracker.ts +0 -221
  547. package/src/runtime/rules.ts +0 -49
  548. package/src/runtime/runtime-builder.ts +0 -814
  549. package/src/runtime/runtime-event-adapter.ts +0 -412
  550. package/src/runtime/runtime-host.ts +0 -250
  551. package/src/runtime/runtime-oauth-token-manager.ts +0 -268
  552. package/src/runtime/session-runtime-orchestrator.ts +0 -1253
  553. package/src/runtime/session-runtime.ts +0 -69
  554. package/src/runtime/subprocess-sandbox.ts +0 -255
  555. package/src/runtime/tool-approval.ts +0 -102
  556. package/src/runtime/user-input-builder.ts +0 -167
  557. package/src/services/agent-events.ts +0 -256
  558. package/src/services/config.ts +0 -5
  559. package/src/services/global-settings.ts +0 -122
  560. package/src/services/local-runtime-bootstrap.ts +0 -424
  561. package/src/services/plugin-tools.ts +0 -86
  562. package/src/services/providers/local-provider-registry.ts +0 -456
  563. package/src/services/providers/local-provider-service.ts +0 -772
  564. package/src/services/session-artifacts.ts +0 -138
  565. package/src/services/session-data.ts +0 -398
  566. package/src/services/session-telemetry.ts +0 -89
  567. package/src/services/storage/artifact-store.ts +0 -1
  568. package/src/services/storage/file-team-store.ts +0 -250
  569. package/src/services/storage/index.ts +0 -11
  570. package/src/services/storage/provider-settings-legacy-migration.ts +0 -789
  571. package/src/services/storage/provider-settings-manager.ts +0 -167
  572. package/src/services/storage/session-store.ts +0 -1
  573. package/src/services/storage/sqlite-session-store.ts +0 -270
  574. package/src/services/storage/sqlite-team-store.ts +0 -537
  575. package/src/services/storage/team-store.ts +0 -36
  576. package/src/services/telemetry/ITelemetryAdapter.ts +0 -94
  577. package/src/services/telemetry/OpenTelemetryAdapter.ts +0 -348
  578. package/src/services/telemetry/OpenTelemetryProvider.ts +0 -415
  579. package/src/services/telemetry/TelemetryLoggerSink.ts +0 -121
  580. package/src/services/telemetry/TelemetryService.ts +0 -139
  581. package/src/services/telemetry/core-events.ts +0 -400
  582. package/src/services/telemetry/distinct-id.ts +0 -58
  583. package/src/services/telemetry/index.ts +0 -20
  584. package/src/services/usage.ts +0 -32
  585. package/src/services/workspace/file-indexer.ts +0 -351
  586. package/src/services/workspace/index.ts +0 -7
  587. package/src/services/workspace/mention-enricher.ts +0 -122
  588. package/src/services/workspace-manifest.ts +0 -72
  589. package/src/session/conversation-store.ts +0 -77
  590. package/src/session/file-session-service.ts +0 -282
  591. package/src/session/index.ts +0 -32
  592. package/src/session/message-builder.ts +0 -941
  593. package/src/session/persistence-service.ts +0 -559
  594. package/src/session/session-graph.ts +0 -92
  595. package/src/session/session-manifest-store.ts +0 -158
  596. package/src/session/session-manifest.ts +0 -29
  597. package/src/session/session-row.ts +0 -199
  598. package/src/session/session-service.ts +0 -324
  599. package/src/session/session-team-coordination.ts +0 -240
  600. package/src/session/subagent-session-manager.ts +0 -397
  601. package/src/session/team-persistence-store.ts +0 -176
  602. package/src/session/workspace-manager.ts +0 -100
  603. package/src/transports/hub.ts +0 -1081
  604. package/src/transports/local.ts +0 -1826
  605. package/src/transports/remote.ts +0 -27
  606. package/src/transports/runtime-host-support.ts +0 -140
  607. package/src/types/chat-schema.ts +0 -81
  608. package/src/types/common.ts +0 -26
  609. package/src/types/config.ts +0 -220
  610. package/src/types/events.ts +0 -80
  611. package/src/types/index.ts +0 -26
  612. package/src/types/provider-settings.ts +0 -54
  613. package/src/types/session.ts +0 -111
  614. package/src/types/sessions.ts +0 -37
  615. package/src/types/storage.ts +0 -56
  616. package/src/types.ts +0 -167
  617. package/src/version.ts +0 -3
@@ -1,1845 +0,0 @@
1
- /**
2
- * Multi-Agent Coordination
3
- *
4
- * Utilities for orchestrating multiple agents working together.
5
- */
6
-
7
- import {
8
- type AgentConfig,
9
- type AgentEvent,
10
- type AgentResult,
11
- type AppendMissionLogInput,
12
- type AttachTeamOutcomeFragmentInput,
13
- type CreateTeamOutcomeInput,
14
- type CreateTeamTaskInput,
15
- type MissionLogEntry,
16
- type ReviewTeamOutcomeFragmentInput,
17
- type RouteToTeammateOptions,
18
- sanitizeFileName,
19
- type TeamMailboxMessage,
20
- type TeamMemberSnapshot,
21
- TeamMessageType,
22
- type TeammateLifecycleSpec,
23
- type TeamOutcome,
24
- type TeamOutcomeFragment,
25
- type TeamOutcomeStatus,
26
- type TeamRunRecord,
27
- type TeamRunStatus,
28
- type TeamRuntimeSnapshot,
29
- type TeamRuntimeState,
30
- type TeamTask,
31
- type TeamTaskListItem,
32
- type TeamTaskStatus,
33
- } from "@clinebot/shared";
34
- import { nanoid } from "nanoid";
35
- import { SessionRuntime } from "../../../runtime/session-runtime-orchestrator";
36
-
37
- // Re-export shared types for backward compatibility
38
- export {
39
- type AppendMissionLogInput,
40
- type AttachTeamOutcomeFragmentInput,
41
- type CreateTeamOutcomeInput,
42
- type CreateTeamTaskInput,
43
- type MissionLogEntry,
44
- type MissionLogKind,
45
- type ReviewTeamOutcomeFragmentInput,
46
- type RouteToTeammateOptions,
47
- type TeamMailboxMessage,
48
- type TeamMemberSnapshot,
49
- TeamMessageType,
50
- type TeammateLifecycleSpec,
51
- type TeamOutcome,
52
- type TeamOutcomeFragment,
53
- type TeamOutcomeFragmentStatus,
54
- type TeamOutcomeStatus,
55
- type TeamRunRecord,
56
- type TeamRunStatus,
57
- type TeamRuntimeSnapshot,
58
- type TeamRuntimeState,
59
- type TeamTask,
60
- type TeamTaskListItem,
61
- type TeamTaskStatus,
62
- } from "@clinebot/shared";
63
-
64
- // =============================================================================
65
- // Types that depend on @clinebot/agents (cannot live in shared)
66
- // =============================================================================
67
-
68
- export interface TeamMemberConfig extends AgentConfig {
69
- role?: string;
70
- }
71
-
72
- export interface AgentTask {
73
- agentId: string;
74
- message: string;
75
- metadata?: Record<string, unknown>;
76
- }
77
-
78
- export interface TaskResult {
79
- agentId: string;
80
- result: AgentResult;
81
- error?: Error;
82
- metadata?: Record<string, unknown>;
83
- }
84
-
85
- export type TeamEvent =
86
- | { type: TeamMessageType.TaskStart; agentId: string; message: string }
87
- | {
88
- type: TeamMessageType.TaskEnd;
89
- agentId: string;
90
- result?: AgentResult;
91
- error?: Error;
92
- messages?: AgentResult["messages"];
93
- }
94
- | { type: TeamMessageType.AgentEvent; agentId: string; event: AgentEvent }
95
- | {
96
- type: TeamMessageType.TeammateSpawned;
97
- agentId: string;
98
- role?: string;
99
- teammate: TeammateLifecycleSpec;
100
- }
101
- | { type: TeamMessageType.TeammateShutdown; agentId: string; reason?: string }
102
- | { type: TeamMessageType.TeamTaskUpdated; task: TeamTask }
103
- | { type: TeamMessageType.TeamMessage; message: TeamMailboxMessage }
104
- | { type: TeamMessageType.TeamMissionLog; entry: MissionLogEntry }
105
- | { type: TeamMessageType.RunQueued; run: TeamRunRecord }
106
- | { type: TeamMessageType.RunStarted; run: TeamRunRecord }
107
- | { type: TeamMessageType.RunProgress; run: TeamRunRecord; message: string }
108
- | { type: TeamMessageType.RunCompleted; run: TeamRunRecord }
109
- | { type: TeamMessageType.RunFailed; run: TeamRunRecord }
110
- | { type: TeamMessageType.RunCancelled; run: TeamRunRecord; reason?: string }
111
- | {
112
- type: TeamMessageType.RunInterrupted;
113
- run: TeamRunRecord;
114
- reason?: string;
115
- }
116
- | { type: TeamMessageType.OutcomeCreated; outcome: TeamOutcome }
117
- | {
118
- type: TeamMessageType.OutcomeFragmentAttached;
119
- fragment: TeamOutcomeFragment;
120
- }
121
- | {
122
- type: TeamMessageType.OutcomeFragmentReviewed;
123
- fragment: TeamOutcomeFragment;
124
- }
125
- | { type: TeamMessageType.OutcomeFinalized; outcome: TeamOutcome };
126
-
127
- export interface AgentTeamsRuntimeOptions {
128
- teamName: string;
129
- leadAgentId?: string;
130
- missionLogIntervalSteps?: number;
131
- missionLogIntervalMs?: number;
132
- maxConcurrentRuns?: number;
133
- onTeamEvent?: (event: TeamEvent) => void;
134
- }
135
-
136
- export interface SpawnTeammateOptions {
137
- agentId: string;
138
- config: TeamMemberConfig;
139
- }
140
-
141
- function isAbortLikeError(error: unknown): boolean {
142
- if (
143
- typeof DOMException !== "undefined" &&
144
- error instanceof DOMException &&
145
- error.name === "AbortError"
146
- ) {
147
- return true;
148
- }
149
- if (!(error instanceof Error)) {
150
- return false;
151
- }
152
- return (
153
- error.name === "AbortError" ||
154
- error.message.toLowerCase().includes("aborted")
155
- );
156
- }
157
-
158
- function isIntentionalShutdownAbort(
159
- member: TeamMemberState | undefined,
160
- error: unknown,
161
- ): boolean {
162
- return member?.status === "stopped" && isAbortLikeError(error);
163
- }
164
-
165
- // =============================================================================
166
- // AgentTeam
167
- // =============================================================================
168
-
169
- const TEAMMATE_API_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes
170
- const RECOVERED_QUEUED_ACTIVITY = "recovered_queued";
171
-
172
- function buildRecoveredRunMessage(run: TeamRunRecord): string {
173
- return `This is an automatic recovery of interrupted team run ${run.id}. The previous process stopped before completion. Continue the task safely, inspect the current workspace state before making changes, and avoid duplicating completed work.\n\n${run.message}`;
174
- }
175
-
176
- export class AgentTeam {
177
- private agents: Map<string, SessionRuntime> = new Map();
178
- private configs: Map<string, TeamMemberConfig> = new Map();
179
- private onTeamEvent?: (event: TeamEvent) => void;
180
-
181
- constructor(
182
- configs?: Record<string, TeamMemberConfig>,
183
- onTeamEvent?: (event: TeamEvent) => void,
184
- ) {
185
- this.onTeamEvent = onTeamEvent;
186
-
187
- if (configs) {
188
- for (const [id, config] of Object.entries(configs)) {
189
- this.addAgent(id, config);
190
- }
191
- }
192
- }
193
-
194
- addAgent(id: string, config: TeamMemberConfig): void {
195
- if (this.agents.has(id)) {
196
- throw new Error(`Agent with id "${id}" already exists in the team`);
197
- }
198
-
199
- const wrappedConfig: AgentConfig = {
200
- ...config,
201
- onEvent: (event: AgentEvent) => {
202
- config.onEvent?.(event);
203
- this.emitEvent({
204
- type: TeamMessageType.AgentEvent,
205
- agentId: id,
206
- event,
207
- });
208
- },
209
- };
210
-
211
- const agent = new SessionRuntime(wrappedConfig);
212
- if (wrappedConfig.onEvent) {
213
- agent.subscribeEvents(wrappedConfig.onEvent);
214
- }
215
- this.agents.set(id, agent);
216
- this.configs.set(id, config);
217
- }
218
-
219
- removeAgent(id: string): boolean {
220
- this.configs.delete(id);
221
- return this.agents.delete(id);
222
- }
223
-
224
- getAgent(id: string): SessionRuntime | undefined {
225
- return this.agents.get(id);
226
- }
227
-
228
- getAgentIds(): string[] {
229
- return Array.from(this.agents.keys());
230
- }
231
-
232
- get size(): number {
233
- return this.agents.size;
234
- }
235
-
236
- async routeTo(agentId: string, message: string): Promise<AgentResult> {
237
- const agent = this.agents.get(agentId);
238
- if (!agent) {
239
- throw new Error(`Agent "${agentId}" not found in team`);
240
- }
241
-
242
- this.emitEvent({ type: TeamMessageType.TaskStart, agentId, message });
243
-
244
- try {
245
- const result = await agent.run(message);
246
- this.emitEvent({ type: TeamMessageType.TaskEnd, agentId, result });
247
- return result;
248
- } catch (error) {
249
- const err = error instanceof Error ? error : new Error(String(error));
250
- this.emitEvent({
251
- type: TeamMessageType.TaskEnd,
252
- agentId,
253
- error: err,
254
- messages: agent.getMessages(),
255
- });
256
- throw error;
257
- }
258
- }
259
-
260
- async continueTo(agentId: string, message: string): Promise<AgentResult> {
261
- const agent = this.agents.get(agentId);
262
- if (!agent) {
263
- throw new Error(`Agent "${agentId}" not found in team`);
264
- }
265
-
266
- this.emitEvent({ type: TeamMessageType.TaskStart, agentId, message });
267
-
268
- try {
269
- const result = await agent.continue(message);
270
- this.emitEvent({ type: TeamMessageType.TaskEnd, agentId, result });
271
- return result;
272
- } catch (error) {
273
- const err = error instanceof Error ? error : new Error(String(error));
274
- this.emitEvent({
275
- type: TeamMessageType.TaskEnd,
276
- agentId,
277
- error: err,
278
- messages: agent.getMessages(),
279
- });
280
- throw error;
281
- }
282
- }
283
-
284
- async runParallel(tasks: AgentTask[]): Promise<TaskResult[]> {
285
- const executions = tasks.map(async (task): Promise<TaskResult> => {
286
- const agent = this.agents.get(task.agentId);
287
- if (!agent) {
288
- return {
289
- agentId: task.agentId,
290
- result: undefined as unknown as AgentResult,
291
- error: new Error(`Agent "${task.agentId}" not found in team`),
292
- metadata: task.metadata,
293
- };
294
- }
295
-
296
- this.emitEvent({
297
- type: TeamMessageType.TaskStart,
298
- agentId: task.agentId,
299
- message: task.message,
300
- });
301
-
302
- try {
303
- const result = await agent.run(task.message);
304
- this.emitEvent({
305
- type: TeamMessageType.TaskEnd,
306
- agentId: task.agentId,
307
- result,
308
- });
309
- return {
310
- agentId: task.agentId,
311
- result,
312
- metadata: task.metadata,
313
- };
314
- } catch (error) {
315
- const err = error instanceof Error ? error : new Error(String(error));
316
- this.emitEvent({
317
- type: TeamMessageType.TaskEnd,
318
- agentId: task.agentId,
319
- error: err,
320
- messages: agent.getMessages(),
321
- });
322
- return {
323
- agentId: task.agentId,
324
- result: undefined as unknown as AgentResult,
325
- error: err,
326
- metadata: task.metadata,
327
- };
328
- }
329
- });
330
-
331
- return Promise.all(executions);
332
- }
333
-
334
- async runSequential(tasks: AgentTask[]): Promise<TaskResult[]> {
335
- const results: TaskResult[] = [];
336
-
337
- for (const task of tasks) {
338
- const agent = this.agents.get(task.agentId);
339
- if (!agent) {
340
- results.push({
341
- agentId: task.agentId,
342
- result: undefined as unknown as AgentResult,
343
- error: new Error(`Agent "${task.agentId}" not found in team`),
344
- metadata: task.metadata,
345
- });
346
- continue;
347
- }
348
-
349
- this.emitEvent({
350
- type: TeamMessageType.TaskStart,
351
- agentId: task.agentId,
352
- message: task.message,
353
- });
354
-
355
- try {
356
- const result = await agent.run(task.message);
357
- this.emitEvent({
358
- type: TeamMessageType.TaskEnd,
359
- agentId: task.agentId,
360
- result,
361
- });
362
- results.push({
363
- agentId: task.agentId,
364
- result,
365
- metadata: task.metadata,
366
- });
367
- } catch (error) {
368
- const err = error instanceof Error ? error : new Error(String(error));
369
- this.emitEvent({
370
- type: TeamMessageType.TaskEnd,
371
- agentId: task.agentId,
372
- error: err,
373
- messages: agent.getMessages(),
374
- });
375
- results.push({
376
- agentId: task.agentId,
377
- result: undefined as unknown as AgentResult,
378
- error: err,
379
- metadata: task.metadata,
380
- });
381
- }
382
- }
383
-
384
- return results;
385
- }
386
-
387
- async runPipeline(
388
- pipeline: string[],
389
- initialMessage: string,
390
- messageTransformer?: (
391
- prevResult: AgentResult,
392
- nextAgentId: string,
393
- ) => string,
394
- ): Promise<TaskResult[]> {
395
- const results: TaskResult[] = [];
396
- let currentMessage = initialMessage;
397
-
398
- for (const agentId of pipeline) {
399
- const agent = this.agents.get(agentId);
400
- if (!agent) {
401
- results.push({
402
- agentId,
403
- result: undefined as unknown as AgentResult,
404
- error: new Error(`Agent "${agentId}" not found in team`),
405
- });
406
- break;
407
- }
408
-
409
- this.emitEvent({
410
- type: TeamMessageType.TaskStart,
411
- agentId,
412
- message: currentMessage,
413
- });
414
-
415
- try {
416
- const result = await agent.run(currentMessage);
417
- this.emitEvent({ type: TeamMessageType.TaskEnd, agentId, result });
418
- results.push({ agentId, result });
419
-
420
- const nextIndex = pipeline.indexOf(agentId) + 1;
421
- if (nextIndex < pipeline.length) {
422
- const nextAgentId = pipeline[nextIndex];
423
- currentMessage = messageTransformer
424
- ? messageTransformer(result, nextAgentId)
425
- : `Previous agent output:\n${result.text}\n\nPlease continue from here.`;
426
- }
427
- } catch (error) {
428
- const err = error instanceof Error ? error : new Error(String(error));
429
- this.emitEvent({
430
- type: TeamMessageType.TaskEnd,
431
- agentId,
432
- error: err,
433
- messages: agent.getMessages(),
434
- });
435
- results.push({
436
- agentId,
437
- result: undefined as unknown as AgentResult,
438
- error: err,
439
- });
440
- break;
441
- }
442
- }
443
-
444
- return results;
445
- }
446
-
447
- abortAll(): void {
448
- for (const agent of this.agents.values()) {
449
- agent.abort(new Error("Agent team abortAll requested"));
450
- }
451
- }
452
-
453
- clear(): void {
454
- this.abortAll();
455
- this.agents.clear();
456
- this.configs.clear();
457
- }
458
-
459
- private emitEvent(event: TeamEvent): void {
460
- try {
461
- this.onTeamEvent?.(event);
462
- } catch {
463
- // Ignore callback errors
464
- }
465
- }
466
- }
467
-
468
- // =============================================================================
469
- // Factory Functions
470
- // =============================================================================
471
-
472
- export function createAgentTeam(
473
- configs: Record<string, TeamMemberConfig>,
474
- onTeamEvent?: (event: TeamEvent) => void,
475
- ): AgentTeam {
476
- return new AgentTeam(configs, onTeamEvent);
477
- }
478
-
479
- export function createWorkerReviewerTeam(configs: {
480
- worker: TeamMemberConfig;
481
- reviewer: TeamMemberConfig;
482
- }): AgentTeam & {
483
- doAndReview: (
484
- message: string,
485
- ) => Promise<{ workerResult: AgentResult; reviewResult: AgentResult }>;
486
- } {
487
- const team = createAgentTeam({
488
- worker: configs.worker,
489
- reviewer: configs.reviewer,
490
- });
491
-
492
- const enhanced = team as AgentTeam & {
493
- doAndReview: (
494
- message: string,
495
- ) => Promise<{ workerResult: AgentResult; reviewResult: AgentResult }>;
496
- };
497
-
498
- enhanced.doAndReview = async (message: string) => {
499
- const workerResult = await team.routeTo("worker", message);
500
- const reviewResult = await team.routeTo(
501
- "reviewer",
502
- `Please review this work:\n\n${workerResult.text}`,
503
- );
504
- return { workerResult, reviewResult };
505
- };
506
-
507
- return enhanced;
508
- }
509
-
510
- // =============================================================================
511
- // Agent Teams Runtime (lead + teammate collaboration)
512
- // =============================================================================
513
-
514
- interface TeamMemberState extends TeamMemberSnapshot {
515
- agent?: SessionRuntime;
516
- runningCount: number;
517
- lastMissionStep: number;
518
- lastMissionAt: number;
519
- pendingSteerMessage?: string;
520
- }
521
-
522
- export class AgentTeamsRuntime {
523
- private readonly teamId: string;
524
- private readonly teamName: string;
525
- private readonly onTeamEvent?: (event: TeamEvent) => void;
526
- private readonly members: Map<string, TeamMemberState> = new Map();
527
- private readonly tasks: Map<string, TeamTask> = new Map();
528
- private readonly missionLog: MissionLogEntry[] = [];
529
- private readonly mailbox: TeamMailboxMessage[] = [];
530
- private missionStepCounter = 0;
531
- private taskCounter = 0;
532
- private messageCounter = 0;
533
- private missionCounter = 0;
534
- private runCounter = 0;
535
- private outcomeCounter = 0;
536
- private outcomeFragmentCounter = 0;
537
- private readonly runs: Map<string, TeamRunRecord & { result?: AgentResult }> =
538
- new Map();
539
- private readonly runQueue: string[] = [];
540
- private queuedRunDispatchTimer: ReturnType<typeof setTimeout> | undefined;
541
- private readonly outcomes: Map<string, TeamOutcome> = new Map();
542
- private readonly outcomeFragments: Map<string, TeamOutcomeFragment> =
543
- new Map();
544
- private readonly missionLogIntervalSteps: number;
545
- private readonly missionLogIntervalMs: number;
546
- private readonly maxConcurrentRuns: number;
547
-
548
- constructor(options: AgentTeamsRuntimeOptions) {
549
- this.teamName = options.teamName;
550
- this.teamId = `t_${sanitizeFileName(nanoid(10))}`;
551
- this.onTeamEvent = options.onTeamEvent;
552
- this.missionLogIntervalSteps = Math.max(
553
- 1,
554
- options.missionLogIntervalSteps ?? 3,
555
- );
556
- this.missionLogIntervalMs = Math.max(
557
- 1000,
558
- options.missionLogIntervalMs ?? 120000,
559
- );
560
- this.maxConcurrentRuns = Math.max(1, options.maxConcurrentRuns ?? 2);
561
- const leadAgentId = options.leadAgentId ?? "lead";
562
- this.members.set(leadAgentId, {
563
- agentId: leadAgentId,
564
- role: "lead",
565
- status: "idle",
566
- runningCount: 0,
567
- lastMissionStep: 0,
568
- lastMissionAt: Date.now(),
569
- });
570
- }
571
-
572
- getTeamId(): string {
573
- return this.teamId;
574
- }
575
-
576
- getTeamName(): string {
577
- return this.teamName;
578
- }
579
-
580
- getMemberRole(agentId: string): "lead" | "teammate" | undefined {
581
- return this.members.get(agentId)?.role;
582
- }
583
-
584
- getMemberIds(): string[] {
585
- return Array.from(this.members.keys());
586
- }
587
-
588
- getTeammateIds(): string[] {
589
- return Array.from(this.members.values())
590
- .filter((member) => member.role === "teammate")
591
- .map((member) => member.agentId);
592
- }
593
-
594
- getTask(taskId: string): TeamTask | undefined {
595
- return this.tasks.get(taskId);
596
- }
597
-
598
- listTasks(): TeamTask[] {
599
- return Array.from(this.tasks.values());
600
- }
601
-
602
- listTaskItems(options?: {
603
- status?: TeamTaskStatus;
604
- assignee?: string;
605
- }): TeamTaskListItem[] {
606
- return Array.from(this.tasks.values())
607
- .map((task) => {
608
- const blockedBy = this.getUnresolvedDependencies(task);
609
- return {
610
- ...task,
611
- blockedBy,
612
- isReady:
613
- task.status === "pending" &&
614
- !task.assignee &&
615
- blockedBy.length === 0,
616
- };
617
- })
618
- .filter((task) => {
619
- if (options?.status && task.status !== options.status) {
620
- return false;
621
- }
622
- if (options?.assignee && task.assignee !== options.assignee) {
623
- return false;
624
- }
625
- return true;
626
- });
627
- }
628
-
629
- listMissionLog(limit?: number): MissionLogEntry[] {
630
- if (!limit || limit <= 0) {
631
- return [...this.missionLog];
632
- }
633
- return this.missionLog.slice(Math.max(0, this.missionLog.length - limit));
634
- }
635
-
636
- listMailbox(
637
- agentId: string,
638
- options?: { unreadOnly?: boolean; markRead?: boolean; limit?: number },
639
- ): TeamMailboxMessage[] {
640
- const unreadOnly = options?.unreadOnly ?? true;
641
- const markRead = options?.markRead ?? true;
642
- const limit = options?.limit;
643
- const messages = this.mailbox.filter(
644
- (message) =>
645
- message.toAgentId === agentId && (!unreadOnly || !message.readAt),
646
- );
647
- const selected =
648
- typeof limit === "number" && limit > 0
649
- ? messages.slice(Math.max(0, messages.length - limit))
650
- : messages;
651
- if (markRead) {
652
- const now = new Date();
653
- for (const message of selected) {
654
- if (!message.readAt) {
655
- message.readAt = now;
656
- }
657
- }
658
- }
659
- return selected.map((message) => ({ ...message }));
660
- }
661
-
662
- getSnapshot(): TeamRuntimeSnapshot {
663
- const taskCounts: Record<TeamTaskStatus, number> = {
664
- pending: 0,
665
- in_progress: 0,
666
- blocked: 0,
667
- completed: 0,
668
- };
669
- for (const task of this.tasks.values()) {
670
- taskCounts[task.status]++;
671
- }
672
- const outcomeCounts: Record<TeamOutcomeStatus, number> = {
673
- draft: 0,
674
- in_review: 0,
675
- finalized: 0,
676
- };
677
- for (const outcome of this.outcomes.values()) {
678
- outcomeCounts[outcome.status]++;
679
- }
680
- return {
681
- teamId: this.teamId,
682
- teamName: this.teamName,
683
- members: Array.from(this.members.values()).map((member) => ({
684
- agentId: member.agentId,
685
- role: member.role,
686
- description: member.description,
687
- status: member.status,
688
- })),
689
- taskCounts,
690
- unreadMessages: this.mailbox.filter((message) => !message.readAt).length,
691
- missionLogEntries: this.missionLog.length,
692
- activeRuns: Array.from(this.runs.values()).filter(
693
- (run) => run.status === "running",
694
- ).length,
695
- queuedRuns: Array.from(this.runs.values()).filter(
696
- (run) => run.status === "queued",
697
- ).length,
698
- outcomeCounts,
699
- };
700
- }
701
-
702
- exportState(): TeamRuntimeState {
703
- return {
704
- teamId: this.teamId,
705
- teamName: this.teamName,
706
- members: Array.from(this.members.values()).map((member) => ({
707
- agentId: member.agentId,
708
- role: member.role,
709
- description: member.description,
710
- status: member.status,
711
- })),
712
- tasks: Array.from(this.tasks.values()).map((task) => ({ ...task })),
713
- mailbox: this.mailbox.map((message) => ({ ...message })),
714
- missionLog: this.missionLog.map((entry) => ({ ...entry })),
715
- runs: Array.from(this.runs.values()).map((run) => ({ ...run })),
716
- outcomes: Array.from(this.outcomes.values()).map((outcome) => ({
717
- ...outcome,
718
- })),
719
- outcomeFragments: Array.from(this.outcomeFragments.values()).map(
720
- (fragment) => ({ ...fragment }),
721
- ),
722
- };
723
- }
724
-
725
- hydrateState(state: TeamRuntimeState): void {
726
- this.clearQueuedRunDispatchTimer();
727
- this.tasks.clear();
728
- for (const task of state.tasks) {
729
- this.tasks.set(task.id, { ...task });
730
- }
731
-
732
- this.mailbox.length = 0;
733
- this.mailbox.push(...state.mailbox.map((message) => ({ ...message })));
734
-
735
- this.missionLog.length = 0;
736
- this.missionLog.push(...state.missionLog.map((entry) => ({ ...entry })));
737
-
738
- this.runs.clear();
739
- for (const run of state.runs ?? []) {
740
- this.runs.set(run.id, { ...run } as TeamRunRecord & {
741
- result?: AgentResult;
742
- });
743
- }
744
- this.runQueue.length = 0;
745
- this.runQueue.push(
746
- ...Array.from(this.runs.values())
747
- .filter((run) => run.status === "queued")
748
- .map((run) => run.id),
749
- );
750
-
751
- this.outcomes.clear();
752
- for (const outcome of state.outcomes ?? []) {
753
- this.outcomes.set(outcome.id, { ...outcome });
754
- }
755
-
756
- this.outcomeFragments.clear();
757
- for (const fragment of state.outcomeFragments ?? []) {
758
- this.outcomeFragments.set(fragment.id, { ...fragment });
759
- }
760
-
761
- const leadMembers = Array.from(this.members.values()).filter(
762
- (member) => member.role === "lead",
763
- );
764
- this.members.clear();
765
- for (const lead of leadMembers) {
766
- this.members.set(lead.agentId, {
767
- ...lead,
768
- status: "idle",
769
- runningCount: 0,
770
- lastMissionStep: this.missionStepCounter,
771
- lastMissionAt: Date.now(),
772
- });
773
- }
774
- for (const member of state.members) {
775
- if (member.role !== "teammate") {
776
- continue;
777
- }
778
- this.members.set(member.agentId, {
779
- agentId: member.agentId,
780
- role: "teammate",
781
- description: member.description,
782
- status: "stopped",
783
- agent: undefined,
784
- runningCount: 0,
785
- lastMissionStep: this.missionStepCounter,
786
- lastMissionAt: Date.now(),
787
- });
788
- }
789
-
790
- this.taskCounter = Math.max(
791
- this.taskCounter,
792
- maxCounter(
793
- state.tasks.map((task) => task.id),
794
- "task_",
795
- ),
796
- );
797
- this.messageCounter = Math.max(
798
- this.messageCounter,
799
- maxCounter(
800
- state.mailbox.map((message) => message.id),
801
- "msg_",
802
- ),
803
- );
804
- this.missionCounter = Math.max(
805
- this.missionCounter,
806
- maxCounter(
807
- state.missionLog.map((entry) => entry.id),
808
- "log_",
809
- ),
810
- );
811
- this.runCounter = Math.max(
812
- this.runCounter,
813
- maxCounter(
814
- (state.runs ?? []).map((run) => run.id),
815
- "run_",
816
- ),
817
- );
818
- this.outcomeCounter = Math.max(
819
- this.outcomeCounter,
820
- maxCounter(
821
- (state.outcomes ?? []).map((outcome) => outcome.id),
822
- "out_",
823
- ),
824
- );
825
- this.outcomeFragmentCounter = Math.max(
826
- this.outcomeFragmentCounter,
827
- maxCounter(
828
- (state.outcomeFragments ?? []).map((fragment) => fragment.id),
829
- "frag_",
830
- ),
831
- );
832
- }
833
-
834
- isTeammateActive(agentId: string): boolean {
835
- const member = this.members.get(agentId);
836
- return !!member && member.role === "teammate" && !!member.agent;
837
- }
838
-
839
- spawnTeammate({ agentId, config }: SpawnTeammateOptions): TeamMemberSnapshot {
840
- const existing = this.members.get(agentId);
841
- if (existing && existing.role !== "teammate") {
842
- throw new Error(
843
- `Team member "${agentId}" already exists and is not a teammate`,
844
- );
845
- }
846
- if (existing && existing.runningCount > 0) {
847
- throw new Error(
848
- `Teammate "${agentId}" is currently running and cannot be respawned`,
849
- );
850
- }
851
-
852
- const wrappedConfig: TeamMemberConfig = {
853
- ...config,
854
- apiTimeoutMs: TEAMMATE_API_TIMEOUT_MS,
855
- consumePendingUserMessage: () => {
856
- const member = this.members.get(agentId);
857
- if (!member || !member.pendingSteerMessage) {
858
- return undefined;
859
- }
860
- const message = member.pendingSteerMessage;
861
- member.pendingSteerMessage = undefined;
862
- return message;
863
- },
864
- onEvent: (event: AgentEvent) => {
865
- config.onEvent?.(event);
866
- this.emitEvent({ type: TeamMessageType.AgentEvent, agentId, event });
867
- this.trackMeaningfulEvent(agentId, event);
868
- },
869
- };
870
-
871
- const agent = new SessionRuntime(wrappedConfig);
872
- if (wrappedConfig.onEvent) {
873
- agent.subscribeEvents(wrappedConfig.onEvent);
874
- }
875
- const teammate: TeamMemberState = {
876
- agentId,
877
- role: "teammate",
878
- description: config.role,
879
- status: "idle",
880
- agent,
881
- runningCount: 0,
882
- lastMissionStep: 0,
883
- lastMissionAt: Date.now(),
884
- };
885
- this.members.set(agentId, teammate);
886
- this.emitEvent({
887
- type: TeamMessageType.TeammateSpawned,
888
- agentId,
889
- role: config.role,
890
- teammate: {
891
- rolePrompt: config.systemPrompt,
892
- modelId: config.modelId,
893
- maxIterations: config.maxIterations,
894
- runtimeAgentId: agent.getAgentId(),
895
- conversationId: agent.getConversationId(),
896
- parentAgentId: null,
897
- },
898
- });
899
- return {
900
- agentId: teammate.agentId,
901
- role: teammate.role,
902
- description: teammate.description,
903
- status: teammate.status,
904
- };
905
- }
906
-
907
- shutdownTeammate(agentId: string, reason?: string): void {
908
- const member = this.members.get(agentId);
909
- if (!member || member.role !== "teammate") {
910
- throw new Error(`Teammate "${agentId}" was not found`);
911
- }
912
- try {
913
- member.agent?.abort();
914
- } catch (error) {
915
- if (!isAbortLikeError(error)) {
916
- throw error;
917
- }
918
- }
919
- member.status = "stopped";
920
- this.emitEvent({ type: TeamMessageType.TeammateShutdown, agentId, reason });
921
- }
922
-
923
- updateTeammateConnections(
924
- overrides: Partial<Pick<AgentConfig, "apiKey" | "baseUrl" | "headers">>,
925
- ): void {
926
- for (const member of this.members.values()) {
927
- if (member.role !== "teammate" || !member.agent) {
928
- continue;
929
- }
930
- member.agent.updateConnection(overrides);
931
- }
932
- }
933
-
934
- createTask(input: CreateTeamTaskInput): TeamTask {
935
- const taskId = `task_${String(++this.taskCounter).padStart(4, "0")}`;
936
- const now = new Date();
937
- const task: TeamTask = {
938
- id: taskId,
939
- title: input.title,
940
- description: input.description,
941
- status: input.assignee ? "in_progress" : "pending",
942
- createdAt: now,
943
- updatedAt: now,
944
- createdBy: input.createdBy,
945
- assignee: input.assignee,
946
- dependsOn: input.dependsOn ?? [],
947
- };
948
- this.tasks.set(taskId, task);
949
- this.emitEvent({
950
- type: TeamMessageType.TeamTaskUpdated,
951
- task: { ...task },
952
- });
953
- return { ...task };
954
- }
955
-
956
- claimTask(taskId: string, agentId: string): TeamTask {
957
- const task = this.requireTask(taskId);
958
- this.assertDependenciesResolved(task);
959
- task.status = "in_progress";
960
- task.assignee = agentId;
961
- task.updatedAt = new Date();
962
- this.emitEvent({
963
- type: TeamMessageType.TeamTaskUpdated,
964
- task: { ...task },
965
- });
966
- this.appendMissionLog({
967
- agentId,
968
- taskId,
969
- kind: "progress",
970
- summary: `Claimed task "${task.title}"`,
971
- });
972
- return { ...task };
973
- }
974
-
975
- blockTask(taskId: string, agentId: string, reason: string): TeamTask {
976
- const task = this.requireTask(taskId);
977
- task.status = "blocked";
978
- task.updatedAt = new Date();
979
- task.summary = reason;
980
- this.emitEvent({
981
- type: TeamMessageType.TeamTaskUpdated,
982
- task: { ...task },
983
- });
984
- this.appendMissionLog({
985
- agentId,
986
- taskId,
987
- kind: "blocked",
988
- summary: reason,
989
- });
990
- return { ...task };
991
- }
992
-
993
- completeTask(taskId: string, agentId: string, summary: string): TeamTask {
994
- const task = this.requireTask(taskId);
995
- task.status = "completed";
996
- task.updatedAt = new Date();
997
- task.summary = summary;
998
- if (!task.assignee) {
999
- task.assignee = agentId;
1000
- }
1001
- this.emitEvent({
1002
- type: TeamMessageType.TeamTaskUpdated,
1003
- task: { ...task },
1004
- });
1005
- this.appendMissionLog({
1006
- agentId,
1007
- taskId,
1008
- kind: "done",
1009
- summary,
1010
- });
1011
- return { ...task };
1012
- }
1013
-
1014
- async routeToTeammate(
1015
- agentId: string,
1016
- message: string,
1017
- options?: RouteToTeammateOptions,
1018
- ): Promise<AgentResult> {
1019
- const member = this.members.get(agentId);
1020
- if (!member || member.role !== "teammate" || !member.agent) {
1021
- throw new Error(`Teammate "${agentId}" was not found`);
1022
- }
1023
- if (!member.agent.canStartRun()) {
1024
- throw new Error(
1025
- `Cannot start a new run while another run is already in progress`,
1026
- );
1027
- }
1028
-
1029
- member.runningCount++;
1030
- member.status = "running";
1031
- this.emitEvent({ type: TeamMessageType.TaskStart, agentId, message });
1032
-
1033
- try {
1034
- const unreadMail = this.listMailbox(agentId, {
1035
- unreadOnly: true,
1036
- markRead: true,
1037
- });
1038
- const enrichedMessage =
1039
- unreadMail.length > 0
1040
- ? `${this.buildMailboxNotification(unreadMail)}\n\n${message}`
1041
- : message;
1042
- const result = options?.continueConversation
1043
- ? await member.agent.continue(enrichedMessage)
1044
- : await member.agent.run(enrichedMessage);
1045
- this.emitEvent({ type: TeamMessageType.TaskEnd, agentId, result });
1046
- this.recordProgressStep(
1047
- agentId,
1048
- `Completed a delegated run (${result.iterations} iterations)`,
1049
- options?.taskId,
1050
- true,
1051
- );
1052
- return result;
1053
- } catch (error) {
1054
- const err = error instanceof Error ? error : new Error(String(error));
1055
- this.emitEvent({
1056
- type: TeamMessageType.TaskEnd,
1057
- agentId,
1058
- error: err,
1059
- messages: member.agent.getMessages(),
1060
- });
1061
- if (!isIntentionalShutdownAbort(member, err)) {
1062
- this.appendMissionLog({
1063
- agentId,
1064
- taskId: options?.taskId,
1065
- kind: "error",
1066
- summary: err.message,
1067
- });
1068
- }
1069
- throw err;
1070
- } finally {
1071
- member.runningCount--;
1072
- if (
1073
- member.runningCount <= 0 &&
1074
- this.members.get(agentId)?.status !== "stopped"
1075
- ) {
1076
- member.status = "idle";
1077
- }
1078
- }
1079
- }
1080
-
1081
- startTeammateRun(
1082
- agentId: string,
1083
- message: string,
1084
- options?: RouteToTeammateOptions & {
1085
- priority?: number;
1086
- maxRetries?: number;
1087
- leaseOwner?: string;
1088
- },
1089
- ): TeamRunRecord {
1090
- const runId = `run_${String(++this.runCounter).padStart(5, "0")}`;
1091
- const record: TeamRunRecord & { result?: AgentResult } = {
1092
- id: runId,
1093
- agentId,
1094
- taskId: options?.taskId,
1095
- status: "queued",
1096
- message,
1097
- priority: options?.priority ?? 0,
1098
- retryCount: 0,
1099
- maxRetries: Math.max(0, options?.maxRetries ?? 0),
1100
- continueConversation: options?.continueConversation,
1101
- startedAt: new Date(0),
1102
- leaseOwner: options?.leaseOwner,
1103
- heartbeatAt: undefined,
1104
- lastProgressAt: new Date(),
1105
- lastProgressMessage: "queued",
1106
- currentActivity: "queued",
1107
- };
1108
- this.runs.set(runId, record);
1109
- this.runQueue.push(runId);
1110
- this.emitEvent({ type: TeamMessageType.RunQueued, run: { ...record } });
1111
- this.dispatchQueuedRuns();
1112
- return { ...record };
1113
- }
1114
-
1115
- private dispatchQueuedRuns(): void {
1116
- this.clearQueuedRunDispatchTimer();
1117
- let nextDelayedAttemptAt: Date | undefined;
1118
- while (
1119
- this.countActiveRuns() < this.maxConcurrentRuns &&
1120
- this.runQueue.length > 0
1121
- ) {
1122
- const nextRun = this.selectNextDispatchableQueuedRun();
1123
- nextDelayedAttemptAt = nextRun.nextDelayedAttemptAt;
1124
- const nextRunIndex = nextRun.index;
1125
- if (nextRunIndex < 0) {
1126
- this.scheduleQueuedRunDispatch(nextDelayedAttemptAt);
1127
- return;
1128
- }
1129
- const [runId] = this.runQueue.splice(nextRunIndex, 1);
1130
- const run = runId ? this.runs.get(runId) : undefined;
1131
- if (!run || run.status !== "queued") {
1132
- continue;
1133
- }
1134
- void this.executeQueuedRun(run);
1135
- }
1136
- this.scheduleQueuedRunDispatch(nextDelayedAttemptAt);
1137
- }
1138
-
1139
- private selectNextDispatchableQueuedRun(): {
1140
- index: number;
1141
- nextDelayedAttemptAt?: Date;
1142
- } {
1143
- let selectedIndex = -1;
1144
- let bestPriority = Number.NEGATIVE_INFINITY;
1145
- let nextDelayedAttemptAt: Date | undefined;
1146
- const now = Date.now();
1147
- for (let index = 0; index < this.runQueue.length; index++) {
1148
- const run = this.runs.get(this.runQueue[index]);
1149
- if (!run || run.status !== "queued") {
1150
- continue;
1151
- }
1152
- if (run.nextAttemptAt && run.nextAttemptAt.getTime() > now) {
1153
- if (!nextDelayedAttemptAt || run.nextAttemptAt < nextDelayedAttemptAt) {
1154
- nextDelayedAttemptAt = run.nextAttemptAt;
1155
- }
1156
- continue;
1157
- }
1158
- if (run.priority > bestPriority) {
1159
- bestPriority = run.priority;
1160
- selectedIndex = index;
1161
- }
1162
- }
1163
- return { index: selectedIndex, nextDelayedAttemptAt };
1164
- }
1165
-
1166
- private scheduleQueuedRunDispatch(nextAttemptAt: Date | undefined): void {
1167
- if (!nextAttemptAt) {
1168
- return;
1169
- }
1170
- const delayMs = Math.max(0, nextAttemptAt.getTime() - Date.now());
1171
- this.queuedRunDispatchTimer = setTimeout(() => {
1172
- this.queuedRunDispatchTimer = undefined;
1173
- this.dispatchQueuedRuns();
1174
- }, delayMs);
1175
- }
1176
-
1177
- private clearQueuedRunDispatchTimer(): void {
1178
- if (!this.queuedRunDispatchTimer) {
1179
- return;
1180
- }
1181
- clearTimeout(this.queuedRunDispatchTimer);
1182
- this.queuedRunDispatchTimer = undefined;
1183
- }
1184
-
1185
- private countActiveRuns(): number {
1186
- let count = 0;
1187
- for (const run of this.runs.values()) {
1188
- if (run.status === "running") {
1189
- count++;
1190
- }
1191
- }
1192
- return count;
1193
- }
1194
-
1195
- private async executeQueuedRun(
1196
- run: TeamRunRecord & { result?: AgentResult },
1197
- ): Promise<void> {
1198
- const recoveredRun = run.currentActivity === RECOVERED_QUEUED_ACTIVITY;
1199
- run.nextAttemptAt = undefined;
1200
- run.status = "running";
1201
- run.startedAt = new Date();
1202
- run.heartbeatAt = new Date();
1203
- run.currentActivity = "run_started";
1204
- this.emitEvent({ type: TeamMessageType.RunStarted, run: { ...run } });
1205
-
1206
- const heartbeatTimer = setInterval(() => {
1207
- if (run.status !== "running") {
1208
- return;
1209
- }
1210
- this.recordRunProgress(run, "heartbeat");
1211
- }, 2000);
1212
-
1213
- try {
1214
- const runMessage = recoveredRun
1215
- ? buildRecoveredRunMessage(run)
1216
- : run.message;
1217
- const result = await this.routeToTeammate(run.agentId, runMessage, {
1218
- taskId: run.taskId,
1219
- continueConversation: run.continueConversation,
1220
- });
1221
- run.status = "completed";
1222
- run.result = result;
1223
- run.endedAt = new Date();
1224
- run.currentActivity = "completed";
1225
- this.emitEvent({ type: TeamMessageType.RunCompleted, run: { ...run } });
1226
- } catch (error) {
1227
- const message =
1228
- error instanceof Error
1229
- ? error.message
1230
- : String(error ?? "Unknown error");
1231
- run.error = message;
1232
- run.endedAt = new Date();
1233
- const member = this.members.get(run.agentId);
1234
- if (isIntentionalShutdownAbort(member, error)) {
1235
- run.status = "cancelled";
1236
- run.currentActivity = "cancelled";
1237
- this.emitEvent({
1238
- type: TeamMessageType.RunCancelled,
1239
- run: { ...run },
1240
- reason: message,
1241
- });
1242
- } else if (run.retryCount < run.maxRetries) {
1243
- run.retryCount++;
1244
- run.status = "queued";
1245
- run.nextAttemptAt = new Date(
1246
- Date.now() + Math.min(30000, 1000 * 2 ** run.retryCount),
1247
- );
1248
- this.runQueue.push(run.id);
1249
- this.recordRunProgress(run, `retry_scheduled_${run.retryCount}`);
1250
- } else {
1251
- run.status = "failed";
1252
- run.currentActivity = "failed";
1253
- this.emitEvent({ type: TeamMessageType.RunFailed, run: { ...run } });
1254
- }
1255
- } finally {
1256
- clearInterval(heartbeatTimer);
1257
- this.dispatchQueuedRuns();
1258
- }
1259
- }
1260
-
1261
- listRuns(options?: {
1262
- status?: TeamRunStatus | null;
1263
- agentId?: string | null;
1264
- includeCompleted?: boolean | null;
1265
- }): TeamRunRecord[] {
1266
- const includeCompleted = options?.includeCompleted ?? true;
1267
- return Array.from(this.runs.values())
1268
- .filter((run) => {
1269
- if (!includeCompleted && !["running", "queued"].includes(run.status)) {
1270
- return false;
1271
- }
1272
- if (options?.status && run.status !== options.status) {
1273
- return false;
1274
- }
1275
- if (options?.agentId && run.agentId !== options.agentId) {
1276
- return false;
1277
- }
1278
- return true;
1279
- })
1280
- .map((run) => ({ ...run }));
1281
- }
1282
-
1283
- getRun(runId: string): TeamRunRecord | undefined {
1284
- const run = this.runs.get(runId);
1285
- return run ? { ...run } : undefined;
1286
- }
1287
-
1288
- async awaitRun(runId: string, pollIntervalMs = 250): Promise<TeamRunRecord> {
1289
- const run = this.runs.get(runId);
1290
- if (!run) {
1291
- throw new Error(`Run "${runId}" was not found`);
1292
- }
1293
- while (run.status === "queued" || run.status === "running") {
1294
- await sleep(pollIntervalMs);
1295
- }
1296
- return { ...run };
1297
- }
1298
-
1299
- async awaitAllRuns(pollIntervalMs = 250): Promise<TeamRunRecord[]> {
1300
- while (
1301
- Array.from(this.runs.values()).some((run) =>
1302
- ["queued", "running"].includes(run.status),
1303
- )
1304
- ) {
1305
- await sleep(pollIntervalMs);
1306
- }
1307
- return this.listRuns();
1308
- }
1309
-
1310
- cancelRun(runId: string, reason?: string): TeamRunRecord {
1311
- const run = this.runs.get(runId);
1312
- if (!run) {
1313
- throw new Error(`Run "${runId}" was not found`);
1314
- }
1315
- if (run.status === "completed" || run.status === "failed") {
1316
- return { ...run };
1317
- }
1318
- run.status = "cancelled";
1319
- run.error = reason;
1320
- run.endedAt = new Date();
1321
- run.currentActivity = "cancelled";
1322
- const queueIndex = this.runQueue.indexOf(runId);
1323
- if (queueIndex >= 0) {
1324
- this.runQueue.splice(queueIndex, 1);
1325
- }
1326
- this.emitEvent({
1327
- type: TeamMessageType.RunCancelled,
1328
- run: { ...run },
1329
- reason,
1330
- });
1331
- return { ...run };
1332
- }
1333
-
1334
- recoverActiveRuns(reason = "runtime_recovered"): TeamRunRecord[] {
1335
- const recovered: TeamRunRecord[] = [];
1336
- for (const run of this.runs.values()) {
1337
- if (!["queued", "running"].includes(run.status)) {
1338
- continue;
1339
- }
1340
-
1341
- const member = this.members.get(run.agentId);
1342
- if (!member || member.role !== "teammate" || !member.agent) {
1343
- run.status = "interrupted";
1344
- run.error = "teammate_unavailable_after_recovery";
1345
- run.endedAt = new Date();
1346
- run.currentActivity = "interrupted";
1347
- this.emitEvent({
1348
- type: TeamMessageType.RunInterrupted,
1349
- run: { ...run },
1350
- reason: run.error,
1351
- });
1352
- continue;
1353
- }
1354
-
1355
- const now = new Date();
1356
- run.status = "queued";
1357
- run.error = undefined;
1358
- run.endedAt = undefined;
1359
- run.heartbeatAt = now;
1360
- run.lastProgressAt = now;
1361
- run.lastProgressMessage = reason;
1362
- run.currentActivity = RECOVERED_QUEUED_ACTIVITY;
1363
- if (!this.runQueue.includes(run.id)) {
1364
- this.runQueue.push(run.id);
1365
- }
1366
- recovered.push({ ...run });
1367
- this.emitEvent({ type: TeamMessageType.RunQueued, run: { ...run } });
1368
- }
1369
- this.dispatchQueuedRuns();
1370
- return recovered;
1371
- }
1372
-
1373
- markStaleRunsInterrupted(reason = "runtime_recovered"): TeamRunRecord[] {
1374
- const interrupted: TeamRunRecord[] = [];
1375
- for (const run of this.runs.values()) {
1376
- if (!["queued", "running"].includes(run.status)) {
1377
- continue;
1378
- }
1379
- run.status = "interrupted";
1380
- run.error = reason;
1381
- run.endedAt = new Date();
1382
- run.currentActivity = "interrupted";
1383
- interrupted.push({ ...run });
1384
- this.emitEvent({
1385
- type: TeamMessageType.RunInterrupted,
1386
- run: { ...run },
1387
- reason,
1388
- });
1389
- }
1390
- this.runQueue.length = 0;
1391
- this.clearQueuedRunDispatchTimer();
1392
- return interrupted;
1393
- }
1394
-
1395
- sendMessage(
1396
- fromAgentId: string,
1397
- toAgentId: string,
1398
- subject: string,
1399
- body: string,
1400
- taskId?: string,
1401
- ): TeamMailboxMessage {
1402
- if (!this.members.has(fromAgentId)) {
1403
- throw new Error(`Unknown sender "${fromAgentId}"`);
1404
- }
1405
- const recipient = this.members.get(toAgentId);
1406
- if (!recipient) {
1407
- throw new Error(`Unknown recipient "${toAgentId}"`);
1408
- }
1409
- const message: TeamMailboxMessage = {
1410
- id: `msg_${String(++this.messageCounter).padStart(5, "0")}`,
1411
- teamId: this.teamId,
1412
- fromAgentId,
1413
- toAgentId,
1414
- subject,
1415
- body,
1416
- taskId,
1417
- sentAt: new Date(),
1418
- };
1419
- this.mailbox.push(message);
1420
- this.emitEvent({
1421
- type: TeamMessageType.TeamMessage,
1422
- message: { ...message },
1423
- });
1424
- if (
1425
- recipient.role === "teammate" &&
1426
- recipient.runningCount > 0 &&
1427
- recipient.agent
1428
- ) {
1429
- recipient.pendingSteerMessage = `[MAILBOX] You got a message from ${fromAgentId}. Subject: "${subject}". Use the team_read_mailbox tool to read it at your convenience.`;
1430
- }
1431
- return { ...message };
1432
- }
1433
-
1434
- broadcast(
1435
- fromAgentId: string,
1436
- subject: string,
1437
- body: string,
1438
- options?: { taskId?: string },
1439
- ): TeamMailboxMessage[] {
1440
- const messages: TeamMailboxMessage[] = [];
1441
- for (const member of this.members.values()) {
1442
- if (member.agentId === fromAgentId) {
1443
- continue;
1444
- }
1445
- if (member.role === "lead") {
1446
- continue;
1447
- }
1448
- messages.push(
1449
- this.sendMessage(
1450
- fromAgentId,
1451
- member.agentId,
1452
- subject,
1453
- body,
1454
- options?.taskId,
1455
- ),
1456
- );
1457
- }
1458
- return messages;
1459
- }
1460
-
1461
- appendMissionLog(input: AppendMissionLogInput): MissionLogEntry {
1462
- if (!this.members.has(input.agentId)) {
1463
- throw new Error(`Unknown team member "${input.agentId}"`);
1464
- }
1465
- const entry: MissionLogEntry = {
1466
- id: `log_${String(++this.missionCounter).padStart(6, "0")}`,
1467
- ts: new Date(),
1468
- teamId: this.teamId,
1469
- agentId: input.agentId,
1470
- taskId: input.taskId,
1471
- kind: input.kind,
1472
- summary: input.summary,
1473
- evidence: input.evidence,
1474
- nextAction: input.nextAction,
1475
- };
1476
- this.missionLog.push(entry);
1477
- const member = this.members.get(input.agentId);
1478
- if (member) {
1479
- member.lastMissionAt = Date.now();
1480
- member.lastMissionStep = this.missionStepCounter;
1481
- }
1482
- this.emitEvent({
1483
- type: TeamMessageType.TeamMissionLog,
1484
- entry: { ...entry },
1485
- });
1486
- return { ...entry };
1487
- }
1488
-
1489
- createOutcome(input: CreateTeamOutcomeInput): TeamOutcome {
1490
- const outcome: TeamOutcome = {
1491
- id: `out_${String(++this.outcomeCounter).padStart(4, "0")}`,
1492
- teamId: this.teamId,
1493
- title: input.title,
1494
- status: "draft",
1495
- requiredSections: [...new Set(input.requiredSections)],
1496
- createdBy: input.createdBy,
1497
- createdAt: new Date(),
1498
- };
1499
- this.outcomes.set(outcome.id, outcome);
1500
- this.emitEvent({
1501
- type: TeamMessageType.OutcomeCreated,
1502
- outcome: { ...outcome },
1503
- });
1504
- return { ...outcome };
1505
- }
1506
-
1507
- listOutcomes(): TeamOutcome[] {
1508
- return Array.from(this.outcomes.values()).map((outcome) => ({
1509
- ...outcome,
1510
- }));
1511
- }
1512
-
1513
- attachOutcomeFragment(
1514
- input: AttachTeamOutcomeFragmentInput,
1515
- ): TeamOutcomeFragment {
1516
- const outcome = this.outcomes.get(input.outcomeId);
1517
- if (!outcome) {
1518
- throw new Error(`Outcome "${input.outcomeId}" was not found`);
1519
- }
1520
- if (!outcome.requiredSections.includes(input.section)) {
1521
- throw new Error(
1522
- `Section "${input.section}" is not part of outcome "${input.outcomeId}"`,
1523
- );
1524
- }
1525
- const fragment: TeamOutcomeFragment = {
1526
- id: `frag_${String(++this.outcomeFragmentCounter).padStart(5, "0")}`,
1527
- teamId: this.teamId,
1528
- outcomeId: input.outcomeId,
1529
- section: input.section,
1530
- sourceAgentId: input.sourceAgentId,
1531
- sourceRunId: input.sourceRunId,
1532
- content: input.content,
1533
- status: "draft",
1534
- createdAt: new Date(),
1535
- };
1536
- this.outcomeFragments.set(fragment.id, fragment);
1537
- if (outcome.status === "draft") {
1538
- outcome.status = "in_review";
1539
- }
1540
- this.emitEvent({
1541
- type: TeamMessageType.OutcomeFragmentAttached,
1542
- fragment: { ...fragment },
1543
- });
1544
- return { ...fragment };
1545
- }
1546
-
1547
- reviewOutcomeFragment(
1548
- input: ReviewTeamOutcomeFragmentInput,
1549
- ): TeamOutcomeFragment {
1550
- const fragment = this.outcomeFragments.get(input.fragmentId);
1551
- if (!fragment) {
1552
- throw new Error(`Fragment "${input.fragmentId}" was not found`);
1553
- }
1554
- fragment.status = input.approved ? "reviewed" : "rejected";
1555
- fragment.reviewedBy = input.reviewedBy;
1556
- fragment.reviewedAt = new Date();
1557
- this.emitEvent({
1558
- type: TeamMessageType.OutcomeFragmentReviewed,
1559
- fragment: { ...fragment },
1560
- });
1561
- return { ...fragment };
1562
- }
1563
-
1564
- listOutcomeFragments(outcomeId: string): TeamOutcomeFragment[] {
1565
- return Array.from(this.outcomeFragments.values())
1566
- .filter((fragment) => fragment.outcomeId === outcomeId)
1567
- .map((fragment) => ({ ...fragment }));
1568
- }
1569
-
1570
- finalizeOutcome(outcomeId: string): TeamOutcome {
1571
- const outcome = this.outcomes.get(outcomeId);
1572
- if (!outcome) {
1573
- throw new Error(`Outcome "${outcomeId}" was not found`);
1574
- }
1575
- const fragments = this.listOutcomeFragments(outcomeId);
1576
- for (const section of outcome.requiredSections) {
1577
- const approvedForSection = fragments.some(
1578
- (fragment) =>
1579
- fragment.section === section && fragment.status === "reviewed",
1580
- );
1581
- if (!approvedForSection) {
1582
- throw new Error(
1583
- `Outcome "${outcomeId}" cannot be finalized. Section "${section}" is missing a reviewed fragment.`,
1584
- );
1585
- }
1586
- }
1587
- outcome.status = "finalized";
1588
- outcome.finalizedAt = new Date();
1589
- this.emitEvent({
1590
- type: TeamMessageType.OutcomeFinalized,
1591
- outcome: { ...outcome },
1592
- });
1593
- return { ...outcome };
1594
- }
1595
-
1596
- cleanup(): void {
1597
- for (const member of this.members.values()) {
1598
- if (member.role === "teammate" && member.runningCount > 0) {
1599
- throw new Error(
1600
- `Cannot cleanup team while teammate "${member.agentId}" is still running`,
1601
- );
1602
- }
1603
- }
1604
- if (
1605
- Array.from(this.runs.values()).some((run) =>
1606
- ["queued", "running"].includes(run.status),
1607
- )
1608
- ) {
1609
- throw new Error(
1610
- "Cannot cleanup team while async teammate runs are still active",
1611
- );
1612
- }
1613
-
1614
- for (const member of this.members.values()) {
1615
- if (member.role === "teammate") {
1616
- try {
1617
- member.agent?.abort();
1618
- } catch (error) {
1619
- if (!isAbortLikeError(error)) {
1620
- throw error;
1621
- }
1622
- }
1623
- }
1624
- }
1625
-
1626
- this.tasks.clear();
1627
- this.mailbox.length = 0;
1628
- this.missionLog.length = 0;
1629
- this.runs.clear();
1630
- this.runQueue.length = 0;
1631
- this.clearQueuedRunDispatchTimer();
1632
- this.outcomes.clear();
1633
- this.outcomeFragments.clear();
1634
-
1635
- for (const [memberId, member] of this.members.entries()) {
1636
- if (member.role === "teammate") {
1637
- this.members.delete(memberId);
1638
- }
1639
- }
1640
- }
1641
-
1642
- private requireTask(taskId: string): TeamTask {
1643
- const task = this.tasks.get(taskId);
1644
- if (!task) {
1645
- throw new Error(`Task "${taskId}" was not found`);
1646
- }
1647
- return task;
1648
- }
1649
-
1650
- private assertDependenciesResolved(task: TeamTask): void {
1651
- const blockedBy = this.getUnresolvedDependencies(task);
1652
- if (blockedBy.length > 0) {
1653
- throw new Error(`Task "${task.id}" is blocked by "${blockedBy[0]}"`);
1654
- }
1655
- }
1656
-
1657
- private getUnresolvedDependencies(task: TeamTask): string[] {
1658
- return task.dependsOn.filter((dependencyId) => {
1659
- const dependency = this.tasks.get(dependencyId);
1660
- return !dependency || dependency.status !== "completed";
1661
- });
1662
- }
1663
-
1664
- private trackMeaningfulEvent(agentId: string, event: AgentEvent): void {
1665
- this.recordRunActivityFromAgentEvent(agentId, event);
1666
-
1667
- if (event.type === "iteration_end" && event.hadToolCalls) {
1668
- this.recordProgressStep(
1669
- agentId,
1670
- `Completed iteration ${event.iteration} with ${event.toolCallCount} tool call(s)`,
1671
- );
1672
- return;
1673
- }
1674
-
1675
- if (
1676
- event.type === "content_end" &&
1677
- event.contentType === "tool" &&
1678
- !event.error
1679
- ) {
1680
- this.recordProgressStep(
1681
- agentId,
1682
- `Finished tool "${event.toolName ?? "unknown"}"`,
1683
- );
1684
- return;
1685
- }
1686
-
1687
- if (event.type === "done") {
1688
- this.appendMissionLog({
1689
- agentId,
1690
- kind: "done",
1691
- summary: `Completed a delegated run (${event.iterations} iterations)`,
1692
- });
1693
- return;
1694
- }
1695
-
1696
- if (event.type === "error") {
1697
- this.appendMissionLog({
1698
- agentId,
1699
- kind: "error",
1700
- summary: event.error.message,
1701
- });
1702
- }
1703
- }
1704
-
1705
- private recordRunActivityFromAgentEvent(
1706
- agentId: string,
1707
- event: AgentEvent,
1708
- ): void {
1709
- let activity: string | undefined;
1710
- switch (event.type) {
1711
- case "iteration_start":
1712
- activity = `iteration_${event.iteration}_started`;
1713
- break;
1714
- case "content_start":
1715
- if (event.contentType === "tool") {
1716
- activity = `running_tool_${event.toolName ?? "unknown"}`;
1717
- }
1718
- break;
1719
- case "content_end":
1720
- if (event.contentType === "tool") {
1721
- activity = event.error
1722
- ? this.formatProgressErrorActivity(
1723
- `tool_${event.toolName ?? "unknown"}_error`,
1724
- event.error,
1725
- )
1726
- : `finished_tool_${event.toolName ?? "unknown"}`;
1727
- }
1728
- break;
1729
- case "done":
1730
- activity = "finalizing_response";
1731
- break;
1732
- case "error":
1733
- activity = this.formatProgressErrorActivity(
1734
- "run_error",
1735
- event.error.message,
1736
- );
1737
- break;
1738
- default:
1739
- break;
1740
- }
1741
- if (!activity) {
1742
- return;
1743
- }
1744
- for (const run of this.runs.values()) {
1745
- if (run.agentId !== agentId || run.status !== "running") {
1746
- continue;
1747
- }
1748
- this.recordRunProgress(run, activity);
1749
- }
1750
- }
1751
-
1752
- private recordRunProgress(run: TeamRunRecord, message: string): void {
1753
- const now = new Date();
1754
- run.heartbeatAt = now;
1755
- run.lastProgressAt = now;
1756
- run.lastProgressMessage = message;
1757
- run.currentActivity = message;
1758
- this.emitEvent({
1759
- type: TeamMessageType.RunProgress,
1760
- run: { ...run },
1761
- message,
1762
- });
1763
- }
1764
-
1765
- private formatProgressErrorActivity(prefix: string, detail: string): string {
1766
- const summary = detail.replace(/\s+/g, " ").trim();
1767
- if (summary.length === 0) {
1768
- return prefix;
1769
- }
1770
- const suffix =
1771
- summary.length > 240 ? `${summary.slice(0, 237).trimEnd()}...` : summary;
1772
- return `${prefix}: ${suffix}`;
1773
- }
1774
-
1775
- private recordProgressStep(
1776
- agentId: string,
1777
- summary: string,
1778
- taskId?: string,
1779
- force = false,
1780
- ): void {
1781
- this.missionStepCounter++;
1782
- const member = this.members.get(agentId);
1783
- if (!member) {
1784
- return;
1785
- }
1786
- const stepsSinceLast = this.missionStepCounter - member.lastMissionStep;
1787
- const elapsedMs = Date.now() - member.lastMissionAt;
1788
- if (
1789
- !force &&
1790
- stepsSinceLast < this.missionLogIntervalSteps &&
1791
- elapsedMs < this.missionLogIntervalMs
1792
- ) {
1793
- return;
1794
- }
1795
- this.appendMissionLog({
1796
- agentId,
1797
- taskId,
1798
- kind: "progress",
1799
- summary,
1800
- });
1801
- }
1802
-
1803
- private buildMailboxNotification(messages: TeamMailboxMessage[]): string {
1804
- if (messages.length === 0) {
1805
- return "";
1806
- }
1807
- const lines: string[] = [
1808
- `[MAILBOX] You have ${messages.length} unread message(s):`,
1809
- ];
1810
- for (const msg of messages) {
1811
- lines.push(
1812
- `--- Message from ${msg.fromAgentId} | subject: ${msg.subject} ---`,
1813
- );
1814
- lines.push(msg.body);
1815
- }
1816
- lines.push("---");
1817
- return lines.join("\n");
1818
- }
1819
-
1820
- private emitEvent(event: TeamEvent): void {
1821
- try {
1822
- this.onTeamEvent?.(event);
1823
- } catch {
1824
- // Ignore callback errors to avoid disrupting execution.
1825
- }
1826
- }
1827
- }
1828
-
1829
- function sleep(ms: number): Promise<void> {
1830
- return new Promise((resolve) => setTimeout(resolve, ms));
1831
- }
1832
-
1833
- function maxCounter(ids: string[], prefix: string): number {
1834
- let max = 0;
1835
- for (const id of ids) {
1836
- if (!id.startsWith(prefix)) {
1837
- continue;
1838
- }
1839
- const value = Number.parseInt(id.slice(prefix.length), 10);
1840
- if (Number.isFinite(value)) {
1841
- max = Math.max(max, value);
1842
- }
1843
- }
1844
- return max;
1845
- }