agent-relay 2.3.2 → 2.3.5

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 (334) hide show
  1. package/README.md +1 -1
  2. package/dist/index.cjs +1 -1
  3. package/dist/src/cli/index.js +124 -7
  4. package/dist/src/cli/index.js.map +1 -1
  5. package/package.json +20 -26
  6. package/packages/acp-bridge/package.json +2 -2
  7. package/packages/bridge/package.json +7 -7
  8. package/packages/config/dist/cloud-config.d.ts +1 -1
  9. package/packages/config/dist/cloud-config.d.ts.map +1 -1
  10. package/packages/config/dist/cloud-config.js.map +1 -1
  11. package/packages/config/dist/schemas.d.ts +5 -5
  12. package/packages/config/dist/schemas.js +1 -1
  13. package/packages/config/dist/schemas.js.map +1 -1
  14. package/packages/config/package.json +2 -2
  15. package/packages/config/src/cloud-config.ts +2 -2
  16. package/packages/config/src/schemas.test.ts +48 -0
  17. package/packages/config/src/schemas.ts +1 -1
  18. package/packages/continuity/package.json +2 -2
  19. package/packages/daemon/package.json +12 -12
  20. package/packages/hooks/package.json +4 -4
  21. package/packages/mcp/package.json +5 -5
  22. package/packages/memory/package.json +2 -2
  23. package/packages/policy/package.json +2 -2
  24. package/packages/protocol/package.json +1 -1
  25. package/packages/resiliency/package.json +1 -1
  26. package/packages/sdk/dist/index.d.ts +1 -29
  27. package/packages/sdk/dist/index.d.ts.map +1 -1
  28. package/packages/sdk/dist/index.js +1 -38
  29. package/packages/sdk/dist/index.js.map +1 -1
  30. package/packages/sdk/package.json +4 -25
  31. package/packages/sdk/src/index.ts +1 -69
  32. package/packages/sdk-py/README.md +56 -0
  33. package/packages/sdk-py/pyproject.toml +23 -0
  34. package/packages/sdk-py/src/agent_relay/__init__.py +27 -0
  35. package/packages/sdk-py/src/agent_relay/builder.py +367 -0
  36. package/packages/sdk-py/src/agent_relay/types.py +92 -0
  37. package/packages/sdk-py/tests/__init__.py +0 -0
  38. package/packages/sdk-py/tests/test_builder.py +101 -0
  39. package/packages/sdk-ts/dist/__tests__/facade.test.d.ts +2 -0
  40. package/packages/sdk-ts/dist/__tests__/facade.test.d.ts.map +1 -0
  41. package/packages/sdk-ts/dist/__tests__/facade.test.js +257 -0
  42. package/packages/sdk-ts/dist/__tests__/facade.test.js.map +1 -0
  43. package/packages/sdk-ts/dist/__tests__/unit.test.d.ts +2 -0
  44. package/packages/sdk-ts/dist/__tests__/unit.test.d.ts.map +1 -0
  45. package/packages/sdk-ts/dist/__tests__/unit.test.js +124 -0
  46. package/packages/sdk-ts/dist/__tests__/unit.test.js.map +1 -0
  47. package/packages/sdk-ts/dist/client.d.ts +2 -0
  48. package/packages/sdk-ts/dist/client.d.ts.map +1 -1
  49. package/packages/sdk-ts/dist/client.js +2 -0
  50. package/packages/sdk-ts/dist/client.js.map +1 -1
  51. package/packages/sdk-ts/dist/index.d.ts +1 -0
  52. package/packages/sdk-ts/dist/index.d.ts.map +1 -1
  53. package/packages/sdk-ts/dist/index.js +1 -0
  54. package/packages/sdk-ts/dist/index.js.map +1 -1
  55. package/packages/sdk-ts/dist/protocol.d.ts +1 -0
  56. package/packages/sdk-ts/dist/protocol.d.ts.map +1 -1
  57. package/packages/sdk-ts/dist/relay.d.ts +44 -0
  58. package/packages/sdk-ts/dist/relay.d.ts.map +1 -1
  59. package/packages/sdk-ts/dist/relay.js +89 -11
  60. package/packages/sdk-ts/dist/relay.js.map +1 -1
  61. package/packages/sdk-ts/dist/relaycast.js +2 -2
  62. package/packages/sdk-ts/dist/relaycast.js.map +1 -1
  63. package/packages/sdk-ts/dist/workflows/barrier.d.ts +72 -0
  64. package/packages/sdk-ts/dist/workflows/barrier.d.ts.map +1 -0
  65. package/packages/sdk-ts/dist/workflows/barrier.js +162 -0
  66. package/packages/sdk-ts/dist/workflows/barrier.js.map +1 -0
  67. package/packages/sdk-ts/dist/workflows/builder.d.ts +101 -0
  68. package/packages/sdk-ts/dist/workflows/builder.d.ts.map +1 -0
  69. package/packages/sdk-ts/dist/workflows/builder.js +179 -0
  70. package/packages/sdk-ts/dist/workflows/builder.js.map +1 -0
  71. package/packages/sdk-ts/dist/workflows/cli.d.ts +10 -0
  72. package/packages/sdk-ts/dist/workflows/cli.d.ts.map +1 -0
  73. package/packages/sdk-ts/dist/workflows/cli.js +82 -0
  74. package/packages/sdk-ts/dist/workflows/cli.js.map +1 -0
  75. package/packages/sdk-ts/dist/workflows/coordinator.d.ts +68 -0
  76. package/packages/sdk-ts/dist/workflows/coordinator.d.ts.map +1 -0
  77. package/packages/sdk-ts/dist/workflows/coordinator.js +353 -0
  78. package/packages/sdk-ts/dist/workflows/coordinator.js.map +1 -0
  79. package/packages/sdk-ts/dist/workflows/index.d.ts +10 -0
  80. package/packages/sdk-ts/dist/workflows/index.d.ts.map +1 -0
  81. package/packages/sdk-ts/dist/workflows/index.js +10 -0
  82. package/packages/sdk-ts/dist/workflows/index.js.map +1 -0
  83. package/packages/sdk-ts/dist/workflows/memory-db.d.ts +17 -0
  84. package/packages/sdk-ts/dist/workflows/memory-db.d.ts.map +1 -0
  85. package/packages/sdk-ts/dist/workflows/memory-db.js +33 -0
  86. package/packages/sdk-ts/dist/workflows/memory-db.js.map +1 -0
  87. package/packages/sdk-ts/dist/workflows/run.d.ts +31 -0
  88. package/packages/sdk-ts/dist/workflows/run.d.ts.map +1 -0
  89. package/packages/sdk-ts/dist/workflows/run.js +24 -0
  90. package/packages/sdk-ts/dist/workflows/run.js.map +1 -0
  91. package/packages/sdk-ts/dist/workflows/runner.d.ts +119 -0
  92. package/packages/sdk-ts/dist/workflows/runner.d.ts.map +1 -0
  93. package/packages/sdk-ts/dist/workflows/runner.js +650 -0
  94. package/packages/sdk-ts/dist/workflows/runner.js.map +1 -0
  95. package/packages/sdk-ts/dist/workflows/state.d.ts +77 -0
  96. package/packages/sdk-ts/dist/workflows/state.d.ts.map +1 -0
  97. package/packages/sdk-ts/dist/workflows/state.js +140 -0
  98. package/packages/sdk-ts/dist/workflows/state.js.map +1 -0
  99. package/packages/sdk-ts/dist/workflows/templates.d.ts +47 -0
  100. package/packages/sdk-ts/dist/workflows/templates.d.ts.map +1 -0
  101. package/packages/sdk-ts/dist/workflows/templates.js +395 -0
  102. package/packages/sdk-ts/dist/workflows/templates.js.map +1 -0
  103. package/packages/sdk-ts/dist/workflows/types.d.ts +126 -0
  104. package/packages/sdk-ts/dist/workflows/types.d.ts.map +1 -0
  105. package/packages/sdk-ts/dist/workflows/types.js +8 -0
  106. package/packages/sdk-ts/dist/workflows/types.js.map +1 -0
  107. package/packages/sdk-ts/package.json +9 -3
  108. package/packages/sdk-ts/src/__tests__/error-scenarios.test.ts +682 -0
  109. package/packages/sdk-ts/src/__tests__/facade.test.ts +296 -0
  110. package/packages/sdk-ts/src/__tests__/swarm-coordinator.test.ts +416 -0
  111. package/packages/sdk-ts/src/__tests__/unit.test.ts +152 -0
  112. package/packages/sdk-ts/src/__tests__/workflow-runner.test.ts +333 -0
  113. package/packages/sdk-ts/src/client.ts +4 -0
  114. package/packages/sdk-ts/src/index.ts +1 -0
  115. package/packages/sdk-ts/src/protocol.ts +1 -1
  116. package/packages/sdk-ts/src/relay.ts +112 -11
  117. package/packages/sdk-ts/src/relaycast.ts +2 -2
  118. package/packages/sdk-ts/src/workflows/README.md +450 -0
  119. package/packages/sdk-ts/src/workflows/barrier.ts +254 -0
  120. package/packages/sdk-ts/src/workflows/builder.ts +241 -0
  121. package/packages/sdk-ts/src/workflows/builtin-templates/bug-fix.yaml +75 -0
  122. package/packages/sdk-ts/src/workflows/builtin-templates/code-review.yaml +82 -0
  123. package/packages/sdk-ts/src/workflows/builtin-templates/documentation.yaml +70 -0
  124. package/packages/sdk-ts/src/workflows/builtin-templates/feature-dev.yaml +76 -0
  125. package/packages/sdk-ts/src/workflows/builtin-templates/refactor.yaml +82 -0
  126. package/packages/sdk-ts/src/workflows/builtin-templates/security-audit.yaml +84 -0
  127. package/packages/sdk-ts/src/workflows/cli.ts +93 -0
  128. package/packages/sdk-ts/src/workflows/coordinator.ts +520 -0
  129. package/packages/sdk-ts/src/workflows/index.ts +9 -0
  130. package/packages/sdk-ts/src/workflows/memory-db.ts +39 -0
  131. package/packages/sdk-ts/src/workflows/run.ts +47 -0
  132. package/packages/sdk-ts/src/workflows/runner.ts +873 -0
  133. package/packages/sdk-ts/src/workflows/schema.json +321 -0
  134. package/packages/sdk-ts/src/workflows/state.ts +279 -0
  135. package/packages/sdk-ts/src/workflows/templates.ts +544 -0
  136. package/packages/sdk-ts/src/workflows/types.ts +178 -0
  137. package/packages/sdk-ts/tsconfig.json +6 -1
  138. package/packages/spawner/package.json +1 -1
  139. package/packages/state/package.json +1 -1
  140. package/packages/storage/package.json +2 -2
  141. package/packages/telemetry/package.json +1 -1
  142. package/packages/trajectory/package.json +2 -2
  143. package/packages/user-directory/package.json +2 -2
  144. package/packages/utils/package.json +3 -3
  145. package/packages/wrapper/package.json +5 -6
  146. package/scripts/postinstall.js +106 -2
  147. package/packages/api-types/.trajectories/active/traj_xbsvuzogscey.json +0 -15
  148. package/packages/api-types/.trajectories/index.json +0 -12
  149. package/packages/api-types/dist/index.d.ts +0 -21
  150. package/packages/api-types/dist/index.d.ts.map +0 -1
  151. package/packages/api-types/dist/index.js +0 -22
  152. package/packages/api-types/dist/index.js.map +0 -1
  153. package/packages/api-types/dist/schemas/agent.d.ts +0 -259
  154. package/packages/api-types/dist/schemas/agent.d.ts.map +0 -1
  155. package/packages/api-types/dist/schemas/agent.js +0 -102
  156. package/packages/api-types/dist/schemas/agent.js.map +0 -1
  157. package/packages/api-types/dist/schemas/api.d.ts +0 -290
  158. package/packages/api-types/dist/schemas/api.d.ts.map +0 -1
  159. package/packages/api-types/dist/schemas/api.js +0 -162
  160. package/packages/api-types/dist/schemas/api.js.map +0 -1
  161. package/packages/api-types/dist/schemas/decision.d.ts +0 -230
  162. package/packages/api-types/dist/schemas/decision.d.ts.map +0 -1
  163. package/packages/api-types/dist/schemas/decision.js +0 -104
  164. package/packages/api-types/dist/schemas/decision.js.map +0 -1
  165. package/packages/api-types/dist/schemas/fleet.d.ts +0 -615
  166. package/packages/api-types/dist/schemas/fleet.d.ts.map +0 -1
  167. package/packages/api-types/dist/schemas/fleet.js +0 -71
  168. package/packages/api-types/dist/schemas/fleet.js.map +0 -1
  169. package/packages/api-types/dist/schemas/history.d.ts +0 -180
  170. package/packages/api-types/dist/schemas/history.d.ts.map +0 -1
  171. package/packages/api-types/dist/schemas/history.js +0 -72
  172. package/packages/api-types/dist/schemas/history.js.map +0 -1
  173. package/packages/api-types/dist/schemas/index.d.ts +0 -14
  174. package/packages/api-types/dist/schemas/index.d.ts.map +0 -1
  175. package/packages/api-types/dist/schemas/index.js +0 -22
  176. package/packages/api-types/dist/schemas/index.js.map +0 -1
  177. package/packages/api-types/dist/schemas/message.d.ts +0 -456
  178. package/packages/api-types/dist/schemas/message.d.ts.map +0 -1
  179. package/packages/api-types/dist/schemas/message.js +0 -88
  180. package/packages/api-types/dist/schemas/message.js.map +0 -1
  181. package/packages/api-types/dist/schemas/session.d.ts +0 -60
  182. package/packages/api-types/dist/schemas/session.d.ts.map +0 -1
  183. package/packages/api-types/dist/schemas/session.js +0 -36
  184. package/packages/api-types/dist/schemas/session.js.map +0 -1
  185. package/packages/api-types/dist/schemas/task.d.ts +0 -111
  186. package/packages/api-types/dist/schemas/task.d.ts.map +0 -1
  187. package/packages/api-types/dist/schemas/task.js +0 -64
  188. package/packages/api-types/dist/schemas/task.js.map +0 -1
  189. package/packages/api-types/package.json +0 -61
  190. package/packages/api-types/scripts/generate-openapi.ts +0 -106
  191. package/packages/api-types/src/index.ts +0 -22
  192. package/packages/api-types/src/schemas/agent.test.ts +0 -164
  193. package/packages/api-types/src/schemas/agent.ts +0 -110
  194. package/packages/api-types/src/schemas/api.test.ts +0 -372
  195. package/packages/api-types/src/schemas/api.ts +0 -194
  196. package/packages/api-types/src/schemas/decision.test.ts +0 -324
  197. package/packages/api-types/src/schemas/decision.ts +0 -136
  198. package/packages/api-types/src/schemas/fleet.test.ts +0 -212
  199. package/packages/api-types/src/schemas/fleet.ts +0 -83
  200. package/packages/api-types/src/schemas/history.test.ts +0 -242
  201. package/packages/api-types/src/schemas/history.ts +0 -84
  202. package/packages/api-types/src/schemas/index.ts +0 -148
  203. package/packages/api-types/src/schemas/message.test.ts +0 -192
  204. package/packages/api-types/src/schemas/message.ts +0 -98
  205. package/packages/api-types/src/schemas/session.test.ts +0 -104
  206. package/packages/api-types/src/schemas/session.ts +0 -40
  207. package/packages/api-types/src/schemas/task.test.ts +0 -192
  208. package/packages/api-types/src/schemas/task.ts +0 -78
  209. package/packages/api-types/tsconfig.json +0 -19
  210. package/packages/api-types/vitest.config.ts +0 -9
  211. package/packages/benchmark/README.md +0 -200
  212. package/packages/benchmark/datasets/coding-tasks.yaml +0 -127
  213. package/packages/benchmark/datasets/coordination-tasks.yaml +0 -122
  214. package/packages/benchmark/datasets/quick-test.yaml +0 -20
  215. package/packages/benchmark/dist/benchmark.d.ts +0 -47
  216. package/packages/benchmark/dist/benchmark.d.ts.map +0 -1
  217. package/packages/benchmark/dist/benchmark.js +0 -224
  218. package/packages/benchmark/dist/benchmark.js.map +0 -1
  219. package/packages/benchmark/dist/cli.d.ts +0 -8
  220. package/packages/benchmark/dist/cli.d.ts.map +0 -1
  221. package/packages/benchmark/dist/cli.js +0 -185
  222. package/packages/benchmark/dist/cli.js.map +0 -1
  223. package/packages/benchmark/dist/harbor.d.ts +0 -53
  224. package/packages/benchmark/dist/harbor.d.ts.map +0 -1
  225. package/packages/benchmark/dist/harbor.js +0 -127
  226. package/packages/benchmark/dist/harbor.js.map +0 -1
  227. package/packages/benchmark/dist/index.d.ts +0 -48
  228. package/packages/benchmark/dist/index.d.ts.map +0 -1
  229. package/packages/benchmark/dist/index.js +0 -50
  230. package/packages/benchmark/dist/index.js.map +0 -1
  231. package/packages/benchmark/dist/runners/base.d.ts +0 -63
  232. package/packages/benchmark/dist/runners/base.d.ts.map +0 -1
  233. package/packages/benchmark/dist/runners/base.js +0 -156
  234. package/packages/benchmark/dist/runners/base.js.map +0 -1
  235. package/packages/benchmark/dist/runners/index.d.ts +0 -10
  236. package/packages/benchmark/dist/runners/index.d.ts.map +0 -1
  237. package/packages/benchmark/dist/runners/index.js +0 -10
  238. package/packages/benchmark/dist/runners/index.js.map +0 -1
  239. package/packages/benchmark/dist/runners/single.d.ts +0 -19
  240. package/packages/benchmark/dist/runners/single.d.ts.map +0 -1
  241. package/packages/benchmark/dist/runners/single.js +0 -111
  242. package/packages/benchmark/dist/runners/single.js.map +0 -1
  243. package/packages/benchmark/dist/runners/subagent.d.ts +0 -32
  244. package/packages/benchmark/dist/runners/subagent.d.ts.map +0 -1
  245. package/packages/benchmark/dist/runners/subagent.js +0 -212
  246. package/packages/benchmark/dist/runners/subagent.js.map +0 -1
  247. package/packages/benchmark/dist/runners/swarm.d.ts +0 -36
  248. package/packages/benchmark/dist/runners/swarm.d.ts.map +0 -1
  249. package/packages/benchmark/dist/runners/swarm.js +0 -273
  250. package/packages/benchmark/dist/runners/swarm.js.map +0 -1
  251. package/packages/benchmark/dist/types.d.ts +0 -178
  252. package/packages/benchmark/dist/types.d.ts.map +0 -1
  253. package/packages/benchmark/dist/types.js +0 -16
  254. package/packages/benchmark/dist/types.js.map +0 -1
  255. package/packages/benchmark/package.json +0 -80
  256. package/packages/benchmark/src/benchmark.ts +0 -298
  257. package/packages/benchmark/src/cli.ts +0 -240
  258. package/packages/benchmark/src/harbor.ts +0 -170
  259. package/packages/benchmark/src/index.ts +0 -73
  260. package/packages/benchmark/src/runners/base.ts +0 -205
  261. package/packages/benchmark/src/runners/index.ts +0 -10
  262. package/packages/benchmark/src/runners/single.ts +0 -121
  263. package/packages/benchmark/src/runners/subagent.ts +0 -240
  264. package/packages/benchmark/src/runners/swarm.ts +0 -326
  265. package/packages/benchmark/src/types.ts +0 -205
  266. package/packages/benchmark/tsconfig.json +0 -20
  267. package/packages/cli-tester/README.md +0 -277
  268. package/packages/cli-tester/dist/index.d.ts +0 -21
  269. package/packages/cli-tester/dist/index.d.ts.map +0 -1
  270. package/packages/cli-tester/dist/index.js +0 -21
  271. package/packages/cli-tester/dist/index.js.map +0 -1
  272. package/packages/cli-tester/dist/utils/credential-check.d.ts +0 -56
  273. package/packages/cli-tester/dist/utils/credential-check.d.ts.map +0 -1
  274. package/packages/cli-tester/dist/utils/credential-check.js +0 -230
  275. package/packages/cli-tester/dist/utils/credential-check.js.map +0 -1
  276. package/packages/cli-tester/dist/utils/socket-client.d.ts +0 -76
  277. package/packages/cli-tester/dist/utils/socket-client.d.ts.map +0 -1
  278. package/packages/cli-tester/dist/utils/socket-client.js +0 -153
  279. package/packages/cli-tester/dist/utils/socket-client.js.map +0 -1
  280. package/packages/cli-tester/docker/Dockerfile +0 -61
  281. package/packages/cli-tester/docker/docker-compose.yml +0 -71
  282. package/packages/cli-tester/docker/entrypoint.sh +0 -58
  283. package/packages/cli-tester/package.json +0 -32
  284. package/packages/cli-tester/scripts/clear-auth.sh +0 -101
  285. package/packages/cli-tester/scripts/inject-message.sh +0 -42
  286. package/packages/cli-tester/scripts/start.sh +0 -71
  287. package/packages/cli-tester/scripts/test-cli.sh +0 -56
  288. package/packages/cli-tester/scripts/test-full-spawn.sh +0 -238
  289. package/packages/cli-tester/scripts/test-registration.sh +0 -182
  290. package/packages/cli-tester/scripts/test-setup-flow.sh +0 -202
  291. package/packages/cli-tester/scripts/test-spawn.sh +0 -140
  292. package/packages/cli-tester/scripts/test-with-daemon.sh +0 -247
  293. package/packages/cli-tester/scripts/verify-auth.sh +0 -112
  294. package/packages/cli-tester/src/index.ts +0 -40
  295. package/packages/cli-tester/src/utils/credential-check.ts +0 -284
  296. package/packages/cli-tester/src/utils/socket-client.ts +0 -211
  297. package/packages/cli-tester/tests/credential-check.test.ts +0 -56
  298. package/packages/cli-tester/tsconfig.json +0 -11
  299. package/packages/sdk/dist/browser-client.d.ts +0 -212
  300. package/packages/sdk/dist/browser-client.d.ts.map +0 -1
  301. package/packages/sdk/dist/browser-client.js +0 -750
  302. package/packages/sdk/dist/browser-client.js.map +0 -1
  303. package/packages/sdk/dist/browser-framing.d.ts +0 -46
  304. package/packages/sdk/dist/browser-framing.d.ts.map +0 -1
  305. package/packages/sdk/dist/browser-framing.js +0 -122
  306. package/packages/sdk/dist/browser-framing.js.map +0 -1
  307. package/packages/sdk/dist/standalone.d.ts +0 -89
  308. package/packages/sdk/dist/standalone.d.ts.map +0 -1
  309. package/packages/sdk/dist/standalone.js +0 -131
  310. package/packages/sdk/dist/standalone.js.map +0 -1
  311. package/packages/sdk/dist/transports/index.d.ts +0 -92
  312. package/packages/sdk/dist/transports/index.d.ts.map +0 -1
  313. package/packages/sdk/dist/transports/index.js +0 -129
  314. package/packages/sdk/dist/transports/index.js.map +0 -1
  315. package/packages/sdk/dist/transports/socket-transport.d.ts +0 -30
  316. package/packages/sdk/dist/transports/socket-transport.d.ts.map +0 -1
  317. package/packages/sdk/dist/transports/socket-transport.js +0 -94
  318. package/packages/sdk/dist/transports/socket-transport.js.map +0 -1
  319. package/packages/sdk/dist/transports/types.d.ts +0 -69
  320. package/packages/sdk/dist/transports/types.d.ts.map +0 -1
  321. package/packages/sdk/dist/transports/types.js +0 -10
  322. package/packages/sdk/dist/transports/types.js.map +0 -1
  323. package/packages/sdk/dist/transports/websocket-transport.d.ts +0 -55
  324. package/packages/sdk/dist/transports/websocket-transport.d.ts.map +0 -1
  325. package/packages/sdk/dist/transports/websocket-transport.js +0 -180
  326. package/packages/sdk/dist/transports/websocket-transport.js.map +0 -1
  327. package/packages/sdk/src/browser-client.ts +0 -985
  328. package/packages/sdk/src/browser-framing.test.ts +0 -115
  329. package/packages/sdk/src/browser-framing.ts +0 -150
  330. package/packages/sdk/src/standalone.ts +0 -183
  331. package/packages/sdk/src/transports/index.ts +0 -197
  332. package/packages/sdk/src/transports/socket-transport.ts +0 -115
  333. package/packages/sdk/src/transports/types.ts +0 -77
  334. package/packages/sdk/src/transports/websocket-transport.ts +0 -245
