@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.
Files changed (2) hide show
  1. package/dist/relay.mjs +72 -67
  2. 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: preferredBackend > agentType mapping > taskType mapping > default (claude)."
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().optional().describe(
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 3, after preferredBackend and agentType). Mapping: code-writing\u2192codex, code-review\u2192claude, document-writing\u2192claude, document-review\u2192codex, research\u2192codex, mixed\u2192claude."
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, preferredBackend, agentType, taskType } = context;
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.4.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: preferredBackend > 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.",
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.4.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.4.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.4.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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rk0429/agentic-relay",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "Unified CLI proxy for Claude Code, Codex CLI, and Gemini CLI with MCP-based multi-layer sub-agent orchestration",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",