agent-relay 2.3.4 → 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 (297) hide show
  1. package/README.md +1 -1
  2. package/dist/src/cli/index.js +124 -7
  3. package/dist/src/cli/index.js.map +1 -1
  4. package/package.json +20 -26
  5. package/packages/acp-bridge/package.json +2 -2
  6. package/packages/bridge/package.json +7 -7
  7. package/packages/config/package.json +2 -2
  8. package/packages/continuity/package.json +2 -2
  9. package/packages/daemon/package.json +12 -12
  10. package/packages/hooks/package.json +4 -4
  11. package/packages/mcp/package.json +5 -5
  12. package/packages/memory/package.json +2 -2
  13. package/packages/policy/package.json +2 -2
  14. package/packages/protocol/package.json +1 -1
  15. package/packages/resiliency/package.json +1 -1
  16. package/packages/sdk/dist/index.d.ts +1 -29
  17. package/packages/sdk/dist/index.d.ts.map +1 -1
  18. package/packages/sdk/dist/index.js +1 -38
  19. package/packages/sdk/dist/index.js.map +1 -1
  20. package/packages/sdk/package.json +4 -25
  21. package/packages/sdk/src/index.ts +1 -69
  22. package/packages/sdk-py/README.md +56 -0
  23. package/packages/sdk-py/pyproject.toml +23 -0
  24. package/packages/sdk-py/src/agent_relay/__init__.py +27 -0
  25. package/packages/sdk-py/src/agent_relay/builder.py +367 -0
  26. package/packages/sdk-py/src/agent_relay/types.py +92 -0
  27. package/packages/sdk-py/tests/__init__.py +0 -0
  28. package/packages/sdk-py/tests/test_builder.py +101 -0
  29. package/packages/sdk-ts/dist/index.d.ts +1 -0
  30. package/packages/sdk-ts/dist/index.d.ts.map +1 -1
  31. package/packages/sdk-ts/dist/index.js +1 -0
  32. package/packages/sdk-ts/dist/index.js.map +1 -1
  33. package/packages/sdk-ts/dist/workflows/barrier.d.ts +72 -0
  34. package/packages/sdk-ts/dist/workflows/barrier.d.ts.map +1 -0
  35. package/packages/sdk-ts/dist/workflows/barrier.js +162 -0
  36. package/packages/sdk-ts/dist/workflows/barrier.js.map +1 -0
  37. package/packages/sdk-ts/dist/workflows/builder.d.ts +101 -0
  38. package/packages/sdk-ts/dist/workflows/builder.d.ts.map +1 -0
  39. package/packages/sdk-ts/dist/workflows/builder.js +179 -0
  40. package/packages/sdk-ts/dist/workflows/builder.js.map +1 -0
  41. package/packages/sdk-ts/dist/workflows/cli.d.ts +10 -0
  42. package/packages/sdk-ts/dist/workflows/cli.d.ts.map +1 -0
  43. package/packages/sdk-ts/dist/workflows/cli.js +82 -0
  44. package/packages/sdk-ts/dist/workflows/cli.js.map +1 -0
  45. package/packages/sdk-ts/dist/workflows/coordinator.d.ts +68 -0
  46. package/packages/sdk-ts/dist/workflows/coordinator.d.ts.map +1 -0
  47. package/packages/sdk-ts/dist/workflows/coordinator.js +353 -0
  48. package/packages/sdk-ts/dist/workflows/coordinator.js.map +1 -0
  49. package/packages/sdk-ts/dist/workflows/index.d.ts +10 -0
  50. package/packages/sdk-ts/dist/workflows/index.d.ts.map +1 -0
  51. package/packages/sdk-ts/dist/workflows/index.js +10 -0
  52. package/packages/sdk-ts/dist/workflows/index.js.map +1 -0
  53. package/packages/sdk-ts/dist/workflows/memory-db.d.ts +17 -0
  54. package/packages/sdk-ts/dist/workflows/memory-db.d.ts.map +1 -0
  55. package/packages/sdk-ts/dist/workflows/memory-db.js +33 -0
  56. package/packages/sdk-ts/dist/workflows/memory-db.js.map +1 -0
  57. package/packages/sdk-ts/dist/workflows/run.d.ts +31 -0
  58. package/packages/sdk-ts/dist/workflows/run.d.ts.map +1 -0
  59. package/packages/sdk-ts/dist/workflows/run.js +24 -0
  60. package/packages/sdk-ts/dist/workflows/run.js.map +1 -0
  61. package/packages/sdk-ts/dist/workflows/runner.d.ts +119 -0
  62. package/packages/sdk-ts/dist/workflows/runner.d.ts.map +1 -0
  63. package/packages/sdk-ts/dist/workflows/runner.js +650 -0
  64. package/packages/sdk-ts/dist/workflows/runner.js.map +1 -0
  65. package/packages/sdk-ts/dist/workflows/state.d.ts +77 -0
  66. package/packages/sdk-ts/dist/workflows/state.d.ts.map +1 -0
  67. package/packages/sdk-ts/dist/workflows/state.js +140 -0
  68. package/packages/sdk-ts/dist/workflows/state.js.map +1 -0
  69. package/packages/sdk-ts/dist/workflows/templates.d.ts +47 -0
  70. package/packages/sdk-ts/dist/workflows/templates.d.ts.map +1 -0
  71. package/packages/sdk-ts/dist/workflows/templates.js +395 -0
  72. package/packages/sdk-ts/dist/workflows/templates.js.map +1 -0
  73. package/packages/sdk-ts/dist/workflows/types.d.ts +126 -0
  74. package/packages/sdk-ts/dist/workflows/types.d.ts.map +1 -0
  75. package/packages/sdk-ts/dist/workflows/types.js +8 -0
  76. package/packages/sdk-ts/dist/workflows/types.js.map +1 -0
  77. package/packages/sdk-ts/package.json +8 -2
  78. package/packages/sdk-ts/src/__tests__/error-scenarios.test.ts +682 -0
  79. package/packages/sdk-ts/src/__tests__/swarm-coordinator.test.ts +416 -0
  80. package/packages/sdk-ts/src/__tests__/workflow-runner.test.ts +333 -0
  81. package/packages/sdk-ts/src/index.ts +1 -0
  82. package/packages/sdk-ts/src/workflows/README.md +450 -0
  83. package/packages/sdk-ts/src/workflows/barrier.ts +254 -0
  84. package/packages/sdk-ts/src/workflows/builder.ts +241 -0
  85. package/packages/sdk-ts/src/workflows/builtin-templates/bug-fix.yaml +75 -0
  86. package/packages/sdk-ts/src/workflows/builtin-templates/code-review.yaml +82 -0
  87. package/packages/sdk-ts/src/workflows/builtin-templates/documentation.yaml +70 -0
  88. package/packages/sdk-ts/src/workflows/builtin-templates/feature-dev.yaml +76 -0
  89. package/packages/sdk-ts/src/workflows/builtin-templates/refactor.yaml +82 -0
  90. package/packages/sdk-ts/src/workflows/builtin-templates/security-audit.yaml +84 -0
  91. package/packages/sdk-ts/src/workflows/cli.ts +93 -0
  92. package/packages/sdk-ts/src/workflows/coordinator.ts +520 -0
  93. package/packages/sdk-ts/src/workflows/index.ts +9 -0
  94. package/packages/sdk-ts/src/workflows/memory-db.ts +39 -0
  95. package/packages/sdk-ts/src/workflows/run.ts +47 -0
  96. package/packages/sdk-ts/src/workflows/runner.ts +873 -0
  97. package/packages/sdk-ts/src/workflows/schema.json +321 -0
  98. package/packages/sdk-ts/src/workflows/state.ts +279 -0
  99. package/packages/sdk-ts/src/workflows/templates.ts +544 -0
  100. package/packages/sdk-ts/src/workflows/types.ts +178 -0
  101. package/packages/sdk-ts/tsconfig.json +6 -1
  102. package/packages/spawner/package.json +1 -1
  103. package/packages/state/package.json +1 -1
  104. package/packages/storage/package.json +2 -2
  105. package/packages/telemetry/package.json +1 -1
  106. package/packages/trajectory/package.json +2 -2
  107. package/packages/user-directory/package.json +2 -2
  108. package/packages/utils/package.json +3 -3
  109. package/packages/wrapper/package.json +5 -6
  110. package/packages/api-types/.trajectories/active/traj_xbsvuzogscey.json +0 -15
  111. package/packages/api-types/.trajectories/index.json +0 -12
  112. package/packages/api-types/dist/index.d.ts +0 -21
  113. package/packages/api-types/dist/index.d.ts.map +0 -1
  114. package/packages/api-types/dist/index.js +0 -22
  115. package/packages/api-types/dist/index.js.map +0 -1
  116. package/packages/api-types/dist/schemas/agent.d.ts +0 -259
  117. package/packages/api-types/dist/schemas/agent.d.ts.map +0 -1
  118. package/packages/api-types/dist/schemas/agent.js +0 -102
  119. package/packages/api-types/dist/schemas/agent.js.map +0 -1
  120. package/packages/api-types/dist/schemas/api.d.ts +0 -290
  121. package/packages/api-types/dist/schemas/api.d.ts.map +0 -1
  122. package/packages/api-types/dist/schemas/api.js +0 -162
  123. package/packages/api-types/dist/schemas/api.js.map +0 -1
  124. package/packages/api-types/dist/schemas/decision.d.ts +0 -230
  125. package/packages/api-types/dist/schemas/decision.d.ts.map +0 -1
  126. package/packages/api-types/dist/schemas/decision.js +0 -104
  127. package/packages/api-types/dist/schemas/decision.js.map +0 -1
  128. package/packages/api-types/dist/schemas/fleet.d.ts +0 -615
  129. package/packages/api-types/dist/schemas/fleet.d.ts.map +0 -1
  130. package/packages/api-types/dist/schemas/fleet.js +0 -71
  131. package/packages/api-types/dist/schemas/fleet.js.map +0 -1
  132. package/packages/api-types/dist/schemas/history.d.ts +0 -180
  133. package/packages/api-types/dist/schemas/history.d.ts.map +0 -1
  134. package/packages/api-types/dist/schemas/history.js +0 -72
  135. package/packages/api-types/dist/schemas/history.js.map +0 -1
  136. package/packages/api-types/dist/schemas/index.d.ts +0 -14
  137. package/packages/api-types/dist/schemas/index.d.ts.map +0 -1
  138. package/packages/api-types/dist/schemas/index.js +0 -22
  139. package/packages/api-types/dist/schemas/index.js.map +0 -1
  140. package/packages/api-types/dist/schemas/message.d.ts +0 -456
  141. package/packages/api-types/dist/schemas/message.d.ts.map +0 -1
  142. package/packages/api-types/dist/schemas/message.js +0 -88
  143. package/packages/api-types/dist/schemas/message.js.map +0 -1
  144. package/packages/api-types/dist/schemas/session.d.ts +0 -60
  145. package/packages/api-types/dist/schemas/session.d.ts.map +0 -1
  146. package/packages/api-types/dist/schemas/session.js +0 -36
  147. package/packages/api-types/dist/schemas/session.js.map +0 -1
  148. package/packages/api-types/dist/schemas/task.d.ts +0 -111
  149. package/packages/api-types/dist/schemas/task.d.ts.map +0 -1
  150. package/packages/api-types/dist/schemas/task.js +0 -64
  151. package/packages/api-types/dist/schemas/task.js.map +0 -1
  152. package/packages/api-types/package.json +0 -61
  153. package/packages/api-types/scripts/generate-openapi.ts +0 -106
  154. package/packages/api-types/src/index.ts +0 -22
  155. package/packages/api-types/src/schemas/agent.test.ts +0 -164
  156. package/packages/api-types/src/schemas/agent.ts +0 -110
  157. package/packages/api-types/src/schemas/api.test.ts +0 -372
  158. package/packages/api-types/src/schemas/api.ts +0 -194
  159. package/packages/api-types/src/schemas/decision.test.ts +0 -324
  160. package/packages/api-types/src/schemas/decision.ts +0 -136
  161. package/packages/api-types/src/schemas/fleet.test.ts +0 -212
  162. package/packages/api-types/src/schemas/fleet.ts +0 -83
  163. package/packages/api-types/src/schemas/history.test.ts +0 -242
  164. package/packages/api-types/src/schemas/history.ts +0 -84
  165. package/packages/api-types/src/schemas/index.ts +0 -148
  166. package/packages/api-types/src/schemas/message.test.ts +0 -192
  167. package/packages/api-types/src/schemas/message.ts +0 -98
  168. package/packages/api-types/src/schemas/session.test.ts +0 -104
  169. package/packages/api-types/src/schemas/session.ts +0 -40
  170. package/packages/api-types/src/schemas/task.test.ts +0 -192
  171. package/packages/api-types/src/schemas/task.ts +0 -78
  172. package/packages/api-types/tsconfig.json +0 -19
  173. package/packages/api-types/vitest.config.ts +0 -9
  174. package/packages/benchmark/README.md +0 -200
  175. package/packages/benchmark/datasets/coding-tasks.yaml +0 -127
  176. package/packages/benchmark/datasets/coordination-tasks.yaml +0 -122
  177. package/packages/benchmark/datasets/quick-test.yaml +0 -20
  178. package/packages/benchmark/dist/benchmark.d.ts +0 -47
  179. package/packages/benchmark/dist/benchmark.d.ts.map +0 -1
  180. package/packages/benchmark/dist/benchmark.js +0 -224
  181. package/packages/benchmark/dist/benchmark.js.map +0 -1
  182. package/packages/benchmark/dist/cli.d.ts +0 -8
  183. package/packages/benchmark/dist/cli.d.ts.map +0 -1
  184. package/packages/benchmark/dist/cli.js +0 -185
  185. package/packages/benchmark/dist/cli.js.map +0 -1
  186. package/packages/benchmark/dist/harbor.d.ts +0 -53
  187. package/packages/benchmark/dist/harbor.d.ts.map +0 -1
  188. package/packages/benchmark/dist/harbor.js +0 -127
  189. package/packages/benchmark/dist/harbor.js.map +0 -1
  190. package/packages/benchmark/dist/index.d.ts +0 -48
  191. package/packages/benchmark/dist/index.d.ts.map +0 -1
  192. package/packages/benchmark/dist/index.js +0 -50
  193. package/packages/benchmark/dist/index.js.map +0 -1
  194. package/packages/benchmark/dist/runners/base.d.ts +0 -63
  195. package/packages/benchmark/dist/runners/base.d.ts.map +0 -1
  196. package/packages/benchmark/dist/runners/base.js +0 -156
  197. package/packages/benchmark/dist/runners/base.js.map +0 -1
  198. package/packages/benchmark/dist/runners/index.d.ts +0 -10
  199. package/packages/benchmark/dist/runners/index.d.ts.map +0 -1
  200. package/packages/benchmark/dist/runners/index.js +0 -10
  201. package/packages/benchmark/dist/runners/index.js.map +0 -1
  202. package/packages/benchmark/dist/runners/single.d.ts +0 -19
  203. package/packages/benchmark/dist/runners/single.d.ts.map +0 -1
  204. package/packages/benchmark/dist/runners/single.js +0 -111
  205. package/packages/benchmark/dist/runners/single.js.map +0 -1
  206. package/packages/benchmark/dist/runners/subagent.d.ts +0 -32
  207. package/packages/benchmark/dist/runners/subagent.d.ts.map +0 -1
  208. package/packages/benchmark/dist/runners/subagent.js +0 -212
  209. package/packages/benchmark/dist/runners/subagent.js.map +0 -1
  210. package/packages/benchmark/dist/runners/swarm.d.ts +0 -36
  211. package/packages/benchmark/dist/runners/swarm.d.ts.map +0 -1
  212. package/packages/benchmark/dist/runners/swarm.js +0 -273
  213. package/packages/benchmark/dist/runners/swarm.js.map +0 -1
  214. package/packages/benchmark/dist/types.d.ts +0 -178
  215. package/packages/benchmark/dist/types.d.ts.map +0 -1
  216. package/packages/benchmark/dist/types.js +0 -16
  217. package/packages/benchmark/dist/types.js.map +0 -1
  218. package/packages/benchmark/package.json +0 -80
  219. package/packages/benchmark/src/benchmark.ts +0 -298
  220. package/packages/benchmark/src/cli.ts +0 -240
  221. package/packages/benchmark/src/harbor.ts +0 -170
  222. package/packages/benchmark/src/index.ts +0 -73
  223. package/packages/benchmark/src/runners/base.ts +0 -205
  224. package/packages/benchmark/src/runners/index.ts +0 -10
  225. package/packages/benchmark/src/runners/single.ts +0 -121
  226. package/packages/benchmark/src/runners/subagent.ts +0 -240
  227. package/packages/benchmark/src/runners/swarm.ts +0 -326
  228. package/packages/benchmark/src/types.ts +0 -205
  229. package/packages/benchmark/tsconfig.json +0 -20
  230. package/packages/cli-tester/README.md +0 -277
  231. package/packages/cli-tester/dist/index.d.ts +0 -21
  232. package/packages/cli-tester/dist/index.d.ts.map +0 -1
  233. package/packages/cli-tester/dist/index.js +0 -21
  234. package/packages/cli-tester/dist/index.js.map +0 -1
  235. package/packages/cli-tester/dist/utils/credential-check.d.ts +0 -56
  236. package/packages/cli-tester/dist/utils/credential-check.d.ts.map +0 -1
  237. package/packages/cli-tester/dist/utils/credential-check.js +0 -230
  238. package/packages/cli-tester/dist/utils/credential-check.js.map +0 -1
  239. package/packages/cli-tester/dist/utils/socket-client.d.ts +0 -76
  240. package/packages/cli-tester/dist/utils/socket-client.d.ts.map +0 -1
  241. package/packages/cli-tester/dist/utils/socket-client.js +0 -153
  242. package/packages/cli-tester/dist/utils/socket-client.js.map +0 -1
  243. package/packages/cli-tester/docker/Dockerfile +0 -61
  244. package/packages/cli-tester/docker/docker-compose.yml +0 -71
  245. package/packages/cli-tester/docker/entrypoint.sh +0 -58
  246. package/packages/cli-tester/package.json +0 -32
  247. package/packages/cli-tester/scripts/clear-auth.sh +0 -101
  248. package/packages/cli-tester/scripts/inject-message.sh +0 -42
  249. package/packages/cli-tester/scripts/start.sh +0 -71
  250. package/packages/cli-tester/scripts/test-cli.sh +0 -56
  251. package/packages/cli-tester/scripts/test-full-spawn.sh +0 -238
  252. package/packages/cli-tester/scripts/test-registration.sh +0 -182
  253. package/packages/cli-tester/scripts/test-setup-flow.sh +0 -202
  254. package/packages/cli-tester/scripts/test-spawn.sh +0 -140
  255. package/packages/cli-tester/scripts/test-with-daemon.sh +0 -247
  256. package/packages/cli-tester/scripts/verify-auth.sh +0 -112
  257. package/packages/cli-tester/src/index.ts +0 -40
  258. package/packages/cli-tester/src/utils/credential-check.ts +0 -284
  259. package/packages/cli-tester/src/utils/socket-client.ts +0 -211
  260. package/packages/cli-tester/tests/credential-check.test.ts +0 -56
  261. package/packages/cli-tester/tsconfig.json +0 -11
  262. package/packages/sdk/dist/browser-client.d.ts +0 -212
  263. package/packages/sdk/dist/browser-client.d.ts.map +0 -1
  264. package/packages/sdk/dist/browser-client.js +0 -750
  265. package/packages/sdk/dist/browser-client.js.map +0 -1
  266. package/packages/sdk/dist/browser-framing.d.ts +0 -46
  267. package/packages/sdk/dist/browser-framing.d.ts.map +0 -1
  268. package/packages/sdk/dist/browser-framing.js +0 -122
  269. package/packages/sdk/dist/browser-framing.js.map +0 -1
  270. package/packages/sdk/dist/standalone.d.ts +0 -89
  271. package/packages/sdk/dist/standalone.d.ts.map +0 -1
  272. package/packages/sdk/dist/standalone.js +0 -131
  273. package/packages/sdk/dist/standalone.js.map +0 -1
  274. package/packages/sdk/dist/transports/index.d.ts +0 -92
  275. package/packages/sdk/dist/transports/index.d.ts.map +0 -1
  276. package/packages/sdk/dist/transports/index.js +0 -129
  277. package/packages/sdk/dist/transports/index.js.map +0 -1
  278. package/packages/sdk/dist/transports/socket-transport.d.ts +0 -30
  279. package/packages/sdk/dist/transports/socket-transport.d.ts.map +0 -1
  280. package/packages/sdk/dist/transports/socket-transport.js +0 -94
  281. package/packages/sdk/dist/transports/socket-transport.js.map +0 -1
  282. package/packages/sdk/dist/transports/types.d.ts +0 -69
  283. package/packages/sdk/dist/transports/types.d.ts.map +0 -1
  284. package/packages/sdk/dist/transports/types.js +0 -10
  285. package/packages/sdk/dist/transports/types.js.map +0 -1
  286. package/packages/sdk/dist/transports/websocket-transport.d.ts +0 -55
  287. package/packages/sdk/dist/transports/websocket-transport.d.ts.map +0 -1
  288. package/packages/sdk/dist/transports/websocket-transport.js +0 -180
  289. package/packages/sdk/dist/transports/websocket-transport.js.map +0 -1
  290. package/packages/sdk/src/browser-client.ts +0 -985
  291. package/packages/sdk/src/browser-framing.test.ts +0 -115
  292. package/packages/sdk/src/browser-framing.ts +0 -150
  293. package/packages/sdk/src/standalone.ts +0 -183
  294. package/packages/sdk/src/transports/index.ts +0 -197
  295. package/packages/sdk/src/transports/socket-transport.ts +0 -115
  296. package/packages/sdk/src/transports/types.ts +0 -77
  297. package/packages/sdk/src/transports/websocket-transport.ts +0 -245
