@agent-relay/sdk 2.3.14 → 2.4.1

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 (179) hide show
  1. package/README.md +68 -838
  2. package/bin/agent-relay-broker +0 -0
  3. package/dist/__tests__/contract-fixtures.test.d.ts +2 -0
  4. package/dist/__tests__/contract-fixtures.test.d.ts.map +1 -0
  5. package/dist/__tests__/contract-fixtures.test.js +85 -0
  6. package/dist/__tests__/contract-fixtures.test.js.map +1 -0
  7. package/dist/__tests__/facade.test.d.ts +2 -0
  8. package/dist/__tests__/facade.test.d.ts.map +1 -0
  9. package/dist/__tests__/facade.test.js +305 -0
  10. package/dist/__tests__/facade.test.js.map +1 -0
  11. package/dist/__tests__/integration.test.d.ts +2 -0
  12. package/dist/__tests__/integration.test.d.ts.map +1 -0
  13. package/dist/__tests__/integration.test.js +169 -0
  14. package/dist/__tests__/integration.test.js.map +1 -0
  15. package/dist/__tests__/pty.test.d.ts +2 -0
  16. package/dist/__tests__/pty.test.d.ts.map +1 -0
  17. package/dist/__tests__/pty.test.js +20 -0
  18. package/dist/__tests__/pty.test.js.map +1 -0
  19. package/dist/__tests__/quickstart.test.d.ts +2 -0
  20. package/dist/__tests__/quickstart.test.d.ts.map +1 -0
  21. package/dist/__tests__/quickstart.test.js +176 -0
  22. package/dist/__tests__/quickstart.test.js.map +1 -0
  23. package/dist/__tests__/spawn-from-env.test.d.ts +2 -0
  24. package/dist/__tests__/spawn-from-env.test.d.ts.map +1 -0
  25. package/dist/__tests__/spawn-from-env.test.js +206 -0
  26. package/dist/__tests__/spawn-from-env.test.js.map +1 -0
  27. package/dist/__tests__/unit.test.d.ts +2 -0
  28. package/dist/__tests__/unit.test.d.ts.map +1 -0
  29. package/dist/__tests__/unit.test.js +347 -0
  30. package/dist/__tests__/unit.test.js.map +1 -0
  31. package/dist/browser.d.ts +16 -0
  32. package/dist/browser.d.ts.map +1 -0
  33. package/dist/browser.js +19 -0
  34. package/dist/browser.js.map +1 -0
  35. package/dist/client.d.ts +140 -526
  36. package/dist/client.d.ts.map +1 -1
  37. package/dist/client.js +416 -1509
  38. package/dist/client.js.map +1 -1
  39. package/dist/consensus-helpers.d.ts +103 -0
  40. package/dist/consensus-helpers.d.ts.map +1 -0
  41. package/dist/consensus-helpers.js +147 -0
  42. package/dist/consensus-helpers.js.map +1 -0
  43. package/dist/consensus.d.ts +72 -0
  44. package/dist/consensus.d.ts.map +1 -0
  45. package/dist/consensus.js +378 -0
  46. package/dist/consensus.js.map +1 -0
  47. package/dist/examples/demo.d.ts +2 -0
  48. package/dist/examples/demo.d.ts.map +1 -0
  49. package/dist/examples/demo.js +63 -0
  50. package/dist/examples/demo.js.map +1 -0
  51. package/dist/examples/example.d.ts +2 -0
  52. package/dist/examples/example.d.ts.map +1 -0
  53. package/dist/examples/example.js +80 -0
  54. package/dist/examples/example.js.map +1 -0
  55. package/dist/examples/quickstart.d.ts +2 -0
  56. package/dist/examples/quickstart.d.ts.map +1 -0
  57. package/dist/examples/quickstart.js +56 -0
  58. package/dist/examples/quickstart.js.map +1 -0
  59. package/dist/examples/ralph-loop.d.ts +2 -0
  60. package/dist/examples/ralph-loop.d.ts.map +1 -0
  61. package/dist/examples/ralph-loop.js +281 -0
  62. package/dist/examples/ralph-loop.js.map +1 -0
  63. package/dist/examples/workflow-superiority.d.ts +32 -0
  64. package/dist/examples/workflow-superiority.d.ts.map +1 -0
  65. package/dist/examples/workflow-superiority.js +1421 -0
  66. package/dist/examples/workflow-superiority.js.map +1 -0
  67. package/dist/index.d.ts +13 -20
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +12 -26
  70. package/dist/index.js.map +1 -1
  71. package/dist/logs.d.ts +70 -25
  72. package/dist/logs.d.ts.map +1 -1
  73. package/dist/logs.js +238 -42
  74. package/dist/logs.js.map +1 -1
  75. package/dist/models.d.ts +9 -0
  76. package/dist/models.d.ts.map +1 -0
  77. package/dist/models.js +17 -0
  78. package/dist/models.js.map +1 -0
  79. package/dist/protocol.d.ts +366 -0
  80. package/dist/protocol.d.ts.map +1 -0
  81. package/dist/protocol.js +2 -0
  82. package/dist/protocol.js.map +1 -0
  83. package/dist/pty.d.ts +8 -0
  84. package/dist/pty.d.ts.map +1 -0
  85. package/dist/pty.js +26 -0
  86. package/dist/pty.js.map +1 -0
  87. package/dist/relay-adapter.d.ts +139 -0
  88. package/dist/relay-adapter.d.ts.map +1 -0
  89. package/dist/relay-adapter.js +210 -0
  90. package/dist/relay-adapter.js.map +1 -0
  91. package/dist/relay.d.ts +304 -0
  92. package/dist/relay.d.ts.map +1 -0
  93. package/dist/relay.js +910 -0
  94. package/dist/relay.js.map +1 -0
  95. package/dist/shadow.d.ts +101 -0
  96. package/dist/shadow.d.ts.map +1 -0
  97. package/dist/shadow.js +174 -0
  98. package/dist/shadow.js.map +1 -0
  99. package/dist/spawn-from-env.d.ts +77 -0
  100. package/dist/spawn-from-env.d.ts.map +1 -0
  101. package/dist/spawn-from-env.js +172 -0
  102. package/dist/spawn-from-env.js.map +1 -0
  103. package/dist/workflows/barrier.d.ts +72 -0
  104. package/dist/workflows/barrier.d.ts.map +1 -0
  105. package/dist/workflows/barrier.js +162 -0
  106. package/dist/workflows/barrier.js.map +1 -0
  107. package/dist/workflows/builder.d.ts +114 -0
  108. package/dist/workflows/builder.d.ts.map +1 -0
  109. package/dist/workflows/builder.js +201 -0
  110. package/dist/workflows/builder.js.map +1 -0
  111. package/dist/workflows/cli.d.ts +11 -0
  112. package/dist/workflows/cli.d.ts.map +1 -0
  113. package/dist/workflows/cli.js +144 -0
  114. package/dist/workflows/cli.js.map +1 -0
  115. package/dist/workflows/coordinator.d.ts +73 -0
  116. package/dist/workflows/coordinator.d.ts.map +1 -0
  117. package/dist/workflows/coordinator.js +647 -0
  118. package/dist/workflows/coordinator.js.map +1 -0
  119. package/dist/workflows/custom-steps.d.ts +73 -0
  120. package/dist/workflows/custom-steps.d.ts.map +1 -0
  121. package/dist/workflows/custom-steps.js +321 -0
  122. package/dist/workflows/custom-steps.js.map +1 -0
  123. package/dist/workflows/dry-run-format.d.ts +6 -0
  124. package/dist/workflows/dry-run-format.d.ts.map +1 -0
  125. package/dist/workflows/dry-run-format.js +68 -0
  126. package/dist/workflows/dry-run-format.js.map +1 -0
  127. package/dist/workflows/file-db.d.ts +33 -0
  128. package/dist/workflows/file-db.d.ts.map +1 -0
  129. package/dist/workflows/file-db.js +108 -0
  130. package/dist/workflows/file-db.js.map +1 -0
  131. package/dist/workflows/index.d.ts +15 -0
  132. package/dist/workflows/index.d.ts.map +1 -0
  133. package/dist/workflows/index.js +15 -0
  134. package/dist/workflows/index.js.map +1 -0
  135. package/dist/workflows/memory-db.d.ts +17 -0
  136. package/dist/workflows/memory-db.d.ts.map +1 -0
  137. package/dist/workflows/memory-db.js +33 -0
  138. package/dist/workflows/memory-db.js.map +1 -0
  139. package/dist/workflows/run.d.ts +38 -0
  140. package/dist/workflows/run.d.ts.map +1 -0
  141. package/dist/workflows/run.js +25 -0
  142. package/dist/workflows/run.js.map +1 -0
  143. package/dist/workflows/runner.d.ts +320 -0
  144. package/dist/workflows/runner.d.ts.map +1 -0
  145. package/dist/workflows/runner.js +2821 -0
  146. package/dist/workflows/runner.js.map +1 -0
  147. package/dist/workflows/state.d.ts +77 -0
  148. package/dist/workflows/state.d.ts.map +1 -0
  149. package/dist/workflows/state.js +140 -0
  150. package/dist/workflows/state.js.map +1 -0
  151. package/dist/workflows/templates.d.ts +47 -0
  152. package/dist/workflows/templates.d.ts.map +1 -0
  153. package/dist/workflows/templates.js +405 -0
  154. package/dist/workflows/templates.js.map +1 -0
  155. package/dist/workflows/trajectory.d.ts +87 -0
  156. package/dist/workflows/trajectory.d.ts.map +1 -0
  157. package/dist/workflows/trajectory.js +441 -0
  158. package/dist/workflows/trajectory.js.map +1 -0
  159. package/dist/workflows/types.d.ts +306 -0
  160. package/dist/workflows/types.d.ts.map +1 -0
  161. package/dist/workflows/types.js +23 -0
  162. package/dist/workflows/types.js.map +1 -0
  163. package/dist/workflows/validator.d.ts +11 -0
  164. package/dist/workflows/validator.d.ts.map +1 -0
  165. package/dist/workflows/validator.js +128 -0
  166. package/dist/workflows/validator.js.map +1 -0
  167. package/package.json +59 -53
  168. package/dist/discovery.d.ts +0 -10
  169. package/dist/discovery.d.ts.map +0 -1
  170. package/dist/discovery.js +0 -22
  171. package/dist/discovery.js.map +0 -1
  172. package/dist/errors.d.ts +0 -9
  173. package/dist/errors.d.ts.map +0 -1
  174. package/dist/errors.js +0 -9
  175. package/dist/errors.js.map +0 -1
  176. package/dist/protocol/index.d.ts +0 -8
  177. package/dist/protocol/index.d.ts.map +0 -1
  178. package/dist/protocol/index.js +0 -8
  179. package/dist/protocol/index.js.map +0 -1
