@clinebot/core 0.0.28 → 0.0.29

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 (339) hide show
  1. package/README.md +7 -0
  2. package/dist/ClineCore.d.ts +28 -2
  3. package/dist/ClineCore.d.ts.map +1 -1
  4. package/dist/account/cline-account-service.d.ts +1 -1
  5. package/dist/account/cline-account-service.d.ts.map +1 -1
  6. package/dist/account/index.d.ts +1 -1
  7. package/dist/account/index.d.ts.map +1 -1
  8. package/dist/account/types.d.ts +5 -0
  9. package/dist/account/types.d.ts.map +1 -1
  10. package/dist/auth/bounded-ttl-cache.d.ts +14 -0
  11. package/dist/auth/bounded-ttl-cache.d.ts.map +1 -0
  12. package/dist/auth/cline.d.ts +27 -2
  13. package/dist/auth/cline.d.ts.map +1 -1
  14. package/dist/auth/oca.d.ts.map +1 -1
  15. package/dist/chat/chat-schema.d.ts +11 -11
  16. package/dist/extensions/config/agent-config-loader.d.ts.map +1 -0
  17. package/dist/{agents → extensions/config}/agent-config-parser.d.ts +2 -2
  18. package/dist/extensions/config/agent-config-parser.d.ts.map +1 -0
  19. package/dist/{agents → extensions/config}/hooks-config-loader.d.ts +1 -1
  20. package/dist/extensions/config/hooks-config-loader.d.ts.map +1 -0
  21. package/dist/{agents → extensions/config}/index.d.ts +2 -4
  22. package/dist/extensions/config/index.d.ts.map +1 -0
  23. package/dist/{runtime/commands.d.ts → extensions/config/runtime-commands.d.ts} +2 -3
  24. package/dist/extensions/config/runtime-commands.d.ts.map +1 -0
  25. package/dist/extensions/config/unified-config-file-watcher.d.ts.map +1 -0
  26. package/dist/extensions/config/user-instruction-config-loader.d.ts.map +1 -0
  27. package/dist/extensions/context/agentic-compaction.d.ts +13 -0
  28. package/dist/extensions/context/agentic-compaction.d.ts.map +1 -0
  29. package/dist/extensions/context/basic-compaction.d.ts +9 -0
  30. package/dist/extensions/context/basic-compaction.d.ts.map +1 -0
  31. package/dist/extensions/context/compaction-shared.d.ts +60 -0
  32. package/dist/extensions/context/compaction-shared.d.ts.map +1 -0
  33. package/dist/extensions/context/compaction.d.ts +20 -0
  34. package/dist/extensions/context/compaction.d.ts.map +1 -0
  35. package/dist/extensions/index.d.ts +5 -0
  36. package/dist/extensions/index.d.ts.map +1 -0
  37. package/dist/extensions/mcp/client.d.ts +3 -0
  38. package/dist/extensions/mcp/client.d.ts.map +1 -0
  39. package/dist/extensions/mcp/config-loader.d.ts.map +1 -0
  40. package/dist/extensions/mcp/index.d.ts +9 -0
  41. package/dist/extensions/mcp/index.d.ts.map +1 -0
  42. package/dist/{mcp → extensions/mcp}/manager.d.ts +1 -2
  43. package/dist/extensions/mcp/manager.d.ts.map +1 -0
  44. package/dist/extensions/mcp/name-transform.d.ts +3 -0
  45. package/dist/extensions/mcp/name-transform.d.ts.map +1 -0
  46. package/dist/extensions/mcp/policies.d.ts +15 -0
  47. package/dist/extensions/mcp/policies.d.ts.map +1 -0
  48. package/dist/extensions/mcp/tools.d.ts +4 -0
  49. package/dist/extensions/mcp/tools.d.ts.map +1 -0
  50. package/dist/{mcp → extensions/mcp}/types.d.ts +29 -1
  51. package/dist/extensions/mcp/types.d.ts.map +1 -0
  52. package/dist/{agents → extensions/plugin}/plugin-config-loader.d.ts +1 -1
  53. package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -0
  54. package/dist/{agents → extensions/plugin}/plugin-loader.d.ts +1 -1
  55. package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -0
  56. package/dist/extensions/plugin/plugin-module-import.d.ts +5 -0
  57. package/dist/extensions/plugin/plugin-module-import.d.ts.map +1 -0
  58. package/dist/{agents → extensions/plugin}/plugin-sandbox.d.ts +1 -1
  59. package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -0
  60. package/dist/extensions/plugin-sandbox-bootstrap.js +485 -0
  61. package/dist/hooks/index.d.ts +4 -0
  62. package/dist/hooks/index.d.ts.map +1 -0
  63. package/dist/hooks/persistent.d.ts +64 -0
  64. package/dist/hooks/persistent.d.ts.map +1 -0
  65. package/dist/hooks/subprocess-runner.d.ts +22 -0
  66. package/dist/hooks/subprocess-runner.d.ts.map +1 -0
  67. package/dist/hooks/subprocess.d.ts +189 -0
  68. package/dist/hooks/subprocess.d.ts.map +1 -0
  69. package/dist/index.d.ts +22 -25
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +560 -447
  72. package/dist/prompt/default-system.d.ts +2 -0
  73. package/dist/prompt/default-system.d.ts.map +1 -0
  74. package/dist/providers/local-provider-service.d.ts +1 -1
  75. package/dist/providers/local-provider-service.d.ts.map +1 -1
  76. package/dist/runtime/checkpoint-hooks.d.ts +21 -0
  77. package/dist/runtime/checkpoint-hooks.d.ts.map +1 -0
  78. package/dist/runtime/hook-file-hooks.d.ts +1 -1
  79. package/dist/runtime/hook-file-hooks.d.ts.map +1 -1
  80. package/dist/runtime/rules.d.ts +1 -1
  81. package/dist/runtime/rules.d.ts.map +1 -1
  82. package/dist/runtime/runtime-builder.d.ts +1 -1
  83. package/dist/runtime/runtime-builder.d.ts.map +1 -1
  84. package/dist/runtime/session-runtime.d.ts +25 -5
  85. package/dist/runtime/session-runtime.d.ts.map +1 -1
  86. package/dist/runtime/subprocess-sandbox.d.ts.map +1 -0
  87. package/dist/runtime/team-runtime-registry.d.ts +1 -1
  88. package/dist/runtime/team-runtime-registry.d.ts.map +1 -1
  89. package/dist/runtime/tool-approval.d.ts +1 -1
  90. package/dist/session/default-session-manager.d.ts +4 -3
  91. package/dist/session/default-session-manager.d.ts.map +1 -1
  92. package/dist/session/file-session-service.d.ts +1 -1
  93. package/dist/session/file-session-service.d.ts.map +1 -1
  94. package/dist/session/{unified-session-persistence-service.d.ts → persistence-service.d.ts} +11 -42
  95. package/dist/session/persistence-service.d.ts.map +1 -0
  96. package/dist/session/rpc-session-service.d.ts +1 -1
  97. package/dist/session/rpc-session-service.d.ts.map +1 -1
  98. package/dist/session/session-agent-events.d.ts +1 -1
  99. package/dist/session/session-artifacts.d.ts.map +1 -1
  100. package/dist/session/session-config-builder.d.ts.map +1 -1
  101. package/dist/session/session-graph.d.ts +1 -1
  102. package/dist/session/session-graph.d.ts.map +1 -1
  103. package/dist/session/session-host.d.ts.map +1 -1
  104. package/dist/session/session-manager.d.ts +6 -5
  105. package/dist/session/session-manager.d.ts.map +1 -1
  106. package/dist/session/session-manifest.d.ts +1 -1
  107. package/dist/session/session-service.d.ts +3 -2
  108. package/dist/session/session-service.d.ts.map +1 -1
  109. package/dist/session/session-team-coordination.d.ts +2 -1
  110. package/dist/session/session-team-coordination.d.ts.map +1 -1
  111. package/dist/session/utils/helpers.d.ts +51 -3
  112. package/dist/session/utils/helpers.d.ts.map +1 -1
  113. package/dist/session/utils/types.d.ts +41 -7
  114. package/dist/session/utils/types.d.ts.map +1 -1
  115. package/dist/session/workspace-manager.d.ts +1 -2
  116. package/dist/session/workspace-manager.d.ts.map +1 -1
  117. package/dist/session/workspace-manifest.d.ts +1 -22
  118. package/dist/session/workspace-manifest.d.ts.map +1 -1
  119. package/dist/storage/file-team-store.d.ts +2 -1
  120. package/dist/storage/file-team-store.d.ts.map +1 -1
  121. package/dist/storage/sqlite-team-store.d.ts +4 -1
  122. package/dist/storage/sqlite-team-store.d.ts.map +1 -1
  123. package/dist/storage/team-store.d.ts.map +1 -1
  124. package/dist/team/delegated-agent.d.ts +44 -0
  125. package/dist/team/delegated-agent.d.ts.map +1 -0
  126. package/dist/team/index.d.ts +1 -0
  127. package/dist/team/index.d.ts.map +1 -1
  128. package/dist/team/multi-agent.d.ts +229 -0
  129. package/dist/team/multi-agent.d.ts.map +1 -0
  130. package/dist/team/projections.d.ts +2 -2
  131. package/dist/team/projections.d.ts.map +1 -1
  132. package/dist/team/runtime.d.ts +5 -0
  133. package/dist/team/runtime.d.ts.map +1 -0
  134. package/dist/team/spawn-agent-tool.d.ts +85 -0
  135. package/dist/team/spawn-agent-tool.d.ts.map +1 -0
  136. package/dist/team/subagent-prompts.d.ts +4 -0
  137. package/dist/team/subagent-prompts.d.ts.map +1 -0
  138. package/dist/team/team-tools.d.ts +35 -0
  139. package/dist/team/team-tools.d.ts.map +1 -0
  140. package/dist/telemetry/OpenTelemetryProvider.d.ts +11 -1
  141. package/dist/telemetry/OpenTelemetryProvider.d.ts.map +1 -1
  142. package/dist/telemetry/{LoggerTelemetryAdapter.d.ts → TelemetryLoggerSink.d.ts} +10 -4
  143. package/dist/telemetry/TelemetryLoggerSink.d.ts.map +1 -0
  144. package/dist/telemetry/TelemetryService.d.ts.map +1 -1
  145. package/dist/telemetry/index.js +15 -28
  146. package/dist/tools/definitions.d.ts +4 -3
  147. package/dist/tools/definitions.d.ts.map +1 -1
  148. package/dist/tools/index.d.ts +5 -5
  149. package/dist/tools/index.d.ts.map +1 -1
  150. package/dist/tools/model-tool-routing.d.ts.map +1 -1
  151. package/dist/tools/presets.d.ts +26 -0
  152. package/dist/tools/presets.d.ts.map +1 -1
  153. package/dist/tools/schemas.d.ts +8 -0
  154. package/dist/tools/schemas.d.ts.map +1 -1
  155. package/dist/tools/types.d.ts +23 -2
  156. package/dist/tools/types.d.ts.map +1 -1
  157. package/dist/types/config.d.ts +47 -3
  158. package/dist/types/config.d.ts.map +1 -1
  159. package/dist/types/events.d.ts +1 -1
  160. package/dist/types/provider-settings.d.ts +1 -1
  161. package/dist/types/provider-settings.d.ts.map +1 -1
  162. package/dist/types/storage.d.ts +2 -1
  163. package/dist/types/storage.d.ts.map +1 -1
  164. package/dist/types.d.ts +7 -16
  165. package/dist/types.d.ts.map +1 -1
  166. package/package.json +15 -12
  167. package/src/ClineCore.test.ts +150 -0
  168. package/src/ClineCore.ts +114 -8
  169. package/src/account/cline-account-service.test.ts +84 -0
  170. package/src/account/cline-account-service.ts +2 -2
  171. package/src/account/index.ts +1 -0
  172. package/src/account/types.ts +6 -0
  173. package/src/auth/bounded-ttl-cache.test.ts +38 -0
  174. package/src/auth/bounded-ttl-cache.ts +53 -0
  175. package/src/auth/cline.test.ts +173 -36
  176. package/src/auth/cline.ts +395 -93
  177. package/src/auth/oca.test.ts +125 -0
  178. package/src/auth/oca.ts +17 -4
  179. package/src/{agents → extensions/config}/agent-config-loader.test.ts +1 -1
  180. package/src/{agents → extensions/config}/agent-config-parser.ts +2 -2
  181. package/src/{agents → extensions/config}/hooks-config-loader.ts +1 -1
  182. package/src/{agents → extensions/config}/index.ts +7 -11
  183. package/src/{runtime/commands.test.ts → extensions/config/runtime-commands.test.ts} +20 -3
  184. package/src/{runtime/commands.ts → extensions/config/runtime-commands.ts} +1 -8
  185. package/src/{agents → extensions/config}/unified-config-file-watcher.ts +15 -2
  186. package/src/{agents → extensions/config}/user-instruction-config-loader.test.ts +90 -2
  187. package/src/{agents → extensions/config}/user-instruction-config-loader.ts +126 -12
  188. package/src/extensions/context/agentic-compaction.ts +119 -0
  189. package/src/extensions/context/basic-compaction.ts +275 -0
  190. package/src/extensions/context/compaction-shared.ts +458 -0
  191. package/src/extensions/context/compaction.test.ts +477 -0
  192. package/src/extensions/context/compaction.ts +203 -0
  193. package/src/extensions/index.ts +12 -0
  194. package/src/extensions/mcp/client.ts +420 -0
  195. package/src/{mcp → extensions/mcp}/index.ts +16 -0
  196. package/src/{mcp → extensions/mcp}/manager.test.ts +1 -2
  197. package/src/{mcp → extensions/mcp}/manager.ts +3 -5
  198. package/src/extensions/mcp/name-transform.ts +33 -0
  199. package/src/extensions/mcp/policies.ts +47 -0
  200. package/src/extensions/mcp/tools.ts +47 -0
  201. package/src/{mcp → extensions/mcp}/types.ts +35 -7
  202. package/src/{agents → extensions/plugin}/plugin-config-loader.test.ts +18 -13
  203. package/src/{agents → extensions/plugin}/plugin-config-loader.ts +1 -1
  204. package/src/{agents → extensions/plugin}/plugin-loader.test.ts +41 -4
  205. package/src/extensions/plugin/plugin-loader.ts +106 -0
  206. package/src/extensions/plugin/plugin-module-import.ts +278 -0
  207. package/src/{agents → extensions/plugin}/plugin-sandbox-bootstrap.ts +30 -92
  208. package/src/{agents → extensions/plugin}/plugin-sandbox.test.ts +60 -3
  209. package/src/{agents → extensions/plugin}/plugin-sandbox.ts +146 -56
  210. package/src/hooks/index.ts +25 -0
  211. package/src/hooks/persistent.ts +661 -0
  212. package/src/hooks/subprocess-runner.ts +196 -0
  213. package/src/hooks/subprocess.ts +669 -0
  214. package/src/index.ts +200 -118
  215. package/src/prompt/default-system.ts +21 -0
  216. package/src/providers/local-provider-registry.ts +1 -1
  217. package/src/providers/local-provider-service.test.ts +23 -2
  218. package/src/providers/local-provider-service.ts +2 -2
  219. package/src/runtime/checkpoint-hooks.test.ts +167 -0
  220. package/src/runtime/checkpoint-hooks.ts +186 -0
  221. package/src/runtime/hook-file-hooks.test.ts +40 -1
  222. package/src/runtime/hook-file-hooks.ts +35 -16
  223. package/src/runtime/index.ts +4 -19
  224. package/src/runtime/rules.ts +4 -1
  225. package/src/runtime/runtime-builder.team-persistence.test.ts +3 -6
  226. package/src/runtime/runtime-builder.test.ts +266 -160
  227. package/src/runtime/runtime-builder.ts +120 -47
  228. package/src/runtime/runtime-parity.test.ts +22 -22
  229. package/src/runtime/session-runtime.ts +36 -6
  230. package/src/runtime/{sandbox/subprocess-sandbox.ts → subprocess-sandbox.ts} +24 -3
  231. package/src/runtime/team-runtime-registry.ts +1 -4
  232. package/src/runtime/tool-approval.ts +1 -1
  233. package/src/session/default-session-manager.e2e.test.ts +2 -2
  234. package/src/session/default-session-manager.test.ts +553 -9
  235. package/src/session/default-session-manager.ts +140 -46
  236. package/src/session/file-session-service.ts +3 -3
  237. package/src/session/index.ts +6 -6
  238. package/src/session/persistence-service.test.ts +212 -0
  239. package/src/session/{unified-session-persistence-service.ts → persistence-service.ts} +106 -172
  240. package/src/session/rpc-session-service.ts +3 -3
  241. package/src/session/runtime-oauth-token-manager.ts +1 -1
  242. package/src/session/session-agent-events.ts +1 -1
  243. package/src/session/session-artifacts.ts +32 -4
  244. package/src/session/session-config-builder.ts +22 -9
  245. package/src/session/session-graph.ts +1 -1
  246. package/src/session/session-host.ts +19 -11
  247. package/src/session/session-manager.ts +11 -6
  248. package/src/session/session-service.team-persistence.test.ts +1 -1
  249. package/src/session/session-service.ts +6 -9
  250. package/src/session/session-team-coordination.ts +7 -3
  251. package/src/session/session-telemetry.ts +1 -1
  252. package/src/session/utils/helpers.test.ts +160 -0
  253. package/src/session/utils/helpers.ts +289 -42
  254. package/src/session/utils/types.ts +47 -7
  255. package/src/session/workspace-manager.ts +5 -3
  256. package/src/session/workspace-manifest.ts +3 -49
  257. package/src/storage/file-team-store.ts +2 -5
  258. package/src/storage/provider-settings-legacy-migration.ts +2 -2
  259. package/src/storage/provider-settings-manager.test.ts +1 -1
  260. package/src/storage/sqlite-team-store.ts +212 -125
  261. package/src/storage/team-store.ts +1 -5
  262. package/src/team/delegated-agent.ts +131 -0
  263. package/src/team/index.ts +1 -0
  264. package/src/team/multi-agent.lifecycle.test.ts +201 -0
  265. package/src/team/multi-agent.ts +1666 -0
  266. package/src/team/projections.ts +2 -4
  267. package/src/team/runtime.ts +54 -0
  268. package/src/team/spawn-agent-tool.test.ts +387 -0
  269. package/src/team/spawn-agent-tool.ts +207 -0
  270. package/src/team/subagent-prompts.ts +41 -0
  271. package/src/team/team-tools.test.ts +802 -0
  272. package/src/team/team-tools.ts +792 -0
  273. package/src/telemetry/OpenTelemetryProvider.test.ts +25 -3
  274. package/src/telemetry/OpenTelemetryProvider.ts +108 -18
  275. package/src/telemetry/TelemetryLoggerSink.test.ts +42 -0
  276. package/src/telemetry/{LoggerTelemetryAdapter.ts → TelemetryLoggerSink.ts} +21 -14
  277. package/src/telemetry/TelemetryService.test.ts +7 -7
  278. package/src/telemetry/TelemetryService.ts +2 -4
  279. package/src/tools/definitions.test.ts +76 -0
  280. package/src/tools/definitions.ts +41 -2
  281. package/src/tools/executors/apply-patch.ts +1 -1
  282. package/src/tools/executors/editor.ts +1 -1
  283. package/src/tools/executors/file-read.ts +1 -1
  284. package/src/tools/executors/search.ts +1 -1
  285. package/src/tools/executors/web-fetch.ts +1 -1
  286. package/src/tools/index.ts +6 -1
  287. package/src/tools/model-tool-routing.ts +2 -0
  288. package/src/tools/presets.test.ts +8 -0
  289. package/src/tools/presets.ts +40 -2
  290. package/src/tools/schemas.ts +19 -0
  291. package/src/tools/types.ts +31 -2
  292. package/src/types/config.ts +61 -7
  293. package/src/types/events.ts +1 -1
  294. package/src/types/index.ts +0 -1
  295. package/src/types/provider-settings.ts +1 -1
  296. package/src/types/storage.ts +2 -5
  297. package/src/types.ts +32 -44
  298. package/dist/agents/agent-config-loader.d.ts.map +0 -1
  299. package/dist/agents/agent-config-parser.d.ts.map +0 -1
  300. package/dist/agents/hooks-config-loader.d.ts.map +0 -1
  301. package/dist/agents/index.d.ts.map +0 -1
  302. package/dist/agents/plugin-config-loader.d.ts.map +0 -1
  303. package/dist/agents/plugin-loader.d.ts.map +0 -1
  304. package/dist/agents/plugin-sandbox-bootstrap.js +0 -446
  305. package/dist/agents/plugin-sandbox.d.ts.map +0 -1
  306. package/dist/agents/unified-config-file-watcher.d.ts.map +0 -1
  307. package/dist/agents/user-instruction-config-loader.d.ts.map +0 -1
  308. package/dist/mcp/config-loader.d.ts.map +0 -1
  309. package/dist/mcp/index.d.ts +0 -5
  310. package/dist/mcp/index.d.ts.map +0 -1
  311. package/dist/mcp/manager.d.ts.map +0 -1
  312. package/dist/mcp/types.d.ts.map +0 -1
  313. package/dist/runtime/commands.d.ts.map +0 -1
  314. package/dist/runtime/sandbox/subprocess-sandbox.d.ts.map +0 -1
  315. package/dist/runtime/skills.d.ts +0 -14
  316. package/dist/runtime/skills.d.ts.map +0 -1
  317. package/dist/runtime/workflows.d.ts +0 -14
  318. package/dist/runtime/workflows.d.ts.map +0 -1
  319. package/dist/session/unified-session-persistence-service.d.ts.map +0 -1
  320. package/dist/telemetry/LoggerTelemetryAdapter.d.ts.map +0 -1
  321. package/dist/types/workspace.d.ts +0 -8
  322. package/dist/types/workspace.d.ts.map +0 -1
  323. package/src/agents/plugin-loader.ts +0 -175
  324. package/src/runtime/skills.ts +0 -44
  325. package/src/runtime/workflows.test.ts +0 -119
  326. package/src/runtime/workflows.ts +0 -45
  327. package/src/session/unified-session-persistence-service.test.ts +0 -85
  328. package/src/telemetry/LoggerTelemetryAdapter.test.ts +0 -42
  329. package/src/types/workspace.ts +0 -7
  330. /package/dist/{agents → extensions/config}/agent-config-loader.d.ts +0 -0
  331. /package/dist/{agents → extensions/config}/unified-config-file-watcher.d.ts +0 -0
  332. /package/dist/{agents → extensions/config}/user-instruction-config-loader.d.ts +0 -0
  333. /package/dist/{mcp → extensions/mcp}/config-loader.d.ts +0 -0
  334. /package/dist/runtime/{sandbox/subprocess-sandbox.d.ts → subprocess-sandbox.d.ts} +0 -0
  335. /package/src/{agents → extensions/config}/agent-config-loader.ts +0 -0
  336. /package/src/{agents → extensions/config}/hooks-config-loader.test.ts +0 -0
  337. /package/src/{agents → extensions/config}/unified-config-file-watcher.test.ts +0 -0
  338. /package/src/{mcp → extensions/mcp}/config-loader.test.ts +0 -0
  339. /package/src/{mcp → extensions/mcp}/config-loader.ts +0 -0
