@alvin0/ai-agent-sdk-core 0.1.0

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 (623) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +52 -0
  3. package/dist/agent/accounting/common.js +2 -0
  4. package/dist/agent/accounting/common.js.map +1 -0
  5. package/dist/agent/accounting/config.js +2 -0
  6. package/dist/agent/accounting/config.js.map +1 -0
  7. package/dist/agent/accounting/contracts.d.ts +36 -0
  8. package/dist/agent/accounting/contracts.d.ts.map +1 -0
  9. package/dist/agent/accounting/delivery/accounting-data.js +2 -0
  10. package/dist/agent/accounting/delivery/accounting-data.js.map +1 -0
  11. package/dist/agent/accounting/delivery/config.js +2 -0
  12. package/dist/agent/accounting/delivery/config.js.map +1 -0
  13. package/dist/agent/accounting/delivery/data.js +2 -0
  14. package/dist/agent/accounting/delivery/data.js.map +1 -0
  15. package/dist/agent/accounting/delivery/support-errors.js +2 -0
  16. package/dist/agent/accounting/delivery/support-errors.js.map +1 -0
  17. package/dist/agent/accounting/delivery/terminal.js +2 -0
  18. package/dist/agent/accounting/delivery/terminal.js.map +1 -0
  19. package/dist/agent/accounting/delivery-types.d.ts +43 -0
  20. package/dist/agent/accounting/delivery-types.d.ts.map +1 -0
  21. package/dist/agent/accounting/error.d.ts +18 -0
  22. package/dist/agent/accounting/error.d.ts.map +1 -0
  23. package/dist/agent/accounting/error.js +2 -0
  24. package/dist/agent/accounting/error.js.map +1 -0
  25. package/dist/agent/accounting/estimate.js +2 -0
  26. package/dist/agent/accounting/estimate.js.map +1 -0
  27. package/dist/agent/accounting/event-buffer.js +2 -0
  28. package/dist/agent/accounting/event-buffer.js.map +1 -0
  29. package/dist/agent/accounting/ledger.js +2 -0
  30. package/dist/agent/accounting/ledger.js.map +1 -0
  31. package/dist/agent/accounting/report.d.ts +70 -0
  32. package/dist/agent/accounting/report.d.ts.map +1 -0
  33. package/dist/agent/accounting/usage.d.ts +13 -0
  34. package/dist/agent/accounting/usage.d.ts.map +1 -0
  35. package/dist/agent/accounting/usage.js +2 -0
  36. package/dist/agent/accounting/usage.js.map +1 -0
  37. package/dist/agent/context/section.d.ts +15 -0
  38. package/dist/agent/context/section.d.ts.map +1 -0
  39. package/dist/agent/context/section.js +2 -0
  40. package/dist/agent/context/section.js.map +1 -0
  41. package/dist/agent/context/types.d.ts +98 -0
  42. package/dist/agent/context/types.d.ts.map +1 -0
  43. package/dist/agent/define/definition.d.ts +110 -0
  44. package/dist/agent/define/definition.d.ts.map +1 -0
  45. package/dist/agent/define/definition.js +2 -0
  46. package/dist/agent/define/definition.js.map +1 -0
  47. package/dist/agent/define/instructions.js +2 -0
  48. package/dist/agent/define/instructions.js.map +1 -0
  49. package/dist/agent/define/output-format.js +2 -0
  50. package/dist/agent/define/output-format.js.map +1 -0
  51. package/dist/agent/define/session/accounting.js +2 -0
  52. package/dist/agent/define/session/accounting.js.map +1 -0
  53. package/dist/agent/define/session/common.js +2 -0
  54. package/dist/agent/define/session/common.js.map +1 -0
  55. package/dist/agent/define/session/config.js +2 -0
  56. package/dist/agent/define/session/config.js.map +1 -0
  57. package/dist/agent/define/session/model-config.js +2 -0
  58. package/dist/agent/define/session/model-config.js.map +1 -0
  59. package/dist/agent/define/session/observer.js +2 -0
  60. package/dist/agent/define/session/observer.js.map +1 -0
  61. package/dist/agent/define/session/run-seal.js +2 -0
  62. package/dist/agent/define/session/run-seal.js.map +1 -0
  63. package/dist/agent/define/session/runtime-binding.js +2 -0
  64. package/dist/agent/define/session/runtime-binding.js.map +1 -0
  65. package/dist/agent/define/session/runtime-compaction.js +2 -0
  66. package/dist/agent/define/session/runtime-compaction.js.map +1 -0
  67. package/dist/agent/define/session/runtime-memory.js +2 -0
  68. package/dist/agent/define/session/runtime-memory.js.map +1 -0
  69. package/dist/agent/define/session/skills.js +2 -0
  70. package/dist/agent/define/session/skills.js.map +1 -0
  71. package/dist/agent/define/session/trace-accounting.js +2 -0
  72. package/dist/agent/define/session/trace-accounting.js.map +1 -0
  73. package/dist/agent/define/session/types.d.ts +217 -0
  74. package/dist/agent/define/session/types.d.ts.map +1 -0
  75. package/dist/agent/define/session/validation.js +2 -0
  76. package/dist/agent/define/session/validation.js.map +1 -0
  77. package/dist/agent/define/session.d.ts +77 -0
  78. package/dist/agent/define/session.d.ts.map +1 -0
  79. package/dist/agent/define/session.js +2 -0
  80. package/dist/agent/define/session.js.map +1 -0
  81. package/dist/agent/history/config.js +2 -0
  82. package/dist/agent/history/config.js.map +1 -0
  83. package/dist/agent/history/history.d.ts +33 -0
  84. package/dist/agent/history/history.d.ts.map +1 -0
  85. package/dist/agent/history/history.js +2 -0
  86. package/dist/agent/history/history.js.map +1 -0
  87. package/dist/agent/history/normalize.d.ts +7 -0
  88. package/dist/agent/history/normalize.d.ts.map +1 -0
  89. package/dist/agent/history/normalize.js +2 -0
  90. package/dist/agent/history/normalize.js.map +1 -0
  91. package/dist/agent/history/project.d.ts +14 -0
  92. package/dist/agent/history/project.d.ts.map +1 -0
  93. package/dist/agent/history/project.js +2 -0
  94. package/dist/agent/history/project.js.map +1 -0
  95. package/dist/agent/history/types.d.ts +85 -0
  96. package/dist/agent/history/types.d.ts.map +1 -0
  97. package/dist/agent/history/validation.js +2 -0
  98. package/dist/agent/history/validation.js.map +1 -0
  99. package/dist/agent/loop/events.d.ts +213 -0
  100. package/dist/agent/loop/events.d.ts.map +1 -0
  101. package/dist/agent/loop/queue.js +2 -0
  102. package/dist/agent/loop/queue.js.map +1 -0
  103. package/dist/agent/loop/run-turn.d.ts +8 -0
  104. package/dist/agent/loop/run-turn.d.ts.map +1 -0
  105. package/dist/agent/loop/run-turn.js +2 -0
  106. package/dist/agent/loop/run-turn.js.map +1 -0
  107. package/dist/agent/loop/schedule.d.ts +62 -0
  108. package/dist/agent/loop/schedule.d.ts.map +1 -0
  109. package/dist/agent/loop/schedule.js +3 -0
  110. package/dist/agent/loop/schedule.js.map +1 -0
  111. package/dist/agent/loop/turn/cancellation.js +2 -0
  112. package/dist/agent/loop/turn/cancellation.js.map +1 -0
  113. package/dist/agent/loop/turn/common.js +2 -0
  114. package/dist/agent/loop/turn/common.js.map +1 -0
  115. package/dist/agent/loop/turn/config.js +2 -0
  116. package/dist/agent/loop/turn/config.js.map +1 -0
  117. package/dist/agent/loop/turn/content.js +4 -0
  118. package/dist/agent/loop/turn/content.js.map +1 -0
  119. package/dist/agent/loop/turn/hooks.js +2 -0
  120. package/dist/agent/loop/turn/hooks.js.map +1 -0
  121. package/dist/agent/loop/turn/model-round.js +2 -0
  122. package/dist/agent/loop/turn/model-round.js.map +1 -0
  123. package/dist/agent/loop/turn/repetition.js +2 -0
  124. package/dist/agent/loop/turn/repetition.js.map +1 -0
  125. package/dist/agent/loop/turn/types.d.ts +82 -0
  126. package/dist/agent/loop/turn/types.d.ts.map +1 -0
  127. package/dist/agent/loop/turn/usage-stop.js +2 -0
  128. package/dist/agent/loop/turn/usage-stop.js.map +1 -0
  129. package/dist/agent/loop/turn/validation.js +2 -0
  130. package/dist/agent/loop/turn/validation.js.map +1 -0
  131. package/dist/agent/loop/types.d.ts +82 -0
  132. package/dist/agent/loop/types.d.ts.map +1 -0
  133. package/dist/agent/memory/accounting-binding.js +2 -0
  134. package/dist/agent/memory/accounting-binding.js.map +1 -0
  135. package/dist/agent/memory/compaction-config.d.ts +63 -0
  136. package/dist/agent/memory/compaction-config.d.ts.map +1 -0
  137. package/dist/agent/memory/compaction-config.js +2 -0
  138. package/dist/agent/memory/compaction-config.js.map +1 -0
  139. package/dist/agent/memory/compaction.d.ts +62 -0
  140. package/dist/agent/memory/compaction.d.ts.map +1 -0
  141. package/dist/agent/memory/compaction.js +6 -0
  142. package/dist/agent/memory/compaction.js.map +1 -0
  143. package/dist/agent/memory/memory.d.ts +61 -0
  144. package/dist/agent/memory/memory.d.ts.map +1 -0
  145. package/dist/agent/memory/memory.js +5 -0
  146. package/dist/agent/memory/memory.js.map +1 -0
  147. package/dist/agent/memory/persistence-types.d.ts +44 -0
  148. package/dist/agent/memory/persistence-types.d.ts.map +1 -0
  149. package/dist/agent/memory/surface-compaction.d.ts +6 -0
  150. package/dist/agent/memory/surface-compaction.d.ts.map +1 -0
  151. package/dist/agent/memory/surface-compaction.js +4 -0
  152. package/dist/agent/memory/surface-compaction.js.map +1 -0
  153. package/dist/agent/memory/token-estimator.d.ts +12 -0
  154. package/dist/agent/memory/token-estimator.d.ts.map +1 -0
  155. package/dist/agent/memory/token-estimator.js +2 -0
  156. package/dist/agent/memory/token-estimator.js.map +1 -0
  157. package/dist/agent/mode/run-agent.d.ts +79 -0
  158. package/dist/agent/mode/run-agent.d.ts.map +1 -0
  159. package/dist/agent/mode/run-agent.js +4 -0
  160. package/dist/agent/mode/run-agent.js.map +1 -0
  161. package/dist/agent/mode/user-input.d.ts +61 -0
  162. package/dist/agent/mode/user-input.d.ts.map +1 -0
  163. package/dist/agent/mode/user-input.js +2 -0
  164. package/dist/agent/mode/user-input.js.map +1 -0
  165. package/dist/agent/skill/catalog.d.ts +53 -0
  166. package/dist/agent/skill/catalog.d.ts.map +1 -0
  167. package/dist/agent/skill/catalog.js +2 -0
  168. package/dist/agent/skill/catalog.js.map +1 -0
  169. package/dist/agent/skill/definition.d.ts +106 -0
  170. package/dist/agent/skill/definition.d.ts.map +1 -0
  171. package/dist/agent/skill/definition.js +2 -0
  172. package/dist/agent/skill/definition.js.map +1 -0
  173. package/dist/agent/skill/provider/config.d.ts +11 -0
  174. package/dist/agent/skill/provider/config.d.ts.map +1 -0
  175. package/dist/agent/skill/provider/config.js +2 -0
  176. package/dist/agent/skill/provider/config.js.map +1 -0
  177. package/dist/agent/skill/provider/context.js +2 -0
  178. package/dist/agent/skill/provider/context.js.map +1 -0
  179. package/dist/agent/skill/provider/definition.d.ts +6 -0
  180. package/dist/agent/skill/provider/definition.d.ts.map +1 -0
  181. package/dist/agent/skill/provider/definition.js +2 -0
  182. package/dist/agent/skill/provider/definition.js.map +1 -0
  183. package/dist/agent/skill/provider/snapshot.js +2 -0
  184. package/dist/agent/skill/provider/snapshot.js.map +1 -0
  185. package/dist/agent/skill/provider/types.d.ts +49 -0
  186. package/dist/agent/skill/provider/types.d.ts.map +1 -0
  187. package/dist/agent/skill/tools.d.ts +45 -0
  188. package/dist/agent/skill/tools.d.ts.map +1 -0
  189. package/dist/agent/skill/tools.js +14 -0
  190. package/dist/agent/skill/tools.js.map +1 -0
  191. package/dist/agent/team/common.d.ts +26 -0
  192. package/dist/agent/team/common.d.ts.map +1 -0
  193. package/dist/agent/team/common.js +2 -0
  194. package/dist/agent/team/common.js.map +1 -0
  195. package/dist/agent/team/composed.d.ts +45 -0
  196. package/dist/agent/team/composed.d.ts.map +1 -0
  197. package/dist/agent/team/composed.js +2 -0
  198. package/dist/agent/team/composed.js.map +1 -0
  199. package/dist/agent/team/contracts.d.ts +54 -0
  200. package/dist/agent/team/contracts.d.ts.map +1 -0
  201. package/dist/agent/team/managed.d.ts +527 -0
  202. package/dist/agent/team/managed.d.ts.map +1 -0
  203. package/dist/agent/team/managed.js +4 -0
  204. package/dist/agent/team/managed.js.map +1 -0
  205. package/dist/agent/team/team.d.ts +142 -0
  206. package/dist/agent/team/team.d.ts.map +1 -0
  207. package/dist/agent/team/team.js +2 -0
  208. package/dist/agent/team/team.js.map +1 -0
  209. package/dist/agent/team/types.d.ts +170 -0
  210. package/dist/agent/team/types.d.ts.map +1 -0
  211. package/dist/agent/tool/approval.d.ts +106 -0
  212. package/dist/agent/tool/approval.d.ts.map +1 -0
  213. package/dist/agent/tool/approval.js +2 -0
  214. package/dist/agent/tool/approval.js.map +1 -0
  215. package/dist/agent/tool/capture.js +2 -0
  216. package/dist/agent/tool/capture.js.map +1 -0
  217. package/dist/agent/tool/config.js +2 -0
  218. package/dist/agent/tool/config.js.map +1 -0
  219. package/dist/agent/tool/definition.d.ts +227 -0
  220. package/dist/agent/tool/definition.d.ts.map +1 -0
  221. package/dist/agent/tool/definition.js +2 -0
  222. package/dist/agent/tool/definition.js.map +1 -0
  223. package/dist/agent/tool/errors.d.ts +82 -0
  224. package/dist/agent/tool/errors.d.ts.map +1 -0
  225. package/dist/agent/tool/errors.js +2 -0
  226. package/dist/agent/tool/errors.js.map +1 -0
  227. package/dist/agent/tool/execution.d.ts +60 -0
  228. package/dist/agent/tool/execution.d.ts.map +1 -0
  229. package/dist/agent/tool/execution.js +2 -0
  230. package/dist/agent/tool/execution.js.map +1 -0
  231. package/dist/agent/tool/output-budget.d.ts +159 -0
  232. package/dist/agent/tool/output-budget.d.ts.map +1 -0
  233. package/dist/agent/tool/output-budget.js +3 -0
  234. package/dist/agent/tool/output-budget.js.map +1 -0
  235. package/dist/agent/tool/pipeline.d.ts +98 -0
  236. package/dist/agent/tool/pipeline.d.ts.map +1 -0
  237. package/dist/agent/tool/pipeline.js +4 -0
  238. package/dist/agent/tool/pipeline.js.map +1 -0
  239. package/dist/agent/tool/registry.d.ts +70 -0
  240. package/dist/agent/tool/registry.d.ts.map +1 -0
  241. package/dist/agent/tool/registry.js +2 -0
  242. package/dist/agent/tool/registry.js.map +1 -0
  243. package/dist/agent/tool/schema.d.ts +12 -0
  244. package/dist/agent/tool/schema.d.ts.map +1 -0
  245. package/dist/agent/tool/schema.js +2 -0
  246. package/dist/agent/tool/schema.js.map +1 -0
  247. package/dist/agent/tool/source-types.d.ts +25 -0
  248. package/dist/agent/tool/source-types.d.ts.map +1 -0
  249. package/dist/agent/trace/trace.d.ts +63 -0
  250. package/dist/agent/trace/trace.d.ts.map +1 -0
  251. package/dist/agent/trace/trace.js +2 -0
  252. package/dist/agent/trace/trace.js.map +1 -0
  253. package/dist/agent.d.ts +52 -0
  254. package/dist/agent.js +1 -0
  255. package/dist/async/settlement.d.ts +6 -0
  256. package/dist/async/settlement.d.ts.map +1 -0
  257. package/dist/async/settlement.js +2 -0
  258. package/dist/async/settlement.js.map +1 -0
  259. package/dist/capability/common/config.js +2 -0
  260. package/dist/capability/common/config.js.map +1 -0
  261. package/dist/capability/common/data.js +2 -0
  262. package/dist/capability/common/data.js.map +1 -0
  263. package/dist/composition/agent/author.d.ts +12 -0
  264. package/dist/composition/agent/author.d.ts.map +1 -0
  265. package/dist/composition/agent/author.js +2 -0
  266. package/dist/composition/agent/author.js.map +1 -0
  267. package/dist/composition/agent/definition.js +2 -0
  268. package/dist/composition/agent/definition.js.map +1 -0
  269. package/dist/composition/agent/native-event.js +2 -0
  270. package/dist/composition/agent/native-event.js.map +1 -0
  271. package/dist/composition/agent/native-tools.js +2 -0
  272. package/dist/composition/agent/native-tools.js.map +1 -0
  273. package/dist/composition/agent/options.js +2 -0
  274. package/dist/composition/agent/options.js.map +1 -0
  275. package/dist/composition/agent/policy.js +2 -0
  276. package/dist/composition/agent/policy.js.map +1 -0
  277. package/dist/composition/agent/public-message.js +2 -0
  278. package/dist/composition/agent/public-message.js.map +1 -0
  279. package/dist/composition/agent/session.js +2 -0
  280. package/dist/composition/agent/session.js.map +1 -0
  281. package/dist/composition/agent/types.d.ts +218 -0
  282. package/dist/composition/agent/types.d.ts.map +1 -0
  283. package/dist/composition/common/counter.js +2 -0
  284. package/dist/composition/common/counter.js.map +1 -0
  285. package/dist/composition/common/errors.d.ts +15 -0
  286. package/dist/composition/common/errors.d.ts.map +1 -0
  287. package/dist/composition/common/errors.js +2 -0
  288. package/dist/composition/common/errors.js.map +1 -0
  289. package/dist/composition/common/json-data.js +2 -0
  290. package/dist/composition/common/json-data.js.map +1 -0
  291. package/dist/composition/credential/config.d.ts +5 -0
  292. package/dist/composition/credential/config.d.ts.map +1 -0
  293. package/dist/composition/credential/config.js +2 -0
  294. package/dist/composition/credential/config.js.map +1 -0
  295. package/dist/composition/credential/definition.d.ts +9 -0
  296. package/dist/composition/credential/definition.d.ts.map +1 -0
  297. package/dist/composition/credential/definition.js +2 -0
  298. package/dist/composition/credential/definition.js.map +1 -0
  299. package/dist/composition/credential/types.d.ts +38 -0
  300. package/dist/composition/credential/types.d.ts.map +1 -0
  301. package/dist/composition/delivery/ack.js +2 -0
  302. package/dist/composition/delivery/ack.js.map +1 -0
  303. package/dist/composition/delivery/attempt.js +2 -0
  304. package/dist/composition/delivery/attempt.js.map +1 -0
  305. package/dist/composition/delivery/batch.js +2 -0
  306. package/dist/composition/delivery/batch.js.map +1 -0
  307. package/dist/composition/delivery/checkpoint.js +2 -0
  308. package/dist/composition/delivery/checkpoint.js.map +1 -0
  309. package/dist/composition/delivery/event.js +2 -0
  310. package/dist/composition/delivery/event.js.map +1 -0
  311. package/dist/composition/delivery/resource.d.ts +11 -0
  312. package/dist/composition/delivery/resource.d.ts.map +1 -0
  313. package/dist/composition/delivery/resource.js +2 -0
  314. package/dist/composition/delivery/resource.js.map +1 -0
  315. package/dist/composition/delivery/staging.js +2 -0
  316. package/dist/composition/delivery/staging.js.map +1 -0
  317. package/dist/composition/diagnostics/config.js +2 -0
  318. package/dist/composition/diagnostics/config.js.map +1 -0
  319. package/dist/composition/diagnostics/ring.d.ts +12 -0
  320. package/dist/composition/diagnostics/ring.d.ts.map +1 -0
  321. package/dist/composition/diagnostics/ring.js +2 -0
  322. package/dist/composition/diagnostics/ring.js.map +1 -0
  323. package/dist/composition/exporter/definition.d.ts +7 -0
  324. package/dist/composition/exporter/definition.d.ts.map +1 -0
  325. package/dist/composition/exporter/definition.js +2 -0
  326. package/dist/composition/exporter/definition.js.map +1 -0
  327. package/dist/composition/exporter/lifecycle.js +2 -0
  328. package/dist/composition/exporter/lifecycle.js.map +1 -0
  329. package/dist/composition/exporter/preflight.js +2 -0
  330. package/dist/composition/exporter/preflight.js.map +1 -0
  331. package/dist/composition/exporter/types.d.ts +25 -0
  332. package/dist/composition/exporter/types.d.ts.map +1 -0
  333. package/dist/composition/exporter/types.js +2 -0
  334. package/dist/composition/exporter/types.js.map +1 -0
  335. package/dist/composition/identity/agent.js +2 -0
  336. package/dist/composition/identity/agent.js.map +1 -0
  337. package/dist/composition/lifecycle/bounded.js +2 -0
  338. package/dist/composition/lifecycle/bounded.js.map +1 -0
  339. package/dist/composition/lifecycle/operations.js +2 -0
  340. package/dist/composition/lifecycle/operations.js.map +1 -0
  341. package/dist/composition/lifecycle/types.d.ts +13 -0
  342. package/dist/composition/lifecycle/types.d.ts.map +1 -0
  343. package/dist/composition/lifecycle/types.js +2 -0
  344. package/dist/composition/lifecycle/types.js.map +1 -0
  345. package/dist/composition/logging/config.js +2 -0
  346. package/dist/composition/logging/config.js.map +1 -0
  347. package/dist/composition/logging/integration.js +2 -0
  348. package/dist/composition/logging/integration.js.map +1 -0
  349. package/dist/composition/logging/logger.d.ts +9 -0
  350. package/dist/composition/logging/logger.d.ts.map +1 -0
  351. package/dist/composition/logging/logger.js +2 -0
  352. package/dist/composition/logging/logger.js.map +1 -0
  353. package/dist/composition/memory/config.d.ts +10 -0
  354. package/dist/composition/memory/config.d.ts.map +1 -0
  355. package/dist/composition/memory/config.js +2 -0
  356. package/dist/composition/memory/config.js.map +1 -0
  357. package/dist/composition/memory/definition.d.ts +7 -0
  358. package/dist/composition/memory/definition.d.ts.map +1 -0
  359. package/dist/composition/memory/definition.js +2 -0
  360. package/dist/composition/memory/definition.js.map +1 -0
  361. package/dist/composition/memory/key.js +2 -0
  362. package/dist/composition/memory/key.js.map +1 -0
  363. package/dist/composition/memory/resume.js +2 -0
  364. package/dist/composition/memory/resume.js.map +1 -0
  365. package/dist/composition/memory/run.js +2 -0
  366. package/dist/composition/memory/run.js.map +1 -0
  367. package/dist/composition/model-catalog/config.js +2 -0
  368. package/dist/composition/model-catalog/config.js.map +1 -0
  369. package/dist/composition/model-catalog/manager.js +2 -0
  370. package/dist/composition/model-catalog/manager.js.map +1 -0
  371. package/dist/composition/model-catalog/options.js +2 -0
  372. package/dist/composition/model-catalog/options.js.map +1 -0
  373. package/dist/composition/model-catalog/types.d.ts +9 -0
  374. package/dist/composition/model-catalog/types.d.ts.map +1 -0
  375. package/dist/composition/observation/config.js +2 -0
  376. package/dist/composition/observation/config.js.map +1 -0
  377. package/dist/composition/observation/extensions.js +2 -0
  378. package/dist/composition/observation/extensions.js.map +1 -0
  379. package/dist/composition/observation/final-report.d.ts +6 -0
  380. package/dist/composition/observation/final-report.d.ts.map +1 -0
  381. package/dist/composition/observation/final-report.js +2 -0
  382. package/dist/composition/observation/final-report.js.map +1 -0
  383. package/dist/composition/observation/health.d.ts +13 -0
  384. package/dist/composition/observation/health.d.ts.map +1 -0
  385. package/dist/composition/observation/port.d.ts +11 -0
  386. package/dist/composition/observation/port.d.ts.map +1 -0
  387. package/dist/composition/observation/port.js +2 -0
  388. package/dist/composition/observation/port.js.map +1 -0
  389. package/dist/composition/preflight.js +2 -0
  390. package/dist/composition/preflight.js.map +1 -0
  391. package/dist/composition/provider/activation.js +2 -0
  392. package/dist/composition/provider/activation.js.map +1 -0
  393. package/dist/composition/provider/definition.d.ts +7 -0
  394. package/dist/composition/provider/definition.d.ts.map +1 -0
  395. package/dist/composition/provider/definition.js +2 -0
  396. package/dist/composition/provider/definition.js.map +1 -0
  397. package/dist/composition/provider/model-selection.js +2 -0
  398. package/dist/composition/provider/model-selection.js.map +1 -0
  399. package/dist/composition/provider/preflight.js +2 -0
  400. package/dist/composition/provider/preflight.js.map +1 -0
  401. package/dist/composition/provider/types.d.ts +38 -0
  402. package/dist/composition/provider/types.d.ts.map +1 -0
  403. package/dist/composition/provider/types.js +2 -0
  404. package/dist/composition/provider/types.js.map +1 -0
  405. package/dist/composition/queue/config.js +2 -0
  406. package/dist/composition/queue/config.js.map +1 -0
  407. package/dist/composition/queue/scheduler.js +2 -0
  408. package/dist/composition/queue/scheduler.js.map +1 -0
  409. package/dist/composition/queue/store.js +2 -0
  410. package/dist/composition/queue/store.js.map +1 -0
  411. package/dist/composition/runtime/config.js +2 -0
  412. package/dist/composition/runtime/config.js.map +1 -0
  413. package/dist/composition/runtime/owner.js +2 -0
  414. package/dist/composition/runtime/owner.js.map +1 -0
  415. package/dist/composition/runtime/public.d.ts +7 -0
  416. package/dist/composition/runtime/public.d.ts.map +1 -0
  417. package/dist/composition/runtime/public.js +2 -0
  418. package/dist/composition/runtime/public.js.map +1 -0
  419. package/dist/composition/runtime/types.d.ts +76 -0
  420. package/dist/composition/runtime/types.d.ts.map +1 -0
  421. package/dist/composition/startup.js +2 -0
  422. package/dist/composition/startup.js.map +1 -0
  423. package/dist/composition/team/config.js +2 -0
  424. package/dist/composition/team/config.js.map +1 -0
  425. package/dist/composition/team/options.js +2 -0
  426. package/dist/composition/team/options.js.map +1 -0
  427. package/dist/composition/team/runtime.js +2 -0
  428. package/dist/composition/team/runtime.js.map +1 -0
  429. package/dist/composition/team/types.d.ts +63 -0
  430. package/dist/composition/team/types.d.ts.map +1 -0
  431. package/dist/composition/tool-source/config.d.ts +5 -0
  432. package/dist/composition/tool-source/config.d.ts.map +1 -0
  433. package/dist/composition/tool-source/config.js +2 -0
  434. package/dist/composition/tool-source/config.js.map +1 -0
  435. package/dist/composition/tool-source/definition.d.ts +7 -0
  436. package/dist/composition/tool-source/definition.d.ts.map +1 -0
  437. package/dist/composition/tool-source/definition.js +2 -0
  438. package/dist/composition/tool-source/definition.js.map +1 -0
  439. package/dist/composition/tool-source/snapshot.js +2 -0
  440. package/dist/composition/tool-source/snapshot.js.map +1 -0
  441. package/dist/contract/adapter.d.ts +91 -0
  442. package/dist/contract/adapter.d.ts.map +1 -0
  443. package/dist/contract/adapter.js +2 -0
  444. package/dist/contract/adapter.js.map +1 -0
  445. package/dist/contract/call-config.d.ts +36 -0
  446. package/dist/contract/call-config.d.ts.map +1 -0
  447. package/dist/contract/call-config.js +2 -0
  448. package/dist/contract/call-config.js.map +1 -0
  449. package/dist/contract/generate-options.d.ts +41 -0
  450. package/dist/contract/generate-options.d.ts.map +1 -0
  451. package/dist/contract/model-info.d.ts +99 -0
  452. package/dist/contract/model-info.d.ts.map +1 -0
  453. package/dist/contract/output-format.d.ts +18 -0
  454. package/dist/contract/output-format.d.ts.map +1 -0
  455. package/dist/contract/retry-policy.d.ts +104 -0
  456. package/dist/contract/retry-policy.d.ts.map +1 -0
  457. package/dist/contract/retry-policy.js +2 -0
  458. package/dist/contract/retry-policy.js.map +1 -0
  459. package/dist/contract/tool.d.ts +65 -0
  460. package/dist/contract/tool.d.ts.map +1 -0
  461. package/dist/contract/tool.js +2 -0
  462. package/dist/contract/tool.js.map +1 -0
  463. package/dist/errors/agent-sdk-error.d.ts +88 -0
  464. package/dist/errors/agent-sdk-error.d.ts.map +1 -0
  465. package/dist/errors/agent-sdk-error.js +2 -0
  466. package/dist/errors/agent-sdk-error.js.map +1 -0
  467. package/dist/errors/capability-identity.d.ts +10 -0
  468. package/dist/errors/capability-identity.d.ts.map +1 -0
  469. package/dist/errors/capability-identity.js +2 -0
  470. package/dist/errors/capability-identity.js.map +1 -0
  471. package/dist/errors/failure.d.ts +33 -0
  472. package/dist/errors/failure.d.ts.map +1 -0
  473. package/dist/errors/failure.js +2 -0
  474. package/dist/errors/failure.js.map +1 -0
  475. package/dist/errors/model-error.d.ts +83 -0
  476. package/dist/errors/model-error.d.ts.map +1 -0
  477. package/dist/errors/model-error.js +2 -0
  478. package/dist/errors/model-error.js.map +1 -0
  479. package/dist/http/api-key.d.ts +47 -0
  480. package/dist/http/api-key.d.ts.map +1 -0
  481. package/dist/http/api-key.js +2 -0
  482. package/dist/http/api-key.js.map +1 -0
  483. package/dist/http/attribution.d.ts +51 -0
  484. package/dist/http/attribution.d.ts.map +1 -0
  485. package/dist/http/attribution.js +2 -0
  486. package/dist/http/attribution.js.map +1 -0
  487. package/dist/index.d.ts +70 -0
  488. package/dist/index.js +1 -0
  489. package/dist/logging/types.d.ts +53 -0
  490. package/dist/logging/types.d.ts.map +1 -0
  491. package/dist/logging/types.js +2 -0
  492. package/dist/logging/types.js.map +1 -0
  493. package/dist/memory.d.ts +10 -0
  494. package/dist/memory.js +1 -0
  495. package/dist/message/content.d.ts +125 -0
  496. package/dist/message/content.d.ts.map +1 -0
  497. package/dist/message/message.d.ts +154 -0
  498. package/dist/message/message.d.ts.map +1 -0
  499. package/dist/message/message.js +2 -0
  500. package/dist/message/message.js.map +1 -0
  501. package/dist/message/projection.d.ts +34 -0
  502. package/dist/message/projection.d.ts.map +1 -0
  503. package/dist/message/projection.js +2 -0
  504. package/dist/message/projection.js.map +1 -0
  505. package/dist/observability/bus.d.ts +7 -0
  506. package/dist/observability/bus.d.ts.map +1 -0
  507. package/dist/observability/bus.js +2 -0
  508. package/dist/observability/bus.js.map +1 -0
  509. package/dist/observability/exporters.d.ts +39 -0
  510. package/dist/observability/exporters.d.ts.map +1 -0
  511. package/dist/observability/exporters.js +2 -0
  512. package/dist/observability/exporters.js.map +1 -0
  513. package/dist/observability/logger.js +2 -0
  514. package/dist/observability/logger.js.map +1 -0
  515. package/dist/observability/projections.d.ts +12 -0
  516. package/dist/observability/projections.d.ts.map +1 -0
  517. package/dist/observability/projections.js +2 -0
  518. package/dist/observability/projections.js.map +1 -0
  519. package/dist/observability/types.d.ts +103 -0
  520. package/dist/observability/types.d.ts.map +1 -0
  521. package/dist/observability.d.ts +20 -0
  522. package/dist/observability.js +1 -0
  523. package/dist/observation/boundaries.js +2 -0
  524. package/dist/observation/boundaries.js.map +1 -0
  525. package/dist/observation/context.d.ts +39 -0
  526. package/dist/observation/context.d.ts.map +1 -0
  527. package/dist/observation/context.js +2 -0
  528. package/dist/observation/context.js.map +1 -0
  529. package/dist/observation/event.d.ts +50 -0
  530. package/dist/observation/event.d.ts.map +1 -0
  531. package/dist/observation/event.js +2 -0
  532. package/dist/observation/event.js.map +1 -0
  533. package/dist/observation/port.d.ts +56 -0
  534. package/dist/observation/port.d.ts.map +1 -0
  535. package/dist/observation/port.js +2 -0
  536. package/dist/observation/port.js.map +1 -0
  537. package/dist/observation/privacy.js +2 -0
  538. package/dist/observation/privacy.js.map +1 -0
  539. package/dist/observation/report.d.ts +117 -0
  540. package/dist/observation/report.d.ts.map +1 -0
  541. package/dist/observation/report.js +2 -0
  542. package/dist/observation/report.js.map +1 -0
  543. package/dist/observation/telemetry-types.d.ts +29 -0
  544. package/dist/observation/telemetry-types.d.ts.map +1 -0
  545. package/dist/observation/usage.d.ts +52 -0
  546. package/dist/observation/usage.d.ts.map +1 -0
  547. package/dist/observation/usage.js +2 -0
  548. package/dist/observation/usage.js.map +1 -0
  549. package/dist/platform/adapter.js +2 -0
  550. package/dist/platform/adapter.js.map +1 -0
  551. package/dist/platform/capability-operation.js +2 -0
  552. package/dist/platform/capability-operation.js.map +1 -0
  553. package/dist/platform/config.js +2 -0
  554. package/dist/platform/config.js.map +1 -0
  555. package/dist/platform/logger-platform.js +2 -0
  556. package/dist/platform/logger-platform.js.map +1 -0
  557. package/dist/platform/resources.js +2 -0
  558. package/dist/platform/resources.js.map +1 -0
  559. package/dist/plugin/provider-plugin.d.ts +37 -0
  560. package/dist/plugin/provider-plugin.d.ts.map +1 -0
  561. package/dist/plugin/provider-plugin.js +2 -0
  562. package/dist/plugin/provider-plugin.js.map +1 -0
  563. package/dist/primitives/brand.d.ts +61 -0
  564. package/dist/primitives/brand.d.ts.map +1 -0
  565. package/dist/primitives/brand.js +2 -0
  566. package/dist/primitives/brand.js.map +1 -0
  567. package/dist/primitives/freeze.d.ts +20 -0
  568. package/dist/primitives/freeze.d.ts.map +1 -0
  569. package/dist/primitives/freeze.js +2 -0
  570. package/dist/primitives/freeze.js.map +1 -0
  571. package/dist/primitives/json-snapshot.js +2 -0
  572. package/dist/primitives/json-snapshot.js.map +1 -0
  573. package/dist/primitives/json.d.ts +32 -0
  574. package/dist/primitives/json.d.ts.map +1 -0
  575. package/dist/primitives/json.js +2 -0
  576. package/dist/primitives/json.js.map +1 -0
  577. package/dist/primitives/never.d.ts +22 -0
  578. package/dist/primitives/never.d.ts.map +1 -0
  579. package/dist/primitives/never.js +2 -0
  580. package/dist/primitives/never.js.map +1 -0
  581. package/dist/primitives/snapshot.d.ts +10 -0
  582. package/dist/primitives/snapshot.d.ts.map +1 -0
  583. package/dist/primitives/snapshot.js +2 -0
  584. package/dist/primitives/snapshot.js.map +1 -0
  585. package/dist/primitives/version.d.ts +6 -0
  586. package/dist/primitives/version.d.ts.map +1 -0
  587. package/dist/primitives/version.js +2 -0
  588. package/dist/primitives/version.js.map +1 -0
  589. package/dist/provider.d.ts +19 -0
  590. package/dist/provider.js +1 -0
  591. package/dist/runtime/model-call-handle.js +2 -0
  592. package/dist/runtime/model-call-handle.js.map +1 -0
  593. package/dist/runtime/model-metadata.js +2 -0
  594. package/dist/runtime/model-metadata.js.map +1 -0
  595. package/dist/runtime/model-stream.js +2 -0
  596. package/dist/runtime/model-stream.js.map +1 -0
  597. package/dist/runtime/registry.d.ts +171 -0
  598. package/dist/runtime/registry.d.ts.map +1 -0
  599. package/dist/runtime/registry.js +2 -0
  600. package/dist/runtime/registry.js.map +1 -0
  601. package/dist/runtime/with-retry.d.ts +45 -0
  602. package/dist/runtime/with-retry.d.ts.map +1 -0
  603. package/dist/runtime/with-retry.js +2 -0
  604. package/dist/runtime/with-retry.js.map +1 -0
  605. package/dist/skills.d.ts +8 -0
  606. package/dist/skills.js +1 -0
  607. package/dist/stream/assembler.d.ts +86 -0
  608. package/dist/stream/assembler.d.ts.map +1 -0
  609. package/dist/stream/assembler.js +2 -0
  610. package/dist/stream/assembler.js.map +1 -0
  611. package/dist/stream/chunk.d.ts +135 -0
  612. package/dist/stream/chunk.d.ts.map +1 -0
  613. package/dist/stream/idle-timeout.d.ts +30 -0
  614. package/dist/stream/idle-timeout.d.ts.map +1 -0
  615. package/dist/stream/idle-timeout.js +2 -0
  616. package/dist/stream/idle-timeout.js.map +1 -0
  617. package/dist/support-safe/error.d.ts +29 -0
  618. package/dist/support-safe/error.d.ts.map +1 -0
  619. package/dist/support-safe/error.js +2 -0
  620. package/dist/support-safe/error.js.map +1 -0
  621. package/dist/tools.d.ts +15 -0
  622. package/dist/tools.js +1 -0
  623. package/package.json +96 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed.js","names":[],"sources":["../../../src/agent/team/managed.ts"],"sourcesContent":["/** Codex-style dynamic worker creation and delegation over AgentTeam. */\n\nimport type { JsonValue } from '../../primitives/index.ts'\nimport { timeoutValue } from '../../platform/config.ts'\nimport { createTextMessage } from '../../message/index.ts'\nimport type { ModelRegistry } from '../../runtime/index.ts'\nimport type { AgentRunEvent } from '../mode/run-agent.ts'\nimport { cloneAgent, type DefinedAgent } from '../define/definition.ts'\nimport {\n type AgentInput,\n type AgentInvocationOptions,\n type AgentResponse,\n type AgentSession,\n type AgentSessionOptions,\n} from '../define/session.ts'\nimport { History, type HistoryEntry, type HistorySnapshot } from '../history/index.ts'\nimport { defineTool, type ToolDefinition } from '../tool/definition.ts'\nimport { ToolRegistry, type ToolCatalog } from '../tool/registry.ts'\nimport { AgentTeam } from './team.ts'\nimport { DEFAULT_WAIT_TIMEOUT_MS } from './common.ts'\nimport type { AgentTeamOptions } from './types.ts'\nimport type { TurnHooks } from '../loop/events.ts'\nimport { waitForSettlement } from '../../async/index.ts'\ntype DetachedSessionOptions = Omit<AgentSessionOptions, 'registry' | 'team' | 'tools'>\n\n/**\n * Default bound on getting one worker RUNNING, overridable per harness with\n * {@link ManagedAgentTeamOptions.spawnTimeoutMs}.\n *\n * Not the worker's deadline — that is `workerTimeoutMs`. This bounds only the\n * setup, so a lead cannot be held for minutes by a call that no longer waits\n * for any work.\n */\nexport const DEFAULT_SPAWN_SETUP_TIMEOUT_MS = 30_000\n\n/** Default bound on stopping one worker; see {@link ManagedAgentTeamOptions.closeTimeoutMs}. */\nexport const DEFAULT_WORKER_CLOSE_TIMEOUT_MS = 30_000\n\n/**\n * Default bound on holding the lead's turn open for news from a worker; see\n * {@link ManagedAgentTeamOptions.holdWaitMs}.\n *\n * Long enough that a lead is not re-prompted about work that has visibly just\n * started, short enough that it keeps control of its own run: at the deadline\n * the turn comes back and the lead decides whether to wait again, close a\n * worker, or answer with what it has.\n */\nexport const DEFAULT_HOLD_WAIT_MS = 15_000\n\n/**\n * What the lead is told about delegating.\n *\n * This used to say little more than \"delegate when it helps\", and the result\n * was a lead that divided AGENTS without dividing WORK. A trace from this\n * project: asked for a todo app built by three agents, it spawned a UI worker,\n * a logic worker and an audit worker in one step, into an empty directory. The\n * audit worker had nothing to review and spent its run inventing a checklist;\n * the other two each discovered the empty directory separately and each decided\n * to scaffold it, one of them announcing it would put the logic in the page\n * component the other had been given. Nothing in the mechanism was broken. The\n * lead had simply never been told what a good division looks like, or that some\n * work has to happen before any division is possible.\n *\n * Both reference implementations answer this in prose rather than with a task\n * graph. Codex's `spawn_agent` description carries sections on when to delegate\n * versus work locally, how to design a subtask, and what to do afterwards; the\n * DeepSeek harness adds a task board where dependencies gate claiming and file\n * hints warn on overlap. Neither offers the model a `depends_on` field. The\n * rules below are that guidance, reduced to the four the trace shows matter:\n *\n * 1. Plan first and name the critical path — delegating before there is\n * anything to delegate is the expensive mistake.\n * 2. Keep the blocking next step local; delegate what runs alongside it.\n * 3. Give each worker a disjoint set of files to write.\n * 4. Do not delegate verification until there is something to verify.\n */\nconst LEAD_INSTRUCTIONS = [\n 'You lead a managed dynamic team. Delegation buys parallelism; it is not a way to distribute a task you have not yet understood.',\n 'PLAN BEFORE YOU DELEGATE. State briefly what the objective needs, which steps block the others, and which can run alongside them, and decide what you will do yourself right now. Only then spawn.',\n 'Do the blocking step yourself. If your very next action depends on a result, producing it locally is faster than delegating it and waiting for it.',\n 'Delegate work that runs alongside your own: concrete, bounded, self-contained, and worth a whole worker.',\n 'GIVE EACH WORKER A DISJOINT SET OF FILES TO WRITE. Declare them in `writes`, and say which in its task. Two workers building different features of one file will each write that file, and the later write erases the earlier one; a spawn that would do this is refused.',\n 'A WORKER THAT ONLY READS DECLARES NOTHING: leave `writes` out. Do not invent a placeholder such as \"none\" or \"/tmp/no-write\" — that claims a real scope, and several readers sharing one stand-in are refused for colliding over a file none of them writes.',\n 'EXPRESS ORDER WITH `dependsOn`, NOT BY SPAWNING LATE. A worker that reviews, integrates, or builds on another names it there: it is created now, held until that work settles, and then given what it produced. Spawn the whole plan in one step and let the order be enforced rather than remembered.',\n 'Do not delegate review, audit or verification against nothing. Either the thing to be reviewed already exists, or the reviewer `dependsOn` whoever is producing it. A reviewer started over an empty workspace produces a checklist, not a review.',\n 'When the work does not exist yet, the first step is yours: establish its shape — scaffold, layout, shared types — and then delegate the independent pieces of it.',\n 'Choose each worker context deliberately: fork when it needs what you have already found out, fresh when its task genuinely stands alone. Given neither, every worker rediscovers the workspace for itself.',\n 'Call spawn_agent several times in one step for work that is genuinely independent, and once for work that is not.',\n 'spawn_agent does not return a result: workers run while you keep working, and each one reports back to you when it finishes.',\n 'After delegating, do useful non-overlapping work. Do not wait by reflex, and do not redo what you delegated.',\n 'Use wait_agents only when you need a result to continue. It returns within its timeout whether or not anyone finished, so read the reported status and decide again.',\n 'Read a finished worker result from list_agents, then call close_agent to release its slot.',\n 'A send_message update or accepted self-check is not the worker final report. Wait for its completed/failed status before normal closure. Use cancelRunning only when deliberately abandoning its unfinished work.',\n 'Never answer as if a worker had reported when it has not; say what is still outstanding instead.',\n 'Synthesize worker results yourself and remain responsible for the final answer.',\n].join(' ')\n\n/**\n * How much of the lead's conversation a new worker starts from.\n *\n * `fresh` is one task and nothing else. `fork` copies the lead's completed\n * conversation so far, so the worker begins already knowing what the lead\n * learned — the state of the workspace, the decisions taken, what the other\n * workers were given.\n *\n * The distinction exists because its absence is expensive in a specific way.\n * With only a task string, every worker re-derives the same context from\n * scratch: three workers spawned into an empty repository each listed the\n * directory, each concluded independently that nothing was there, and each\n * decided on its own to scaffold it. Both reference implementations offer the\n * same choice — Codex as `fork_context`/`fork_turns`, the DeepSeek harness as\n * `context: 'fresh' | 'fork'`, whose naming this follows.\n */\nexport type ManagedAgentSpawnContext = 'fresh' | 'fork'\n\n/**\n * A worker kind the host declares up front.\n *\n * Without a declared set, `specialty` is free text the model invents at the\n * moment it spawns: the harness is handed `\"Code review, accessibility,\n * security và quality audit\"` and can make nothing of it — not that the role\n * reads rather than writes, not that it needs code to exist first. So it\n * cannot help order the work, and the lead is left inventing both the role and\n * its place in the plan in the same breath.\n *\n * Declaring roles turns that into a choice from a list the host wrote, with\n * `whenToUse` stating the precondition in the spawn schema where the lead\n * reads it. Codex does the same thing with `agent_type` and its role registry.\n */\nexport interface ManagedAgentRole {\n /** Referred to by `spawn_agent`; the enum the lead chooses from. */\n readonly name: string\n /** What this role is for. Shown to the lead in the spawn tool schema. */\n readonly description: string\n /** When choosing it is correct — and when it is premature. */\n readonly whenToUse?: string\n /** Added to the worker's own instructions; defaults to `description`. */\n readonly instructions?: string\n}\n\n/** What to do about two workers that would write the same files at once. */\nexport type WriteScopeConflictPolicy = 'reject' | 'warn' | 'off'\n\nexport interface ManagedAgentSpawnRequest {\n /** Optional stable team address; generated as worker_N when omitted. */\n readonly name?: string\n readonly task: string\n /** Short specialization added to the generated worker's instructions. */\n readonly specialty?: string\n /**\n * Context the worker starts from; defaults to\n * {@link ManagedAgentTeamOptions.defaultSpawnContext}.\n */\n readonly context?: ManagedAgentSpawnContext\n /** One of {@link ManagedAgentTeamOptions.roles}, when the host declared any. */\n readonly role?: string\n /**\n * Workers that must finish before this one starts.\n *\n * The harness holds it back until every one of them has settled, and then\n * gives it what they produced. This is the difference between dividing\n * agents and dividing work: a lead can spawn the whole plan in one step —\n * which is what it wants to do — and the ORDER is still respected, because\n * ordering is no longer something the model has to remember to enforce by\n * spawning late.\n *\n * A dependency that fails still releases its dependents, and they are told\n * it failed. Waiting only for success turns one broken worker into a\n * permanently stalled plan.\n */\n readonly dependsOn?: readonly string[]\n /**\n * Files and directories this worker may write, workspace-relative.\n *\n * Declared so the harness can refuse a division that cannot work. Two\n * workers given overlapping scopes with no ordering between them will both\n * write those files, and the later write erases the earlier one — observed\n * as a UI worker announcing it would put its logic in the very page\n * component the logic worker had been assigned.\n */\n readonly writes?: readonly string[]\n}\n\nexport interface ResolvedManagedAgentSpawnRequest extends ManagedAgentSpawnRequest {\n readonly name: string\n readonly context: ManagedAgentSpawnContext\n readonly dependsOn: readonly string[]\n readonly writes: readonly string[]\n}\n\nexport interface ManagedAgentWorkerResult {\n readonly worker: string\n readonly agentId: string\n readonly conversationId: string\n readonly text: string\n readonly succeeded: boolean\n}\n\n/**\n * Where a generated worker is in its life.\n *\n * `completed` and `failed` are final but NOT gone: a finished worker stays\n * addressable and keeps occupying a `maxWorkers` slot until it is closed, so\n * a lead that spawns without closing runs out of workers rather than silently\n * accumulating them.\n */\nexport type ManagedAgentWorkerStatus =\n | 'pending' | 'running' | 'completed' | 'failed' | 'closed'\n\nexport interface ManagedAgentWorker {\n readonly name: string\n readonly agentId: string\n readonly conversationId: string\n readonly task: string\n readonly specialty?: string\n /** Context this worker was started from. */\n readonly context: ManagedAgentSpawnContext\n readonly role?: string\n /** Workers that had to settle before this one could start. */\n readonly dependsOn: readonly string[]\n /** Files this worker declared it would write. */\n readonly writes: readonly string[]\n readonly status: ManagedAgentWorkerStatus\n /** Non-fatal problems with the division of work, e.g. an accepted overlap. */\n readonly warnings?: readonly string[]\n readonly result?: ManagedAgentWorkerResult\n readonly error?: string\n}\n\nexport interface ManagedAgentTeamOptions {\n readonly registry: ModelRegistry\n readonly lead: DefinedAgent\n readonly leadName?: string\n readonly leadDescription?: string\n readonly team?: AgentTeam | AgentTeamOptions\n readonly maxWorkers?: number\n /** Maximum UTF-8 worker task bytes. Defaults to 64 KiB. */\n readonly maxTaskBytes?: number\n /** Maximum UTF-8 specialty bytes. Defaults to 8 KiB. */\n readonly maxSpecialtyBytes?: number\n /**\n * Context a `spawn_agent` call starts a worker from when it does not say.\n * Defaults to `'fresh'`.\n *\n * `'fresh'` is the default because forking is not free: the worker pays for\n * the lead's whole conversation in input tokens on every round it runs, and\n * a worker whose task genuinely stands alone gains nothing for it. A host\n * that knows its workers always operate on the lead's workspace — and so\n * would otherwise watch each of them rediscover it — should set `'fork'`\n * here rather than hope the lead remembers to ask.\n */\n readonly defaultSpawnContext?: ManagedAgentSpawnContext\n /**\n * Worker kinds the lead may choose from, with what each is for.\n *\n * Declaring them replaces free-text `specialty` with an enum, and puts each\n * role's `whenToUse` in the spawn schema — the one place the lead is certain\n * to read before choosing. Leave it unset and `specialty` behaves as before.\n */\n readonly roles?: readonly ManagedAgentRole[]\n /**\n * What to do when a spawn declares `writes` overlapping a worker that would\n * run at the same time. Defaults to `'reject'`.\n *\n * Rejecting is the default because the alternative is silent data loss: both\n * workers write the file and the later write wins. The refusal names the\n * conflicting worker and the overlap, so the lead's available fix — add it\n * to `dependsOn`, or narrow the scope — is visible in the error itself.\n * `'warn'` records it on the worker instead and lets it run; `'off'` skips\n * the check.\n */\n readonly writeScopePolicy?: WriteScopeConflictPolicy\n /**\n * Cap on how much of a dependency's result is handed to its dependents.\n * Defaults to 8 KiB per dependency.\n */\n readonly maxDependencyReportBytes?: number\n /** End-to-end deadline for one generated worker. Defaults to 10 minutes. */\n readonly workerTimeoutMs?: number\n /** Maximum wait per worker event observer callback. Defaults to 1 second. */\n readonly observerTimeoutMs?: number\n /**\n * How long closing one worker waits for it to stop.\n * Defaults to {@link DEFAULT_WORKER_CLOSE_TIMEOUT_MS}.\n *\n * After that its slot is freed regardless. A worker that ignores its\n * cancellation must not be able to hold the harness at its cap forever.\n */\n readonly closeTimeoutMs?: number\n /**\n * How long the lead's turn is held open waiting for a worker to report,\n * before the lead is asked again. Defaults to {@link DEFAULT_HOLD_WAIT_MS}.\n *\n * Zero-length would be a spin: the lead answers, is told its workers are\n * still running, answers again, and burns its budget before any result\n * arrives. Codex blocks the parent inside its `wait_agent` tool for the same\n * reason.\n */\n readonly holdWaitMs?: number\n /** Allow model-invoked close_agent to cancel unfinished work (default true).\n * Host closeWorker, disposal and user cancellation are always available. */\n readonly allowModelWorkerCancellation?: boolean\n /**\n * How long `spawn_agent` may take to get a worker running.\n * Defaults to {@link DEFAULT_SPAWN_SETUP_TIMEOUT_MS}.\n *\n * Only the setup: the worker's own deadline is `workerTimeoutMs`, and how\n * long the lead may WAIT for it is the team's `waitTimeoutMs` — pass it\n * through `team: { waitTimeoutMs }` when building the harness.\n */\n readonly spawnTimeoutMs?: number\n /** Defaults to cloning the lead definition under the generated worker id. */\n readonly workerTemplate?: DefinedAgent\n readonly workerFactory?: (\n request: ResolvedManagedAgentSpawnRequest,\n ) => DefinedAgent | Promise<DefinedAgent>\n readonly leadSessionOptions?: DetachedSessionOptions & { readonly tools?: ToolCatalog | readonly ToolDefinition<any>[] }\n readonly workerSessionOptions?: DetachedSessionOptions & { readonly tools?: ToolCatalog | readonly ToolDefinition<any>[] }\n /** Per-worker runtime dependencies for least-privilege tools and workspace policy. */\n readonly workerSessionOptionsFactory?: (\n request: ResolvedManagedAgentSpawnRequest,\n ) => (DetachedSessionOptions & { readonly tools?: ToolCatalog | readonly ToolDefinition<any>[] })\n | Promise<DetachedSessionOptions & { readonly tools?: ToolCatalog | readonly ToolDefinition<any>[] }>\n /** Observe every generated worker's model, tool, trace, and compaction events. */\n readonly onWorkerEvent?: (\n worker: string,\n event: AgentRunEvent,\n ) => void | Promise<void>\n}\n\ninterface WorkerRuntime {\n readonly request: ResolvedManagedAgentSpawnRequest\n readonly session: AgentSession\n status: ManagedAgentWorkerStatus\n /**\n * Whether the lead's own turn created this worker.\n *\n * It decides who is owed the completion report. A worker the MODEL spawned\n * belongs to a conversation that is waiting for a synthesis, so its report\n * wakes an idle lead. A worker the HOST spawned belongs to the host, which is\n * driving the lead itself; waking it there would start a turn the caller did\n * not ask for.\n */\n readonly leadDriven: boolean\n /**\n * Cancels this worker's run.\n *\n * Owned here rather than by the team: `AgentTeam.cancel` only aborts a\n * team-scheduled wake, not a run a host started itself, so without this a\n * detached worker would survive both `close_agent` and `dispose`.\n */\n readonly controller: AbortController\n /**\n * Set the moment a close begins, before anything is aborted.\n *\n * `status` cannot carry this: it only becomes `'closed'` after the run has\n * settled, so the abort's own rejection arrives while the worker still looks\n * like a running one — and gets reported to the lead as a FAILURE it did not\n * cause and cannot act on.\n */\n closing: boolean\n /**\n * This worker's own deadline, so a run that ended can say WHY.\n *\n * An expired deadline surfaces as an ordinary abort — indistinguishable from\n * a close, or from a cancelled parent — unless the signal that expired is\n * kept and asked. Codex reports a status the parent can branch on; this is\n * what makes one reportable here.\n */\n deadline: AbortSignal | undefined\n /** Resolves when the run has ended and been recorded. Never rejects. */\n settled: Promise<void>\n /**\n * Releases a worker held back by `dependsOn`; undefined once it has started.\n *\n * The team holds the matching promise, so `wait_agents` and `list_agents`\n * report a held worker as `pending` rather than as one that has finished.\n */\n start: (() => void) | undefined\n /** Resolves {@link settled}; called exactly once, whatever ended the worker. */\n readonly markSettled: () => void\n warnings: readonly string[]\n result: ManagedAgentWorkerResult | undefined\n error: string | undefined\n}\n\n/**\n * A dynamic harness whose lead can create specialized workers with spawn_agent.\n *\n * `spawn_agent` blocks the lead for as long as its worker runs, so it declares\n * that blocking to the team as a wait edge. Cycle detection is only as good as\n * the graph it can see: an unrecorded edge does not merely go unchecked, it\n * lets the cycle it completes through, and a worker waiting for the lead that\n * is waiting for it deadlocks both until a timeout.\n *\n * Each worker is a real connected AgentSession and remains addressable afterward.\n */\nexport class ManagedAgentTeam {\n readonly team: AgentTeam\n readonly lead: AgentSession\n readonly leadName: string\n private readonly options: ManagedAgentTeamOptions\n private readonly maxWorkers: number\n private readonly maxTaskBytes: number\n private readonly maxSpecialtyBytes: number\n private readonly workerTimeoutMs: number\n private readonly observerTimeoutMs: number\n private readonly closeTimeoutMs: number\n private readonly holdWaitMs: number\n private readonly spawnTimeoutMs: number\n private readonly workerRuntimes = new Map<string, WorkerRuntime>()\n private readonly reservedNames = new Set<string>()\n private workerSequence = 0\n private readonly maxDependencyReportBytes: number\n private readonly roles: Map<string, ManagedAgentRole>\n\n constructor(options: ManagedAgentTeamOptions) {\n this.options = options\n this.maxWorkers = positiveInteger(options.maxWorkers ?? 7, 'maxWorkers')\n this.maxTaskBytes = positiveInteger(options.maxTaskBytes ?? 64 * 1024, 'maxTaskBytes')\n this.maxSpecialtyBytes = positiveInteger(options.maxSpecialtyBytes ?? 8 * 1024, 'maxSpecialtyBytes')\n this.workerTimeoutMs = timeoutValue(options.workerTimeoutMs ?? 10 * 60_000)\n this.observerTimeoutMs = timeoutValue(options.observerTimeoutMs ?? 1_000)\n this.closeTimeoutMs = timeoutValue(options.closeTimeoutMs ?? DEFAULT_WORKER_CLOSE_TIMEOUT_MS)\n this.holdWaitMs = timeoutValue(options.holdWaitMs ?? DEFAULT_HOLD_WAIT_MS)\n this.spawnTimeoutMs = timeoutValue(options.spawnTimeoutMs ?? DEFAULT_SPAWN_SETUP_TIMEOUT_MS)\n this.maxDependencyReportBytes = positiveInteger(\n options.maxDependencyReportBytes ?? 8 * 1024,\n 'maxDependencyReportBytes',\n )\n this.roles = new Map((options.roles ?? []).map(role => [role.name, role]))\n if (this.roles.size !== (options.roles ?? []).length) {\n throw new Error('managed agent roles contain a duplicate name')\n }\n this.team = options.team instanceof AgentTeam\n ? options.team\n : new AgentTeam({\n ...options.team,\n maxMembers: options.team?.maxMembers ?? this.maxWorkers + 1,\n })\n this.leadName = memberName(options.leadName ?? options.lead.id)\n this.lead = options.lead.createSession({\n ...options.leadSessionOptions,\n hooks: this.leadHooks(options.leadSessionOptions?.hooks),\n registry: options.registry,\n tools: mergeTools(options.leadSessionOptions?.tools, this.controlTools()),\n team: {\n team: this.team,\n name: this.leadName,\n role: 'lead',\n instructions: LEAD_INSTRUCTIONS,\n ...(options.leadDescription === undefined ? {} : { description: options.leadDescription }),\n },\n })\n }\n\n /**\n * Hold the lead's turn open while a worker of its is unfinished.\n *\n * This is Codex's shape, arrived at from the other side: there the parent\n * stays inside its turn and loops on its wait tool until it has what it\n * needs. A lead that concludes while its workers are still running answers\n * from nothing — and once the turn is over, the reports that arrive\n * afterwards have no turn left to be read in, so the work stops with no\n * synthesis at all.\n *\n * `runTurn` re-runs a turn whose `onTurnEnd` hook appended history, so\n * saying so is enough to send the lead round again. Its own step and turn\n * budgets bound this, and `canContinue` leaves an aborted or exhausted turn\n * free to end.\n * @param host - Hooks the host supplied; theirs run first and are kept.\n * @returns The hooks to give the lead's session.\n */\n private leadHooks(host: TurnHooks | undefined): TurnHooks {\n return {\n ...host,\n beforeStep: async (context) => {\n // The request for this round is rebuilt from history, so anything\n // delivered quietly before now is about to be read.\n this.unreadReports = false\n return await host?.beforeStep?.(context) ?? { kind: 'proceed' as const }\n },\n onTurnEnd: async (context) => {\n await host?.onTurnEnd?.(context)\n if (!context.canContinue) {\n // The turn is over and cannot be extended — a spent step budget, an\n // error, a stop. A report that arrived during it has no round left to\n // be read in, and the run would end with the synthesis unwritten, so\n // one more turn is scheduled for when the lead goes idle.\n if (this.unreadReports) {\n this.unreadReports = false\n try { this.team.wake(this.leadName) } catch { /* team disposed */ }\n }\n return\n }\n // Pending counts as busy. A worker held behind `dependsOn` has not\n // started, but it WILL run and report, and a lead that concluded while\n // its dependency chain was still queued answers from work that never\n // reached it.\n const outstanding = [...this.workerRuntimes.values()]\n .filter(runtime => runtime.status === 'running' || runtime.status === 'pending')\n if (outstanding.length === 0) return\n // WAIT for news before spending another model call.\n //\n // Re-prompting immediately is a spin: measured on a real run, a lead\n // with slow researchers answered \"still waiting\" twelve times in half a\n // second and had no budget left when the results finally arrived. Codex\n // has the parent block inside `wait_agent` until a mailbox update\n // arrives or a deadline passes; the DeepSeek harness starts the next\n // round only when there is something to start it for. This is the same\n // shape from inside the hook: the turn stays open, costing nothing,\n // until a worker reports or the wait expires.\n await this.awaitWorkerNews(outstanding)\n const busy = [...this.workerRuntimes.values()]\n .filter(runtime => runtime.status === 'running' || runtime.status === 'pending')\n .map(runtime => runtime.request.name)\n if (busy.length === 0) {\n this.lead.inject(\n 'Every worker has reported. Read their results and write the answer you owe the'\n + ' user; do not delegate again unless something is genuinely missing.',\n )\n return\n }\n this.lead.inject(\n `Not finished: ${busy.join(', ')} ${busy.length === 1 ? 'is' : 'are'} still running. `\n + 'Use wait_agents to wait for them and read their results, or close_agent with cancelRunning: true to '\n + 'give up on one. Do not present a conclusion that depends on work they have '\n + 'not reported yet.',\n )\n },\n }\n }\n\n /** Run the lead. It decides whether and how many workers to create. */\n run(input: AgentInput, invocation: AgentInvocationOptions = {}): Promise<AgentResponse> {\n return this.lead.run(input, invocation)\n }\n\n /**\n * Add a message to the lead's context, and make sure something reads it.\n *\n * Injection alone is enough only while the lead is mid-turn: its next model\n * round rebuilds the request from history and picks the message up. Once the\n * lead has answered and is only waiting on its workers, an injected message\n * sits in history with nothing scheduled to read it — which is what happened\n * to a user who typed a correction while the researchers were still running\n * and never got an answer to it. Idle, the lead is scheduled one turn.\n * @param text - What the user said.\n * @returns True; the message is always accepted.\n */\n steer(text: string): boolean {\n this.lead.inject(text)\n // Ends a wait the lead is parked in, so the correction is read now rather\n // than after its wait budget expires.\n try { this.team.notifySteer(this.leadName) } catch { /* team disposed */ }\n if (!this.lead.isRunning) {\n try { this.team.wake(this.leadName) } catch { /* team disposed */ }\n }\n return true\n }\n\n /** Host-side equivalent of the model's spawn_agent tool. */\n /**\n * Create a worker and start it, WITHOUT waiting for it.\n *\n * Returns as soon as the worker is running. Use {@link awaitWorker} for its\n * result, {@link workers} for its status, or let the worker's completion\n * notification reach the lead on its own.\n * @param request - Task, and optionally a name and a specialty.\n * @param signal - Cancels the setup, not the worker's run.\n * @returns The worker, in its `running` state.\n */\n async spawn(\n request: ManagedAgentSpawnRequest,\n signal?: AbortSignal,\n ): Promise<ManagedAgentWorker> {\n signal?.throwIfAborted()\n const resolved: ResolvedManagedAgentSpawnRequest = {\n name: memberName(request.name ?? this.nextWorkerName()),\n task: boundedString(request.task, 'worker task', this.maxTaskBytes),\n ...(request.specialty === undefined\n ? {}\n : { specialty: boundedString(request.specialty, 'worker specialty', this.maxSpecialtyBytes) }),\n context: request.context ?? this.options.defaultSpawnContext ?? 'fresh',\n ...(request.role === undefined ? {} : { role: this.requireRole(request.role) }),\n dependsOn: this.resolveDependencies(request.dependsOn ?? []),\n writes: [...new Set((request.writes ?? []).map(normalizeWriteScope))],\n }\n if (this.workerRuntimes.size + this.reservedNames.size >= this.maxWorkers) {\n throw new Error(`managed agent team reached its ${this.maxWorkers}-worker limit`)\n }\n if (this.reservedNames.has(resolved.name) || this.workerRuntimes.has(resolved.name)\n || this.team.members().some(member => member.name === resolved.name)) {\n throw new Error(`managed worker '${resolved.name}' already exists`)\n }\n\n this.reservedNames.add(resolved.name)\n let runtime: WorkerRuntime | undefined\n try {\n const warnings = this.checkWriteScopes(resolved)\n const operationSignal = combineSignals(signal, AbortSignal.timeout(this.workerTimeoutMs))\n const definition = await abortable(this.workerDefinition(resolved), operationSignal)\n operationSignal.throwIfAborted()\n const scopedSessionOptions = this.options.workerSessionOptionsFactory === undefined\n ? undefined\n : await abortable(Promise.resolve(this.options.workerSessionOptionsFactory(resolved)), operationSignal)\n operationSignal.throwIfAborted()\n const session = definition.createSession({\n ...this.options.workerSessionOptions,\n ...scopedSessionOptions,\n ...(resolved.context === 'fork' ? { history: this.forkLeadHistory() } : {}),\n registry: this.options.registry,\n team: {\n team: this.team,\n name: resolved.name,\n role: 'peer',\n // A worker exists to finish one task and hand back a result, so it\n // gets no verb that can block it or push work elsewhere. With them\n // it has no stopping point: a worker wanting guidance messages a\n // peer and then waits, and only a cancellation ends its run.\n tools: 'reporting',\n instructions: [\n `You are a dynamically created worker reporting to '${this.leadName}'.`,\n 'Complete the delegated task independently and return a concise evidence-backed result.',\n 'Do not broaden the task or attempt to become team lead.',\n // Observed in a real run: a worker called send_message on its own\n // name, which is refused, because it read the tool as the way to\n // report. Reporting is what finishing already does.\n `Your result is delivered to '${this.leadName}' when you finish, so do not use send_message to report it; that tool is only for passing context to a DIFFERENT worker, never to yourself.`,\n 'If you lack information, state what is missing in your result rather than waiting for an answer.',\n ].join(' '),\n ...(resolved.specialty === undefined ? {} : { description: resolved.specialty }),\n },\n })\n const controller = new AbortController()\n let markSettled!: () => void\n runtime = {\n request: resolved,\n session,\n status: 'pending',\n leadDriven: this.lead.isRunning,\n closing: false,\n deadline: undefined,\n controller,\n settled: new Promise<void>((resolve) => { markSettled = resolve }),\n markSettled,\n start: undefined,\n warnings,\n result: undefined,\n error: undefined,\n }\n this.workerRuntimes.set(resolved.name, runtime)\n this.reservedNames.delete(resolved.name)\n\n await this.team.sendMessage({\n from: this.leadName,\n target: resolved.name,\n message: resolved.task,\n delivery: 'quiet',\n signal: operationSignal,\n })\n if (definition.memory.autoCaptureObjective) {\n session.memory.captureOriginalObjective(createTextMessage(resolved.task))\n }\n\n if (resolved.dependsOn.length > 0 && !this.dependenciesSettled(resolved.dependsOn)) {\n // Held, not started. The promise handed to the team is what makes the\n // wait honest: without it `wait_agents` asks an idle session whether it\n // is finished, is told yes, and the lead reads a worker that never ran\n // as one that had nothing to report.\n const held = new Promise<void>((resolve) => { runtime!.start = resolve })\n this.team.markPending(resolved.name, held)\n return this.workerView(runtime)\n }\n this.beginWorker(runtime)\n return this.workerView(runtime)\n } catch (error: unknown) {\n if (runtime !== undefined) {\n runtime.status = 'failed'\n runtime.error = errorMessage(error)\n runtime.start = undefined\n runtime.markSettled()\n }\n throw error\n } finally {\n this.reservedNames.delete(resolved.name)\n }\n }\n\n /**\n * Put a worker on the model, at last.\n *\n * Separate from `spawn` because a worker with dependencies is created now and\n * started later; the two used to be the same moment.\n */\n private beginWorker(runtime: WorkerRuntime): void {\n const name = runtime.request.name\n runtime.start?.()\n runtime.start = undefined\n this.team.markPending(name, undefined)\n // Closed while it was held: there is nothing left to start, and starting it\n // anyway would resurrect a worker the lead had already let go.\n if (runtime.status !== 'pending') return\n runtime.status = 'running'\n\n // Started, NOT awaited. `runPending` begins the run eagerly and\n // synchronously, so by the time this returns the worker is genuinely\n // going; the promise is simply left for `followWorker` to watch.\n // Awaiting it in `spawn` is what blinded the lead: parked inside its own\n // tool call it could not read the worker's messages, could not spawn\n // anything else, and could not be told that the worker had gone quiet.\n //\n // `runPending` rather than `streamPending`, and that is load-bearing:\n // `onEvent` is delivered by the consumer `runPending` wraps around the\n // handle, so a bare `streamPending` starts the run and reports NOTHING.\n // Every worker event is lost with it — including the approval requests a\n // worker parks on, which leaves it waiting for an answer nobody was ever\n // shown, and the run hangs.\n const deadline = AbortSignal.timeout(this.workerTimeoutMs)\n runtime.deadline = deadline\n const running = runtime.session.runPending({\n signal: combineSignals(runtime.controller.signal, deadline),\n ...(this.options.onWorkerEvent === undefined\n ? {}\n : { onEvent: (event: AgentRunEvent) => this.observeWorkerEvent(name, event) }),\n })\n void this.followWorker(runtime, running)\n }\n\n /**\n * The `role` parameter, when the host declared any roles.\n *\n * Each role's purpose and precondition go in the description, which is where\n * Codex puts its role registry too: the lead is choosing a role at the\n * moment it reads this, so this is the only place the guidance can arrive in\n * time to change the choice.\n * @returns A one-property object to spread, or nothing.\n */\n private roleSchema(): Record<string, unknown> {\n if (this.roles.size === 0) return {}\n const lines = [...this.roles.values()].map(role =>\n `- ${role.name}: ${role.description}`\n + (role.whenToUse === undefined ? '' : ` Use when: ${role.whenToUse}`))\n return {\n role: {\n type: 'string',\n enum: [...this.roles.keys()],\n description: `Which kind of worker this is.\\n${lines.join('\\n')}`,\n },\n }\n }\n\n /** Resolve a declared role name, or say which ones exist. */\n private requireRole(name: unknown): string {\n const value = nonEmpty(name, 'worker role')\n if (this.roles.size === 0) {\n throw new Error('this managed team declares no roles, so spawn_agent takes no role')\n }\n if (!this.roles.has(value)) {\n throw new Error(\n `unknown worker role '${value}'; declared roles are ${[...this.roles.keys()].join(', ')}`,\n )\n }\n return value\n }\n\n /**\n * Check the named dependencies and return them deduplicated.\n *\n * A dependency can only name a worker that already exists, and a new worker\n * is not yet nameable by anything, so the graph cannot contain a cycle by\n * construction — no cycle check is needed here, and a `dependsOn` that could\n * name a future worker would need one.\n */\n private resolveDependencies(names: readonly string[]): readonly string[] {\n return [...new Set(names.map((name) => {\n const address = memberName(name)\n if (!this.workerRuntimes.has(address)) {\n throw new Error(\n `unknown dependency '${address}'; a worker can only depend on one that already exists`,\n )\n }\n return address\n }))]\n }\n\n /**\n * Judge a new worker's write scopes against the ones already in flight.\n *\n * Only workers that could run AT THE SAME TIME conflict. One that this\n * worker depends on, directly or through others, writes its files before\n * this one begins, so sharing a scope with it is ordinary sequential work —\n * and is in fact the fix the refusal points at.\n * @param request - The resolved spawn request.\n * @returns Warnings to record; throws instead under the `reject` policy.\n */\n private checkWriteScopes(request: ResolvedManagedAgentSpawnRequest): readonly string[] {\n const policy = this.options.writeScopePolicy ?? 'reject'\n if (policy === 'off' || request.writes.length === 0) return []\n const ancestors = this.ancestorsOf(request.dependsOn)\n const found: string[] = []\n for (const other of this.workerRuntimes.values()) {\n if (other.status !== 'pending' && other.status !== 'running') continue\n if (ancestors.has(other.request.name)) continue\n const clash = request.writes.filter(mine =>\n other.request.writes.some(theirs => scopesOverlap(mine, theirs)))\n if (clash.length === 0) continue\n const detail = `'${other.request.name}' also writes ${clash.join(', ')}`\n if (policy === 'reject') {\n throw new Error(\n `worker '${request.name}' would write files another running worker writes: ${detail}.`\n + ` Add '${other.request.name}' to dependsOn so it runs after, or narrow the scopes`\n // Observed in a real run: four read-only researchers each declared the\n // same placeholder scope and collided over a file none of them would\n // ever write. The refusal used to offer only dependsOn and narrowing,\n // which sends a worker that writes nothing looking for a better fake\n // path instead of dropping the field.\n + ' — or omit writes entirely if this worker only reads.',\n )\n }\n found.push(detail)\n }\n return found\n }\n\n /**\n * Say what actually happened to a worker, in words the lead can act on.\n *\n * A raw abort reads \"The operation was aborted due to timeout\", which tells\n * the lead nothing about WHOSE timeout or whether re-delegating would help.\n * Codex reports a status the parent can branch on; the DeepSeek harness\n * records a blocker code with an explanation. This is the same idea at the\n * size this harness needs.\n * @param error - Whatever ended the run.\n * @returns The explanation to record and report.\n */\n private describeWorkerFailure(error: unknown, runtime: WorkerRuntime | undefined): string {\n if (runtime?.deadline?.aborted === true) return this.deadlineFailure()\n const name = (error as { name?: unknown } | null)?.name\n if (name === 'TimeoutError') return this.deadlineFailure()\n if (name === 'AbortError') return 'its work was cancelled before it finished'\n return errorMessage(error)\n }\n\n /** The one explanation an expired worker deadline deserves. */\n private deadlineFailure(): string {\n return `it ran past its ${String(this.workerTimeoutMs)}ms deadline without finishing.`\n + ' Narrow the task, or split it, before delegating it again'\n }\n\n /**\n * Block until a worker reports, or the hold deadline passes.\n *\n * Bounded on purpose. An unbounded wait would hand the whole run's liveness to\n * the slowest worker and, since this runs inside a turn hook, would be cut off\n * by the hook timeout rather than by anything that understands the work. When\n * it expires the lead gets its turn back and decides for itself — wait again\n * with `wait_agents`, close one, or answer with what it has.\n * @param outstanding - Workers that have not settled.\n */\n private async awaitWorkerNews(outstanding: readonly WorkerRuntime[]): Promise<void> {\n let timer: ReturnType<typeof setTimeout> | undefined\n const deadline = new Promise<void>((resolve) => {\n timer = setTimeout(resolve, this.holdWaitMs)\n // A timer must never be the reason a process stays alive. Node exposes\n // `unref`; a browser timer has no such handle and needs none.\n ;(timer as unknown as { unref?: () => void }).unref?.()\n })\n try {\n await Promise.race([...outstanding.map(runtime => runtime.settled), deadline])\n } finally {\n if (timer !== undefined) clearTimeout(timer)\n }\n }\n\n /** Every worker reachable through `dependsOn`, transitively. */\n private ancestorsOf(names: readonly string[], seen = new Set<string>()): Set<string> {\n for (const name of names) {\n if (seen.has(name)) continue\n seen.add(name)\n const runtime = this.workerRuntimes.get(name)\n if (runtime !== undefined) this.ancestorsOf(runtime.request.dependsOn, seen)\n }\n return seen\n }\n\n /** Whether every named worker has reached a final state. */\n private dependenciesSettled(names: readonly string[]): boolean {\n return names.every((name) => {\n const runtime = this.workerRuntimes.get(name)\n // Gone means closed and detached: settled, and no longer able to report.\n return runtime === undefined || SETTLED_WORKER_STATUS.has(runtime.status)\n })\n }\n\n /**\n * Start whatever was waiting on the worker that just settled.\n *\n * Dependents are released when their dependencies SETTLE, not when they\n * succeed. Requiring success would let one failed worker strand every step\n * planned after it, and a plan that stalls silently is worse than one whose\n * later stages are told the earlier ones broke — which is exactly what they\n * are told: each dependent starts with what its dependencies produced.\n */\n private async releaseDependents(finished: string): Promise<void> {\n const ready = [...this.workerRuntimes.values()].filter(runtime =>\n runtime.status === 'pending'\n && runtime.request.dependsOn.includes(finished)\n && this.dependenciesSettled(runtime.request.dependsOn))\n for (const runtime of ready) {\n const report = this.dependencyReport(runtime.request.dependsOn)\n if (report !== undefined) {\n try {\n await this.team.sendMessage({\n from: this.leadName,\n target: runtime.request.name,\n message: report,\n delivery: 'quiet',\n })\n } catch {\n // A worker that cannot be told what came before it is still better\n // started than stranded; its own task stands on its own.\n }\n }\n this.beginWorker(runtime)\n }\n }\n\n /** What the dependencies produced, as context for a dependent about to start. */\n private dependencyReport(names: readonly string[]): string | undefined {\n const lines = names.map((name) => {\n const runtime = this.workerRuntimes.get(name)\n if (runtime === undefined) return `- ${name}: closed before reporting.`\n if (runtime.error !== undefined) {\n const partial = runtime.result?.text\n return `- ${name} FAILED: ${runtime.error}`\n + (partial ? `\\nPartial findings (not a completed task): ${truncate(partial, this.maxDependencyReportBytes)}` : '')\n }\n const text = runtime.result?.text ?? ''\n return `- ${name} finished: ${truncate(text, this.maxDependencyReportBytes)}`\n })\n if (lines.length === 0) return undefined\n return [\n 'Work you depend on has finished. Its results follow; build on them rather than redoing them.',\n ...lines,\n ].join('\\n')\n }\n\n /**\n * Watch a detached worker run to its end and report it.\n *\n * Never rejects: the run has no awaiting caller, so a throw here would be an\n * unhandled rejection. Failures are recorded on the runtime and told to the\n * lead instead, which is the same shape `AgentTeam.runWakeLoop` uses for the\n * other kind of un-awaited member run.\n */\n private async followWorker(\n runtime: WorkerRuntime,\n running: Promise<AgentResponse>,\n ): Promise<void> {\n const name = runtime.request.name\n try {\n const response = await running\n if (runtime.status !== 'closed' && !runtime.closing) {\n // A run that RESOLVES has not necessarily succeeded: a model call that\n // failed ends the turn with an error reason and an empty answer. Read\n // as a success it became \"Worker 'x' finished:\" with nothing after the\n // colon — the lead told a sector was done by a worker that never got\n // an answer out of the model, which is worse than being told nothing.\n const failure = runtime.deadline?.aborted === true\n ? this.deadlineFailure()\n : failureOf(response)\n if (failure !== undefined) {\n runtime.status = 'failed'\n runtime.error = failure\n // A failed final request must not erase evidence already returned.\n // Preserve partial output, but never report it as successful work.\n if (response.text.trim() !== '') {\n runtime.result = Object.freeze({\n worker: name,\n agentId: runtime.session.definition.id,\n conversationId: runtime.session.conversationId,\n text: response.text,\n succeeded: false,\n })\n }\n this.team.recordOutcome(name, { kind: 'failed', message: failure })\n await this.notifyLead(name, `failed: ${failure}`\n + (runtime.result === undefined ? '' : `\\nPartial findings (not a completed task): ${runtime.result.text}`))\n } else {\n runtime.status = 'completed'\n runtime.result = Object.freeze({\n worker: name,\n agentId: runtime.session.definition.id,\n conversationId: runtime.session.conversationId,\n text: response.text,\n succeeded: response.outcome.completed,\n })\n this.team.recordOutcome(name, { kind: 'completed', text: response.text })\n await this.notifyLead(name, `finished: ${response.text}`)\n }\n }\n } catch (error: unknown) {\n // A close is not a failure. Reporting the abort it caused would tell the\n // lead its own decision went wrong, and — once a report can wake an idle\n // lead — would start a turn about a worker it deliberately abandoned.\n if (runtime.status !== 'closed' && !runtime.closing) {\n runtime.status = 'failed'\n runtime.error = this.describeWorkerFailure(error, runtime)\n this.team.recordOutcome(name, { kind: 'failed', message: runtime.error })\n await this.notifyLead(name, `failed: ${runtime.error}`)\n }\n } finally {\n runtime.markSettled()\n // Whatever ended this worker — success, failure, or a close — the work\n // planned after it is no longer waiting on anything.\n await this.releaseDependents(name)\n }\n }\n\n /**\n * Tell the lead what one of its workers did.\n *\n * Quiet WHILE THE LEAD IS STILL IN ITS TURN: the report appends to history\n * and the next model round rebuilds its request from history, so the lead\n * reads it without an extra turn being scheduled. Holding that turn open is\n * {@link leadHooks}'s job.\n *\n * A wake-up once the lead has gone idle, because then nothing else will ever\n * read the report. The hold cannot cover every case — a turn that ended on\n * its step budget, or on an error, is not eligible to continue, and a worker\n * that outlives the run reports into a conversation with no turn left. That\n * is the failure this exists for: the transcript ends on a worker's own\n * output, and the synthesis the lead was there to write never happens. One\n * more turn is the point, not a duplicate answer.\n */\n private async notifyLead(worker: string, summary: string): Promise<void> {\n const delivery = this.deliveryFor(worker)\n // A quiet report is a bet that the lead's next model round will read it.\n // Cleared by `beforeStep`, which is that round; still set at the end of a\n // turn that cannot continue, it means the bet lost and nobody ever will.\n if (delivery === 'quiet') this.unreadReports = true\n try {\n await this.team.sendMessage({\n from: worker,\n target: this.leadName,\n message: `Worker '${worker}' ${summary}`,\n delivery,\n })\n } catch {\n // The lead may already be gone, or the team disposed. A worker's report\n // is not worth failing anything else over; `workers()` still has it.\n }\n }\n\n /**\n * Quiet into an open turn, a wake-up into an idle conversation.\n * @param worker - The worker whose report is being delivered.\n * @returns The delivery the report needs to actually be read.\n */\n private deliveryFor(worker: string): 'quiet' | 'wakeup' {\n // Mid-turn: the next model round rebuilds its request from history, so the\n // report is read without scheduling anything.\n if (this.lead.isRunning) return 'quiet'\n // Idle, and the host is driving: waking would start a turn it did not ask\n // for, and it can read the result from `workers()` whenever it likes.\n if (this.workerRuntimes.get(worker)?.leadDriven !== true) return 'quiet'\n return 'wakeup'\n }\n\n /** Set when a worker report was delivered quietly and no round has read it. */\n private unreadReports = false\n\n /**\n * Wait until no worker is outstanding and the lead has nothing left to do.\n *\n * The roster cannot answer this on its own. A worker's last event fires\n * before its run resolves, and its completion report — the thing that wakes\n * the lead — is delivered after that. For the moment in between, every member\n * looks idle: a caller watching the roster sees a finished team and stops\n * listening, exactly as the synthesis is about to be written. Waiting here\n * covers that gap, because a worker's `settled` resolves only once its report\n * has been delivered.\n * @param signal - Gives up waiting; the work itself is not cancelled.\n */\n async whenQuiet(signal?: AbortSignal): Promise<void> {\n for (;;) {\n signal?.throwIfAborted()\n const outstanding = [...this.workerRuntimes.values()]\n .filter(runtime => runtime.status === 'pending' || runtime.status === 'running')\n if (outstanding.length > 0) await Promise.all(outstanding.map(runtime => runtime.settled))\n await this.team.whenIdle(this.leadName, signal)\n const busy = [...this.workerRuntimes.values()]\n .some(runtime => runtime.status === 'pending' || runtime.status === 'running')\n if (!busy) return\n }\n }\n\n /** Current detached worker lifecycle view. */\n workers(): readonly ManagedAgentWorker[] {\n return Object.freeze([...this.workerRuntimes.values()].map(runtime => this.workerView(runtime)))\n }\n\n private workerView(runtime: WorkerRuntime): ManagedAgentWorker {\n return Object.freeze({\n name: runtime.request.name,\n agentId: runtime.session.definition.id,\n conversationId: runtime.session.conversationId,\n task: runtime.request.task,\n status: runtime.status,\n context: runtime.request.context,\n dependsOn: runtime.request.dependsOn,\n writes: runtime.request.writes,\n ...(runtime.request.role === undefined ? {} : { role: runtime.request.role }),\n ...(runtime.warnings.length === 0 ? {} : { warnings: runtime.warnings }),\n ...(runtime.request.specialty === undefined ? {} : { specialty: runtime.request.specialty }),\n ...(runtime.result === undefined ? {} : { result: runtime.result }),\n ...(runtime.error === undefined ? {} : { error: runtime.error }),\n })\n }\n\n /**\n * Wait for one worker to finish, for at most `timeoutMs`.\n *\n * Bounded on purpose. An unbounded wait is how a host loses the ability to\n * tell a slow worker from a stuck one; a caller that gets `undefined` back\n * still holds every other option.\n * @param name - Worker address.\n * @param options - Budget, default {@link DEFAULT_WAIT_TIMEOUT_MS}, and a signal.\n * @returns Its result, or undefined if it had not finished in time.\n */\n async awaitWorker(\n name: string,\n options: { readonly timeoutMs?: number; readonly signal?: AbortSignal } = {},\n ): Promise<ManagedAgentWorkerResult | undefined> {\n const address = memberName(name)\n const runtime = this.workerRuntimes.get(address)\n if (runtime === undefined) throw new Error(`unknown managed worker '${address}'`)\n const budget = timeoutValue(options.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS)\n // The timer is cleared either way: a worker that finishes early must not\n // leave one pending, which in a long-lived host is a slow leak.\n let timer: ReturnType<typeof setTimeout> | undefined\n const deadline = new Promise<void>((resolve) => { timer = setTimeout(resolve, budget) })\n try {\n await Promise.race([runtime.settled, deadline])\n } finally {\n clearTimeout(timer)\n }\n options.signal?.throwIfAborted()\n return runtime.result\n }\n\n /**\n * Stop a worker and give up its slot.\n *\n * This is the stopping point a delegated agent otherwise lacks. A worker that\n * has already finished is still occupying a `maxWorkers` slot, so closing is\n * how a lead makes room for the next one.\n * @param name - Worker address.\n * @param reason - Cancellation reason for a worker still running.\n * @returns The status it held before being closed.\n */\n async closeWorker(\n name: string,\n reason: unknown = new Error('managed worker closed'),\n ): Promise<ManagedAgentWorkerStatus> {\n const address = memberName(name)\n const runtime = this.workerRuntimes.get(address)\n if (runtime === undefined) throw new Error(`unknown managed worker '${address}'`)\n const previous = runtime.status\n runtime.closing = true\n runtime.controller.abort(reason)\n // The controller only governs the run THIS harness started. A worker the\n // lead reached with followup_task, or any wake-up delivery, is running\n // under the team's own scheduler, and aborting the harness controller does\n // nothing to it: observed in a real run, a closed worker kept calling the\n // model for another fourteen seconds and submitted its result after the\n // lead had already answered, so the conversation ended on the worker's\n // output instead of the lead's synthesis.\n try {\n await this.team.cancel(address, reason)\n } catch {\n // A cancellation that times out must not wedge the close: the slot is\n // freed either way, exactly as it is for a run that ignores its signal.\n }\n if (previous === 'pending') {\n // Never started, so there is no run to wait for — and `settled` would\n // never resolve on its own, because nothing is going to end.\n runtime.status = 'closed'\n runtime.start = undefined\n this.team.markPending(address, undefined)\n runtime.markSettled()\n } else {\n // Waited for, but not indefinitely, and a worker that ignores its signal\n // does not get to wedge the harness: the slot is freed either way. The\n // wait is what usually lets `detach` succeed, since it refuses a member\n // whose session is still running.\n await waitForSettlement(runtime.settled, this.closeTimeoutMs)\n runtime.status = 'closed'\n }\n this.workerRuntimes.delete(address)\n try { this.team.detach(address) } catch { /* already gone, or the team is disposed */ }\n // Closing is a settlement too: work planned after this worker must not be\n // left waiting on one the lead has abandoned.\n await this.releaseDependents(address)\n return previous\n }\n\n /**\n * Stop every worker this harness started.\n *\n * Workers outlive the lead's turn by design, so something has to end them:\n * without this a detached run would keep calling the model after the host had\n * moved on. Disposing the underlying `AgentTeam` is left to whoever owns it.\n * @param reason - Cancellation reason handed to each worker.\n */\n async dispose(reason: unknown = new Error('managed agent team disposed')): Promise<void> {\n const names = [...this.workerRuntimes.keys()]\n await Promise.allSettled(names.map(name => this.closeWorker(name, reason)))\n }\n\n /** Remove one idle generated worker from the harness and shared roster. */\n removeWorker(name: string): void {\n const address = memberName(name)\n const runtime = this.workerRuntimes.get(address)\n if (runtime === undefined) throw new Error(`unknown managed worker '${address}'`)\n if (runtime.status === 'running' || runtime.session.isRunning) {\n throw new Error(`cannot remove running managed worker '${address}'`)\n }\n this.team.detach(address)\n this.workerRuntimes.delete(address)\n }\n\n private controlTools(): readonly ToolDefinition<any>[] {\n return Object.freeze([\n defineTool({\n name: 'spawn_agent',\n description: [\n 'Create a connected specialist worker and start one task on it.',\n 'Returns as soon as the worker is running, WITHOUT its result: keep working,',\n 'and you will be told when it finishes. Use wait_agents to pause for it,',\n 'list_agents to read its status and result, and close_agent when done with it.',\n 'Before the first call, plan: name the step that blocks the others and do that',\n 'one yourself. Then spawn the rest of the plan in one step: declare each',\n 'worker\\'s `writes` so two never write the same file, and use `dependsOn` for',\n 'anything that must follow another worker rather than waiting to spawn it.',\n ].join(' '),\n parameters: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: 'Optional unique worker address; omitted generates worker_N.',\n },\n task: {\n type: 'string',\n description: 'Concrete bounded task assigned to the worker.'\n + ' State which files it owns and may write, so two workers never write the same one.',\n },\n specialty: {\n type: 'string',\n description: 'Optional worker role or domain specialization.',\n },\n context: {\n type: 'string',\n enum: ['fresh', 'fork'],\n description: 'fresh starts the worker from its task alone;'\n + ' fork also gives it your conversation so far, so it does not have to'\n + ' rediscover what you already established. Prefer fork when the task'\n + ' depends on findings of yours.',\n },\n dependsOn: {\n type: 'array',\n items: { type: 'string' },\n description: 'Names of workers that must finish before this one starts.'\n + ' The worker is created now and held until they do, then given what they'\n + ' produced — so spawn the whole plan at once and express the ORDER here'\n + ' rather than by spawning later. Use it for anything that reviews,'\n + ' integrates or builds on another worker.',\n },\n writes: {\n type: 'array',\n items: { type: 'string' },\n description: 'Files and directories this worker may write, workspace-relative.'\n + ' A spawn that would write what another worker running at the same time'\n + ' writes is refused, because both would write it and the later write wins.'\n + ' Declare them and the conflict is caught before any work is lost.'\n + ' OMIT this entirely for a worker that only reads — a stand-in path such'\n + ' as \"none\" or \"/tmp/no-write\" claims a real scope, and several readers'\n + ' sharing that stand-in collide with each other over a file none of them'\n + ' will ever write.',\n },\n ...this.roleSchema(),\n },\n required: ['task'],\n additionalProperties: false,\n },\n parse: parseSpawnTool,\n execute: async (request, context) => asJson(await this.spawn(request, context.signal)),\n // Seconds, not the worker's whole deadline: this call only starts the\n // worker now. Leaving it at workerTimeoutMs would let a stuck SETUP\n // hold the lead for ten minutes.\n timeoutMs: this.spawnTimeoutMs,\n isConcurrencySafe: () => true,\n }),\n defineTool({\n name: 'close_agent',\n budgetExempt: true,\n description: [\n 'Close a worker you no longer need and free its slot.',\n 'A finished worker still occupies one until closed, so close it once you have read its result.',\n 'A running or pending worker is kept alive by default so it can finish its final report.',\n this.options.allowModelWorkerCancellation === false\n ? 'The host requires worker reports: you cannot cancel unfinished workers. Wait for their result.'\n : 'Set cancelRunning: true only to deliberately abandon unfinished work and cancel it.',\n 'Returns the status it held before closing.',\n ].join(' '),\n parameters: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Worker address returned by spawn_agent.' },\n cancelRunning: { type: 'boolean', description: 'Explicitly cancel an unfinished worker. Defaults to false.' },\n },\n required: ['name'],\n additionalProperties: false,\n },\n parse: parseCloseTool,\n execute: async ({ name, cancelRunning }) => {\n const runtime = this.workerRuntimes.get(name)\n if (runtime !== undefined && (!cancelRunning || this.options.allowModelWorkerCancellation === false)\n && (runtime.status === 'pending' || runtime.status === 'running' || runtime.session.isRunning)) {\n return asJson({\n worker: name, closed: false,\n status: runtime.status === 'pending' ? 'pending' : 'running',\n instruction: 'The worker has not finished its final report. Use wait_agents and read its completed result before closing.'\n + (this.options.allowModelWorkerCancellation === false ? ' Model cancellation is disabled by the host.'\n : ' To deliberately abandon this work, call close_agent with cancelRunning: true.'),\n })\n }\n return asJson({ worker: name, closed: true, previousStatus: await this.closeWorker(name) })\n },\n timeoutMs: this.workerTimeoutMs,\n }),\n ])\n }\n\n /**\n * Build the history a `fork` worker starts from.\n *\n * Limits come from the WORKER's session options, not the lead's: this is the\n * worker's own history from here on, and it is the worker's configured\n * ceiling that has to hold it.\n * @returns The lead's completed conversation as a fresh history.\n */\n private forkLeadHistory(): History {\n const entries = completedHistoryPrefix(this.lead.snapshot().history)\n return History.fromSnapshot(\n { version: 1, entries },\n this.options.workerSessionOptions?.historyLimits ?? {},\n )\n }\n\n private async workerDefinition(\n request: ResolvedManagedAgentSpawnRequest,\n ): Promise<DefinedAgent> {\n if (this.options.workerFactory !== undefined) return this.options.workerFactory(request)\n const template = this.options.workerTemplate ?? this.options.lead\n const role = request.role === undefined ? undefined : this.roles.get(request.role)\n const roleText = role === undefined\n ? ''\n : ` You are the '${role.name}' worker. ${role.instructions ?? role.description}`\n const specialty = request.specialty === undefined\n ? ''\n : ` Your specialization is: ${request.specialty}.`\n return cloneAgent(template, {\n id: request.name,\n name: request.name,\n instructions: `${template.instructions}\\n\\nYou are dynamically assigned worker '${request.name}'.${roleText}${specialty}`,\n })\n }\n\n private nextWorkerName(): string {\n while (true) {\n const candidate = `worker_${++this.workerSequence}`\n if (!this.reservedNames.has(candidate) && !this.workerRuntimes.has(candidate)\n && !this.team.members().some(member => member.name === candidate)) return candidate\n }\n }\n\n private async observeWorkerEvent(worker: string, event: AgentRunEvent): Promise<void> {\n const observer = Promise.resolve().then(() => this.options.onWorkerEvent?.(worker, event))\n await waitForSettlement(observer, this.observerTimeoutMs)\n }\n}\n\nexport function createManagedAgentTeam(options: ManagedAgentTeamOptions): ManagedAgentTeam {\n return new ManagedAgentTeam(options)\n}\n\nfunction mergeTools(\n supplied: ToolCatalog | readonly ToolDefinition<any>[] | undefined,\n generated: readonly ToolDefinition<any>[],\n): ToolRegistry {\n const registry = new ToolRegistry()\n if (supplied !== undefined) {\n const tools = 'names' in supplied\n ? supplied.names().map(name => supplied.get(name))\n .filter((tool): tool is ToolDefinition => tool !== undefined)\n : supplied\n for (const tool of tools) registry.register(tool)\n }\n for (const tool of generated) registry.register(tool)\n return registry\n}\n\nfunction parseCloseTool(value: unknown): { name: string; cancelRunning: boolean } {\n const input = object(value, 'close_agent arguments')\n if (Object.keys(input).some(key => key !== 'name' && key !== 'cancelRunning')) {\n throw new TypeError('close_agent arguments contain unknown fields')\n }\n if (input.cancelRunning !== undefined && typeof input.cancelRunning !== 'boolean') {\n throw new TypeError('close_agent cancelRunning must be a boolean')\n }\n return { name: memberName(input.name), cancelRunning: input.cancelRunning === true }\n}\n\nfunction parseSpawnTool(value: unknown): ManagedAgentSpawnRequest {\n const input = object(value, 'spawn_agent arguments')\n const known = new Set([\n 'name', 'task', 'specialty', 'context', 'role', 'dependsOn', 'writes',\n ])\n if (Object.keys(input).some(key => !known.has(key))) {\n throw new TypeError('spawn_agent arguments contain unknown fields')\n }\n return {\n task: nonEmpty(input.task, 'worker task'),\n ...(input.name === undefined ? {} : { name: memberName(input.name) }),\n ...(input.specialty === undefined\n ? {}\n : { specialty: nonEmpty(input.specialty, 'worker specialty') }),\n ...(input.context === undefined ? {} : { context: spawnContext(input.context) }),\n ...(input.role === undefined ? {} : { role: nonEmpty(input.role, 'worker role') }),\n ...(input.dependsOn === undefined\n ? {}\n : { dependsOn: stringArray(input.dependsOn, 'dependsOn') }),\n ...(input.writes === undefined ? {} : { writes: stringArray(input.writes, 'writes') }),\n }\n}\n\nfunction stringArray(value: unknown, label: string): readonly string[] {\n if (!Array.isArray(value)) throw new TypeError(`${label} must be an array of strings`)\n return value.map(entry => nonEmpty(entry, `${label} entry`))\n}\n\nfunction spawnContext(value: unknown): ManagedAgentSpawnContext {\n if (value !== 'fresh' && value !== 'fork') {\n throw new TypeError(\"worker context must be 'fresh' or 'fork'\")\n }\n return value\n}\n\n/**\n * Copy the lead's conversation up to the last point it was complete.\n *\n * The lead is INSIDE a turn when it calls `spawn_agent`: the assistant message\n * carrying that very call is already in history, and its result cannot be,\n * because producing it is what this code is doing. Handing that tail to a\n * worker gives it a conversation ending in an unanswered tool call — which\n * providers reject, and which would turn a context optimisation into a spawn\n * that fails outright.\n *\n * So the fork is cut at the last position where no tool call was outstanding.\n * That is also the honest boundary in meaning: work still in flight is not yet\n * something the lead knows. The DeepSeek harness names the same rule a\n * \"completed-turn prefix\".\n *\n * A prefix is safe to hydrate as a history in its own right: `replace` surface\n * ops and compaction records only ever reference earlier entries, so cutting\n * from the end cannot orphan a reference.\n * @param snapshot - The lead's history, taken mid-turn.\n * @returns Entries up to that boundary; empty when nothing has completed.\n */\nexport function completedHistoryPrefix(\n snapshot: HistorySnapshot,\n): readonly HistoryEntry[] {\n const pending = new Set<string>()\n let cut = 0\n snapshot.entries.forEach((entry, index) => {\n const event = entry.event\n if (event.kind === 'tool-call') pending.add(event.callId)\n else if (event.kind === 'tool-result') pending.delete(event.callId)\n else if (event.kind === 'assistant') {\n // The assistant MESSAGE carries its own tool-call blocks, separately from\n // the `tool-call` events beside it. Counting only the events left the\n // spawn call in the fork, complete with the synthetic \"interrupted before\n // a result was recorded\" error the request builder pairs it with — the\n // worker's first sight of its lead being that it had just failed.\n for (const block of event.message.content) {\n if (block.type === 'tool-call') pending.add(block.id)\n }\n }\n // An interrupted assistant message is a turn that never finished; treating\n // it as settled context would hand a worker a half-formed intention.\n const settled = pending.size === 0\n && !(event.kind === 'assistant' && event.interrupted === true)\n if (settled) cut = index + 1\n })\n return snapshot.entries.slice(0, cut)\n}\n\nfunction object(value: unknown, label: string): Record<string, unknown> {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n throw new TypeError(`${label} must be an object`)\n }\n return value as Record<string, unknown>\n}\n\nfunction memberName(value: unknown): string {\n const name = nonEmpty(value, 'managed agent name')\n if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(name)) {\n throw new TypeError('managed agent name must start with a letter and contain only letters, digits, _ or -')\n }\n if (name.length > 128) throw new TypeError('managed agent name must not exceed 128 characters')\n return name\n}\n\nfunction nonEmpty(value: unknown, label: string): string {\n if (typeof value !== 'string' || value.trim().length === 0) {\n throw new TypeError(`${label} must be a non-empty string`)\n }\n return value\n}\n\nfunction boundedString(value: unknown, label: string, maxBytes: number): string {\n const text = nonEmpty(value, label)\n if (new TextEncoder().encode(text).byteLength > maxBytes) {\n throw new TypeError(`${label} exceeds the ${maxBytes}-byte limit`)\n }\n return text\n}\n\nfunction positiveInteger(value: number, label: string): number {\n if (!Number.isSafeInteger(value) || value < 1) throw new TypeError(`${label} must be a positive integer`)\n return value\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nasync function abortable<T>(promise: Promise<T>, signal: AbortSignal): Promise<T> {\n if (signal.aborted) throw signal.reason ?? new Error('managed worker aborted')\n return await new Promise<T>((resolve, reject) => {\n const abort = () => {\n signal.removeEventListener('abort', abort)\n reject(signal.reason ?? new Error('managed worker aborted'))\n }\n signal.addEventListener('abort', abort, { once: true })\n void promise.then(\n value => { signal.removeEventListener('abort', abort); resolve(value) },\n error => { signal.removeEventListener('abort', abort); reject(error) },\n )\n })\n}\n\nfunction combineSignals(...signals: readonly (AbortSignal | undefined)[]): AbortSignal {\n const active = signals.filter((candidate): candidate is AbortSignal => candidate !== undefined)\n return active.length === 1 ? active[0]! : AbortSignal.any(active)\n}\n\nfunction asJson(value: unknown): JsonValue { return value as JsonValue }\n\n/** Worker states that will never change again on their own. */\nconst SETTLED_WORKER_STATUS: ReadonlySet<ManagedAgentWorkerStatus> =\n new Set<ManagedAgentWorkerStatus>(['completed', 'failed', 'closed'])\n\n/**\n * Reduce one declared write scope to a comparable path.\n *\n * Comparison is by path component, so the shapes that mean the same directory\n * have to arrive spelled the same way: `./app/`, `app`, and `app\\` all name\n * `app`, and a worker writing `app/page.tsx` conflicts with one writing `app`.\n */\n/**\n * Why a worker's run did not produce an answer, if it did not.\n *\n * A rejected run is obvious; a run that ends on an error reason is not, because\n * it resolves like any other. Both leave the lead with nothing to read, so both\n * are failures as far as the report is concerned.\n * @param response - What the worker's run returned.\n * @returns The failure to report, or undefined when the worker actually answered.\n */\nfunction failureOf(response: AgentResponse): string | undefined {\n const reason = response.outcome.reason\n if (reason.kind === 'error') return reason.failure.message\n if (reason.kind === 'max-tokens') return 'the model stopped at its output limit'\n if (reason.kind === 'usage-unavailable') return 'the provider reported no usage for a billed call'\n if (reason.kind === 'aborted') return 'the run was aborted'\n if (reason.kind === 'budget-exhausted' && !response.outcome.completed) {\n return `the run stopped at its ${reason.budget} limit before completing the task`\n }\n // An empty answer from an otherwise clean run is still nothing to synthesize.\n if (response.text.trim() === '') return 'it produced no answer'\n return undefined\n}\n\nfunction normalizeWriteScope(value: unknown): string {\n const text = nonEmpty(value, 'worker write scope').trim().split('\\\\').join('/')\n const trimmed = text.replace(/^\\.?\\/+/, '').replace(/\\/+$/, '')\n if (trimmed.length === 0 || trimmed === '.') {\n throw new TypeError('a worker write scope must name a file or directory, not the whole workspace')\n }\n return trimmed\n}\n\n/** Whether two normalized scopes cover any of the same files. */\nfunction scopesOverlap(left: string, right: string): boolean {\n return left === right || left.startsWith(`${right}/`) || right.startsWith(`${left}/`)\n}\n\n/** Cut text to a byte budget without splitting a UTF-16 surrogate pair. */\nfunction truncate(text: string, maxBytes: number): string {\n const encoded = new TextEncoder().encode(text)\n if (encoded.byteLength <= maxBytes) return text\n const kept = new TextDecoder('utf-8', { fatal: false })\n .decode(encoded.subarray(0, maxBytes))\n .replace(/�$/, '')\n return `${kept}… (truncated)`\n}\n"],"mappings":"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"}
@@ -0,0 +1,142 @@
1
+ import { ContentBlock } from "../../message/content.js";
2
+ import { ToolDefinition } from "../tool/definition.js";
3
+ import { TeamMemberAttachmentOptions, TeamPort, TeamSessionPort, TeamToolAccess } from "./contracts.js";
4
+ import { AgentMemberOutcome, AgentMessageRecord, AgentTeamMember, AgentTeamOptions, LinkAgentOptions, SendAgentMessageRequest, SendAgentMessageResult } from "./types.js";
5
+ //#region src/agent/team/team.d.ts
6
+ /**
7
+ * Connect long-lived local AgentSessions and remote protocol peers behind one
8
+ * roster and one model-facing messaging surface.
9
+ */
10
+ declare class AgentTeam implements TeamPort {
11
+ private readonly ownRemoteTask?;
12
+ readonly id: string;
13
+ private readonly maxMembers;
14
+ private readonly maxMessageBytes;
15
+ private readonly maxLinkedResultBytes;
16
+ private readonly maxMessages;
17
+ private readonly maxMailboxBytes;
18
+ private readonly maxMetadataBytes;
19
+ private readonly disposeTimeoutMs;
20
+ private readonly operationTimeoutMs;
21
+ private readonly observerTimeoutMs;
22
+ private readonly waitTimeoutMs;
23
+ private readonly minWaitTimeoutMs;
24
+ private onEvent;
25
+ private onAgentEvent;
26
+ private readonly roster;
27
+ private readonly links;
28
+ private readonly mailbox;
29
+ private mailboxBytes;
30
+ private pendingMessages;
31
+ private pendingMailboxBytes;
32
+ private readonly lifecycle;
33
+ private readonly waitEdges;
34
+ private disposed;
35
+ private disposeTask;
36
+ constructor(options?: AgentTeamOptions, ownRemoteTask?: ((signal: AbortSignal) => () => void) | undefined);
37
+ /** Called by AgentSession after its tool catalog is assembled. */
38
+ attach(session: TeamSessionPort, options?: TeamMemberAttachmentOptions): void;
39
+ /** Link one remote transport, including an official A2A protocol client. */
40
+ linkAgent(options: LinkAgentOptions): () => void;
41
+ /** Remove exactly one idle local session registration. */
42
+ detach(name: string): void;
43
+ /** Current detached roster: local members first, then remote links. */
44
+ members(): readonly AgentTeamMember[];
45
+ /** Immutable audit log. Local target history remains its resumable receipt. */
46
+ messages(): readonly AgentMessageRecord[];
47
+ /** Deliver to a local mailbox or dispatch through a linked remote transport. */
48
+ sendMessage(request: SendAgentMessageRequest): Promise<SendAgentMessageResult>;
49
+ /** Wake-up alias used by hosts and model tools. */
50
+ followup(from: string, target: string, message: string | readonly ContentBlock[], signal?: AbortSignal): Promise<SendAgentMessageResult>;
51
+ /** Wait until all local wake-up work or remote dispatches settle. */
52
+ whenIdle(name: string, signal?: AbortSignal): Promise<void>;
53
+ /**
54
+ * Report that the user steered something into a local member mid-turn.
55
+ *
56
+ * Ends whatever that member is currently waiting on. A member parked in
57
+ * `wait_agents` would otherwise finish its budget before reading a correction
58
+ * that has been sitting in its history the whole time; Codex ends its
59
+ * `wait_agent` early on steered input for the same reason.
60
+ * @param name - Local member address.
61
+ */
62
+ notifySteer(name: string): void;
63
+ /**
64
+ * Schedule one turn for a local member over context it already has.
65
+ *
66
+ * A wake-up delivery carries a message; this carries nothing. It exists for
67
+ * the case where the context arrived earlier and quietly — appended to a
68
+ * member that was mid-turn, on the assumption its next model round would read
69
+ * it — and that round never came. Without this the message sits in history
70
+ * with nothing left to read it.
71
+ * @param name - Local member address.
72
+ */
73
+ wake(name: string): void;
74
+ /** Cancel team-owned scheduled work for one member without mutating its history. */
75
+ cancel(name: string, reason?: unknown): Promise<void>;
76
+ /** Permanently close this control plane and cancel every team-owned operation. */
77
+ dispose(reason?: unknown): Promise<void>;
78
+ /** Model-facing tools bound to one immutable local sender identity. */
79
+ toolsFor(sender: string, access?: TeamToolAccess): readonly ToolDefinition<any>[];
80
+ /** Identity and routing semantics added to each attached member's system text. */
81
+ instructionsFor(name: string): string;
82
+ private dispatchRemote;
83
+ private scheduleWake;
84
+ private runWakeLoop;
85
+ private requireLocalMember;
86
+ /**
87
+ * Record that `sender` is blocked until `targets` are idle.
88
+ *
89
+ * The `wait_agents` tool calls this, and so must any HOST that blocks one
90
+ * member on another. An unrecorded edge is invisible here, which is worse
91
+ * than having no detection at all: the cycle it completes gets waved through,
92
+ * and both sides then wait for each other until a timeout expires.
93
+ *
94
+ * `spawn_agent` used to be such a host — it awaited the worker it created —
95
+ * and needed an edge declared for it. It no longer waits, so the cycle it
96
+ * could close no longer exists.
97
+ * @param sender - The member that will block.
98
+ * @param targets - Members it is waiting for.
99
+ * @returns A release; call it when the wait ends, however it ends.
100
+ * @throws `TEAM_WAIT_CYCLE` when the wait would close a cycle.
101
+ */
102
+ beginWait(sender: string, targets: readonly string[]): () => void;
103
+ private hasWaitPath;
104
+ private requireAddress;
105
+ private assertAddressAvailable;
106
+ private assertCapacity;
107
+ private assertActive;
108
+ private reserveMailbox;
109
+ /**
110
+ * Record how a member's run ended.
111
+ *
112
+ * For a host that starts a member's run itself and therefore owns the result
113
+ * the member's own bookkeeping never sees — `spawn_agent` running a worker
114
+ * concurrently. Without this the roster could report that a worker had
115
+ * stopped but not what it concluded, which is the whole point of asking.
116
+ * @param name - Member address.
117
+ * @param outcome - How the run ended.
118
+ */
119
+ recordOutcome(name: string, outcome: AgentMemberOutcome): void;
120
+ /**
121
+ * Declare that a member exists but has deliberately not been started.
122
+ *
123
+ * A host that orders work — starting one member only once another has
124
+ * finished — needs the roster to say so, and `wait_agents` to believe it. A
125
+ * member whose session has never run looks exactly like one that has
126
+ * finished: idle, not running, nothing outstanding. A coordinator told that
127
+ * would wait on it, be answered at once, read no outcome, and conclude the
128
+ * work was done.
129
+ *
130
+ * The promise is what `whenIdle` waits on, so the pending state cannot be a
131
+ * flag that a waiter has to poll.
132
+ * @param name - Local member address.
133
+ * @param until - Resolves when the host starts it; undefined clears the state.
134
+ */
135
+ markPending(name: string, until: Promise<void> | undefined): void;
136
+ private view;
137
+ private emit;
138
+ private observeAgentEvent;
139
+ }
140
+ //#endregion
141
+ export { AgentTeam };
142
+ //# sourceMappingURL=team.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team.d.ts","names":[],"sources":["../../../src/agent/team/team.ts"],"mappings":";;;;;;;;;cA6Ea,qBAAqB;mBA4Bb;WA3BV;mBACQ;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;mBACA;UACT;UACA;mBACS;mBACA;mBACA;UACT;UACA;UACA;mBACS;mBACA;UACT;UACA;EAER,YACE,UAAS,kBACQ,kBAAiB,QAAQ;;EA2B5C,OAAO,SAAS,iBAAiB,UAAS;;EA2B1C,UAAU,SAAS;;EAyBnB,OAAO;;EAUP,oBAAoB;;EAQpB,qBAAqB;;EAKf,YAAY,SAAS,0BAA0B,QAAQ;;EA4E7D,SACE,cACA,gBACA,2BAA2B,gBAC3B,SAAS,cACR,QAAQ;;EAQL,SAAS,cAAc,SAAS,cAAc;;;;;;;;;;EAoCpD,YAAY;;;;;;;;;;;EAiBZ,KAAK;;EAMC,OAAO,cAAc,mBAA2D;;EA2BtF,QAAQ,mBAAmD;;EAmC3D,SAAS,gBAAgB,SAAQ,0BAAmC;;EA0IpE,gBAAgB;UAuBF;UA+CN;UAmBM;UAiDN;;;;;;;;;;;;;;;;;EAuBR,UAAU,gBAAgB;UA2BlB;UAUA;UAOA;UAMA;UAMA;UAIA;;;;;;;;;;;EA4BR,cAAc,cAAc,SAAS;;;;;;;;;;;;;;;;EAqBrC,YAAY,cAAc,OAAO;UAIzB;UA2BA;UAIM"}
@@ -0,0 +1,2 @@
1
+ import{waitForSettlement as e}from"../../async/settlement.js";import{timeoutValue as t}from"../../platform/config.js";import{AgentSdkError as n}from"../../errors/agent-sdk-error.js";import{createUserMessage as r}from"../../message/message.js";import{defineTool as i}from"../tool/definition.js";import{TEAM_TOOL_NAMES as a,abortable as o,asJson as s,boundedString as c,byteLength as l,combineSignals as u,deepCloneFreeze as d,emptyObject as f,errorMessage as p,memberName as m,messageContent as h,messageToolSchema as g,newMessageId as _,newTeamId as v,parseMessageTool as y,parseWaitTool as b,positiveInteger as x,withTimeout as S}from"./common.js";var C=class{ownRemoteTask;id;maxMembers;maxMessageBytes;maxLinkedResultBytes;maxMessages;maxMailboxBytes;maxMetadataBytes;disposeTimeoutMs;operationTimeoutMs;observerTimeoutMs;waitTimeoutMs;minWaitTimeoutMs;onEvent;onAgentEvent;roster=new Map;links=new Map;mailbox=[];mailboxBytes=0;pendingMessages=0;pendingMailboxBytes=0;lifecycle=new AbortController;waitEdges=new Map;disposed=!1;disposeTask;constructor(e={},n){this.ownRemoteTask=n,this.id=c(e.id??v(),`team id`,1024),this.maxMembers=x(e.maxMembers??8,`maxMembers`),this.maxMessageBytes=x(e.maxMessageBytes??65536,`maxMessageBytes`),this.maxLinkedResultBytes=x(e.maxLinkedResultBytes??1048576,`maxLinkedResultBytes`),this.maxMessages=x(e.maxMessages??1e4,`maxMessages`),this.maxMailboxBytes=x(e.maxMailboxBytes??67108864,`maxMailboxBytes`),this.maxMetadataBytes=x(e.maxMetadataBytes??8192,`maxMetadataBytes`),this.disposeTimeoutMs=t(e.disposeTimeoutMs??3e4),this.operationTimeoutMs=t(e.operationTimeoutMs??6e5),this.observerTimeoutMs=t(e.observerTimeoutMs??1e3),this.waitTimeoutMs=t(e.waitTimeoutMs??3e4),this.minWaitTimeoutMs=Math.min(t(e.minWaitTimeoutMs??5e3),this.waitTimeoutMs),this.onEvent=e.onEvent,this.onAgentEvent=e.onAgentEvent}attach(e,t={}){this.assertActive();let n=m(t.name??e.definition.id);this.assertAddressAvailable(n),this.assertCapacity();let r=t.role??(this.roster.size===0?`lead`:`peer`);if(r===`lead`&&[...this.roster.values()].some(e=>e.role===`lead`))throw Error(`A2A team '${this.id}' already has a lead`);let i={kind:`local`,name:n,role:r,access:t.tools===`reporting`?`reporting`:`full`,session:e,wakeRequestedSeq:0,wakeConsumedSeq:0,wakeTask:void 0,wakeController:void 0,error:void 0,outcome:void 0,pendingStart:void 0,steerController:void 0,...t.description===void 0?{}:{description:c(t.description,`member description`,this.maxMetadataBytes)},...t.instructions===void 0?{}:{instructions:c(t.instructions,`member instructions`,this.maxMetadataBytes)}};this.roster.set(n,i),this.emit({type:`member-attached`,member:this.view(i)})}linkAgent(e){this.assertActive();let t=m(e.name);if(this.assertAddressAvailable(t),this.assertCapacity(),typeof e.transport?.send!=`function`)throw TypeError(`linked agent transport must implement send()`);let n={kind:`remote`,name:t,role:`peer`,transport:e.transport,tail:Promise.resolve(),pending:0,controllers:new Set,error:void 0,...e.description===void 0?{}:{description:c(e.description,`linked agent description`,this.maxMetadataBytes)}};return this.links.set(t,n),this.emit({type:`member-linked`,member:this.view(n)}),()=>{if(this.links.get(t)===n){if(n.pending>0)throw Error(`cannot unlink running A2A member '${t}'`);this.links.delete(t)}}}detach(e){this.assertActive();let t=this.requireLocalMember(e);if(t.session.isRunning||t.wakeTask!==void 0)throw Error(`cannot detach running A2A member '${t.name}'`);this.roster.delete(t.name)}members(){return Object.freeze([...this.roster.values(),...this.links.values()].map(e=>this.view(e)))}messages(){return d(this.mailbox)}async sendMessage(e){this.assertActive(),e.signal?.throwIfAborted();let t=this.requireLocalMember(e.from),n=this.requireAddress(e.target);if(n.kind===`local`&&t===n)throw Error(`an A2A member cannot message itself`);let i=e.delivery??`quiet`;if(i!==`quiet`&&i!==`wakeup`)throw TypeError(`A2A delivery must be 'quiet' or 'wakeup'`);if(n.kind===`remote`&&i===`quiet`)throw Error(`remote A2A member '${n.name}' cannot accept quiet injection; use followup_task or delivery 'wakeup'`);let a=_(),o=h(e.message,this.maxMessageBytes),s=d([{type:`text`,text:`A2A message ${a} from ${t.name}:`},...o]),c=l(s);if(c>this.maxMessageBytes)throw Error(`A2A message exceeds the ${this.maxMessageBytes}-byte limit`);let u=n.kind===`remote`?c+this.maxLinkedResultBytes:c,f=this.reserveMailbox(u),p;try{if(n.kind===`local`){let e=r({source:{kind:`agent-message`,teamId:this.id,messageId:a,sender:t.name,senderAgentId:t.session.definition.id},content:s}),o=n.session.inject(e);i===`wakeup`&&this.scheduleWake(n,o)}else p=await this.dispatchRemote(n,{teamId:this.id,messageId:a,sender:t.name,senderAgentId:t.session.definition.id,content:s,...e.signal===void 0?{}:{signal:e.signal}});let o=d({id:a,teamId:this.id,sender:t.name,senderAgentId:t.session.definition.id,target:n.name,targetAgentId:n.kind===`local`?n.session.definition.id:n.transport.agentId,delivery:i,content:s,status:`accepted`,createdAt:new Date().toISOString(),...p===void 0?{}:{result:p}}),u=c+(p===void 0?0:l(p));return this.mailbox.push(o),this.mailboxBytes+=u,this.emit({type:`message-accepted`,message:d(o)}),d({messageId:a,status:`accepted`,delivery:i,target:n.name,...p===void 0?{}:{result:p}})}finally{f()}}followup(e,t,n,r){return this.sendMessage({from:e,target:t,message:n,delivery:`wakeup`,...r===void 0?{}:{signal:r}})}async whenIdle(e,t){let n=this.requireAddress(e);if(n.kind===`remote`){for(;;){let e=n.tail;if(await o(e,t),e===n.tail&&n.pending===0)break}return}for(;;){let e=n.wakeRequestedSeq,r=n.wakeTask,i=n.pendingStart;if(i!==void 0&&await o(i,t),r!==void 0&&await o(r,t),await n.session.whenIdle(t),n.wakeTask===void 0&&!n.session.isRunning&&n.pendingStart===void 0&&n.wakeConsumedSeq>=n.wakeRequestedSeq&&e===n.wakeRequestedSeq)return}}notifySteer(e){let t=this.requireLocalMember(e),n=t.steerController;t.steerController=void 0,n?.abort(Error(`user input steered into the active turn`))}wake(e){let t=this.requireLocalMember(e);this.scheduleWake(t,t.wakeRequestedSeq+1)}async cancel(e,t=Error(`A2A member work cancelled`)){let n=this.requireAddress(e);if(n.kind===`remote`){for(let e of n.controllers)e.abort(t);await S(n.tail,this.disposeTimeoutMs,`A2A member '${n.name}' did not cancel within ${this.disposeTimeoutMs}ms`,`TEAM_CANCELLATION_TIMEOUT`);return}n.wakeConsumedSeq=n.wakeRequestedSeq;let r=n.wakeController,i=n.wakeTask;r?.abort(t),i!==void 0&&await S(i,this.disposeTimeoutMs,`A2A member '${n.name}' did not cancel within ${this.disposeTimeoutMs}ms`,`TEAM_CANCELLATION_TIMEOUT`)}dispose(e=Error(`A2A team disposed`)){if(this.disposeTask!==void 0)return this.disposeTask;this.disposed=!0,this.lifecycle.abort(e);let t=Promise.allSettled([...[...this.roster.values()].map(t=>this.cancel(t.name,e)),...[...this.links.values()].map(t=>this.cancel(t.name,e))]).then(e=>{this.roster.clear(),this.links.clear(),this.emit({type:`team-disposed`,teamId:this.id}),this.mailbox.length=0,this.mailboxBytes=0,this.waitEdges.clear(),this.onEvent=void 0,this.onAgentEvent=void 0;let t=e.find(e=>e.status===`rejected`);if(t!==void 0)throw new n(`A2A team '${this.id}' did not dispose within ${this.disposeTimeoutMs}ms`,`TEAM_DISPOSE_TIMEOUT`,{cause:t.reason})});return this.disposeTask=S(t,this.disposeTimeoutMs,`A2A team '${this.id}' did not dispose within ${this.disposeTimeoutMs}ms`,`TEAM_DISPOSE_TIMEOUT`),this.disposeTask}toolsFor(e,n=`full`){this.assertActive();let r=m(e),o=n===`full`;return Object.freeze([i({name:a.list,budgetExempt:!0,description:`List local and remote addressable agents, their protocols, supported delivery modes, and status.`,parameters:{type:`object`,properties:{},additionalProperties:!1},parse:e=>f(e,`list_agents`),execute:()=>s(this.members()),isConcurrencySafe:()=>!0}),i({name:a.send,budgetExempt:!0,description:`Inject quiet context into ANOTHER local agent without starting it. Name a target from list_agents other than yourself; your own result already goes back to whoever started you, so reporting does not need this tool. Remote A2A peers require followup_task.`,parameters:g(`Message to add to the target context.`),parse:y,execute:async({target:e,message:t},n)=>s(await this.sendMessage({from:r,target:e,message:t,delivery:`quiet`,signal:n.signal}))}),...o?[i({name:a.followup,budgetExempt:!0,description:`Send active work to a local agent or interoperable remote A2A peer and wait for its accepted result.`,parameters:g(`Follow-up instruction the target must process.`),parse:y,execute:async({target:e,message:t},n)=>s(await this.followup(r,e,t,n.signal))})]:[],...o?[i({name:a.wait,budgetExempt:!0,description:`Wait until one of the selected local or remote agents finishes its scheduled work, then return their current roster state. Returns early with interrupted=true when the user sends you something while you wait, so read that before waiting again.`,parameters:{type:`object`,properties:{targets:{type:`array`,items:{type:`string`},minItems:1,description:`Exact agent names returned by list_agents.`},timeoutMs:{type:`number`,description:`Give up after this long and report instead, default ${String(this.waitTimeoutMs)}. Anything under ${String(this.minWaitTimeoutMs)} is raised to it: a wait too short to finish anything costs a model round and returns the roster unchanged.`}},required:[`targets`],additionalProperties:!1},parse:b,execute:async({targets:n,timeoutMs:i},a)=>{let o=this.beginWait(r,n),c=i===void 0?this.waitTimeoutMs:Math.min(Math.max(t(i),this.minWaitTimeoutMs),this.waitTimeoutMs);try{let t=new AbortController,r=this.roster.get(m(e));r!==void 0&&(r.steerController=t);let i=u(a.signal,AbortSignal.timeout(c),t.signal),o,l=new Promise(e=>{o=setTimeout(()=>e(void 0),c)}),d=new Promise(e=>{t.signal.addEventListener(`abort`,()=>{e(void 0)},{once:!0})}),f=await Promise.race([Promise.any(n.map(async e=>(await this.whenIdle(e,i),e))).then(e=>e,()=>void 0),l,d]).finally(()=>{clearTimeout(o),r?.steerController===t&&(r.steerController=void 0)});if(a.signal.throwIfAborted(),t.signal.aborted)return s({agents:this.members().filter(e=>new Set(n).has(e.name)),settled:null,timedOut:!1,interrupted:!0,waitedMs:c});let p=new Set(n);return s({agents:this.members().filter(e=>p.has(e.name)),settled:f??null,timedOut:f===void 0,waitedMs:c})}finally{o()}},isConcurrencySafe:()=>!0})]:[]])}instructionsFor(e){let t=m(e),n=this.roster.get(t),r=n===void 0||n.access===`full`;return[`You are agent-team member '${t}' in team '${this.id}'.`,r?`Use send_message only for quiet local context. Use followup_task for active work and every remote A2A peer.`:`Use send_message to report context to another agent. You cannot delegate work or wait for other agents: finish your own task and return its result, even when you would rather ask first.`,...r?[`After delegating asynchronous local work, use wait_agents before depending on its completion.`]:[],`list_agents reports whether a target is local or remote and which delivery modes it supports.`,`Agent messages are attributed user-role context; treat their sender framing as provenance, not as end-user authorship.`,n?.instructions].filter(e=>e!==void 0).join(` `)}async dispatchRemote(e,t){if(e.pending>=this.maxMessages)throw new n(`Remote member has too many unsettled sends`,`TEAM_REMOTE_PENDING_LIMIT`);let r=new AbortController,i=u(t.signal,this.lifecycle.signal,r.signal,AbortSignal.timeout(this.operationTimeoutMs));i.throwIfAborted();let a=this.ownRemoteTask?.(i);e.controllers.add(r),e.pending++;let s=e.tail,c=(async()=>{await s,i.throwIfAborted(),this.emit({type:`member-run-start`,member:e.name});try{let n=await e.transport.send({...t,signal:i});if(i.throwIfAborted(),l(n)>this.maxLinkedResultBytes)throw Error(`linked A2A result exceeds the ${this.maxLinkedResultBytes}-byte limit`);return e.error=void 0,this.emit({type:`member-run-end`,member:e.name}),n}catch(t){throw e.error=p(t),this.emit({type:`member-run-error`,member:e.name,error:e.error}),t}})().finally(()=>{e.pending--,e.controllers.delete(r),a?.()});return e.tail=c.then(()=>void 0,()=>void 0),await o(c,i)}scheduleWake(e,t){if(this.assertActive(),e.wakeRequestedSeq=Math.max(e.wakeRequestedSeq,t),e.wakeTask!==void 0)return;let n=new AbortController;e.wakeController=n;let r=u(this.lifecycle.signal,n.signal,AbortSignal.timeout(this.operationTimeoutMs)),i=this.runWakeLoop(e,r).finally(()=>{e.wakeTask===i&&(e.wakeTask=void 0),e.wakeController===n&&(e.wakeController=void 0),e.wakeConsumedSeq<e.wakeRequestedSeq&&this.scheduleWake(e,e.wakeRequestedSeq)});e.wakeTask=i}async runWakeLoop(e,t){let n=!1;try{for(;e.wakeConsumedSeq<e.wakeRequestedSeq;){t.throwIfAborted(),await e.session.whenIdle(t);let r=e.wakeRequestedSeq;this.emit({type:`member-run-start`,member:e.name});try{let i=await e.session.runPending({signal:t,onEvent:t=>this.observeAgentEvent(e.name,t)});if(t.aborted){e.wakeConsumedSeq=r,this.emit({type:`member-run-cancelled`,member:e.name}),n=!0;continue}e.error=void 0,e.outcome={kind:`completed`,text:w(i)},e.wakeConsumedSeq=r,this.emit({type:`member-run-end`,member:e.name})}catch(i){if(t.aborted){e.error=void 0,e.wakeConsumedSeq=r,this.emit({type:`member-run-cancelled`,member:e.name}),n=!0;continue}if(e.session.isRunning)continue;e.error=p(i),e.outcome={kind:`failed`,message:e.error},e.wakeConsumedSeq=r,this.emit({type:`member-run-error`,member:e.name,error:e.error})}}}catch(r){if(!t.aborted)throw r;e.error=void 0,e.wakeConsumedSeq=e.wakeRequestedSeq,n||this.emit({type:`member-run-cancelled`,member:e.name})}}requireLocalMember(e){let t=m(e),n=this.roster.get(t);if(n===void 0)throw Error(`unknown local A2A member '${t}'`);return n}beginWait(e,t){for(let r of t)if(this.requireAddress(r),r===e||this.hasWaitPath(r,e,new Set))throw new n(`wait_agents would create a coordination cycle`,`TEAM_WAIT_CYCLE`);let r=this.waitEdges.get(e);r===void 0&&(r=new Map,this.waitEdges.set(e,r));for(let e of t)r.set(e,(r.get(e)??0)+1);let i=!0;return()=>{if(!i)return;i=!1;let n=this.waitEdges.get(e);if(n!==void 0){for(let e of t){let t=n.get(e)??0;t<=1?n.delete(e):n.set(e,t-1)}n.size===0&&this.waitEdges.delete(e)}}}hasWaitPath(e,t,n){if(e===t)return!0;if(n.has(e))return!1;n.add(e);for(let r of this.waitEdges.get(e)?.keys()??[])if(this.hasWaitPath(r,t,n))return!0;return!1}requireAddress(e){let t=m(e),n=this.roster.get(t)??this.links.get(t);if(n===void 0)throw Error(`unknown A2A member '${t}'`);return n}assertAddressAvailable(e){if(this.roster.has(e)||this.links.has(e))throw Error(`A2A member '${e}' is already attached or linked`)}assertCapacity(){if(this.roster.size+this.links.size>=this.maxMembers)throw Error(`A2A team '${this.id}' reached its ${this.maxMembers}-member limit`)}assertActive(){if(this.disposed)throw Error(`A2A team '${this.id}' is disposed`)}reserveMailbox(e){if(this.mailbox.length+this.pendingMessages>=this.maxMessages)throw Error(`A2A team '${this.id}' reached its ${this.maxMessages}-message mailbox limit`);if(this.mailboxBytes+this.pendingMailboxBytes+e>this.maxMailboxBytes)throw Error(`A2A team '${this.id}' reached its ${this.maxMailboxBytes}-byte mailbox limit`);this.pendingMessages++,this.pendingMailboxBytes+=e;let t=!1;return()=>{t||(t=!0,this.pendingMessages--,this.pendingMailboxBytes-=e)}}recordOutcome(e,t){let n=this.requireLocalMember(e);n.outcome=t,n.error=t.kind===`failed`?t.message:void 0}markPending(e,t){this.requireLocalMember(e).pendingStart=t}view(e){return e.kind===`remote`?Object.freeze({name:e.name,agentId:e.transport.agentId,kind:`remote`,role:e.role,status:e.error===void 0?e.pending>0?`running`:`idle`:`failed`,protocol:e.transport.protocol,deliveries:Object.freeze([`wakeup`]),...e.description===void 0?{}:{description:e.description},...e.error===void 0?{}:{error:e.error}}):Object.freeze({name:e.name,agentId:e.session.definition.id,kind:`local`,conversationId:e.session.conversationId,role:e.role,status:e.error===void 0?e.pendingStart===void 0?e.session.isRunning||e.wakeTask!==void 0?`running`:`idle`:`pending`:`failed`,protocol:`in-process`,deliveries:Object.freeze([`quiet`,`wakeup`]),...e.description===void 0?{}:{description:e.description},...e.error===void 0?{}:{error:e.error},...e.outcome===void 0?{}:{outcome:e.outcome}})}emit(e){try{this.onEvent?.(e)}catch{}}async observeAgentEvent(t,n){if(this.onAgentEvent===void 0)return;let r=Promise.resolve().then(()=>this.onAgentEvent?.(t,n));await e(r,this.observerTimeoutMs)}};function w(e){let t=e?.text;return typeof t==`string`?t:``}export{C as AgentTeam};
2
+ //# sourceMappingURL=team.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team.js","names":[],"sources":["../../../src/agent/team/team.ts"],"sourcesContent":["import type { AgentRunEvent } from '../mode/run-agent.ts'\nimport { defineTool, type ToolDefinition } from '../tool/definition.ts'\nimport type { ContentBlock } from '../../message/index.ts'\nimport { createUserMessage } from '../../message/index.ts'\nimport { waitForSettlement } from '../../async/index.ts'\nimport { AgentSdkError } from '../../errors/index.ts'\nimport { timeoutValue } from '../../platform/config.ts'\nimport type {\n TeamMemberAttachmentOptions, TeamPort, TeamSessionPort, TeamToolAccess,\n} from './contracts.ts'\nimport type {\n AgentMemberOutcome, AgentMessageRecord, AgentTeamEvent, AgentTeamMember, AgentTeamOptions,\n LinkAgentOptions, LinkedAgentResult, SendAgentMessageRequest, SendAgentMessageResult,\n} from './types.ts'\nimport {\n messageToolSchema, parseMessageTool, parseWaitTool, emptyObject, messageContent, memberName,\n boundedString, positiveInteger, byteLength, errorMessage, asJson, deepCloneFreeze, newTeamId,\n newMessageId, abortable, combineSignals, withTimeout, TEAM_TOOL_NAMES,\n DEFAULT_MIN_WAIT_TIMEOUT_MS,\n DEFAULT_WAIT_TIMEOUT_MS,\n} from './common.ts'\n\n/** Shared control plane for local sessions and interoperable remote A2A peers. */\n\ninterface LocalMemberRuntime {\n readonly kind: 'local'\n readonly name: string\n readonly description?: string\n readonly instructions?: string\n readonly role: 'lead' | 'peer'\n /** Which team verbs it was attached with; shapes its routing guidance. */\n readonly access: TeamToolAccess\n readonly session: TeamSessionPort\n wakeRequestedSeq: number\n wakeConsumedSeq: number\n wakeTask: Promise<void> | undefined\n wakeController: AbortController | undefined\n error: string | undefined\n /** How its last run ended, for a coordinator that did not await the run. */\n outcome: AgentMemberOutcome | undefined\n /**\n * Set while the host is holding this member back, and resolved when it lets\n * it start. See {@link AgentTeam.markPending}.\n */\n pendingStart: Promise<void> | undefined\n /**\n * Aborted when the user steers something into this member mid-turn.\n *\n * A member parked in `wait_agents` is not listening to its own conversation:\n * the wait is bounded by its own budget, so a correction typed while it waits\n * sits unread for as long as that budget lasts. Codex's `wait_agent` \"ends\n * early when new user input is steered into the active turn\" for the same\n * reason. Replaced after each notification, so one interruption ends one\n * wait.\n */\n steerController: AbortController | undefined\n}\n\ninterface RemoteMemberRuntime {\n readonly kind: 'remote'\n readonly name: string\n readonly description?: string\n readonly role: 'peer'\n readonly transport: LinkAgentOptions['transport']\n tail: Promise<void>\n pending: number\n readonly controllers: Set<AbortController>\n error: string | undefined\n}\n\ntype AddressableMember = LocalMemberRuntime | RemoteMemberRuntime\n\n\n/**\n * Connect long-lived local AgentSessions and remote protocol peers behind one\n * roster and one model-facing messaging surface.\n */\nexport class AgentTeam implements TeamPort {\n readonly id: string\n private readonly maxMembers: number\n private readonly maxMessageBytes: number\n private readonly maxLinkedResultBytes: number\n private readonly maxMessages: number\n private readonly maxMailboxBytes: number\n private readonly maxMetadataBytes: number\n private readonly disposeTimeoutMs: number\n private readonly operationTimeoutMs: number\n private readonly observerTimeoutMs: number\n private readonly waitTimeoutMs: number\n private readonly minWaitTimeoutMs: number\n private onEvent: ((event: AgentTeamEvent) => void) | undefined\n private onAgentEvent: AgentTeamOptions['onAgentEvent']\n private readonly roster = new Map<string, LocalMemberRuntime>()\n private readonly links = new Map<string, RemoteMemberRuntime>()\n private readonly mailbox: AgentMessageRecord[] = []\n private mailboxBytes = 0\n private pendingMessages = 0\n private pendingMailboxBytes = 0\n private readonly lifecycle = new AbortController()\n private readonly waitEdges = new Map<string, Map<string, number>>()\n private disposed = false\n private disposeTask: Promise<void> | undefined\n\n constructor(\n options: AgentTeamOptions = {},\n private readonly ownRemoteTask?: (signal: AbortSignal) => () => void,\n ) {\n this.id = boundedString(options.id ?? newTeamId(), 'team id', 1024)\n this.maxMembers = positiveInteger(options.maxMembers ?? 8, 'maxMembers')\n this.maxMessageBytes = positiveInteger(options.maxMessageBytes ?? 64 * 1024, 'maxMessageBytes')\n this.maxLinkedResultBytes = positiveInteger(\n options.maxLinkedResultBytes ?? 1024 * 1024,\n 'maxLinkedResultBytes',\n )\n this.maxMessages = positiveInteger(options.maxMessages ?? 10_000, 'maxMessages')\n this.maxMailboxBytes = positiveInteger(options.maxMailboxBytes ?? 64 * 1024 * 1024, 'maxMailboxBytes')\n this.maxMetadataBytes = positiveInteger(options.maxMetadataBytes ?? 8 * 1024, 'maxMetadataBytes')\n this.disposeTimeoutMs = timeoutValue(options.disposeTimeoutMs ?? 30_000)\n this.operationTimeoutMs = timeoutValue(options.operationTimeoutMs ?? 10 * 60_000)\n this.observerTimeoutMs = timeoutValue(options.observerTimeoutMs ?? 1_000)\n this.waitTimeoutMs = timeoutValue(options.waitTimeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS)\n // A floor above the ceiling would clamp every call up to a budget the host\n // said was too long; the host's own maximum wins.\n this.minWaitTimeoutMs = Math.min(\n timeoutValue(options.minWaitTimeoutMs ?? DEFAULT_MIN_WAIT_TIMEOUT_MS),\n this.waitTimeoutMs,\n )\n this.onEvent = options.onEvent\n this.onAgentEvent = options.onAgentEvent\n }\n\n /** Called by AgentSession after its tool catalog is assembled. */\n attach(session: TeamSessionPort, options: TeamMemberAttachmentOptions = {}): void {\n this.assertActive()\n const name = memberName(options.name ?? session.definition.id)\n this.assertAddressAvailable(name)\n this.assertCapacity()\n const role = options.role ?? (this.roster.size === 0 ? 'lead' : 'peer')\n if (role === 'lead' && [...this.roster.values()].some(member => member.role === 'lead')) {\n throw new Error(`A2A team '${this.id}' already has a lead`)\n }\n const access: TeamToolAccess = options.tools === 'reporting' ? 'reporting' : 'full'\n const member: LocalMemberRuntime = {\n kind: 'local', name, role, access, session,\n wakeRequestedSeq: 0, wakeConsumedSeq: 0,\n wakeTask: undefined, wakeController: undefined, error: undefined, outcome: undefined,\n pendingStart: undefined, steerController: undefined,\n ...(options.description === undefined ? {} : {\n description: boundedString(options.description, 'member description', this.maxMetadataBytes),\n }),\n ...(options.instructions === undefined ? {} : {\n instructions: boundedString(options.instructions, 'member instructions', this.maxMetadataBytes),\n }),\n }\n this.roster.set(name, member)\n this.emit({ type: 'member-attached', member: this.view(member) })\n }\n\n /** Link one remote transport, including an official A2A protocol client. */\n linkAgent(options: LinkAgentOptions): () => void {\n this.assertActive()\n const name = memberName(options.name)\n this.assertAddressAvailable(name)\n this.assertCapacity()\n if (typeof options.transport?.send !== 'function') {\n throw new TypeError('linked agent transport must implement send()')\n }\n const member: RemoteMemberRuntime = {\n kind: 'remote', name, role: 'peer', transport: options.transport,\n tail: Promise.resolve(), pending: 0, controllers: new Set(), error: undefined,\n ...(options.description === undefined ? {} : {\n description: boundedString(options.description, 'linked agent description', this.maxMetadataBytes),\n }),\n }\n this.links.set(name, member)\n this.emit({ type: 'member-linked', member: this.view(member) })\n return () => {\n if (this.links.get(name) !== member) return\n if (member.pending > 0) throw new Error(`cannot unlink running A2A member '${name}'`)\n this.links.delete(name)\n }\n }\n\n /** Remove exactly one idle local session registration. */\n detach(name: string): void {\n this.assertActive()\n const member = this.requireLocalMember(name)\n if (member.session.isRunning || member.wakeTask !== undefined) {\n throw new Error(`cannot detach running A2A member '${member.name}'`)\n }\n this.roster.delete(member.name)\n }\n\n /** Current detached roster: local members first, then remote links. */\n members(): readonly AgentTeamMember[] {\n return Object.freeze([\n ...this.roster.values(),\n ...this.links.values(),\n ].map(member => this.view(member)))\n }\n\n /** Immutable audit log. Local target history remains its resumable receipt. */\n messages(): readonly AgentMessageRecord[] {\n return deepCloneFreeze(this.mailbox)\n }\n\n /** Deliver to a local mailbox or dispatch through a linked remote transport. */\n async sendMessage(request: SendAgentMessageRequest): Promise<SendAgentMessageResult> {\n this.assertActive()\n request.signal?.throwIfAborted()\n const sender = this.requireLocalMember(request.from)\n const target = this.requireAddress(request.target)\n if (target.kind === 'local' && sender === target) throw new Error('an A2A member cannot message itself')\n const delivery = request.delivery ?? 'quiet'\n if (delivery !== 'quiet' && delivery !== 'wakeup') {\n throw new TypeError(\"A2A delivery must be 'quiet' or 'wakeup'\")\n }\n if (target.kind === 'remote' && delivery === 'quiet') {\n throw new Error(\n `remote A2A member '${target.name}' cannot accept quiet injection; use followup_task or delivery 'wakeup'`,\n )\n }\n const id = newMessageId()\n const content = messageContent(request.message, this.maxMessageBytes)\n const framed = deepCloneFreeze([\n { type: 'text' as const, text: `A2A message ${id} from ${sender.name}:` },\n ...content,\n ])\n const contentBytes = byteLength(framed)\n if (contentBytes > this.maxMessageBytes) {\n throw new Error(`A2A message exceeds the ${this.maxMessageBytes}-byte limit`)\n }\n const reservedBytes = target.kind === 'remote'\n ? contentBytes + this.maxLinkedResultBytes\n : contentBytes\n const releaseReservation = this.reserveMailbox(reservedBytes)\n\n let result: LinkedAgentResult | undefined\n try {\n if (target.kind === 'local') {\n const message = createUserMessage({\n source: {\n kind: 'agent-message' as const,\n teamId: this.id, messageId: id, sender: sender.name,\n senderAgentId: sender.session.definition.id,\n },\n content: framed,\n })\n const seq = target.session.inject(message)\n if (delivery === 'wakeup') this.scheduleWake(target, seq)\n } else {\n result = await this.dispatchRemote(target, {\n teamId: this.id, messageId: id, sender: sender.name,\n senderAgentId: sender.session.definition.id, content: framed,\n ...(request.signal === undefined ? {} : { signal: request.signal }),\n })\n }\n\n const record: AgentMessageRecord = deepCloneFreeze({\n id, teamId: this.id, sender: sender.name,\n senderAgentId: sender.session.definition.id,\n target: target.name,\n targetAgentId: target.kind === 'local'\n ? target.session.definition.id\n : target.transport.agentId,\n delivery, content: framed, status: 'accepted' as const,\n createdAt: new Date().toISOString(),\n ...(result === undefined ? {} : { result }),\n })\n const retainedBytes = contentBytes + (result === undefined ? 0 : byteLength(result))\n this.mailbox.push(record)\n this.mailboxBytes += retainedBytes\n this.emit({ type: 'message-accepted', message: deepCloneFreeze(record) })\n return deepCloneFreeze({\n messageId: id, status: 'accepted' as const, delivery, target: target.name,\n ...(result === undefined ? {} : { result }),\n })\n } finally {\n releaseReservation()\n }\n }\n\n /** Wake-up alias used by hosts and model tools. */\n followup(\n from: string,\n target: string,\n message: string | readonly ContentBlock[],\n signal?: AbortSignal,\n ): Promise<SendAgentMessageResult> {\n return this.sendMessage({\n from, target, message, delivery: 'wakeup',\n ...(signal === undefined ? {} : { signal }),\n })\n }\n\n /** Wait until all local wake-up work or remote dispatches settle. */\n async whenIdle(name: string, signal?: AbortSignal): Promise<void> {\n const member = this.requireAddress(name)\n if (member.kind === 'remote') {\n while (true) {\n const tail = member.tail\n await abortable(tail, signal)\n if (tail === member.tail && member.pending === 0) break\n }\n return\n }\n while (true) {\n const requested = member.wakeRequestedSeq\n const task = member.wakeTask\n // A member the host is holding back has not finished; it has not begun.\n // Waiting on its session would be answered at once, and the waiter would\n // read that as work completed.\n const held = member.pendingStart\n if (held !== undefined) await abortable(held, signal)\n if (task !== undefined) await abortable(task, signal)\n await member.session.whenIdle(signal)\n if (member.wakeTask === undefined && !member.session.isRunning\n && member.pendingStart === undefined\n && member.wakeConsumedSeq >= member.wakeRequestedSeq\n && requested === member.wakeRequestedSeq) return\n }\n }\n\n /**\n * Report that the user steered something into a local member mid-turn.\n *\n * Ends whatever that member is currently waiting on. A member parked in\n * `wait_agents` would otherwise finish its budget before reading a correction\n * that has been sitting in its history the whole time; Codex ends its\n * `wait_agent` early on steered input for the same reason.\n * @param name - Local member address.\n */\n notifySteer(name: string): void {\n const member = this.requireLocalMember(name)\n const controller = member.steerController\n member.steerController = undefined\n controller?.abort(new Error('user input steered into the active turn'))\n }\n\n /**\n * Schedule one turn for a local member over context it already has.\n *\n * A wake-up delivery carries a message; this carries nothing. It exists for\n * the case where the context arrived earlier and quietly — appended to a\n * member that was mid-turn, on the assumption its next model round would read\n * it — and that round never came. Without this the message sits in history\n * with nothing left to read it.\n * @param name - Local member address.\n */\n wake(name: string): void {\n const member = this.requireLocalMember(name)\n this.scheduleWake(member, member.wakeRequestedSeq + 1)\n }\n\n /** Cancel team-owned scheduled work for one member without mutating its history. */\n async cancel(name: string, reason: unknown = new Error('A2A member work cancelled')): Promise<void> {\n const member = this.requireAddress(name)\n if (member.kind === 'remote') {\n for (const controller of member.controllers) controller.abort(reason)\n await withTimeout(\n member.tail,\n this.disposeTimeoutMs,\n `A2A member '${member.name}' did not cancel within ${this.disposeTimeoutMs}ms`,\n 'TEAM_CANCELLATION_TIMEOUT',\n )\n return\n }\n member.wakeConsumedSeq = member.wakeRequestedSeq\n const controller = member.wakeController\n const task = member.wakeTask\n controller?.abort(reason)\n if (task !== undefined) {\n await withTimeout(\n task,\n this.disposeTimeoutMs,\n `A2A member '${member.name}' did not cancel within ${this.disposeTimeoutMs}ms`,\n 'TEAM_CANCELLATION_TIMEOUT',\n )\n }\n }\n\n /** Permanently close this control plane and cancel every team-owned operation. */\n dispose(reason: unknown = new Error('A2A team disposed')): Promise<void> {\n if (this.disposeTask !== undefined) return this.disposeTask\n this.disposed = true\n this.lifecycle.abort(reason)\n const settling = Promise.allSettled([\n ...[...this.roster.values()].map(member => this.cancel(member.name, reason)),\n ...[...this.links.values()].map(member => this.cancel(member.name, reason)),\n ]).then(results => {\n this.roster.clear()\n this.links.clear()\n this.emit({ type: 'team-disposed', teamId: this.id })\n this.mailbox.length = 0\n this.mailboxBytes = 0\n this.waitEdges.clear()\n this.onEvent = undefined\n this.onAgentEvent = undefined\n const failure = results.find((result): result is PromiseRejectedResult => result.status === 'rejected')\n if (failure !== undefined) {\n throw new AgentSdkError(\n `A2A team '${this.id}' did not dispose within ${this.disposeTimeoutMs}ms`,\n 'TEAM_DISPOSE_TIMEOUT',\n { cause: failure.reason },\n )\n }\n })\n this.disposeTask = withTimeout(\n settling,\n this.disposeTimeoutMs,\n `A2A team '${this.id}' did not dispose within ${this.disposeTimeoutMs}ms`,\n 'TEAM_DISPOSE_TIMEOUT',\n )\n return this.disposeTask\n }\n\n /** Model-facing tools bound to one immutable local sender identity. */\n toolsFor(sender: string, access: TeamToolAccess = 'full'): readonly ToolDefinition<any>[] {\n this.assertActive()\n const name = memberName(sender)\n // Called before `attach`, so the access level arrives as an argument\n // rather than being looked up on the member that does not exist yet.\n const coordinating = access === 'full'\n // Coordination is not exploration. A lead that has spent its tool budget\n // still has to be able to hand the work over and collect it; blocking\n // these is what strands a team run with finished members and no report.\n return Object.freeze([\n defineTool({\n name: TEAM_TOOL_NAMES.list,\n budgetExempt: true,\n description: 'List local and remote addressable agents, their protocols, supported delivery modes, and status.',\n parameters: { type: 'object', properties: {}, additionalProperties: false },\n parse: raw => emptyObject(raw, 'list_agents'),\n execute: () => asJson(this.members()),\n isConcurrencySafe: () => true,\n }),\n defineTool({\n name: TEAM_TOOL_NAMES.send,\n budgetExempt: true,\n description: 'Inject quiet context into ANOTHER local agent without starting it.'\n + ' Name a target from list_agents other than yourself; your own result already'\n + ' goes back to whoever started you, so reporting does not need this tool.'\n + ' Remote A2A peers require followup_task.',\n parameters: messageToolSchema('Message to add to the target context.'),\n parse: parseMessageTool,\n execute: async ({ target, message }, ctx) => asJson(await this.sendMessage({\n from: name, target, message, delivery: 'quiet', signal: ctx.signal,\n })),\n }),\n ...!coordinating ? [] : [defineTool({\n name: TEAM_TOOL_NAMES.followup,\n budgetExempt: true,\n description: 'Send active work to a local agent or interoperable remote A2A peer and wait for its accepted result.',\n parameters: messageToolSchema('Follow-up instruction the target must process.'),\n parse: parseMessageTool,\n execute: async ({ target, message }, ctx) => asJson(\n await this.followup(name, target, message, ctx.signal),\n ),\n })],\n ...!coordinating ? [] : [defineTool({\n name: TEAM_TOOL_NAMES.wait,\n budgetExempt: true,\n description: 'Wait until one of the selected local or remote agents finishes its scheduled'\n + ' work, then return their current roster state. Returns early with interrupted=true when'\n + ' the user sends you something while you wait, so read that before waiting again.',\n parameters: {\n type: 'object',\n properties: {\n targets: {\n type: 'array', items: { type: 'string' }, minItems: 1,\n description: 'Exact agent names returned by list_agents.',\n },\n timeoutMs: {\n type: 'number',\n description:\n `Give up after this long and report instead, default ${String(this.waitTimeoutMs)}.`\n + ` Anything under ${String(this.minWaitTimeoutMs)} is raised to it: a wait too short to`\n + ` finish anything costs a model round and returns the roster unchanged.`,\n },\n },\n required: ['targets'], additionalProperties: false,\n },\n parse: parseWaitTool,\n execute: async ({ targets, timeoutMs }, ctx) => {\n const release = this.beginWait(name, targets)\n const budget = timeoutMs === undefined\n ? this.waitTimeoutMs\n : Math.min(\n Math.max(timeoutValue(timeoutMs), this.minWaitTimeoutMs),\n this.waitTimeoutMs,\n )\n try {\n // Returns as soon as the FIRST target settles, and always within\n // the budget. Waiting for all of them, forever, is what turned one\n // slow agent into a window that looked hung: a coordinator that\n // gets the roster back can decide for itself whether to wait again.\n //\n // The budget is enforced HERE rather than only by handing members a\n // deadline signal: a member that does not honour the signal would\n // otherwise hold the wait open past its own timeout, and a timeout\n // a callee can ignore is not a timeout.\n // A wait that cannot be interrupted is a wait the user cannot\n // correct: the caller is parked here, so its own new input has\n // nothing else to end it before the budget runs out.\n const steer = new AbortController()\n const caller = this.roster.get(memberName(sender))\n if (caller !== undefined) caller.steerController = steer\n const signal = combineSignals(ctx.signal, AbortSignal.timeout(budget), steer.signal)\n let timer: ReturnType<typeof setTimeout> | undefined\n const expiry = new Promise<undefined>((resolve) => {\n timer = setTimeout(() => resolve(undefined), budget)\n })\n const interrupted = new Promise<undefined>((resolve) => {\n steer.signal.addEventListener('abort', () => { resolve(undefined) }, { once: true })\n })\n const settled = await Promise.race([\n Promise.any(targets.map(async (target) => {\n await this.whenIdle(target, signal)\n return target\n })).then(target => target, () => undefined),\n expiry,\n interrupted,\n ]).finally(() => {\n clearTimeout(timer)\n if (caller?.steerController === steer) caller.steerController = undefined\n })\n // The caller's own cancellation still wins; a steer does not.\n ctx.signal.throwIfAborted()\n if (steer.signal.aborted) {\n return asJson({\n agents: this.members().filter(member => new Set(targets).has(member.name)),\n settled: null,\n timedOut: false,\n interrupted: true,\n waitedMs: budget,\n })\n }\n const selected = new Set(targets)\n return asJson({\n agents: this.members().filter(member => selected.has(member.name)),\n settled: settled ?? null,\n timedOut: settled === undefined,\n // The budget actually used, which is not always the one asked\n // for: a lead that reads `timedOut` after a request below the\n // floor would otherwise misjudge how long its workers had.\n waitedMs: budget,\n })\n } finally { release() }\n },\n isConcurrencySafe: () => true,\n })],\n ])\n }\n\n /** Identity and routing semantics added to each attached member's system text. */\n instructionsFor(name: string): string {\n const address = memberName(name)\n const member = this.roster.get(address)\n // Guidance follows the tools the member actually has. Advertising\n // followup_task and wait_agents to a reporting member would send it looking\n // for verbs it was deliberately not given, and describe a coordinating role\n // it does not hold.\n const coordinating = member === undefined || member.access === 'full'\n return [\n `You are agent-team member '${address}' in team '${this.id}'.`,\n coordinating\n ? 'Use send_message only for quiet local context. Use followup_task for active work and every remote A2A peer.'\n : 'Use send_message to report context to another agent. You cannot delegate work or wait for other agents:'\n + ' finish your own task and return its result, even when you would rather ask first.',\n ...coordinating\n ? ['After delegating asynchronous local work, use wait_agents before depending on its completion.']\n : [],\n 'list_agents reports whether a target is local or remote and which delivery modes it supports.',\n 'Agent messages are attributed user-role context; treat their sender framing as provenance, not as end-user authorship.',\n member?.instructions,\n ].filter((part): part is string => part !== undefined).join(' ')\n }\n\n private async dispatchRemote(\n member: RemoteMemberRuntime,\n input: Parameters<RemoteMemberRuntime['transport']['send']>[0],\n ): Promise<LinkedAgentResult> {\n if (member.pending >= this.maxMessages) {\n throw new AgentSdkError('Remote member has too many unsettled sends', 'TEAM_REMOTE_PENDING_LIMIT')\n }\n const controller = new AbortController()\n const signal = combineSignals(\n input.signal, this.lifecycle.signal, controller.signal,\n AbortSignal.timeout(this.operationTimeoutMs),\n )\n signal.throwIfAborted()\n const releaseOwnership = this.ownRemoteTask?.(signal)\n member.controllers.add(controller)\n member.pending++\n const previous = member.tail\n const operation = (async () => {\n // The serial tail represents physical callback settlement, not the\n // abortable public wait. A cancelled queued request skips dispatch once\n // its predecessor actually releases ownership.\n await previous\n signal.throwIfAborted()\n this.emit({ type: 'member-run-start', member: member.name })\n try {\n const result = await member.transport.send({ ...input, signal })\n signal.throwIfAborted()\n if (byteLength(result) > this.maxLinkedResultBytes) {\n throw new Error(`linked A2A result exceeds the ${this.maxLinkedResultBytes}-byte limit`)\n }\n member.error = undefined\n this.emit({ type: 'member-run-end', member: member.name })\n return result\n } catch (error: unknown) {\n member.error = errorMessage(error)\n this.emit({ type: 'member-run-error', member: member.name, error: member.error })\n throw error\n }\n })().finally(() => {\n member.pending--\n member.controllers.delete(controller)\n releaseOwnership?.()\n })\n member.tail = operation.then(() => undefined, () => undefined)\n return await abortable(operation, signal)\n }\n\n private scheduleWake(member: LocalMemberRuntime, seq: number): void {\n this.assertActive()\n member.wakeRequestedSeq = Math.max(member.wakeRequestedSeq, seq)\n if (member.wakeTask !== undefined) return\n const controller = new AbortController()\n member.wakeController = controller\n const signal = combineSignals(\n this.lifecycle.signal, controller.signal, AbortSignal.timeout(this.operationTimeoutMs),\n )\n const task = this.runWakeLoop(member, signal).finally(() => {\n if (member.wakeTask === task) member.wakeTask = undefined\n if (member.wakeController === controller) member.wakeController = undefined\n if (member.wakeConsumedSeq < member.wakeRequestedSeq) {\n this.scheduleWake(member, member.wakeRequestedSeq)\n }\n })\n member.wakeTask = task\n }\n\n private async runWakeLoop(member: LocalMemberRuntime, signal: AbortSignal): Promise<void> {\n let cancellationReported = false\n try {\n while (member.wakeConsumedSeq < member.wakeRequestedSeq) {\n signal.throwIfAborted()\n await member.session.whenIdle(signal)\n const through = member.wakeRequestedSeq\n this.emit({ type: 'member-run-start', member: member.name })\n try {\n const response = await member.session.runPending({\n signal,\n onEvent: event => this.observeAgentEvent(member.name, event),\n })\n if (signal.aborted) {\n member.wakeConsumedSeq = through\n this.emit({ type: 'member-run-cancelled', member: member.name })\n cancellationReported = true\n continue\n }\n member.error = undefined\n // Recorded so a coordinator can read the member's answer from the\n // roster. `runPending` hands it to whoever awaited the run, and with\n // a wake-up delivery that is nobody.\n member.outcome = { kind: 'completed', text: responseText(response) }\n member.wakeConsumedSeq = through\n this.emit({ type: 'member-run-end', member: member.name })\n } catch (error: unknown) {\n if (signal.aborted) {\n member.error = undefined\n member.wakeConsumedSeq = through\n this.emit({ type: 'member-run-cancelled', member: member.name })\n cancellationReported = true\n continue\n }\n if (member.session.isRunning) continue\n member.error = errorMessage(error)\n member.outcome = { kind: 'failed', message: member.error }\n member.wakeConsumedSeq = through\n this.emit({ type: 'member-run-error', member: member.name, error: member.error })\n }\n }\n } catch (error: unknown) {\n if (!signal.aborted) throw error\n member.error = undefined\n member.wakeConsumedSeq = member.wakeRequestedSeq\n if (!cancellationReported) this.emit({ type: 'member-run-cancelled', member: member.name })\n }\n }\n\n private requireLocalMember(value: string): LocalMemberRuntime {\n const name = memberName(value)\n const member = this.roster.get(name)\n if (member === undefined) throw new Error(`unknown local A2A member '${name}'`)\n return member\n }\n\n /**\n * Record that `sender` is blocked until `targets` are idle.\n *\n * The `wait_agents` tool calls this, and so must any HOST that blocks one\n * member on another. An unrecorded edge is invisible here, which is worse\n * than having no detection at all: the cycle it completes gets waved through,\n * and both sides then wait for each other until a timeout expires.\n *\n * `spawn_agent` used to be such a host — it awaited the worker it created —\n * and needed an edge declared for it. It no longer waits, so the cycle it\n * could close no longer exists.\n * @param sender - The member that will block.\n * @param targets - Members it is waiting for.\n * @returns A release; call it when the wait ends, however it ends.\n * @throws `TEAM_WAIT_CYCLE` when the wait would close a cycle.\n */\n beginWait(sender: string, targets: readonly string[]): () => void {\n for (const target of targets) {\n this.requireAddress(target)\n if (target === sender || this.hasWaitPath(target, sender, new Set())) {\n throw new AgentSdkError('wait_agents would create a coordination cycle', 'TEAM_WAIT_CYCLE')\n }\n }\n let outgoing = this.waitEdges.get(sender)\n if (outgoing === undefined) {\n outgoing = new Map()\n this.waitEdges.set(sender, outgoing)\n }\n for (const target of targets) outgoing.set(target, (outgoing.get(target) ?? 0) + 1)\n let active = true\n return () => {\n if (!active) return\n active = false\n const edges = this.waitEdges.get(sender)\n if (edges === undefined) return\n for (const target of targets) {\n const count = edges.get(target) ?? 0\n if (count <= 1) edges.delete(target); else edges.set(target, count - 1)\n }\n if (edges.size === 0) this.waitEdges.delete(sender)\n }\n }\n\n private hasWaitPath(from: string, target: string, visited: Set<string>): boolean {\n if (from === target) return true\n if (visited.has(from)) return false\n visited.add(from)\n for (const next of this.waitEdges.get(from)?.keys() ?? []) {\n if (this.hasWaitPath(next, target, visited)) return true\n }\n return false\n }\n\n private requireAddress(value: string): AddressableMember {\n const name = memberName(value)\n const member = this.roster.get(name) ?? this.links.get(name)\n if (member === undefined) throw new Error(`unknown A2A member '${name}'`)\n return member\n }\n\n private assertAddressAvailable(name: string): void {\n if (this.roster.has(name) || this.links.has(name)) {\n throw new Error(`A2A member '${name}' is already attached or linked`)\n }\n }\n\n private assertCapacity(): void {\n if (this.roster.size + this.links.size >= this.maxMembers) {\n throw new Error(`A2A team '${this.id}' reached its ${this.maxMembers}-member limit`)\n }\n }\n\n private assertActive(): void {\n if (this.disposed) throw new Error(`A2A team '${this.id}' is disposed`)\n }\n\n private reserveMailbox(contentBytes: number): () => void {\n if (this.mailbox.length + this.pendingMessages >= this.maxMessages) {\n throw new Error(`A2A team '${this.id}' reached its ${this.maxMessages}-message mailbox limit`)\n }\n if (this.mailboxBytes + this.pendingMailboxBytes + contentBytes > this.maxMailboxBytes) {\n throw new Error(`A2A team '${this.id}' reached its ${this.maxMailboxBytes}-byte mailbox limit`)\n }\n this.pendingMessages++\n this.pendingMailboxBytes += contentBytes\n let released = false\n return () => {\n if (released) return\n released = true\n this.pendingMessages--\n this.pendingMailboxBytes -= contentBytes\n }\n }\n\n /**\n * Record how a member's run ended.\n *\n * For a host that starts a member's run itself and therefore owns the result\n * the member's own bookkeeping never sees — `spawn_agent` running a worker\n * concurrently. Without this the roster could report that a worker had\n * stopped but not what it concluded, which is the whole point of asking.\n * @param name - Member address.\n * @param outcome - How the run ended.\n */\n recordOutcome(name: string, outcome: AgentMemberOutcome): void {\n const member = this.requireLocalMember(name)\n member.outcome = outcome\n member.error = outcome.kind === 'failed' ? outcome.message : undefined\n }\n\n /**\n * Declare that a member exists but has deliberately not been started.\n *\n * A host that orders work — starting one member only once another has\n * finished — needs the roster to say so, and `wait_agents` to believe it. A\n * member whose session has never run looks exactly like one that has\n * finished: idle, not running, nothing outstanding. A coordinator told that\n * would wait on it, be answered at once, read no outcome, and conclude the\n * work was done.\n *\n * The promise is what `whenIdle` waits on, so the pending state cannot be a\n * flag that a waiter has to poll.\n * @param name - Local member address.\n * @param until - Resolves when the host starts it; undefined clears the state.\n */\n markPending(name: string, until: Promise<void> | undefined): void {\n this.requireLocalMember(name).pendingStart = until\n }\n\n private view(member: AddressableMember): AgentTeamMember {\n if (member.kind === 'remote') {\n return Object.freeze({\n name: member.name, agentId: member.transport.agentId, kind: 'remote' as const,\n role: member.role,\n status: member.error === undefined ? (member.pending > 0 ? 'running' : 'idle') : 'failed',\n protocol: member.transport.protocol,\n deliveries: Object.freeze(['wakeup'] as const),\n ...(member.description === undefined ? {} : { description: member.description }),\n ...(member.error === undefined ? {} : { error: member.error }),\n })\n }\n return Object.freeze({\n name: member.name, agentId: member.session.definition.id, kind: 'local' as const,\n conversationId: member.session.conversationId, role: member.role,\n status: member.error !== undefined\n ? 'failed'\n : member.pendingStart !== undefined\n ? 'pending'\n : member.session.isRunning || member.wakeTask !== undefined ? 'running' : 'idle',\n protocol: 'in-process', deliveries: Object.freeze(['quiet', 'wakeup'] as const),\n ...(member.description === undefined ? {} : { description: member.description }),\n ...(member.error === undefined ? {} : { error: member.error }),\n ...(member.outcome === undefined ? {} : { outcome: member.outcome }),\n })\n }\n\n private emit(event: AgentTeamEvent): void {\n try { this.onEvent?.(event) } catch { /* observers do not own control-plane correctness */ }\n }\n\n private async observeAgentEvent(member: string, event: AgentRunEvent): Promise<void> {\n if (this.onAgentEvent === undefined) return\n const observer = Promise.resolve().then(() => this.onAgentEvent?.(member, event))\n await waitForSettlement(observer, this.observerTimeoutMs)\n }\n}\n\n/**\n * The answer text out of a run result.\n *\n * `TeamSessionPort.runPending` returns `unknown` on purpose — the port exists so\n * the control plane does not depend on the concrete session — so the one field\n * needed here is read structurally.\n * @param response - Whatever the member's run resolved with.\n * @returns Its text, or the empty string.\n */\nfunction responseText(response: unknown): string {\n const text = (response as { text?: unknown } | null)?.text\n return typeof text === 'string' ? text : ''\n}\n"],"mappings":"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"}