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
@@ -1,750 +0,0 @@
1
- /**
2
- * BrowserRelayClient - Browser-compatible Agent Relay SDK Client
3
- * @agent-relay/sdk
4
- *
5
- * A client designed for browser environments using WebSocket transport.
6
- * Can also be used in Node.js with the WebSocket transport.
7
- *
8
- * Key differences from RelayClient:
9
- * - Uses transport abstraction instead of direct socket access
10
- * - No Node.js-specific dependencies (node:net, node:crypto)
11
- * - Uses browser-compatible APIs (crypto.randomUUID, etc.)
12
- */
13
- import { createAutoTransport, } from './transports/index.js';
14
- import { PROTOCOL_VERSION, } from '@agent-relay/protocol';
15
- import { encodeFrameLegacyBrowser, BrowserFrameParser } from './browser-framing.js';
16
- const DEFAULT_CONFIG = {
17
- agentName: 'agent',
18
- quiet: false,
19
- reconnect: true,
20
- maxReconnectAttempts: 10,
21
- reconnectDelayMs: 1000,
22
- reconnectMaxDelayMs: 30000,
23
- };
24
- // Simple ID generator (browser-compatible)
25
- let idCounter = 0;
26
- function generateId() {
27
- return `${Date.now().toString(36)}-${(++idCounter).toString(36)}`;
28
- }
29
- // Browser-compatible UUID generator
30
- function generateUUID() {
31
- // Use crypto.randomUUID if available (modern browsers)
32
- if (typeof crypto !== 'undefined' && crypto.randomUUID) {
33
- return crypto.randomUUID();
34
- }
35
- // Fallback: simple UUID v4 implementation
36
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
37
- const r = (Math.random() * 16) | 0;
38
- const v = c === 'x' ? r : (r & 0x3) | 0x8;
39
- return v.toString(16);
40
- });
41
- }
42
- /**
43
- * Circular buffer for O(1) deduplication with bounded memory.
44
- */
45
- class CircularDedupeCache {
46
- ids = new Set();
47
- ring;
48
- head = 0;
49
- capacity;
50
- constructor(capacity = 2000) {
51
- this.capacity = capacity;
52
- this.ring = new Array(capacity);
53
- }
54
- check(id) {
55
- if (this.ids.has(id))
56
- return true;
57
- if (this.ids.size >= this.capacity) {
58
- const oldest = this.ring[this.head];
59
- if (oldest)
60
- this.ids.delete(oldest);
61
- }
62
- this.ring[this.head] = id;
63
- this.ids.add(id);
64
- this.head = (this.head + 1) % this.capacity;
65
- return false;
66
- }
67
- clear() {
68
- this.ids.clear();
69
- this.ring = new Array(this.capacity);
70
- this.head = 0;
71
- }
72
- }
73
- /**
74
- * BrowserRelayClient - A browser-compatible relay client.
75
- *
76
- * Uses WebSocket transport by default, making it compatible with browsers.
77
- * Can also be used in Node.js for WebSocket-based connections.
78
- *
79
- * @example Browser usage
80
- * ```typescript
81
- * import { BrowserRelayClient } from '@agent-relay/sdk/browser';
82
- *
83
- * const client = new BrowserRelayClient({
84
- * agentName: 'MyAgent',
85
- * transport: {
86
- * wsUrl: 'wss://relay.example.com/ws',
87
- * },
88
- * });
89
- *
90
- * await client.connect();
91
- *
92
- * client.onMessage = (from, payload) => {
93
- * console.log(`Message from ${from}: ${payload.body}`);
94
- * };
95
- *
96
- * client.sendMessage('OtherAgent', 'Hello!');
97
- * ```
98
- */
99
- export class BrowserRelayClient {
100
- config;
101
- transport;
102
- parser;
103
- _state = 'DISCONNECTED';
104
- sessionId;
105
- resumeToken;
106
- reconnectAttempts = 0;
107
- reconnectDelay;
108
- reconnectTimer;
109
- _destroyed = false;
110
- dedupeCache = new CircularDedupeCache(2000);
111
- writeQueue = [];
112
- writeScheduled = false;
113
- pendingSyncAcks = new Map();
114
- pendingRequests = new Map();
115
- // Event handlers
116
- onMessage;
117
- onChannelMessage;
118
- onStateChange;
119
- onError;
120
- constructor(config) {
121
- this.config = { ...DEFAULT_CONFIG, ...config };
122
- this.parser = new BrowserFrameParser(); // Always uses legacy mode (4-byte header, JSON only)
123
- this.reconnectDelay = this.config.reconnectDelayMs ?? DEFAULT_CONFIG.reconnectDelayMs;
124
- }
125
- get state() {
126
- return this._state;
127
- }
128
- get agentName() {
129
- return this.config.agentName;
130
- }
131
- get currentSessionId() {
132
- return this.sessionId;
133
- }
134
- /**
135
- * Connect to the relay daemon.
136
- */
137
- async connect() {
138
- if (this._state !== 'DISCONNECTED' && this._state !== 'BACKOFF') {
139
- return;
140
- }
141
- this.setState('CONNECTING');
142
- // Create transport if not provided
143
- if (!this.transport) {
144
- if (this.config.transportInstance) {
145
- this.transport = this.config.transportInstance;
146
- }
147
- else if (this.config.transport) {
148
- this.transport = createAutoTransport(this.config.transport);
149
- }
150
- else {
151
- throw new Error('Transport configuration required. Provide either transport options or transportInstance.');
152
- }
153
- }
154
- // Set up transport events
155
- this.transport.setEvents({
156
- onConnect: () => {
157
- this.setState('HANDSHAKING');
158
- this.sendHello();
159
- },
160
- onData: (data) => this.handleData(data),
161
- onClose: () => this.handleDisconnect(),
162
- onError: (err) => this.handleError(err),
163
- });
164
- try {
165
- await this.transport.connect();
166
- // Wait for READY state
167
- await new Promise((resolve, reject) => {
168
- let checkReady;
169
- const cleanup = () => {
170
- clearInterval(checkReady);
171
- clearTimeout(timeout);
172
- };
173
- const timeout = setTimeout(() => {
174
- cleanup();
175
- reject(new Error('Connection handshake timeout'));
176
- }, 5000);
177
- checkReady = setInterval(() => {
178
- if (this._state === 'READY') {
179
- cleanup();
180
- resolve();
181
- }
182
- else if (this._state === 'DISCONNECTED') {
183
- cleanup();
184
- reject(new Error('Connection failed'));
185
- }
186
- }, 10);
187
- });
188
- }
189
- catch (err) {
190
- this.setState('DISCONNECTED');
191
- throw err;
192
- }
193
- }
194
- /**
195
- * Disconnect from the relay daemon.
196
- */
197
- disconnect() {
198
- if (this.reconnectTimer) {
199
- clearTimeout(this.reconnectTimer);
200
- this.reconnectTimer = undefined;
201
- }
202
- if (this.transport) {
203
- // Send BYE message
204
- this.send({
205
- v: PROTOCOL_VERSION,
206
- type: 'BYE',
207
- id: generateId(),
208
- ts: Date.now(),
209
- payload: {},
210
- });
211
- this.transport.disconnect();
212
- this.transport = undefined;
213
- }
214
- this.setState('DISCONNECTED');
215
- }
216
- /**
217
- * Permanently destroy the client.
218
- */
219
- destroy() {
220
- this._destroyed = true;
221
- this.disconnect();
222
- }
223
- /**
224
- * Send a message to another agent.
225
- */
226
- sendMessage(to, body, kind = 'message', data, thread, meta) {
227
- if (this._state !== 'READY') {
228
- return false;
229
- }
230
- const envelope = {
231
- v: PROTOCOL_VERSION,
232
- type: 'SEND',
233
- id: generateId(),
234
- ts: Date.now(),
235
- to,
236
- payload: {
237
- kind,
238
- body,
239
- data,
240
- thread,
241
- },
242
- payload_meta: meta,
243
- };
244
- return this.send(envelope);
245
- }
246
- /**
247
- * Send an ACK for a delivered message.
248
- */
249
- sendAck(payload) {
250
- if (this._state !== 'READY') {
251
- return false;
252
- }
253
- const envelope = {
254
- v: PROTOCOL_VERSION,
255
- type: 'ACK',
256
- id: generateId(),
257
- ts: Date.now(),
258
- payload,
259
- };
260
- return this.send(envelope);
261
- }
262
- /**
263
- * Send a request to another agent and wait for their response.
264
- */
265
- async request(to, body, options = {}) {
266
- if (this._state !== 'READY') {
267
- throw new Error('Client not ready');
268
- }
269
- const correlationId = generateUUID();
270
- const timeoutMs = options.timeout ?? 30000;
271
- const kind = options.kind ?? 'message';
272
- return new Promise((resolve, reject) => {
273
- const timeoutHandle = setTimeout(() => {
274
- this.pendingRequests.delete(correlationId);
275
- reject(new Error(`Request timeout after ${timeoutMs}ms waiting for response from ${to}`));
276
- }, timeoutMs);
277
- this.pendingRequests.set(correlationId, {
278
- resolve,
279
- reject,
280
- timeoutHandle,
281
- targetAgent: to,
282
- });
283
- const envelope = {
284
- v: PROTOCOL_VERSION,
285
- type: 'SEND',
286
- id: generateId(),
287
- ts: Date.now(),
288
- to,
289
- payload: {
290
- kind,
291
- body,
292
- data: {
293
- ...options.data,
294
- _correlationId: correlationId,
295
- },
296
- thread: options.thread,
297
- },
298
- payload_meta: {
299
- replyTo: correlationId,
300
- },
301
- };
302
- const sent = this.send(envelope);
303
- if (!sent) {
304
- clearTimeout(timeoutHandle);
305
- this.pendingRequests.delete(correlationId);
306
- reject(new Error('Failed to send request'));
307
- }
308
- });
309
- }
310
- /**
311
- * Respond to a request from another agent.
312
- */
313
- respond(correlationId, to, body, data) {
314
- if (this._state !== 'READY') {
315
- return false;
316
- }
317
- const envelope = {
318
- v: PROTOCOL_VERSION,
319
- type: 'SEND',
320
- id: generateId(),
321
- ts: Date.now(),
322
- to,
323
- payload: {
324
- kind: 'message',
325
- body,
326
- data: {
327
- ...data,
328
- _correlationId: correlationId,
329
- _isResponse: true,
330
- },
331
- },
332
- payload_meta: {
333
- replyTo: correlationId,
334
- },
335
- };
336
- return this.send(envelope);
337
- }
338
- /**
339
- * Broadcast a message to all agents.
340
- */
341
- broadcast(body, kind = 'message', data) {
342
- return this.sendMessage('*', body, kind, data);
343
- }
344
- /**
345
- * Bind as a shadow to a primary agent.
346
- */
347
- bindAsShadow(primaryAgent, options = {}) {
348
- if (this._state !== 'READY')
349
- return false;
350
- return this.send({
351
- v: PROTOCOL_VERSION,
352
- type: 'SHADOW_BIND',
353
- id: generateId(),
354
- ts: Date.now(),
355
- payload: {
356
- primaryAgent,
357
- speakOn: options.speakOn,
358
- receiveIncoming: options.receiveIncoming,
359
- receiveOutgoing: options.receiveOutgoing,
360
- },
361
- });
362
- }
363
- /**
364
- * Unbind from a primary agent.
365
- */
366
- unbindAsShadow(primaryAgent) {
367
- if (this._state !== 'READY')
368
- return false;
369
- return this.send({
370
- v: PROTOCOL_VERSION,
371
- type: 'SHADOW_UNBIND',
372
- id: generateId(),
373
- ts: Date.now(),
374
- payload: {
375
- primaryAgent,
376
- },
377
- });
378
- }
379
- /**
380
- * Send log output to the daemon.
381
- */
382
- sendLog(data) {
383
- if (this._state !== 'READY') {
384
- return false;
385
- }
386
- const envelope = {
387
- v: PROTOCOL_VERSION,
388
- type: 'LOG',
389
- id: generateId(),
390
- ts: Date.now(),
391
- payload: {
392
- data,
393
- timestamp: Date.now(),
394
- },
395
- };
396
- return this.send(envelope);
397
- }
398
- // =============================================================================
399
- // Channel Operations
400
- // =============================================================================
401
- /**
402
- * Join a channel.
403
- */
404
- joinChannel(channel, displayName) {
405
- if (this._state !== 'READY') {
406
- return false;
407
- }
408
- const envelope = {
409
- v: PROTOCOL_VERSION,
410
- type: 'CHANNEL_JOIN',
411
- id: generateId(),
412
- ts: Date.now(),
413
- payload: {
414
- channel,
415
- displayName,
416
- },
417
- };
418
- return this.send(envelope);
419
- }
420
- /**
421
- * Leave a channel.
422
- */
423
- leaveChannel(channel, reason) {
424
- if (this._state !== 'READY')
425
- return false;
426
- const envelope = {
427
- v: PROTOCOL_VERSION,
428
- type: 'CHANNEL_LEAVE',
429
- id: generateId(),
430
- ts: Date.now(),
431
- payload: {
432
- channel,
433
- reason,
434
- },
435
- };
436
- return this.send(envelope);
437
- }
438
- /**
439
- * Send a message to a channel.
440
- */
441
- sendChannelMessage(channel, body, options) {
442
- if (this._state !== 'READY') {
443
- return false;
444
- }
445
- const envelope = {
446
- v: PROTOCOL_VERSION,
447
- type: 'CHANNEL_MESSAGE',
448
- id: generateId(),
449
- ts: Date.now(),
450
- payload: {
451
- channel,
452
- body,
453
- thread: options?.thread,
454
- mentions: options?.mentions,
455
- attachments: options?.attachments,
456
- data: options?.data,
457
- },
458
- };
459
- return this.send(envelope);
460
- }
461
- // =============================================================================
462
- // Private Methods
463
- // =============================================================================
464
- setState(state) {
465
- this._state = state;
466
- if (this.onStateChange) {
467
- this.onStateChange(state);
468
- }
469
- }
470
- sendHello() {
471
- const hello = {
472
- v: PROTOCOL_VERSION,
473
- type: 'HELLO',
474
- id: generateId(),
475
- ts: Date.now(),
476
- payload: {
477
- agent: this.config.agentName,
478
- entityType: this.config.entityType,
479
- cli: this.config.cli,
480
- displayName: this.config.displayName,
481
- avatarUrl: this.config.avatarUrl,
482
- capabilities: {
483
- ack: true,
484
- resume: true,
485
- max_inflight: 256,
486
- supports_topics: true,
487
- },
488
- session: this.resumeToken ? { resume_token: this.resumeToken } : undefined,
489
- },
490
- };
491
- this.send(hello);
492
- }
493
- send(envelope) {
494
- if (!this.transport || this.transport.state !== 'connected') {
495
- return false;
496
- }
497
- try {
498
- const frame = encodeFrameLegacyBrowser(envelope);
499
- this.writeQueue.push(frame);
500
- if (!this.writeScheduled) {
501
- this.writeScheduled = true;
502
- // Use setTimeout(0) for browser compatibility (instead of setImmediate)
503
- setTimeout(() => this.flushWrites(), 0);
504
- }
505
- return true;
506
- }
507
- catch (err) {
508
- this.handleError(err);
509
- return false;
510
- }
511
- }
512
- flushWrites() {
513
- this.writeScheduled = false;
514
- if (this.writeQueue.length === 0 || !this.transport)
515
- return;
516
- // Concatenate all buffers
517
- const totalLength = this.writeQueue.reduce((sum, buf) => sum + buf.length, 0);
518
- const combined = new Uint8Array(totalLength);
519
- let offset = 0;
520
- for (const buf of this.writeQueue) {
521
- combined.set(buf, offset);
522
- offset += buf.length;
523
- }
524
- this.transport.send(combined);
525
- this.writeQueue = [];
526
- }
527
- handleData(data) {
528
- try {
529
- const frames = this.parser.push(data);
530
- for (const frame of frames) {
531
- this.processFrame(frame);
532
- }
533
- }
534
- catch (err) {
535
- this.handleError(err);
536
- }
537
- }
538
- processFrame(envelope) {
539
- switch (envelope.type) {
540
- case 'WELCOME':
541
- this.handleWelcome(envelope);
542
- break;
543
- case 'DELIVER':
544
- this.handleDeliver(envelope);
545
- break;
546
- case 'CHANNEL_MESSAGE':
547
- this.handleChannelMessage(envelope);
548
- break;
549
- case 'PING':
550
- this.handlePing(envelope);
551
- break;
552
- case 'ACK':
553
- this.handleAck(envelope);
554
- break;
555
- case 'ERROR':
556
- this.handleErrorFrame(envelope);
557
- break;
558
- case 'BUSY':
559
- if (!this.config.quiet) {
560
- console.warn('[sdk] Server busy, backing off');
561
- }
562
- break;
563
- }
564
- }
565
- handleWelcome(envelope) {
566
- this.sessionId = envelope.payload.session_id;
567
- this.resumeToken = envelope.payload.resume_token;
568
- this.reconnectAttempts = 0;
569
- this.reconnectDelay = this.config.reconnectDelayMs ?? DEFAULT_CONFIG.reconnectDelayMs;
570
- this.setState('READY');
571
- if (!this.config.quiet) {
572
- console.log(`[sdk] Connected as ${this.config.agentName} (session: ${this.sessionId})`);
573
- }
574
- }
575
- handleDeliver(envelope) {
576
- // Send ACK
577
- this.send({
578
- v: PROTOCOL_VERSION,
579
- type: 'ACK',
580
- id: generateId(),
581
- ts: Date.now(),
582
- payload: {
583
- ack_id: envelope.id,
584
- seq: envelope.delivery.seq,
585
- },
586
- });
587
- const duplicate = this.dedupeCache.check(envelope.id);
588
- if (duplicate) {
589
- return;
590
- }
591
- // Check if this is a response to a pending request
592
- const correlationId = this.extractCorrelationId(envelope);
593
- if (correlationId && envelope.from) {
594
- const pending = this.pendingRequests.get(correlationId);
595
- if (pending) {
596
- clearTimeout(pending.timeoutHandle);
597
- this.pendingRequests.delete(correlationId);
598
- pending.resolve({
599
- from: envelope.from,
600
- body: envelope.payload.body,
601
- data: envelope.payload.data,
602
- correlationId,
603
- thread: envelope.payload.thread,
604
- payload: envelope.payload,
605
- });
606
- }
607
- }
608
- if (this.onMessage && envelope.from) {
609
- this.onMessage(envelope.from, envelope.payload, envelope.id, envelope.payload_meta, envelope.delivery.originalTo);
610
- }
611
- }
612
- extractCorrelationId(envelope) {
613
- if (envelope.payload_meta?.replyTo) {
614
- return envelope.payload_meta.replyTo;
615
- }
616
- if (envelope.payload.data && typeof envelope.payload.data._correlationId === 'string') {
617
- return envelope.payload.data._correlationId;
618
- }
619
- return undefined;
620
- }
621
- handleChannelMessage(envelope) {
622
- const duplicate = this.dedupeCache.check(envelope.id);
623
- if (duplicate) {
624
- return;
625
- }
626
- if (this.onChannelMessage && envelope.from) {
627
- this.onChannelMessage(envelope.from, envelope.payload.channel, envelope.payload.body, envelope);
628
- }
629
- // Also call onMessage for backwards compatibility
630
- if (this.onMessage && envelope.from) {
631
- const sendPayload = {
632
- kind: 'message',
633
- body: envelope.payload.body,
634
- data: {
635
- _isChannelMessage: true,
636
- _channel: envelope.payload.channel,
637
- _mentions: envelope.payload.mentions,
638
- },
639
- thread: envelope.payload.thread,
640
- };
641
- this.onMessage(envelope.from, sendPayload, envelope.id, undefined, envelope.payload.channel);
642
- }
643
- }
644
- handleAck(envelope) {
645
- const correlationId = envelope.payload.correlationId;
646
- if (!correlationId)
647
- return;
648
- const pending = this.pendingSyncAcks.get(correlationId);
649
- if (!pending)
650
- return;
651
- clearTimeout(pending.timeoutHandle);
652
- this.pendingSyncAcks.delete(correlationId);
653
- pending.resolve(envelope.payload);
654
- }
655
- handlePing(envelope) {
656
- this.send({
657
- v: PROTOCOL_VERSION,
658
- type: 'PONG',
659
- id: generateId(),
660
- ts: Date.now(),
661
- payload: envelope.payload ?? {},
662
- });
663
- }
664
- handleErrorFrame(envelope) {
665
- if (!this.config.quiet) {
666
- console.error('[sdk] Server error:', envelope.payload);
667
- }
668
- if (envelope.payload.code === 'RESUME_TOO_OLD') {
669
- this.resumeToken = undefined;
670
- this.sessionId = undefined;
671
- }
672
- if (envelope.payload.fatal) {
673
- if (!this.config.quiet) {
674
- console.error('[sdk] Fatal error received, will not reconnect:', envelope.payload.message);
675
- }
676
- this._destroyed = true;
677
- }
678
- }
679
- handleDisconnect() {
680
- this.parser.reset();
681
- this.transport = undefined;
682
- this.rejectPendingSyncAcks(new Error('Disconnected while awaiting ACK'));
683
- this.rejectPendingRequests(new Error('Disconnected while awaiting request response'));
684
- if (this._destroyed) {
685
- this.setState('DISCONNECTED');
686
- return;
687
- }
688
- if (this.config.reconnect && this.reconnectAttempts < (this.config.maxReconnectAttempts ?? DEFAULT_CONFIG.maxReconnectAttempts)) {
689
- this.scheduleReconnect();
690
- }
691
- else {
692
- this.setState('DISCONNECTED');
693
- if (this.reconnectAttempts >= (this.config.maxReconnectAttempts ?? DEFAULT_CONFIG.maxReconnectAttempts) && !this.config.quiet) {
694
- console.error(`[sdk] Max reconnect attempts reached (${this.config.maxReconnectAttempts}), giving up`);
695
- }
696
- }
697
- }
698
- handleError(error) {
699
- if (!this.config.quiet) {
700
- console.error('[sdk] Error:', error.message);
701
- }
702
- if (this.onError) {
703
- this.onError(error);
704
- }
705
- }
706
- rejectPendingSyncAcks(error) {
707
- for (const [correlationId, pending] of this.pendingSyncAcks.entries()) {
708
- clearTimeout(pending.timeoutHandle);
709
- pending.reject(error);
710
- this.pendingSyncAcks.delete(correlationId);
711
- }
712
- }
713
- rejectPendingRequests(error) {
714
- for (const [correlationId, pending] of this.pendingRequests.entries()) {
715
- clearTimeout(pending.timeoutHandle);
716
- pending.reject(error);
717
- this.pendingRequests.delete(correlationId);
718
- }
719
- }
720
- scheduleReconnect() {
721
- // Cannot reconnect when using transportInstance - we can't recreate an
722
- // externally-provided transport. Users must handle reconnection themselves
723
- // or use transport options instead.
724
- if (!this.config.transport && this.config.transportInstance) {
725
- if (!this.config.quiet) {
726
- console.warn('[sdk] Cannot auto-reconnect with transportInstance. ' +
727
- 'Use transport options instead, or handle reconnection manually.');
728
- }
729
- this.setState('DISCONNECTED');
730
- return;
731
- }
732
- this.setState('BACKOFF');
733
- this.reconnectAttempts++;
734
- const jitter = Math.random() * 0.3 + 0.85;
735
- const maxDelay = this.config.reconnectMaxDelayMs ?? DEFAULT_CONFIG.reconnectMaxDelayMs;
736
- const delay = Math.min(this.reconnectDelay * jitter, maxDelay);
737
- this.reconnectDelay *= 2;
738
- if (!this.config.quiet) {
739
- console.log(`[sdk] Reconnecting in ${Math.round(delay)}ms (attempt ${this.reconnectAttempts})`);
740
- }
741
- this.reconnectTimer = setTimeout(() => {
742
- // Re-create transport for reconnection
743
- if (this.config.transport) {
744
- this.transport = createAutoTransport(this.config.transport);
745
- }
746
- this.connect().catch(() => { });
747
- }, delay);
748
- }
749
- }
750
- //# sourceMappingURL=browser-client.js.map