@@ -0,0 +1,792 @@
1
+ import type { AgentResult } from "@clinebot/agents";
2
+ import {
3
+ createTool,
4
+ TEAM_AWAIT_TIMEOUT_MS,
5
+ TEAM_RUN_MESSAGE_PREVIEW_LIMIT,
6
+ TEAM_RUN_TEXT_PREVIEW_LIMIT,
7
+ type TeamAttachOutcomeFragmentInput,
8
+ TeamAttachOutcomeFragmentInputSchema,
9
+ type TeamAwaitAllRunsInput,
10
+ TeamAwaitAllRunsInputSchema,
11
+ type TeamAwaitRunInput,
12
+ TeamAwaitRunInputSchema,
13
+ type TeamBroadcastInput,
14
+ TeamBroadcastInputSchema,
15
+ type TeamCancelRunInput,
16
+ TeamCancelRunInputSchema,
17
+ type TeamCleanupInput,
18
+ TeamCleanupInputSchema,
19
+ type TeamCreateOutcomeInput,
20
+ TeamCreateOutcomeInputSchema,
21
+ type TeamFinalizeOutcomeInput,
22
+ TeamFinalizeOutcomeInputSchema,
23
+ type TeamListOutcomesInput,
24
+ TeamListOutcomesInputSchema,
25
+ type TeamListRunsInput,
26
+ TeamListRunsInputSchema,
27
+ type TeamLogUpdateInput,
28
+ TeamLogUpdateInputSchema,
29
+ type TeamReadMailboxInput,
30
+ TeamReadMailboxInputSchema,
31
+ type TeamReviewOutcomeFragmentInput,
32
+ TeamReviewOutcomeFragmentInputSchema,
33
+ type TeamRunRecord,
34
+ type TeamRunResultSummary,
35
+ type TeamRunTaskInput,
36
+ TeamRunTaskInputSchema,
37
+ type TeamRunToolSummary,
38
+ type TeamRuntimeState,
39
+ type TeamSendMessageInput,
40
+ TeamSendMessageInputSchema,
41
+ type TeamShutdownTeammateInput,
42
+ TeamShutdownTeammateInputSchema,
43
+ type TeamSpawnTeammateInput,
44
+ TeamSpawnTeammateInputSchema,
45
+ type TeamStatusInput,
46
+ TeamStatusInputSchema,
47
+ type TeamTaskInput,
48
+ TeamTaskInputSchema,
49
+ type TeamTaskToolResult,
50
+ type TeamTeammateSpec,
51
+ type Tool,
52
+ validateWithZod,
53
+ zodToJsonSchema,
54
+ } from "@clinebot/shared";
55
+ import {
56
+ buildDelegatedAgentConfig,
57
+ type DelegatedAgentConfigProvider,
58
+ type DelegatedAgentRuntimeConfig,
59
+ } from "./delegated-agent";
60
+ import type { AgentTeamsRuntime } from "./multi-agent";
61
+
62
+ function truncateText(value: string, maxLength: number): string {
63
+ const normalized = value.replace(/\s+/g, " ").trim();
64
+ if (normalized.length <= maxLength) {
65
+ return normalized;
66
+ }
67
+ return `${normalized.slice(0, Math.max(0, maxLength - 3)).trimEnd()}...`;
68
+ }
69
+
70
+ function summarizeRunResult(
71
+ run: TeamRunRecord,
72
+ ): TeamRunResultSummary | undefined {
73
+ const result = run.result as AgentResult | undefined;
74
+ if (!result) {
75
+ return undefined;
76
+ }
77
+ return {
78
+ textPreview: truncateText(result.text, TEAM_RUN_TEXT_PREVIEW_LIMIT),
79
+ iterations: result.iterations,
80
+ finishReason: result.finishReason,
81
+ durationMs: result.durationMs,
82
+ usage: {
83
+ inputTokens: result.usage.inputTokens,
84
+ outputTokens: result.usage.outputTokens,
85
+ cacheReadTokens: result.usage.cacheReadTokens,
86
+ cacheWriteTokens: result.usage.cacheWriteTokens,
87
+ totalCost: result.usage.totalCost,
88
+ },
89
+ };
90
+ }
91
+
92
+ function summarizeRun(run: TeamRunRecord): TeamRunToolSummary {
93
+ return {
94
+ id: run.id,
95
+ agentId: run.agentId,
96
+ taskId: run.taskId,
97
+ status: run.status,
98
+ messagePreview: truncateText(run.message, TEAM_RUN_MESSAGE_PREVIEW_LIMIT),
99
+ priority: run.priority,
100
+ retryCount: run.retryCount,
101
+ maxRetries: run.maxRetries,
102
+ nextAttemptAt: run.nextAttemptAt,
103
+ continueConversation: run.continueConversation,
104
+ startedAt: run.startedAt,
105
+ endedAt: run.endedAt,
106
+ leaseOwner: run.leaseOwner,
107
+ heartbeatAt: run.heartbeatAt,
108
+ lastProgressAt: run.lastProgressAt,
109
+ lastProgressMessage: run.lastProgressMessage,
110
+ currentActivity: run.currentActivity,
111
+ error: run.error,
112
+ resultSummary: summarizeRunResult(run),
113
+ };
114
+ }
115
+
116
+ export type TeamTeammateRuntimeConfig = DelegatedAgentRuntimeConfig;
117
+
118
+ export interface CreateAgentTeamsToolsOptions {
119
+ runtime: AgentTeamsRuntime;
120
+ requesterId: string;
121
+ teammateConfigProvider: DelegatedAgentConfigProvider;
122
+ createBaseTools?: () => Tool[];
123
+ allowSpawn?: boolean;
124
+ includeSpawnTool?: boolean;
125
+ includeManagementTools?: boolean;
126
+ onLeadToolsUnlocked?: (tools: Tool[]) => void;
127
+ }
128
+
129
+ export interface BootstrapAgentTeamsOptions {
130
+ runtime: AgentTeamsRuntime;
131
+ teammateConfigProvider: DelegatedAgentConfigProvider;
132
+ createBaseTools?: () => Tool[];
133
+ leadAgentId?: string;
134
+ restoredTeammates?: TeamTeammateSpec[];
135
+ restoredFromPersistence?: boolean;
136
+ includeLeadSpawnTool?: boolean;
137
+ includeLeadManagementTools?: boolean;
138
+ onLeadToolsUnlocked?: (tools: Tool[]) => void;
139
+ }
140
+
141
+ export interface BootstrapAgentTeamsResult {
142
+ tools: Tool[];
143
+ restoredFromPersistence: boolean;
144
+ restoredTeammates: string[];
145
+ }
146
+
147
+ function spawnTeamTeammate(
148
+ options: Omit<CreateAgentTeamsToolsOptions, "requesterId" | "allowSpawn"> & {
149
+ requesterId: string;
150
+ spec: TeamTeammateSpec;
151
+ },
152
+ ): void {
153
+ const teammateTools: Tool[] = [];
154
+ if (options.createBaseTools) {
155
+ teammateTools.push(...options.createBaseTools());
156
+ }
157
+ teammateTools.push(
158
+ ...createAgentTeamsTools({
159
+ runtime: options.runtime,
160
+ requesterId: options.spec.agentId,
161
+ teammateConfigProvider: options.teammateConfigProvider,
162
+ createBaseTools: options.createBaseTools,
163
+ allowSpawn: false,
164
+ }),
165
+ );
166
+ options.runtime.spawnTeammate({
167
+ agentId: options.spec.agentId,
168
+ config: buildDelegatedAgentConfig({
169
+ kind: "teammate",
170
+ prompt: options.spec.rolePrompt,
171
+ role: options.spec.rolePrompt,
172
+ configProvider: options.teammateConfigProvider,
173
+ tools: teammateTools,
174
+ maxIterations: options.spec.maxIterations,
175
+ cwd: options.teammateConfigProvider.getRuntimeConfig().cwd,
176
+ }),
177
+ });
178
+ }
179
+
180
+ export function bootstrapAgentTeams(
181
+ options: BootstrapAgentTeamsOptions,
182
+ ): BootstrapAgentTeamsResult {
183
+ const leadAgentId = options.leadAgentId ?? "lead";
184
+ const restoredFromPersistence = options.restoredFromPersistence === true;
185
+
186
+ const tools = createAgentTeamsTools({
187
+ runtime: options.runtime,
188
+ requesterId: leadAgentId,
189
+ teammateConfigProvider: options.teammateConfigProvider,
190
+ createBaseTools: options.createBaseTools,
191
+ allowSpawn: true,
192
+ includeSpawnTool: options.includeLeadSpawnTool,
193
+ includeManagementTools: options.includeLeadManagementTools,
194
+ onLeadToolsUnlocked: options.onLeadToolsUnlocked,
195
+ });
196
+
197
+ const restoredTeammates: string[] = [];
198
+ for (const spec of options.restoredTeammates ?? []) {
199
+ if (options.runtime.isTeammateActive(spec.agentId)) {
200
+ continue;
201
+ }
202
+ spawnTeamTeammate({
203
+ runtime: options.runtime,
204
+ requesterId: leadAgentId,
205
+ teammateConfigProvider: options.teammateConfigProvider,
206
+ createBaseTools: options.createBaseTools,
207
+ spec,
208
+ });
209
+ restoredTeammates.push(spec.agentId);
210
+ }
211
+
212
+ return {
213
+ tools,
214
+ restoredFromPersistence,
215
+ restoredTeammates,
216
+ };
217
+ }
218
+
219
+ export function createAgentTeamsTools(
220
+ options: CreateAgentTeamsToolsOptions,
221
+ ): Tool[] {
222
+ const allowSpawn = options.allowSpawn ?? true;
223
+ const includeSpawnTool = options.includeSpawnTool ?? true;
224
+ const includeManagementTools = options.includeManagementTools ?? true;
225
+ const tools: Tool[] = [];
226
+
227
+ if (includeSpawnTool) {
228
+ tools.push(
229
+ createTool<TeamSpawnTeammateInput, { agentId: string; status: string }>({
230
+ name: "team_spawn_teammate",
231
+ description: "Spawn a teammate with a required agentId and rolePrompt.",
232
+ inputSchema: zodToJsonSchema(TeamSpawnTeammateInputSchema),
233
+ execute: async (input) => {
234
+ const validatedInput = validateWithZod(
235
+ TeamSpawnTeammateInputSchema,
236
+ input,
237
+ );
238
+ if (options.runtime.getMemberRole(options.requesterId) !== "lead") {
239
+ throw new Error("Only the lead agent can manage teammates.");
240
+ }
241
+ if (!allowSpawn) {
242
+ throw new Error("Spawning teammates is disabled in this context.");
243
+ }
244
+ const spec: TeamTeammateSpec = {
245
+ agentId: validatedInput.agentId,
246
+ rolePrompt: validatedInput.rolePrompt,
247
+ maxIterations: validatedInput.maxIterations,
248
+ };
249
+ spawnTeamTeammate({
250
+ runtime: options.runtime,
251
+ requesterId: options.requesterId,
252
+ teammateConfigProvider: options.teammateConfigProvider,
253
+ createBaseTools: options.createBaseTools,
254
+ spec,
255
+ });
256
+ if (!includeManagementTools) {
257
+ options.onLeadToolsUnlocked?.(
258
+ createAgentTeamsTools({
259
+ ...options,
260
+ includeSpawnTool: false,
261
+ includeManagementTools: true,
262
+ onLeadToolsUnlocked: undefined,
263
+ }),
264
+ );
265
+ }
266
+ return { agentId: validatedInput.agentId, status: "spawned" };
267
+ },
268
+ }) as Tool,
269
+ );
270
+ }
271
+
272
+ if (!includeManagementTools) {
273
+ return tools;
274
+ }
275
+
276
+ tools.push(
277
+ createTool<TeamShutdownTeammateInput, { agentId: string; status: string }>({
278
+ name: "team_shutdown_teammate",
279
+ description: "Shutdown a teammate by agentId.",
280
+ inputSchema: zodToJsonSchema(TeamShutdownTeammateInputSchema),
281
+ execute: async (input) => {
282
+ const validatedInput = validateWithZod(
283
+ TeamShutdownTeammateInputSchema,
284
+ input,
285
+ );
286
+ if (options.runtime.getMemberRole(options.requesterId) !== "lead") {
287
+ throw new Error("Only the lead agent can manage teammates.");
288
+ }
289
+ options.runtime.shutdownTeammate(
290
+ validatedInput.agentId,
291
+ validatedInput.reason,
292
+ );
293
+ return { agentId: validatedInput.agentId, status: "stopped" };
294
+ },
295
+ }) as Tool,
296
+ );
297
+
298
+ tools.push(
299
+ createTool<TeamStatusInput, ReturnType<AgentTeamsRuntime["getSnapshot"]>>({
300
+ name: "team_status",
301
+ description:
302
+ "Return a snapshot of team members, task counts, mailbox, and mission log stats.",
303
+ inputSchema: zodToJsonSchema(TeamStatusInputSchema),
304
+ execute: async (input) => {
305
+ validateWithZod(TeamStatusInputSchema, input);
306
+ return options.runtime.getSnapshot();
307
+ },
308
+ }) as Tool,
309
+ );
310
+
311
+ tools.push(
312
+ createTool<TeamTaskInput, TeamTaskToolResult>({
313
+ name: "team_task",
314
+ description:
315
+ "Manage shared team tasks. Use action=create|list|claim|complete|block.",
316
+ inputSchema: zodToJsonSchema(TeamTaskInputSchema),
317
+ execute: async (input) => {
318
+ const validatedInput = validateWithZod(TeamTaskInputSchema, input);
319
+ switch (validatedInput.action) {
320
+ case "create": {
321
+ const task = options.runtime.createTask({
322
+ title: validatedInput.title!,
323
+ description: validatedInput.description!,
324
+ dependsOn: validatedInput.dependsOn,
325
+ assignee: validatedInput.assignee,
326
+ createdBy: options.requesterId,
327
+ });
328
+ return {
329
+ action: "create",
330
+ taskId: task.id,
331
+ status: task.status,
332
+ };
333
+ }
334
+ case "list":
335
+ return {
336
+ action: "list",
337
+ tasks: options.runtime.listTaskItems({
338
+ status: validatedInput.status,
339
+ assignee: validatedInput.assignee,
340
+ unassignedOnly: validatedInput.unassignedOnly,
341
+ readyOnly: validatedInput.readyOnly,
342
+ }),
343
+ };
344
+ case "claim": {
345
+ const task = options.runtime.claimTask(
346
+ validatedInput.taskId!,
347
+ options.requesterId,
348
+ );
349
+ return {
350
+ action: "claim",
351
+ taskId: task.id,
352
+ status: task.status,
353
+ nextStep:
354
+ "Task is now in_progress. Execute the work using team_run_task or your own tools, then call team_task with action=complete when done.",
355
+ };
356
+ }
357
+ case "complete": {
358
+ const task = options.runtime.completeTask(
359
+ validatedInput.taskId!,
360
+ options.requesterId,
361
+ validatedInput.summary!,
362
+ );
363
+ return {
364
+ action: "complete",
365
+ taskId: task.id,
366
+ status: task.status,
367
+ };
368
+ }
369
+ case "block": {
370
+ const task = options.runtime.blockTask(
371
+ validatedInput.taskId!,
372
+ options.requesterId,
373
+ validatedInput.reason!,
374
+ );
375
+ return {
376
+ action: "block",
377
+ taskId: task.id,
378
+ status: task.status,
379
+ };
380
+ }
381
+ }
382
+ },
383
+ }) as Tool,
384
+ );
385
+
386
+ tools.push(
387
+ createTool<
388
+ TeamRunTaskInput,
389
+ {
390
+ agentId: string;
391
+ mode: "sync" | "async";
392
+ runId?: string;
393
+ text?: string;
394
+ iterations?: number;
395
+ }
396
+ >({
397
+ name: "team_run_task",
398
+ description:
399
+ "Route a delegated task to a teammate. Choose sync (wait) or async (run in background).",
400
+ inputSchema: zodToJsonSchema(TeamRunTaskInputSchema),
401
+ execute: async (input) => {
402
+ const validatedInput = validateWithZod(TeamRunTaskInputSchema, input);
403
+ if (validatedInput.runMode === "async") {
404
+ const run = options.runtime.startTeammateRun(
405
+ validatedInput.agentId,
406
+ validatedInput.task,
407
+ {
408
+ taskId: validatedInput.taskId || undefined,
409
+ fromAgentId: options.requesterId,
410
+ continueConversation:
411
+ validatedInput.continueConversation || undefined,
412
+ },
413
+ );
414
+ return {
415
+ agentId: validatedInput.agentId,
416
+ mode: "async",
417
+ runId: run.id,
418
+ };
419
+ }
420
+ const result = await options.runtime.routeToTeammate(
421
+ validatedInput.agentId,
422
+ validatedInput.task,
423
+ {
424
+ taskId: validatedInput.taskId || undefined,
425
+ fromAgentId: options.requesterId,
426
+ continueConversation:
427
+ validatedInput.continueConversation || undefined,
428
+ },
429
+ );
430
+ return {
431
+ agentId: validatedInput.agentId,
432
+ mode: "sync",
433
+ text: result.text,
434
+ iterations: result.iterations,
435
+ };
436
+ },
437
+ }) as Tool,
438
+ );
439
+
440
+ tools.push(
441
+ createTool<TeamCancelRunInput, { runId: string; status: string }>({
442
+ name: "team_cancel_run",
443
+ description: "Cancel one async teammate run.",
444
+ inputSchema: zodToJsonSchema(TeamCancelRunInputSchema),
445
+ execute: async (input) => {
446
+ const validatedInput = validateWithZod(TeamCancelRunInputSchema, input);
447
+ const run = options.runtime.cancelRun(
448
+ validatedInput.runId,
449
+ validatedInput.reason,
450
+ );
451
+ return { runId: run.id, status: run.status };
452
+ },
453
+ }) as Tool,
454
+ );
455
+
456
+ tools.push(
457
+ createTool<TeamListRunsInput, TeamRunToolSummary[]>({
458
+ name: "team_list_runs",
459
+ description:
460
+ "List teammate runs started with team_run_task in async mode, including live activity/progress fields when available.",
461
+ inputSchema: zodToJsonSchema(TeamListRunsInputSchema),
462
+ execute: async (input) =>
463
+ options.runtime
464
+ .listRuns(validateWithZod(TeamListRunsInputSchema, input))
465
+ .map(summarizeRun),
466
+ }) as Tool,
467
+ );
468
+
469
+ tools.push(
470
+ createTool<TeamAwaitRunInput, TeamRunToolSummary>({
471
+ name: "team_await_run",
472
+ description:
473
+ "Wait for one async run by runId. Uses a long timeout for legitimate teammate work.",
474
+ inputSchema: zodToJsonSchema(TeamAwaitRunInputSchema),
475
+ timeoutMs: TEAM_AWAIT_TIMEOUT_MS,
476
+ execute: async (input) => {
477
+ const validatedInput = validateWithZod(TeamAwaitRunInputSchema, input);
478
+ const run = await options.runtime.awaitRun(validatedInput.runId);
479
+ if (run.status === "failed") {
480
+ throw new Error(
481
+ `Run "${run.id}" failed${run.error ? `: ${run.error}` : ""}`,
482
+ );
483
+ }
484
+ if (run.status === "cancelled") {
485
+ throw new Error(
486
+ `Run "${run.id}" was cancelled${run.error ? `: ${run.error}` : ""}`,
487
+ );
488
+ }
489
+ if (run.status === "interrupted") {
490
+ throw new Error(
491
+ `Run "${run.id}" was interrupted${run.error ? `: ${run.error}` : ""}`,
492
+ );
493
+ }
494
+ return summarizeRun(run);
495
+ },
496
+ }) as Tool,
497
+ );
498
+
499
+ tools.push(
500
+ createTool<TeamAwaitAllRunsInput, TeamRunToolSummary[]>({
501
+ name: "team_await_all_runs",
502
+ description:
503
+ "Wait for all active async runs to complete. Uses a long timeout for legitimate teammate work.",
504
+ inputSchema: zodToJsonSchema(TeamAwaitAllRunsInputSchema),
505
+ timeoutMs: TEAM_AWAIT_TIMEOUT_MS,
506
+ execute: async (input) => {
507
+ validateWithZod(TeamAwaitAllRunsInputSchema, input);
508
+ const runs = await options.runtime.awaitAllRuns();
509
+ const failedRuns = runs.filter((run) =>
510
+ ["failed", "cancelled", "interrupted"].includes(run.status),
511
+ );
512
+ if (failedRuns.length > 0) {
513
+ const details = failedRuns
514
+ .map(
515
+ (run) =>
516
+ `${run.id}:${run.status}${run.error ? `(${run.error})` : ""}`,
517
+ )
518
+ .join(", ");
519
+ throw new Error(
520
+ `One or more runs did not complete successfully: ${details}`,
521
+ );
522
+ }
523
+ return runs.map(summarizeRun);
524
+ },
525
+ }) as Tool,
526
+ );
527
+
528
+ tools.push(
529
+ createTool<TeamSendMessageInput, { id: string; toAgentId: string }>({
530
+ name: "team_send_message",
531
+ description: "Send a direct mailbox message to one teammate.",
532
+ inputSchema: zodToJsonSchema(TeamSendMessageInputSchema),
533
+ execute: async (input) => {
534
+ const validatedInput = validateWithZod(
535
+ TeamSendMessageInputSchema,
536
+ input,
537
+ );
538
+ const message = options.runtime.sendMessage(
539
+ options.requesterId,
540
+ validatedInput.toAgentId,
541
+ validatedInput.subject,
542
+ validatedInput.body,
543
+ validatedInput.taskId ?? undefined,
544
+ );
545
+ return { id: message.id, toAgentId: message.toAgentId };
546
+ },
547
+ }) as Tool,
548
+ );
549
+
550
+ tools.push(
551
+ createTool<TeamBroadcastInput, { delivered: number }>({
552
+ name: "team_broadcast",
553
+ description: "Broadcast a mailbox message to all teammates.",
554
+ inputSchema: zodToJsonSchema(TeamBroadcastInputSchema),
555
+ execute: async (input) => {
556
+ const validatedInput = validateWithZod(TeamBroadcastInputSchema, input);
557
+ const messages = options.runtime.broadcast(
558
+ options.requesterId,
559
+ validatedInput.subject,
560
+ validatedInput.body,
561
+ {
562
+ taskId: validatedInput.taskId ?? undefined,
563
+ includeLead: validatedInput.includeLead ?? undefined,
564
+ },
565
+ );
566
+ return { delivered: messages.length };
567
+ },
568
+ }) as Tool,
569
+ );
570
+
571
+ tools.push(
572
+ createTool<
573
+ TeamReadMailboxInput,
574
+ ReturnType<AgentTeamsRuntime["listMailbox"]>
575
+ >({
576
+ name: "team_read_mailbox",
577
+ description: "Read the current agent mailbox.",
578
+ inputSchema: zodToJsonSchema(TeamReadMailboxInputSchema),
579
+ execute: async (input) => {
580
+ const validatedInput = validateWithZod(
581
+ TeamReadMailboxInputSchema,
582
+ input,
583
+ );
584
+ return options.runtime.listMailbox(options.requesterId, {
585
+ unreadOnly: validatedInput.unreadOnly,
586
+ limit: validatedInput.limit,
587
+ markRead: true,
588
+ });
589
+ },
590
+ }) as Tool,
591
+ );
592
+
593
+ tools.push(
594
+ createTool<TeamLogUpdateInput, { id: string }>({
595
+ name: "team_log_update",
596
+ description: "Append a mission log update for this agent.",
597
+ inputSchema: zodToJsonSchema(TeamLogUpdateInputSchema),
598
+ execute: async (input) => {
599
+ const validatedInput = validateWithZod(TeamLogUpdateInputSchema, input);
600
+ const entry = options.runtime.appendMissionLog({
601
+ agentId: options.requesterId,
602
+ taskId: validatedInput.taskId || undefined,
603
+ kind: validatedInput.kind,
604
+ summary: validatedInput.summary,
605
+ evidence: validatedInput.evidence?.length
606
+ ? validatedInput.evidence
607
+ : undefined,
608
+ nextAction: validatedInput.nextAction || undefined,
609
+ });
610
+ return { id: entry.id };
611
+ },
612
+ }) as Tool,
613
+ );
614
+
615
+ tools.push(
616
+ createTool<TeamCleanupInput, { status: string }>({
617
+ name: "team_cleanup",
618
+ description:
619
+ "Clean up the team runtime. Fails if teammates are still running.",
620
+ inputSchema: zodToJsonSchema(TeamCleanupInputSchema),
621
+ execute: async (input) => {
622
+ validateWithZod(TeamCleanupInputSchema, input);
623
+ if (options.runtime.getMemberRole(options.requesterId) !== "lead") {
624
+ throw new Error("Only the lead agent can run cleanup.");
625
+ }
626
+ options.runtime.cleanup();
627
+ return { status: "cleaned" };
628
+ },
629
+ }) as Tool,
630
+ );
631
+
632
+ tools.push(
633
+ createTool<TeamCreateOutcomeInput, { outcomeId: string; status: string }>({
634
+ name: "team_create_outcome",
635
+ description: "Create a converged team outcome.",
636
+ inputSchema: zodToJsonSchema(TeamCreateOutcomeInputSchema),
637
+ execute: async (input) => {
638
+ const validatedInput = validateWithZod(
639
+ TeamCreateOutcomeInputSchema,
640
+ input,
641
+ );
642
+ const outcome = options.runtime.createOutcome({
643
+ title: validatedInput.title,
644
+ requiredSections: validatedInput.requiredSections,
645
+ createdBy: options.requesterId,
646
+ });
647
+ return {
648
+ outcomeId: outcome.id,
649
+ status: outcome.status,
650
+ requiredSections: outcome.requiredSections,
651
+ };
652
+ },
653
+ }) as Tool,
654
+ );
655
+
656
+ tools.push(
657
+ createTool<
658
+ TeamAttachOutcomeFragmentInput,
659
+ { fragmentId: string; status: string }
660
+ >({
661
+ name: "team_attach_outcome_fragment",
662
+ description: "Attach a fragment to an outcome section.",
663
+ inputSchema: zodToJsonSchema(TeamAttachOutcomeFragmentInputSchema),
664
+ execute: async (input) => {
665
+ const validatedInput = validateWithZod(
666
+ TeamAttachOutcomeFragmentInputSchema,
667
+ input,
668
+ );
669
+ const fragment = options.runtime.attachOutcomeFragment({
670
+ outcomeId: validatedInput.outcomeId,
671
+ section: validatedInput.section,
672
+ sourceAgentId: options.requesterId,
673
+ sourceRunId: validatedInput.sourceRunId || undefined,
674
+ content: validatedInput.content,
675
+ });
676
+ return { fragmentId: fragment.id, status: fragment.status };
677
+ },
678
+ }) as Tool,
679
+ );
680
+
681
+ tools.push(
682
+ createTool<
683
+ TeamReviewOutcomeFragmentInput,
684
+ { fragmentId: string; status: string }
685
+ >({
686
+ name: "team_review_outcome_fragment",
687
+ description: "Review one outcome fragment.",
688
+ inputSchema: zodToJsonSchema(TeamReviewOutcomeFragmentInputSchema),
689
+ execute: async (input) => {
690
+ const validatedInput = validateWithZod(
691
+ TeamReviewOutcomeFragmentInputSchema,
692
+ input,
693
+ );
694
+ const fragment = options.runtime.reviewOutcomeFragment({
695
+ fragmentId: validatedInput.fragmentId,
696
+ reviewedBy: options.requesterId,
697
+ approved: validatedInput.approved,
698
+ });
699
+ return { fragmentId: fragment.id, status: fragment.status };
700
+ },
701
+ }) as Tool,
702
+ );
703
+
704
+ tools.push(
705
+ createTool<TeamFinalizeOutcomeInput, { outcomeId: string; status: string }>(
706
+ {
707
+ name: "team_finalize_outcome",
708
+ description: "Finalize one outcome.",
709
+ inputSchema: zodToJsonSchema(TeamFinalizeOutcomeInputSchema),
710
+ execute: async (input) => {
711
+ const validatedInput = validateWithZod(
712
+ TeamFinalizeOutcomeInputSchema,
713
+ input,
714
+ );
715
+ const outcome = options.runtime.finalizeOutcome(
716
+ validatedInput.outcomeId,
717
+ );
718
+ return { outcomeId: outcome.id, status: outcome.status };
719
+ },
720
+ },
721
+ ) as Tool,
722
+ );
723
+
724
+ tools.push(
725
+ createTool<
726
+ TeamListOutcomesInput,
727
+ ReturnType<AgentTeamsRuntime["listOutcomes"]>
728
+ >({
729
+ name: "team_list_outcomes",
730
+ description: "List team outcomes.",
731
+ inputSchema: zodToJsonSchema(TeamListOutcomesInputSchema),
732
+ execute: async (input) => {
733
+ validateWithZod(TeamListOutcomesInputSchema, input);
734
+ return options.runtime.listOutcomes();
735
+ },
736
+ }) as Tool,
737
+ );
738
+
739
+ return tools;
740
+ }
741
+
742
+ export function reviveTeamStateDates(
743
+ state: TeamRuntimeState,
744
+ ): TeamRuntimeState {
745
+ return {
746
+ ...state,
747
+ tasks: state.tasks.map((task) => ({
748
+ ...task,
749
+ createdAt: new Date(task.createdAt),
750
+ updatedAt: new Date(task.updatedAt),
751
+ })),
752
+ mailbox: state.mailbox.map((message) => ({
753
+ ...message,
754
+ sentAt: new Date(message.sentAt),
755
+ readAt: message.readAt ? new Date(message.readAt) : undefined,
756
+ })),
757
+ missionLog: state.missionLog.map((entry) => ({
758
+ ...entry,
759
+ ts: new Date(entry.ts),
760
+ })),
761
+ runs: (state.runs ?? []).map((run) => ({
762
+ ...run,
763
+ startedAt: new Date(run.startedAt),
764
+ endedAt: run.endedAt ? new Date(run.endedAt) : undefined,
765
+ nextAttemptAt: run.nextAttemptAt
766
+ ? new Date(run.nextAttemptAt)
767
+ : undefined,
768
+ heartbeatAt: run.heartbeatAt ? new Date(run.heartbeatAt) : undefined,
769
+ })),
770
+ outcomes: (state.outcomes ?? []).map((outcome) => ({
771
+ ...outcome,
772
+ createdAt: new Date(outcome.createdAt),
773
+ finalizedAt: outcome.finalizedAt
774
+ ? new Date(outcome.finalizedAt)
775
+ : undefined,
776
+ })),
777
+ outcomeFragments: (state.outcomeFragments ?? []).map((fragment) => ({
778
+ ...fragment,
779
+ createdAt: new Date(fragment.createdAt),
780
+ reviewedAt: fragment.reviewedAt
781
+ ? new Date(fragment.reviewedAt)
782
+ : undefined,
783
+ })),
784
+ };
785
+ }
786
+
787
+ export function sanitizeTeamName(name: string): string {
788
+ return name
789
+ .toLowerCase()
790
+ .replace(/[^a-z0-9._-]+/g, "-")
791
+ .replace(/^-+|-+$/g, "");
792
+ }