@rk0429/agentic-relay 1.4.2 → 1.6.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 +57 -41
- package/package.json +1 -1
package/dist/relay.mjs
CHANGED
|
@@ -104,7 +104,7 @@ function validateMetadataValue(value, path2, depth) {
|
|
|
104
104
|
}
|
|
105
105
|
function validateMetadata(raw) {
|
|
106
106
|
if (raw === void 0 || raw === null) {
|
|
107
|
-
return {};
|
|
107
|
+
return { taskId: "TASK-000" };
|
|
108
108
|
}
|
|
109
109
|
if (!isPlainObject(raw)) {
|
|
110
110
|
throw new Error("metadata must be a plain object");
|
|
@@ -127,10 +127,13 @@ function validateMetadata(raw) {
|
|
|
127
127
|
validateMetadataValue(value, key, 1);
|
|
128
128
|
}
|
|
129
129
|
const typed = raw;
|
|
130
|
-
if (typed.taskId
|
|
130
|
+
if (typed.taskId === void 0) {
|
|
131
|
+
typed.taskId = "TASK-000";
|
|
132
|
+
}
|
|
133
|
+
if (typeof typed.taskId !== "string") {
|
|
131
134
|
throw new Error("metadata.taskId must be a string");
|
|
132
135
|
}
|
|
133
|
-
if (
|
|
136
|
+
if (!TASK_ID_PATTERN.test(typed.taskId)) {
|
|
134
137
|
throw new Error("metadata.taskId must match ^(TASK|GOAL)-\\d{3,}$");
|
|
135
138
|
}
|
|
136
139
|
if (typed.agentType !== void 0 && typeof typed.agentType !== "string") {
|
|
@@ -1012,6 +1015,13 @@ function buildChildMcpServers(parentMcpServers, childHttpUrl) {
|
|
|
1012
1015
|
return result;
|
|
1013
1016
|
}
|
|
1014
1017
|
function resolveValidatedSessionMetadata(input) {
|
|
1018
|
+
if (input.metadata === void 0 || input.metadata === null) {
|
|
1019
|
+
throw new Error("metadata is required");
|
|
1020
|
+
}
|
|
1021
|
+
const rawTaskId = input.metadata.taskId;
|
|
1022
|
+
if (typeof rawTaskId !== "string" || rawTaskId.trim().length === 0) {
|
|
1023
|
+
throw new Error("metadata.taskId is required");
|
|
1024
|
+
}
|
|
1015
1025
|
const validated = validateMetadata(input.metadata);
|
|
1016
1026
|
const mergedMetadata = { ...validated };
|
|
1017
1027
|
if (mergedMetadata.agentType === void 0 && input.agent !== void 0) {
|
|
@@ -1076,16 +1086,12 @@ async function executeSpawnAgent(input, registry2, sessionManager2, guard, hooks
|
|
|
1076
1086
|
const availableBackends = registry2.listIds();
|
|
1077
1087
|
const selectionContext = {
|
|
1078
1088
|
availableBackends,
|
|
1079
|
-
preferredBackend: input.preferredBackend,
|
|
1080
1089
|
agentType: input.agent,
|
|
1081
1090
|
taskType: input.taskType
|
|
1082
1091
|
};
|
|
1083
1092
|
const selectionResult = backendSelector.selectBackendWithReason(selectionContext);
|
|
1084
1093
|
effectiveBackend = selectionResult.backend;
|
|
1085
1094
|
selectionReason = selectionResult.reason;
|
|
1086
|
-
} else if (input.fallbackBackend) {
|
|
1087
|
-
effectiveBackend = input.fallbackBackend;
|
|
1088
|
-
selectionReason = "fallbackBackend";
|
|
1089
1095
|
} else {
|
|
1090
1096
|
effectiveBackend = "claude";
|
|
1091
1097
|
selectionReason = "default(no-selector)";
|
|
@@ -1227,6 +1233,24 @@ ${skillText}
|
|
|
1227
1233
|
|
|
1228
1234
|
${wrapped}` : wrapped;
|
|
1229
1235
|
}
|
|
1236
|
+
} else {
|
|
1237
|
+
const autoSkillPaths = [
|
|
1238
|
+
`.agents/skills/${input.agent}`,
|
|
1239
|
+
`.claude/skills/${input.agent}`
|
|
1240
|
+
];
|
|
1241
|
+
for (const skillPath of autoSkillPaths) {
|
|
1242
|
+
const skillText = readSkillContext({ skillPath });
|
|
1243
|
+
if (!skillText) {
|
|
1244
|
+
continue;
|
|
1245
|
+
}
|
|
1246
|
+
const wrapped = `<skill-context path="${skillPath}">
|
|
1247
|
+
${skillText}
|
|
1248
|
+
</skill-context>`;
|
|
1249
|
+
enhancedSystemPrompt = enhancedSystemPrompt ? `${enhancedSystemPrompt}
|
|
1250
|
+
|
|
1251
|
+
${wrapped}` : wrapped;
|
|
1252
|
+
break;
|
|
1253
|
+
}
|
|
1230
1254
|
}
|
|
1231
1255
|
if (input.agentDefinition) {
|
|
1232
1256
|
const defText = readAgentDefinition(input.agentDefinition.definitionPath);
|
|
@@ -1236,6 +1260,17 @@ ${defText}
|
|
|
1236
1260
|
</agent-definition>`;
|
|
1237
1261
|
enhancedSystemPrompt = enhancedSystemPrompt ? `${enhancedSystemPrompt}
|
|
1238
1262
|
|
|
1263
|
+
${wrapped}` : wrapped;
|
|
1264
|
+
}
|
|
1265
|
+
} else {
|
|
1266
|
+
const autoDefinitionPath = `.agents/agents/${input.agent}.md`;
|
|
1267
|
+
const defText = readAgentDefinition(autoDefinitionPath);
|
|
1268
|
+
if (defText) {
|
|
1269
|
+
const wrapped = `<agent-definition source="${autoDefinitionPath}">
|
|
1270
|
+
${defText}
|
|
1271
|
+
</agent-definition>`;
|
|
1272
|
+
enhancedSystemPrompt = enhancedSystemPrompt ? `${enhancedSystemPrompt}
|
|
1273
|
+
|
|
1239
1274
|
${wrapped}` : wrapped;
|
|
1240
1275
|
}
|
|
1241
1276
|
}
|
|
@@ -1395,7 +1430,6 @@ ${input.prompt}`;
|
|
|
1395
1430
|
const metadata = {
|
|
1396
1431
|
durationMs: new Date(completedAt).getTime() - new Date(spawnStartedAt).getTime(),
|
|
1397
1432
|
selectedBackend: effectiveBackend,
|
|
1398
|
-
...input.preferredBackend ? { requestedBackend: input.preferredBackend } : {},
|
|
1399
1433
|
selectionReason,
|
|
1400
1434
|
startedAt: spawnStartedAt,
|
|
1401
1435
|
completedAt,
|
|
@@ -1634,13 +1668,10 @@ var init_spawn_agent = __esm({
|
|
|
1634
1668
|
init_logger();
|
|
1635
1669
|
init_metadata_validation();
|
|
1636
1670
|
spawnAgentInputSchema = z2.object({
|
|
1637
|
-
fallbackBackend: z2.enum(["claude", "codex", "gemini"]).optional().describe(
|
|
1638
|
-
"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)."
|
|
1639
|
-
),
|
|
1640
1671
|
prompt: z2.string().describe(
|
|
1641
1672
|
"The task instruction for the sub-agent. Be specific and include all necessary context for autonomous execution."
|
|
1642
1673
|
),
|
|
1643
|
-
agent: z2.string().
|
|
1674
|
+
agent: z2.string().describe(
|
|
1644
1675
|
"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."
|
|
1645
1676
|
),
|
|
1646
1677
|
systemPrompt: z2.string().optional().describe(
|
|
@@ -1659,23 +1690,20 @@ var init_spawn_agent = __esm({
|
|
|
1659
1690
|
agentDefinition: z2.object({
|
|
1660
1691
|
definitionPath: z2.string().describe("Path to the agent definition .md file (e.g., '.agents/agents/coder.md')")
|
|
1661
1692
|
}).optional().describe("Agent definition file to inject into the sub-agent's system prompt as <agent-definition> context."),
|
|
1662
|
-
preferredBackend: z2.enum(["claude", "codex", "gemini"]).optional().describe(
|
|
1663
|
-
"Preferred backend override. Takes highest priority in backend selection. Use when the automatic agentType/taskType mapping does not match your needs."
|
|
1664
|
-
),
|
|
1665
1693
|
taskType: z2.enum(["code-writing", "code-review", "document-writing", "document-review", "research", "mixed"]).optional().describe(
|
|
1666
|
-
"Task type hint for automatic backend selection (priority
|
|
1694
|
+
"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."
|
|
1667
1695
|
),
|
|
1668
1696
|
taskInstructionPath: z2.string().optional().describe(
|
|
1669
1697
|
"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."
|
|
1670
1698
|
),
|
|
1671
1699
|
label: z2.string().optional().describe("Human-readable label for identifying this agent in parallel results and logs."),
|
|
1672
1700
|
metadata: z2.object({
|
|
1673
|
-
taskId: z2.string().regex(TASK_ID_PATTERN)
|
|
1701
|
+
taskId: z2.string().regex(TASK_ID_PATTERN),
|
|
1674
1702
|
agentType: z2.string().optional(),
|
|
1675
1703
|
label: z2.string().optional(),
|
|
1676
1704
|
parentTaskId: z2.string().optional(),
|
|
1677
1705
|
tags: z2.array(z2.string()).optional()
|
|
1678
|
-
}).catchall(z2.unknown()).
|
|
1706
|
+
}).catchall(z2.unknown()).describe("Session metadata for task linkage and orchestration context.")
|
|
1679
1707
|
});
|
|
1680
1708
|
}
|
|
1681
1709
|
});
|
|
@@ -2129,13 +2157,10 @@ var init_backend_selector = __esm({
|
|
|
2129
2157
|
return this.selectBackendWithReason(context).backend;
|
|
2130
2158
|
}
|
|
2131
2159
|
selectBackendWithReason(context) {
|
|
2132
|
-
const { availableBackends,
|
|
2160
|
+
const { availableBackends, agentType, taskType } = context;
|
|
2133
2161
|
if (availableBackends.length === 0) {
|
|
2134
2162
|
throw new Error("No backends available");
|
|
2135
2163
|
}
|
|
2136
|
-
if (preferredBackend && availableBackends.includes(preferredBackend)) {
|
|
2137
|
-
return { backend: preferredBackend, reason: "preferredBackend" };
|
|
2138
|
-
}
|
|
2139
2164
|
if (agentType) {
|
|
2140
2165
|
const mapped = this.agentToBackendMap[agentType];
|
|
2141
2166
|
if (mapped && availableBackends.includes(mapped)) {
|
|
@@ -2420,7 +2445,7 @@ var init_server = __esm({
|
|
|
2420
2445
|
this.agentEventStore
|
|
2421
2446
|
);
|
|
2422
2447
|
this.server = new McpServer(
|
|
2423
|
-
{ name: "agentic-relay", version: "1.
|
|
2448
|
+
{ name: "agentic-relay", version: "1.6.0" },
|
|
2424
2449
|
createMcpServerOptions()
|
|
2425
2450
|
);
|
|
2426
2451
|
this.registerTools(this.server);
|
|
@@ -2558,7 +2583,7 @@ var init_server = __esm({
|
|
|
2558
2583
|
server.experimental.tasks.registerToolTask(
|
|
2559
2584
|
"spawn_agent",
|
|
2560
2585
|
{
|
|
2561
|
-
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:
|
|
2586
|
+
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). metadata with metadata.taskId is required for task-first delegation. Use 'agentDefinition' to inject an agent .md file, 'skillContext' for a SKILL.md, or 'systemPrompt' for custom instructions.",
|
|
2562
2587
|
inputSchema: spawnAgentInputSchema.shape,
|
|
2563
2588
|
execution: { taskSupport: "optional" }
|
|
2564
2589
|
},
|
|
@@ -2614,20 +2639,11 @@ var init_server = __esm({
|
|
|
2614
2639
|
failedResults: z7.array(z7.object({
|
|
2615
2640
|
index: z7.number(),
|
|
2616
2641
|
originalInput: spawnAgentInputSchema
|
|
2617
|
-
})).min(1).describe("Array of failed results with their original input configurations")
|
|
2618
|
-
overrides: z7.object({
|
|
2619
|
-
preferredBackend: z7.enum(["claude", "codex", "gemini"]).optional()
|
|
2620
|
-
}).optional().describe("Parameter overrides applied to all retried agents")
|
|
2642
|
+
})).min(1).describe("Array of failed results with their original input configurations")
|
|
2621
2643
|
},
|
|
2622
2644
|
async (params) => {
|
|
2623
2645
|
try {
|
|
2624
|
-
const agents = params.failedResults.map((r) => {
|
|
2625
|
-
const input = { ...r.originalInput };
|
|
2626
|
-
if (params.overrides) {
|
|
2627
|
-
if (params.overrides.preferredBackend !== void 0) input.preferredBackend = params.overrides.preferredBackend;
|
|
2628
|
-
}
|
|
2629
|
-
return input;
|
|
2630
|
-
});
|
|
2646
|
+
const agents = params.failedResults.map((r) => ({ ...r.originalInput }));
|
|
2631
2647
|
const result = await executeSpawnAgentsParallel(
|
|
2632
2648
|
agents,
|
|
2633
2649
|
this.registry,
|
|
@@ -2908,7 +2924,7 @@ var init_server = __esm({
|
|
|
2908
2924
|
sessionIdGenerator: () => randomUUID()
|
|
2909
2925
|
});
|
|
2910
2926
|
const server = new McpServer(
|
|
2911
|
-
{ name: "agentic-relay", version: "1.
|
|
2927
|
+
{ name: "agentic-relay", version: "1.6.0" },
|
|
2912
2928
|
createMcpServerOptions()
|
|
2913
2929
|
);
|
|
2914
2930
|
this.registerTools(server);
|
|
@@ -5591,7 +5607,7 @@ function fromSessionData(data) {
|
|
|
5591
5607
|
updatedAt,
|
|
5592
5608
|
lastHeartbeatAt: Number.isNaN(lastHeartbeatAt.getTime()) ? updatedAt : lastHeartbeatAt,
|
|
5593
5609
|
staleNotifiedAt: staleNotifiedAt && !Number.isNaN(staleNotifiedAt.getTime()) ? staleNotifiedAt : null,
|
|
5594
|
-
metadata: data.metadata && typeof data.metadata === "object" ? data.metadata : {}
|
|
5610
|
+
metadata: data.metadata && typeof data.metadata === "object" ? data.metadata : { taskId: "TASK-000" }
|
|
5595
5611
|
};
|
|
5596
5612
|
}
|
|
5597
5613
|
var SessionManager = class _SessionManager {
|
|
@@ -6660,7 +6676,7 @@ var ContextMonitor = class {
|
|
|
6660
6676
|
sessionId,
|
|
6661
6677
|
backendId,
|
|
6662
6678
|
parentSessionId: void 0,
|
|
6663
|
-
metadata: sessionMetadata ?? {},
|
|
6679
|
+
metadata: sessionMetadata ?? { taskId: "TASK-000" },
|
|
6664
6680
|
data: {
|
|
6665
6681
|
usagePercent,
|
|
6666
6682
|
currentTokens,
|
|
@@ -7347,7 +7363,7 @@ function createMCPCommand(configManager2, registry2, sessionManager2, hooksEngin
|
|
|
7347
7363
|
responseOutputDir,
|
|
7348
7364
|
relayConfig
|
|
7349
7365
|
);
|
|
7350
|
-
await server.start({ transport, port, currentVersion: "1.
|
|
7366
|
+
await server.start({ transport, port, currentVersion: "1.6.0" });
|
|
7351
7367
|
}
|
|
7352
7368
|
})
|
|
7353
7369
|
},
|
|
@@ -7507,7 +7523,7 @@ function createVersionCommand(registry2) {
|
|
|
7507
7523
|
description: "Show relay and backend versions"
|
|
7508
7524
|
},
|
|
7509
7525
|
async run() {
|
|
7510
|
-
const relayVersion = "1.
|
|
7526
|
+
const relayVersion = "1.6.0";
|
|
7511
7527
|
console.log(`agentic-relay v${relayVersion}`);
|
|
7512
7528
|
console.log("");
|
|
7513
7529
|
console.log("Backends:");
|
|
@@ -7904,7 +7920,7 @@ var subCommandNames = /* @__PURE__ */ new Set(["claude", "codex", "gemini", "upd
|
|
|
7904
7920
|
var main = defineCommand11({
|
|
7905
7921
|
meta: {
|
|
7906
7922
|
name: "relay",
|
|
7907
|
-
version: "1.
|
|
7923
|
+
version: "1.6.0",
|
|
7908
7924
|
description: "Unified CLI proxy for Claude Code, Codex CLI, and Gemini CLI"
|
|
7909
7925
|
},
|
|
7910
7926
|
args: {
|
package/package.json
CHANGED