@@ -3,20 +3,7 @@
3
3
  *
4
4
  * Lightweight SDK for agent-to-agent communication via Agent Relay.
5
5
  *
6
- * ## Quick Start (Standalone - No Setup Required)
7
- *
8
- * ```typescript
9
- * import { createRelay } from '@agent-relay/sdk';
10
- *
11
- * const relay = await createRelay();
12
- * const alice = await relay.client('Alice');
13
- * const bob = await relay.client('Bob');
14
- *
15
- * bob.onMessage = (from, { body }) => console.log(`${from}: ${body}`);
16
- * alice.sendMessage('Bob', 'Hello!');
17
- * ```
18
- *
19
- * ## With External Daemon
6
+ * ## Quick Start
20
7
  *
21
8
  * ```typescript
22
9
  * import { RelayClient } from '@agent-relay/sdk';
@@ -24,33 +11,9 @@
24
11
  * const client = new RelayClient({ agentName: 'MyAgent' });
25
12
  * await client.connect();
26
13
  * ```
27
- *
28
- * ## Browser Usage (WebSocket)
29
- *
30
- * ```typescript
31
- * import { BrowserRelayClient } from '@agent-relay/sdk';
32
- *
33
- * const client = new BrowserRelayClient({
34
- * agentName: 'BrowserAgent',
35
- * transport: { wsUrl: 'wss://relay.example.com/ws' },
36
- * });
37
- * await client.connect();
38
- * ```
39
14
  */
