@rk0429/agentic-relay 2.0.8 → 2.0.10
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/relay.mjs +288 -377
- package/package.json +1 -1
package/dist/relay.mjs
CHANGED
|
@@ -204,129 +204,6 @@ var init_version_check = __esm({
|
|
|
204
204
|
}
|
|
205
205
|
});
|
|
206
206
|
|
|
207
|
-
// src/mcp-server/deferred-cleanup-task-store.ts
|
|
208
|
-
import { isTerminal } from "@modelcontextprotocol/sdk/experimental/tasks/interfaces.js";
|
|
209
|
-
import { randomBytes } from "crypto";
|
|
210
|
-
var DeferredCleanupTaskStore;
|
|
211
|
-
var init_deferred_cleanup_task_store = __esm({
|
|
212
|
-
"src/mcp-server/deferred-cleanup-task-store.ts"() {
|
|
213
|
-
"use strict";
|
|
214
|
-
DeferredCleanupTaskStore = class {
|
|
215
|
-
tasks = /* @__PURE__ */ new Map();
|
|
216
|
-
cleanupTimers = /* @__PURE__ */ new Map();
|
|
217
|
-
generateTaskId() {
|
|
218
|
-
return randomBytes(16).toString("hex");
|
|
219
|
-
}
|
|
220
|
-
async createTask(taskParams, requestId, request, _sessionId) {
|
|
221
|
-
const taskId = this.generateTaskId();
|
|
222
|
-
if (this.tasks.has(taskId)) {
|
|
223
|
-
throw new Error(`Task with ID ${taskId} already exists`);
|
|
224
|
-
}
|
|
225
|
-
const actualTtl = taskParams.ttl ?? null;
|
|
226
|
-
const createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
227
|
-
const task = {
|
|
228
|
-
taskId,
|
|
229
|
-
status: "working",
|
|
230
|
-
ttl: actualTtl,
|
|
231
|
-
createdAt,
|
|
232
|
-
lastUpdatedAt: createdAt,
|
|
233
|
-
pollInterval: taskParams.pollInterval ?? 1e3
|
|
234
|
-
};
|
|
235
|
-
this.tasks.set(taskId, { task, request, requestId });
|
|
236
|
-
return { ...task };
|
|
237
|
-
}
|
|
238
|
-
async getTask(taskId, _sessionId) {
|
|
239
|
-
const stored = this.tasks.get(taskId);
|
|
240
|
-
return stored ? { ...stored.task } : null;
|
|
241
|
-
}
|
|
242
|
-
async storeTaskResult(taskId, status, result, _sessionId) {
|
|
243
|
-
const stored = this.tasks.get(taskId);
|
|
244
|
-
if (!stored) {
|
|
245
|
-
throw new Error(`Task with ID ${taskId} not found`);
|
|
246
|
-
}
|
|
247
|
-
if (isTerminal(stored.task.status)) {
|
|
248
|
-
throw new Error(
|
|
249
|
-
`Cannot store result for task ${taskId} in terminal status '${stored.task.status}'. Task results can only be stored once.`
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
stored.result = result;
|
|
253
|
-
stored.task.status = status;
|
|
254
|
-
stored.task.lastUpdatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
255
|
-
this.scheduleCleanup(taskId, stored.task.ttl);
|
|
256
|
-
}
|
|
257
|
-
async getTaskResult(taskId, _sessionId) {
|
|
258
|
-
const stored = this.tasks.get(taskId);
|
|
259
|
-
if (!stored) {
|
|
260
|
-
throw new Error(`Task with ID ${taskId} not found`);
|
|
261
|
-
}
|
|
262
|
-
if (!stored.result) {
|
|
263
|
-
throw new Error(`Task ${taskId} has no result stored`);
|
|
264
|
-
}
|
|
265
|
-
return stored.result;
|
|
266
|
-
}
|
|
267
|
-
async updateTaskStatus(taskId, status, statusMessage, _sessionId) {
|
|
268
|
-
const stored = this.tasks.get(taskId);
|
|
269
|
-
if (!stored) {
|
|
270
|
-
throw new Error(`Task with ID ${taskId} not found`);
|
|
271
|
-
}
|
|
272
|
-
if (isTerminal(stored.task.status)) {
|
|
273
|
-
throw new Error(
|
|
274
|
-
`Cannot update task ${taskId} from terminal status '${stored.task.status}'.`
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
stored.task.status = status;
|
|
278
|
-
if (statusMessage) {
|
|
279
|
-
stored.task.statusMessage = statusMessage;
|
|
280
|
-
}
|
|
281
|
-
stored.task.lastUpdatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
282
|
-
if (isTerminal(status)) {
|
|
283
|
-
this.scheduleCleanup(taskId, stored.task.ttl);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
async listTasks(cursor, _sessionId) {
|
|
287
|
-
const PAGE_SIZE = 10;
|
|
288
|
-
const allTaskIds = Array.from(this.tasks.keys());
|
|
289
|
-
let startIndex = 0;
|
|
290
|
-
if (cursor) {
|
|
291
|
-
const cursorIndex = allTaskIds.indexOf(cursor);
|
|
292
|
-
if (cursorIndex >= 0) {
|
|
293
|
-
startIndex = cursorIndex + 1;
|
|
294
|
-
} else {
|
|
295
|
-
throw new Error(`Invalid cursor: ${cursor}`);
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
const pageTaskIds = allTaskIds.slice(startIndex, startIndex + PAGE_SIZE);
|
|
299
|
-
const tasks = pageTaskIds.map((id) => {
|
|
300
|
-
const stored = this.tasks.get(id);
|
|
301
|
-
return { ...stored.task };
|
|
302
|
-
});
|
|
303
|
-
const nextCursor = startIndex + PAGE_SIZE < allTaskIds.length ? pageTaskIds[pageTaskIds.length - 1] : void 0;
|
|
304
|
-
return { tasks, nextCursor };
|
|
305
|
-
}
|
|
306
|
-
/** Cleanup all timers (for testing or graceful shutdown) */
|
|
307
|
-
cleanup() {
|
|
308
|
-
for (const timer of this.cleanupTimers.values()) {
|
|
309
|
-
clearTimeout(timer);
|
|
310
|
-
}
|
|
311
|
-
this.cleanupTimers.clear();
|
|
312
|
-
this.tasks.clear();
|
|
313
|
-
}
|
|
314
|
-
scheduleCleanup(taskId, ttl) {
|
|
315
|
-
if (!ttl) return;
|
|
316
|
-
const existingTimer = this.cleanupTimers.get(taskId);
|
|
317
|
-
if (existingTimer) {
|
|
318
|
-
clearTimeout(existingTimer);
|
|
319
|
-
}
|
|
320
|
-
const timer = setTimeout(() => {
|
|
321
|
-
this.tasks.delete(taskId);
|
|
322
|
-
this.cleanupTimers.delete(taskId);
|
|
323
|
-
}, ttl);
|
|
324
|
-
this.cleanupTimers.set(taskId, timer);
|
|
325
|
-
}
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
});
|
|
329
|
-
|
|
330
207
|
// src/core/agent-event-store.ts
|
|
331
208
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
332
209
|
import { join as join6 } from "path";
|
|
@@ -1390,7 +1267,10 @@ ${input.prompt}`;
|
|
|
1390
1267
|
} else {
|
|
1391
1268
|
effectiveNativeSessionId = input.resumeSessionId;
|
|
1392
1269
|
}
|
|
1393
|
-
return adapter.continueSession(effectiveNativeSessionId, effectivePrompt
|
|
1270
|
+
return adapter.continueSession(effectiveNativeSessionId, effectivePrompt, {
|
|
1271
|
+
...input.model ? { model: input.model } : {},
|
|
1272
|
+
...signal ? { signal } : {}
|
|
1273
|
+
});
|
|
1394
1274
|
} else {
|
|
1395
1275
|
let mcpServers;
|
|
1396
1276
|
if (childHttpUrl) {
|
|
@@ -8109,24 +7989,6 @@ var init_backend_selector = __esm({
|
|
|
8109
7989
|
}
|
|
8110
7990
|
});
|
|
8111
7991
|
|
|
8112
|
-
// src/types/mcp.ts
|
|
8113
|
-
var DEFAULT_TASK_TTL, DEFAULT_POLL_INTERVAL;
|
|
8114
|
-
var init_mcp = __esm({
|
|
8115
|
-
"src/types/mcp.ts"() {
|
|
8116
|
-
"use strict";
|
|
8117
|
-
DEFAULT_TASK_TTL = 5 * 60 * 1e3;
|
|
8118
|
-
DEFAULT_POLL_INTERVAL = 3e3;
|
|
8119
|
-
}
|
|
8120
|
-
});
|
|
8121
|
-
|
|
8122
|
-
// src/types/index.ts
|
|
8123
|
-
var init_types2 = __esm({
|
|
8124
|
-
"src/types/index.ts"() {
|
|
8125
|
-
"use strict";
|
|
8126
|
-
init_mcp();
|
|
8127
|
-
}
|
|
8128
|
-
});
|
|
8129
|
-
|
|
8130
7992
|
// src/mcp-server/response-formatter.ts
|
|
8131
7993
|
import * as fs from "fs";
|
|
8132
7994
|
import * as path from "path";
|
|
@@ -8290,7 +8152,6 @@ __export(server_exports, {
|
|
|
8290
8152
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8291
8153
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
8292
8154
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
8293
|
-
import { InMemoryTaskMessageQueue } from "@modelcontextprotocol/sdk/experimental/tasks/stores/in-memory.js";
|
|
8294
8155
|
import { createServer } from "http";
|
|
8295
8156
|
import { mkdirSync as mkdirSync3 } from "fs";
|
|
8296
8157
|
import path2 from "path";
|
|
@@ -8317,20 +8178,20 @@ function extractRelayContextFromUrl(url) {
|
|
|
8317
8178
|
}
|
|
8318
8179
|
return void 0;
|
|
8319
8180
|
}
|
|
8320
|
-
function
|
|
8321
|
-
const
|
|
8322
|
-
|
|
8323
|
-
|
|
8324
|
-
|
|
8325
|
-
|
|
8326
|
-
|
|
8327
|
-
}
|
|
8181
|
+
function combineAbortSignals(...signals) {
|
|
8182
|
+
const activeSignals = signals.filter((signal) => signal !== void 0);
|
|
8183
|
+
if (activeSignals.length === 0) {
|
|
8184
|
+
return void 0;
|
|
8185
|
+
}
|
|
8186
|
+
if (activeSignals.length === 1) {
|
|
8187
|
+
return activeSignals[0];
|
|
8188
|
+
}
|
|
8189
|
+
return AbortSignal.any(activeSignals);
|
|
8328
8190
|
}
|
|
8329
8191
|
var spawnAgentsParallelInputShape, MAX_CHILD_HTTP_SESSIONS, DEFAULT_TASKS_DB_PATH, RelayMCPServer;
|
|
8330
8192
|
var init_server = __esm({
|
|
8331
8193
|
"src/mcp-server/server.ts"() {
|
|
8332
8194
|
"use strict";
|
|
8333
|
-
init_deferred_cleanup_task_store();
|
|
8334
8195
|
init_agent_event_store();
|
|
8335
8196
|
init_session_health_monitor();
|
|
8336
8197
|
init_recursion_guard();
|
|
@@ -8346,7 +8207,6 @@ var init_server = __esm({
|
|
|
8346
8207
|
init_metadata_validation();
|
|
8347
8208
|
init_logger();
|
|
8348
8209
|
init_version_check();
|
|
8349
|
-
init_types2();
|
|
8350
8210
|
init_response_formatter();
|
|
8351
8211
|
init_tasks();
|
|
8352
8212
|
spawnAgentsParallelInputShape = {
|
|
@@ -8453,8 +8313,7 @@ var init_server = __esm({
|
|
|
8453
8313
|
this.agentEventStore
|
|
8454
8314
|
);
|
|
8455
8315
|
this.server = new McpServer(
|
|
8456
|
-
{ name: "agentic-relay", version: "2.0.
|
|
8457
|
-
createMcpServerOptions()
|
|
8316
|
+
{ name: "agentic-relay", version: "2.0.10" }
|
|
8458
8317
|
);
|
|
8459
8318
|
this.registerTools(this.server);
|
|
8460
8319
|
this.sessionHealthMonitor.start();
|
|
@@ -8481,173 +8340,87 @@ var init_server = __esm({
|
|
|
8481
8340
|
get childHttpServer() {
|
|
8482
8341
|
return this._childHttpServer;
|
|
8483
8342
|
}
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
* Fire-and-forget: errors are caught and stored as failed task results.
|
|
8487
|
-
*/
|
|
8488
|
-
runSpawnAgentInBackground(taskId, params, extra, relayContext, signal) {
|
|
8489
|
-
const run = async () => {
|
|
8490
|
-
try {
|
|
8491
|
-
const result = await executeSpawnAgent(
|
|
8492
|
-
params,
|
|
8493
|
-
this.registry,
|
|
8494
|
-
this.sessionManager,
|
|
8495
|
-
this.guard,
|
|
8496
|
-
this.hooksEngine,
|
|
8497
|
-
this.contextMonitor,
|
|
8498
|
-
this.backendSelector,
|
|
8499
|
-
this._childHttpUrl,
|
|
8500
|
-
void 0,
|
|
8501
|
-
this.agentEventStore,
|
|
8502
|
-
this.hookMemoryDir,
|
|
8503
|
-
void 0,
|
|
8504
|
-
this.taskLifecycleManager,
|
|
8505
|
-
relayContext,
|
|
8506
|
-
signal
|
|
8507
|
-
);
|
|
8508
|
-
const controlOptions = {
|
|
8509
|
-
inlineSummaryLength: this.inlineSummaryLength ?? DEFAULT_INLINE_SUMMARY_LENGTH,
|
|
8510
|
-
sessionId: result.sessionId,
|
|
8511
|
-
responseOutputDir: this.responseOutputDir
|
|
8512
|
-
};
|
|
8513
|
-
const { text, isError } = await formatSpawnAgentResponse(result, controlOptions);
|
|
8514
|
-
const callToolResult = {
|
|
8515
|
-
content: [{ type: "text", text }],
|
|
8516
|
-
isError
|
|
8517
|
-
};
|
|
8518
|
-
await extra.taskStore.storeTaskResult(
|
|
8519
|
-
taskId,
|
|
8520
|
-
"completed",
|
|
8521
|
-
callToolResult
|
|
8522
|
-
);
|
|
8523
|
-
} catch (outerError) {
|
|
8524
|
-
try {
|
|
8525
|
-
const message = outerError instanceof Error ? outerError.message : String(outerError);
|
|
8526
|
-
await extra.taskStore.storeTaskResult(
|
|
8527
|
-
taskId,
|
|
8528
|
-
"failed",
|
|
8529
|
-
{
|
|
8530
|
-
content: [{ type: "text", text: `Error: ${message}` }],
|
|
8531
|
-
isError: true
|
|
8532
|
-
}
|
|
8533
|
-
);
|
|
8534
|
-
} catch (storeError) {
|
|
8535
|
-
logger.error(
|
|
8536
|
-
`Failed to store task result for ${taskId}: ${storeError instanceof Error ? storeError.message : String(storeError)}`
|
|
8537
|
-
);
|
|
8538
|
-
}
|
|
8539
|
-
}
|
|
8540
|
-
};
|
|
8541
|
-
void run();
|
|
8542
|
-
}
|
|
8543
|
-
/**
|
|
8544
|
-
* Run spawn_agents_parallel in the background and store the result in taskStore.
|
|
8545
|
-
* Fire-and-forget: errors are caught and stored as failed task results.
|
|
8546
|
-
*/
|
|
8547
|
-
runSpawnAgentsParallelInBackground(taskId, agents, extra, relayContext, signal) {
|
|
8548
|
-
const run = async () => {
|
|
8549
|
-
try {
|
|
8550
|
-
const result = await executeSpawnAgentsParallel(
|
|
8551
|
-
agents,
|
|
8552
|
-
this.registry,
|
|
8553
|
-
this.sessionManager,
|
|
8554
|
-
this.guard,
|
|
8555
|
-
this.hooksEngine,
|
|
8556
|
-
this.contextMonitor,
|
|
8557
|
-
this.backendSelector,
|
|
8558
|
-
this._childHttpUrl,
|
|
8559
|
-
void 0,
|
|
8560
|
-
this.agentEventStore,
|
|
8561
|
-
this.hookMemoryDir,
|
|
8562
|
-
void 0,
|
|
8563
|
-
this.taskLifecycleManager,
|
|
8564
|
-
relayContext,
|
|
8565
|
-
signal
|
|
8566
|
-
);
|
|
8567
|
-
const controlOptions = {
|
|
8568
|
-
inlineSummaryLength: this.inlineSummaryLength ?? DEFAULT_INLINE_SUMMARY_LENGTH,
|
|
8569
|
-
responseOutputDir: this.responseOutputDir
|
|
8570
|
-
};
|
|
8571
|
-
const { text, isError } = await formatParallelResponse(result, controlOptions);
|
|
8572
|
-
const callToolResult = {
|
|
8573
|
-
content: [{ type: "text", text }],
|
|
8574
|
-
isError
|
|
8575
|
-
};
|
|
8576
|
-
await extra.taskStore.storeTaskResult(
|
|
8577
|
-
taskId,
|
|
8578
|
-
"completed",
|
|
8579
|
-
callToolResult
|
|
8580
|
-
);
|
|
8581
|
-
} catch (outerError) {
|
|
8582
|
-
try {
|
|
8583
|
-
const message = outerError instanceof Error ? outerError.message : String(outerError);
|
|
8584
|
-
await extra.taskStore.storeTaskResult(
|
|
8585
|
-
taskId,
|
|
8586
|
-
"failed",
|
|
8587
|
-
{
|
|
8588
|
-
content: [{ type: "text", text: `Error: ${message}` }],
|
|
8589
|
-
isError: true
|
|
8590
|
-
}
|
|
8591
|
-
);
|
|
8592
|
-
} catch (storeError) {
|
|
8593
|
-
logger.error(
|
|
8594
|
-
`Failed to store parallel task result for ${taskId}: ${storeError instanceof Error ? storeError.message : String(storeError)}`
|
|
8595
|
-
);
|
|
8596
|
-
}
|
|
8597
|
-
}
|
|
8598
|
-
};
|
|
8599
|
-
void run();
|
|
8600
|
-
}
|
|
8601
|
-
registerTools(server, relayContext, signal) {
|
|
8602
|
-
server.experimental.tasks.registerToolTask(
|
|
8343
|
+
registerTools(server, relayContext, sessionSignal) {
|
|
8344
|
+
server.tool(
|
|
8603
8345
|
"spawn_agent",
|
|
8604
|
-
|
|
8605
|
-
|
|
8606
|
-
|
|
8607
|
-
|
|
8608
|
-
|
|
8609
|
-
|
|
8610
|
-
|
|
8611
|
-
|
|
8612
|
-
|
|
8613
|
-
|
|
8614
|
-
|
|
8615
|
-
|
|
8616
|
-
|
|
8617
|
-
|
|
8618
|
-
|
|
8619
|
-
|
|
8620
|
-
|
|
8621
|
-
|
|
8622
|
-
|
|
8623
|
-
extra.
|
|
8346
|
+
"Spawn a sub-agent on a backend CLI (Claude Code, Codex CLI, or Gemini CLI). The agent executes the given prompt in non-interactive mode and returns the result. Backend is auto-selected by priority: agentType mapping (coder/researcher\u2192codex, documenter\u2192claude) > taskType mapping > default (claude). metadata with metadata.taskId is required for task-first delegation. Use 'agentDefinition' to inject an agent .md file, 'skillContext' for a SKILL.md, or 'systemPrompt' for custom instructions.",
|
|
8347
|
+
spawnAgentInputSchema.shape,
|
|
8348
|
+
async (params, extra) => {
|
|
8349
|
+
try {
|
|
8350
|
+
const result = await executeSpawnAgent(
|
|
8351
|
+
params,
|
|
8352
|
+
this.registry,
|
|
8353
|
+
this.sessionManager,
|
|
8354
|
+
this.guard,
|
|
8355
|
+
this.hooksEngine,
|
|
8356
|
+
this.contextMonitor,
|
|
8357
|
+
this.backendSelector,
|
|
8358
|
+
this._childHttpUrl,
|
|
8359
|
+
void 0,
|
|
8360
|
+
this.agentEventStore,
|
|
8361
|
+
this.hookMemoryDir,
|
|
8362
|
+
void 0,
|
|
8363
|
+
this.taskLifecycleManager,
|
|
8364
|
+
relayContext,
|
|
8365
|
+
combineAbortSignals(extra.signal, sessionSignal)
|
|
8624
8366
|
);
|
|
8367
|
+
const controlOptions = {
|
|
8368
|
+
inlineSummaryLength: this.inlineSummaryLength ?? DEFAULT_INLINE_SUMMARY_LENGTH,
|
|
8369
|
+
sessionId: result.sessionId,
|
|
8370
|
+
responseOutputDir: this.responseOutputDir
|
|
8371
|
+
};
|
|
8372
|
+
const { text, isError } = await formatSpawnAgentResponse(result, controlOptions);
|
|
8373
|
+
return {
|
|
8374
|
+
content: [{ type: "text", text }],
|
|
8375
|
+
isError
|
|
8376
|
+
};
|
|
8377
|
+
} catch (error) {
|
|
8378
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
8379
|
+
return {
|
|
8380
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
8381
|
+
isError: true
|
|
8382
|
+
};
|
|
8625
8383
|
}
|
|
8626
8384
|
}
|
|
8627
8385
|
);
|
|
8628
|
-
server.
|
|
8386
|
+
server.tool(
|
|
8629
8387
|
"spawn_agents_parallel",
|
|
8630
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
|
|
8634
|
-
|
|
8635
|
-
|
|
8636
|
-
|
|
8637
|
-
|
|
8638
|
-
|
|
8639
|
-
|
|
8640
|
-
|
|
8641
|
-
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
|
|
8646
|
-
|
|
8647
|
-
|
|
8648
|
-
|
|
8649
|
-
extra.
|
|
8388
|
+
"Spawn multiple sub-agents in parallel across available backends. Use this when you have 2+ independent tasks that can execute concurrently. Each agent entry accepts the same parameters as spawn_agent. Results are returned as an array with per-agent status (success/failure). RecursionGuard batch pre-validation ensures the batch fits within call limits. Failed results include 'originalInput' for retry via retry_failed_agents.",
|
|
8389
|
+
spawnAgentsParallelInputShape,
|
|
8390
|
+
async (params, extra) => {
|
|
8391
|
+
try {
|
|
8392
|
+
const result = await executeSpawnAgentsParallel(
|
|
8393
|
+
params.agents,
|
|
8394
|
+
this.registry,
|
|
8395
|
+
this.sessionManager,
|
|
8396
|
+
this.guard,
|
|
8397
|
+
this.hooksEngine,
|
|
8398
|
+
this.contextMonitor,
|
|
8399
|
+
this.backendSelector,
|
|
8400
|
+
this._childHttpUrl,
|
|
8401
|
+
void 0,
|
|
8402
|
+
this.agentEventStore,
|
|
8403
|
+
this.hookMemoryDir,
|
|
8404
|
+
void 0,
|
|
8405
|
+
this.taskLifecycleManager,
|
|
8406
|
+
relayContext,
|
|
8407
|
+
combineAbortSignals(extra.signal, sessionSignal)
|
|
8650
8408
|
);
|
|
8409
|
+
const controlOptions = {
|
|
8410
|
+
inlineSummaryLength: this.inlineSummaryLength ?? DEFAULT_INLINE_SUMMARY_LENGTH,
|
|
8411
|
+
responseOutputDir: this.responseOutputDir
|
|
8412
|
+
};
|
|
8413
|
+
const { text, isError } = await formatParallelResponse(result, controlOptions);
|
|
8414
|
+
return {
|
|
8415
|
+
content: [{ type: "text", text }],
|
|
8416
|
+
isError
|
|
8417
|
+
};
|
|
8418
|
+
} catch (error) {
|
|
8419
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
8420
|
+
return {
|
|
8421
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
8422
|
+
isError: true
|
|
8423
|
+
};
|
|
8651
8424
|
}
|
|
8652
8425
|
}
|
|
8653
8426
|
);
|
|
@@ -8660,7 +8433,7 @@ var init_server = __esm({
|
|
|
8660
8433
|
originalInput: spawnAgentInputSchema
|
|
8661
8434
|
})).min(1).describe("Array of failed results with their original input configurations")
|
|
8662
8435
|
},
|
|
8663
|
-
async (params) => {
|
|
8436
|
+
async (params, extra) => {
|
|
8664
8437
|
try {
|
|
8665
8438
|
const agents = params.failedResults.map((r) => ({ ...r.originalInput }));
|
|
8666
8439
|
const result = await executeSpawnAgentsParallel(
|
|
@@ -8678,7 +8451,7 @@ var init_server = __esm({
|
|
|
8678
8451
|
void 0,
|
|
8679
8452
|
this.taskLifecycleManager,
|
|
8680
8453
|
relayContext,
|
|
8681
|
-
signal
|
|
8454
|
+
combineAbortSignals(extra.signal, sessionSignal)
|
|
8682
8455
|
);
|
|
8683
8456
|
const controlOptions = {
|
|
8684
8457
|
inlineSummaryLength: this.inlineSummaryLength ?? DEFAULT_INLINE_SUMMARY_LENGTH,
|
|
@@ -8972,8 +8745,7 @@ var init_server = __esm({
|
|
|
8972
8745
|
sessionIdGenerator: () => randomUUID()
|
|
8973
8746
|
});
|
|
8974
8747
|
const server = new McpServer(
|
|
8975
|
-
{ name: "agentic-relay", version: "2.0.
|
|
8976
|
-
createMcpServerOptions()
|
|
8748
|
+
{ name: "agentic-relay", version: "2.0.10" }
|
|
8977
8749
|
);
|
|
8978
8750
|
this.registerTools(server, childRelayContext, abortController.signal);
|
|
8979
8751
|
transport.onclose = () => {
|
|
@@ -8984,7 +8756,7 @@ var init_server = __esm({
|
|
|
8984
8756
|
if (ctrl) {
|
|
8985
8757
|
ctrl.abort();
|
|
8986
8758
|
sessionAbortControllers.delete(sid2);
|
|
8987
|
-
logger.debug(`Child MCP session closed,
|
|
8759
|
+
logger.debug(`Child MCP session closed, in-flight requests aborted: ${sid2}`);
|
|
8988
8760
|
} else {
|
|
8989
8761
|
logger.debug(`Child MCP session closed: ${sid2}`);
|
|
8990
8762
|
}
|
|
@@ -9748,7 +9520,7 @@ __export(types_exports, {
|
|
|
9748
9520
|
DEFAULT_TUI_CONFIG: () => DEFAULT_TUI_CONFIG
|
|
9749
9521
|
});
|
|
9750
9522
|
var DEFAULT_TUI_CONFIG;
|
|
9751
|
-
var
|
|
9523
|
+
var init_types2 = __esm({
|
|
9752
9524
|
"src/tui/types.ts"() {
|
|
9753
9525
|
"use strict";
|
|
9754
9526
|
DEFAULT_TUI_CONFIG = {
|
|
@@ -9772,7 +9544,7 @@ var TUIConfigManager;
|
|
|
9772
9544
|
var init_tui_config_manager = __esm({
|
|
9773
9545
|
"src/tui/services/tui-config-manager.ts"() {
|
|
9774
9546
|
"use strict";
|
|
9775
|
-
|
|
9547
|
+
init_types2();
|
|
9776
9548
|
TUIConfigManager = class {
|
|
9777
9549
|
constructor(configManager2) {
|
|
9778
9550
|
this.configManager = configManager2;
|
|
@@ -10099,7 +9871,7 @@ function App({ registry: registry2, sessionManager: sessionManager2, hooksEngine
|
|
|
10099
9871
|
setTuiConfig(updated);
|
|
10100
9872
|
setStatusMessage(`Config updated: ${key} = ${JSON.stringify(value)}`);
|
|
10101
9873
|
} else if (subCmd === "reset") {
|
|
10102
|
-
const { DEFAULT_TUI_CONFIG: DEFAULT_TUI_CONFIG2 } = await Promise.resolve().then(() => (
|
|
9874
|
+
const { DEFAULT_TUI_CONFIG: DEFAULT_TUI_CONFIG2 } = await Promise.resolve().then(() => (init_types2(), types_exports));
|
|
10103
9875
|
for (const [section, sectionValue] of Object.entries(DEFAULT_TUI_CONFIG2)) {
|
|
10104
9876
|
for (const [k, v] of Object.entries(sectionValue)) {
|
|
10105
9877
|
await tuiConfigManager.set(`${section}.${k}`, v);
|
|
@@ -10311,6 +10083,18 @@ import { homedir as homedir7 } from "os";
|
|
|
10311
10083
|
// src/infrastructure/process-manager.ts
|
|
10312
10084
|
init_logger();
|
|
10313
10085
|
import { execa } from "execa";
|
|
10086
|
+
function toProcessResultFromError(error) {
|
|
10087
|
+
const exitCode = typeof error === "object" && error !== null && "exitCode" in error && typeof error.exitCode === "number" ? error.exitCode : 1;
|
|
10088
|
+
const stdout = typeof error === "object" && error !== null && "stdout" in error && typeof error.stdout === "string" ? error.stdout : "";
|
|
10089
|
+
const stderr = typeof error === "object" && error !== null && "stderr" in error && typeof error.stderr === "string" && error.stderr.length > 0 ? error.stderr : error instanceof Error ? error.message : String(error);
|
|
10090
|
+
return { exitCode, stdout, stderr };
|
|
10091
|
+
}
|
|
10092
|
+
function getCanceledMessage(signal) {
|
|
10093
|
+
if (!signal?.aborted) {
|
|
10094
|
+
return "";
|
|
10095
|
+
}
|
|
10096
|
+
return signal.reason instanceof Error ? signal.reason.message : typeof signal.reason === "string" ? signal.reason : "";
|
|
10097
|
+
}
|
|
10314
10098
|
var ProcessManager = class {
|
|
10315
10099
|
activeProcesses = /* @__PURE__ */ new Set();
|
|
10316
10100
|
constructor() {
|
|
@@ -10324,6 +10108,7 @@ var ProcessManager = class {
|
|
|
10324
10108
|
env: options?.env,
|
|
10325
10109
|
extendEnv: options?.env ? false : true,
|
|
10326
10110
|
timeout: options?.timeout,
|
|
10111
|
+
cancelSignal: options?.signal,
|
|
10327
10112
|
reject: false
|
|
10328
10113
|
};
|
|
10329
10114
|
const proc = execa(command, args, execaOptions);
|
|
@@ -10344,6 +10129,7 @@ var ProcessManager = class {
|
|
|
10344
10129
|
env: options?.env,
|
|
10345
10130
|
extendEnv: options?.env ? false : true,
|
|
10346
10131
|
timeout: options?.timeout,
|
|
10132
|
+
cancelSignal: options?.signal,
|
|
10347
10133
|
reject: false
|
|
10348
10134
|
};
|
|
10349
10135
|
const proc = execa(command, args, execaOptions);
|
|
@@ -10353,8 +10139,10 @@ var ProcessManager = class {
|
|
|
10353
10139
|
return {
|
|
10354
10140
|
exitCode: result.exitCode ?? 1,
|
|
10355
10141
|
stdout: result.stdout?.toString() ?? "",
|
|
10356
|
-
stderr: result.stderr?.toString()
|
|
10142
|
+
stderr: result.stderr?.toString() || getCanceledMessage(options?.signal)
|
|
10357
10143
|
};
|
|
10144
|
+
} catch (error) {
|
|
10145
|
+
return toProcessResultFromError(error);
|
|
10358
10146
|
} finally {
|
|
10359
10147
|
this.activeProcesses.delete(proc);
|
|
10360
10148
|
}
|
|
@@ -10366,7 +10154,9 @@ var ProcessManager = class {
|
|
|
10366
10154
|
input: stdinData,
|
|
10367
10155
|
cwd: options?.cwd,
|
|
10368
10156
|
env: options?.env,
|
|
10157
|
+
extendEnv: options?.env ? false : true,
|
|
10369
10158
|
timeout: options?.timeout,
|
|
10159
|
+
cancelSignal: options?.signal,
|
|
10370
10160
|
reject: false
|
|
10371
10161
|
};
|
|
10372
10162
|
const proc = execa(command, args, execaOptions);
|
|
@@ -10376,8 +10166,10 @@ var ProcessManager = class {
|
|
|
10376
10166
|
return {
|
|
10377
10167
|
exitCode: result.exitCode ?? 1,
|
|
10378
10168
|
stdout: result.stdout?.toString() ?? "",
|
|
10379
|
-
stderr: result.stderr?.toString()
|
|
10169
|
+
stderr: result.stderr?.toString() || getCanceledMessage(options?.signal)
|
|
10380
10170
|
};
|
|
10171
|
+
} catch (error) {
|
|
10172
|
+
return toProcessResultFromError(error);
|
|
10381
10173
|
} finally {
|
|
10382
10174
|
this.activeProcesses.delete(proc);
|
|
10383
10175
|
}
|
|
@@ -10466,7 +10258,7 @@ var BaseAdapter = class _BaseAdapter {
|
|
|
10466
10258
|
}
|
|
10467
10259
|
return result.stdout.trim();
|
|
10468
10260
|
}
|
|
10469
|
-
async continueSession(_nativeSessionId, _prompt) {
|
|
10261
|
+
async continueSession(_nativeSessionId, _prompt, _options) {
|
|
10470
10262
|
return {
|
|
10471
10263
|
exitCode: 1,
|
|
10472
10264
|
stdout: "",
|
|
@@ -10855,9 +10647,11 @@ var ClaudeAdapter = class extends BaseAdapter {
|
|
|
10855
10647
|
if (timer !== void 0) clearTimeout(timer);
|
|
10856
10648
|
}
|
|
10857
10649
|
}
|
|
10858
|
-
async continueSession(nativeSessionId, prompt) {
|
|
10650
|
+
async continueSession(nativeSessionId, prompt, options) {
|
|
10859
10651
|
const timeoutMs = resolveClaudeSdkTimeoutMs();
|
|
10860
10652
|
const abortController = new AbortController();
|
|
10653
|
+
const onAbort = () => abortController.abort();
|
|
10654
|
+
options?.signal?.addEventListener("abort", onAbort, { once: true });
|
|
10861
10655
|
const timer = timeoutMs !== void 0 ? setTimeout(() => abortController.abort(), timeoutMs) : void 0;
|
|
10862
10656
|
try {
|
|
10863
10657
|
const { query } = await loadClaudeSDK();
|
|
@@ -10906,6 +10700,7 @@ var ClaudeAdapter = class extends BaseAdapter {
|
|
|
10906
10700
|
stderr: error instanceof Error ? error.message : String(error)
|
|
10907
10701
|
};
|
|
10908
10702
|
} finally {
|
|
10703
|
+
options?.signal?.removeEventListener("abort", onAbort);
|
|
10909
10704
|
if (timer !== void 0) clearTimeout(timer);
|
|
10910
10705
|
}
|
|
10911
10706
|
}
|
|
@@ -11008,8 +10803,8 @@ var ClaudeAdapter = class extends BaseAdapter {
|
|
|
11008
10803
|
|
|
11009
10804
|
// src/adapters/codex-adapter.ts
|
|
11010
10805
|
init_logger();
|
|
11011
|
-
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, mkdtemp, copyFile } from "fs/promises";
|
|
11012
|
-
import { homedir as homedir2 } from "os";
|
|
10806
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, mkdtemp, copyFile, rm } from "fs/promises";
|
|
10807
|
+
import { homedir as homedir2, tmpdir } from "os";
|
|
11013
10808
|
import { join as join2, dirname as dirname2 } from "path";
|
|
11014
10809
|
async function loadCodexSDK() {
|
|
11015
10810
|
return await import("@openai/codex-sdk");
|
|
@@ -11195,6 +10990,70 @@ async function copyIfExists(from, to) {
|
|
|
11195
10990
|
throw error;
|
|
11196
10991
|
}
|
|
11197
10992
|
}
|
|
10993
|
+
async function readFileIfExists(path3) {
|
|
10994
|
+
try {
|
|
10995
|
+
return await readFile2(path3, "utf-8");
|
|
10996
|
+
} catch (error) {
|
|
10997
|
+
if (isFileNotFoundError(error)) {
|
|
10998
|
+
return void 0;
|
|
10999
|
+
}
|
|
11000
|
+
throw error;
|
|
11001
|
+
}
|
|
11002
|
+
}
|
|
11003
|
+
function parseCodexExecJson(stdout) {
|
|
11004
|
+
const parsed = {
|
|
11005
|
+
completedMessages: [],
|
|
11006
|
+
errorMessages: []
|
|
11007
|
+
};
|
|
11008
|
+
for (const rawLine of stdout.split(/\r?\n/)) {
|
|
11009
|
+
const line = rawLine.trim();
|
|
11010
|
+
if (!line) continue;
|
|
11011
|
+
let event;
|
|
11012
|
+
try {
|
|
11013
|
+
event = JSON.parse(line);
|
|
11014
|
+
} catch {
|
|
11015
|
+
continue;
|
|
11016
|
+
}
|
|
11017
|
+
if (typeof event !== "object" || event === null || !("type" in event) || typeof event.type !== "string") {
|
|
11018
|
+
continue;
|
|
11019
|
+
}
|
|
11020
|
+
switch (event.type) {
|
|
11021
|
+
case "thread.started":
|
|
11022
|
+
if ("thread_id" in event && typeof event.thread_id === "string") {
|
|
11023
|
+
parsed.threadId = event.thread_id;
|
|
11024
|
+
}
|
|
11025
|
+
break;
|
|
11026
|
+
case "item.completed":
|
|
11027
|
+
if ("item" in event && typeof event.item === "object" && event.item !== null && "type" in event.item && event.item.type === "agent_message" && "text" in event.item && typeof event.item.text === "string") {
|
|
11028
|
+
parsed.completedMessages.push(event.item.text);
|
|
11029
|
+
}
|
|
11030
|
+
break;
|
|
11031
|
+
case "turn.completed":
|
|
11032
|
+
if ("usage" in event && typeof event.usage === "object" && event.usage !== null) {
|
|
11033
|
+
const cachedInputTokens = "cached_input_tokens" in event.usage && typeof event.usage.cached_input_tokens === "number" ? event.usage.cached_input_tokens : 0;
|
|
11034
|
+
parsed.tokenUsage = {
|
|
11035
|
+
inputTokens: ("input_tokens" in event.usage && typeof event.usage.input_tokens === "number" ? event.usage.input_tokens : 0) + cachedInputTokens,
|
|
11036
|
+
outputTokens: "output_tokens" in event.usage && typeof event.usage.output_tokens === "number" ? event.usage.output_tokens : 0,
|
|
11037
|
+
...cachedInputTokens > 0 ? { cachedInputTokens } : {}
|
|
11038
|
+
};
|
|
11039
|
+
}
|
|
11040
|
+
break;
|
|
11041
|
+
case "turn.failed":
|
|
11042
|
+
if ("error" in event && typeof event.error === "object" && event.error !== null && "message" in event.error && typeof event.error.message === "string") {
|
|
11043
|
+
parsed.failureMessage = event.error.message;
|
|
11044
|
+
}
|
|
11045
|
+
break;
|
|
11046
|
+
case "error":
|
|
11047
|
+
if ("message" in event && typeof event.message === "string") {
|
|
11048
|
+
parsed.errorMessages.push(event.message);
|
|
11049
|
+
}
|
|
11050
|
+
break;
|
|
11051
|
+
default:
|
|
11052
|
+
break;
|
|
11053
|
+
}
|
|
11054
|
+
}
|
|
11055
|
+
return parsed;
|
|
11056
|
+
}
|
|
11198
11057
|
var CodexAdapter = class extends BaseAdapter {
|
|
11199
11058
|
id = "codex";
|
|
11200
11059
|
command = "codex";
|
|
@@ -11328,6 +11187,62 @@ ${systemPrompt}
|
|
|
11328
11187
|
[User Request]
|
|
11329
11188
|
${prompt}`;
|
|
11330
11189
|
}
|
|
11190
|
+
shouldHardenRelayChild(flags) {
|
|
11191
|
+
return Boolean(
|
|
11192
|
+
flags.mcpContext || flags.mcpServers && Object.keys(flags.mcpServers).length > 0
|
|
11193
|
+
);
|
|
11194
|
+
}
|
|
11195
|
+
buildCodexExecBaseArgs(model, hardenRelayChild) {
|
|
11196
|
+
const args = [
|
|
11197
|
+
"-a",
|
|
11198
|
+
"never",
|
|
11199
|
+
"-C",
|
|
11200
|
+
process.cwd()
|
|
11201
|
+
];
|
|
11202
|
+
if (model) {
|
|
11203
|
+
args.unshift(model);
|
|
11204
|
+
args.unshift("--model");
|
|
11205
|
+
}
|
|
11206
|
+
if (hardenRelayChild) {
|
|
11207
|
+
args.push("-c", "project_root_markers=[]");
|
|
11208
|
+
}
|
|
11209
|
+
return args;
|
|
11210
|
+
}
|
|
11211
|
+
async runCodexExecCommand(args, prompt, env, signal, isolatedCodexHome, fallbackNativeSessionId) {
|
|
11212
|
+
const execTempDir = await mkdtemp(join2(tmpdir(), "relay-codex-exec-"));
|
|
11213
|
+
const outputPath = join2(execTempDir, "last-message.txt");
|
|
11214
|
+
try {
|
|
11215
|
+
const result = await this.processManager.executeWithInput(
|
|
11216
|
+
this.command,
|
|
11217
|
+
[...args, "--json", "-o", outputPath, "-"],
|
|
11218
|
+
prompt,
|
|
11219
|
+
{ env, signal }
|
|
11220
|
+
);
|
|
11221
|
+
const parsed = parseCodexExecJson(result.stdout);
|
|
11222
|
+
const outputFileContent = await readFileIfExists(outputPath);
|
|
11223
|
+
const finalResponse = outputFileContent ?? parsed.completedMessages.join("\n");
|
|
11224
|
+
const nativeSessionId = parsed.threadId ? encodeNativeSessionId(parsed.threadId, isolatedCodexHome) : fallbackNativeSessionId;
|
|
11225
|
+
if (result.exitCode === 0) {
|
|
11226
|
+
return {
|
|
11227
|
+
exitCode: 0,
|
|
11228
|
+
stdout: finalResponse,
|
|
11229
|
+
stderr: "",
|
|
11230
|
+
...nativeSessionId ? { nativeSessionId } : {},
|
|
11231
|
+
...parsed.tokenUsage ? { tokenUsage: parsed.tokenUsage } : {}
|
|
11232
|
+
};
|
|
11233
|
+
}
|
|
11234
|
+
const stderr = signal?.aborted ? "Codex execution cancelled: parent session disconnected" : parsed.failureMessage ?? parsed.errorMessages.at(-1) ?? (result.stderr || "Codex execution failed");
|
|
11235
|
+
return {
|
|
11236
|
+
exitCode: result.exitCode || 1,
|
|
11237
|
+
stdout: finalResponse,
|
|
11238
|
+
stderr,
|
|
11239
|
+
...nativeSessionId ? { nativeSessionId } : {},
|
|
11240
|
+
...parsed.tokenUsage ? { tokenUsage: parsed.tokenUsage } : {}
|
|
11241
|
+
};
|
|
11242
|
+
} finally {
|
|
11243
|
+
await rm(execTempDir, { recursive: true, force: true }).catch(() => void 0);
|
|
11244
|
+
}
|
|
11245
|
+
}
|
|
11331
11246
|
async execute(flags) {
|
|
11332
11247
|
if (!flags.prompt) {
|
|
11333
11248
|
throw new Error("execute requires a prompt (-p flag)");
|
|
@@ -11338,28 +11253,22 @@ ${prompt}`;
|
|
|
11338
11253
|
systemPrompt
|
|
11339
11254
|
);
|
|
11340
11255
|
try {
|
|
11341
|
-
const { Codex } = await loadCodexSDK();
|
|
11342
11256
|
const { options, isolatedCodexHome } = await this.buildCodexOptions(flags);
|
|
11343
|
-
const
|
|
11344
|
-
|
|
11345
|
-
|
|
11346
|
-
|
|
11347
|
-
|
|
11348
|
-
|
|
11349
|
-
|
|
11350
|
-
|
|
11351
|
-
|
|
11352
|
-
|
|
11353
|
-
|
|
11354
|
-
|
|
11355
|
-
|
|
11356
|
-
|
|
11357
|
-
|
|
11358
|
-
thread.id,
|
|
11359
|
-
isolatedCodexHome
|
|
11360
|
-
)
|
|
11361
|
-
} : {}
|
|
11362
|
-
};
|
|
11257
|
+
const args = this.buildCodexExecBaseArgs(
|
|
11258
|
+
flags.model,
|
|
11259
|
+
this.shouldHardenRelayChild(flags)
|
|
11260
|
+
);
|
|
11261
|
+
args.push("exec");
|
|
11262
|
+
if (this.shouldHardenRelayChild(flags)) {
|
|
11263
|
+
args.push("--disable", "multi_agent");
|
|
11264
|
+
}
|
|
11265
|
+
return await this.runCodexExecCommand(
|
|
11266
|
+
args,
|
|
11267
|
+
effectivePrompt,
|
|
11268
|
+
options.env,
|
|
11269
|
+
flags.signal,
|
|
11270
|
+
isolatedCodexHome
|
|
11271
|
+
);
|
|
11363
11272
|
} catch (error) {
|
|
11364
11273
|
if (flags.signal?.aborted) {
|
|
11365
11274
|
return {
|
|
@@ -11479,34 +11388,36 @@ ${prompt}`;
|
|
|
11479
11388
|
};
|
|
11480
11389
|
}
|
|
11481
11390
|
}
|
|
11482
|
-
async continueSession(nativeSessionId, prompt) {
|
|
11391
|
+
async continueSession(nativeSessionId, prompt, options) {
|
|
11483
11392
|
try {
|
|
11484
|
-
const { Codex } = await loadCodexSDK();
|
|
11485
11393
|
const { threadId, codexHome } = decodeNativeSessionId(nativeSessionId);
|
|
11486
|
-
const
|
|
11487
|
-
|
|
11488
|
-
env
|
|
11489
|
-
|
|
11490
|
-
|
|
11491
|
-
|
|
11492
|
-
|
|
11493
|
-
|
|
11494
|
-
|
|
11495
|
-
|
|
11496
|
-
|
|
11497
|
-
|
|
11498
|
-
|
|
11499
|
-
|
|
11500
|
-
|
|
11501
|
-
|
|
11502
|
-
const result = await thread.run(prompt);
|
|
11503
|
-
return {
|
|
11504
|
-
exitCode: 0,
|
|
11505
|
-
stdout: result.finalResponse,
|
|
11506
|
-
stderr: "",
|
|
11394
|
+
const env = codexHome ? {
|
|
11395
|
+
...Object.fromEntries(
|
|
11396
|
+
Object.entries(process.env).filter(
|
|
11397
|
+
([, value]) => value !== void 0
|
|
11398
|
+
)
|
|
11399
|
+
),
|
|
11400
|
+
CODEX_HOME: codexHome
|
|
11401
|
+
} : void 0;
|
|
11402
|
+
const args = this.buildCodexExecBaseArgs(options?.model, true);
|
|
11403
|
+
args.push("exec", "resume", "--disable", "multi_agent", threadId);
|
|
11404
|
+
return await this.runCodexExecCommand(
|
|
11405
|
+
args,
|
|
11406
|
+
prompt,
|
|
11407
|
+
env,
|
|
11408
|
+
options?.signal,
|
|
11409
|
+
codexHome,
|
|
11507
11410
|
nativeSessionId
|
|
11508
|
-
|
|
11411
|
+
);
|
|
11509
11412
|
} catch (error) {
|
|
11413
|
+
if (options?.signal?.aborted) {
|
|
11414
|
+
return {
|
|
11415
|
+
exitCode: 1,
|
|
11416
|
+
stdout: "",
|
|
11417
|
+
stderr: "Codex execution cancelled: parent session disconnected",
|
|
11418
|
+
nativeSessionId
|
|
11419
|
+
};
|
|
11420
|
+
}
|
|
11510
11421
|
return {
|
|
11511
11422
|
exitCode: 1,
|
|
11512
11423
|
stdout: "",
|
|
@@ -13617,7 +13528,7 @@ function createMCPCommand(configManager2, registry2, sessionManager2, hooksEngin
|
|
|
13617
13528
|
responseOutputDir,
|
|
13618
13529
|
relayConfig
|
|
13619
13530
|
);
|
|
13620
|
-
await server.start({ transport, port, currentVersion: "2.0.
|
|
13531
|
+
await server.start({ transport, port, currentVersion: "2.0.10" });
|
|
13621
13532
|
}
|
|
13622
13533
|
})
|
|
13623
13534
|
},
|
|
@@ -13777,7 +13688,7 @@ function createVersionCommand(registry2) {
|
|
|
13777
13688
|
description: "Show relay and backend versions"
|
|
13778
13689
|
},
|
|
13779
13690
|
async run() {
|
|
13780
|
-
const relayVersion = "2.0.
|
|
13691
|
+
const relayVersion = "2.0.10";
|
|
13781
13692
|
console.log(`agentic-relay v${relayVersion}`);
|
|
13782
13693
|
console.log("");
|
|
13783
13694
|
console.log("Backends:");
|
|
@@ -14174,7 +14085,7 @@ var subCommandNames = /* @__PURE__ */ new Set(["claude", "codex", "gemini", "upd
|
|
|
14174
14085
|
var main = defineCommand11({
|
|
14175
14086
|
meta: {
|
|
14176
14087
|
name: "relay",
|
|
14177
|
-
version: "2.0.
|
|
14088
|
+
version: "2.0.10",
|
|
14178
14089
|
description: "Unified CLI proxy for Claude Code, Codex CLI, and Gemini CLI"
|
|
14179
14090
|
},
|
|
14180
14091
|
args: {
|
package/package.json
CHANGED