agent-relay 3.0.1 → 3.1.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/README.md +37 -244
- package/bin/agent-relay-broker-darwin-arm64 +0 -0
- package/bin/agent-relay-broker-darwin-x64 +0 -0
- package/bin/agent-relay-broker-linux-arm64 +0 -0
- package/bin/agent-relay-broker-linux-x64 +0 -0
- package/dist/index.cjs +342 -60
- package/dist/src/cli/commands/core.d.ts +2 -0
- package/dist/src/cli/commands/core.d.ts.map +1 -1
- package/dist/src/cli/commands/core.js +9 -2
- package/dist/src/cli/commands/core.js.map +1 -1
- package/dist/src/cli/lib/broker-lifecycle.d.ts.map +1 -1
- package/dist/src/cli/lib/broker-lifecycle.js +87 -28
- package/dist/src/cli/lib/broker-lifecycle.js.map +1 -1
- package/package.json +9 -8
- package/packages/acp-bridge/README.md +50 -67
- package/packages/acp-bridge/package.json +2 -2
- package/packages/config/package.json +1 -1
- package/packages/hooks/package.json +4 -4
- package/packages/memory/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/sdk/README.md +169 -64
- package/packages/sdk/dist/__tests__/contract-fixtures.test.js +76 -9
- package/packages/sdk/dist/__tests__/contract-fixtures.test.js.map +1 -1
- package/packages/sdk/dist/__tests__/facade.test.js +48 -0
- package/packages/sdk/dist/__tests__/facade.test.js.map +1 -1
- package/packages/sdk/dist/__tests__/integration.test.js +11 -5
- package/packages/sdk/dist/__tests__/integration.test.js.map +1 -1
- package/packages/sdk/dist/__tests__/unit.test.js +36 -0
- package/packages/sdk/dist/__tests__/unit.test.js.map +1 -1
- package/packages/sdk/dist/client.d.ts +36 -3
- package/packages/sdk/dist/client.d.ts.map +1 -1
- package/packages/sdk/dist/client.js +142 -9
- package/packages/sdk/dist/client.js.map +1 -1
- package/packages/sdk/dist/protocol.d.ts +7 -1
- package/packages/sdk/dist/protocol.d.ts.map +1 -1
- package/packages/sdk/dist/relay.d.ts +74 -11
- package/packages/sdk/dist/relay.d.ts.map +1 -1
- package/packages/sdk/dist/relay.js +175 -27
- package/packages/sdk/dist/relay.js.map +1 -1
- package/packages/sdk/dist/workflows/runner.d.ts.map +1 -1
- package/packages/sdk/dist/workflows/runner.js +71 -36
- package/packages/sdk/dist/workflows/runner.js.map +1 -1
- package/packages/sdk/dist/workflows/types.d.ts +1 -1
- package/packages/sdk/dist/workflows/types.d.ts.map +1 -1
- package/packages/sdk/package.json +2 -2
- package/packages/sdk/src/__tests__/contract-fixtures.test.ts +88 -9
- package/packages/sdk/src/__tests__/error-scenarios.test.ts +1 -1
- package/packages/sdk/src/__tests__/facade.test.ts +68 -0
- package/packages/sdk/src/__tests__/idle-nudge.test.ts +205 -257
- package/packages/sdk/src/__tests__/integration.test.ts +11 -5
- package/packages/sdk/src/__tests__/orchestration-upgrades.test.ts +277 -13
- package/packages/sdk/src/__tests__/swarm-coordinator.test.ts +1 -0
- package/packages/sdk/src/__tests__/unit.test.ts +44 -0
- package/packages/sdk/src/__tests__/workflow-runner.test.ts +67 -7
- package/packages/sdk/src/__tests__/workflow-trajectory.test.ts +4 -5
- package/packages/sdk/src/client.ts +195 -14
- package/packages/sdk/src/examples/workflows/runner-idle-refactor.yaml +306 -0
- package/packages/sdk/src/protocol.ts +7 -2
- package/packages/sdk/src/relay.ts +271 -38
- package/packages/sdk/src/workflows/runner.ts +73 -42
- package/packages/sdk/src/workflows/schema.json +1 -1
- package/packages/sdk/src/workflows/types.ts +1 -1
- package/packages/sdk/vitest.config.ts +1 -0
- package/packages/sdk-py/README.md +89 -102
- package/packages/sdk-py/agent_relay/__init__.py +16 -19
- package/packages/sdk-py/pyproject.toml +6 -2
- package/packages/sdk-py/src/agent_relay/__init__.py +35 -1
- package/packages/sdk-py/src/agent_relay/client.py +776 -0
- package/packages/sdk-py/src/agent_relay/models.py +27 -0
- package/packages/sdk-py/src/agent_relay/protocol.py +114 -0
- package/packages/sdk-py/src/agent_relay/relay.py +860 -0
- package/packages/sdk-py/tests/test_relay_lifecycle_hooks.py +250 -0
- package/packages/telemetry/package.json +1 -1
- package/packages/trajectory/package.json +2 -2
- package/packages/user-directory/package.json +2 -2
- package/packages/utils/package.json +2 -2
- package/scripts/postinstall.js +35 -162
- package/packages/sdk/.trajectories/active/traj_1771875803391_84ca57b2.json +0 -50
- package/packages/sdk/.trajectories/active/traj_1771891934534_06504121.json +0 -50
- package/packages/sdk/.trajectories/active/traj_1771891957929_211afc4e.json +0 -50
- package/packages/sdk/.trajectories/active/traj_1771891982509_38c84638.json +0 -50
- package/packages/sdk/.trajectories/completed/traj_1771875803188_cd6d181c.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771875803204_f2aeb8c8.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771875803210_d65f3f1a.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771875803218_e454a25d.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771875803223_d7a64815.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771875803227_7e56da5b.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771875803235_4fbf93b4.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771875803243_47931c71.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771875803258_3816f3fe.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771875803268_8061140e.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771875803326_ae6f9c78.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771875808396_cbde0a6c.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771875812026_aa2442bb.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771875815431_c2c656c5.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771875818645_3a4dbf02.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771891934403_24923c03.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891934421_dca16e24.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891934430_057706f7.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891934442_faf97382.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891934454_5542ecd5.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891934464_12202a08.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891934487_94378275.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891934503_ca728c13.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891934519_100af69a.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891934536_62ad39d9.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891934553_d6798a52.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891939537_541c8096.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771891942985_36ab9a4d.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771891946453_e8a6e05f.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771891949838_5de0de84.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771891957807_0ecfb4f4.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891957827_c4539239.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891957836_91168b48.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891957848_8c5cad0b.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891957857_0986b293.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891957872_8a3113af.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891957884_0bb85208.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891957892_86c75e2e.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891957907_98ca0e6f.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891957918_d9091231.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891957931_dcaf77ed.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891962931_eb1fdee2.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771891966262_9061a93f.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771891969915_1adaba19.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771891973588_f08b79e9.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771891982421_f1985bce.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891982432_e7a84163.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891982447_369b842a.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891982469_5fc45199.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891982495_454c7cb3.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891982514_08098e03.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891982526_b351d778.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891982533_fa542d83.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891982540_18ab24dc.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891982544_5b4fa163.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891982548_c13f089a.json +0 -80
- package/packages/sdk/.trajectories/completed/traj_1771891987510_23f6da1f.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771891991466_912c2e04.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771891994891_60604be2.json +0 -91
- package/packages/sdk/.trajectories/completed/traj_1771891998370_cfaf9b8b.json +0 -91
- package/packages/sdk/bin/agent-relay-broker +0 -0
package/dist/index.cjs
CHANGED
|
@@ -8975,6 +8975,9 @@ var AgentRelayProcessError = class extends Error {
|
|
|
8975
8975
|
this.name = "AgentRelayProcessError";
|
|
8976
8976
|
}
|
|
8977
8977
|
};
|
|
8978
|
+
function isHeadlessProvider(value) {
|
|
8979
|
+
return value === "claude" || value === "opencode";
|
|
8980
|
+
}
|
|
8978
8981
|
var AgentRelayClient = class _AgentRelayClient {
|
|
8979
8982
|
options;
|
|
8980
8983
|
child;
|
|
@@ -8989,6 +8992,8 @@ var AgentRelayClient = class _AgentRelayClient {
|
|
|
8989
8992
|
eventBuffer = [];
|
|
8990
8993
|
maxBufferSize = 1e3;
|
|
8991
8994
|
exitPromise;
|
|
8995
|
+
/** The workspace key returned by the broker in its hello_ack response. */
|
|
8996
|
+
workspaceKey;
|
|
8992
8997
|
constructor(options = {}) {
|
|
8993
8998
|
this.options = {
|
|
8994
8999
|
binaryPath: options.binaryPath ?? resolveDefaultBinaryPath(),
|
|
@@ -9098,11 +9103,12 @@ var AgentRelayClient = class _AgentRelayClient {
|
|
|
9098
9103
|
});
|
|
9099
9104
|
return result;
|
|
9100
9105
|
}
|
|
9101
|
-
async
|
|
9106
|
+
async spawnHeadless(input) {
|
|
9102
9107
|
await this.start();
|
|
9103
9108
|
const agent = {
|
|
9104
9109
|
name: input.name,
|
|
9105
|
-
runtime: "
|
|
9110
|
+
runtime: "headless",
|
|
9111
|
+
provider: input.provider,
|
|
9106
9112
|
args: input.args ?? [],
|
|
9107
9113
|
channels: input.channels ?? []
|
|
9108
9114
|
};
|
|
@@ -9112,6 +9118,42 @@ var AgentRelayClient = class _AgentRelayClient {
|
|
|
9112
9118
|
});
|
|
9113
9119
|
return result;
|
|
9114
9120
|
}
|
|
9121
|
+
async spawnProvider(input) {
|
|
9122
|
+
const transport = input.transport ?? (input.provider === "opencode" ? "headless" : "pty");
|
|
9123
|
+
if (transport === "headless") {
|
|
9124
|
+
if (!isHeadlessProvider(input.provider)) {
|
|
9125
|
+
throw new AgentRelayProcessError(`provider '${input.provider}' does not support headless transport (supported: claude, opencode)`);
|
|
9126
|
+
}
|
|
9127
|
+
return this.spawnHeadless({
|
|
9128
|
+
name: input.name,
|
|
9129
|
+
provider: input.provider,
|
|
9130
|
+
args: input.args,
|
|
9131
|
+
channels: input.channels,
|
|
9132
|
+
task: input.task
|
|
9133
|
+
});
|
|
9134
|
+
}
|
|
9135
|
+
return this.spawnPty({
|
|
9136
|
+
name: input.name,
|
|
9137
|
+
cli: input.provider,
|
|
9138
|
+
args: input.args,
|
|
9139
|
+
channels: input.channels,
|
|
9140
|
+
task: input.task,
|
|
9141
|
+
model: input.model,
|
|
9142
|
+
cwd: input.cwd,
|
|
9143
|
+
team: input.team,
|
|
9144
|
+
shadowOf: input.shadowOf,
|
|
9145
|
+
shadowMode: input.shadowMode,
|
|
9146
|
+
idleThresholdSecs: input.idleThresholdSecs,
|
|
9147
|
+
restartPolicy: input.restartPolicy,
|
|
9148
|
+
continueFrom: input.continueFrom
|
|
9149
|
+
});
|
|
9150
|
+
}
|
|
9151
|
+
async spawnClaude(input) {
|
|
9152
|
+
return this.spawnProvider({ ...input, provider: "claude" });
|
|
9153
|
+
}
|
|
9154
|
+
async spawnOpencode(input) {
|
|
9155
|
+
return this.spawnProvider({ ...input, provider: "opencode" });
|
|
9156
|
+
}
|
|
9115
9157
|
async release(name, reason) {
|
|
9116
9158
|
await this.start();
|
|
9117
9159
|
return this.requestOk("release_agent", { name, reason });
|
|
@@ -9250,8 +9292,11 @@ var AgentRelayClient = class _AgentRelayClient {
|
|
|
9250
9292
|
resolve3();
|
|
9251
9293
|
});
|
|
9252
9294
|
});
|
|
9253
|
-
await this.requestHello();
|
|
9295
|
+
const helloAck = await this.requestHello();
|
|
9254
9296
|
console.log("[broker] Broker ready (hello handshake complete)");
|
|
9297
|
+
if (helloAck.workspace_key) {
|
|
9298
|
+
this.workspaceKey = helloAck.workspace_key;
|
|
9299
|
+
}
|
|
9255
9300
|
}
|
|
9256
9301
|
disposeProcessHandles() {
|
|
9257
9302
|
this.stdoutRl?.close();
|
|
@@ -9367,12 +9412,16 @@ var AgentRelayClient = class _AgentRelayClient {
|
|
|
9367
9412
|
}
|
|
9368
9413
|
};
|
|
9369
9414
|
var CLI_MODEL_FLAG_CLIS = /* @__PURE__ */ new Set(["claude", "codex", "gemini", "goose", "aider"]);
|
|
9415
|
+
var CLI_DEFAULT_ARGS = {
|
|
9416
|
+
codex: ["-c", "check_for_update_on_startup=false"]
|
|
9417
|
+
};
|
|
9370
9418
|
function buildPtyArgsWithModel(cli, args, model) {
|
|
9371
|
-
const
|
|
9419
|
+
const cliName = cli.split(":")[0].trim().toLowerCase();
|
|
9420
|
+
const defaultArgs = CLI_DEFAULT_ARGS[cliName] ?? [];
|
|
9421
|
+
const baseArgs = [...defaultArgs, ...args];
|
|
9372
9422
|
if (!model) {
|
|
9373
9423
|
return baseArgs;
|
|
9374
9424
|
}
|
|
9375
|
-
const cliName = cli.split(":")[0].trim().toLowerCase();
|
|
9376
9425
|
if (!CLI_MODEL_FLAG_CLIS.has(cliName)) {
|
|
9377
9426
|
return baseArgs;
|
|
9378
9427
|
}
|
|
@@ -9403,6 +9452,71 @@ function expandTilde(p) {
|
|
|
9403
9452
|
function isExplicitPath(binaryPath) {
|
|
9404
9453
|
return binaryPath.includes("/") || binaryPath.includes("\\") || binaryPath.startsWith(".") || binaryPath.startsWith("~");
|
|
9405
9454
|
}
|
|
9455
|
+
function detectPlatformSuffix() {
|
|
9456
|
+
const platformMap = {
|
|
9457
|
+
darwin: { arm64: "darwin-arm64", x64: "darwin-x64" },
|
|
9458
|
+
linux: { arm64: "linux-arm64", x64: "linux-x64" }
|
|
9459
|
+
};
|
|
9460
|
+
return platformMap[process.platform]?.[process.arch] ?? null;
|
|
9461
|
+
}
|
|
9462
|
+
function getLatestVersionSync() {
|
|
9463
|
+
try {
|
|
9464
|
+
const result = (0, import_node_child_process.execSync)("curl -fsSL https://api.github.com/repos/AgentWorkforce/relay/releases/latest", {
|
|
9465
|
+
timeout: 15e3,
|
|
9466
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
9467
|
+
}).toString();
|
|
9468
|
+
const match = result.match(/"tag_name"\s*:\s*"v?([^"]+)"/);
|
|
9469
|
+
return match?.[1] ?? null;
|
|
9470
|
+
} catch {
|
|
9471
|
+
return null;
|
|
9472
|
+
}
|
|
9473
|
+
}
|
|
9474
|
+
function installBrokerBinary() {
|
|
9475
|
+
const suffix = detectPlatformSuffix();
|
|
9476
|
+
if (!suffix) {
|
|
9477
|
+
throw new AgentRelayProcessError(`Unsupported platform: ${process.platform}-${process.arch}`);
|
|
9478
|
+
}
|
|
9479
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || "";
|
|
9480
|
+
const installDir = import_node_path.default.join(homeDir, ".agent-relay", "bin");
|
|
9481
|
+
const brokerExe = process.platform === "win32" ? "agent-relay-broker.exe" : "agent-relay-broker";
|
|
9482
|
+
const targetPath = import_node_path.default.join(installDir, brokerExe);
|
|
9483
|
+
console.log(`[agent-relay] Broker binary not found, installing for ${suffix}...`);
|
|
9484
|
+
const version3 = getLatestVersionSync();
|
|
9485
|
+
if (!version3) {
|
|
9486
|
+
throw new AgentRelayProcessError("Failed to fetch latest agent-relay version from GitHub.\nInstall manually: curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash");
|
|
9487
|
+
}
|
|
9488
|
+
const binaryName = `agent-relay-broker-${suffix}`;
|
|
9489
|
+
const downloadUrl = `https://github.com/AgentWorkforce/relay/releases/download/v${version3}/${binaryName}`;
|
|
9490
|
+
console.log(`[agent-relay] Downloading v${version3} from ${downloadUrl}`);
|
|
9491
|
+
try {
|
|
9492
|
+
import_node_fs.default.mkdirSync(installDir, { recursive: true });
|
|
9493
|
+
(0, import_node_child_process.execSync)(`curl -fsSL "${downloadUrl}" -o "${targetPath}"`, {
|
|
9494
|
+
timeout: 6e4,
|
|
9495
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
9496
|
+
});
|
|
9497
|
+
import_node_fs.default.chmodSync(targetPath, 493);
|
|
9498
|
+
if (process.platform === "darwin") {
|
|
9499
|
+
try {
|
|
9500
|
+
(0, import_node_child_process.execSync)(`codesign --force --sign - "${targetPath}"`, {
|
|
9501
|
+
timeout: 1e4,
|
|
9502
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
9503
|
+
});
|
|
9504
|
+
} catch {
|
|
9505
|
+
}
|
|
9506
|
+
}
|
|
9507
|
+
(0, import_node_child_process.execSync)(`"${targetPath}" --help`, { timeout: 1e4, stdio: ["pipe", "pipe", "pipe"] });
|
|
9508
|
+
} catch (err) {
|
|
9509
|
+
try {
|
|
9510
|
+
import_node_fs.default.unlinkSync(targetPath);
|
|
9511
|
+
} catch {
|
|
9512
|
+
}
|
|
9513
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
9514
|
+
throw new AgentRelayProcessError(`Failed to install broker binary: ${message}
|
|
9515
|
+
Install manually: curl -fsSL https://raw.githubusercontent.com/AgentWorkforce/relay/main/install.sh | bash`);
|
|
9516
|
+
}
|
|
9517
|
+
console.log(`[agent-relay] Broker installed to ${targetPath}`);
|
|
9518
|
+
return targetPath;
|
|
9519
|
+
}
|
|
9406
9520
|
function resolveDefaultBinaryPath() {
|
|
9407
9521
|
const brokerExe = process.platform === "win32" ? "agent-relay-broker.exe" : "agent-relay-broker";
|
|
9408
9522
|
const moduleDir = import_node_path.default.dirname((0, import_node_url.fileURLToPath)(import_meta_url));
|
|
@@ -9410,7 +9524,15 @@ function resolveDefaultBinaryPath() {
|
|
|
9410
9524
|
if (import_node_fs.default.existsSync(workspaceRelease)) {
|
|
9411
9525
|
return workspaceRelease;
|
|
9412
9526
|
}
|
|
9413
|
-
const
|
|
9527
|
+
const binDir = import_node_path.default.resolve(moduleDir, "..", "bin");
|
|
9528
|
+
const suffix = detectPlatformSuffix();
|
|
9529
|
+
if (suffix) {
|
|
9530
|
+
const platformBinary = import_node_path.default.join(binDir, `agent-relay-broker-${suffix}`);
|
|
9531
|
+
if (import_node_fs.default.existsSync(platformBinary)) {
|
|
9532
|
+
return platformBinary;
|
|
9533
|
+
}
|
|
9534
|
+
}
|
|
9535
|
+
const bundled = import_node_path.default.join(binDir, brokerExe);
|
|
9414
9536
|
if (import_node_fs.default.existsSync(bundled)) {
|
|
9415
9537
|
return bundled;
|
|
9416
9538
|
}
|
|
@@ -9419,7 +9541,7 @@ function resolveDefaultBinaryPath() {
|
|
|
9419
9541
|
if (import_node_fs.default.existsSync(standaloneBroker)) {
|
|
9420
9542
|
return standaloneBroker;
|
|
9421
9543
|
}
|
|
9422
|
-
return
|
|
9544
|
+
return installBrokerBinary();
|
|
9423
9545
|
}
|
|
9424
9546
|
|
|
9425
9547
|
// packages/config/src/relay-config.ts
|
|
@@ -15176,7 +15298,7 @@ var DefaultModels = {
|
|
|
15176
15298
|
};
|
|
15177
15299
|
|
|
15178
15300
|
// node_modules/@relaycast/sdk/dist/version.js
|
|
15179
|
-
var SDK_VERSION = "0.4.
|
|
15301
|
+
var SDK_VERSION = "0.4.2";
|
|
15180
15302
|
|
|
15181
15303
|
// node_modules/@relaycast/types/node_modules/zod/v4/classic/external.js
|
|
15182
15304
|
var external_exports2 = {};
|
|
@@ -45021,12 +45143,26 @@ var AgentRelay = class {
|
|
|
45021
45143
|
onDeliveryUpdate = null;
|
|
45022
45144
|
onAgentExitRequested = null;
|
|
45023
45145
|
onAgentIdle = null;
|
|
45146
|
+
// ── Public accessors ────────────────────────────────────────────────────
|
|
45147
|
+
/** The resolved Relaycast workspace API key (available after first spawn). */
|
|
45148
|
+
get workspaceKey() {
|
|
45149
|
+
return this.relayApiKey;
|
|
45150
|
+
}
|
|
45151
|
+
/** Observer URL for the auto-created workspace (available after first spawn). */
|
|
45152
|
+
get observerUrl() {
|
|
45153
|
+
if (!this.relayApiKey)
|
|
45154
|
+
return void 0;
|
|
45155
|
+
return `https://observer.relaycast.dev/?key=${this.relayApiKey}`;
|
|
45156
|
+
}
|
|
45024
45157
|
// Shorthand spawners
|
|
45025
45158
|
codex;
|
|
45026
45159
|
claude;
|
|
45027
45160
|
gemini;
|
|
45028
45161
|
clientOptions;
|
|
45029
45162
|
defaultChannels;
|
|
45163
|
+
workspaceName;
|
|
45164
|
+
relaycastBaseUrl;
|
|
45165
|
+
relayApiKey;
|
|
45030
45166
|
client;
|
|
45031
45167
|
startPromise;
|
|
45032
45168
|
unsubEvent;
|
|
@@ -45043,6 +45179,8 @@ var AgentRelay = class {
|
|
|
45043
45179
|
idleResolverSeq = 0;
|
|
45044
45180
|
constructor(options = {}) {
|
|
45045
45181
|
this.defaultChannels = options.channels ?? ["general"];
|
|
45182
|
+
this.workspaceName = options.workspaceName;
|
|
45183
|
+
this.relaycastBaseUrl = options.relaycastBaseUrl;
|
|
45046
45184
|
this.clientOptions = {
|
|
45047
45185
|
binaryPath: options.binaryPath,
|
|
45048
45186
|
binaryArgs: options.binaryArgs,
|
|
@@ -45084,26 +45222,44 @@ var AgentRelay = class {
|
|
|
45084
45222
|
console.warn(`[AgentRelay] spawnPty("${input.name}"): no channels specified, defaulting to "general". Set explicit channels for workflow isolation.`);
|
|
45085
45223
|
}
|
|
45086
45224
|
const channels = input.channels ?? ["general"];
|
|
45087
|
-
const
|
|
45225
|
+
const lifecycleContext = {
|
|
45088
45226
|
name: input.name,
|
|
45089
45227
|
cli: input.cli,
|
|
45090
|
-
args: input.args,
|
|
45091
45228
|
channels,
|
|
45092
|
-
task: input.task
|
|
45093
|
-
|
|
45094
|
-
|
|
45095
|
-
|
|
45096
|
-
|
|
45097
|
-
|
|
45098
|
-
|
|
45099
|
-
|
|
45100
|
-
|
|
45101
|
-
|
|
45102
|
-
|
|
45103
|
-
|
|
45104
|
-
|
|
45229
|
+
task: input.task
|
|
45230
|
+
};
|
|
45231
|
+
await this.invokeLifecycleHook(input.onStart, lifecycleContext, `spawnPty("${input.name}") onStart`);
|
|
45232
|
+
let result;
|
|
45233
|
+
try {
|
|
45234
|
+
result = await client.spawnPty({
|
|
45235
|
+
name: input.name,
|
|
45236
|
+
cli: input.cli,
|
|
45237
|
+
args: input.args,
|
|
45238
|
+
channels,
|
|
45239
|
+
task: input.task,
|
|
45240
|
+
model: input.model,
|
|
45241
|
+
cwd: input.cwd,
|
|
45242
|
+
team: input.team,
|
|
45243
|
+
shadowOf: input.shadowOf,
|
|
45244
|
+
shadowMode: input.shadowMode,
|
|
45245
|
+
idleThresholdSecs: input.idleThresholdSecs,
|
|
45246
|
+
restartPolicy: input.restartPolicy
|
|
45247
|
+
});
|
|
45248
|
+
} catch (error95) {
|
|
45249
|
+
await this.invokeLifecycleHook(input.onError, {
|
|
45250
|
+
...lifecycleContext,
|
|
45251
|
+
error: error95
|
|
45252
|
+
}, `spawnPty("${input.name}") onError`);
|
|
45253
|
+
throw error95;
|
|
45254
|
+
}
|
|
45255
|
+
this.resetAgentLifecycleState(result.name);
|
|
45105
45256
|
const agent = this.makeAgent(result.name, result.runtime, channels);
|
|
45106
45257
|
this.knownAgents.set(agent.name, agent);
|
|
45258
|
+
await this.invokeLifecycleHook(input.onSuccess, {
|
|
45259
|
+
...lifecycleContext,
|
|
45260
|
+
name: result.name,
|
|
45261
|
+
runtime: result.runtime
|
|
45262
|
+
}, `spawnPty("${input.name}") onSuccess`);
|
|
45107
45263
|
return agent;
|
|
45108
45264
|
}
|
|
45109
45265
|
async spawn(name, cli, task, options) {
|
|
@@ -45119,7 +45275,10 @@ var AgentRelay = class {
|
|
|
45119
45275
|
shadowOf: options?.shadowOf,
|
|
45120
45276
|
shadowMode: options?.shadowMode,
|
|
45121
45277
|
idleThresholdSecs: options?.idleThresholdSecs,
|
|
45122
|
-
restartPolicy: options?.restartPolicy
|
|
45278
|
+
restartPolicy: options?.restartPolicy,
|
|
45279
|
+
onStart: options?.onStart,
|
|
45280
|
+
onSuccess: options?.onSuccess,
|
|
45281
|
+
onError: options?.onError
|
|
45123
45282
|
});
|
|
45124
45283
|
}
|
|
45125
45284
|
async spawnAndWait(name, cli, task, options) {
|
|
@@ -45128,7 +45287,7 @@ var AgentRelay = class {
|
|
|
45128
45287
|
if (waitForMessage) {
|
|
45129
45288
|
return this.waitForAgentMessage(name, timeoutMs ?? 6e4);
|
|
45130
45289
|
}
|
|
45131
|
-
return this.waitForAgentReady(name, timeoutMs ??
|
|
45290
|
+
return this.waitForAgentReady(name, timeoutMs ?? 6e4);
|
|
45132
45291
|
}
|
|
45133
45292
|
// ── Human source ────────────────────────────────────────────────────────
|
|
45134
45293
|
human(opts) {
|
|
@@ -45318,7 +45477,7 @@ var AgentRelay = class {
|
|
|
45318
45477
|
* The agent's CLI may not yet be ready to receive messages.
|
|
45319
45478
|
* Use `waitForAgentMessage()` for full readiness.
|
|
45320
45479
|
*/
|
|
45321
|
-
async waitForAgentReady(name, timeoutMs =
|
|
45480
|
+
async waitForAgentReady(name, timeoutMs = 6e4) {
|
|
45322
45481
|
const client = await this.ensureStarted();
|
|
45323
45482
|
const existing = this.knownAgents.get(name);
|
|
45324
45483
|
if (existing && this.readyAgents.has(name)) {
|
|
@@ -45492,14 +45651,42 @@ var AgentRelay = class {
|
|
|
45492
45651
|
}
|
|
45493
45652
|
}
|
|
45494
45653
|
}
|
|
45654
|
+
/**
|
|
45655
|
+
* Ensure a Relaycast workspace API key is available.
|
|
45656
|
+
* Resolution order:
|
|
45657
|
+
* 1. Already resolved (cached from a previous call)
|
|
45658
|
+
* 2. RELAY_API_KEY in options.env
|
|
45659
|
+
* 3. RELAY_API_KEY in process.env
|
|
45660
|
+
* 4. Auto-create a fresh workspace via the Relaycast REST API
|
|
45661
|
+
*/
|
|
45662
|
+
async ensureRelaycastApiKey() {
|
|
45663
|
+
if (this.relayApiKey)
|
|
45664
|
+
return;
|
|
45665
|
+
const envKey = this.clientOptions.env?.RELAY_API_KEY ?? process.env.RELAY_API_KEY;
|
|
45666
|
+
if (envKey) {
|
|
45667
|
+
this.relayApiKey = envKey;
|
|
45668
|
+
if (!this.clientOptions.env) {
|
|
45669
|
+
this.clientOptions.env = { ...process.env, RELAY_API_KEY: envKey };
|
|
45670
|
+
} else if (!this.clientOptions.env.RELAY_API_KEY) {
|
|
45671
|
+
this.clientOptions.env.RELAY_API_KEY = envKey;
|
|
45672
|
+
}
|
|
45673
|
+
return;
|
|
45674
|
+
}
|
|
45675
|
+
if (!this.clientOptions.env) {
|
|
45676
|
+
this.clientOptions.env = { ...process.env };
|
|
45677
|
+
}
|
|
45678
|
+
}
|
|
45495
45679
|
async ensureStarted() {
|
|
45496
45680
|
if (this.client)
|
|
45497
45681
|
return this.client;
|
|
45498
45682
|
if (this.startPromise)
|
|
45499
45683
|
return this.startPromise;
|
|
45500
|
-
this.startPromise = AgentRelayClient.start(this.clientOptions).then((c) => {
|
|
45684
|
+
this.startPromise = this.ensureRelaycastApiKey().then(() => AgentRelayClient.start(this.clientOptions)).then((c) => {
|
|
45501
45685
|
this.client = c;
|
|
45502
45686
|
this.startPromise = void 0;
|
|
45687
|
+
if (c.workspaceKey) {
|
|
45688
|
+
this.relayApiKey = c.workspaceKey;
|
|
45689
|
+
}
|
|
45503
45690
|
this.wireEvents(c);
|
|
45504
45691
|
return c;
|
|
45505
45692
|
}).catch((err) => {
|
|
@@ -45644,11 +45831,26 @@ var AgentRelay = class {
|
|
|
45644
45831
|
},
|
|
45645
45832
|
exitCode: void 0,
|
|
45646
45833
|
exitSignal: void 0,
|
|
45647
|
-
async release(
|
|
45834
|
+
async release(reasonOrOptions) {
|
|
45835
|
+
const releaseOptions = relay.normalizeReleaseOptions(reasonOrOptions);
|
|
45836
|
+
const releaseContext = {
|
|
45837
|
+
name,
|
|
45838
|
+
reason: releaseOptions.reason
|
|
45839
|
+
};
|
|
45648
45840
|
const client = await relay.ensureStarted();
|
|
45649
|
-
await
|
|
45841
|
+
await relay.invokeLifecycleHook(releaseOptions.onStart, releaseContext, `release("${name}") onStart`);
|
|
45842
|
+
try {
|
|
45843
|
+
await client.release(name, releaseOptions.reason);
|
|
45844
|
+
await relay.invokeLifecycleHook(releaseOptions.onSuccess, releaseContext, `release("${name}") onSuccess`);
|
|
45845
|
+
} catch (error95) {
|
|
45846
|
+
await relay.invokeLifecycleHook(releaseOptions.onError, {
|
|
45847
|
+
...releaseContext,
|
|
45848
|
+
error: error95
|
|
45849
|
+
}, `release("${name}") onError`);
|
|
45850
|
+
throw error95;
|
|
45851
|
+
}
|
|
45650
45852
|
},
|
|
45651
|
-
async waitForReady(timeoutMs =
|
|
45853
|
+
async waitForReady(timeoutMs = 6e4) {
|
|
45652
45854
|
await relay.waitForAgentReady(name, timeoutMs);
|
|
45653
45855
|
},
|
|
45654
45856
|
waitForExit(timeoutMs) {
|
|
@@ -45769,31 +45971,83 @@ var AgentRelay = class {
|
|
|
45769
45971
|
createSpawner(cli, defaultName, runtime) {
|
|
45770
45972
|
return {
|
|
45771
45973
|
spawn: async (options) => {
|
|
45772
|
-
const client = await this.ensureStarted();
|
|
45773
45974
|
const name = options?.name ?? defaultName;
|
|
45774
45975
|
const channels = options?.channels ?? ["general"];
|
|
45775
45976
|
const args = options?.args ?? [];
|
|
45776
45977
|
const task = options?.task;
|
|
45777
|
-
|
|
45778
|
-
|
|
45779
|
-
result = await client.spawnHeadlessClaude({ name, args, channels, task });
|
|
45780
|
-
} else {
|
|
45781
|
-
result = await client.spawnPty({
|
|
45978
|
+
if (runtime === "pty") {
|
|
45979
|
+
return this.spawnPty({
|
|
45782
45980
|
name,
|
|
45783
45981
|
cli,
|
|
45784
45982
|
args,
|
|
45785
45983
|
channels,
|
|
45786
45984
|
task,
|
|
45787
45985
|
model: options?.model,
|
|
45788
|
-
cwd: options?.cwd
|
|
45986
|
+
cwd: options?.cwd,
|
|
45987
|
+
onStart: options?.onStart,
|
|
45988
|
+
onSuccess: options?.onSuccess,
|
|
45989
|
+
onError: options?.onError
|
|
45789
45990
|
});
|
|
45790
45991
|
}
|
|
45992
|
+
const client = await this.ensureStarted();
|
|
45993
|
+
const lifecycleContext = {
|
|
45994
|
+
name,
|
|
45995
|
+
cli,
|
|
45996
|
+
channels,
|
|
45997
|
+
task
|
|
45998
|
+
};
|
|
45999
|
+
await this.invokeLifecycleHook(options?.onStart, lifecycleContext, `spawn("${name}") onStart`);
|
|
46000
|
+
let result;
|
|
46001
|
+
try {
|
|
46002
|
+
result = await client.spawnProvider({
|
|
46003
|
+
name,
|
|
46004
|
+
provider: cli,
|
|
46005
|
+
transport: "headless",
|
|
46006
|
+
args,
|
|
46007
|
+
channels,
|
|
46008
|
+
task
|
|
46009
|
+
});
|
|
46010
|
+
} catch (error95) {
|
|
46011
|
+
await this.invokeLifecycleHook(options?.onError, {
|
|
46012
|
+
...lifecycleContext,
|
|
46013
|
+
error: error95
|
|
46014
|
+
}, `spawn("${name}") onError`);
|
|
46015
|
+
throw error95;
|
|
46016
|
+
}
|
|
46017
|
+
this.resetAgentLifecycleState(result.name);
|
|
45791
46018
|
const agent = this.makeAgent(result.name, result.runtime, channels);
|
|
45792
46019
|
this.knownAgents.set(agent.name, agent);
|
|
46020
|
+
await this.invokeLifecycleHook(options?.onSuccess, {
|
|
46021
|
+
...lifecycleContext,
|
|
46022
|
+
name: result.name,
|
|
46023
|
+
runtime: result.runtime
|
|
46024
|
+
}, `spawn("${name}") onSuccess`);
|
|
45793
46025
|
return agent;
|
|
45794
46026
|
}
|
|
45795
46027
|
};
|
|
45796
46028
|
}
|
|
46029
|
+
async invokeLifecycleHook(hook, context, label) {
|
|
46030
|
+
if (!hook) {
|
|
46031
|
+
return;
|
|
46032
|
+
}
|
|
46033
|
+
try {
|
|
46034
|
+
await hook(context);
|
|
46035
|
+
} catch (error95) {
|
|
46036
|
+
console.warn(`[AgentRelay] ${label} hook threw`, error95);
|
|
46037
|
+
}
|
|
46038
|
+
}
|
|
46039
|
+
resetAgentLifecycleState(name) {
|
|
46040
|
+
this.readyAgents.delete(name);
|
|
46041
|
+
this.messageReadyAgents.delete(name);
|
|
46042
|
+
this.exitedAgents.delete(name);
|
|
46043
|
+
this.idleAgents.delete(name);
|
|
46044
|
+
}
|
|
46045
|
+
normalizeReleaseOptions(reasonOrOptions) {
|
|
46046
|
+
if (typeof reasonOrOptions === "string" || reasonOrOptions === void 0) {
|
|
46047
|
+
return { reason: reasonOrOptions };
|
|
46048
|
+
}
|
|
46049
|
+
return reasonOrOptions;
|
|
46050
|
+
}
|
|
45797
46051
|
};
|
|
45798
46052
|
|
|
45799
46053
|
// packages/sdk/dist/consensus.js
|
|
@@ -47299,6 +47553,22 @@ var WorkflowTrajectory = class {
|
|
|
47299
47553
|
};
|
|
47300
47554
|
|
|
47301
47555
|
// packages/sdk/dist/workflows/runner.js
|
|
47556
|
+
var _resolvedCursorCli;
|
|
47557
|
+
function resolveCursorCli() {
|
|
47558
|
+
if (_resolvedCursorCli !== void 0)
|
|
47559
|
+
return _resolvedCursorCli;
|
|
47560
|
+
const candidates = ["cursor-agent", "agent"];
|
|
47561
|
+
for (const candidate of candidates) {
|
|
47562
|
+
try {
|
|
47563
|
+
(0, import_node_child_process3.execFileSync)("which", [candidate], { stdio: "ignore" });
|
|
47564
|
+
_resolvedCursorCli = candidate;
|
|
47565
|
+
return candidate;
|
|
47566
|
+
} catch {
|
|
47567
|
+
}
|
|
47568
|
+
}
|
|
47569
|
+
_resolvedCursorCli = "agent";
|
|
47570
|
+
return _resolvedCursorCli;
|
|
47571
|
+
}
|
|
47302
47572
|
var WorkflowRunner = class _WorkflowRunner {
|
|
47303
47573
|
db;
|
|
47304
47574
|
workspaceId;
|
|
@@ -47393,6 +47663,17 @@ var WorkflowRunner = class _WorkflowRunner {
|
|
|
47393
47663
|
}
|
|
47394
47664
|
this.relayApiKey = apiKey;
|
|
47395
47665
|
this.relayApiKeyAutoCreated = true;
|
|
47666
|
+
const dashboardPort = process.env.AGENT_RELAY_DASHBOARD_PORT || "3888";
|
|
47667
|
+
fetch(`http://127.0.0.1:${dashboardPort}/api/relay-config`, {
|
|
47668
|
+
method: "POST",
|
|
47669
|
+
headers: { "content-type": "application/json" },
|
|
47670
|
+
body: JSON.stringify({ apiKey })
|
|
47671
|
+
}).then((res2) => {
|
|
47672
|
+
if (!res2.ok) {
|
|
47673
|
+
console.warn(`[WorkflowRunner] dashboard key push failed: HTTP ${res2.status}`);
|
|
47674
|
+
}
|
|
47675
|
+
}).catch(() => {
|
|
47676
|
+
});
|
|
47396
47677
|
}
|
|
47397
47678
|
getRelayEnv() {
|
|
47398
47679
|
if (!this.relayApiKey) {
|
|
@@ -48075,8 +48356,7 @@ ${err.suggestion}`);
|
|
|
48075
48356
|
this.log("API key resolved");
|
|
48076
48357
|
if (this.relayApiKeyAutoCreated && this.relayApiKey) {
|
|
48077
48358
|
this.log(`Workspace created \u2014 follow this run in Relaycast:`);
|
|
48078
|
-
this.log(`
|
|
48079
|
-
this.log(` Observer: https://observer.relaycast.dev (paste key above)`);
|
|
48359
|
+
this.log(` Observer: https://observer.relaycast.dev/?key=${this.relayApiKey}`);
|
|
48080
48360
|
this.log(` Channel: ${channel}`);
|
|
48081
48361
|
}
|
|
48082
48362
|
this.log("Starting broker...");
|
|
@@ -48182,19 +48462,6 @@ ${err.suggestion}`);
|
|
|
48182
48462
|
if (!isResume && workflow2.preflight?.length) {
|
|
48183
48463
|
await this.runPreflightChecks(workflow2.preflight, runId);
|
|
48184
48464
|
}
|
|
48185
|
-
if (this.relay && !isResume) {
|
|
48186
|
-
const agentPreflight = workflow2.steps.filter((s) => s.type !== "deterministic" && s.type !== "worktree" && s.agent).map((s) => {
|
|
48187
|
-
const agentDef = agentMap.get(s.agent);
|
|
48188
|
-
return agentDef && agentDef.interactive !== false ? { name: `${s.name}-${runId.slice(0, 8)}`, cli: agentDef.cli } : null;
|
|
48189
|
-
}).filter((e) => e !== null);
|
|
48190
|
-
if (agentPreflight.length > 0) {
|
|
48191
|
-
this.log(`Pre-registering ${agentPreflight.length} agents with Relaycast...`);
|
|
48192
|
-
await this.relay.preflightAgents(agentPreflight).catch((err) => {
|
|
48193
|
-
this.log(`[preflight-agents] warning: ${err.message} \u2014 continuing without pre-registration`);
|
|
48194
|
-
});
|
|
48195
|
-
this.log("Agent pre-registration complete");
|
|
48196
|
-
}
|
|
48197
|
-
}
|
|
48198
48465
|
this.log(`Executing ${workflow2.steps.length} steps (pattern: ${config3.swarm.pattern})`);
|
|
48199
48466
|
await this.executeSteps(workflow2, stepStates, agentMap, config3.errorHandling, runId);
|
|
48200
48467
|
const allCompleted = [...stepStates.values()].every((s) => s.row.status === "completed" || s.row.status === "skipped");
|
|
@@ -48576,8 +48843,6 @@ ${trimmedOutput.slice(0, 200)}`);
|
|
|
48576
48843
|
});
|
|
48577
48844
|
await this.persistStepOutput(runId, step.name, output);
|
|
48578
48845
|
this.emit({ type: "step:completed", runId, stepName: step.name, output });
|
|
48579
|
-
this.postToChannel(`**[${step.name}]** Completed (deterministic)
|
|
48580
|
-
${output.slice(0, 500)}${output.length > 500 ? "\n...(truncated)" : ""}`);
|
|
48581
48846
|
} catch (err) {
|
|
48582
48847
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
48583
48848
|
this.postToChannel(`**[${step.name}]** Failed: ${errorMsg}`);
|
|
@@ -48792,8 +49057,6 @@ ${output.slice(0, 500)}${output.length > 500 ? "\n...(truncated)" : ""}`);
|
|
|
48792
49057
|
});
|
|
48793
49058
|
await this.persistStepOutput(runId, step.name, output);
|
|
48794
49059
|
this.emit({ type: "step:completed", runId, stepName: step.name, output });
|
|
48795
|
-
this.postToChannel(`**[${step.name}]** Completed
|
|
48796
|
-
${output.slice(0, 500)}${output.length > 500 ? "\n...(truncated)" : ""}`);
|
|
48797
49060
|
await this.trajectory?.stepCompleted(step, output, attempt + 1);
|
|
48798
49061
|
return;
|
|
48799
49062
|
} catch (err) {
|
|
@@ -48831,6 +49094,11 @@ ${output.slice(0, 500)}${output.length > 500 ? "\n...(truncated)" : ""}`);
|
|
|
48831
49094
|
return { cmd: "aider", args: ["--message", task, "--yes-always", "--no-git", ...extraArgs] };
|
|
48832
49095
|
case "goose":
|
|
48833
49096
|
return { cmd: "goose", args: ["run", "--text", task, "--no-session", ...extraArgs] };
|
|
49097
|
+
case "cursor-agent":
|
|
49098
|
+
case "agent":
|
|
49099
|
+
return { cmd: cli, args: ["--force", "-p", task, ...extraArgs] };
|
|
49100
|
+
case "cursor":
|
|
49101
|
+
return { cmd: resolveCursorCli(), args: ["--force", "-p", task, ...extraArgs] };
|
|
48834
49102
|
}
|
|
48835
49103
|
}
|
|
48836
49104
|
/**
|
|
@@ -48838,11 +49106,12 @@ ${output.slice(0, 500)}${output.length > 500 ? "\n...(truncated)" : ""}`);
|
|
|
48838
49106
|
* Explicit fields on the definition always win over preset-inferred defaults.
|
|
48839
49107
|
*/
|
|
48840
49108
|
static resolveAgentDef(def) {
|
|
49109
|
+
const resolvedCli = def.cli === "cursor" ? resolveCursorCli() : def.cli;
|
|
48841
49110
|
if (!def.preset)
|
|
48842
|
-
return def;
|
|
49111
|
+
return resolvedCli !== def.cli ? { ...def, cli: resolvedCli } : def;
|
|
48843
49112
|
const nonInteractivePresets = ["worker", "reviewer", "analyst"];
|
|
48844
49113
|
const defaults = nonInteractivePresets.includes(def.preset) ? { interactive: false } : {};
|
|
48845
|
-
return { ...defaults, ...def };
|
|
49114
|
+
return { ...defaults, ...def, cli: resolvedCli };
|
|
48846
49115
|
}
|
|
48847
49116
|
/**
|
|
48848
49117
|
* Returns a preset-specific prefix that is prepended to the non-interactive
|
|
@@ -49157,7 +49426,17 @@ DO NOT:
|
|
|
49157
49426
|
async waitForExitWithIdleNudging(agent, agentDef, step, timeoutMs) {
|
|
49158
49427
|
const nudgeConfig = this.currentConfig?.swarm.idleNudge;
|
|
49159
49428
|
if (!nudgeConfig) {
|
|
49160
|
-
|
|
49429
|
+
const result = await Promise.race([
|
|
49430
|
+
agent.waitForExit(timeoutMs).then((r) => ({ kind: "exit", result: r })),
|
|
49431
|
+
agent.waitForIdle(timeoutMs).then((r) => ({ kind: "idle", result: r }))
|
|
49432
|
+
]);
|
|
49433
|
+
if (result.kind === "idle" && result.result === "idle") {
|
|
49434
|
+
this.log(`[${step.name}] Agent "${agent.name}" went idle \u2014 treating as complete`);
|
|
49435
|
+
this.postToChannel(`**[${step.name}]** Agent \`${agent.name}\` idle \u2014 treating as complete`);
|
|
49436
|
+
await agent.release();
|
|
49437
|
+
return "released";
|
|
49438
|
+
}
|
|
49439
|
+
return result.result;
|
|
49161
49440
|
}
|
|
49162
49441
|
const nudgeAfterMs = nudgeConfig.nudgeAfterMs ?? 12e4;
|
|
49163
49442
|
const escalateAfterMs = nudgeConfig.escalateAfterMs ?? 12e4;
|
|
@@ -49572,7 +49851,7 @@ ${excerpt}` : "";
|
|
|
49572
49851
|
const withoutSystemReminders = text.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/giu, "").replace(/<system-reminder>[\s\S]*/giu, "");
|
|
49573
49852
|
const normalized = withoutSystemReminders.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
49574
49853
|
const ansiStripped = stripAnsi(normalized);
|
|
49575
|
-
const SPINNER = "\\u2756\\u2738\\u2739\\u273a\\u273b\\u273c\\u273d\\u2731\\u2732\\u2733\\u2734\\u2735\\u2736\\u2737\\u2743\\u2745\\u2746\\u25d6\\u25d7\\u25d8\\u25d9\\u2022\\u25cf\\u25cb\\u25a0\\u25a1\\u25b6\\u25c0\\u23f5\\u23f6\\u23f7\\u23f8\\u23f9\\u25e2\\u25e3\\u25e4\\u25e5\\u2597\\u2596\\u2598\\u259d\\u2bc8\\u2bc7\\u2bc5\\u2bc6\\u00b7\\u2590\\u258c\\u2588\\u2584\\u2580\\u259a\\u259e";
|
|
49854
|
+
const SPINNER = "\\u2756\\u2738\\u2739\\u273a\\u273b\\u273c\\u273d\\u2731\\u2732\\u2733\\u2734\\u2735\\u2736\\u2737\\u2743\\u2745\\u2746\\u25d6\\u25d7\\u25d8\\u25d9\\u2022\\u25cf\\u25cb\\u25a0\\u25a1\\u25b6\\u25c0\\u23f5\\u23f6\\u23f7\\u23f8\\u23f9\\u25e2\\u25e3\\u25e4\\u25e5\\u2597\\u2596\\u2598\\u259d\\u2bc8\\u2bc7\\u2bc5\\u2bc6\\u00b7\\u2590\\u258c\\u2588\\u2584\\u2580\\u259a\\u259e\\u2b21\\u2b22";
|
|
49576
49855
|
const spinnerRe = new RegExp(`[${SPINNER}]`, "gu");
|
|
49577
49856
|
const spinnerClassRe = new RegExp(`^[\\s${SPINNER}]*$`, "u");
|
|
49578
49857
|
const boxDrawingOnlyRe = /^[\s\u2500-\u257f\u2580-\u259f\u25a0-\u25ff\-_=~]{3,}$/u;
|
|
@@ -49582,6 +49861,7 @@ ${excerpt}` : "";
|
|
|
49582
49861
|
const uiHintRe = /\b(?:Press\s+up\s+to\s+edit|tab\s+to\s+queue|bypass\s+permissions|esc\s+to\s+interrupt)\b/iu;
|
|
49583
49862
|
const thinkingLineRe = new RegExp(`^[\\s${SPINNER}]*\\s*\\w[\\w\\s]*\\u2026\\s*$`, "u");
|
|
49584
49863
|
const cursorOnlyRe = /^[\s❯⎿›»◀▶←→↑↓⟨⟩⟪⟫·]+$/u;
|
|
49864
|
+
const cursorAgentRe = /^(?:Cursor Agent|[\s⬡⬢]*Generating[.\s]|\[Pasted text|Auto-run all|Add a follow-up|ctrl\+c to stop|shift\+tab|Auto$|\/\s*commands|@\s*files|!\s*shell|follow-ups?\s|The user ha)/iu;
|
|
49585
49865
|
const slashCommandRe = /^\/\w+\s*$/u;
|
|
49586
49866
|
const mcpJsonKvRe = /^\s*"(?:type|method|params|result|id|jsonrpc|tool|name|arguments|content|role|metadata)"\s*:/u;
|
|
49587
49867
|
const meaningfulContentRe = /[a-zA-Z0-9]/u;
|
|
@@ -49630,6 +49910,8 @@ ${excerpt}` : "";
|
|
|
49630
49910
|
continue;
|
|
49631
49911
|
if (cursorOnlyRe.test(trimmed))
|
|
49632
49912
|
continue;
|
|
49913
|
+
if (cursorAgentRe.test(trimmed))
|
|
49914
|
+
continue;
|
|
49633
49915
|
if (slashCommandRe.test(trimmed))
|
|
49634
49916
|
continue;
|
|
49635
49917
|
if (!meaningfulContentRe.test(trimmed))
|
|
@@ -45,6 +45,8 @@ export interface CoreRelay {
|
|
|
45
45
|
}>;
|
|
46
46
|
shutdown: () => Promise<unknown>;
|
|
47
47
|
onBrokerStderr?: (listener: (line: string) => void) => () => void;
|
|
48
|
+
/** Relaycast workspace API key, available after the hello handshake. */
|
|
49
|
+
workspaceKey?: string;
|
|
48
50
|
}
|
|
49
51
|
export interface CoreFileSystem {
|
|
50
52
|
existsSync: (path: string) => boolean;
|