40
15
  // Main client (Node.js, Unix sockets)
41
16
  export { RelayClient, } from './client.js';
42
- // Browser-compatible client (WebSocket)
43
- export { BrowserRelayClient, } from './browser-client.js';
44
- // Transport abstractions
45
- export {
46
- // Socket transport (Node.js)
47
- SocketTransport, createSocketTransport,
48
- // WebSocket transport (Browser + Node.js)
49
- WebSocketTransport, createWebSocketTransport, socketPathToWsUrl,
50
- // Auto-detection
51
- createAutoTransport, detectEnvironment, isBrowser, isNode, } from './transports/index.js';
52
- // Standalone relay (in-process daemon for simple use cases)
53
- export { createRelay, createPair, } from './standalone.js';
54
17
  // Protocol types (re-export for convenience)
55
18
  export { PROTOCOL_VERSION, } from './protocol/index.js';
56
19
  // Framing utilities
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,sCAAsC;AACtC,OAAO,EACL,WAAW,GAOZ,MAAM,aAAa,CAAC;AAErB,wCAAwC;AACxC,OAAO,EACL,kBAAkB,GAKnB,MAAM,qBAAqB,CAAC;AAE7B,yBAAyB;AACzB,OAAO;AAOL,6BAA6B;AAC7B,eAAe,EACf,qBAAqB;AAErB,0CAA0C;AAC1C,kBAAkB,EAClB,wBAAwB,EACxB,iBAAiB;AAEjB,iBAAiB;AACjB,mBAAmB,EAEnB,iBAAiB,EAEjB,SAAS,EACT,MAAM,GACP,MAAM,uBAAuB,CAAC;AAE/B,4DAA4D;AAC5D,OAAO,EACL,WAAW,EACX,UAAU,GAGX,MAAM,iBAAiB,CAAC;AAEzB,6CAA6C;AAC7C,OAAO,EACL,gBAAgB,GA0CjB,MAAM,qBAAqB,CAAC;AAE7B,oBAAoB;AACpB,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAE7B,yDAAyD;AACzD,OAAO,EACL,OAAO,EACP,gBAAgB,GAGjB,MAAM,WAAW,CAAC;AAEnB,0EAA0E;AAC1E,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,0BAA0B,EAC1B,eAAe,EACf,kBAAkB,GAKnB,MAAM,gBAAgB,CAAC;AAExB,cAAc;AACd,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,UAAU,GACX,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,sCAAsC;AACtC,OAAO,EACL,WAAW,GAOZ,MAAM,aAAa,CAAC;AAErB,6CAA6C;AAC7C,OAAO,EACL,gBAAgB,GA0CjB,MAAM,qBAAqB,CAAC;AAE7B,oBAAoB;AACpB,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAE7B,yDAAyD;AACzD,OAAO,EACL,OAAO,EACP,gBAAgB,GAGjB,MAAM,WAAW,CAAC;AAEnB,0EAA0E;AAC1E,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,0BAA0B,EAC1B,eAAe,EACf,kBAAkB,GAKnB,MAAM,gBAAgB,CAAC;AAExB,cAAc;AACd,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,UAAU,GACX,MAAM,aAAa,CAAC"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-relay/sdk",
3
- "version": "2.3.2",
3
+ "version": "2.3.5",
4
4
  "description": "Lightweight SDK for agent-to-agent communication via Agent Relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -10,11 +10,6 @@
