@rk0429/agentic-relay 1.4.1 → 1.5.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 +72 -67
- package/package.json +1 -1
package/dist/relay.mjs
CHANGED
|
@@ -160,6 +160,47 @@ var init_metadata_validation = __esm({
|
|
|
160
160
|
}
|
|
161
161
|
});
|
|
162
162
|
|
|
163
|
+
// src/infrastructure/version-check.ts
|
|
164
|
+
async function getLatestNpmVersion(packageName) {
|
|
165
|
+
try {
|
|
166
|
+
const response = await fetch(
|
|
167
|
+
`https://registry.npmjs.org/${packageName}/latest`,
|
|
168
|
+
{
|
|
169
|
+
headers: { Accept: "application/json" },
|
|
170
|
+
signal: AbortSignal.timeout(5e3)
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
if (!response.ok) {
|
|
174
|
+
logger.debug(
|
|
175
|
+
`npm registry returned ${response.status} for ${packageName}`
|
|
176
|
+
);
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
const data = await response.json();
|
|
180
|
+
return data.version ?? null;
|
|
181
|
+
} catch (error) {
|
|
182
|
+
logger.debug(
|
|
183
|
+
`Failed to check npm registry: ${error instanceof Error ? error.message : String(error)}`
|
|
184
|
+
);
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function compareSemver(a, b) {
|
|
189
|
+
const partsA = a.replace(/^v/, "").split(".").map(Number);
|
|
190
|
+
const partsB = b.replace(/^v/, "").split(".").map(Number);
|
|
191
|
+
for (let i = 0; i < 3; i++) {
|
|
192
|
+
const diff = (partsA[i] ?? 0) - (partsB[i] ?? 0);
|
|
193
|
+
if (diff !== 0) return diff;
|
|
194
|
+
}
|
|
195
|
+
return 0;
|
|
196
|
+
}
|
|
197
|
+
var init_version_check = __esm({
|
|
198
|
+
"src/infrastructure/version-check.ts"() {
|
|
199
|
+
"use strict";
|
|
200
|
+
init_logger();
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
|
|
163
204
|
// src/mcp-server/deferred-cleanup-task-store.ts
|
|
164
205
|
import { isTerminal } from "@modelcontextprotocol/sdk/experimental/tasks/interfaces.js";
|
|
165
206
|
import { randomBytes } from "crypto";
|
|
@@ -1035,7 +1076,6 @@ async function executeSpawnAgent(input, registry2, sessionManager2, guard, hooks
|
|
|
1035
1076
|
const availableBackends = registry2.listIds();
|
|
1036
1077
|
const selectionContext = {
|
|
1037
1078
|
availableBackends,
|
|
1038
|
-
preferredBackend: input.preferredBackend,
|
|
1039
1079
|
agentType: input.agent,
|
|
1040
1080
|
taskType: input.taskType
|
|
1041
1081
|
};
|
|
@@ -1354,7 +1394,6 @@ ${input.prompt}`;
|
|
|
1354
1394
|
const metadata = {
|
|
1355
1395
|
durationMs: new Date(completedAt).getTime() - new Date(spawnStartedAt).getTime(),
|
|
1356
1396
|
selectedBackend: effectiveBackend,
|
|
1357
|
-
...input.preferredBackend ? { requestedBackend: input.preferredBackend } : {},
|
|
1358
1397
|
selectionReason,
|
|
1359
1398
|
startedAt: spawnStartedAt,
|
|
1360
1399
|
completedAt,
|
|
@@ -1594,12 +1633,12 @@ var init_spawn_agent = __esm({
|
|
|
1594
1633
|
init_metadata_validation();
|
|
1595
1634
|
spawnAgentInputSchema = z2.object({
|
|
1596
1635
|
fallbackBackend: z2.enum(["claude", "codex", "gemini"]).optional().describe(
|
|
1597
|
-
"Optional fallback backend. Used only when BackendSelector is not active or cannot determine a backend. When BackendSelector is active, backend is auto-selected by priority:
|
|
1636
|
+
"Optional fallback backend. Used only when BackendSelector is not active or cannot determine a backend. When BackendSelector is active, backend is auto-selected by priority: agentType mapping > taskType mapping > default (claude)."
|
|
1598
1637
|
),
|
|
1599
1638
|
prompt: z2.string().describe(
|
|
1600
1639
|
"The task instruction for the sub-agent. Be specific and include all necessary context for autonomous execution."
|
|
1601
1640
|
),
|
|
1602
|
-
agent: z2.string().
|
|
1641
|
+
agent: z2.string().describe(
|
|
1603
1642
|
"Agent type identifier (e.g., 'coder', 'researcher', 'documenter', 'software-engineer'). Affects backend auto-selection: coder/researcher/software-engineer/devops-engineer\u2192codex, documenter\u2192claude. Also used to resolve agentDefinition files from .agents/agents/<agent>.md."
|
|
1604
1643
|
),
|
|
1605
1644
|
systemPrompt: z2.string().optional().describe(
|
|
@@ -1618,11 +1657,8 @@ var init_spawn_agent = __esm({
|
|
|
1618
1657
|
agentDefinition: z2.object({
|
|
1619
1658
|
definitionPath: z2.string().describe("Path to the agent definition .md file (e.g., '.agents/agents/coder.md')")
|
|
1620
1659
|
}).optional().describe("Agent definition file to inject into the sub-agent's system prompt as <agent-definition> context."),
|
|
1621
|
-
preferredBackend: z2.enum(["claude", "codex", "gemini"]).optional().describe(
|
|
1622
|
-
"Preferred backend override. Takes highest priority in backend selection. Use when the automatic agentType/taskType mapping does not match your needs."
|
|
1623
|
-
),
|
|
1624
1660
|
taskType: z2.enum(["code-writing", "code-review", "document-writing", "document-review", "research", "mixed"]).optional().describe(
|
|
1625
|
-
"Task type hint for automatic backend selection (priority
|
|
1661
|
+
"Task type hint for automatic backend selection (priority 2, after agentType). Mapping: code-writing\u2192codex, code-review\u2192claude, document-writing\u2192claude, document-review\u2192codex, research\u2192codex, mixed\u2192claude."
|
|
1626
1662
|
),
|
|
1627
1663
|
taskInstructionPath: z2.string().optional().describe(
|
|
1628
1664
|
"Path to a file containing task instructions. Content is prepended to the prompt. Path is resolved relative to the project root and validated against path traversal."
|
|
@@ -2088,13 +2124,10 @@ var init_backend_selector = __esm({
|
|
|
2088
2124
|
return this.selectBackendWithReason(context).backend;
|
|
2089
2125
|
}
|
|
2090
2126
|
selectBackendWithReason(context) {
|
|
2091
|
-
const { availableBackends,
|
|
2127
|
+
const { availableBackends, agentType, taskType } = context;
|
|
2092
2128
|
if (availableBackends.length === 0) {
|
|
2093
2129
|
throw new Error("No backends available");
|
|
2094
2130
|
}
|
|
2095
|
-
if (preferredBackend && availableBackends.includes(preferredBackend)) {
|
|
2096
|
-
return { backend: preferredBackend, reason: "preferredBackend" };
|
|
2097
|
-
}
|
|
2098
2131
|
if (agentType) {
|
|
2099
2132
|
const mapped = this.agentToBackendMap[agentType];
|
|
2100
2133
|
if (mapped && availableBackends.includes(mapped)) {
|
|
@@ -2330,6 +2363,7 @@ var init_server = __esm({
|
|
|
2330
2363
|
init_backend_selector();
|
|
2331
2364
|
init_metadata_validation();
|
|
2332
2365
|
init_logger();
|
|
2366
|
+
init_version_check();
|
|
2333
2367
|
init_types();
|
|
2334
2368
|
init_response_formatter();
|
|
2335
2369
|
spawnAgentsParallelInputShape = {
|
|
@@ -2378,7 +2412,7 @@ var init_server = __esm({
|
|
|
2378
2412
|
this.agentEventStore
|
|
2379
2413
|
);
|
|
2380
2414
|
this.server = new McpServer(
|
|
2381
|
-
{ name: "agentic-relay", version: "1.
|
|
2415
|
+
{ name: "agentic-relay", version: "1.5.0" },
|
|
2382
2416
|
createMcpServerOptions()
|
|
2383
2417
|
);
|
|
2384
2418
|
this.registerTools(this.server);
|
|
@@ -2516,7 +2550,7 @@ var init_server = __esm({
|
|
|
2516
2550
|
server.experimental.tasks.registerToolTask(
|
|
2517
2551
|
"spawn_agent",
|
|
2518
2552
|
{
|
|
2519
|
-
description: "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:
|
|
2553
|
+
description: "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). Use 'agentDefinition' to inject an agent .md file, 'skillContext' for a SKILL.md, or 'systemPrompt' for custom instructions.",
|
|
2520
2554
|
inputSchema: spawnAgentInputSchema.shape,
|
|
2521
2555
|
execution: { taskSupport: "optional" }
|
|
2522
2556
|
},
|
|
@@ -2572,20 +2606,11 @@ var init_server = __esm({
|
|
|
2572
2606
|
failedResults: z7.array(z7.object({
|
|
2573
2607
|
index: z7.number(),
|
|
2574
2608
|
originalInput: spawnAgentInputSchema
|
|
2575
|
-
})).min(1).describe("Array of failed results with their original input configurations")
|
|
2576
|
-
overrides: z7.object({
|
|
2577
|
-
preferredBackend: z7.enum(["claude", "codex", "gemini"]).optional()
|
|
2578
|
-
}).optional().describe("Parameter overrides applied to all retried agents")
|
|
2609
|
+
})).min(1).describe("Array of failed results with their original input configurations")
|
|
2579
2610
|
},
|
|
2580
2611
|
async (params) => {
|
|
2581
2612
|
try {
|
|
2582
|
-
const agents = params.failedResults.map((r) => {
|
|
2583
|
-
const input = { ...r.originalInput };
|
|
2584
|
-
if (params.overrides) {
|
|
2585
|
-
if (params.overrides.preferredBackend !== void 0) input.preferredBackend = params.overrides.preferredBackend;
|
|
2586
|
-
}
|
|
2587
|
-
return input;
|
|
2588
|
-
});
|
|
2613
|
+
const agents = params.failedResults.map((r) => ({ ...r.originalInput }));
|
|
2589
2614
|
const result = await executeSpawnAgentsParallel(
|
|
2590
2615
|
agents,
|
|
2591
2616
|
this.registry,
|
|
@@ -2782,8 +2807,25 @@ var init_server = __esm({
|
|
|
2782
2807
|
}
|
|
2783
2808
|
);
|
|
2784
2809
|
}
|
|
2810
|
+
async checkForUpdates(currentVersion) {
|
|
2811
|
+
try {
|
|
2812
|
+
const latest = await getLatestNpmVersion("@rk0429/agentic-relay");
|
|
2813
|
+
if (latest && compareSemver(latest, currentVersion) > 0) {
|
|
2814
|
+
logger.warn(
|
|
2815
|
+
`A newer version of @rk0429/agentic-relay is available: ${latest} (current: ${currentVersion})`
|
|
2816
|
+
);
|
|
2817
|
+
logger.warn(
|
|
2818
|
+
" Run: npm install -g @rk0429/agentic-relay@latest"
|
|
2819
|
+
);
|
|
2820
|
+
}
|
|
2821
|
+
} catch {
|
|
2822
|
+
}
|
|
2823
|
+
}
|
|
2785
2824
|
async start(options) {
|
|
2786
2825
|
const transportType = options?.transport ?? "stdio";
|
|
2826
|
+
if (options?.currentVersion) {
|
|
2827
|
+
void this.checkForUpdates(options.currentVersion);
|
|
2828
|
+
}
|
|
2787
2829
|
if (transportType === "stdio") {
|
|
2788
2830
|
redirectToStderr();
|
|
2789
2831
|
logger.info("Starting agentic-relay MCP server (stdio transport)...");
|
|
@@ -2849,7 +2891,7 @@ var init_server = __esm({
|
|
|
2849
2891
|
sessionIdGenerator: () => randomUUID()
|
|
2850
2892
|
});
|
|
2851
2893
|
const server = new McpServer(
|
|
2852
|
-
{ name: "agentic-relay", version: "1.
|
|
2894
|
+
{ name: "agentic-relay", version: "1.5.0" },
|
|
2853
2895
|
createMcpServerOptions()
|
|
2854
2896
|
);
|
|
2855
2897
|
this.registerTools(server);
|
|
@@ -6982,45 +7024,8 @@ function createBackendCommand(backendId, registry2, sessionManager2, hooksEngine
|
|
|
6982
7024
|
|
|
6983
7025
|
// src/commands/update.ts
|
|
6984
7026
|
init_logger();
|
|
7027
|
+
init_version_check();
|
|
6985
7028
|
import { defineCommand as defineCommand2 } from "citty";
|
|
6986
|
-
|
|
6987
|
-
// src/infrastructure/version-check.ts
|
|
6988
|
-
init_logger();
|
|
6989
|
-
async function getLatestNpmVersion(packageName) {
|
|
6990
|
-
try {
|
|
6991
|
-
const response = await fetch(
|
|
6992
|
-
`https://registry.npmjs.org/${packageName}/latest`,
|
|
6993
|
-
{
|
|
6994
|
-
headers: { Accept: "application/json" },
|
|
6995
|
-
signal: AbortSignal.timeout(5e3)
|
|
6996
|
-
}
|
|
6997
|
-
);
|
|
6998
|
-
if (!response.ok) {
|
|
6999
|
-
logger.debug(
|
|
7000
|
-
`npm registry returned ${response.status} for ${packageName}`
|
|
7001
|
-
);
|
|
7002
|
-
return null;
|
|
7003
|
-
}
|
|
7004
|
-
const data = await response.json();
|
|
7005
|
-
return data.version ?? null;
|
|
7006
|
-
} catch (error) {
|
|
7007
|
-
logger.debug(
|
|
7008
|
-
`Failed to check npm registry: ${error instanceof Error ? error.message : String(error)}`
|
|
7009
|
-
);
|
|
7010
|
-
return null;
|
|
7011
|
-
}
|
|
7012
|
-
}
|
|
7013
|
-
function compareSemver(a, b) {
|
|
7014
|
-
const partsA = a.replace(/^v/, "").split(".").map(Number);
|
|
7015
|
-
const partsB = b.replace(/^v/, "").split(".").map(Number);
|
|
7016
|
-
for (let i = 0; i < 3; i++) {
|
|
7017
|
-
const diff = (partsA[i] ?? 0) - (partsB[i] ?? 0);
|
|
7018
|
-
if (diff !== 0) return diff;
|
|
7019
|
-
}
|
|
7020
|
-
return 0;
|
|
7021
|
-
}
|
|
7022
|
-
|
|
7023
|
-
// src/commands/update.ts
|
|
7024
7029
|
var PACKAGE_NAME = "@rk0429/agentic-relay";
|
|
7025
7030
|
var CURRENT_VERSION = "0.4.0";
|
|
7026
7031
|
function createUpdateCommand(registry2) {
|
|
@@ -7325,7 +7330,7 @@ function createMCPCommand(configManager2, registry2, sessionManager2, hooksEngin
|
|
|
7325
7330
|
responseOutputDir,
|
|
7326
7331
|
relayConfig
|
|
7327
7332
|
);
|
|
7328
|
-
await server.start({ transport, port });
|
|
7333
|
+
await server.start({ transport, port, currentVersion: "1.5.0" });
|
|
7329
7334
|
}
|
|
7330
7335
|
})
|
|
7331
7336
|
},
|
|
@@ -7485,7 +7490,7 @@ function createVersionCommand(registry2) {
|
|
|
7485
7490
|
description: "Show relay and backend versions"
|
|
7486
7491
|
},
|
|
7487
7492
|
async run() {
|
|
7488
|
-
const relayVersion = "1.
|
|
7493
|
+
const relayVersion = "1.5.0";
|
|
7489
7494
|
console.log(`agentic-relay v${relayVersion}`);
|
|
7490
7495
|
console.log("");
|
|
7491
7496
|
console.log("Backends:");
|
|
@@ -7882,7 +7887,7 @@ var subCommandNames = /* @__PURE__ */ new Set(["claude", "codex", "gemini", "upd
|
|
|
7882
7887
|
var main = defineCommand11({
|
|
7883
7888
|
meta: {
|
|
7884
7889
|
name: "relay",
|
|
7885
|
-
version: "1.
|
|
7890
|
+
version: "1.5.0",
|
|
7886
7891
|
description: "Unified CLI proxy for Claude Code, Codex CLI, and Gemini CLI"
|
|
7887
7892
|
},
|
|
7888
7893
|
args: {
|
package/package.json
CHANGED