@rk0429/agentic-relay 0.10.0 → 0.11.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 +66 -26
- package/package.json +1 -1
package/dist/relay.mjs
CHANGED
|
@@ -55,8 +55,8 @@ var init_recursion_guard = __esm({
|
|
|
55
55
|
RecursionGuard = class _RecursionGuard {
|
|
56
56
|
constructor(config = {
|
|
57
57
|
maxDepth: 5,
|
|
58
|
-
maxCallsPerSession:
|
|
59
|
-
timeoutSec:
|
|
58
|
+
maxCallsPerSession: 50,
|
|
59
|
+
timeoutSec: 1800
|
|
60
60
|
}) {
|
|
61
61
|
this.config = config;
|
|
62
62
|
}
|
|
@@ -110,10 +110,15 @@ var init_recursion_guard = __esm({
|
|
|
110
110
|
reason: `Max calls per session exceeded: ${currentCount} >= ${this.config.maxCallsPerSession}`
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
|
-
if (this.detectLoop(
|
|
113
|
+
if (this.detectLoop(
|
|
114
|
+
context.traceId,
|
|
115
|
+
context.backend,
|
|
116
|
+
context.promptHash,
|
|
117
|
+
context.taskType
|
|
118
|
+
)) {
|
|
114
119
|
return {
|
|
115
120
|
allowed: false,
|
|
116
|
-
reason: `Loop detected: same (backend=${context.backend}, promptHash=${context.promptHash}) appeared
|
|
121
|
+
reason: `Loop detected: same (backend=${context.backend}, taskType=${context.taskType ?? ""}, promptHash=${context.promptHash}) appeared 5+ times in trace ${context.traceId}`
|
|
117
122
|
};
|
|
118
123
|
}
|
|
119
124
|
return { allowed: true };
|
|
@@ -127,7 +132,7 @@ var init_recursion_guard = __esm({
|
|
|
127
132
|
} else {
|
|
128
133
|
this.callCounts.set(context.traceId, { count: 1, createdAt: Date.now() });
|
|
129
134
|
}
|
|
130
|
-
const key = `${context.backend}:${context.promptHash}`;
|
|
135
|
+
const key = `${context.backend}:${context.taskType ?? ""}:${context.promptHash}`;
|
|
131
136
|
const hashEntry = this.promptHashes.get(context.traceId);
|
|
132
137
|
if (hashEntry) {
|
|
133
138
|
hashEntry.hashes.push(key);
|
|
@@ -135,12 +140,12 @@ var init_recursion_guard = __esm({
|
|
|
135
140
|
this.promptHashes.set(context.traceId, { hashes: [key], createdAt: Date.now() });
|
|
136
141
|
}
|
|
137
142
|
}
|
|
138
|
-
/** Detect if the same (backend + promptHash) combination has appeared
|
|
139
|
-
detectLoop(traceId, backend, promptHash) {
|
|
140
|
-
const key = `${backend}:${promptHash}`;
|
|
143
|
+
/** Detect if the same (backend + taskType + promptHash) combination has appeared 5+ times */
|
|
144
|
+
detectLoop(traceId, backend, promptHash, taskType) {
|
|
145
|
+
const key = `${backend}:${taskType ?? ""}:${promptHash}`;
|
|
141
146
|
const hashes = this.promptHashes.get(traceId)?.hashes ?? [];
|
|
142
147
|
const count = hashes.filter((h) => h === key).length;
|
|
143
|
-
return count >=
|
|
148
|
+
return count >= 5;
|
|
144
149
|
}
|
|
145
150
|
/** Get current config (for testing/inspection) */
|
|
146
151
|
getConfig() {
|
|
@@ -344,7 +349,8 @@ async function executeSpawnAgent(input, registry2, sessionManager2, guard, hooks
|
|
|
344
349
|
traceId: envContext.traceId,
|
|
345
350
|
depth: envContext.depth,
|
|
346
351
|
backend: effectiveBackend,
|
|
347
|
-
promptHash
|
|
352
|
+
promptHash,
|
|
353
|
+
taskType: input.taskType
|
|
348
354
|
};
|
|
349
355
|
const guardResult = guard.canSpawn(context);
|
|
350
356
|
if (!guardResult.allowed) {
|
|
@@ -490,7 +496,34 @@ ${input.prompt}`;
|
|
|
490
496
|
_failureReason: "session_continuation_unsupported"
|
|
491
497
|
};
|
|
492
498
|
}
|
|
493
|
-
|
|
499
|
+
let effectiveNativeSessionId;
|
|
500
|
+
if (input.resumeSessionId.startsWith("relay-")) {
|
|
501
|
+
const existingSession = await sessionManager2.get(input.resumeSessionId);
|
|
502
|
+
if (!existingSession) {
|
|
503
|
+
return {
|
|
504
|
+
exitCode: 1,
|
|
505
|
+
stdout: "",
|
|
506
|
+
stderr: `Session not found: ${input.resumeSessionId}`,
|
|
507
|
+
_noSession: true,
|
|
508
|
+
_failureReason: "session_not_found"
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
if (!existingSession.nativeSessionId) {
|
|
512
|
+
return {
|
|
513
|
+
exitCode: 1,
|
|
514
|
+
stdout: "",
|
|
515
|
+
stderr: `Session ${input.resumeSessionId} has no native session ID (session may have failed before completing)`,
|
|
516
|
+
_noSession: true,
|
|
517
|
+
_failureReason: "session_not_found"
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
effectiveNativeSessionId = existingSession.nativeSessionId;
|
|
521
|
+
} else {
|
|
522
|
+
effectiveNativeSessionId = input.resumeSessionId;
|
|
523
|
+
}
|
|
524
|
+
return adapter.continueSession(effectiveNativeSessionId, effectivePrompt, {
|
|
525
|
+
...input.maxTurns !== void 0 ? { maxTurns: input.maxTurns } : {}
|
|
526
|
+
});
|
|
494
527
|
} else {
|
|
495
528
|
let mcpServers;
|
|
496
529
|
if (childHttpUrl) {
|
|
@@ -550,7 +583,10 @@ ${input.prompt}`;
|
|
|
550
583
|
guard.recordSpawn(context);
|
|
551
584
|
const status = result.exitCode === 0 ? "completed" : "error";
|
|
552
585
|
const failureReason = result.exitCode !== 0 ? inferFailureReason(result.stderr, result.stdout) : void 0;
|
|
553
|
-
await sessionManager2.update(session.relaySessionId, {
|
|
586
|
+
await sessionManager2.update(session.relaySessionId, {
|
|
587
|
+
status,
|
|
588
|
+
...result.nativeSessionId ? { nativeSessionId: result.nativeSessionId } : {}
|
|
589
|
+
});
|
|
554
590
|
const completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
555
591
|
const metadata = {
|
|
556
592
|
durationMs: new Date(completedAt).getTime() - new Date(spawnStartedAt).getTime(),
|
|
@@ -1115,7 +1151,7 @@ var init_server = __esm({
|
|
|
1115
1151
|
this.backendSelector = new BackendSelector();
|
|
1116
1152
|
this.server = new McpServer({
|
|
1117
1153
|
name: "agentic-relay",
|
|
1118
|
-
version: "0.
|
|
1154
|
+
version: "0.11.0"
|
|
1119
1155
|
});
|
|
1120
1156
|
this.registerTools(this.server);
|
|
1121
1157
|
}
|
|
@@ -1423,7 +1459,7 @@ var init_server = __esm({
|
|
|
1423
1459
|
});
|
|
1424
1460
|
const server = new McpServer({
|
|
1425
1461
|
name: "agentic-relay",
|
|
1426
|
-
version: "0.
|
|
1462
|
+
version: "0.11.0"
|
|
1427
1463
|
});
|
|
1428
1464
|
this.registerTools(server);
|
|
1429
1465
|
transport.onclose = () => {
|
|
@@ -1639,7 +1675,7 @@ var BaseAdapter = class _BaseAdapter {
|
|
|
1639
1675
|
}
|
|
1640
1676
|
return result.stdout.trim();
|
|
1641
1677
|
}
|
|
1642
|
-
async continueSession(_nativeSessionId, _prompt) {
|
|
1678
|
+
async continueSession(_nativeSessionId, _prompt, _options) {
|
|
1643
1679
|
return {
|
|
1644
1680
|
exitCode: 1,
|
|
1645
1681
|
stdout: "",
|
|
@@ -1996,31 +2032,33 @@ var ClaudeAdapter = class extends BaseAdapter {
|
|
|
1996
2032
|
if (timer !== void 0) clearTimeout(timer);
|
|
1997
2033
|
}
|
|
1998
2034
|
}
|
|
1999
|
-
async continueSession(nativeSessionId, prompt) {
|
|
2035
|
+
async continueSession(nativeSessionId, prompt, options) {
|
|
2000
2036
|
const timeoutMs = resolveClaudeSdkTimeoutMs();
|
|
2001
2037
|
const abortController = new AbortController();
|
|
2002
2038
|
const timer = timeoutMs !== void 0 ? setTimeout(() => abortController.abort(), timeoutMs) : void 0;
|
|
2003
2039
|
try {
|
|
2004
2040
|
const { query } = await loadClaudeSDK();
|
|
2005
2041
|
const permissionMode = this.getPermissionMode();
|
|
2006
|
-
const
|
|
2042
|
+
const queryOptions = {
|
|
2007
2043
|
abortController,
|
|
2008
2044
|
resume: nativeSessionId,
|
|
2009
|
-
maxTurns: 1,
|
|
2045
|
+
maxTurns: options?.maxTurns ?? 1,
|
|
2010
2046
|
cwd: process.cwd(),
|
|
2011
2047
|
strictMcpConfig: true
|
|
2012
2048
|
};
|
|
2013
2049
|
if (permissionMode === "bypassPermissions") {
|
|
2014
|
-
|
|
2015
|
-
|
|
2050
|
+
queryOptions.permissionMode = "bypassPermissions";
|
|
2051
|
+
queryOptions.allowDangerouslySkipPermissions = true;
|
|
2016
2052
|
}
|
|
2017
2053
|
const q = query({
|
|
2018
2054
|
prompt,
|
|
2019
|
-
options
|
|
2055
|
+
options: queryOptions
|
|
2020
2056
|
});
|
|
2021
2057
|
let resultText = "";
|
|
2058
|
+
let sessionId = "";
|
|
2022
2059
|
for await (const message of q) {
|
|
2023
2060
|
if (message.type === "result") {
|
|
2061
|
+
sessionId = message.session_id;
|
|
2024
2062
|
if (message.subtype === "success") {
|
|
2025
2063
|
resultText = message.result;
|
|
2026
2064
|
}
|
|
@@ -2029,7 +2067,8 @@ var ClaudeAdapter = class extends BaseAdapter {
|
|
|
2029
2067
|
return {
|
|
2030
2068
|
exitCode: 0,
|
|
2031
2069
|
stdout: resultText,
|
|
2032
|
-
stderr: ""
|
|
2070
|
+
stderr: "",
|
|
2071
|
+
...sessionId ? { nativeSessionId: sessionId } : {}
|
|
2033
2072
|
};
|
|
2034
2073
|
} catch (error) {
|
|
2035
2074
|
if (abortController.signal.aborted) {
|
|
@@ -2459,7 +2498,7 @@ ${prompt}`;
|
|
|
2459
2498
|
};
|
|
2460
2499
|
}
|
|
2461
2500
|
}
|
|
2462
|
-
async continueSession(nativeSessionId, prompt) {
|
|
2501
|
+
async continueSession(nativeSessionId, prompt, _options) {
|
|
2463
2502
|
try {
|
|
2464
2503
|
const { Codex } = await loadCodexSDK();
|
|
2465
2504
|
const codex = new Codex();
|
|
@@ -2471,7 +2510,8 @@ ${prompt}`;
|
|
|
2471
2510
|
return {
|
|
2472
2511
|
exitCode: 0,
|
|
2473
2512
|
stdout: result.finalResponse,
|
|
2474
|
-
stderr: ""
|
|
2513
|
+
stderr: "",
|
|
2514
|
+
nativeSessionId
|
|
2475
2515
|
};
|
|
2476
2516
|
} catch (error) {
|
|
2477
2517
|
return {
|
|
@@ -4371,7 +4411,7 @@ function createVersionCommand(registry2) {
|
|
|
4371
4411
|
description: "Show relay and backend versions"
|
|
4372
4412
|
},
|
|
4373
4413
|
async run() {
|
|
4374
|
-
const relayVersion = "0.
|
|
4414
|
+
const relayVersion = "0.11.0";
|
|
4375
4415
|
console.log(`agentic-relay v${relayVersion}`);
|
|
4376
4416
|
console.log("");
|
|
4377
4417
|
console.log("Backends:");
|
|
@@ -4721,7 +4761,7 @@ void configManager.getConfig().then((config) => {
|
|
|
4721
4761
|
var main = defineCommand10({
|
|
4722
4762
|
meta: {
|
|
4723
4763
|
name: "relay",
|
|
4724
|
-
version: "0.
|
|
4764
|
+
version: "0.11.0",
|
|
4725
4765
|
description: "Unified CLI proxy for Claude Code, Codex CLI, and Gemini CLI"
|
|
4726
4766
|
},
|
|
4727
4767
|
subCommands: {
|
package/package.json
CHANGED