10
10
  "types": "./dist/index.d.ts",
11
11
  "import": "./dist/index.js"
12
12
  },
13
- "./standalone": {
14
- "types": "./dist/standalone.d.ts",
15
- "import": "./dist/standalone.js",
16
- "default": "./dist/standalone.js"
17
- },
18
13
  "./protocol": {
19
14
  "types": "./dist/protocol/index.d.ts",
20
15
  "import": "./dist/protocol/index.js",
@@ -25,16 +20,6 @@
25
20
  "import": "./dist/client.js",
26
21
  "default": "./dist/client.js"
27
22
  },
28
- "./browser": {
29
- "types": "./dist/browser-client.d.ts",
30
- "import": "./dist/browser-client.js",
31
- "default": "./dist/browser-client.js"
32
- },
33
- "./transports": {
34
- "types": "./dist/transports/index.d.ts",
35
- "import": "./dist/transports/index.js",
36
- "default": "./dist/transports/index.js"
37
- },
38
23
  "./discovery": {
39
24
  "types": "./dist/discovery.d.ts",
40
25
  "import": "./dist/discovery.js",
@@ -62,9 +47,7 @@
62
47
  "agent",
63
48
  "ai",
64
49
  "communication",
65
- "sdk",
66
- "websocket",
67
- "browser"
50
+ "sdk"
68
51
  ],