@@ -1,115 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { encodeFrameLegacyBrowser, BrowserFrameParser } from './browser-framing.js';
3
-
4
- describe('browser-framing', () => {
5
- describe('encodeFrameLegacyBrowser', () => {
6
- it('encodes envelope with 4-byte length header', () => {
7
- const envelope = { type: 'PING', v: 1, id: 'test', ts: 12345, payload: {} };
8
- const frame = encodeFrameLegacyBrowser(envelope);
9
-
10
- // Should be Uint8Array
11
- expect(frame).toBeInstanceOf(Uint8Array);
12
-
13
- // First 4 bytes should be the length in big-endian
14
- const view = new DataView(frame.buffer);
15
- const length = view.getUint32(0, false);
16
-
17
- // Payload should match the encoded JSON length
18
- const json = JSON.stringify(envelope);
19
- expect(length).toBe(new TextEncoder().encode(json).length);
20
- });
21
-
22
- it('throws on oversized frames', () => {
23
- const largePayload = 'x'.repeat(1024 * 1024 + 1);
24
- const envelope = { type: 'SEND', v: 1, id: 'test', ts: 12345, payload: { body: largePayload } };
25
-
26
- expect(() => encodeFrameLegacyBrowser(envelope)).toThrow(/Frame too large/);
27
- });
28
- });
29
-
30
- describe('BrowserFrameParser', () => {
31
- it('parses complete frame', () => {
32
- const envelope = { type: 'PONG', v: 1, id: 'abc', ts: 999, payload: {} };
33
- const frame = encodeFrameLegacyBrowser(envelope);
34
-
35
- const parser = new BrowserFrameParser();
36
- const parsed = parser.push(frame);
37
-
38
- expect(parsed).toHaveLength(1);
39
- expect(parsed[0]).toEqual(envelope);
40
- });
41
-
42
- it('handles partial frames', () => {
43
- const envelope = { type: 'SEND', v: 1, id: 'xyz', ts: 1000, payload: { to: 'Agent', body: 'Hello' } };
44
- const frame = encodeFrameLegacyBrowser(envelope);
45
-
46
- const parser = new BrowserFrameParser();
47
-
48
- // Send first half
49
- const half = Math.floor(frame.length / 2);
50
- let parsed = parser.push(frame.subarray(0, half));
51
- expect(parsed).toHaveLength(0);
52
-
53
- // Send second half
54
- parsed = parser.push(frame.subarray(half));
55
- expect(parsed).toHaveLength(1);
56
- expect(parsed[0]).toEqual(envelope);
57
- });
58
-
59
- it('parses multiple frames in sequence', () => {
60
- const envelopes = [
61
- { type: 'PING', v: 1, id: '1', ts: 1, payload: {} },
62
- { type: 'PONG', v: 1, id: '2', ts: 2, payload: {} },
63
- { type: 'ACK', v: 1, id: '3', ts: 3, payload: { messageId: 'x' } },
64
- ];
65
-
66
- const frames = envelopes.map(e => encodeFrameLegacyBrowser(e));
67
- const combined = new Uint8Array(frames.reduce((sum, f) => sum + f.length, 0));
68
- let offset = 0;
69
- for (const frame of frames) {
70
- combined.set(frame, offset);
71
- offset += frame.length;
72
- }
73
-
74
- const parser = new BrowserFrameParser();
75
- const parsed = parser.push(combined);
76
-
77
- expect(parsed).toHaveLength(3);
78
- expect(parsed).toEqual(envelopes);
79
- });
80
-
81
- it('tracks pending bytes correctly', () => {
82
- const parser = new BrowserFrameParser();
83
- expect(parser.pendingBytes).toBe(0);
84
-
85
- // Push partial header
86
- parser.push(new Uint8Array([0, 0, 0, 10])); // Header claiming 10 byte payload
87
- expect(parser.pendingBytes).toBe(4);
88
-
89
- // Push partial payload
90
- parser.push(new Uint8Array([123])); // Just '{'
91
- expect(parser.pendingBytes).toBe(5);
92
- });
93
-
94
- it('throws on oversized frame', () => {
95
- const parser = new BrowserFrameParser();
96
-
97
- // Create header claiming 2MB payload
98
- const header = new Uint8Array(4);
99
- const view = new DataView(header.buffer);
100
- view.setUint32(0, 2 * 1024 * 1024, false);
101
-
102
- expect(() => parser.push(header)).toThrow(/Frame too large/);
103
- });
104
-
105
- it('resets parser state', () => {
106
- const parser = new BrowserFrameParser();
107
- parser.push(new Uint8Array([0, 0, 0, 5, 123])); // Partial frame
108
-
109
- expect(parser.pendingBytes).toBeGreaterThan(0);
110
-
111
- parser.reset();
112
- expect(parser.pendingBytes).toBe(0);
113
- });
114
- });
115
- });
@@ -1,150 +0,0 @@
1
- /**
2
- * Browser-compatible frame encoding/decoding for the Agent Relay protocol.
3
- *
4
- * Uses Uint8Array and DataView instead of Node.js Buffer for browser compatibility.
5
- *
6
- * Wire format (legacy):
7
- * - 4 bytes: big-endian payload length
8
- * - N bytes: JSON payload
9
- */
10
-
11
- import type { Envelope } from '@agent-relay/protocol';
12
-
13
- export const MAX_FRAME_BYTES = 1024 * 1024; // 1 MiB
14
- export const LEGACY_HEADER_SIZE = 4;
15
-
16
- const textEncoder = new TextEncoder();
17
- const textDecoder = new TextDecoder();
18
-
19
- /**
20
- * Encode a frame in legacy format (4-byte header, JSON only).
21
- * Browser-compatible version using Uint8Array.
22
- */
23
- export function encodeFrameLegacyBrowser(envelope: Envelope): Uint8Array {
24
- const json = JSON.stringify(envelope);
25
- const data = textEncoder.encode(json);
26
-
27
- if (data.length > MAX_FRAME_BYTES) {
28
- throw new Error(`Frame too large: ${data.length} > ${MAX_FRAME_BYTES}`);
29
- }
30
-
31
- const frame = new Uint8Array(LEGACY_HEADER_SIZE + data.length);
32
- const view = new DataView(frame.buffer);
33
-
34
- // Write 4-byte big-endian length header
35
- view.setUint32(0, data.length, false);
36
-
37
- // Copy payload
38
- frame.set(data, LEGACY_HEADER_SIZE);
39
-
40
- return frame;
41
- }
42
-
43
- /**
44
- * Browser-compatible frame parser using Uint8Array and DataView.
45
- */
46
- export class BrowserFrameParser {
47
- private buffer: Uint8Array;
48
- private head = 0;
49
- private tail = 0;
50
- private readonly capacity: number;
51
- private readonly maxFrameBytes: number;
52
-
53
- constructor(maxFrameBytes: number = MAX_FRAME_BYTES) {
54
- this.maxFrameBytes = maxFrameBytes;
55
- this.capacity = maxFrameBytes * 2 + LEGACY_HEADER_SIZE;
56
- this.buffer = new Uint8Array(this.capacity);
57
- }
58
-
59
- /**
60
- * Get current unread bytes in buffer.
61
- */
62
- get pendingBytes(): number {
63
- return this.tail - this.head;
64
- }
65
-
66
- /**
67
- * Push data into the parser and extract complete frames.
68
- *
69
- * @param data - Incoming data as Uint8Array
70
- * @returns Array of parsed envelope frames
71
- */
72
- push(data: Uint8Array): Envelope[] {
73
- const spaceAtEnd = this.capacity - this.tail;
74
-
75
- if (data.length > spaceAtEnd) {
76
- this.compact();
77
-
78
- if (data.length > this.capacity - this.tail) {
79
- throw new Error(`Buffer overflow: data ${data.length} exceeds capacity`);
80
- }
81
- }
82
-
83
- // Copy incoming data to buffer
84
- this.buffer.set(data, this.tail);
85
- this.tail += data.length;
86
-
87
- return this.extractFrames();
88
- }
89
-
90
- private extractFrames(): Envelope[] {
91
- const frames: Envelope[] = [];
92
- const view = new DataView(this.buffer.buffer);
93
-
94
- while (this.pendingBytes >= LEGACY_HEADER_SIZE) {
95
- // Read 4-byte big-endian length
96
- const frameLength = view.getUint32(this.head, false);
97
-
98
- if (frameLength > this.maxFrameBytes) {
99
- throw new Error(`Frame too large: ${frameLength} > ${this.maxFrameBytes}`);
100
- }
101
-
102
- const totalLength = LEGACY_HEADER_SIZE + frameLength;
103
-
104
- if (this.pendingBytes < totalLength) {
105
- break;
106
- }
107
-
108
- const payloadStart = this.head + LEGACY_HEADER_SIZE;
109
- const payloadEnd = this.head + totalLength;
110
-
111
- let envelope: Envelope;
112
- try {
113
- const payload = this.buffer.subarray(payloadStart, payloadEnd);
114
- const json = textDecoder.decode(payload);
115
- envelope = JSON.parse(json) as Envelope;
116
- } catch (err) {
117
- throw new Error(`Invalid frame payload: ${err}`);
118
- }
119
-
120
- this.head += totalLength;
121
- frames.push(envelope);
122
- }
123
-
124
- if (this.head > this.capacity / 2 && this.pendingBytes < this.capacity / 4) {
125
- this.compact();
126
- }
127
-
128
- return frames;
129
- }
130
-
131
- private compact(): void {
132
- if (this.head === 0) return;
133
-
134
- const pending = this.pendingBytes;
135
- if (pending > 0) {
136
- // Copy remaining data to start of buffer
137
- this.buffer.copyWithin(0, this.head, this.tail);
138
- }
139
- this.tail = pending;
140
- this.head = 0;
141
- }
142
-
143
- /**
144
- * Reset the parser state.
145
- */
146
- reset(): void {
147
- this.head = 0;
148
- this.tail = 0;
149
- }
150
- }
@@ -1,183 +0,0 @@
1
- /**
2
- * Standalone Relay - Dead Simple Agent Communication
3
- *
4
- * Use Agent Relay as a pure communication layer without any external setup.
5
- * Just import and go.
6
- *
7
- * @example
8
- * ```typescript
9
- * import { createRelay } from '@agent-relay/sdk/standalone';
10
- *
11
- * const relay = await createRelay();
12
- *
13
- * const alice = await relay.client('Alice');
14
- * const bob = await relay.client('Bob');
15
- *
16
- * bob.onMessage = (from, { body }) => console.log(`${from}: ${body}`);
17
- * alice.sendMessage('Bob', 'Hello!');
18
- *
19
- * await relay.stop();
20
- * ```
21
- */
22
-
23
- import { RelayClient, type ClientConfig } from './client.js';
24
-
25
- // Types for the daemon (avoid importing to keep this file lightweight)
26
- interface DaemonLike {
27
- start(): Promise<void>;
28
- stop(): Promise<void>;
29
- isRunning: boolean;
30
- }
31
-
32
- export interface RelayConfig {
33
- /** Socket path for IPC. Default: /tmp/agent-relay-standalone.sock */
34
- socketPath?: string;
35
- /** Suppress console logging. Default: true */
36
- quiet?: boolean;
37
- /** Enable agent spawning. Default: false */
38
- spawnManager?: boolean;
39
- }
40
-
41
- export interface Relay {
42
- /** Create a connected client for an agent */
43
- client(name: string, config?: Partial<ClientConfig>): Promise<RelayClient>;
44
- /** Stop the relay and disconnect all clients */
45
- stop(): Promise<void>;
46
- /** Check if relay is running */
47
- readonly isRunning: boolean;
48
- /** The socket path being used */
49
- readonly socketPath: string;
50
- }
51
-
52
- const DEFAULT_SOCKET_PATH = '/tmp/agent-relay-standalone.sock';
53
-
54
- /**
55
- * Create a standalone relay for pure agent-to-agent communication.
56
- *
57
- * This starts an in-process daemon - no external setup required.
58
- * Perfect for using Agent Relay as just a communication layer.
59
- *
60
- * @example Basic Usage
61
- * ```typescript
62
- * const relay = await createRelay();
63
- *
64
- * const agent1 = await relay.client('Agent1');
65
- * const agent2 = await relay.client('Agent2');
66
- *
67
- * agent2.onMessage = (from, payload) => {
68
- * console.log(`Message from ${from}: ${payload.body}`);
69
- * };
70
- *
71
- * agent1.sendMessage('Agent2', 'Hello!');
72
- * ```
73
- *
74
- * @example With Custom Socket
75
- * ```typescript
76
- * const relay = await createRelay({ socketPath: '/tmp/my-relay.sock' });
77
- * ```
78
- */
79
- export async function createRelay(config: RelayConfig = {}): Promise<Relay> {
80
- const socketPath = config.socketPath ?? DEFAULT_SOCKET_PATH;
81
- const quiet = config.quiet ?? true;
82
-
83
- // Lazy-load daemon to keep SDK lightweight for client-only users
84
- let Daemon: new (config: Record<string, unknown>) => DaemonLike;
85
- try {
86
- // Dynamic import using variable to prevent TypeScript from resolving the module
87
- // This avoids circular dependency: sdk -> daemon -> bridge -> mcp -> sdk
88
- const daemonModulePath = '@agent-relay/daemon';
89
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
90
- const daemonModule: any = await import(/* webpackIgnore: true */ daemonModulePath);
91
- Daemon = daemonModule.Daemon;
92
- } catch {
93
- throw new Error(
94
- 'To use standalone relay, install @agent-relay/daemon:\n' +
95
- ' npm install @agent-relay/daemon\n\n' +
96
- 'Or if you have an external daemon running, use RelayClient directly.'
97
- );
98
- }
99
-
100
- const daemon = new Daemon({
101
- socketPath,
102
- consensus: false, // Minimal mode - just messaging
103
- cloudSync: false, // No cloud features
104
- spawnManager: config.spawnManager ?? false,
105
- });
106
-
107
- await daemon.start();
108
-
109
- const clients: RelayClient[] = [];
110
-
111
- return {
112
- async client(name: string, clientConfig: Partial<ClientConfig> = {}): Promise<RelayClient> {
113
- const client = new RelayClient({
114
- agentName: name,
115
- socketPath,
116
- quiet,
117
- reconnect: true,
118
- ...clientConfig,
119
- });
120
- await client.connect();
121
- clients.push(client);
122
- return client;
123
- },
124
-
125
- async stop(): Promise<void> {
126
- // Disconnect all clients first
127
- for (const client of clients) {
128
- client.destroy();
129
- }
130
- clients.length = 0;
131
- // Stop the daemon
132
- await daemon.stop();
133
- },
134
-
135
- get isRunning(): boolean {
136
- return daemon.isRunning;
137
- },
138
-
139
- get socketPath(): string {
140
- return socketPath;
141
- },
142
- };
143
- }
144
-
145
- /**
146
- * Quick helper to create two connected agents for simple communication.
147
- *
148
- * @example
149
- * ```typescript
150
- * const { alice, bob, stop } = await createPair('Alice', 'Bob');
151
- *
152
- * bob.onMessage = (from, { body }) => console.log(`${from}: ${body}`);
153
- * alice.sendMessage('Bob', 'Hi there!');
154
- *
155
- * await stop();
156
- * ```
157
- */
158
- export async function createPair(
159
- name1: string,
160
- name2: string,
161
- config: RelayConfig = {}
162
- ): Promise<{
163
- [K in typeof name1]: RelayClient;
164
- } & {
165
- [K in typeof name2]: RelayClient;
166
- } & {
167
- relay: Relay;
168
- stop: () => Promise<void>;
169
- }> {
170
- const relay = await createRelay(config);
171
- const client1 = await relay.client(name1);
172
- const client2 = await relay.client(name2);
173
-
174
- return {
175
- [name1]: client1,
176
- [name2]: client2,
177
- relay,
178
- stop: () => relay.stop(),
179
- } as any;
180
- }
181
-
182
- // Re-export client for convenience
183
- export { RelayClient, type ClientConfig } from './client.js';
@@ -1,197 +0,0 @@
1
- /**
2
- * Transport module for relay client communication.
3
- * @agent-relay/sdk
4
- *
5
- * Provides transport abstraction and implementations:
6
- * - SocketTransport: Unix/TCP sockets (Node.js only)
7
- * - WebSocketTransport: WebSocket connections (Node.js and Browser)
8
- *
9
- * Auto-detection selects the appropriate transport based on environment.
10
- */
11
-
12
- // Types
13
- export type {
14
- Transport,
15
- TransportConfig,
16
- TransportEvents,
17
- TransportState,
18
- TransportFactory,
19
- } from './types.js';
20
-
21
- // Socket transport (Node.js)
22
- export {
23
- SocketTransport,
24
- createSocketTransport,
25
- type SocketTransportConfig,
26
- } from './socket-transport.js';
27
-
28
- // WebSocket transport (Node.js and Browser)
29
- export {
30
- WebSocketTransport,
31
- createWebSocketTransport,
32
- socketPathToWsUrl,
33
- type WebSocketTransportConfig,
34
- } from './websocket-transport.js';
35
-
36
- // Re-export types from types.ts for convenience
37
- import type { Transport, TransportConfig } from './types.js';
38
- import { SocketTransport, type SocketTransportConfig } from './socket-transport.js';
39
- import { WebSocketTransport, type WebSocketTransportConfig, socketPathToWsUrl } from './websocket-transport.js';
40
-
41
- /**
42
- * Environment detection result.
43
- */
44
- export interface EnvironmentInfo {
45
- /** Running in browser environment */
46
- isBrowser: boolean;
47
- /** Running in Node.js environment */
48
- isNode: boolean;
49
- /** WebSocket API is available */
50
- hasWebSocket: boolean;
51
- /** Unix sockets are available (Node.js only) */
52
- hasUnixSockets: boolean;
53
- }
54
-
55
- /**
56
- * Detect the current runtime environment.
57
- */
58
- export function detectEnvironment(): EnvironmentInfo {
59
- const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
60
- const isNode = typeof process !== 'undefined' &&
61
- process.versions != null &&
62
- process.versions.node != null;
63
- const hasWebSocket = typeof WebSocket !== 'undefined' || isNode; // 'ws' can provide WebSocket in Node
64
- const hasUnixSockets = isNode; // Only Node.js supports Unix sockets
65
-
66
- return {
67
- isBrowser,
68
- isNode,
69
- hasWebSocket,
70
- hasUnixSockets,
71
- };
72
- }
73
-
74
- /**
75
- * Options for creating an auto-detected transport.
76
- */
77
- export interface AutoTransportOptions extends TransportConfig {
78
- /** Unix socket path (for Node.js socket transport) */
79
- socketPath?: string;
80
- /** WebSocket URL (for WebSocket transport) */
81
- wsUrl?: string;
82
- /** WebSocket host (used with port to construct URL) */
83
- wsHost?: string;
84
- /** WebSocket port (default: 3888) */
85
- wsPort?: number;
86
- /** WebSocket path (default: /ws) */
87
- wsPath?: string;
88
- /** Use secure WebSocket (wss://) */
89
- wsSecure?: boolean;
90
- /** Force a specific transport type */
91
- forceTransport?: 'socket' | 'websocket';
92
- }
93
-
94
- /**
95
- * Create a transport automatically based on environment and options.
96
- *
97
- * In browser environments, WebSocket transport is always used.
98
- * In Node.js, Unix socket is preferred if socketPath is provided,
99
- * otherwise WebSocket is used if wsUrl or wsHost is provided.
100
- *
101
- * @param options - Transport configuration options
102
- * @returns Configured transport instance
103
- *
104
- * @example Browser usage
105
- * ```typescript
106
- * const transport = createAutoTransport({
107
- * wsUrl: 'wss://relay.example.com/ws'
108
- * });
109
- * ```
110
- *
111
- * @example Node.js with Unix socket
112
- * ```typescript
113
- * const transport = createAutoTransport({
114
- * socketPath: '/tmp/agent-relay.sock'
115
- * });
116
- * ```
117
- *
118
- * @example Node.js with WebSocket
119
- * ```typescript
120
- * const transport = createAutoTransport({
121
- * wsHost: 'localhost',
122
- * wsPort: 3888
123
- * });
124
- * ```
125
- */
126
- export function createAutoTransport(options: AutoTransportOptions): Transport {
127
- const env = detectEnvironment();
128
- const { forceTransport, ...config } = options;
129
-
130
- // Forced transport type
131
- if (forceTransport === 'websocket') {
132
- return createWsTransportFromOptions(options);
133
- }
134
- if (forceTransport === 'socket') {
135
- if (!options.socketPath) {
136
- throw new Error('socketPath is required when forcing socket transport');
137
- }
138
- if (!env.hasUnixSockets) {
139
- throw new Error('Unix sockets are not available in this environment');
140
- }
141
- return new SocketTransport({
142
- socketPath: options.socketPath,
143
- connectTimeout: config.connectTimeout,
144
- });
145
- }
146
-
147
- // Auto-detect: Browser always uses WebSocket
148
- if (env.isBrowser) {
149
- return createWsTransportFromOptions(options);
150
- }
151
-
152
- // Node.js: prefer Unix socket if path is provided
153
- if (env.isNode && options.socketPath) {
154
- return new SocketTransport({
155
- socketPath: options.socketPath,
156
- connectTimeout: config.connectTimeout,
157
- });
158
- }
159
-
160
- // Fall back to WebSocket
161
- return createWsTransportFromOptions(options);
162
- }
163
-
164
- /**
165
- * Create WebSocket transport from options.
166
- */
167
- function createWsTransportFromOptions(options: AutoTransportOptions): WebSocketTransport {
168
- let url = options.wsUrl;
169
-
170
- if (!url) {
171
- // Construct URL from components
172
- const host = options.wsHost ?? 'localhost';
173
- const port = options.wsPort ?? 3888;
174
- const path = options.wsPath ?? '/ws';
175
- const secure = options.wsSecure ?? false;
176
- url = socketPathToWsUrl(host, port, path, secure);
177
- }
178
-
179
- return new WebSocketTransport({
180
- url,
181
- connectTimeout: options.connectTimeout,
182
- });
183
- }
184
-
185
- /**
186
- * Check if running in a browser environment.
187
- */
188
- export function isBrowser(): boolean {
189
- return detectEnvironment().isBrowser;
190
- }
191
-
192
- /**
193
- * Check if running in Node.js environment.
194
- */
195
- export function isNode(): boolean {
196
- return detectEnvironment().isNode;
197
- }