@rk0429/agentic-relay 0.14.0 → 0.15.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 +80 -12
  2. package/package.json +1 -1
package/dist/relay.mjs CHANGED
@@ -446,6 +446,7 @@ function inferFailureReason(stderr, stdout, sdkErrorMetadata) {
446
446
  const combined = `${stderr} ${stdout}`.toLowerCase();
447
447
  if (combined.includes("timed out") || combined.includes("timeout")) return "timeout";
448
448
  if (combined.includes("max turns") || combined.includes("max_turns") || combined.includes("turn limit")) return "max_turns_exhausted";
449
+ if (combined.includes("429") || combined.includes("capacity_exhausted") || combined.includes("model_capacity_exhausted") || combined.includes("ratelimitexceeded") || combined.includes("resource_exhausted")) return "rate_limit";
449
450
  return "adapter_error";
450
451
  }
451
452
  function buildContextFromEnv() {
@@ -617,7 +618,6 @@ ${input.prompt}`;
617
618
  }
618
619
  onProgress?.({ stage: "spawning", percent: 10 });
619
620
  try {
620
- let result;
621
621
  const executePromise = (async () => {
622
622
  if (input.resumeSessionId) {
623
623
  if (!adapter.continueSession) {
@@ -681,7 +681,7 @@ ${input.prompt}`;
681
681
  });
682
682
  }
683
683
  })();
