@llm-dev-ops/agentics-cli 2.7.3 → 2.7.5

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.
@@ -0,0 +1,87 @@
1
+ /**
2
+ * ADR-PIPELINE-096 D3 — Agent-Claim Registry.
3
+ *
4
+ * Maps the four headline financial metrics that the executive summary,
5
+ * decision memo, and financial analysis render onto specific agents and
6
+ * response paths. The renderer consults this registry FIRST when synthesising
7
+ * a number; if the canonical agent returned a value, that value is the source
8
+ * of truth and the rendered cell carries `src=<agent>`. If the registry has no
9
+ * winner, the renderer falls through to `unit-economics.json`, then to the
10
+ * per-employee heuristic from ADR-095.
11
+ *
12
+ * The registry is intentionally NARROW — it covers only the four metrics that
13
+ * appear in every CXO-facing document. Adding a new metric is a one-line
14
+ * change here plus a renderer hook; we are explicit about which numbers carry
15
+ * source attribution and which do not.
16
+ */
17
+ /**
18
+ * The four headline metrics that get source attribution. Lined up with the
19
+ * fcv-tag `kind=` values from ADR-PIPELINE-073 (financial-claim-extractor).
20
+ */
21
+ export type ClaimKind = 'investment' | 'roi' | 'npv' | 'payback' | 'savings';
22
+ /**
23
+ * One entry maps a metric to a specific agent and a response-path
24
+ * (dot-delimited). Multiple entries per kind are allowed and ranked by
25
+ * priority — the first agent that returned a value wins.
26
+ */
27
+ export interface ClaimMapping {
28
+ /** The metric this mapping resolves. */
29
+ readonly kind: ClaimKind;
30
+ /** Domain identifier — e.g. `costops`, `simulator`, `platform`. */
31
+ readonly domain: string;
32
+ /** Agent identifier within the domain — e.g. `forecast`, `roi`, `scenario`. */
33
+ readonly agent: string;
34
+ /** Dot-delimited path inside the agent's response object. Supports `.` and array `[0]` notation. */
35
+ readonly response_path: string;
36
+ /** Lower numbers are tried first. Stable, declarative priority. */
37
+ readonly priority: number;
38
+ /** Optional human-readable methodology string used in the rendered cell. */
39
+ readonly methodology?: string;
40
+ }
41
+ /**
42
+ * Canonical mapping table. Adding a new agent that returns one of the four
43
+ * metrics is a single-line append here. The renderer never hardcodes
44
+ * agent/path knowledge; everything flows through this table.
45
+ */
46
+ export declare const AGENT_CLAIM_REGISTRY: ReadonlyArray<ClaimMapping>;
47
+ /** Minimal shape we need from any agent invocation result. */
48
+ export interface AgentResultLike {
49
+ readonly domain: string;
50
+ readonly agent: string;
51
+ readonly status: number;
52
+ readonly response: unknown;
53
+ }
54
+ /** A claim that has been resolved against the registry. */
55
+ export interface ResolvedClaim {
56
+ /** Raw value from the agent (number or string — caller decides format). */
57
+ readonly value: number | string;
58
+ /** Source attribution for the rendered `src=` attribute. */
59
+ readonly source: string;
60
+ /** Methodology string for the cell text. */
61
+ readonly methodology: string;
62
+ /** Which agent produced this value. */
63
+ readonly domain: string;
64
+ readonly agent: string;
65
+ }
66
+ /**
67
+ * Look up the highest-priority agent that returned a value for `kind`.
68
+ * Returns `null` when no registered agent succeeded with a non-null value at
69
+ * the response path. Caller decides whether to fall through to
70
+ * unit-economics.json or to the per-employee heuristic.
71
+ */
72
+ export declare function resolveClaim(kind: ClaimKind, results: ReadonlyArray<AgentResultLike>): ResolvedClaim | null;
73
+ /**
74
+ * Resolve ALL agents that returned a value for `kind`. Used by D3 part 2's
75
+ * triangulation surface to detect agreement / divergence across multiple
76
+ * sources for the same metric.
77
+ */
78
+ export declare function resolveAllClaims(kind: ClaimKind, results: ReadonlyArray<AgentResultLike>): ResolvedClaim[];
79
+ /**
80
+ * Walk a dot-delimited path inside a response object. Supports nested objects
81
+ * and array indices via `[N]` notation. Returns `null` for any miss.
82
+ *
83
+ * Example: `data.dcf.npv_5yr_usd` → result.data.dcf.npv_5yr_usd
84
+ * Example: `data.scenarios[0].npv` → result.data.scenarios[0].npv
85
+ */
86
+ export declare function readResponsePath(response: unknown, path: string): unknown;
87
+ //# sourceMappingURL=agent-claim-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-claim-registry.d.ts","sourceRoot":"","sources":["../../src/synthesis/agent-claim-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,CAAC;AAE7E;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,oGAAoG;IACpG,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,4EAA4E;IAC5E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAMD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,YAAY,CA8F5D,CAAC;AAMF,8DAA8D;AAC9D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAChC,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,4CAA4C;IAC5C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,uCAAuC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,aAAa,CAAC,eAAe,CAAC,GACtC,aAAa,GAAG,IAAI,CAgCtB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,aAAa,CAAC,eAAe,CAAC,GACtC,aAAa,EAAE,CA8BjB;AAMD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAqCzE"}
@@ -0,0 +1,257 @@
1
+ /**
2
+ * ADR-PIPELINE-096 D3 — Agent-Claim Registry.
3
+ *
4
+ * Maps the four headline financial metrics that the executive summary,
5
+ * decision memo, and financial analysis render onto specific agents and
6
+ * response paths. The renderer consults this registry FIRST when synthesising
7
+ * a number; if the canonical agent returned a value, that value is the source
8
+ * of truth and the rendered cell carries `src=<agent>`. If the registry has no
9
+ * winner, the renderer falls through to `unit-economics.json`, then to the
10
+ * per-employee heuristic from ADR-095.
11
+ *
12
+ * The registry is intentionally NARROW — it covers only the four metrics that
13
+ * appear in every CXO-facing document. Adding a new metric is a one-line
14
+ * change here plus a renderer hook; we are explicit about which numbers carry
15
+ * source attribution and which do not.
16
+ */
17
+ // ---------------------------------------------------------------------------
18
+ // Registry (declarative — the single place mappings live)
19
+ // ---------------------------------------------------------------------------
20
+ /**
21
+ * Canonical mapping table. Adding a new agent that returns one of the four
22
+ * metrics is a single-line append here. The renderer never hardcodes
23
+ * agent/path knowledge; everything flows through this table.
24
+ */
25
+ export const AGENT_CLAIM_REGISTRY = [
26
+ // ── Investment (Total Investment / Total Cost) ─────────────────────────────
27
+ {
28
+ kind: 'investment',
29
+ domain: 'costops',
30
+ agent: 'forecast',
31
+ response_path: 'data.investment.total_usd',
32
+ priority: 10,
33
+ methodology: 'costops/forecast: total program investment forecast',
34
+ },
35
+ {
36
+ kind: 'investment',
37
+ domain: 'costops',
38
+ agent: 'budget',
39
+ response_path: 'data.allocated_budget.usd',
40
+ priority: 20,
41
+ methodology: 'costops/budget: allocated budget envelope',
42
+ },
43
+ {
44
+ kind: 'investment',
45
+ domain: 'costops',
46
+ agent: 'attribution',
47
+ response_path: 'data.total_cost.usd',
48
+ priority: 30,
49
+ methodology: 'costops/attribution: cost attribution rollup',
50
+ },
51
+ // ── ROI (Expected ROI / Return on Investment) ──────────────────────────────
52
+ {
53
+ kind: 'roi',
54
+ domain: 'costops',
55
+ agent: 'roi',
56
+ response_path: 'data.roi_pct',
57
+ priority: 10,
58
+ methodology: 'costops/roi: program ROI calculation',
59
+ },
60
+ {
61
+ kind: 'roi',
62
+ domain: 'costops',
63
+ agent: 'tradeoff',
64
+ response_path: 'data.roi_pct',
65
+ priority: 20,
66
+ methodology: 'costops/tradeoff: ROI under cost-quality tradeoff',
67
+ },
68
+ // ── NPV (5-year NPV) ───────────────────────────────────────────────────────
69
+ {
70
+ kind: 'npv',
71
+ domain: 'simulator',
72
+ agent: 'scenario',
73
+ response_path: 'data.dcf.npv_5yr_usd',
74
+ priority: 10,
75
+ methodology: 'simulator/scenario: 5-year DCF, scenario midpoint',
76
+ },
77
+ {
78
+ kind: 'npv',
79
+ domain: 'costops',
80
+ agent: 'forecast',
81
+ response_path: 'data.npv.five_year_usd',
82
+ priority: 20,
83
+ methodology: 'costops/forecast: 5-year NPV from forecast',
84
+ },
85
+ // ── Payback (Payback Period) ───────────────────────────────────────────────
86
+ {
87
+ kind: 'payback',
88
+ domain: 'costops',
89
+ agent: 'budget',
90
+ response_path: 'data.payback_months',
91
+ priority: 10,
92
+ methodology: 'costops/budget: payback period',
93
+ },
94
+ {
95
+ kind: 'payback',
96
+ domain: 'costops',
97
+ agent: 'forecast',
98
+ response_path: 'data.payback_months',
99
+ priority: 20,
100
+ methodology: 'costops/forecast: payback from cumulative cashflow',
101
+ },
102
+ // ── Savings (Annual Efficiency Gain / Revenue Impact) ──────────────────────
103
+ {
104
+ kind: 'savings',
105
+ domain: 'costops',
106
+ agent: 'roi',
107
+ response_path: 'data.annual_savings_usd',
108
+ priority: 10,
109
+ methodology: 'costops/roi: annual savings from ROI calc',
110
+ },
111
+ {
112
+ kind: 'savings',
113
+ domain: 'costops',
114
+ agent: 'attribution',
115
+ response_path: 'data.annual_savings.usd',
116
+ priority: 20,
117
+ methodology: 'costops/attribution: annual savings',
118
+ },
119
+ ];
120
+ /**
121
+ * Look up the highest-priority agent that returned a value for `kind`.
122
+ * Returns `null` when no registered agent succeeded with a non-null value at
123
+ * the response path. Caller decides whether to fall through to
124
+ * unit-economics.json or to the per-employee heuristic.
125
+ */
126
+ export function resolveClaim(kind, results) {
127
+ // Filter mappings to this kind, sorted by priority (lower wins).
128
+ const candidates = AGENT_CLAIM_REGISTRY
129
+ .filter(m => m.kind === kind)
130
+ .slice()
131
+ .sort((a, b) => a.priority - b.priority);
132
+ // Index agent results by `domain/agent` for O(1) lookup.
133
+ const byKey = new Map();
134
+ for (const r of results) {
135
+ if (r.status >= 200 && r.status < 300) {
136
+ byKey.set(`${r.domain}/${r.agent}`, r);
137
+ }
138
+ }
139
+ for (const c of candidates) {
140
+ const result = byKey.get(`${c.domain}/${c.agent}`);
141
+ if (!result)
142
+ continue;
143
+ const value = readResponsePath(result.response, c.response_path);
144
+ if (value === null || value === undefined)
145
+ continue;
146
+ if (typeof value !== 'number' && typeof value !== 'string')
147
+ continue;
148
+ if (typeof value === 'string' && value.trim().length === 0)
149
+ continue;
150
+ return {
151
+ value,
152
+ source: `${c.domain}/${c.agent}`,
153
+ methodology: c.methodology ?? `${c.domain}/${c.agent}`,
154
+ domain: c.domain,
155
+ agent: c.agent,
156
+ };
157
+ }
158
+ return null;
159
+ }
160
+ /**
161
+ * Resolve ALL agents that returned a value for `kind`. Used by D3 part 2's
162
+ * triangulation surface to detect agreement / divergence across multiple
163
+ * sources for the same metric.
164
+ */
165
+ export function resolveAllClaims(kind, results) {
166
+ const candidates = AGENT_CLAIM_REGISTRY
167
+ .filter(m => m.kind === kind)
168
+ .slice()
169
+ .sort((a, b) => a.priority - b.priority);
170
+ const byKey = new Map();
171
+ for (const r of results) {
172
+ if (r.status >= 200 && r.status < 300) {
173
+ byKey.set(`${r.domain}/${r.agent}`, r);
174
+ }
175
+ }
176
+ const out = [];
177
+ for (const c of candidates) {
178
+ const result = byKey.get(`${c.domain}/${c.agent}`);
179
+ if (!result)
180
+ continue;
181
+ const value = readResponsePath(result.response, c.response_path);
182
+ if (value === null || value === undefined)
183
+ continue;
184
+ if (typeof value !== 'number' && typeof value !== 'string')
185
+ continue;
186
+ if (typeof value === 'string' && value.trim().length === 0)
187
+ continue;
188
+ out.push({
189
+ value,
190
+ source: `${c.domain}/${c.agent}`,
191
+ methodology: c.methodology ?? `${c.domain}/${c.agent}`,
192
+ domain: c.domain,
193
+ agent: c.agent,
194
+ });
195
+ }
196
+ return out;
197
+ }
198
+ // ---------------------------------------------------------------------------
199
+ // Helpers
200
+ // ---------------------------------------------------------------------------
201
+ /**
202
+ * Walk a dot-delimited path inside a response object. Supports nested objects
203
+ * and array indices via `[N]` notation. Returns `null` for any miss.
204
+ *
205
+ * Example: `data.dcf.npv_5yr_usd` → result.data.dcf.npv_5yr_usd
206
+ * Example: `data.scenarios[0].npv` → result.data.scenarios[0].npv
207
+ */
208
+ export function readResponsePath(response, path) {
209
+ if (response === null || response === undefined)
210
+ return null;
211
+ // Tokenize the path on `.` and `[N]`.
212
+ const tokens = [];
213
+ let buf = '';
214
+ for (let i = 0; i < path.length; i++) {
215
+ const ch = path[i];
216
+ if (ch === '.') {
217
+ if (buf)
218
+ tokens.push(buf);
219
+ buf = '';
220
+ }
221
+ else if (ch === '[') {
222
+ if (buf)
223
+ tokens.push(buf);
224
+ buf = '';
225
+ const close = path.indexOf(']', i);
226
+ if (close === -1)
227
+ return null;
228
+ const idx = parseInt(path.slice(i + 1, close), 10);
229
+ if (Number.isNaN(idx))
230
+ return null;
231
+ tokens.push(idx);
232
+ i = close;
233
+ }
234
+ else {
235
+ buf += ch;
236
+ }
237
+ }
238
+ if (buf)
239
+ tokens.push(buf);
240
+ let cur = response;
241
+ for (const tok of tokens) {
242
+ if (cur === null || cur === undefined)
243
+ return null;
244
+ if (typeof tok === 'number') {
245
+ if (!Array.isArray(cur))
246
+ return null;
247
+ cur = cur[tok];
248
+ }
249
+ else {
250
+ if (typeof cur !== 'object')
251
+ return null;
252
+ cur = cur[tok];
253
+ }
254
+ }
255
+ return cur ?? null;
256
+ }
257
+ //# sourceMappingURL=agent-claim-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-claim-registry.js","sourceRoot":"","sources":["../../src/synthesis/agent-claim-registry.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ask-artifact-writer.d.ts","sourceRoot":"","sources":["../../src/synthesis/ask-artifact-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAiBH,OAAO,KAAK,EACV,WAAW,EAEZ,MAAM,uBAAuB,CAAC;AAgB/B,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,EAAE,aAAa,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8mCD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,GAAG,IAAI,CAmBjF;AAoED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CA2E9D"}
1
+ {"version":3,"file":"ask-artifact-writer.d.ts","sourceRoot":"","sources":["../../src/synthesis/ask-artifact-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAiBH,OAAO,KAAK,EACV,WAAW,EAEZ,MAAM,uBAAuB,CAAC;AAgB/B,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,EAAE,aAAa,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6rCD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,GAAG,IAAI,CAmBjF;AAoED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CA2E9D"}
@@ -65,9 +65,88 @@ function buildManifest(input) {
65
65
  status: a.succeeded ? 'success' : 'error',
66
66
  })),