69
52
  "author": "Khaliq Gant",
70
53
  "license": "Apache-2.0",
@@ -77,8 +60,8 @@
77
60
  "access": "public"
78
61
  },
79
62
  "dependencies": {
80
- "@agent-relay/protocol": "2.3.2",
81
- "@agent-relay/utils": "2.3.2"
63
+ "@agent-relay/protocol": "2.3.5",
64
+ "@agent-relay/utils": "2.3.5"
82
65
  },
83
66
  "engines": {
84
67
  "node": ">=18.0.0"
@@ -91,10 +74,6 @@
91
74
  "optional": true
92
75
  }
93
76
  },
94
- "optionalDependencies": {
95
- "@msgpack/msgpack": "^3.0.0",
96
- "ws": "^8.0.0"
97
- },
98
77
  "devDependencies": {
99
78
  "@types/node": "^22.19.3",
100
79
  "typescript": "^5.9.3",
@@ -3,20 +3,7 @@
3
3
  *
4
4
  * Lightweight SDK for agent-to-agent communication via Agent Relay.
5
5
  *
6
- * ## Quick Start (Standalone - No Setup Required)
7
- *
8
- * ```typescript
9
- * import { createRelay } from '@agent-relay/sdk';
10
- *
11
- * const relay = await createRelay();
12
- * const alice = await relay.client('Alice');
13
- * const bob = await relay.client('Bob');
14
- *
15
- * bob.onMessage = (from, { body }) => console.log(`${from}: ${body}`);
16
- * alice.sendMessage('Bob', 'Hello!');
17
- * ```
18
- *
19
- * ## With External Daemon
6
+ * ## Quick Start
20
7
  *
21
8
  * ```typescript
22
9
  * import { RelayClient } from '@agent-relay/sdk';
@@ -24,18 +11,6 @@
24
11
  * const client = new RelayClient({ agentName: 'MyAgent' });
25
12
  * await client.connect();
26
13
  * ```
27
- *
28
- * ## Browser Usage (WebSocket)
29
- *
30
- * ```typescript
31
- * import { BrowserRelayClient } from '@agent-relay/sdk';
32
- *
33
- * const client = new BrowserRelayClient({
34
- * agentName: 'BrowserAgent',
35
- * transport: { wsUrl: 'wss://relay.example.com/ws' },
36
- * });
37
- * await client.connect();
38
- * ```
39
14
  */
40
15
 
41
16
  // Main client (Node.js, Unix sockets)
@@ -49,49 +24,6 @@ export {
49
24
  type SpawnResult,
50
25
  } from './client.js';
51
26
 
52
- // Browser-compatible client (WebSocket)
53
- export {
54
- BrowserRelayClient,
55
- type BrowserClientState,
56
- type BrowserClientConfig,
57
- type BrowserRequestOptions,
58
- type BrowserRequestResponse,
59
- } from './browser-client.js';
60
-
61
- // Transport abstractions
62
- export {
63
- // Types
64
- type Transport,
65
- type TransportConfig,
66
- type TransportEvents,
67
- type TransportState,
68
- type TransportFactory,
69
- // Socket transport (Node.js)
70
- SocketTransport,
71
- createSocketTransport,
72
- type SocketTransportConfig,
73
- // WebSocket transport (Browser + Node.js)
74
- WebSocketTransport,
75
- createWebSocketTransport,
76
- socketPathToWsUrl,
77
- type WebSocketTransportConfig,
78
- // Auto-detection
79
- createAutoTransport,
80
- type AutoTransportOptions,
81
- detectEnvironment,
82
- type EnvironmentInfo,
83
- isBrowser,
84
- isNode,
85
- } from './transports/index.js';
86
-
87
- // Standalone relay (in-process daemon for simple use cases)
88
- export {
89
- createRelay,
90
- createPair,
91
- type Relay,
92
- type RelayConfig,
93
- } from './standalone.js';
94
-
95
27
  // Protocol types (re-export for convenience)
96
28
  export {
97
29
  PROTOCOL_VERSION,
@@ -0,0 +1,56 @@
1
+ # Agent Relay Python SDK
2
+
3
+ Python SDK for defining and running Agent Relay workflows.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install agent-relay
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Builder API
14
+
15
+ ```python
16
+ from agent_relay import workflow
17
+
18
+ result = (
19
+ workflow("my-migration")
20
+ .pattern("dag")
21
+ .agent("backend", cli="claude", role="Backend engineer")
22
+ .agent("tester", cli="claude", role="Test engineer")
23
+ .step("build", agent="backend", task="Build the API endpoints")
24
+ .step("test", agent="tester", task="Write tests", depends_on=["build"])
25
+ .run()
26
+ )
27
+ ```
28
+
29
+ ### Run from YAML
30
+
31
+ ```python
32
+ from agent_relay import run_yaml
33
+
34
+ result = run_yaml("workflows/daytona-migration.yaml")
35
+ ```
36
+
37
+ ### Export to YAML
38
+
39
+ ```python
40
+ config_yaml = (
41
+ workflow("my-workflow")
42
+ .pattern("fan-out")
43
+ .agent("worker", cli="claude")
44
+ .step("task1", agent="worker", task="Do something")
45
+ .to_yaml()
46
+ )
47
+ ```
48
+
49
+ ## Requirements
50
+
51
+ - Python 3.10+
52
+ - `agent-relay` CLI installed (`npm install -g agent-relay`)
53
+
54
+ ## License
55
+
56
+ Apache-2.0 — Copyright 2025 Agent Workforce Incorporated
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "agent-relay"
7
+ version = "0.1.0"
8
+ description = "Python SDK for Agent Relay workflows"
9
+ readme = "README.md"
10
+ license = "Apache-2.0"
11
+ requires-python = ">=3.10"
12
+ dependencies = [
13
+ "pyyaml>=6.0",
14
+ ]
15
+
16
+ [project.optional-dependencies]
17
+ dev = [
18
+ "pytest>=8.0",
19
+ "pytest-asyncio>=0.23",
20
+ ]
21
+
22
+ [tool.hatch.build.targets.wheel]
23
+ packages = ["src/agent_relay"]
@@ -0,0 +1,27 @@
1
+ """Agent Relay Python SDK — workflow builder and runner."""
2
+
3
+ from .builder import workflow, WorkflowBuilder, run_yaml
4
+ from .types import (
5
+ AgentOptions,
6
+ StepOptions,
7
+ ErrorOptions,
8
+ RunOptions,
9
+ WorkflowResult,
10
+ SwarmPattern,
11
+ AgentCli,
12
+ VerificationCheck,
13
+ )
14
+
15
+ __all__ = [
16
+ "workflow",
17
+ "WorkflowBuilder",
18
+ "run_yaml",
19
+ "AgentOptions",
20
+ "StepOptions",
21
+ "ErrorOptions",
22
+ "RunOptions",
23
+ "WorkflowResult",
24
+ "SwarmPattern",
25
+ "AgentCli",
26
+ "VerificationCheck",
27
+ ]
@@ -0,0 +1,367 @@
1
+ """Fluent workflow builder for Agent Relay.
2
+
3
+ Example::
4
+
5
+ from agent_relay import workflow
6
+
7
+ result = (
8
+ workflow("my-migration")
9
+ .pattern("dag")
10
+ .agent("backend", cli="claude", role="Backend engineer")
11
+ .agent("tester", cli="claude", role="Test engineer")
12
+ .step("build", agent="backend", task="Build the API endpoints")
13
+ .step("test", agent="tester", task="Write integration tests", depends_on=["build"])
14
+ .run()
15
+ )
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import json
21
+ import shutil
22
+ import subprocess
23
+ import tempfile
24
+ from pathlib import Path
25
+ from typing import Any
26
+
27
+ import yaml
28
+
29
+ from .types import (
30
+ AgentCli,
31
+ AgentOptions,
32
+ ErrorOptions,
33
+ RunOptions,
34
+ StepOptions,
35
+ StepResult,
36
+ SwarmPattern,
37
+ VerificationCheck,
38
+ WorkflowResult,
39
+ )
40
+
41
+
42
+ class WorkflowBuilder:
43
+ """Fluent builder that constructs a RelayYamlConfig and runs it via agent-relay CLI."""
44
+
45
+ def __init__(self, name: str) -> None:
46
+ self._name = name
47
+ self._description: str | None = None
48
+ self._pattern: SwarmPattern = "dag"
49
+ self._max_concurrency: int | None = None
50
+ self._timeout_ms: int | None = None
51
+ self._channel: str | None = None
52
+ self._agents: list[dict[str, Any]] = []
53
+ self._steps: list[dict[str, Any]] = []
54
+ self._error_handling: dict[str, Any] | None = None
55
+
56
+ def description(self, desc: str) -> WorkflowBuilder:
57
+ """Set workflow description."""
58
+ self._description = desc
59
+ return self
60
+
61
+ def pattern(self, p: SwarmPattern) -> WorkflowBuilder:
62
+ """Set swarm pattern (default: "dag")."""
63
+ self._pattern = p
64
+ return self
65
+
66
+ def max_concurrency(self, n: int) -> WorkflowBuilder:
67
+ """Set maximum concurrent agents."""
68
+ self._max_concurrency = n
69
+ return self
70
+
71
+ def timeout(self, ms: int) -> WorkflowBuilder:
72
+ """Set global timeout in milliseconds."""
73
+ self._timeout_ms = ms
74
+ return self
75
+
76
+ def channel(self, ch: str) -> WorkflowBuilder:
77
+ """Set the relay channel for agent communication."""
78
+ self._channel = ch
79
+ return self
80
+
81
+ def agent(
82
+ self,
83
+ name: str,
84
+ *,
85
+ cli: AgentCli = "claude",
86
+ role: str | None = None,
87
+ task: str | None = None,
88
+ channels: list[str] | None = None,
89
+ model: str | None = None,
90
+ max_tokens: int | None = None,
91
+ timeout_ms: int | None = None,
92
+ retries: int | None = None,
93
+ ) -> WorkflowBuilder:
94
+ """Add an agent definition."""
95
+ opts = AgentOptions(
96
+ cli=cli,
97
+ role=role,
98
+ task=task,
99
+ channels=channels,
100
+ model=model,
101
+ max_tokens=max_tokens,
102
+ timeout_ms=timeout_ms,
103
+ retries=retries,
104
+ )
105
+ agent_def: dict[str, Any] = {"name": name, "cli": opts.cli}
106
+
107
+ if opts.role is not None:
108
+ agent_def["role"] = opts.role
109
+ if opts.task is not None:
110
+ agent_def["task"] = opts.task
111
+ if opts.channels is not None:
112
+ agent_def["channels"] = opts.channels
113
+
114
+ constraints: dict[str, Any] = {}
115
+ if opts.model is not None:
116
+ constraints["model"] = opts.model
117
+ if opts.max_tokens is not None:
118
+ constraints["maxTokens"] = opts.max_tokens
119
+ if opts.timeout_ms is not None:
120
+ constraints["timeoutMs"] = opts.timeout_ms
121
+ if opts.retries is not None:
122
+ constraints["retries"] = opts.retries
123
+ if constraints:
124
+ agent_def["constraints"] = constraints
125
+
126
+ self._agents.append(agent_def)
127
+ return self
128
+
129
+ def step(
130
+ self,
131
+ name: str,
132
+ *,
133
+ agent: str,
134
+ task: str,
135
+ depends_on: list[str] | None = None,
136
+ verification: VerificationCheck | None = None,
137
+ timeout_ms: int | None = None,
138
+ retries: int | None = None,
139
+ ) -> WorkflowBuilder:
140
+ """Add a workflow step."""
141
+ opts = StepOptions(
142
+ agent=agent,
143
+ task=task,
144
+ depends_on=depends_on,
145
+ verification=verification,
146
+ timeout_ms=timeout_ms,
147
+ retries=retries,
148
+ )
149
+ step_def: dict[str, Any] = {
150
+ "name": name,
151
+ "agent": opts.agent,
152
+ "task": opts.task,
153
+ }
154
+
155
+ if opts.depends_on is not None:
156
+ step_def["dependsOn"] = opts.depends_on
157
+ if opts.verification is not None:
158
+ step_def["verification"] = opts.verification.to_dict()
159
+ if opts.timeout_ms is not None:
160
+ step_def["timeoutMs"] = opts.timeout_ms
161
+ if opts.retries is not None:
162
+ step_def["retries"] = opts.retries
163
+
164
+ self._steps.append(step_def)
165
+ return self
166
+
167
+ def on_error(
168
+ self,
169
+ strategy: str,
170
+ *,
171
+ max_retries: int | None = None,
172
+ retry_delay_ms: int | None = None,
173
+ notify_channel: str | None = None,
174
+ ) -> WorkflowBuilder:
175
+ """Set error handling strategy."""
176
+ opts = ErrorOptions(
177
+ max_retries=max_retries,
178
+ retry_delay_ms=retry_delay_ms,
179
+ notify_channel=notify_channel,
180
+ )
181
+ self._error_handling = {"strategy": strategy}
182
+ if opts.max_retries is not None:
183
+ self._error_handling["maxRetries"] = opts.max_retries
184
+ if opts.retry_delay_ms is not None:
185
+ self._error_handling["retryDelayMs"] = opts.retry_delay_ms
186
+ if opts.notify_channel is not None:
187
+ self._error_handling["notifyChannel"] = opts.notify_channel
188
+ return self
189
+
190
+ def to_config(self) -> dict[str, Any]:
191
+ """Build and return the config as a dictionary (matches RelayYamlConfig shape)."""
192
+ if not self._agents:
193
+ raise ValueError("Workflow must have at least one agent")
194
+ if not self._steps:
195
+ raise ValueError("Workflow must have at least one step")
196
+
197
+ swarm: dict[str, Any] = {"pattern": self._pattern}
198
+ if self._max_concurrency is not None:
199
+ swarm["maxConcurrency"] = self._max_concurrency
200
+ if self._timeout_ms is not None:
201
+ swarm["timeoutMs"] = self._timeout_ms
202
+ if self._channel is not None:
203
+ swarm["channel"] = self._channel
204
+
205
+ config: dict[str, Any] = {
206
+ "version": "1.0",
207
+ "name": self._name,
208
+ "swarm": swarm,
209
+ "agents": list(self._agents),
210
+ "workflows": [
211
+ {
212
+ "name": f"{self._name}-workflow",
213
+ "steps": list(self._steps),
214
+ }
215
+ ],
216
+ }
217
+
218
+ if self._description is not None:
219
+ config["description"] = self._description
220
+ if self._error_handling is not None:
221
+ config["errorHandling"] = self._error_handling
222
+
223
+ return config
224
+
225
+ def to_yaml(self) -> str:
226
+ """Serialize the config to a YAML string."""
227
+ return yaml.dump(self.to_config(), default_flow_style=False, sort_keys=False)
228
+
229
+ def run(self, options: RunOptions | None = None) -> WorkflowResult:
230
+ """Build the config, write to a temp YAML file, and execute via agent-relay CLI.
231
+
232
+ Requires ``agent-relay`` to be installed and available on PATH.
233
+ """
234
+ opts = options or RunOptions()
235
+
236
+ cmd_prefix = _find_agent_relay()
237
+ if cmd_prefix is None:
238
+ raise RuntimeError(
239
+ "agent-relay CLI not found. Install it with: npm install -g agent-relay"
240
+ )
241
+
242
+ config_yaml = self.to_yaml()
243
+
244
+ with tempfile.NamedTemporaryFile(
245
+ mode="w", suffix=".yaml", prefix="relay-workflow-", delete=False
246
+ ) as f:
247
+ f.write(config_yaml)
248
+ yaml_path = f.name
249
+
250
+ try:
251
+ cmd = [*cmd_prefix, "run", yaml_path]
252
+ if opts.workflow:
253
+ cmd.extend(["--workflow", opts.workflow])
254
+
255
+ result = subprocess.run(
256
+ cmd,
257
+ capture_output=True,
258
+ text=True,
259
+ cwd=opts.cwd,
260
+ )
261
+
262
+ return _parse_cli_output(result)
263
+
264
+ finally:
265
+ Path(yaml_path).unlink(missing_ok=True)
266
+
267
+
268
+ def workflow(name: str) -> WorkflowBuilder:
269
+ """Create a new workflow builder.
270
+
271
+ Example::
272
+
273
+ from agent_relay import workflow
274
+
275
+ result = (
276
+ workflow("feature-build")
277
+ .pattern("dag")
278
+ .agent("dev", cli="claude", role="Developer")
279
+ .step("implement", agent="dev", task="Build the feature")
280
+ .run()
281
+ )
282
+ """
283
+ return WorkflowBuilder(name)
284
+
285
+
286
+ def run_yaml(yaml_path: str, options: RunOptions | None = None) -> WorkflowResult:
287
+ """Run an existing relay.yaml workflow file.
288
+
289
+ Example::
290
+
291
+ from agent_relay import run_yaml
292
+
293
+ result = run_yaml("workflows/daytona-migration.yaml")
294
+ """
295
+ opts = options or RunOptions()
296
+
297
+ cmd_prefix = _find_agent_relay()
298
+ if cmd_prefix is None:
299
+ raise RuntimeError(
300
+ "agent-relay CLI not found. Install it with: npm install -g agent-relay"
301
+ )
302
+
303
+ cmd = [*cmd_prefix, "run", yaml_path]
304
+ if opts.workflow:
305
+ cmd.extend(["--workflow", opts.workflow])
306
+
307
+ result = subprocess.run(
308
+ cmd,
309
+ capture_output=True,
310
+ text=True,
311
+ cwd=opts.cwd,
312
+ )
313
+
314
+ return _parse_cli_output(result)
315
+
316
+
317
+ # ── Internal helpers ─────────────────────────────────────────────────────────
318
+
319
+
320
+ def _find_agent_relay() -> list[str] | None:
321
+ """Find the agent-relay binary on PATH or via npx. Returns the command prefix."""
322
+ binary = shutil.which("agent-relay")
323
+ if binary:
324
+ return [binary]
325
+
326
+ # Check if npx is available as fallback
327
+ npx = shutil.which("npx")
328
+ if npx:
329
+ return [npx, "agent-relay"]
330
+
331
+ return None
332
+
333
+
334
+ def _parse_cli_output(result: subprocess.CompletedProcess[str]) -> WorkflowResult:
335
+ """Parse agent-relay CLI output into a WorkflowResult."""
336
+ output = result.stdout.strip()
337
+ lines = output.split("\n") if output else []
338
+
339
+ steps: list[StepResult] = []
340
+ for line in lines:
341
+ if line.startswith("[step]"):
342
+ parts = line.removeprefix("[step]").strip().split(" ", 1)
343
+ if len(parts) >= 2:
344
+ step_name = parts[0]
345
+ rest = parts[1]
346
+ if "completed" in rest:
347
+ steps.append(StepResult(name=step_name, status="completed"))
348
+ elif "failed" in rest:
349
+ error = rest.split(":", 1)[1].strip() if ":" in rest else None
350
+ steps.append(StepResult(name=step_name, status="failed", error=error))
351
+ elif "skipped" in rest:
352
+ steps.append(StepResult(name=step_name, status="skipped"))
353
+
354
+ if result.returncode == 0:
355
+ return WorkflowResult(
356
+ status="completed",
357
+ run_id="", # CLI doesn't expose run ID yet
358
+ steps=steps,
359
+ )
360
+
361
+ error = result.stderr.strip() or result.stdout.strip()
362
+ return WorkflowResult(
363
+ status="failed",
364
+ run_id="",
365
+ error=error,
366
+ steps=steps,
367
+ )