@llm-dev-ops/agentics-cli 2.5.4 → 2.7.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/cli/index.js +80 -13
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/agents.d.ts +7 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +130 -23
- package/dist/commands/agents.js.map +1 -1
- package/dist/errors/transient.d.ts +67 -0
- package/dist/errors/transient.d.ts.map +1 -0
- package/dist/errors/transient.js +260 -0
- package/dist/errors/transient.js.map +1 -0
- package/dist/mcp/agent-event-parser.d.ts +53 -0
- package/dist/mcp/agent-event-parser.d.ts.map +1 -0
- package/dist/mcp/agent-event-parser.js +159 -0
- package/dist/mcp/agent-event-parser.js.map +1 -0
- package/dist/mcp/mcp-server.js +34 -15
- package/dist/mcp/mcp-server.js.map +1 -1
- package/dist/observability/degradations.d.ts +58 -0
- package/dist/observability/degradations.d.ts.map +1 -0
- package/dist/observability/degradations.js +74 -0
- package/dist/observability/degradations.js.map +1 -0
- package/dist/pipeline/phase1-verdict.d.ts +55 -0
- package/dist/pipeline/phase1-verdict.d.ts.map +1 -0
- package/dist/pipeline/phase1-verdict.js +186 -0
- package/dist/pipeline/phase1-verdict.js.map +1 -0
- package/dist/pipeline/phase2-preflight.d.ts +44 -0
- package/dist/pipeline/phase2-preflight.d.ts.map +1 -0
- package/dist/pipeline/phase2-preflight.js +120 -0
- package/dist/pipeline/phase2-preflight.js.map +1 -0
- package/dist/pipeline/swarm-orchestrator.d.ts.map +1 -1
- package/dist/pipeline/swarm-orchestrator.js +67 -5
- package/dist/pipeline/swarm-orchestrator.js.map +1 -1
- package/dist/synthesis/financial-claim-extractor.d.ts +11 -0
- package/dist/synthesis/financial-claim-extractor.d.ts.map +1 -1
- package/dist/synthesis/financial-claim-extractor.js +24 -0
- package/dist/synthesis/financial-claim-extractor.js.map +1 -1
- package/dist/synthesis/simulation-artifact-generator.d.ts.map +1 -1
- package/dist/synthesis/simulation-artifact-generator.js +28 -3
- package/dist/synthesis/simulation-artifact-generator.js.map +1 -1
- package/dist/synthesis/simulation-renderers.d.ts +1 -1
- package/dist/synthesis/simulation-renderers.d.ts.map +1 -1
- package/dist/synthesis/simulation-renderers.js +39 -13
- package/dist/synthesis/simulation-renderers.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADR-PIPELINE-089 §1 — Centralized transient-failure classification.
|
|
3
|
+
*
|
|
4
|
+
* The retry loops in `executeNaturalLanguageRoute` (src/commands/agents.ts)
|
|
5
|
+
* used to inline a substring allowlist over `Error.message`:
|
|
6
|
+
*
|
|
7
|
+
* const isRetryable = msg.includes('unavailable')
|
|
8
|
+
* || msg.includes('timeout')
|
|
9
|
+
* || msg.includes('rate exceeded')
|
|
10
|
+
* || msg.includes('econnreset')
|
|
11
|
+
* || msg.includes('econnrefused')
|
|
12
|
+
* || msg.includes('network error')
|
|
13
|
+
* || msg.includes('aborterror');
|
|
14
|
+
*
|
|
15
|
+
* Three problems with that shape:
|
|
16
|
+
*
|
|
17
|
+
* 1. `unreachable` is NOT on the list. Several adapter paths surface that
|
|
18
|
+
* word when a Cloud Run backend is down, and the retry loop then bails
|
|
19
|
+
* on attempt 1 — the exact field-report symptom on 2026-04-22.
|
|
20
|
+
* 2. It only looks at `.message`. Node/undici errors often carry the
|
|
21
|
+
* transient signal on `.code` (ECONNRESET, ETIMEDOUT) or on a wrapped
|
|
22
|
+
* HTTP `response.status` (503, 504). Both were invisible to the
|
|
23
|
+
* substring check.
|
|
24
|
+
* 3. 400-class terminal failures (contract_violation, unauthorized) never
|
|
25
|
+
* had an explicit short-circuit. A future drift that made their message
|
|
26
|
+
* match a retryable substring would silently retry three times.
|
|
27
|
+
*
|
|
28
|
+
* This module exposes:
|
|
29
|
+
* - isTransientFailure(err) — returns true when a retry has a reasonable
|
|
30
|
+
* chance of succeeding (widened allowlist + code + status + cause-chain).
|
|
31
|
+
* - isTerminalFailure(err) — returns true when retrying cannot help
|
|
32
|
+
* (payload / auth / canonical-not-found). Takes precedence over
|
|
33
|
+
* isTransientFailure when both match.
|
|
34
|
+
*
|
|
35
|
+
* Used by: the simulation retry loops at src/commands/agents.ts:4154 and
|
|
36
|
+
* :4505. Future sites should import and reuse the helper instead of
|
|
37
|
+
* re-inlining a substring list.
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* True when the failure shape suggests a retry has a reasonable chance of
|
|
41
|
+
* succeeding: network resets, timeouts, 5xx, rate limits, cold-starts.
|
|
42
|
+
*
|
|
43
|
+
* Takes precedence over isTerminalFailure when inspecting a wrapped error:
|
|
44
|
+
* callers should test `isTerminalFailure(e)` first and short-circuit if true.
|
|
45
|
+
*/
|
|
46
|
+
export declare function isTransientFailure(err: unknown): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* True when retrying cannot help: bad payload, bad credentials, canonical
|
|
49
|
+
* 404. Callers should short-circuit their retry loop on true.
|
|
50
|
+
*/
|
|
51
|
+
export declare function isTerminalFailure(err: unknown): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Best-effort classification used by the Phase 1 Health Gate when deciding
|
|
54
|
+
* whether a simulator-level failure should produce a `failed` vs `degraded`
|
|
55
|
+
* verdict.
|
|
56
|
+
*
|
|
57
|
+
* - 'transient' → the retry loop gave up but the error was retryable;
|
|
58
|
+
* environment-flake. Still counts as a failure for verdict purposes
|
|
59
|
+
* (we already retried) but tags the degradation so the user knows a
|
|
60
|
+
* re-run is likely to succeed.
|
|
61
|
+
* - 'terminal' → payload/credentials/canonical. Actionable by user.
|
|
62
|
+
* - 'unknown' → neither signature matched. Treat as terminal for
|
|
63
|
+
* verdict purposes (do not recommend a re-run) but surface the raw
|
|
64
|
+
* message so the user can see what happened.
|
|
65
|
+
*/
|
|
66
|
+
export declare function classifyFailure(err: unknown): 'transient' | 'terminal' | 'unknown';
|
|
67
|
+
//# sourceMappingURL=transient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transient.d.ts","sourceRoot":"","sources":["../../src/errors/transient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AA0JH;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAiCxD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAoBvD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,CAIlF"}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADR-PIPELINE-089 §1 — Centralized transient-failure classification.
|
|
3
|
+
*
|
|
4
|
+
* The retry loops in `executeNaturalLanguageRoute` (src/commands/agents.ts)
|
|
5
|
+
* used to inline a substring allowlist over `Error.message`:
|
|
6
|
+
*
|
|
7
|
+
* const isRetryable = msg.includes('unavailable')
|
|
8
|
+
* || msg.includes('timeout')
|
|
9
|
+
* || msg.includes('rate exceeded')
|
|
10
|
+
* || msg.includes('econnreset')
|
|
11
|
+
* || msg.includes('econnrefused')
|
|
12
|
+
* || msg.includes('network error')
|
|
13
|
+
* || msg.includes('aborterror');
|
|
14
|
+
*
|
|
15
|
+
* Three problems with that shape:
|
|
16
|
+
*
|
|
17
|
+
* 1. `unreachable` is NOT on the list. Several adapter paths surface that
|
|
18
|
+
* word when a Cloud Run backend is down, and the retry loop then bails
|
|
19
|
+
* on attempt 1 — the exact field-report symptom on 2026-04-22.
|
|
20
|
+
* 2. It only looks at `.message`. Node/undici errors often carry the
|
|
21
|
+
* transient signal on `.code` (ECONNRESET, ETIMEDOUT) or on a wrapped
|
|
22
|
+
* HTTP `response.status` (503, 504). Both were invisible to the
|
|
23
|
+
* substring check.
|
|
24
|
+
* 3. 400-class terminal failures (contract_violation, unauthorized) never
|
|
25
|
+
* had an explicit short-circuit. A future drift that made their message
|
|
26
|
+
* match a retryable substring would silently retry three times.
|
|
27
|
+
*
|
|
28
|
+
* This module exposes:
|
|
29
|
+
* - isTransientFailure(err) — returns true when a retry has a reasonable
|
|
30
|
+
* chance of succeeding (widened allowlist + code + status + cause-chain).
|
|
31
|
+
* - isTerminalFailure(err) — returns true when retrying cannot help
|
|
32
|
+
* (payload / auth / canonical-not-found). Takes precedence over
|
|
33
|
+
* isTransientFailure when both match.
|
|
34
|
+
*
|
|
35
|
+
* Used by: the simulation retry loops at src/commands/agents.ts:4154 and
|
|
36
|
+
* :4505. Future sites should import and reuse the helper instead of
|
|
37
|
+
* re-inlining a substring list.
|
|
38
|
+
*/
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// Keyword sets — lowercase compares on error.message
|
|
41
|
+
// ============================================================================
|
|
42
|
+
const TRANSIENT_MESSAGE_KEYWORDS = [
|
|
43
|
+
'unavailable',
|
|
44
|
+
'service_unavailable',
|
|
45
|
+
'unreachable',
|
|
46
|
+
'timeout',
|
|
47
|
+
'timed out',
|
|
48
|
+
'etimedout',
|
|
49
|
+
'rate exceeded',
|
|
50
|
+
'rate limit',
|
|
51
|
+
'too many requests',
|
|
52
|
+
'econnreset',
|
|
53
|
+
'connection reset',
|
|
54
|
+
'econnrefused',
|
|
55
|
+
'connection refused',
|
|
56
|
+
'enotfound',
|
|
57
|
+
'eai_again',
|
|
58
|
+
'network error',
|
|
59
|
+
'aborterror',
|
|
60
|
+
'socket hang up',
|
|
61
|
+
'und_err_socket',
|
|
62
|
+
'upstream connect error',
|
|
63
|
+
'upstream request timeout',
|
|
64
|
+
];
|
|
65
|
+
const TERMINAL_MESSAGE_KEYWORDS = [
|
|
66
|
+
'contract_violation',
|
|
67
|
+
'contract violation',
|
|
68
|
+
'invalid_payload',
|
|
69
|
+
'bad request',
|
|
70
|
+
'malformed',
|
|
71
|
+
'unauthorized',
|
|
72
|
+
'forbidden',
|
|
73
|
+
'invalid api key',
|
|
74
|
+
'invalid credentials',
|
|
75
|
+
'payload_too_large',
|
|
76
|
+
'payload too large',
|
|
77
|
+
];
|
|
78
|
+
// ============================================================================
|
|
79
|
+
// Error codes — exact match on error.code (typically Node/undici/fetch)
|
|
80
|
+
// ============================================================================
|
|
81
|
+
const TRANSIENT_ERROR_CODES = new Set([
|
|
82
|
+
'ECONNRESET',
|
|
83
|
+
'ECONNREFUSED',
|
|
84
|
+
'ETIMEDOUT',
|
|
85
|
+
'ESOCKETTIMEDOUT',
|
|
86
|
+
'ENOTFOUND',
|
|
87
|
+
'EAI_AGAIN',
|
|
88
|
+
'EPIPE',
|
|
89
|
+
'UND_ERR_SOCKET',
|
|
90
|
+
'UND_ERR_CONNECT_TIMEOUT',
|
|
91
|
+
'UND_ERR_HEADERS_TIMEOUT',
|
|
92
|
+
'UND_ERR_BODY_TIMEOUT',
|
|
93
|
+
'AbortError',
|
|
94
|
+
]);
|
|
95
|
+
// ============================================================================
|
|
96
|
+
// HTTP statuses — exact match on error.status or error.response.status
|
|
97
|
+
// ============================================================================
|
|
98
|
+
const TRANSIENT_HTTP_STATUSES = new Set([
|
|
99
|
+
408, // Request Timeout
|
|
100
|
+
425, // Too Early
|
|
101
|
+
429, // Too Many Requests (retry-after)
|
|
102
|
+
500, // Internal Server Error (often transient in Cloud Run)
|
|
103
|
+
502, // Bad Gateway
|
|
104
|
+
503, // Service Unavailable
|
|
105
|
+
504, // Gateway Timeout
|
|
106
|
+
522, // Cloudflare connection timeout
|
|
107
|
+
524, // Cloudflare a timeout occurred
|
|
108
|
+
]);
|
|
109
|
+
const TERMINAL_HTTP_STATUSES = new Set([
|
|
110
|
+
400, // Bad Request
|
|
111
|
+
401, // Unauthorized
|
|
112
|
+
403, // Forbidden
|
|
113
|
+
404, // Not Found (ambiguous — only terminal when path canonical; callers that know otherwise can override)
|
|
114
|
+
405, // Method Not Allowed
|
|
115
|
+
409, // Conflict
|
|
116
|
+
410, // Gone
|
|
117
|
+
413, // Payload Too Large
|
|
118
|
+
422, // Unprocessable Entity
|
|
119
|
+
]);
|
|
120
|
+
// ============================================================================
|
|
121
|
+
// Unwrapping helpers
|
|
122
|
+
// ============================================================================
|
|
123
|
+
const MAX_CAUSE_DEPTH = 3;
|
|
124
|
+
function extractStatus(err) {
|
|
125
|
+
if (typeof err.status === 'number')
|
|
126
|
+
return err.status;
|
|
127
|
+
if (typeof err.statusCode === 'number')
|
|
128
|
+
return err.statusCode;
|
|
129
|
+
const resp = err.response;
|
|
130
|
+
if (resp && typeof resp === 'object') {
|
|
131
|
+
if (typeof resp.status === 'number')
|
|
132
|
+
return resp.status;
|
|
133
|
+
if (typeof resp.statusCode === 'number')
|
|
134
|
+
return resp.statusCode;
|
|
135
|
+
}
|
|
136
|
+
// Parse "HTTP 503", "status 504", "504 Gateway Timeout" out of message
|
|
137
|
+
if (typeof err.message === 'string') {
|
|
138
|
+
const m = err.message.match(/\b(?:HTTP\s*)?(\d{3})\b/);
|
|
139
|
+
if (m) {
|
|
140
|
+
const n = Number(m[1]);
|
|
141
|
+
if (n >= 400 && n < 600)
|
|
142
|
+
return n;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
function extractCode(err) {
|
|
148
|
+
if (typeof err.code === 'string')
|
|
149
|
+
return err.code;
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
function extractMessage(err) {
|
|
153
|
+
if (typeof err.message === 'string')
|
|
154
|
+
return err.message.toLowerCase();
|
|
155
|
+
return '';
|
|
156
|
+
}
|
|
157
|
+
/** Walk the `.cause` chain up to MAX_CAUSE_DEPTH levels, flattening fields into an array. */
|
|
158
|
+
function unwrapChain(err) {
|
|
159
|
+
const chain = [];
|
|
160
|
+
let cur = err;
|
|
161
|
+
for (let i = 0; i <= MAX_CAUSE_DEPTH && cur; i++) {
|
|
162
|
+
if (cur && typeof cur === 'object') {
|
|
163
|
+
chain.push(cur);
|
|
164
|
+
cur = cur.cause;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return chain;
|
|
171
|
+
}
|
|
172
|
+
// ============================================================================
|
|
173
|
+
// Public API
|
|
174
|
+
// ============================================================================
|
|
175
|
+
/**
|
|
176
|
+
* True when the failure shape suggests a retry has a reasonable chance of
|
|
177
|
+
* succeeding: network resets, timeouts, 5xx, rate limits, cold-starts.
|
|
178
|
+
*
|
|
179
|
+
* Takes precedence over isTerminalFailure when inspecting a wrapped error:
|
|
180
|
+
* callers should test `isTerminalFailure(e)` first and short-circuit if true.
|
|
181
|
+
*/
|
|
182
|
+
export function isTransientFailure(err) {
|
|
183
|
+
if (err == null)
|
|
184
|
+
return false;
|
|
185
|
+
// Raw string errors: substring match only.
|
|
186
|
+
if (typeof err === 'string') {
|
|
187
|
+
const lower = err.toLowerCase();
|
|
188
|
+
return TRANSIENT_MESSAGE_KEYWORDS.some(k => lower.includes(k));
|
|
189
|
+
}
|
|
190
|
+
if (typeof err !== 'object')
|
|
191
|
+
return false;
|
|
192
|
+
const chain = unwrapChain(err);
|
|
193
|
+
for (const link of chain) {
|
|
194
|
+
// HTTP status — strongest signal.
|
|
195
|
+
const status = extractStatus(link);
|
|
196
|
+
if (status !== undefined) {
|
|
197
|
+
if (TRANSIENT_HTTP_STATUSES.has(status))
|
|
198
|
+
return true;
|
|
199
|
+
// If the status is in the terminal set, the caller should have
|
|
200
|
+
// already short-circuited via isTerminalFailure. We do NOT return
|
|
201
|
+
// false here because a wrapper may carry a transient signal elsewhere
|
|
202
|
+
// in the chain (e.g. ETIMEDOUT wrapped as HTTP 500).
|
|
203
|
+
}
|
|
204
|
+
// Error code — Node/undici/fetch.
|
|
205
|
+
const code = extractCode(link);
|
|
206
|
+
if (code && TRANSIENT_ERROR_CODES.has(code))
|
|
207
|
+
return true;
|
|
208
|
+
// Message substring — widened keyword set.
|
|
209
|
+
const msg = extractMessage(link);
|
|
210
|
+
if (msg && TRANSIENT_MESSAGE_KEYWORDS.some(k => msg.includes(k)))
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* True when retrying cannot help: bad payload, bad credentials, canonical
|
|
217
|
+
* 404. Callers should short-circuit their retry loop on true.
|
|
218
|
+
*/
|
|
219
|
+
export function isTerminalFailure(err) {
|
|
220
|
+
if (err == null)
|
|
221
|
+
return false;
|
|
222
|
+
if (typeof err === 'string') {
|
|
223
|
+
const lower = err.toLowerCase();
|
|
224
|
+
return TERMINAL_MESSAGE_KEYWORDS.some(k => lower.includes(k));
|
|
225
|
+
}
|
|
226
|
+
if (typeof err !== 'object')
|
|
227
|
+
return false;
|
|
228
|
+
const chain = unwrapChain(err);
|
|
229
|
+
for (const link of chain) {
|
|
230
|
+
const status = extractStatus(link);
|
|
231
|
+
if (status !== undefined && TERMINAL_HTTP_STATUSES.has(status))
|
|
232
|
+
return true;
|
|
233
|
+
const msg = extractMessage(link);
|
|
234
|
+
if (msg && TERMINAL_MESSAGE_KEYWORDS.some(k => msg.includes(k)))
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Best-effort classification used by the Phase 1 Health Gate when deciding
|
|
241
|
+
* whether a simulator-level failure should produce a `failed` vs `degraded`
|
|
242
|
+
* verdict.
|
|
243
|
+
*
|
|
244
|
+
* - 'transient' → the retry loop gave up but the error was retryable;
|
|
245
|
+
* environment-flake. Still counts as a failure for verdict purposes
|
|
246
|
+
* (we already retried) but tags the degradation so the user knows a
|
|
247
|
+
* re-run is likely to succeed.
|
|
248
|
+
* - 'terminal' → payload/credentials/canonical. Actionable by user.
|
|
249
|
+
* - 'unknown' → neither signature matched. Treat as terminal for
|
|
250
|
+
* verdict purposes (do not recommend a re-run) but surface the raw
|
|
251
|
+
* message so the user can see what happened.
|
|
252
|
+
*/
|
|
253
|
+
export function classifyFailure(err) {
|
|
254
|
+
if (isTerminalFailure(err))
|
|
255
|
+
return 'terminal';
|
|
256
|
+
if (isTransientFailure(err))
|
|
257
|
+
return 'transient';
|
|
258
|
+
return 'unknown';
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=transient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transient.js","sourceRoot":"","sources":["../../src/errors/transient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADR-PIPELINE-090: stderr-line → AgentEvent parser for the MCP wrapper.
|
|
3
|
+
*
|
|
4
|
+
* Extracted into its own module so unit tests can exercise the parsing
|
|
5
|
+
* without importing src/mcp/mcp-server.ts (which attaches stdin/stdout
|
|
6
|
+
* listeners at module load time — inappropriate for jest).
|
|
7
|
+
*
|
|
8
|
+
* The grammars recognized here are the actual log prefixes emitted by:
|
|
9
|
+
* - src/commands/agents.ts (ruvector simulation retry + [local] fallbacks)
|
|
10
|
+
* - src/pipeline/swarm-orchestrator.ts ([AGENTICS] [OK|FAIL|FB|!!] ...)
|
|
11
|
+
* - src/pipeline/auto-chain.ts (>> Phase N: ...)
|
|
12
|
+
* - src/pipeline/phase2-preflight.ts (via swarm-orchestrator — [PREFLIGHT] ...)
|
|
13
|
+
* - ADR-089 verdict line (Phase 1 verdict: ...)
|
|
14
|
+
*
|
|
15
|
+
* If you add a new log prefix at one of those sites, add a matching
|
|
16
|
+
* parser branch here so the event reaches the Agent Invocation Report
|
|
17
|
+
* instead of being silently dropped.
|
|
18
|
+
*/
|
|
19
|
+
export interface AgentEvent {
|
|
20
|
+
phase: number;
|
|
21
|
+
kind: 'sim-start' | 'sim-ok' | 'sim-fail' | 'sim-retry' | 'ok' | 'fail' | 'fallback' | 'preflight' | 'verdict' | 'phase-header';
|
|
22
|
+
domain?: string;
|
|
23
|
+
agent?: string;
|
|
24
|
+
role?: string;
|
|
25
|
+
timingMs?: number;
|
|
26
|
+
reason?: string;
|
|
27
|
+
raw: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Try to parse a single stderr line into an AgentEvent. Returns null for
|
|
31
|
+
* lines that aren't agent-relevant.
|
|
32
|
+
*
|
|
33
|
+
* `state.phase` is mutated when a phase header is seen, so subsequent
|
|
34
|
+
* events get tagged with the current phase. Callers pass the same state
|
|
35
|
+
* across calls for a single pipeline run.
|
|
36
|
+
*/
|
|
37
|
+
export declare function parseAgentEvent(line: string, state: {
|
|
38
|
+
phase: number;
|
|
39
|
+
}): AgentEvent | null;
|
|
40
|
+
/**
|
|
41
|
+
* One-line human-readable render of an AgentEvent for MCP progress
|
|
42
|
+
* notifications. Kept deliberately short so Claude Code's notification
|
|
43
|
+
* area doesn't truncate the useful part.
|
|
44
|
+
*/
|
|
45
|
+
export declare function formatAgentEventLive(ev: AgentEvent): string;
|
|
46
|
+
/**
|
|
47
|
+
* End-of-run Agent Invocation Report. Grouped by phase; per-phase shows
|
|
48
|
+
* ok/fail/fallback counts then a per-agent table. Always appended to the
|
|
49
|
+
* tool response so the user has a written record regardless of whether
|
|
50
|
+
* live progress notifications were rendered.
|
|
51
|
+
*/
|
|
52
|
+
export declare function formatAgentReport(events: readonly AgentEvent[], traceId?: string): string;
|
|
53
|
+
//# sourceMappingURL=agent-event-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-event-parser.d.ts","sourceRoot":"","sources":["../../src/mcp/agent-event-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,GAAG,cAAc,CAAC;IAChI,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,GAAG,IAAI,CA8DzF;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,UAAU,GAAG,MAAM,CAgB3D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAoDzF"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADR-PIPELINE-090: stderr-line → AgentEvent parser for the MCP wrapper.
|
|
3
|
+
*
|
|
4
|
+
* Extracted into its own module so unit tests can exercise the parsing
|
|
5
|
+
* without importing src/mcp/mcp-server.ts (which attaches stdin/stdout
|
|
6
|
+
* listeners at module load time — inappropriate for jest).
|
|
7
|
+
*
|
|
8
|
+
* The grammars recognized here are the actual log prefixes emitted by:
|
|
9
|
+
* - src/commands/agents.ts (ruvector simulation retry + [local] fallbacks)
|
|
10
|
+
* - src/pipeline/swarm-orchestrator.ts ([AGENTICS] [OK|FAIL|FB|!!] ...)
|
|
11
|
+
* - src/pipeline/auto-chain.ts (>> Phase N: ...)
|
|
12
|
+
* - src/pipeline/phase2-preflight.ts (via swarm-orchestrator — [PREFLIGHT] ...)
|
|
13
|
+
* - ADR-089 verdict line (Phase 1 verdict: ...)
|
|
14
|
+
*
|
|
15
|
+
* If you add a new log prefix at one of those sites, add a matching
|
|
16
|
+
* parser branch here so the event reaches the Agent Invocation Report
|
|
17
|
+
* instead of being silently dropped.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Try to parse a single stderr line into an AgentEvent. Returns null for
|
|
21
|
+
* lines that aren't agent-relevant.
|
|
22
|
+
*
|
|
23
|
+
* `state.phase` is mutated when a phase header is seen, so subsequent
|
|
24
|
+
* events get tagged with the current phase. Callers pass the same state
|
|
25
|
+
* across calls for a single pipeline run.
|
|
26
|
+
*/
|
|
27
|
+
export function parseAgentEvent(line, state) {
|
|
28
|
+
const clean = line.replace(/\x1b\[[0-9;]*m/g, '').trim();
|
|
29
|
+
if (!clean)
|
|
30
|
+
return null;
|
|
31
|
+
let m = clean.match(/^>>\s*Phase\s+(\d+):\s*(.+?)\s*$/);
|
|
32
|
+
if (m) {
|
|
33
|
+
state.phase = Number(m[1]);
|
|
34
|
+
return { phase: state.phase, kind: 'phase-header', role: m[2], raw: clean };
|
|
35
|
+
}
|
|
36
|
+
if (/^\[RUVECTOR\]\s+Running simulation/i.test(clean)) {
|
|
37
|
+
return { phase: state.phase, kind: 'sim-start', domain: 'simulator', agent: 'enterprise', raw: clean };
|
|
38
|
+
}
|
|
39
|
+
if (/^\[RUVECTOR\]\s+Simulation succeeded/i.test(clean)) {
|
|
40
|
+
return { phase: state.phase, kind: 'sim-ok', domain: 'simulator', agent: 'enterprise', raw: clean };
|
|
41
|
+
}
|
|
42
|
+
if (/^\[RUVECTOR\]\s+(Retry|Attempt\s+\d+)/i.test(clean)) {
|
|
43
|
+
return { phase: state.phase, kind: 'sim-retry', domain: 'simulator', agent: 'enterprise', reason: clean, raw: clean };
|
|
44
|
+
}
|
|
45
|
+
if (/^\[RUVECTOR\]\s+(Simulation failed|Terminal error|Non-retryable|Unrecognized error)/i.test(clean)) {
|
|
46
|
+
return { phase: state.phase, kind: 'sim-fail', domain: 'simulator', agent: 'enterprise', reason: clean, raw: clean };
|
|
47
|
+
}
|
|
48
|
+
// [AGENTICS] [OK|FAIL|FB|!!] domain/agent (role) — Nms [suffix]
|
|
49
|
+
m = clean.match(/^\[AGENTICS\]\s+\[(OK|FAIL|FB|!!)\]\s+([^/]+)\/(\S+)\s*\(([^)]+)\)\s*—\s*(\d+)ms(.*)$/);
|
|
50
|
+
if (m) {
|
|
51
|
+
const status = m[1];
|
|
52
|
+
const domain = m[2];
|
|
53
|
+
const agent = m[3];
|
|
54
|
+
const role = m[4];
|
|
55
|
+
const timingMs = Number(m[5]);
|
|
56
|
+
const suffix = (m[6] ?? '').trim();
|
|
57
|
+
const kind = status === 'OK' ? 'ok'
|
|
58
|
+
: status === 'FB' ? 'fallback'
|
|
59
|
+
: 'fail';
|
|
60
|
+
return { phase: state.phase, kind, domain, agent, role, timingMs, reason: suffix || undefined, raw: clean };
|
|
61
|
+
}
|
|
62
|
+
// [local] domain/agent using local compute[: reason] or (reason)
|
|
63
|
+
m = clean.match(/^\[local\]\s+([^/]+)\/(\S+)\s+using local compute(?:\s*(?::|\()\s*(.+?)\)?)?\s*$/);
|
|
64
|
+
if (m) {
|
|
65
|
+
return {
|
|
66
|
+
phase: state.phase,
|
|
67
|
+
kind: 'fallback',
|
|
68
|
+
domain: m[1],
|
|
69
|
+
agent: m[2],
|
|
70
|
+
reason: m[3]?.trim(),
|
|
71
|
+
raw: clean,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (/^\[PREFLIGHT\]/i.test(clean)) {
|
|
75
|
+
return { phase: state.phase, kind: 'preflight', reason: clean, raw: clean };
|
|
76
|
+
}
|
|
77
|
+
m = clean.match(/^Phase\s+1\s+verdict:\s+(HEALTHY|DEGRADED|FAILED)\s*(?:—\s*(.+))?$/i);
|
|
78
|
+
if (m) {
|
|
79
|
+
return { phase: 1, kind: 'verdict', role: m[1], reason: m[2], raw: clean };
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* One-line human-readable render of an AgentEvent for MCP progress
|
|
85
|
+
* notifications. Kept deliberately short so Claude Code's notification
|
|
86
|
+
* area doesn't truncate the useful part.
|
|
87
|
+
*/
|
|
88
|
+
export function formatAgentEventLive(ev) {
|
|
89
|
+
const tag = ev.phase > 0 ? `P${ev.phase}` : ' ';
|
|
90
|
+
const who = ev.domain && ev.agent ? `${ev.domain}/${ev.agent}` : '';
|
|
91
|
+
const time = ev.timingMs != null ? ` (${ev.timingMs}ms)` : '';
|
|
92
|
+
switch (ev.kind) {
|
|
93
|
+
case 'phase-header': return `${tag} ▶ Phase ${ev.phase}: ${ev.role ?? ''}`;
|
|
94
|
+
case 'sim-start': return `${tag} 🔄 simulator/enterprise — starting`;
|
|
95
|
+
case 'sim-ok': return `${tag} ✓ simulator/enterprise`;
|
|
96
|
+
case 'sim-retry': return `${tag} ⟳ simulator/enterprise — ${ev.reason?.slice(0, 100) ?? 'retrying'}`;
|
|
97
|
+
case 'sim-fail': return `${tag} ✗ simulator/enterprise — ${ev.reason?.slice(0, 100) ?? 'failed'}`;
|
|
98
|
+
case 'ok': return `${tag} ✓ ${who}${time}`;
|
|
99
|
+
case 'fail': return `${tag} ✗ ${who}${time}${ev.reason ? ' — ' + ev.reason.slice(0, 80) : ''}`;
|
|
100
|
+
case 'fallback': return `${tag} ⚠ ${who} — local fallback${ev.reason ? ' (' + ev.reason.slice(0, 80) + ')' : ''}`;
|
|
101
|
+
case 'preflight': return `${tag} 🔍 ${ev.reason?.replace(/^\[PREFLIGHT\]\s*/, '') ?? 'preflight'}`;
|
|
102
|
+
case 'verdict': return `${tag} 📋 Phase 1 verdict: ${ev.role}${ev.reason ? ' — ' + ev.reason : ''}`;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* End-of-run Agent Invocation Report. Grouped by phase; per-phase shows
|
|
107
|
+
* ok/fail/fallback counts then a per-agent table. Always appended to the
|
|
108
|
+
* tool response so the user has a written record regardless of whether
|
|
109
|
+
* live progress notifications were rendered.
|
|
110
|
+
*/
|
|
111
|
+
export function formatAgentReport(events, traceId) {
|
|
112
|
+
if (events.length === 0)
|
|
113
|
+
return '';
|
|
114
|
+
const lines = [];
|
|
115
|
+
lines.push('═══ Agent Invocation Report ═══');
|
|
116
|
+
if (traceId)
|
|
117
|
+
lines.push(`Trace: ${traceId}`);
|
|
118
|
+
lines.push('');
|
|
119
|
+
const byPhase = new Map();
|
|
120
|
+
for (const ev of events) {
|
|
121
|
+
if (!byPhase.has(ev.phase))
|
|
122
|
+
byPhase.set(ev.phase, []);
|
|
123
|
+
byPhase.get(ev.phase).push(ev);
|
|
124
|
+
}
|
|
125
|
+
const phases = [...byPhase.keys()].sort((a, b) => a - b);
|
|
126
|
+
for (const p of phases) {
|
|
127
|
+
const evs = byPhase.get(p);
|
|
128
|
+
const header = evs.find(e => e.kind === 'phase-header');
|
|
129
|
+
const label = header?.role ?? (p === 1 ? 'Simulation + graph-routed dispatch' : `Phase ${p}`);
|
|
130
|
+
lines.push(`Phase ${p}: ${label}`);
|
|
131
|
+
const ok = evs.filter(e => e.kind === 'ok' || e.kind === 'sim-ok').length;
|
|
132
|
+
const fail = evs.filter(e => e.kind === 'fail' || e.kind === 'sim-fail').length;
|
|
133
|
+
const fb = evs.filter(e => e.kind === 'fallback').length;
|
|
134
|
+
lines.push(` ${ok} ok · ${fail} fail · ${fb} local-fallback`);
|
|
135
|
+
const rows = evs.filter(e => e.kind === 'ok' || e.kind === 'fail' || e.kind === 'fallback' ||
|
|
136
|
+
e.kind === 'sim-ok' || e.kind === 'sim-fail');
|
|
137
|
+
for (const e of rows) {
|
|
138
|
+
const who = e.domain && e.agent ? `${e.domain}/${e.agent}` : '(unknown)';
|
|
139
|
+
const icon = e.kind === 'ok' || e.kind === 'sim-ok' ? '✓'
|
|
140
|
+
: e.kind === 'fallback' ? '⚠'
|
|
141
|
+
: '✗';
|
|
142
|
+
const time = e.timingMs != null ? `${e.timingMs}ms`.padStart(8) : ' -';
|
|
143
|
+
const source = e.kind === 'fallback' ? 'local' : (e.kind === 'fail' || e.kind === 'sim-fail' ? 'error' : 'cloud');
|
|
144
|
+
const note = e.reason ? ` — ${e.reason.slice(0, 100)}` : '';
|
|
145
|
+
lines.push(` ${icon} ${who.padEnd(40)} ${time} ${source}${note}`);
|
|
146
|
+
}
|
|
147
|
+
const verdict = evs.find(e => e.kind === 'verdict');
|
|
148
|
+
if (verdict) {
|
|
149
|
+
lines.push(` → ${verdict.role} — ${verdict.reason ?? ''}`);
|
|
150
|
+
}
|
|
151
|
+
const preflights = evs.filter(e => e.kind === 'preflight');
|
|
152
|
+
for (const pf of preflights) {
|
|
153
|
+
lines.push(` → ${pf.reason?.replace(/^\[PREFLIGHT\]\s*/, '') ?? ''}`);
|
|
154
|
+
}
|
|
155
|
+
lines.push('');
|
|
156
|
+
}
|
|
157
|
+
return lines.join('\n');
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=agent-event-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-event-parser.js","sourceRoot":"","sources":["../../src/mcp/agent-event-parser.ts"],"names":[],"mappings":"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"}
|