@rk0429/agentic-relay 0.14.1 → 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 +60 -8
  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.1" },
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.1" },
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";
@@ -2935,6 +2972,21 @@ ${prompt}`;
2935
2972
  if (!flags.prompt) {
2936
2973
  throw new Error("execute requires a prompt (-p flag)");
2937
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) {
2938
2990
  const effectivePrompt = this.buildEffectivePrompt(flags);
2939
2991
  const args = [];
2940
2992
  if (flags.model) {
@@ -4674,7 +4726,7 @@ function createVersionCommand(registry2) {
4674
4726
  description: "Show relay and backend versions"
4675
4727
  },
4676
4728
  async run() {
4677
- const relayVersion = "0.14.1";
4729
+ const relayVersion = "0.15.0";
4678
4730
  console.log(`agentic-relay v${relayVersion}`);
4679
4731
  console.log("");
4680
4732
  console.log("Backends:");
@@ -5024,7 +5076,7 @@ void configManager.getConfig().then((config) => {
5024
5076
  var main = defineCommand10({
5025
5077
  meta: {
5026
5078
  name: "relay",
5027
- version: "0.14.1",
5079
+ version: "0.15.0",
5028
5080
  description: "Unified CLI proxy for Claude Code, Codex CLI, and Gemini CLI"
5029
5081
  },
5030
5082
  subCommands: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rk0429/agentic-relay",
3
- "version": "0.14.1",
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",