67
67
  artifacts: [...baseArtifacts, ...engArtifacts],
68
- schema_version: '1.0.0',
68
+ // ADR-PIPELINE-096 D2 — runtime lineage block. Populated from the route
69
+ // result + a fresh Ruflo availability probe. Backwards-compatible: every
70
+ // existing consumer ignores the new top-level key per ADR-088. Surface
71
+ // points: `agentics status`, the `agentics-status` MCP tool, and
72
+ // `agent-fleet-report.md`.
73
+ runtime: buildRuntimeLineage(input, agents),
74
+ schema_version: '1.1.0',
69
75
  };
70
76
  }
77
+ /**
78
+ * ADR-096 D2 — assemble the `runtime` block. Best-effort: if any sub-probe
79
+ * fails (Ruflo unreachable, etc.), the offending field is null/undefined and
80
+ * the rest still populates. Never throws.
81
+ */
82
+ function buildRuntimeLineage(input, agents) {
83
+ // Ruflo availability — uses ADR-094's cached probe so this is a microsecond
84
+ // lookup after the first call, NOT a fresh subprocess.
85
+ let ruflo;
86
+ try {
87
+ // Dynamic require so this module stays loadable in environments where the
88
+ // ruflo-phase-executor's deps aren't installed (e.g. tests).
89
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
90
+ const rufloMod = require('../pipeline/ruflo-phase-executor.js');
91
+ const probe = typeof rufloMod.checkRufloAvailable === 'function' ? rufloMod.checkRufloAvailable() : null;
92
+ if (probe && typeof probe === 'object') {
93
+ const p = probe;
94
+ ruflo = {
95
+ available: Boolean(p['available']),
96
+ version: typeof p['version'] === 'string' ? p['version'] : 'N/A',
97
+ binary: typeof p['binary'] === 'string' ? p['binary'] : '',
98
+ reason: typeof p['reason'] === 'string' ? p['reason'] : (p['available'] ? 'ok' : 'unknown'),
99
+ };
100
+ }
101
+ else {
102
+ ruflo = { available: false, version: 'N/A', binary: '', reason: 'probe-failed' };
103
+ }
104
+ }
105
+ catch {
106
+ ruflo = { available: false, version: 'N/A', binary: '', reason: 'probe-threw' };
107
+ }
108
+ // Ruvector / hyperbolic simulation — `simulator/enterprise` invocations
109
+ // and graph-routing calls (the simulation-tier branch of
110
+ // executeAgentsInvokeCommand) all flow through ruvector. We surface the
111
+ // count and the per-call latency that we already track in the route result.
112
+ const simulatorAgents = agents.filter(a => a.domain === 'simulator');
113
+ const ruvector = {
114
+ hyperbolic_simulations: simulatorAgents.map(a => ({
115
+ agent: `${a.domain}/${a.agent}`,
116
+ status: a.succeeded ? 'success' : 'error',
117
+ })),
118
+ embedding_lookups: 0, // populated by D2.1 follow-up when graph-router exposes a counter
119
+ graph_routing_invocations: input.routeResult.kind === 'multi' ? 1 : 0, // capability-graph route attempt; 0 on consultancy bypass
120
+ };
121
+ // Fleet metadata — depth + per-domain success/fail counts.
122
+ const byDomain = {};
123
+ for (const a of agents) {
124
+ const slot = byDomain[a.domain] ?? { dispatched: 0, succeeded: 0, failed: 0 };
125
+ slot.dispatched++;
126
+ if (a.succeeded)
127
+ slot.succeeded++;
128
+ else
129
+ slot.failed++;
130
+ byDomain[a.domain] = slot;
131
+ }
132
+ const dispatched = agents.length;
133
+ const succeeded = agents.filter(a => a.succeeded).length;
134
+ const failed = dispatched - succeeded;
135
+ // Depth is read from the route result (set by the caller via
136
+ // `executeNaturalLanguageRoute(query, { depth })`). Fallback heuristic when
137
+ // the value isn't carried through: 100+ agents is consultancy, 20+ is
138
+ // standard, otherwise lite.
139
+ const inferredDepth = dispatched >= 100 ? 'consultancy' : dispatched >= 20 ? 'standard' : 'lite';
140
+ const fleet = {
141
+ depth: inferredDepth,
142
+ dispatched,
143
+ succeeded,
144
+ failed,
145
+ by_domain: byDomain,
146
+ cloud_breaker: { tripped: false }, // populated by D2.2 when cloud-breaker state surfaces from agents.ts
147
+ };
148
+ return { ruflo, ruvector, fleet };
149
+ }
71
150
  function buildResultsJson(input) {
72
151
  if (input.routeResult.kind === 'multi') {
73
152
  return {