@rk0429/agentic-relay 0.11.0 → 0.12.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/relay.mjs +174 -90
- package/package.json +1 -1
package/dist/relay.mjs
CHANGED
|
@@ -1047,6 +1047,24 @@ var init_backend_selector = __esm({
|
|
|
1047
1047
|
}
|
|
1048
1048
|
});
|
|
1049
1049
|
|
|
1050
|
+
// src/types/mcp.ts
|
|
1051
|
+
var DEFAULT_TASK_TTL, DEFAULT_POLL_INTERVAL;
|
|
1052
|
+
var init_mcp = __esm({
|
|
1053
|
+
"src/types/mcp.ts"() {
|
|
1054
|
+
"use strict";
|
|
1055
|
+
DEFAULT_TASK_TTL = 5 * 60 * 1e3;
|
|
1056
|
+
DEFAULT_POLL_INTERVAL = 3e3;
|
|
1057
|
+
}
|
|
1058
|
+
});
|
|
1059
|
+
|
|
1060
|
+
// src/types/index.ts
|
|
1061
|
+
var init_types = __esm({
|
|
1062
|
+
"src/types/index.ts"() {
|
|
1063
|
+
"use strict";
|
|
1064
|
+
init_mcp();
|
|
1065
|
+
}
|
|
1066
|
+
});
|
|
1067
|
+
|
|
1050
1068
|
// src/mcp-server/response-formatter.ts
|
|
1051
1069
|
function formatSpawnAgentResponse(result) {
|
|
1052
1070
|
const isError = result.exitCode !== 0;
|
|
@@ -1119,9 +1137,20 @@ __export(server_exports, {
|
|
|
1119
1137
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
1120
1138
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
1121
1139
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
1140
|
+
import { InMemoryTaskStore } from "@modelcontextprotocol/sdk/experimental/tasks/stores/in-memory.js";
|
|
1141
|
+
import { InMemoryTaskMessageQueue } from "@modelcontextprotocol/sdk/experimental/tasks/stores/in-memory.js";
|
|
1122
1142
|
import { createServer } from "http";
|
|
1123
1143
|
import { randomUUID } from "crypto";
|
|
1124
1144
|
import { z as z5 } from "zod";
|
|
1145
|
+
function createMcpServerOptions() {
|
|
1146
|
+
const taskStore = new InMemoryTaskStore();
|
|
1147
|
+
return {
|
|
1148
|
+
capabilities: { tasks: { requests: { tools: { call: {} } } } },
|
|
1149
|
+
taskStore,
|
|
1150
|
+
taskMessageQueue: new InMemoryTaskMessageQueue(),
|
|
1151
|
+
defaultTaskPollInterval: DEFAULT_POLL_INTERVAL
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1125
1154
|
var spawnAgentsParallelInputShape, MAX_CHILD_HTTP_SESSIONS, RelayMCPServer;
|
|
1126
1155
|
var init_server = __esm({
|
|
1127
1156
|
"src/mcp-server/server.ts"() {
|
|
@@ -1134,6 +1163,7 @@ var init_server = __esm({
|
|
|
1134
1163
|
init_list_available_backends();
|
|
1135
1164
|
init_backend_selector();
|
|
1136
1165
|
init_logger();
|
|
1166
|
+
init_types();
|
|
1137
1167
|
init_response_formatter();
|
|
1138
1168
|
spawnAgentsParallelInputShape = {
|
|
1139
1169
|
agents: z5.array(spawnAgentInputSchema).min(1).max(10).describe(
|
|
@@ -1149,10 +1179,10 @@ var init_server = __esm({
|
|
|
1149
1179
|
this.contextMonitor = contextMonitor2;
|
|
1150
1180
|
this.guard = new RecursionGuard(guardConfig);
|
|
1151
1181
|
this.backendSelector = new BackendSelector();
|
|
1152
|
-
this.server = new McpServer(
|
|
1153
|
-
name: "agentic-relay",
|
|
1154
|
-
|
|
1155
|
-
|
|
1182
|
+
this.server = new McpServer(
|
|
1183
|
+
{ name: "agentic-relay", version: "0.12.0" },
|
|
1184
|
+
createMcpServerOptions()
|
|
1185
|
+
);
|
|
1156
1186
|
this.registerTools(this.server);
|
|
1157
1187
|
}
|
|
1158
1188
|
server;
|
|
@@ -1168,94 +1198,148 @@ var init_server = __esm({
|
|
|
1168
1198
|
get childHttpServer() {
|
|
1169
1199
|
return this._childHttpServer;
|
|
1170
1200
|
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1201
|
+
/**
|
|
1202
|
+
* Run spawn_agent in the background and store the result in taskStore.
|
|
1203
|
+
* Fire-and-forget: errors are caught and stored as failed task results.
|
|
1204
|
+
*/
|
|
1205
|
+
runSpawnAgentInBackground(taskId, params, extra) {
|
|
1206
|
+
const run = async () => {
|
|
1207
|
+
try {
|
|
1208
|
+
const result = await executeSpawnAgent(
|
|
1209
|
+
params,
|
|
1210
|
+
this.registry,
|
|
1211
|
+
this.sessionManager,
|
|
1212
|
+
this.guard,
|
|
1213
|
+
this.hooksEngine,
|
|
1214
|
+
this.contextMonitor,
|
|
1215
|
+
this.backendSelector,
|
|
1216
|
+
this._childHttpUrl
|
|
1217
|
+
);
|
|
1218
|
+
const { text, isError } = formatSpawnAgentResponse(result);
|
|
1219
|
+
const callToolResult = {
|
|
1220
|
+
content: [{ type: "text", text }],
|
|
1221
|
+
isError
|
|
1222
|
+
};
|
|
1223
|
+
await extra.taskStore.storeTaskResult(
|
|
1224
|
+
taskId,
|
|
1225
|
+
"completed",
|
|
1226
|
+
callToolResult
|
|
1227
|
+
);
|
|
1228
|
+
} catch (outerError) {
|
|
1177
1229
|
try {
|
|
1178
|
-
const
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
progress: progress.percent ?? 0,
|
|
1186
|
-
total: 100,
|
|
1187
|
-
message: progress.stage
|
|
1188
|
-
}
|
|
1189
|
-
});
|
|
1230
|
+
const message = outerError instanceof Error ? outerError.message : String(outerError);
|
|
1231
|
+
await extra.taskStore.storeTaskResult(
|
|
1232
|
+
taskId,
|
|
1233
|
+
"failed",
|
|
1234
|
+
{
|
|
1235
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1236
|
+
isError: true
|
|
1190
1237
|
}
|
|
1191
|
-
};
|
|
1192
|
-
const result = await executeSpawnAgent(
|
|
1193
|
-
params,
|
|
1194
|
-
this.registry,
|
|
1195
|
-
this.sessionManager,
|
|
1196
|
-
this.guard,
|
|
1197
|
-
this.hooksEngine,
|
|
1198
|
-
this.contextMonitor,
|
|
1199
|
-
this.backendSelector,
|
|
1200
|
-
this._childHttpUrl,
|
|
1201
|
-
onProgress
|
|
1202
1238
|
);
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
};
|
|
1208
|
-
} catch (error) {
|
|
1209
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1210
|
-
return {
|
|
1211
|
-
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1212
|
-
isError: true
|
|
1213
|
-
};
|
|
1239
|
+
} catch (storeError) {
|
|
1240
|
+
logger.error(
|
|
1241
|
+
`Failed to store task result for ${taskId}: ${storeError instanceof Error ? storeError.message : String(storeError)}`
|
|
1242
|
+
);
|
|
1214
1243
|
}
|
|
1215
1244
|
}
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1245
|
+
};
|
|
1246
|
+
void run();
|
|
1247
|
+
}
|
|
1248
|
+
/**
|
|
1249
|
+
* Run spawn_agents_parallel in the background and store the result in taskStore.
|
|
1250
|
+
* Fire-and-forget: errors are caught and stored as failed task results.
|
|
1251
|
+
*/
|
|
1252
|
+
runSpawnAgentsParallelInBackground(taskId, agents, extra) {
|
|
1253
|
+
const run = async () => {
|
|
1254
|
+
try {
|
|
1255
|
+
const result = await executeSpawnAgentsParallel(
|
|
1256
|
+
agents,
|
|
1257
|
+
this.registry,
|
|
1258
|
+
this.sessionManager,
|
|
1259
|
+
this.guard,
|
|
1260
|
+
this.hooksEngine,
|
|
1261
|
+
this.contextMonitor,
|
|
1262
|
+
this.backendSelector,
|
|
1263
|
+
this._childHttpUrl
|
|
1264
|
+
);
|
|
1265
|
+
const { text, isError } = formatParallelResponse(result);
|
|
1266
|
+
const callToolResult = {
|
|
1267
|
+
content: [{ type: "text", text }],
|
|
1268
|
+
isError
|
|
1269
|
+
};
|
|
1270
|
+
await extra.taskStore.storeTaskResult(
|
|
1271
|
+
taskId,
|
|
1272
|
+
"completed",
|
|
1273
|
+
callToolResult
|
|
1274
|
+
);
|
|
1275
|
+
} catch (outerError) {
|
|
1222
1276
|
try {
|
|
1223
|
-
const
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
progress: progress.percent ?? 0,
|
|
1231
|
-
total: 100,
|
|
1232
|
-
message: progress.stage
|
|
1233
|
-
}
|
|
1234
|
-
});
|
|
1277
|
+
const message = outerError instanceof Error ? outerError.message : String(outerError);
|
|
1278
|
+
await extra.taskStore.storeTaskResult(
|
|
1279
|
+
taskId,
|
|
1280
|
+
"failed",
|
|
1281
|
+
{
|
|
1282
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
1283
|
+
isError: true
|
|
1235
1284
|
}
|
|
1236
|
-
};
|
|
1237
|
-
const result = await executeSpawnAgentsParallel(
|
|
1238
|
-
params.agents,
|
|
1239
|
-
this.registry,
|
|
1240
|
-
this.sessionManager,
|
|
1241
|
-
this.guard,
|
|
1242
|
-
this.hooksEngine,
|
|
1243
|
-
this.contextMonitor,
|
|
1244
|
-
this.backendSelector,
|
|
1245
|
-
this._childHttpUrl,
|
|
1246
|
-
onProgress
|
|
1247
1285
|
);
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1286
|
+
} catch (storeError) {
|
|
1287
|
+
logger.error(
|
|
1288
|
+
`Failed to store parallel task result for ${taskId}: ${storeError instanceof Error ? storeError.message : String(storeError)}`
|
|
1289
|
+
);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
};
|
|
1293
|
+
void run();
|
|
1294
|
+
}
|
|
1295
|
+
registerTools(server) {
|
|
1296
|
+
server.experimental.tasks.registerToolTask(
|
|
1297
|
+
"spawn_agent",
|
|
1298
|
+
{
|
|
1299
|
+
description: "Spawn a sub-agent on the specified backend CLI (Claude Code, Codex CLI, or Gemini CLI). The agent executes the given prompt in non-interactive mode and returns the result. Use 'agent' for named agent configurations (Claude only), 'systemPrompt' for custom role instructions (all backends), 'skillContext' to inject a skill definition (SKILL.md/SUBSKILL.md), 'agentDefinition' to inject an agent definition file into the sub-agent's system prompt, 'preferredBackend' to override automatic backend selection, or 'taskType' to hint at the task nature for backend selection.",
|
|
1300
|
+
inputSchema: spawnAgentInputSchema.shape,
|
|
1301
|
+
execution: { taskSupport: "optional" }
|
|
1302
|
+
},
|
|
1303
|
+
{
|
|
1304
|
+
createTask: async (params, extra) => {
|
|
1305
|
+
const task = await extra.taskStore.createTask({
|
|
1306
|
+
ttl: DEFAULT_TASK_TTL,
|
|
1307
|
+
pollInterval: DEFAULT_POLL_INTERVAL
|
|
1308
|
+
});
|
|
1309
|
+
this.runSpawnAgentInBackground(task.taskId, params, extra);
|
|
1310
|
+
return { task };
|
|
1311
|
+
},
|
|
1312
|
+
getTask: async (_params, extra) => {
|
|
1313
|
+
const task = await extra.taskStore.getTask(extra.taskId);
|
|
1314
|
+
return { task: task ?? void 0 };
|
|
1315
|
+
},
|
|
1316
|
+
getTaskResult: async (_params, extra) => {
|
|
1317
|
+
return await extra.taskStore.getTaskResult(extra.taskId);
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
);
|
|
1321
|
+
server.experimental.tasks.registerToolTask(
|
|
1322
|
+
"spawn_agents_parallel",
|
|
1323
|
+
{
|
|
1324
|
+
description: "Spawn multiple sub-agents in parallel across available backends. Each agent entry accepts the same parameters as spawn_agent. All agents are executed concurrently via Promise.allSettled, and results are returned as an array with per-agent status. RecursionGuard batch pre-validation ensures the entire batch fits within call limits before execution begins. Failed results include 'originalInput' for retry via retry_failed_agents.",
|
|
1325
|
+
inputSchema: spawnAgentsParallelInputShape,
|
|
1326
|
+
execution: { taskSupport: "optional" }
|
|
1327
|
+
},
|
|
1328
|
+
{
|
|
1329
|
+
createTask: async (params, extra) => {
|
|
1330
|
+
const task = await extra.taskStore.createTask({
|
|
1331
|
+
ttl: DEFAULT_TASK_TTL,
|
|
1332
|
+
pollInterval: DEFAULT_POLL_INTERVAL
|
|
1333
|
+
});
|
|
1334
|
+
this.runSpawnAgentsParallelInBackground(task.taskId, params.agents, extra);
|
|
1335
|
+
return { task };
|
|
1336
|
+
},
|
|
1337
|
+
getTask: async (_params, extra) => {
|
|
1338
|
+
const task = await extra.taskStore.getTask(extra.taskId);
|
|
1339
|
+
return { task: task ?? void 0 };
|
|
1340
|
+
},
|
|
1341
|
+
getTaskResult: async (_params, extra) => {
|
|
1342
|
+
return await extra.taskStore.getTaskResult(extra.taskId);
|
|
1259
1343
|
}
|
|
1260
1344
|
}
|
|
1261
1345
|
);
|
|
@@ -1457,10 +1541,10 @@ var init_server = __esm({
|
|
|
1457
1541
|
const transport = new StreamableHTTPServerTransport({
|
|
1458
1542
|
sessionIdGenerator: () => randomUUID()
|
|
1459
1543
|
});
|
|
1460
|
-
const server = new McpServer(
|
|
1461
|
-
name: "agentic-relay",
|
|
1462
|
-
|
|
1463
|
-
|
|
1544
|
+
const server = new McpServer(
|
|
1545
|
+
{ name: "agentic-relay", version: "0.12.0" },
|
|
1546
|
+
createMcpServerOptions()
|
|
1547
|
+
);
|
|
1464
1548
|
this.registerTools(server);
|
|
1465
1549
|
transport.onclose = () => {
|
|
1466
1550
|
const sid2 = transport.sessionId;
|
|
@@ -4411,7 +4495,7 @@ function createVersionCommand(registry2) {
|
|
|
4411
4495
|
description: "Show relay and backend versions"
|
|
4412
4496
|
},
|
|
4413
4497
|
async run() {
|
|
4414
|
-
const relayVersion = "0.
|
|
4498
|
+
const relayVersion = "0.12.0";
|
|
4415
4499
|
console.log(`agentic-relay v${relayVersion}`);
|
|
4416
4500
|
console.log("");
|
|
4417
4501
|
console.log("Backends:");
|
|
@@ -4761,7 +4845,7 @@ void configManager.getConfig().then((config) => {
|
|
|
4761
4845
|
var main = defineCommand10({
|
|
4762
4846
|
meta: {
|
|
4763
4847
|
name: "relay",
|
|
4764
|
-
version: "0.
|
|
4848
|
+
version: "0.12.0",
|
|
4765
4849
|
description: "Unified CLI proxy for Claude Code, Codex CLI, and Gemini CLI"
|
|
4766
4850
|
},
|
|
4767
4851
|
subCommands: {
|
package/package.json
CHANGED