684
- result = await executePromise;
684
+ const result = await executePromise;
685
685
  if (result && "_noSession" in result) {
686
686
  return {
687
687
  sessionId: session.relaySessionId,
@@ -1208,6 +1208,35 @@ var init_types = __esm({
1208
1208
  });
1209
1209
 
1210
1210
  // src/mcp-server/response-formatter.ts
1211
+ function truncateStderr(stderr) {
1212
+ if (!stderr) return stderr;
1213
+ const blocks = stderr.split("\n\n");
1214
+ if (blocks.length > 1) {
1215
+ const seen = /* @__PURE__ */ new Set();
1216
+ const unique = [];
1217
+ let duplicateCount = 0;
1218
+ for (const block of blocks) {
1219
+ const trimmed = block.trim();
1220
+ if (!trimmed) continue;
1221
+ if (seen.has(trimmed)) {
1222
+ duplicateCount++;
1223
+ } else {
1224
+ seen.add(trimmed);
1225
+ unique.push(block);
1226
+ }
1227
+ }
1228
+ if (duplicateCount > 0) {
1229
+ stderr = unique.join("\n\n") + `
1230
+ [${duplicateCount} duplicate block(s) removed]`;
1231
+ }
1232
+ }
1233
+ if (stderr.length > STDERR_MAX_LENGTH) {
1234
+ const totalLength = stderr.length;
1235
+ stderr = stderr.slice(0, STDERR_MAX_LENGTH) + `
1236
+ [truncated, ${totalLength} total chars]`;
1237
+ }
1238
+ return stderr;
1239
+ }
1211
1240
  function formatSpawnAgentResponse(result) {
1212
1241
  const isError = result.exitCode !== 0;
1213
1242
  let text;
@@ -1216,7 +1245,7 @@ function formatSpawnAgentResponse(result) {
1216
1245
  text = `FAILED (exit ${result.exitCode}${reasonPart})`;
1217
1246
  if (result.stderr) {
1218
1247
  text += `
1219
- ${result.stderr}`;
1248
+ ${truncateStderr(result.stderr)}`;
1220
1249
  }
1221
1250
  } else {
1222
1251
  text = `Session: ${result.sessionId}
@@ -1256,7 +1285,7 @@ function formatParallelResponse(result) {
1256
1285
  } else {
1257
1286
  const reasonPart = r.failureReason ? `, reason: ${r.failureReason}` : "";
1258
1287
  parts.push(`--- Agent ${r.index}${labelPart} FAILED (${backend}, ${duration}${reasonPart}) ---`);
1259
- parts.push(r.stderr || r.error || "(no output)");
1288
+ parts.push(truncateStderr(r.stderr || r.error || "") || "(no output)");
1260
1289
  }
1261
1290
  parts.push("");
1262
1291
  }
@@ -1265,9 +1294,11 @@ ${JSON.stringify(result, null, 2)}
1265
1294
  </metadata>`);
1266
1295
  return { text: parts.join("\n"), isError };
1267
1296
  }
1297
+ var STDERR_MAX_LENGTH;
1268
1298
  var init_response_formatter = __esm({
1269
1299
  "src/mcp-server/response-formatter.ts"() {
1270
1300
  "use strict";
1301
+ STDERR_MAX_LENGTH = 2e3;
1271
1302
  }
1272
1303
  });
1273
1304
 
@@ -1322,7 +1353,7 @@ var init_server = __esm({
1322
1353
  this.guard = new RecursionGuard(guardConfig);
1323
1354
  this.backendSelector = new BackendSelector();
1324
1355
  this.server = new McpServer(
1325
- { name: "agentic-relay", version: "0.14.0" },
1356
+ { name: "agentic-relay", version: "0.15.0" },
1326
1357
  createMcpServerOptions()
1327
1358
  );
1328
1359
  this.registerTools(this.server);
@@ -1684,7 +1715,7 @@ var init_server = __esm({
1684
1715
  sessionIdGenerator: () => randomUUID()
1685
1716
  });
1686
1717
  const server = new McpServer(
1687
- { name: "agentic-relay", version: "0.14.0" },
1718
+ { name: "agentic-relay", version: "0.15.0" },
1688
1719
  createMcpServerOptions()
1689
1720
  );
1690
1721
  this.registerTools(server);
@@ -2856,6 +2887,12 @@ init_logger();
2856
2887
  import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
2857
2888
  import { homedir as homedir3 } from "os";
2858
2889
  import { join as join3, dirname as dirname3 } from "path";
2890
+ var GEMINI_FALLBACK_CHAIN = [
2891
+ "gemini-3.1-pro-preview",
2892
+ "gemini-2.5-pro",
2893
+ "gemini-2.5-flash"
2894
+ ];
2895
+ var RATE_LIMIT_PATTERN = /429|MODEL_CAPACITY_EXHAUSTED|rateLimitExceeded|RESOURCE_EXHAUSTED/i;
2859
2896
  var GeminiAdapter = class extends BaseAdapter {
2860
2897
  id = "gemini";
2861
2898
  command = "gemini";
@@ -2868,9 +2905,8 @@ var GeminiAdapter = class extends BaseAdapter {
2868
2905
  const authenticated = hasApiKey || hasGoogleAdc;
2869
2906
  if (!authenticated) {
2870
2907
  return {
2871
- // Optimistic fallback: Gemini may still authenticate via ADC at runtime.
2872
- authenticated: true,
2873
- message: "Gemini authentication status unknown - ADC may be available at runtime"
2908
+ authenticated: false,
2909
+ message: "Gemini authentication not configured. Set GEMINI_API_KEY or configure Google ADC."
2874
2910
  };
2875
2911
  }
2876
2912
  return { authenticated };
@@ -2918,10 +2954,39 @@ ${prompt}`;
2918
2954
  }
2919
2955
  return prompt;
2920
2956
  }
2957
+ buildEnv(flags) {
2958
+ const env = {};
2959
+ for (const [key, value] of Object.entries(process.env)) {
2960
+ if (value !== void 0) {
2961
+ env[key] = value;
2962
+ }
2963
+ }
2964
+ if (flags.mcpContext) {
2965
+ env.RELAY_TRACE_ID = flags.mcpContext.traceId;
2966
+ env.RELAY_PARENT_SESSION_ID = flags.mcpContext.parentSessionId;
2967
+ env.RELAY_DEPTH = String(flags.mcpContext.depth);
2968
+ }
2969
+ return env;
2970
+ }
2921
2971
  async execute(flags) {
2922
2972
  if (!flags.prompt) {
2923
2973
  throw new Error("execute requires a prompt (-p flag)");
2924
2974
  }
2975
+ if (flags.model) {
2976
+ return this.executeOnce(flags);
2977
+ }
2978
+ let lastResult;
2979
+ for (const model of GEMINI_FALLBACK_CHAIN) {
2980
+ const result = await this.executeOnce({ ...flags, model });
2981
+ if (result.exitCode === 0 || !RATE_LIMIT_PATTERN.test(result.stderr)) {
2982
+ return result;
2983
+ }
2984
+ logger.warn(`Gemini model ${model} rate limited, trying next fallback...`);
2985
+ lastResult = result;
2986
+ }
2987
+ return lastResult;
2988
+ }
2989
+ async executeOnce(flags) {
2925
2990
  const effectivePrompt = this.buildEffectivePrompt(flags);
2926
2991
  const args = [];
2927
2992
  if (flags.model) {
@@ -2934,7 +2999,10 @@ ${prompt}`;
2934
2999
  args.push("--verbose");
2935
3000
  }
2936
3001
  args.push("-p", effectivePrompt);
2937
- return this.processManager.execute(this.command, args);
3002
+ return this.processManager.execute(this.command, args, {
3003
+ stdinMode: "ignore",
3004
+ env: this.buildEnv(flags)
3005
+ });
2938
3006
  }
2939
3007
  async resumeSession(sessionId, flags) {
2940
3008
  const args = [];
@@ -4658,7 +4726,7 @@ function createVersionCommand(registry2) {
4658
4726
  description: "Show relay and backend versions"
4659
4727
  },
4660
4728
  async run() {
4661
- const relayVersion = "0.14.0";
4729
+ const relayVersion = "0.15.0";
4662
4730
  console.log(`agentic-relay v${relayVersion}`);
4663
4731
  console.log("");
4664
4732
  console.log("Backends:");
@@ -5008,7 +5076,7 @@ void configManager.getConfig().then((config) => {
5008
5076
  var main = defineCommand10({
5009
5077
  meta: {
5010
5078
  name: "relay",
5011
- version: "0.14.0",
5079
+ version: "0.15.0",
5012
5080
  description: "Unified CLI proxy for Claude Code, Codex CLI, and Gemini CLI"
5013
5081
  },
5014
5082
  subCommands: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rk0429/agentic-relay",
3
- "version": "0.14.0",
3
+ "version": "0.15.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",