agent-relay 6.3.5 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +300 -104
- package/package.json +9 -9
package/dist/index.cjs
CHANGED
|
@@ -43503,6 +43503,7 @@ __export(index_exports, {
|
|
|
43503
43503
|
DEFAULT_PROXY_ENV_REGISTRY: () => DEFAULT_PROXY_ENV_REGISTRY,
|
|
43504
43504
|
DefaultModels: () => DefaultModels,
|
|
43505
43505
|
ERROR_SEARCH_HINT: () => ERROR_SEARCH_HINT,
|
|
43506
|
+
EventBus: () => EventBus,
|
|
43506
43507
|
GEMINI_MODEL_OPTIONS: () => GEMINI_MODEL_OPTIONS,
|
|
43507
43508
|
GeminiModels: () => GeminiModels,
|
|
43508
43509
|
GitHubClient: () => GitHubClient,
|
|
@@ -44423,6 +44424,69 @@ function formatBrokerNotFoundError() {
|
|
|
44423
44424
|
return `@agent-relay/sdk couldn't find an agent-relay-broker binary for ${process.platform}-${process.arch}. The optional dependency ${pkgName} is expected to be installed alongside @agent-relay/sdk. Try reinstalling with --include=optional, or set BROKER_BINARY_PATH to point at a broker binary you've downloaded manually.`;
|
|
44424
44425
|
}
|
|
44425
44426
|
|
|
44427
|
+
// packages/sdk/dist/event-bus.js
|
|
44428
|
+
var EventBus = class {
|
|
44429
|
+
handlers = /* @__PURE__ */ new Map();
|
|
44430
|
+
/**
|
|
44431
|
+
* Register a handler for `event`. Returns an unsubscribe function that
|
|
44432
|
+
* removes the handler when called.
|
|
44433
|
+
*/
|
|
44434
|
+
addListener(event, handler) {
|
|
44435
|
+
let set2 = this.handlers.get(event);
|
|
44436
|
+
if (!set2) {
|
|
44437
|
+
set2 = /* @__PURE__ */ new Set();
|
|
44438
|
+
this.handlers.set(event, set2);
|
|
44439
|
+
}
|
|
44440
|
+
set2.add(handler);
|
|
44441
|
+
return () => {
|
|
44442
|
+
const current = this.handlers.get(event);
|
|
44443
|
+
if (current !== set2)
|
|
44444
|
+
return;
|
|
44445
|
+
current.delete(handler);
|
|
44446
|
+
if (current.size === 0) {
|
|
44447
|
+
this.handlers.delete(event);
|
|
44448
|
+
}
|
|
44449
|
+
};
|
|
44450
|
+
}
|
|
44451
|
+
/** Remove a previously-registered handler. Idempotent. */
|
|
44452
|
+
removeListener(event, handler) {
|
|
44453
|
+
const set2 = this.handlers.get(event);
|
|
44454
|
+
if (!set2)
|
|
44455
|
+
return;
|
|
44456
|
+
set2.delete(handler);
|
|
44457
|
+
if (set2.size === 0) {
|
|
44458
|
+
this.handlers.delete(event);
|
|
44459
|
+
}
|
|
44460
|
+
}
|
|
44461
|
+
/** Number of currently-registered handlers for `event`. Useful for tests. */
|
|
44462
|
+
listenerCount(event) {
|
|
44463
|
+
return this.handlers.get(event)?.size ?? 0;
|
|
44464
|
+
}
|
|
44465
|
+
/** Snapshot the handlers for `event` so iteration is safe under concurrent mutation. */
|
|
44466
|
+
listeners(event) {
|
|
44467
|
+
const set2 = this.handlers.get(event);
|
|
44468
|
+
return set2 ? Array.from(set2) : [];
|
|
44469
|
+
}
|
|
44470
|
+
/**
|
|
44471
|
+
* Fire `event` with `args`, awaiting each handler sequentially in
|
|
44472
|
+
* registration order. Handler exceptions are caught and logged; they
|
|
44473
|
+
* never abort the dispatch chain.
|
|
44474
|
+
*
|
|
44475
|
+
* Return value is intentionally `void`; consumers that need to collect
|
|
44476
|
+
* patches (e.g. `beforeAgentSpawn`'s shallow-merge contract) iterate
|
|
44477
|
+
* `listeners()` directly so they can capture each handler's return.
|
|
44478
|
+
*/
|
|
44479
|
+
async emit(event, ...args) {
|
|
44480
|
+
for (const handler of this.listeners(event)) {
|
|
44481
|
+
try {
|
|
44482
|
+
await handler(...args);
|
|
44483
|
+
} catch (err) {
|
|
44484
|
+
console.error(`[agent-relay] listener for "${String(event)}" threw:`, err);
|
|
44485
|
+
}
|
|
44486
|
+
}
|
|
44487
|
+
}
|
|
44488
|
+
};
|
|
44489
|
+
|
|
44426
44490
|
// packages/sdk/dist/client.js
|
|
44427
44491
|
function isHeadlessProvider(value) {
|
|
44428
44492
|
return value === "claude" || value === "opencode";
|
|
@@ -44430,6 +44494,45 @@ function isHeadlessProvider(value) {
|
|
|
44430
44494
|
function resolveSpawnTransport(input) {
|
|
44431
44495
|
return input.transport ?? (input.provider === "opencode" ? "headless" : "pty");
|
|
44432
44496
|
}
|
|
44497
|
+
function buildSpawnPtyBody(input) {
|
|
44498
|
+
return {
|
|
44499
|
+
name: input.name,
|
|
44500
|
+
cli: input.cli,
|
|
44501
|
+
...input.model !== void 0 ? { model: input.model } : {},
|
|
44502
|
+
args: input.args ?? [],
|
|
44503
|
+
...input.task !== void 0 ? { task: input.task } : {},
|
|
44504
|
+
channels: input.channels ?? [],
|
|
44505
|
+
...input.cwd !== void 0 ? { cwd: input.cwd } : {},
|
|
44506
|
+
...input.team !== void 0 ? { team: input.team } : {},
|
|
44507
|
+
...input.agentToken !== void 0 ? { agentToken: input.agentToken } : {},
|
|
44508
|
+
...input.shadowOf !== void 0 ? { shadowOf: input.shadowOf } : {},
|
|
44509
|
+
...input.shadowMode !== void 0 ? { shadowMode: input.shadowMode } : {},
|
|
44510
|
+
...input.continueFrom !== void 0 ? { continueFrom: input.continueFrom } : {},
|
|
44511
|
+
...input.idleThresholdSecs !== void 0 ? { idleThresholdSecs: input.idleThresholdSecs } : {},
|
|
44512
|
+
...input.restartPolicy !== void 0 ? { restartPolicy: input.restartPolicy } : {},
|
|
44513
|
+
...input.skipRelayPrompt !== void 0 ? { skipRelayPrompt: input.skipRelayPrompt } : {}
|
|
44514
|
+
};
|
|
44515
|
+
}
|
|
44516
|
+
function buildSpawnProviderBody(input, transport) {
|
|
44517
|
+
return {
|
|
44518
|
+
name: input.name,
|
|
44519
|
+
cli: input.provider,
|
|
44520
|
+
...input.model !== void 0 ? { model: input.model } : {},
|
|
44521
|
+
args: input.args ?? [],
|
|
44522
|
+
...input.task !== void 0 ? { task: input.task } : {},
|
|
44523
|
+
channels: input.channels ?? [],
|
|
44524
|
+
...input.cwd !== void 0 ? { cwd: input.cwd } : {},
|
|
44525
|
+
...input.team !== void 0 ? { team: input.team } : {},
|
|
44526
|
+
...input.agentToken !== void 0 ? { agentToken: input.agentToken } : {},
|
|
44527
|
+
...input.shadowOf !== void 0 ? { shadowOf: input.shadowOf } : {},
|
|
44528
|
+
...input.shadowMode !== void 0 ? { shadowMode: input.shadowMode } : {},
|
|
44529
|
+
...input.continueFrom !== void 0 ? { continueFrom: input.continueFrom } : {},
|
|
44530
|
+
...input.idleThresholdSecs !== void 0 ? { idleThresholdSecs: input.idleThresholdSecs } : {},
|
|
44531
|
+
...input.restartPolicy !== void 0 ? { restartPolicy: input.restartPolicy } : {},
|
|
44532
|
+
...input.skipRelayPrompt !== void 0 ? { skipRelayPrompt: input.skipRelayPrompt } : {},
|
|
44533
|
+
transport
|
|
44534
|
+
};
|
|
44535
|
+
}
|
|
44433
44536
|
function isProcessRunning(pid) {
|
|
44434
44537
|
if (!Number.isInteger(pid) || pid <= 0) {
|
|
44435
44538
|
return false;
|
|
@@ -44467,7 +44570,13 @@ var AgentRelayClient = class _AgentRelayClient {
|
|
|
44467
44570
|
/** Lease renewal timer (only for spawned brokers). */
|
|
44468
44571
|
leaseTimer = null;
|
|
44469
44572
|
workspaceKey;
|
|
44573
|
+
/** Resolved broker URL — captured so call-site lifecycle contexts can surface it. */
|
|
44574
|
+
baseUrl;
|
|
44575
|
+
/** Shared multi-listener registry. Created bare when no `eventBus` is passed in. */
|
|
44576
|
+
eventBus;
|
|
44470
44577
|
constructor(options) {
|
|
44578
|
+
this.baseUrl = options.baseUrl;
|
|
44579
|
+
this.eventBus = options.eventBus ?? new EventBus();
|
|
44471
44580
|
this.transport = new BrokerTransport({
|
|
44472
44581
|
baseUrl: options.baseUrl,
|
|
44473
44582
|
apiKey: options.apiKey,
|
|
@@ -44475,6 +44584,39 @@ var AgentRelayClient = class _AgentRelayClient {
|
|
|
44475
44584
|
requestTimeoutMs: options.requestTimeoutMs
|
|
44476
44585
|
});
|
|
44477
44586
|
}
|
|
44587
|
+
/**
|
|
44588
|
+
* Register a listener on the client's event bus. Returns an unsubscribe
|
|
44589
|
+
* function. Equivalent to `client.eventBus.addListener(...)` but mirrors
|
|
44590
|
+
* the `AgentRelay` facade API so direct-client callers don't need to
|
|
44591
|
+
* reach through `.eventBus`.
|
|
44592
|
+
*/
|
|
44593
|
+
addListener(event, handler) {
|
|
44594
|
+
return this.eventBus.addListener(event, handler);
|
|
44595
|
+
}
|
|
44596
|
+
/** Remove a previously-registered listener. */
|
|
44597
|
+
removeListener(event, handler) {
|
|
44598
|
+
this.eventBus.removeListener(event, handler);
|
|
44599
|
+
}
|
|
44600
|
+
/**
|
|
44601
|
+
* Fold `beforeAgentSpawn` patches into the input. Listeners run in
|
|
44602
|
+
* registration order; each may return a {@link SpawnPatch} that is
|
|
44603
|
+
* shallow-merged over the running result. Handler exceptions are caught
|
|
44604
|
+
* and logged but do not abort the chain.
|
|
44605
|
+
*/
|
|
44606
|
+
async runBeforeSpawn(ctx) {
|
|
44607
|
+
let resolved = { ...ctx.input };
|
|
44608
|
+
for (const handler of this.eventBus.listeners("beforeAgentSpawn")) {
|
|
44609
|
+
try {
|
|
44610
|
+
const patch = await handler({ ...ctx, input: resolved });
|
|
44611
|
+
if (patch && typeof patch === "object") {
|
|
44612
|
+
resolved = { ...resolved, ...patch };
|
|
44613
|
+
}
|
|
44614
|
+
} catch (err) {
|
|
44615
|
+
console.error("[agent-relay] beforeAgentSpawn listener threw:", err);
|
|
44616
|
+
}
|
|
44617
|
+
}
|
|
44618
|
+
return resolved;
|
|
44619
|
+
}
|
|
44478
44620
|
/**
|
|
44479
44621
|
* Connect to an already-running broker by reading its connection file.
|
|
44480
44622
|
*
|
|
@@ -44504,7 +44646,11 @@ var AgentRelayClient = class _AgentRelayClient {
|
|
|
44504
44646
|
if (!isProcessRunning(conn.pid)) {
|
|
44505
44647
|
throw new Error(`Stale broker connection file (${connPath}) points to dead pid ${conn.pid}. Start the broker with 'agent-relay up' or use AgentRelayClient.spawn().`);
|
|
44506
44648
|
}
|
|
44507
|
-
return new _AgentRelayClient({
|
|
44649
|
+
return new _AgentRelayClient({
|
|
44650
|
+
baseUrl: conn.url,
|
|
44651
|
+
apiKey: conn.api_key,
|
|
44652
|
+
...options?.eventBus ? { eventBus: options.eventBus } : {}
|
|
44653
|
+
});
|
|
44508
44654
|
}
|
|
44509
44655
|
/**
|
|
44510
44656
|
* Spawn a local broker process and return a connected client.
|
|
@@ -44564,7 +44710,8 @@ var AgentRelayClient = class _AgentRelayClient {
|
|
|
44564
44710
|
const client = new _AgentRelayClient({
|
|
44565
44711
|
baseUrl,
|
|
44566
44712
|
apiKey,
|
|
44567
|
-
requestTimeoutMs: options?.requestTimeoutMs
|
|
44713
|
+
requestTimeoutMs: options?.requestTimeoutMs,
|
|
44714
|
+
...options?.eventBus ? { eventBus: options.eventBus } : {}
|
|
44568
44715
|
});
|
|
44569
44716
|
client.child = child;
|
|
44570
44717
|
const brokerExited = new Promise((_2, reject) => {
|
|
@@ -44632,53 +44779,52 @@ var AgentRelayClient = class _AgentRelayClient {
|
|
|
44632
44779
|
}
|
|
44633
44780
|
// ── Agent lifecycle ────────────────────────────────────────────────
|
|
44634
44781
|
async spawnPty(input) {
|
|
44635
|
-
|
|
44636
|
-
|
|
44637
|
-
|
|
44638
|
-
|
|
44639
|
-
|
|
44640
|
-
|
|
44641
|
-
|
|
44642
|
-
|
|
44643
|
-
|
|
44644
|
-
|
|
44645
|
-
|
|
44646
|
-
|
|
44647
|
-
|
|
44648
|
-
|
|
44649
|
-
|
|
44650
|
-
|
|
44651
|
-
|
|
44652
|
-
|
|
44653
|
-
|
|
44654
|
-
}
|
|
44782
|
+
const beforeCtx = {
|
|
44783
|
+
kind: "pty",
|
|
44784
|
+
input,
|
|
44785
|
+
spawnerPid: process.pid,
|
|
44786
|
+
spawnStartTs: (/* @__PURE__ */ new Date()).toISOString(),
|
|
44787
|
+
baseUrl: this.baseUrl
|
|
44788
|
+
};
|
|
44789
|
+
const t0 = Date.now();
|
|
44790
|
+
const resolvedInput = await this.runBeforeSpawn(beforeCtx);
|
|
44791
|
+
try {
|
|
44792
|
+
const result = await this.transport.request("/api/spawn", {
|
|
44793
|
+
method: "POST",
|
|
44794
|
+
body: JSON.stringify(buildSpawnPtyBody(resolvedInput))
|
|
44795
|
+
});
|
|
44796
|
+
await this.emitAfterSpawn(beforeCtx, resolvedInput, t0, result, void 0);
|
|
44797
|
+
return result;
|
|
44798
|
+
} catch (err) {
|
|
44799
|
+
await this.emitAfterSpawn(beforeCtx, resolvedInput, t0, void 0, err);
|
|
44800
|
+
throw err;
|
|
44801
|
+
}
|
|
44655
44802
|
}
|
|
44656
44803
|
async spawnProvider(input) {
|
|
44657
44804
|
const transport = resolveSpawnTransport(input);
|
|
44658
44805
|
if (transport === "headless" && !isHeadlessProvider(input.provider)) {
|
|
44659
44806
|
throw new Error(`provider '${input.provider}' does not support headless transport (supported: claude, opencode)`);
|
|
44660
44807
|
}
|
|
44661
|
-
|
|
44662
|
-
|
|
44663
|
-
|
|
44664
|
-
|
|
44665
|
-
|
|
44666
|
-
|
|
44667
|
-
|
|
44668
|
-
|
|
44669
|
-
|
|
44670
|
-
|
|
44671
|
-
|
|
44672
|
-
|
|
44673
|
-
|
|
44674
|
-
|
|
44675
|
-
|
|
44676
|
-
|
|
44677
|
-
|
|
44678
|
-
|
|
44679
|
-
|
|
44680
|
-
|
|
44681
|
-
});
|
|
44808
|
+
const beforeCtx = {
|
|
44809
|
+
kind: "provider",
|
|
44810
|
+
input,
|
|
44811
|
+
spawnerPid: process.pid,
|
|
44812
|
+
spawnStartTs: (/* @__PURE__ */ new Date()).toISOString(),
|
|
44813
|
+
baseUrl: this.baseUrl
|
|
44814
|
+
};
|
|
44815
|
+
const t0 = Date.now();
|
|
44816
|
+
const resolvedInput = await this.runBeforeSpawn(beforeCtx);
|
|
44817
|
+
try {
|
|
44818
|
+
const result = await this.transport.request("/api/spawn", {
|
|
44819
|
+
method: "POST",
|
|
44820
|
+
body: JSON.stringify(buildSpawnProviderBody(resolvedInput, transport))
|
|
44821
|
+
});
|
|
44822
|
+
await this.emitAfterSpawn(beforeCtx, resolvedInput, t0, result, void 0);
|
|
44823
|
+
return result;
|
|
44824
|
+
} catch (err) {
|
|
44825
|
+
await this.emitAfterSpawn(beforeCtx, resolvedInput, t0, void 0, err);
|
|
44826
|
+
throw err;
|
|
44827
|
+
}
|
|
44682
44828
|
}
|
|
44683
44829
|
async spawnHeadless(input) {
|
|
44684
44830
|
return this.spawnProvider({ ...input, transport: "headless" });
|
|
@@ -44690,10 +44836,39 @@ var AgentRelayClient = class _AgentRelayClient {
|
|
|
44690
44836
|
return this.spawnProvider({ ...input, provider: "opencode" });
|
|
44691
44837
|
}
|
|
44692
44838
|
async release(name, reason) {
|
|
44693
|
-
|
|
44694
|
-
|
|
44695
|
-
|
|
44696
|
-
|
|
44839
|
+
const beforeCtx = { name, reason, baseUrl: this.baseUrl };
|
|
44840
|
+
const t0 = Date.now();
|
|
44841
|
+
await this.eventBus.emit("beforeAgentRelease", beforeCtx);
|
|
44842
|
+
try {
|
|
44843
|
+
const result = await this.transport.request(`/api/spawned/${encodeURIComponent(name)}`, {
|
|
44844
|
+
method: "DELETE",
|
|
44845
|
+
...reason ? { body: JSON.stringify({ reason }) } : {}
|
|
44846
|
+
});
|
|
44847
|
+
const afterCtx = {
|
|
44848
|
+
...beforeCtx,
|
|
44849
|
+
durationMs: Date.now() - t0
|
|
44850
|
+
};
|
|
44851
|
+
await this.eventBus.emit("afterAgentRelease", afterCtx);
|
|
44852
|
+
return result;
|
|
44853
|
+
} catch (err) {
|
|
44854
|
+
const afterCtx = {
|
|
44855
|
+
...beforeCtx,
|
|
44856
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
44857
|
+
durationMs: Date.now() - t0
|
|
44858
|
+
};
|
|
44859
|
+
await this.eventBus.emit("afterAgentRelease", afterCtx);
|
|
44860
|
+
throw err;
|
|
44861
|
+
}
|
|
44862
|
+
}
|
|
44863
|
+
async emitAfterSpawn(beforeCtx, resolvedInput, startMs, result, error51) {
|
|
44864
|
+
const afterCtx = {
|
|
44865
|
+
...beforeCtx,
|
|
44866
|
+
resolvedInput,
|
|
44867
|
+
...result ? { result } : {},
|
|
44868
|
+
...error51 !== void 0 ? { error: error51 instanceof Error ? error51 : new Error(String(error51)) } : {},
|
|
44869
|
+
durationMs: Date.now() - startMs
|
|
44870
|
+
};
|
|
44871
|
+
await this.eventBus.emit("afterAgentSpawn", afterCtx);
|
|
44697
44872
|
}
|
|
44698
44873
|
async listAgents() {
|
|
44699
44874
|
const result = await this.transport.request("/api/spawned");
|
|
@@ -70529,20 +70704,40 @@ function toWorkspaceRegistryEntry(value) {
|
|
|
70529
70704
|
};
|
|
70530
70705
|
}
|
|
70531
70706
|
var AgentRelay = class {
|
|
70532
|
-
|
|
70533
|
-
|
|
70534
|
-
|
|
70535
|
-
|
|
70536
|
-
|
|
70537
|
-
|
|
70538
|
-
|
|
70539
|
-
|
|
70540
|
-
|
|
70541
|
-
|
|
70542
|
-
|
|
70543
|
-
|
|
70544
|
-
|
|
70545
|
-
|
|
70707
|
+
/**
|
|
70708
|
+
* Multi-listener event registry. Subscribe via {@link addListener} or
|
|
70709
|
+
* `bus.addListener` directly; emit happens internally as broker events
|
|
70710
|
+
* arrive and at SDK call sites for the spawn / release lifecycle hooks.
|
|
70711
|
+
*
|
|
70712
|
+
* The bus is shared with the underlying `AgentRelayClient` (created via
|
|
70713
|
+
* {@link ensureStarted}) so listeners registered on either object see
|
|
70714
|
+
* the same events.
|
|
70715
|
+
*/
|
|
70716
|
+
bus = new EventBus();
|
|
70717
|
+
// ── Listener registration ───────────────────────────────────────────────
|
|
70718
|
+
/**
|
|
70719
|
+
* Register a listener for a relay lifecycle event. Returns an
|
|
70720
|
+
* unsubscribe function.
|
|
70721
|
+
*
|
|
70722
|
+
* Example:
|
|
70723
|
+
* ```ts
|
|
70724
|
+
* const off = relay.addListener('agentSpawned', (agent) => console.log(agent.name));
|
|
70725
|
+
* // later:
|
|
70726
|
+
* off();
|
|
70727
|
+
* ```
|
|
70728
|
+
*
|
|
70729
|
+
* Replaces the pre-2.x single-callback `on*` fields. Multiple listeners
|
|
70730
|
+
* can register for the same event; they fire sequentially in
|
|
70731
|
+
* registration order. Async handlers are awaited. Handler exceptions
|
|
70732
|
+
* are caught and logged; one bad listener never blocks the others.
|
|
70733
|
+
*/
|
|
70734
|
+
addListener(event, handler) {
|
|
70735
|
+
return this.bus.addListener(event, handler);
|
|
70736
|
+
}
|
|
70737
|
+
/** Remove a previously-registered listener. Idempotent. */
|
|
70738
|
+
removeListener(event, handler) {
|
|
70739
|
+
this.bus.removeListener(event, handler);
|
|
70740
|
+
}
|
|
70546
70741
|
// ── Public accessors ────────────────────────────────────────────────────
|
|
70547
70742
|
/** The resolved Relaycast workspace API key (available after first spawn). */
|
|
70548
70743
|
get workspaceKey() {
|
|
@@ -70893,7 +71088,7 @@ var AgentRelay = class {
|
|
|
70893
71088
|
data: input.data,
|
|
70894
71089
|
mode: input.mode
|
|
70895
71090
|
};
|
|
70896
|
-
this.
|
|
71091
|
+
void this.bus.emit("messageSent", msg);
|
|
70897
71092
|
return msg;
|
|
70898
71093
|
}
|
|
70899
71094
|
};
|
|
@@ -71268,7 +71463,7 @@ var AgentRelay = class {
|
|
|
71268
71463
|
return;
|
|
71269
71464
|
}
|
|
71270
71465
|
state.active = active;
|
|
71271
|
-
this.
|
|
71466
|
+
void this.bus.emit("agentActivityChanged", {
|
|
71272
71467
|
name,
|
|
71273
71468
|
active,
|
|
71274
71469
|
pendingDeliveries: state.pendingDeliveries.size,
|
|
@@ -71385,6 +71580,7 @@ var AgentRelay = class {
|
|
|
71385
71580
|
return this.startPromise;
|
|
71386
71581
|
this.startPromise = this.ensureRelaycastApiKey().then(() => AgentRelayClient.spawn({
|
|
71387
71582
|
...this.clientOptions,
|
|
71583
|
+
eventBus: this.bus,
|
|
71388
71584
|
onStderr: (line) => {
|
|
71389
71585
|
for (const listener of this.stderrListeners) {
|
|
71390
71586
|
try {
|
|
@@ -71434,7 +71630,7 @@ var AgentRelay = class {
|
|
|
71434
71630
|
threadId: event.thread_id,
|
|
71435
71631
|
mode: event.injection_mode ?? event.mode
|
|
71436
71632
|
};
|
|
71437
|
-
this.
|
|
71633
|
+
void this.bus.emit("messageReceived", msg);
|
|
71438
71634
|
break;
|
|
71439
71635
|
}
|
|
71440
71636
|
case "agent_spawned": {
|
|
@@ -71443,7 +71639,7 @@ var AgentRelay = class {
|
|
|
71443
71639
|
this.messageReadyAgents.delete(event.name);
|
|
71444
71640
|
this.exitedAgents.delete(event.name);
|
|
71445
71641
|
this.idleAgents.delete(event.name);
|
|
71446
|
-
this.
|
|
71642
|
+
void this.bus.emit("agentSpawned", agent);
|
|
71447
71643
|
break;
|
|
71448
71644
|
}
|
|
71449
71645
|
case "agent_released": {
|
|
@@ -71453,7 +71649,7 @@ var AgentRelay = class {
|
|
|
71453
71649
|
this.readyAgents.delete(event.name);
|
|
71454
71650
|
this.messageReadyAgents.delete(event.name);
|
|
71455
71651
|
this.idleAgents.delete(event.name);
|
|
71456
|
-
this.
|
|
71652
|
+
void this.bus.emit("agentReleased", agent);
|
|
71457
71653
|
this.knownAgents.delete(event.name);
|
|
71458
71654
|
this.outputListeners.delete(event.name);
|
|
71459
71655
|
this.exitResolvers.get(event.name)?.resolve("released");
|
|
@@ -71474,7 +71670,7 @@ var AgentRelay = class {
|
|
|
71474
71670
|
if (event.reason !== void 0) {
|
|
71475
71671
|
agent.exitReason = event.reason;
|
|
71476
71672
|
}
|
|
71477
|
-
this.
|
|
71673
|
+
void this.bus.emit("agentExited", agent);
|
|
71478
71674
|
this.knownAgents.delete(event.name);
|
|
71479
71675
|
this.outputListeners.delete(event.name);
|
|
71480
71676
|
this.exitResolvers.get(event.name)?.resolve("exited");
|
|
@@ -71486,7 +71682,7 @@ var AgentRelay = class {
|
|
|
71486
71682
|
case "agent_exit": {
|
|
71487
71683
|
const agent = this.knownAgents.get(event.name) ?? this.ensureAgentHandle(event.name, "pty", []);
|
|
71488
71684
|
agent.exitReason = event.reason;
|
|
71489
|
-
this.
|
|
71685
|
+
void this.bus.emit("agentExitRequested", { name: event.name, reason: event.reason });
|
|
71490
71686
|
break;
|
|
71491
71687
|
}
|
|
71492
71688
|
case "worker_ready": {
|
|
@@ -71494,17 +71690,17 @@ var AgentRelay = class {
|
|
|
71494
71690
|
this.readyAgents.add(event.name);
|
|
71495
71691
|
this.exitedAgents.delete(event.name);
|
|
71496
71692
|
this.idleAgents.delete(event.name);
|
|
71497
|
-
this.
|
|
71693
|
+
void this.bus.emit("agentReady", agent);
|
|
71498
71694
|
break;
|
|
71499
71695
|
}
|
|
71500
71696
|
case "channel_subscribed": {
|
|
71501
71697
|
this.addAgentChannels(event.name, event.channels);
|
|
71502
|
-
this.
|
|
71698
|
+
void this.bus.emit("channelSubscribed", { agent: event.name, channels: event.channels });
|
|
71503
71699
|
break;
|
|
71504
71700
|
}
|
|
71505
71701
|
case "channel_unsubscribed": {
|
|
71506
71702
|
this.removeAgentChannels(event.name, event.channels);
|
|
71507
|
-
this.
|
|
71703
|
+
void this.bus.emit("channelUnsubscribed", { agent: event.name, channels: event.channels });
|
|
71508
71704
|
break;
|
|
71509
71705
|
}
|
|
71510
71706
|
case "delivery_queued": {
|
|
@@ -71550,7 +71746,7 @@ var AgentRelay = class {
|
|
|
71550
71746
|
}
|
|
71551
71747
|
case "worker_stream": {
|
|
71552
71748
|
this.idleAgents.delete(event.name);
|
|
71553
|
-
this.
|
|
71749
|
+
void this.bus.emit("workerOutput", {
|
|
71554
71750
|
name: event.name,
|
|
71555
71751
|
stream: event.stream,
|
|
71556
71752
|
chunk: event.chunk
|
|
@@ -71561,7 +71757,7 @@ var AgentRelay = class {
|
|
|
71561
71757
|
case "agent_idle": {
|
|
71562
71758
|
this.clearAgentDeliveries(event.name, "agent_idle");
|
|
71563
71759
|
this.idleAgents.add(event.name);
|
|
71564
|
-
this.
|
|
71760
|
+
void this.bus.emit("agentIdle", {
|
|
71565
71761
|
name: event.name,
|
|
71566
71762
|
idleSecs: event.idle_secs
|
|
71567
71763
|
});
|
|
@@ -71571,7 +71767,7 @@ var AgentRelay = class {
|
|
|
71571
71767
|
}
|
|
71572
71768
|
}
|
|
71573
71769
|
if (event.kind.startsWith("delivery_") || event.kind.startsWith("message_delivery_")) {
|
|
71574
|
-
this.
|
|
71770
|
+
void this.bus.emit("deliveryUpdate", event);
|
|
71575
71771
|
}
|
|
71576
71772
|
});
|
|
71577
71773
|
}
|
|
@@ -71730,7 +71926,7 @@ var AgentRelay = class {
|
|
|
71730
71926
|
data: input.data,
|
|
71731
71927
|
mode: input.mode
|
|
71732
71928
|
};
|
|
71733
|
-
relay.
|
|
71929
|
+
void relay.bus.emit("messageSent", msg);
|
|
71734
71930
|
return msg;
|
|
71735
71931
|
},
|
|
71736
71932
|
async subscribe(channelsToAdd) {
|
|
@@ -72394,7 +72590,7 @@ var ShadowManager = class {
|
|
|
72394
72590
|
* Determine which shadows should receive a copy of a message
|
|
72395
72591
|
* between `from` and `to`. Returns a list of shadow copies to deliver.
|
|
72396
72592
|
*
|
|
72397
|
-
* Call this from your `
|
|
72593
|
+
* Call this from your `messageReceived` / `messageSent` listeners
|
|
72398
72594
|
* to fan out shadow copies.
|
|
72399
72595
|
*/
|
|
72400
72596
|
intercept(from, to2) {
|
|
@@ -72882,15 +73078,15 @@ async function spawnFromEnv(options = {}) {
|
|
|
72882
73078
|
cwd: policy.cwd ?? process.cwd(),
|
|
72883
73079
|
env
|
|
72884
73080
|
});
|
|
72885
|
-
relay.
|
|
73081
|
+
relay.addListener("agentSpawned", (agent) => {
|
|
72886
73082
|
console.log(`[spawn-from-env] Agent spawned: ${agent.name}`);
|
|
72887
|
-
};
|
|
72888
|
-
relay.
|
|
73083
|
+
});
|
|
73084
|
+
relay.addListener("agentReady", (agent) => {
|
|
72889
73085
|
console.log(`[spawn-from-env] Agent ready: ${agent.name}`);
|
|
72890
|
-
};
|
|
72891
|
-
relay.
|
|
73086
|
+
});
|
|
73087
|
+
relay.addListener("agentExited", (agent) => {
|
|
72892
73088
|
console.log(`[spawn-from-env] Agent exited: ${agent.name} code=${agent.exitCode ?? "none"} signal=${agent.exitSignal ?? "none"}`);
|
|
72893
|
-
};
|
|
73089
|
+
});
|
|
72894
73090
|
try {
|
|
72895
73091
|
const agent = await relay.spawnPty({
|
|
72896
73092
|
name: policy.name,
|
|
@@ -82414,6 +82610,7 @@ var WorkflowRunner = class _WorkflowRunner {
|
|
|
82414
82610
|
runStartTime;
|
|
82415
82611
|
/** Unsubscribe handle for broker stderr listener wired during a run. */
|
|
82416
82612
|
unsubBrokerStderr;
|
|
82613
|
+
unsubRelayListeners = [];
|
|
82417
82614
|
/** Tracks last idle log time per agent to debounce idle warnings (30s multiples). */
|
|
82418
82615
|
lastIdleLog = /* @__PURE__ */ new Map();
|
|
82419
82616
|
/** Tracks last logged activity type per agent to avoid duplicate status lines. */
|
|
@@ -84405,7 +84602,7 @@ ${err.suggestion}`);
|
|
|
84405
84602
|
// long-running PTY processes from earlier steps. 120s gives room to breathe.
|
|
84406
84603
|
requestTimeoutMs: this.relayOptions.requestTimeoutMs ?? 12e4
|
|
84407
84604
|
});
|
|
84408
|
-
this.relay.
|
|
84605
|
+
this.unsubRelayListeners.push(this.relay.addListener("workerOutput", ({ name, chunk }) => {
|
|
84409
84606
|
const listener = this.ptyListeners.get(name);
|
|
84410
84607
|
if (listener)
|
|
84411
84608
|
listener(chunk);
|
|
@@ -84444,8 +84641,8 @@ ${err.suggestion}`);
|
|
|
84444
84641
|
this.lastActivity.set(name, activity);
|
|
84445
84642
|
this.log(`[${shortName}] ${activity}`);
|
|
84446
84643
|
}
|
|
84447
|
-
};
|
|
84448
|
-
this.relay.
|
|
84644
|
+
}));
|
|
84645
|
+
this.unsubRelayListeners.push(this.relay.addListener("messageReceived", (msg) => {
|
|
84449
84646
|
this.emit({
|
|
84450
84647
|
type: "broker:event",
|
|
84451
84648
|
runId,
|
|
@@ -84482,8 +84679,8 @@ ${err.suggestion}`);
|
|
|
84482
84679
|
});
|
|
84483
84680
|
void this.trajectory?.ownerMonitoringEvent(supervision.stepName, supervision.logicalName, `Messaged ${msg.to}: ${msg.text.slice(0, 120)}`, { to: msg.to, text: msg.text });
|
|
84484
84681
|
}
|
|
84485
|
-
};
|
|
84486
|
-
this.relay.
|
|
84682
|
+
}));
|
|
84683
|
+
this.unsubRelayListeners.push(this.relay.addListener("agentSpawned", (agent) => {
|
|
84487
84684
|
this.emit({
|
|
84488
84685
|
type: "broker:event",
|
|
84489
84686
|
runId,
|
|
@@ -84496,8 +84693,8 @@ ${err.suggestion}`);
|
|
|
84496
84693
|
if (!this.activeAgentHandles.has(agent.name)) {
|
|
84497
84694
|
this.log(`[spawned] ${agent.name} (${agent.runtime})`);
|
|
84498
84695
|
}
|
|
84499
|
-
};
|
|
84500
|
-
this.relay.
|
|
84696
|
+
}));
|
|
84697
|
+
this.unsubRelayListeners.push(this.relay.addListener("agentReleased", (agent) => {
|
|
84501
84698
|
this.emit({
|
|
84502
84699
|
type: "broker:event",
|
|
84503
84700
|
runId,
|
|
@@ -84506,8 +84703,8 @@ ${err.suggestion}`);
|
|
|
84506
84703
|
name: agent.name
|
|
84507
84704
|
}
|
|
84508
84705
|
});
|
|
84509
|
-
};
|
|
84510
|
-
this.relay.
|
|
84706
|
+
}));
|
|
84707
|
+
this.unsubRelayListeners.push(this.relay.addListener("agentExited", (agent) => {
|
|
84511
84708
|
this.emit({
|
|
84512
84709
|
type: "broker:event",
|
|
84513
84710
|
runId,
|
|
@@ -84523,11 +84720,11 @@ ${err.suggestion}`);
|
|
|
84523
84720
|
if (!this.activeAgentHandles.has(agent.name)) {
|
|
84524
84721
|
this.log(`[exited] ${agent.name} (code: ${agent.exitCode ?? "?"})`);
|
|
84525
84722
|
}
|
|
84526
|
-
};
|
|
84527
|
-
this.relay.
|
|
84723
|
+
}));
|
|
84724
|
+
this.unsubRelayListeners.push(this.relay.addListener("deliveryUpdate", (event) => {
|
|
84528
84725
|
this.emit({ type: "broker:event", runId, event });
|
|
84529
|
-
};
|
|
84530
|
-
this.relay.
|
|
84726
|
+
}));
|
|
84727
|
+
this.unsubRelayListeners.push(this.relay.addListener("agentIdle", ({ name, idleSecs }) => {
|
|
84531
84728
|
this.emit({
|
|
84532
84729
|
type: "broker:event",
|
|
84533
84730
|
runId,
|
|
@@ -84543,7 +84740,7 @@ ${err.suggestion}`);
|
|
|
84543
84740
|
const shortName = name.replace(/-[a-f0-9]{6,}$/, "");
|
|
84544
84741
|
this.log(`[idle] ${shortName} silent for ${bucket}s`);
|
|
84545
84742
|
}
|
|
84546
|
-
};
|
|
84743
|
+
}));
|
|
84547
84744
|
this.relaycast = void 0;
|
|
84548
84745
|
this.relaycastAgent = void 0;
|
|
84549
84746
|
this.unsubBrokerStderr = this.relay.onBrokerStderr((line) => {
|
|
@@ -84654,15 +84851,13 @@ ${err.suggestion}`);
|
|
|
84654
84851
|
this.ptyListeners.clear();
|
|
84655
84852
|
this.unsubBrokerStderr?.();
|
|
84656
84853
|
this.unsubBrokerStderr = void 0;
|
|
84657
|
-
|
|
84658
|
-
|
|
84659
|
-
|
|
84660
|
-
|
|
84661
|
-
|
|
84662
|
-
this.relay.onAgentIdle = null;
|
|
84663
|
-
this.relay.onWorkerOutput = null;
|
|
84664
|
-
this.relay.onDeliveryUpdate = null;
|
|
84854
|
+
for (const off of this.unsubRelayListeners) {
|
|
84855
|
+
try {
|
|
84856
|
+
off();
|
|
84857
|
+
} catch {
|
|
84858
|
+
}
|
|
84665
84859
|
}
|
|
84860
|
+
this.unsubRelayListeners = [];
|
|
84666
84861
|
this.lastIdleLog.clear();
|
|
84667
84862
|
this.lastActivity.clear();
|
|
84668
84863
|
this.supervisedRuntimeAgents.clear();
|
|
@@ -94695,6 +94890,7 @@ init_dist2();
|
|
|
94695
94890
|
DEFAULT_PROXY_ENV_REGISTRY,
|
|
94696
94891
|
DefaultModels,
|
|
94697
94892
|
ERROR_SEARCH_HINT,
|
|
94893
|
+
EventBus,
|
|
94698
94894
|
GEMINI_MODEL_OPTIONS,
|
|
94699
94895
|
GeminiModels,
|
|
94700
94896
|
GitHubClient,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-relay",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "Real-time agent-to-agent communication system",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -132,14 +132,14 @@
|
|
|
132
132
|
},
|
|
133
133
|
"homepage": "https://github.com/AgentWorkforce/relay#readme",
|
|
134
134
|
"dependencies": {
|
|
135
|
-
"@agent-relay/cloud": "
|
|
136
|
-
"@agent-relay/config": "
|
|
137
|
-
"@agent-relay/hooks": "
|
|
138
|
-
"@agent-relay/sdk": "
|
|
139
|
-
"@agent-relay/telemetry": "
|
|
140
|
-
"@agent-relay/trajectory": "
|
|
141
|
-
"@agent-relay/user-directory": "
|
|
142
|
-
"@agent-relay/utils": "
|
|
135
|
+
"@agent-relay/cloud": "7.0.0",
|
|
136
|
+
"@agent-relay/config": "7.0.0",
|
|
137
|
+
"@agent-relay/hooks": "7.0.0",
|
|
138
|
+
"@agent-relay/sdk": "7.0.0",
|
|
139
|
+
"@agent-relay/telemetry": "7.0.0",
|
|
140
|
+
"@agent-relay/trajectory": "7.0.0",
|
|
141
|
+
"@agent-relay/user-directory": "7.0.0",
|
|
142
|
+
"@agent-relay/utils": "7.0.0",
|
|
143
143
|
"@aws-sdk/client-s3": "3.1020.0",
|
|
144
144
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
145
145
|
"@relayauth/core": "^0.1.2",
|