@llm-dev-ops/agentics-cli 2.4.0 → 2.5.1
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/adapters/base-adapter.d.ts +5 -1
- package/dist/adapters/base-adapter.d.ts.map +1 -1
- package/dist/adapters/base-adapter.js +13 -0
- package/dist/adapters/base-adapter.js.map +1 -1
- package/dist/agents/repo-agent-runner.d.ts +2 -0
- package/dist/agents/repo-agent-runner.d.ts.map +1 -1
- package/dist/agents/repo-agent-runner.js +4 -2
- package/dist/agents/repo-agent-runner.js.map +1 -1
- package/dist/agents/system-prompts.d.ts.map +1 -1
- package/dist/agents/system-prompts.js +19 -0
- package/dist/agents/system-prompts.js.map +1 -1
- package/dist/commands/agents.d.ts +25 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +186 -3
- package/dist/commands/agents.js.map +1 -1
- package/dist/config/endpoints.d.ts.map +1 -1
- package/dist/config/endpoints.js +8 -0
- package/dist/config/endpoints.js.map +1 -1
- package/dist/config/qe-gating.d.ts +81 -0
- package/dist/config/qe-gating.d.ts.map +1 -0
- package/dist/config/qe-gating.js +138 -0
- package/dist/config/qe-gating.js.map +1 -0
- package/dist/pipeline/phase5-build/qe-gating-executor.d.ts +73 -0
- package/dist/pipeline/phase5-build/qe-gating-executor.d.ts.map +1 -0
- package/dist/pipeline/phase5-build/qe-gating-executor.js +134 -0
- package/dist/pipeline/phase5-build/qe-gating-executor.js.map +1 -0
- package/dist/promotion/graph-diff.d.ts +39 -0
- package/dist/promotion/graph-diff.d.ts.map +1 -0
- package/dist/promotion/graph-diff.js +60 -0
- package/dist/promotion/graph-diff.js.map +1 -0
- package/dist/promotion/sampler-lib.d.ts +45 -0
- package/dist/promotion/sampler-lib.d.ts.map +1 -0
- package/dist/promotion/sampler-lib.js +96 -0
- package/dist/promotion/sampler-lib.js.map +1 -0
- package/dist/routing/domain-boundary.d.ts +92 -0
- package/dist/routing/domain-boundary.d.ts.map +1 -0
- package/dist/routing/domain-boundary.js +208 -0
- package/dist/routing/domain-boundary.js.map +1 -0
- package/dist/routing/graph-router.d.ts +31 -1
- package/dist/routing/graph-router.d.ts.map +1 -1
- package/dist/routing/graph-router.js +91 -4
- package/dist/routing/graph-router.js.map +1 -1
- package/dist/routing/index.d.ts +13 -3
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +9 -4
- package/dist/routing/index.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/docs/ecosystem.graph.json +87 -14
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA6LxD,UAAU,WAAW;IACnB,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAuLrD,CAAC;AAMF,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtG,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAMD,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,cAAc,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAkB3B;AAED,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,kBAAkB,CAAC,CA0B7B;AAED,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,kBAAkB,CAAC,CA8d7B;AA+zCD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAgB3E;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAQ9E;AAMD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,KAAK,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,WAAW,EAAE,KAAK,CAAC;QACjB,MAAM,EAAE,oBAAoB,CAAC;QAC7B,MAAM,EAAE,kBAAkB,GAAG;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KAChD,CAAC,CAAC;IACH;;;;OAIG;IACH,OAAO,CAAC,EAAE;QACR,UAAU,EAAE,sBAAsB,EAAE,CAAC;KACtC,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,0BAA0B,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,qBAAqB,CAAA;CAAE,CAAC;AAqGrD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,GACpB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkjDzB;AAMD,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,WAAW,CAAC,CA0hBtB;AAED,wBAAgB,oCAAoC,CAAC,MAAM,EAAE,0BAA0B,GAAG,MAAM,CAY/F;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAqCrF;AAED,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAK5E;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CA2BlF"}
|
package/dist/commands/agents.js
CHANGED
|
@@ -94,6 +94,94 @@ async function runCopilotViaClaudeMax(agent, payload, correlationId) {
|
|
|
94
94
|
return null; // claude --print failed — fall through to cloud function
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
+
// ADR-066 extension: inference-gateway/route via claude --print.
|
|
98
|
+
// The gateway's "route" agent is a pure reasoning task (pick best provider/model
|
|
99
|
+
// for a request given hints). We run it locally through the user's Claude Max
|
|
100
|
+
// session so no server-side Anthropic API key is required.
|
|
101
|
+
async function runInferenceRoutingViaClaudeMax(payload, correlationId) {
|
|
102
|
+
let claudeBin = null;
|
|
103
|
+
const envBin = process.env['AGENTICS_CLAUDE_BIN'];
|
|
104
|
+
if (envBin) {
|
|
105
|
+
claudeBin = envBin;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
for (const candidate of ['claude', 'claude-code']) {
|
|
109
|
+
try {
|
|
110
|
+
const found = execFileSync(process.platform === 'win32' ? 'where' : 'which', [candidate], { stdio: ['pipe', 'pipe', 'pipe'], timeout: 5_000, encoding: 'utf-8' }).trim().split(/\r?\n/)[0]?.trim();
|
|
111
|
+
if (found) {
|
|
112
|
+
claudeBin = found;
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch { /* not found */ }
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (!claudeBin)
|
|
120
|
+
return null;
|
|
121
|
+
const systemPrompt = [
|
|
122
|
+
'You are an inference routing advisor.',
|
|
123
|
+
'Given an inference request and routing hints, choose the best (provider, model) pair.',
|
|
124
|
+
'Return ONLY valid JSON (no markdown fences) with shape:',
|
|
125
|
+
'{',
|
|
126
|
+
' "chosen_provider": "anthropic" | "openai" | "google",',
|
|
127
|
+
' "chosen_model": "<model-id>",',
|
|
128
|
+
' "routing_decision": {',
|
|
129
|
+
' "rationale": "<one-sentence reason>",',
|
|
130
|
+
' "estimated_latency_ms": <number>,',
|
|
131
|
+
' "estimated_cost_usd_per_1k_tokens": <number>,',
|
|
132
|
+
' "quality_tier": "tier-1" | "tier-2" | "tier-3"',
|
|
133
|
+
' },',
|
|
134
|
+
' "fallbacks": [{ "provider": "...", "model": "...", "reason": "..." }],',
|
|
135
|
+
' "honored_hints": [<list of hint fields respected>]',
|
|
136
|
+
'}',
|
|
137
|
+
'Honor hints.preferred_providers and hints.excluded_providers strictly.',
|
|
138
|
+
'Honor hints.max_latency_tier (1=fastest, 3=slowest-tolerable).',
|
|
139
|
+
'If hints.optimize_cost is true, prefer cheaper models when quality allows.',
|
|
140
|
+
'If request.model is specified and not excluded, prefer honoring it.',
|
|
141
|
+
].join('\n');
|
|
142
|
+
const fullPrompt = `${systemPrompt}\n\nRequest:\n${JSON.stringify(payload, null, 2)}`;
|
|
143
|
+
try {
|
|
144
|
+
const rawOutput = execFileSync(claudeBin, [
|
|
145
|
+
'--print',
|
|
146
|
+
'--output-format', 'text',
|
|
147
|
+
'--model', process.env['AGENTICS_CLAUDE_MODEL'] || 'claude-sonnet-4-20250514',
|
|
148
|
+
fullPrompt,
|
|
149
|
+
], {
|
|
150
|
+
encoding: 'utf-8',
|
|
151
|
+
timeout: 60_000,
|
|
152
|
+
maxBuffer: 5 * 1024 * 1024,
|
|
153
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
154
|
+
env: { ...process.env, MCP_SERVER_MODE: undefined },
|
|
155
|
+
});
|
|
156
|
+
let cleaned = rawOutput.trim();
|
|
157
|
+
if (cleaned.startsWith('```')) {
|
|
158
|
+
cleaned = cleaned.replace(/^```(?:json)?\s*\n?/, '').replace(/\n?```\s*$/, '');
|
|
159
|
+
}
|
|
160
|
+
const jsonMatch = cleaned.match(/\{[\s\S]*\}/);
|
|
161
|
+
if (!jsonMatch)
|
|
162
|
+
return null;
|
|
163
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
164
|
+
return {
|
|
165
|
+
...parsed,
|
|
166
|
+
_source: 'claude-max',
|
|
167
|
+
execution_metadata: {
|
|
168
|
+
trace_id: correlationId,
|
|
169
|
+
timestamp: new Date().toISOString(),
|
|
170
|
+
service: 'inference-gateway-agents',
|
|
171
|
+
execution_id: correlationId,
|
|
172
|
+
agent: 'inference-routing-agent',
|
|
173
|
+
engine: 'claude-max',
|
|
174
|
+
},
|
|
175
|
+
layers_executed: [
|
|
176
|
+
{ layer: 'AGENT_ROUTING', status: 'completed' },
|
|
177
|
+
{ layer: 'INFERENCE_GATEWAY_ROUTE', status: 'completed' },
|
|
178
|
+
],
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
97
185
|
export const AGENT_DOMAINS = {
|
|
98
186
|
'test-bench': {
|
|
99
187
|
serviceName: 'test-bench-agents',
|
|
@@ -230,6 +318,53 @@ export const AGENT_DOMAINS = {
|
|
|
230
318
|
agents: ['decision', 'executive-summary', 'decision-memo', 'risk-score'],
|
|
231
319
|
phase: 'Phase 9: Apex Platform',
|
|
232
320
|
},
|
|
321
|
+
// ADR-PIPELINE-080 registered quality_engineering in the ecosystem graph and
|
|
322
|
+
// wired agentic-qe into repo-agent-runner FUNCTION_NAMES, but left the
|
|
323
|
+
// dispatch-time AGENT_DOMAINS registry untouched. ADR-PIPELINE-087 §1
|
|
324
|
+
// restores the missing entry so resolveAgentRef() → executeAgentsInvokeCommand
|
|
325
|
+
// does not throw "Unknown domain" on AQE selections.
|
|
326
|
+
'quality-engineering': {
|
|
327
|
+
serviceName: 'agentic-qe-agents',
|
|
328
|
+
agents: [
|
|
329
|
+
'test-design',
|
|
330
|
+
'unit-test-gen',
|
|
331
|
+
'integration-test-gen',
|
|
332
|
+
'property-test-gen',
|
|
333
|
+
'bdd-test-gen',
|
|
334
|
+
'coverage-analysis',
|
|
335
|
+
'coverage-gap-detect',
|
|
336
|
+
'defect-prediction',
|
|
337
|
+
'flaky-detection',
|
|
338
|
+
'rca',
|
|
339
|
+
'traceability',
|
|
340
|
+
'chaos',
|
|
341
|
+
'test-execution',
|
|
342
|
+
'qe-reporting',
|
|
343
|
+
],
|
|
344
|
+
phase: 'Phase 8: Validation',
|
|
345
|
+
},
|
|
346
|
+
// diligence-artifacts is driven by phase coordinators (phase2/phase3/phase4)
|
|
347
|
+
// rather than cloud-function dispatch. Registering it here lets
|
|
348
|
+
// ADR-PIPELINE-087 §1 resolve SPARC/ADR/DDD classifier selections to a known
|
|
349
|
+
// domain — dispatch returns a pipeline-owned-elsewhere 502 instead of the
|
|
350
|
+
// previous silent drop, which is the visibility the ADR is enforcing.
|
|
351
|
+
'diligence-artifacts': {
|
|
352
|
+
serviceName: 'diligence-artifacts',
|
|
353
|
+
agents: [
|
|
354
|
+
'sparc-specification',
|
|
355
|
+
'sparc-pseudocode',
|
|
356
|
+
'sparc-architecture',
|
|
357
|
+
'sparc-refinement',
|
|
358
|
+
'sparc-completion',
|
|
359
|
+
'sparc-merge',
|
|
360
|
+
'adr-generation',
|
|
361
|
+
'ddd-domain-model',
|
|
362
|
+
'context-map',
|
|
363
|
+
'adr-validator',
|
|
364
|
+
'documentation',
|
|
365
|
+
],
|
|
366
|
+
phase: 'Phase 3-5: Diligence Artifacts',
|
|
367
|
+
},
|
|
233
368
|
};
|
|
234
369
|
// ============================================================================
|
|
235
370
|
// Command Implementations
|
|
@@ -323,11 +458,35 @@ export async function executeAgentsInvokeCommand(domain, agent, payload, options
|
|
|
323
458
|
invokeHeaders['X-Anthropic-Api-Key'] = anthropicKey;
|
|
324
459
|
}
|
|
325
460
|
}
|
|
326
|
-
//
|
|
327
|
-
|
|
461
|
+
// ADR-066 extension: inference-gateway/route via Claude Max — the gateway's
|
|
462
|
+
// route agent is a reasoning task, so we run it locally through the user's
|
|
463
|
+
// Claude session instead of requiring a server-side Anthropic API key.
|
|
464
|
+
if (domain === 'inference-gateway' && agent === 'route') {
|
|
465
|
+
const routingResult = await runInferenceRoutingViaClaudeMax(normalizedPayload, correlationId);
|
|
466
|
+
if (routingResult) {
|
|
467
|
+
return {
|
|
468
|
+
domain,
|
|
469
|
+
agent,
|
|
470
|
+
status: 200,
|
|
471
|
+
response: routingResult,
|
|
472
|
+
timing: Date.now() - start,
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
// Fall through to cloud function (which will 503 without provider keys)
|
|
476
|
+
// and then to the existing computeUniversalFallback path.
|
|
477
|
+
}
|
|
478
|
+
// governance-dashboard, policy-engine, and costops require execution context in HTTP headers
|
|
479
|
+
if (domain === 'governance-dashboard' || domain === 'policy-engine' || domain === 'costops') {
|
|
328
480
|
invokeHeaders['x-execution-id'] = correlationId;
|
|
329
481
|
invokeHeaders['x-parent-span-id'] = correlationId;
|
|
330
482
|
}
|
|
483
|
+
// research-lab requires execution_context as a top-level body field (not headers).
|
|
484
|
+
if (domain === 'research-lab' && normalizedPayload && typeof normalizedPayload === 'object') {
|
|
485
|
+
normalizedPayload = {
|
|
486
|
+
...normalizedPayload,
|
|
487
|
+
execution_context: { execution_id: correlationId, parent_span_id: correlationId },
|
|
488
|
+
};
|
|
489
|
+
}
|
|
331
490
|
let response;
|
|
332
491
|
try {
|
|
333
492
|
response = await adapter.invoke({
|
|
@@ -2028,7 +2187,7 @@ function extractScenarioContext(query) {
|
|
|
2028
2187
|
* simulator wants "scenario_id" + "parameters"). This function maps the user's
|
|
2029
2188
|
* natural-language query into the correct shape.
|
|
2030
2189
|
*/
|
|
2031
|
-
function buildDomainPayload(domain, agent, query, correlationId) {
|
|
2190
|
+
export function buildDomainPayload(domain, agent, query, correlationId) {
|
|
2032
2191
|
// Some agents have strict schema validation and reject unknown properties.
|
|
2033
2192
|
// Only include execution_ref for agents that accept it.
|
|
2034
2193
|
const base = { execution_ref: correlationId };
|
|
@@ -3733,12 +3892,19 @@ export async function executeNaturalLanguageRoute(query, options) {
|
|
|
3733
3892
|
const artMsg = artifactErr instanceof Error ? artifactErr.message : String(artifactErr);
|
|
3734
3893
|
console.error(`[WARN] Graph-routed artifact generation failed: ${artMsg}`);
|
|
3735
3894
|
}
|
|
3895
|
+
// ADR-PIPELINE-087 §4: propagate classifier-selected-but-unresolved
|
|
3896
|
+
// agents to the caller. Empty array is the healthy case; any entry
|
|
3897
|
+
// indicates a graph→resolver gap (→ CI guard, §8) or a rename drift.
|
|
3898
|
+
const routingMeta = graphResult.unresolved.length > 0
|
|
3899
|
+
? { unresolved: graphResult.unresolved.map(u => ({ stage: u.stage, agentName: u.agentName, capability: u.capability })) }
|
|
3900
|
+
: { unresolved: [] };
|
|
3736
3901
|
return {
|
|
3737
3902
|
kind: 'multi',
|
|
3738
3903
|
result: {
|
|
3739
3904
|
query,
|
|
3740
3905
|
intents,
|
|
3741
3906
|
invocations,
|
|
3907
|
+
routing: routingMeta,
|
|
3742
3908
|
timing: elapsed,
|
|
3743
3909
|
},
|
|
3744
3910
|
};
|
|
@@ -4105,6 +4271,18 @@ export function formatMultiAgentRouteForDisplay(result) {
|
|
|
4105
4271
|
lines.push(`Agents invoked: ${agentCount} (${succeeded} succeeded${failed > 0 ? `, ${failed} failed` : ''})`);
|
|
4106
4272
|
lines.push(`Total Timing: ${result.timing}ms`);
|
|
4107
4273
|
lines.push('');
|
|
4274
|
+
// ADR-PIPELINE-087 §4: surface unresolved classifier selections at the top
|
|
4275
|
+
// of the display so operators (and MCP clients relaying stdout) see the
|
|
4276
|
+
// routing gap immediately instead of having to infer it from missing work.
|
|
4277
|
+
const unresolved = result.routing?.unresolved ?? [];
|
|
4278
|
+
if (unresolved.length > 0) {
|
|
4279
|
+
lines.push(`⚠️ Routing gaps — ${unresolved.length} classifier-selected agent${unresolved.length === 1 ? '' : 's'} not dispatched (ADR-PIPELINE-087 §4):`);
|
|
4280
|
+
for (const u of unresolved) {
|
|
4281
|
+
lines.push(` - ${u.stage}: ${u.agentName} (capability "${u.capability}")`);
|
|
4282
|
+
}
|
|
4283
|
+
lines.push(' Fix: add these names to AGENT_NAME_TO_DOMAIN in src/routing/graph-router.ts.');
|
|
4284
|
+
lines.push('');
|
|
4285
|
+
}
|
|
4108
4286
|
for (const inv of result.invocations) {
|
|
4109
4287
|
const label = `[${inv.intent.domain}/${inv.intent.agent}]`;
|
|
4110
4288
|
if ('error' in inv.result) {
|
|
@@ -4137,6 +4315,11 @@ export function routeResultToJson(routeResult, query) {
|
|
|
4137
4315
|
reasoning: i.intent.reasoning,
|
|
4138
4316
|
result: 'error' in i.result ? { error: i.result.error } : i.result,
|
|
4139
4317
|
})),
|
|
4318
|
+
// ADR-PIPELINE-087 §4: include routing.unresolved in the JSON envelope
|
|
4319
|
+
// so programmatic consumers (MCP clients, CI) can detect drops.
|
|
4320
|
+
routing: {
|
|
4321
|
+
unresolved: routeResult.result.routing?.unresolved ?? [],
|
|
4322
|
+
},
|
|
4140
4323
|
timing: routeResult.result.timing,
|
|
4141
4324
|
};
|
|
4142
4325
|
}
|