Binary file
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=contract-fixtures.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-fixtures.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/contract-fixtures.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,85 @@
1
+ import assert from 'node:assert/strict';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import test from 'node:test';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { AgentRelayClient, AgentRelayProtocolError } from '../client.js';
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = path.dirname(__filename);
9
+ const fixturesDir = path.resolve(__dirname, '../../../contracts/fixtures');
10
+ function readFixture(name) {
11
+ const fixturePath = path.join(fixturesDir, name);
12
+ const raw = fs.readFileSync(fixturePath, 'utf8');
13
+ return JSON.parse(raw);
14
+ }
15
+ function isCurrentSdkBrokerEventShape(event) {
16
+ const kind = event.kind;
17
+ if (typeof kind !== 'string')
18
+ return false;
19
+ switch (kind) {
20
+ case 'relay_inbound':
21
+ return (typeof event.event_id === 'string' &&
22
+ typeof event.from === 'string' &&
23
+ typeof event.target === 'string' &&
24
+ typeof event.body === 'string');
25
+ case 'agent_spawned':
26
+ return typeof event.name === 'string' && typeof event.runtime === 'string';
27
+ case 'agent_exited':
28
+ return typeof event.name === 'string';
29
+ case 'agent_released':
30
+ return typeof event.name === 'string';
31
+ case 'worker_ready':
32
+ return typeof event.name === 'string' && typeof event.runtime === 'string';
33
+ case 'agent_idle':
34
+ return typeof event.name === 'string' && typeof event.idle_secs === 'number';
35
+ case 'delivery_verified':
36
+ return (typeof event.name === 'string' &&
37
+ typeof event.delivery_id === 'string' &&
38
+ typeof event.event_id === 'string');
39
+ case 'delivery_failed':
40
+ return (typeof event.name === 'string' &&
41
+ typeof event.delivery_id === 'string' &&
42
+ typeof event.event_id === 'string' &&
43
+ typeof event.reason === 'string');
44
+ case 'worker_error':
45
+ return (typeof event.name === 'string' &&
46
+ typeof event.code === 'string' &&
47
+ typeof event.message === 'string');
48
+ case 'agent_restarting':
49
+ case 'agent_restarted':
50
+ case 'agent_permanently_dead':
51
+ return typeof event.name === 'string';
52
+ default:
53
+ return false;
54
+ }
55
+ }
56
+ test('contracts: broker-sdk unsupported_operation fallback maps to shared RelayErrorCode set', async () => {
57
+ const fixture = readFixture('error-fixtures.json');
58
+ const allowedCodes = new Set(fixture.relay_errors.map((entry) => entry.code));
59
+ const client = new AgentRelayClient();
60
+ client.start = async () => undefined;
61
+ client.requestOk = async () => {
62
+ throw new AgentRelayProtocolError({
63
+ code: 'unsupported_operation',
64
+ message: 'send_message unsupported',
65
+ retryable: false,
66
+ });
67
+ };
68
+ const result = await client.sendMessage({
69
+ to: 'WorkerA',
70
+ text: 'contract-gate probe',
71
+ });
72
+ assert.equal(result.event_id, 'unsupported_operation');
73
+ // TODO(contract-wave1-error-codes): broker-sdk fallback sentinel should align
74
+ // with shared RelayErrorCode contracts, or be mapped before surface exposure.
75
+ assert.equal(allowedCodes.has(result.event_id), true, `unsupported fallback code \"${result.event_id}\" is outside shared RelayErrorCode fixture set`);
76
+ });
77
+ test('contracts: broker-sdk event surface conforms to shared BrokerEvent fixture envelope', async () => {
78
+ const fixture = readFixture('event-fixtures.json');
79
+ for (const event of fixture.contract_events) {
80
+ // TODO(contract-wave1-event-envelope): broker-sdk should consume/emit the
81
+ // shared envelope shape (eventId/seq/timestamp/payload) from contracts fixtures.
82
+ assert.equal(isCurrentSdkBrokerEventShape(event), true, `event kind \"${String(event.kind)}\" does not match current broker-sdk event surface`);
83
+ }
84
+ });
85
+ //# sourceMappingURL=contract-fixtures.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-fixtures.test.js","sourceRoot":"","sources":["../../src/__tests__/contract-fixtures.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=facade.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facade.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/facade.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,305 @@
1
+ /**
2
+ * Facade integration tests — exercises new AgentRelay capabilities:
3
+ * spawn with initial task, getLogs, waitForAny, broadcast, onAgentReady, exit code.
4
+ *
5
+ * Run:
6
+ * npm run build && node --test dist/__tests__/facade.test.js
7
+ *
8
+ * Requires:
9
+ * RELAY_API_KEY — Relaycast workspace key
10
+ * AGENT_RELAY_BIN (optional) — path to agent-relay-broker binary
11
+ */
12
+ import assert from "node:assert/strict";
13
+ import fs from "node:fs";
14
+ import path from "node:path";
15
+ import test from "node:test";
16
+ import { AgentRelay } from "../relay.js";
17
+ // ── helpers ─────────────────────────────────────────────────────────────────
18
+ function resolveBinaryPath() {
19
+ if (process.env.AGENT_RELAY_BIN) {
20
+ return process.env.AGENT_RELAY_BIN;
21
+ }
22
+ return path.resolve(process.cwd(), "../../target/debug/agent-relay-broker");
23
+ }
24
+ function requireRelaycast(t) {
25
+ if (!process.env.RELAY_API_KEY?.trim()) {
26
+ t.skip("RELAY_API_KEY is required");
27
+ return false;
28
+ }
29
+ return true;
30
+ }
31
+ function requireBinary(t) {
32
+ const bin = resolveBinaryPath();
33
+ if (!fs.existsSync(bin)) {
34
+ t.skip(`agent-relay-broker binary not found at ${bin}`);
35
+ return null;
36
+ }
37
+ return bin;
38
+ }
39
+ function makeRelay(bin) {
40
+ return new AgentRelay({
41
+ binaryPath: bin,
42
+ requestTimeoutMs: 10_000,
43
+ env: process.env,
44
+ });
45
+ }
46
+ // ── spawn with initial task ─────────────────────────────────────────────────
47
+ test("facade: spawn with initial task delivers task after worker_ready", async (t) => {
48
+ if (!requireRelaycast(t))
49
+ return;
50
+ const bin = requireBinary(t);
51
+ if (!bin)
52
+ return;
53
+ const suffix = Date.now().toString(36);
54
+ const relay = makeRelay(bin);
55
+ const readyNames = [];
56
+ relay.onAgentReady = (agent) => readyNames.push(agent.name);
57
+ try {
58
+ const agent = await relay.spawnPty({
59
+ name: `Task-${suffix}`,
60
+ cli: "cat",
61
+ channels: ["general"],
62
+ task: "Hello from initial task",
63
+ });
64
+ // Wait a bit for worker_ready event to propagate
65
+ await new Promise((r) => setTimeout(r, 2_000));
66
+ assert.ok(readyNames.includes(agent.name), "onAgentReady should fire for spawned agent");
67
+ await agent.release();
68
+ }
69
+ finally {
70
+ await relay.shutdown();
71
+ }
72
+ });
73
+ // ── onAgentReady ────────────────────────────────────────────────────────────
74
+ test("facade: onAgentReady fires when worker becomes ready", async (t) => {
75
+ if (!requireRelaycast(t))
76
+ return;
77
+ const bin = requireBinary(t);
78
+ if (!bin)
79
+ return;
80
+ const suffix = Date.now().toString(36);
81
+ const relay = makeRelay(bin);
82
+ const readyAgents = [];
83
+ relay.onAgentReady = (agent) => readyAgents.push(agent);
84
+ try {
85
+ const agent = await relay.spawnPty({
86
+ name: `Ready-${suffix}`,
87
+ cli: "cat",
88
+ channels: ["general"],
89
+ });
90
+ // Give the worker time to send worker_ready
91
+ await new Promise((r) => setTimeout(r, 2_000));
92
+ assert.ok(readyAgents.some((a) => a.name === agent.name), "onAgentReady should fire with the correct agent");
93
+ await agent.release();
94
+ }
95
+ finally {
96
+ await relay.shutdown();
97
+ }
98
+ });
99
+ // ── broadcast ───────────────────────────────────────────────────────────────
100
+ test("facade: broadcast sends to all agents", async (t) => {
101
+ if (!requireRelaycast(t))
102
+ return;
103
+ const bin = requireBinary(t);
104
+ if (!bin)
105
+ return;
106
+ const suffix = Date.now().toString(36);
107
+ const relay = makeRelay(bin);
108
+ const sentMessages = [];
109
+ relay.onMessageSent = (msg) => sentMessages.push(msg);
110
+ try {
111
+ const agent = await relay.spawnPty({
112
+ name: `Broadcast-${suffix}`,
113
+ cli: "cat",
114
+ channels: ["general"],
115
+ });
116
+ const msg = await relay.broadcast("Hello everyone!");
117
+ assert.equal(msg.to, "*");
118
+ assert.equal(msg.text, "Hello everyone!");
119
+ assert.equal(msg.from, "human:orchestrator");
120
+ assert.equal(sentMessages.length, 1);
121
+ // Broadcast with custom from
122
+ const msg2 = await relay.broadcast("Custom sender", { from: "System" });
123
+ assert.equal(msg2.from, "System");
124
+ await agent.release();
125
+ }
126
+ finally {
127
+ await relay.shutdown();
128
+ }
129
+ });
130
+ // ── waitForAny ──────────────────────────────────────────────────────────────
131
+ test("facade: waitForAny returns first agent to exit", async (t) => {
132
+ if (!requireRelaycast(t))
133
+ return;
134
+ const bin = requireBinary(t);
135
+ if (!bin)
136
+ return;
137
+ const suffix = Date.now().toString(36);
138
+ const relay = makeRelay(bin);
139
+ try {
140
+ const [a, b] = await Promise.all([
141
+ relay.spawnPty({ name: `WaitA-${suffix}`, cli: "cat", channels: ["general"] }),
142
+ relay.spawnPty({ name: `WaitB-${suffix}`, cli: "cat", channels: ["general"] }),
143
+ ]);
144
+ // Release agent A — it should be the first to exit
145
+ setTimeout(() => a.release(), 500);
146
+ const { agent, result } = await AgentRelay.waitForAny([a, b], 10_000);
147
+ assert.equal(agent.name, a.name);
148
+ assert.equal(result, "released");
149
+ await b.release();
150
+ }
151
+ finally {
152
+ await relay.shutdown();
153
+ }
154
+ });
155
+ // ── waitForAny with timeout ─────────────────────────────────────────────────
156
+ test("facade: waitForAny respects timeout", async (t) => {
157
+ if (!requireRelaycast(t))
158
+ return;
159
+ const bin = requireBinary(t);
160
+ if (!bin)
161
+ return;
162
+ const suffix = Date.now().toString(36);
163
+ const relay = makeRelay(bin);
164
+ try {
165
+ const agent = await relay.spawnPty({
166
+ name: `Timeout-${suffix}`,
167
+ cli: "cat",
168
+ channels: ["general"],
169
+ });
170
+ const { result } = await AgentRelay.waitForAny([agent], 500);
171
+ assert.equal(result, "timeout");
172
+ await agent.release();
173
+ }
174
+ finally {
175
+ await relay.shutdown();
176
+ }
177
+ });
178
+ // ── exit code ───────────────────────────────────────────────────────────────
179
+ test("facade: onAgentExited populates exitCode and exitSignal", async (t) => {
180
+ if (!requireRelaycast(t))
181
+ return;
182
+ const bin = requireBinary(t);
183
+ if (!bin)
184
+ return;
185
+ const suffix = Date.now().toString(36);
186
+ const relay = makeRelay(bin);
187
+ const exitedAgents = [];
188
+ relay.onAgentExited = (agent) => exitedAgents.push(agent);
189
+ try {
190
+ const agent = await relay.spawnPty({
191
+ name: `Exit-${suffix}`,
192
+ cli: "cat",
193
+ channels: ["general"],
194
+ });
195
+ await agent.release();
196
+ // Give time for exit event to propagate
197
+ await new Promise((r) => setTimeout(r, 1_000));
198
+ // The agent should have exited — check that exitCode or exitSignal is set
199
+ // (exact values depend on how cat is terminated)
200
+ const exited = exitedAgents.find((a) => a.name === agent.name);
201
+ if (exited) {
202
+ assert.ok(exited.exitCode !== undefined || exited.exitSignal !== undefined, "exitCode or exitSignal should be populated");
203
+ }
204
+ // It's also valid for only onAgentReleased to fire (not onAgentExited)
205
+ // since the broker may clean up before the process exits
206
+ }
207
+ finally {
208
+ await relay.shutdown();
209
+ }
210
+ });
211
+ // ── getLogs ──────────────────────────────────────────────────────────────────
212
+ test("facade: getLogs returns log content for agent", async (t) => {
213
+ if (!requireRelaycast(t))
214
+ return;
215
+ const bin = requireBinary(t);
216
+ if (!bin)
217
+ return;
218
+ const suffix = Date.now().toString(36);
219
+ const relay = makeRelay(bin);
220
+ try {
221
+ const agent = await relay.spawnPty({
222
+ name: `Logs-${suffix}`,
223
+ cli: "cat",
224
+ channels: ["general"],
225
+ });
226
+ // Give time for some output to be logged
227
+ await new Promise((r) => setTimeout(r, 2_000));
228
+ const logs = await relay.getLogs(agent.name);
229
+ // Logs may or may not be found depending on whether the worker writes to the log file
230
+ // The important thing is the API works without error
231
+ assert.equal(logs.agent, agent.name);
232
+ assert.equal(typeof logs.found, "boolean");
233
+ assert.equal(typeof logs.content, "string");
234
+ await agent.release();
235
+ }
236
+ finally {
237
+ await relay.shutdown();
238
+ }
239
+ });
240
+ // ── listLoggedAgents ────────────────────────────────────────────────────────
241
+ test("facade: listLoggedAgents returns array", async (t) => {
242
+ if (!requireRelaycast(t))
243
+ return;
244
+ const bin = requireBinary(t);
245
+ if (!bin)
246
+ return;
247
+ const relay = makeRelay(bin);
248
+ try {
249
+ // Just verify the API works and returns an array
250
+ const agents = await relay.listLoggedAgents();
251
+ assert.ok(Array.isArray(agents));
252
+ }
253
+ finally {
254
+ await relay.shutdown();
255
+ }
256
+ });
257
+ // ── workspaceKey / observerUrl from hello_ack ────────────────────────────────
258
+ test("facade: workspaceKey is populated from broker hello_ack after startup", async (t) => {
259
+ const bin = requireBinary(t);
260
+ if (!bin)
261
+ return;
262
+ // Create relay WITHOUT passing RELAY_API_KEY in env — broker creates its own
263
+ // workspace and returns the key via hello_ack. This tests the fix for the
264
+ // "dual workspace" bug where SDK and broker used different workspace keys.
265
+ const envWithoutKey = { ...process.env };
266
+ delete envWithoutKey.RELAY_API_KEY;
267
+ const relay = new AgentRelay({
268
+ binaryPath: bin,
269
+ requestTimeoutMs: 15_000,
270
+ env: envWithoutKey,
271
+ });
272
+ try {
273
+ await relay.getStatus();
274
+ // After startup, workspaceKey MUST be set from the broker's hello_ack.
275
+ assert.ok(relay.workspaceKey, "workspaceKey must be set after broker startup (read from hello_ack workspace_key field)");
276
+ assert.match(relay.workspaceKey, /^rk_live_/, "workspaceKey must be a valid workspace key (rk_live_ prefix)");
277
+ // observerUrl must be correctly formatted.
278
+ assert.ok(relay.observerUrl, "observerUrl must be defined when workspaceKey is set");
279
+ assert.ok(relay.observerUrl.includes(relay.workspaceKey), "observerUrl must contain the workspace key");
280
+ }
281
+ finally {
282
+ await relay.shutdown();
283
+ }
284
+ });
285
+ test("facade: workspaceKey from env matches broker hello_ack when valid", async (t) => {
286
+ if (!requireRelaycast(t))
287
+ return;
288
+ const bin = requireBinary(t);
289
+ if (!bin)
290
+ return;
291
+ // When RELAY_API_KEY is valid, the broker uses it and returns the same key
292
+ // in hello_ack. SDK and broker must be on the same workspace.
293
+ const relay = makeRelay(bin);
294
+ try {
295
+ await relay.getStatus();
296
+ assert.ok(relay.workspaceKey, "workspaceKey must be set after startup");
297
+ // The workspace key returned by broker must match what we passed in.
298
+ assert.equal(relay.workspaceKey, process.env.RELAY_API_KEY, "broker hello_ack workspace_key must match the RELAY_API_KEY we passed — " +
299
+ "a mismatch means broker and SDK are on different workspaces, breaking MCP auth");
300
+ }
301
+ finally {
302
+ await relay.shutdown();
303
+ }
304
+ });
305
+ //# sourceMappingURL=facade.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facade.test.js","sourceRoot":"","sources":["../../src/__tests__/facade.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,169 @@
1
+ import assert from 'node:assert/strict';
2
+ import fs from 'node:fs';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import test, { before } from 'node:test';
6
+ import { AgentRelayClient, AgentRelayProcessError } from '../client.js';
7
+ import { RelayCast } from '@relaycast/sdk';
8
+ function resolveBinaryPath() {
9
+ if (process.env.AGENT_RELAY_BIN) {
10
+ return process.env.AGENT_RELAY_BIN;
11
+ }
12
+ return path.resolve(process.cwd(), '../../target/debug/agent-relay-broker');
13
+ }
14
+ function resolveBundledBinaryPath() {
15
+ const exe = process.platform === 'win32' ? 'agent-relay-broker.exe' : 'agent-relay-broker';
16
+ return path.resolve(process.cwd(), 'bin', exe);
17
+ }
18
+ // Ensure RELAY_API_KEY is available before any tests run.
19
+ // Creates an ephemeral workspace if no key is set.
20
+ before(async () => {
21
+ if (process.env.RELAY_API_KEY?.trim())
22
+ return;
23
+ const ws = await RelayCast.createWorkspace(`sdk-test-${Date.now().toString(36)}`);
24
+ const workspace = ws;
25
+ const apiKey = workspace.apiKey ?? workspace.api_key;
26
+ if (!apiKey) {
27
+ throw new Error('RelayCast.createWorkspace() did not return an API key');
28
+ }
29
+ process.env.RELAY_API_KEY = apiKey;
30
+ });
31
+ test('sdk can use bundled binary by default', async (t) => {
32
+ const bundledBinary = resolveBundledBinaryPath();
33
+ if (!fs.existsSync(bundledBinary)) {
34
+ t.skip(`bundled binary not found at ${bundledBinary}`);
35
+ return;
36
+ }
37
+ const client = await AgentRelayClient.start({
38
+ env: process.env,
39
+ });
40
+ try {
41
+ const agents = await client.listAgents();
42
+ assert.ok(Array.isArray(agents), 'listAgents should return an array');
43
+ }
44
+ finally {
45
+ await client.shutdown();
46
+ }
47
+ });
48
+ test('sdk can start broker and manage agent lifecycle', async (t) => {
49
+ const binaryPath = resolveBinaryPath();
50
+ if (!fs.existsSync(binaryPath)) {
51
+ t.skip(`agent-relay-broker binary not found at ${binaryPath}`);
52
+ return;
53
+ }
54
+ const client = await AgentRelayClient.start({
55
+ binaryPath,
56
+ requestTimeoutMs: 8_000,
57
+ shutdownTimeoutMs: 2_000,
58
+ env: process.env,
59
+ });
60
+ const spawnedName = `sdk-test-${Date.now().toString(36)}`;
61
+ const seenEvents = [];
62
+ const unsub = client.onEvent((event) => {
63
+ seenEvents.push(event.kind);
64
+ });
65
+ try {
66
+ const spawned = await client.spawnPty({
67
+ name: spawnedName,
68
+ cli: 'cat',
69
+ channels: ['general'],
70
+ });
71
+ assert.equal(spawned.name, spawnedName);
72
+ assert.equal(spawned.runtime, 'pty');
73
+ const agentsAfterSpawn = await client.listAgents();
74
+ const spawnedAgent = agentsAfterSpawn.find((agent) => agent.name === spawnedName);
75
+ assert.ok(spawnedAgent, 'spawned agent should be present in listAgents()');
76
+ assert.equal(spawnedAgent?.runtime, 'pty');
77
+ const released = await client.release(spawnedName);
78
+ assert.equal(released.name, spawnedName);
79
+ const agentsAfterRelease = await client.listAgents();
80
+ assert.equal(agentsAfterRelease.some((agent) => agent.name === spawnedName), false, 'released agent should not be present in listAgents()');
81
+ assert.ok(seenEvents.includes('agent_spawned'), 'expected agent_spawned event');
82
+ assert.ok(seenEvents.includes('agent_released'), 'expected agent_released event');
83
+ }
84
+ finally {
85
+ unsub();
86
+ await client.shutdown();
87
+ }
88
+ });
89
+ test('sdk can spawn and release headless claude worker', async (t) => {
90
+ const binaryPath = resolveBinaryPath();
91
+ if (!fs.existsSync(binaryPath)) {
92
+ t.skip(`agent-relay-broker binary not found at ${binaryPath}`);
93
+ return;
94
+ }
95
+ const client = await AgentRelayClient.start({
96
+ binaryPath,
97
+ requestTimeoutMs: 8_000,
98
+ shutdownTimeoutMs: 2_000,
99
+ env: process.env,
100
+ });
101
+ const spawnedName = `sdk-headless-${Date.now().toString(36)}`;
102
+ const seenEvents = [];
103
+ const unsub = client.onEvent((event) => {
104
+ seenEvents.push(event.kind);
105
+ });
106
+ try {
107
+ const spawned = await client.spawnHeadlessClaude({
108
+ name: spawnedName,
109
+ channels: ['general'],
110
+ });
111
+ assert.equal(spawned.name, spawnedName);
112
+ assert.equal(spawned.runtime, 'headless_claude');
113
+ const agentsAfterSpawn = await client.listAgents();
114
+ const spawnedAgent = agentsAfterSpawn.find((agent) => agent.name === spawnedName);
115
+ assert.ok(spawnedAgent, 'spawned headless agent should be present in listAgents()');
116
+ assert.equal(spawnedAgent?.runtime, 'headless_claude');
117
+ const released = await client.release(spawnedName);
118
+ assert.equal(released.name, spawnedName);
119
+ const agentsAfterRelease = await client.listAgents();
120
+ assert.equal(agentsAfterRelease.some((agent) => agent.name === spawnedName), false, 'released headless agent should not be present in listAgents()');
121
+ assert.ok(seenEvents.includes('agent_spawned'), 'expected agent_spawned event');
122
+ assert.ok(seenEvents.includes('agent_released'), 'expected agent_released event');
123
+ }
124
+ finally {
125
+ unsub();
126
+ await client.shutdown();
127
+ }
128
+ });
129
+ test('sdk surfaces process error when binary is missing', async () => {
130
+ await assert.rejects(AgentRelayClient.start({
131
+ binaryPath: '/definitely/missing/agent-relay-broker',
132
+ requestTimeoutMs: 1_000,
133
+ }), (error) => {
134
+ return error instanceof AgentRelayProcessError || error instanceof Error;
135
+ });
136
+ });
137
+ test('sdk includes broker stderr details when startup fails', async (t) => {
138
+ const binaryPath = resolveBinaryPath();
139
+ if (!fs.existsSync(binaryPath)) {
140
+ t.skip(`agent-relay-broker binary not found at ${binaryPath}`);
141
+ return;
142
+ }
143
+ const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'sdk-broker-lock-'));
144
+ const first = await AgentRelayClient.start({
145
+ binaryPath,
146
+ cwd,
147
+ requestTimeoutMs: 8_000,
148
+ shutdownTimeoutMs: 2_000,
149
+ env: process.env,
150
+ });
151
+ try {
152
+ await assert.rejects(AgentRelayClient.start({
153
+ binaryPath,
154
+ cwd,
155
+ requestTimeoutMs: 2_000,
156
+ shutdownTimeoutMs: 2_000,
157
+ env: process.env,
158
+ }), (error) => {
159
+ assert.ok(error instanceof AgentRelayProcessError || error instanceof Error);
160
+ assert.match(String(error.message), /another broker instance is already running/i);
161
+ return true;
162
+ });
163
+ }
164
+ finally {
165
+ await first.shutdown();
166
+ fs.rmSync(cwd, { recursive: true, force: true });
167
+ }
168
+ });
169
+ //# sourceMappingURL=integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../../src/__tests__/integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pty.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pty.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/pty.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,20 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+ import { cleanLines, stripAnsi } from "../pty.js";
4
+ test("stripAnsi: strips CSI/OSC sequences", () => {
5
+ assert.equal(stripAnsi("\x1b[32mgreen\x1b[0m"), "green");
6
+ assert.equal(stripAnsi("\x1b]0;title\x07text"), "text");
7
+ });
8
+ test("stripAnsi: preserves cursor-forward spacing for ANSI CSI", () => {
9
+ const input = "\x1b[1CYes,\x1b[2CI\x1b[1Caccept";
10
+ assert.equal(stripAnsi(input), " Yes, I accept");
11
+ });
12
+ test("stripAnsi: preserves cursor-forward spacing for orphaned CSI", () => {
13
+ const input = "[1CYes,[2CI[1Caccept";
14
+ assert.equal(stripAnsi(input), " Yes, I accept");
15
+ });
16
+ test("cleanLines: strips ANSI and keeps non-empty lines", () => {
17
+ const lines = cleanLines("\x1b[32mline-1\x1b[0m\n\nline-2\n");
18
+ assert.deepEqual(lines, ["line-1", "line-2"]);
19
+ });
20
+ //# sourceMappingURL=pty.test.js.map