@brutalist/mcp 1.11.2 → 1.13.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/brutalist-server.js +1 -1
- package/dist/cli-adapters/claude-adapter.d.ts +12 -2
- package/dist/cli-adapters/claude-adapter.d.ts.map +1 -1
- package/dist/cli-adapters/claude-adapter.js +175 -38
- package/dist/cli-adapters/claude-adapter.js.map +1 -1
- package/dist/cli-adapters/codex-adapter.d.ts +18 -1
- package/dist/cli-adapters/codex-adapter.d.ts.map +1 -1
- package/dist/cli-adapters/codex-adapter.js +86 -3
- package/dist/cli-adapters/codex-adapter.js.map +1 -1
- package/dist/cli-adapters/gemini-adapter.d.ts +22 -1
- package/dist/cli-adapters/gemini-adapter.d.ts.map +1 -1
- package/dist/cli-adapters/gemini-adapter.js +100 -3
- package/dist/cli-adapters/gemini-adapter.js.map +1 -1
- package/dist/cli-adapters/index.d.ts +55 -9
- package/dist/cli-adapters/index.d.ts.map +1 -1
- package/dist/cli-adapters/index.js.map +1 -1
- package/dist/cli-agents.d.ts.map +1 -1
- package/dist/cli-agents.js +53 -56
- package/dist/cli-agents.js.map +1 -1
- package/dist/mcp-registry.d.ts +48 -4
- package/dist/mcp-registry.d.ts.map +1 -1
- package/dist/mcp-registry.js +92 -12
- package/dist/mcp-registry.js.map +1 -1
- package/package.json +1 -1
package/dist/brutalist-server.js
CHANGED
|
@@ -13,7 +13,7 @@ import { getDomain, generateToolConfig } from './registry/domains.js';
|
|
|
13
13
|
import { filterToolsByIntent, getMatchingDomainIds } from './tool-router.js';
|
|
14
14
|
import { DebateOrchestrator } from './debate/index.js';
|
|
15
15
|
// Use environment variable or fallback to manual version
|
|
16
|
-
const PACKAGE_VERSION = process.env.npm_package_version || "1.
|
|
16
|
+
const PACKAGE_VERSION = process.env.npm_package_version || "1.13.0";
|
|
17
17
|
/**
|
|
18
18
|
* BrutalistServer - Composition root for the Brutalist MCP Server
|
|
19
19
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { StructuredLogger } from '../logger.js';
|
|
2
2
|
import type { CLIAgentOptions } from '../cli-agents.js';
|
|
3
3
|
import type { ModelResolver } from '../model-resolver.js';
|
|
4
|
-
import type { CLIProvider, CLIBuilderConfig, CLIName } from './index.js';
|
|
4
|
+
import type { CLIProvider, CLIBuilderConfig, CLIName, DecodeResult } from './index.js';
|
|
5
5
|
export declare class ClaudeAdapter implements CLIProvider {
|
|
6
6
|
readonly name: CLIName;
|
|
7
7
|
getConfig(): CLIBuilderConfig;
|
|
@@ -21,6 +21,16 @@ export declare class ClaudeAdapter implements CLIProvider {
|
|
|
21
21
|
* Falls back to 'result' event if no assistant text was captured.
|
|
22
22
|
*/
|
|
23
23
|
decodeOutput(rawOutput: string, args: string[], log?: StructuredLogger): string;
|
|
24
|
-
|
|
24
|
+
decode(stdout: string, _stderr: string, args: string[], log?: StructuredLogger): DecodeResult;
|
|
25
|
+
/**
|
|
26
|
+
* Structured decode of stream-json output.
|
|
27
|
+
*
|
|
28
|
+
* Refusal classification is keyed on `result.subtype` / `is_error` —
|
|
29
|
+
* the binary's own protocol-level signal. Quota classification looks
|
|
30
|
+
* at anchored Anthropic markers ONLY in the error-envelope `result`
|
|
31
|
+
* field (already scoped to a known-error pathway), never in the
|
|
32
|
+
* accumulated assistant text.
|
|
33
|
+
*/
|
|
34
|
+
private decodeStream;
|
|
25
35
|
}
|
|
26
36
|
//# sourceMappingURL=claude-adapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-adapter.d.ts","sourceRoot":"","sources":["../../src/cli-adapters/claude-adapter.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"claude-adapter.d.ts","sourceRoot":"","sources":["../../src/cli-adapters/claude-adapter.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAoFvF,qBAAa,aAAc,YAAW,WAAW;IAC/C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAY;IAElC,SAAS,IAAI,gBAAgB;IAIvB,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,eAAe,EACxB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC;QACT,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAI5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAqGF;;;;;;OAMG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,MAAM;IAwB/E,MAAM,CACJ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,CAAC,EAAE,gBAAgB,GACrB,YAAY;IASf;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY;CAyIrB"}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { logger as rootLogger } from '../logger.js';
|
|
15
15
|
import { parseNDJSON } from './shared.js';
|
|
16
|
-
import { resolveServers, listRegisteredServers,
|
|
16
|
+
import { resolveServers, listRegisteredServers, writeClaudeMcpConfigSecure, ensurePlaywrightBrowsers, } from '../mcp-registry.js';
|
|
17
17
|
/**
|
|
18
18
|
* Cycle 4 Task T19 (F10 — security): pre-filter caller-supplied MCP
|
|
19
19
|
* server names against the registry-known set BEFORE handing them to
|
|
@@ -55,7 +55,12 @@ function sanitizeMcpServerNames(requested, log) {
|
|
|
55
55
|
}
|
|
56
56
|
const CLAUDE_CONFIG = {
|
|
57
57
|
command: 'claude',
|
|
58
|
-
|
|
58
|
+
// The binary drives non-interactive runs via NDJSON `stream-json` mode
|
|
59
|
+
// rather than the deprecated `-p`/`--print` flag. The `--input-format`
|
|
60
|
+
// help text claims it "only works with --print", but that annotation
|
|
61
|
+
// is stale — verified empirically against v2.1.142 and confirmed by
|
|
62
|
+
// the Agent SDK source, which spawns the binary without --print.
|
|
63
|
+
defaultArgs: ['--input-format', 'stream-json'],
|
|
59
64
|
modelArgName: '--model',
|
|
60
65
|
mpcEnvCleanup: ['CLAUDE_MCP_CONFIG', 'MCP_ENABLED', 'CLAUDECODE', 'CLAUDE_CODE_ENTRYPOINT'],
|
|
61
66
|
streamingArgs: () => ['--output-format', 'stream-json', '--verbose'],
|
|
@@ -99,18 +104,30 @@ export class ClaudeAdapter {
|
|
|
99
104
|
args.push(...config.streamingArgs(options));
|
|
100
105
|
}
|
|
101
106
|
// Always enforce write-tool denial and permission bypass for non-interactive
|
|
102
|
-
// tool use. In
|
|
103
|
-
// would otherwise require approval;
|
|
104
|
-
// (legal, research, security), this
|
|
105
|
-
// training-data answers instead of invoking
|
|
106
|
-
// these two flags out of the MCP conditional
|
|
107
|
-
// tools are usable in every run while preserving
|
|
108
|
-
// NotebookEdit barrier. MCP wiring below remains gated on
|
|
107
|
+
// tool use. In stream-json mode (as in the deprecated --print mode), Claude
|
|
108
|
+
// Code silently skips tool calls that would otherwise require approval;
|
|
109
|
+
// for verification-oriented prompts (legal, research, security), this
|
|
110
|
+
// caused agents to fall back to training-data answers instead of invoking
|
|
111
|
+
// WebSearch/WebFetch. Lifting these two flags out of the MCP conditional
|
|
112
|
+
// ensures native web/search tools are usable in every run while preserving
|
|
113
|
+
// the Edit/Write/NotebookEdit barrier. MCP wiring below remains gated on
|
|
114
|
+
// mcpEnabled.
|
|
109
115
|
if (config.mcpSupport) {
|
|
110
116
|
args.push(config.mcpSupport.writeProtection.flag, config.mcpSupport.writeProtection.value);
|
|
111
117
|
args.push('--permission-mode', 'bypassPermissions');
|
|
112
118
|
}
|
|
113
|
-
// MCP configuration
|
|
119
|
+
// MCP configuration — all configs route through the secure-file
|
|
120
|
+
// path. Inline JSON would put MCP server `command`, `args`, and
|
|
121
|
+
// `env` on argv where they're visible via `ps`/`/proc/<pid>/cmdline`/
|
|
122
|
+
// crash reports. Real MCP servers commonly take credentials in
|
|
123
|
+
// args (`--api-key`, `--token`, `--auth=Bearer`), not just env, so
|
|
124
|
+
// an env-only predicate would leak. One extra writeFile per spawn
|
|
125
|
+
// is rounding error against the spawn itself, and routing through
|
|
126
|
+
// a file is the only design that's robust against future MCP spec
|
|
127
|
+
// shapes we haven't anticipated.
|
|
128
|
+
//
|
|
129
|
+
// `claude --help`: `--mcp-config <configs...> Load MCP servers
|
|
130
|
+
// from JSON files or strings`. We use the path form.
|
|
114
131
|
let tempMcpConfigPath;
|
|
115
132
|
if (mcpEnabled && config.mcpSupport) {
|
|
116
133
|
// Pre-filter via sanitizeMcpServerNames — unknown names are
|
|
@@ -125,16 +142,22 @@ export class ClaudeAdapter {
|
|
|
125
142
|
}
|
|
126
143
|
if (serverNames.length > 0) {
|
|
127
144
|
const mcp = config.mcpSupport;
|
|
128
|
-
|
|
129
|
-
const sessionId = options.sessionId || 'default';
|
|
130
|
-
tempMcpConfigPath = await writeClaudeMCPConfig(servers, sessionId);
|
|
145
|
+
tempMcpConfigPath = await writeClaudeMcpConfigSecure(servers);
|
|
131
146
|
args.push(mcp.configFlag, tempMcpConfigPath);
|
|
132
147
|
args.push(mcp.strictFlag);
|
|
133
148
|
log.info(`\u{1F50C} MCP enabled for claude: [${serverNames.join(', ')}]`);
|
|
134
149
|
}
|
|
135
150
|
}
|
|
136
|
-
// Build prompt
|
|
151
|
+
// Build prompt: wrap the combined system+user text as a single NDJSON
|
|
152
|
+
// `user` message — the wire shape the binary's `--input-format
|
|
153
|
+
// stream-json` reader accepts. Caller (cli-agents.spawnAsync) pipes
|
|
154
|
+
// this string to child stdin verbatim then closes stdin, which the
|
|
155
|
+
// binary treats as end-of-turn after the first user message.
|
|
137
156
|
const combinedPrompt = `${systemPrompt}\n\n${userPrompt}`;
|
|
157
|
+
const stdinPayload = JSON.stringify({
|
|
158
|
+
type: 'user',
|
|
159
|
+
message: { role: 'user', content: combinedPrompt },
|
|
160
|
+
}) + '\n';
|
|
138
161
|
// Add CLI-specific env
|
|
139
162
|
const env = { ...secureEnv };
|
|
140
163
|
// Forward auth credentials. ANTHROPIC_API_KEY is the long-standing
|
|
@@ -154,7 +177,7 @@ export class ClaudeAdapter {
|
|
|
154
177
|
}
|
|
155
178
|
}
|
|
156
179
|
env.BRUTALIST_SUBPROCESS = '1';
|
|
157
|
-
return { command: config.command, args, input:
|
|
180
|
+
return { command: config.command, args, input: stdinPayload, env, tempMcpConfigPath, model: resolvedModel };
|
|
158
181
|
}
|
|
159
182
|
/**
|
|
160
183
|
* Decode Claude's stream-json NDJSON output into plain text.
|
|
@@ -164,21 +187,56 @@ export class ClaudeAdapter {
|
|
|
164
187
|
* Falls back to 'result' event if no assistant text was captured.
|
|
165
188
|
*/
|
|
166
189
|
decodeOutput(rawOutput, args, log) {
|
|
167
|
-
//
|
|
190
|
+
// Legacy text-only API. Preserves the pre-Phase-2 behavior matrix:
|
|
191
|
+
// - assistant text on `ok`
|
|
192
|
+
// - the redacted F8 marker when the decoder saw a structured
|
|
193
|
+
// error event (refusal, or `kind: 'error'` with reason
|
|
194
|
+
// `'unknown'` — the case that maps to "we saw a Claude error
|
|
195
|
+
// result event but couldn't classify it as quota")
|
|
196
|
+
// - '' for benign empty/malformed inputs so the orchestrator's
|
|
197
|
+
// legacy `if (decodedText) { finalOutput = decodedText }`
|
|
198
|
+
// fall-through preserves the raw-stdout pass-through path
|
|
199
|
+
//
|
|
200
|
+
// The orchestrator (cli-agents.ts) consumes `decode()` directly
|
|
201
|
+
// post-Phase-2 and never sees this shim. Kept for the three
|
|
202
|
+
// legacy proxies at cli-agents.ts:716-728 and characterization
|
|
203
|
+
// tests that pin the marker shape.
|
|
204
|
+
const result = this.decode(rawOutput, '', args, log);
|
|
205
|
+
if (result.kind === 'ok')
|
|
206
|
+
return result.text;
|
|
207
|
+
if (result.kind === 'refused')
|
|
208
|
+
return '[Claude Error] <redacted>';
|
|
209
|
+
if (result.kind === 'error' && result.reason === 'unknown') {
|
|
210
|
+
return '[Claude Error] <redacted>';
|
|
211
|
+
}
|
|
212
|
+
return '';
|
|
213
|
+
}
|
|
214
|
+
decode(stdout, _stderr, args, log) {
|
|
215
|
+
// Only structured-decode if Claude was run with stream-json format.
|
|
216
|
+
// Non-stream-json runs are pre-formatted text — pass through.
|
|
168
217
|
if (!(args.includes('--output-format') && args.includes('stream-json'))) {
|
|
169
|
-
return
|
|
218
|
+
return { kind: 'ok', text: stdout };
|
|
170
219
|
}
|
|
171
|
-
return this.
|
|
220
|
+
return this.decodeStream(stdout, log ?? rootLogger);
|
|
172
221
|
}
|
|
173
|
-
|
|
222
|
+
/**
|
|
223
|
+
* Structured decode of stream-json output.
|
|
224
|
+
*
|
|
225
|
+
* Refusal classification is keyed on `result.subtype` / `is_error` —
|
|
226
|
+
* the binary's own protocol-level signal. Quota classification looks
|
|
227
|
+
* at anchored Anthropic markers ONLY in the error-envelope `result`
|
|
228
|
+
* field (already scoped to a known-error pathway), never in the
|
|
229
|
+
* accumulated assistant text.
|
|
230
|
+
*/
|
|
231
|
+
decodeStream(ndjsonOutput, log) {
|
|
174
232
|
if (!ndjsonOutput || !ndjsonOutput.trim()) {
|
|
175
233
|
log.warn('decodeClaudeStreamJson: empty input');
|
|
176
|
-
return '';
|
|
234
|
+
return { kind: 'error', reason: 'empty' };
|
|
177
235
|
}
|
|
178
236
|
const events = parseNDJSON(ndjsonOutput, log);
|
|
179
237
|
if (events.length === 0) {
|
|
180
238
|
log.warn('decodeClaudeStreamJson: no valid JSON events found in output');
|
|
181
|
-
return '';
|
|
239
|
+
return { kind: 'error', reason: 'malformed' };
|
|
182
240
|
}
|
|
183
241
|
const textParts = [];
|
|
184
242
|
let resultText = '';
|
|
@@ -192,14 +250,23 @@ export class ClaudeAdapter {
|
|
|
192
250
|
// `CLIAgentResponse.output` field). Instead, we only track
|
|
193
251
|
// whether an error was present and classify its shape via the
|
|
194
252
|
// event subtype / is_error flag for metadata-only emission.
|
|
253
|
+
//
|
|
254
|
+
// Phase 2: the raw `result` value is still NOT logged or returned
|
|
255
|
+
// verbatim, but we DO inspect it locally to match anchored
|
|
256
|
+
// Anthropic quota markers — that classification then drives the
|
|
257
|
+
// DecodeResult.reason. The captured value never leaves this
|
|
258
|
+
// function; only the resulting `reason` enum and the subtype
|
|
259
|
+
// (already a static SDK enum) reach the caller.
|
|
195
260
|
let errorPresent = false;
|
|
196
261
|
let errorClass;
|
|
262
|
+
let errorEnvelopeText;
|
|
197
263
|
for (const event of events) {
|
|
198
264
|
if (typeof event !== 'object' || event === null)
|
|
199
265
|
continue;
|
|
200
266
|
const typedEvent = event;
|
|
201
267
|
if (typedEvent.type === 'assistant' && typedEvent.message?.content) {
|
|
202
|
-
// Extract only text blocks
|
|
268
|
+
// Extract only `text` blocks; skip `thinking`, `tool_use`,
|
|
269
|
+
// `tool_result`, image, and any future block types the binary adds.
|
|
203
270
|
const content = typedEvent.message.content;
|
|
204
271
|
if (Array.isArray(content)) {
|
|
205
272
|
for (const item of content) {
|
|
@@ -210,50 +277,120 @@ export class ClaudeAdapter {
|
|
|
210
277
|
}
|
|
211
278
|
}
|
|
212
279
|
else if (typedEvent.type === 'result') {
|
|
213
|
-
|
|
280
|
+
// Terminal sentinel. Treat as error when the subtype is exactly
|
|
281
|
+
// `error` or an `error_*` variant (SDK emits `error_max_turns`,
|
|
282
|
+
// `error_during_execution`, etc.) OR `is_error` flag is set.
|
|
283
|
+
// The `error_*` prefix is anchored by the underscore so a
|
|
284
|
+
// hypothetical forward-compat subtype like `errored_warning`
|
|
285
|
+
// or `errored_partial` does NOT trip the error path —
|
|
286
|
+
// unrecognized subtypes fall through to the resultText branch,
|
|
287
|
+
// preserving pre-migration characterization.
|
|
288
|
+
const subtype = typeof typedEvent.subtype === 'string' ? typedEvent.subtype : '';
|
|
289
|
+
const isError = subtype === 'error' || subtype.startsWith('error_') || !!typedEvent.is_error;
|
|
290
|
+
if (isError) {
|
|
214
291
|
errorPresent = true;
|
|
215
292
|
// errorClass captures only the shape of the error, not its
|
|
216
293
|
// content: the event subtype (static enum) or a fallback
|
|
217
294
|
// tag. Never the underlying `typedEvent.error` /
|
|
218
295
|
// `typedEvent.result` string value.
|
|
219
|
-
errorClass =
|
|
220
|
-
?
|
|
296
|
+
errorClass = subtype.length > 0
|
|
297
|
+
? subtype
|
|
221
298
|
: (typedEvent.is_error ? 'is_error' : 'unknown');
|
|
299
|
+
// Capture the envelope text for LOCAL anchored-marker matching
|
|
300
|
+
// only. This variable stays inside `decodeStream` — it is not
|
|
301
|
+
// returned, not logged, and not exposed via DecodeResult.
|
|
302
|
+
const envelopeRaw = typedEvent.error ?? typedEvent.result;
|
|
303
|
+
if (typeof envelopeRaw === 'string') {
|
|
304
|
+
errorEnvelopeText = envelopeRaw;
|
|
305
|
+
}
|
|
222
306
|
}
|
|
223
307
|
else if (typedEvent.result) {
|
|
224
308
|
resultText = typedEvent.result;
|
|
225
309
|
}
|
|
226
310
|
}
|
|
227
|
-
|
|
311
|
+
else if (typedEvent.type === 'control_request') {
|
|
312
|
+
// The binary should never send these in our flag set
|
|
313
|
+
// (`permission-mode bypassPermissions`, no SDK in-process MCP
|
|
314
|
+
// servers, no canUseTool callback). If we observe one, the run
|
|
315
|
+
// produced a hang or an unanswered request on the binary side
|
|
316
|
+
// — surface it for diagnosis. Replying with a `control_response`
|
|
317
|
+
// would require streaming-side stdin write (spawnAsync's
|
|
318
|
+
// onProgress path), which is out of scope here.
|
|
319
|
+
log.warn('decodeClaudeStreamJson: unexpected control_request from binary', {
|
|
320
|
+
subtype: typeof typedEvent.request?.subtype === 'string'
|
|
321
|
+
? typedEvent.request.subtype
|
|
322
|
+
: 'unknown',
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
// Silently skipped event types (informational, no decoder action
|
|
326
|
+
// needed): `system` (incl. `subtype:init`), `user`
|
|
327
|
+
// (tool_result/replay), `rate_limit_event`, `keep_alive`,
|
|
328
|
+
// `stream_event` (only with --include-partial-messages, which we
|
|
329
|
+
// never set), `control_response`, `control_cancel_request`,
|
|
330
|
+
// `transcript_mirror`, and any future top-level types.
|
|
228
331
|
}
|
|
229
|
-
//
|
|
230
|
-
//
|
|
332
|
+
// Structured refusal — the binary's own protocol-level signal said
|
|
333
|
+
// this turn errored. Classify quota vs. unknown using ONLY the
|
|
334
|
+
// error envelope (which never reaches the returned value), never
|
|
335
|
+
// the accumulated assistant text.
|
|
231
336
|
if (errorPresent) {
|
|
337
|
+
const reason = classifyClaudeErrorReason(errorEnvelopeText);
|
|
232
338
|
log.error('decodeClaudeStreamJson: Claude returned error result', {
|
|
233
339
|
errorPresent: true,
|
|
234
340
|
eventCount: events.length,
|
|
235
341
|
errorClass: errorClass ?? 'unknown',
|
|
342
|
+
reason,
|
|
236
343
|
});
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
// return shape; for now the marker keeps the existing string
|
|
242
|
-
// return type intact with zero sensitive bytes.
|
|
243
|
-
return '[Claude Error] <redacted>';
|
|
344
|
+
if (reason === 'quota') {
|
|
345
|
+
return { kind: 'refused', reason: 'quota', detail: errorClass };
|
|
346
|
+
}
|
|
347
|
+
return { kind: 'error', reason: 'unknown', detail: errorClass };
|
|
244
348
|
}
|
|
245
349
|
// Use accumulated assistant text if available, fall back to result event
|
|
246
350
|
if (textParts.length > 0) {
|
|
247
|
-
return textParts.join('\n\n');
|
|
351
|
+
return { kind: 'ok', text: textParts.join('\n\n') };
|
|
248
352
|
}
|
|
249
353
|
if (resultText) {
|
|
250
|
-
return resultText;
|
|
354
|
+
return { kind: 'ok', text: resultText };
|
|
251
355
|
}
|
|
252
356
|
log.warn('decodeClaudeStreamJson: no text content found in stream-json output', {
|
|
253
357
|
eventCount: events.length,
|
|
254
358
|
eventTypes: events.map(e => e.type).filter(Boolean)
|
|
255
359
|
});
|
|
256
|
-
return '';
|
|
360
|
+
return { kind: 'error', reason: 'empty' };
|
|
257
361
|
}
|
|
258
362
|
}
|
|
363
|
+
/**
|
|
364
|
+
* Classify a Claude error-envelope string against anchored Anthropic
|
|
365
|
+
* quota markers. Operates only on the `result.result` / `result.error`
|
|
366
|
+
* field already known to be inside an error result event — never on
|
|
367
|
+
* assistant prose. Returns 'quota' for known quota markers, 'unknown'
|
|
368
|
+
* otherwise so the caller can decide between `refused` and `error` kinds.
|
|
369
|
+
*
|
|
370
|
+
* Anchored markers chosen against Anthropic's stable error vocabulary:
|
|
371
|
+
* - "usage limit reached" — Claude Pro/Max 5-hour cap
|
|
372
|
+
* - "rate_limit_exceeded" — API error type string
|
|
373
|
+
* - "rate limit" — only inside the known-error envelope
|
|
374
|
+
* - "429" — HTTP status (envelope contains it on
|
|
375
|
+
* API-layer 429 propagation)
|
|
376
|
+
* - "5-hour limit" — Anthropic subscription cap phrase
|
|
377
|
+
* - "Limit reached" — CLI direct-quote refusal line
|
|
378
|
+
*
|
|
379
|
+
* No fallthrough to loose substrings — if none of these match, return
|
|
380
|
+
* 'unknown' and let the orchestrator surface a structured error rather
|
|
381
|
+
* than fabricating a refusal classification.
|
|
382
|
+
*/
|
|
383
|
+
function classifyClaudeErrorReason(envelope) {
|
|
384
|
+
if (!envelope)
|
|
385
|
+
return 'unknown';
|
|
386
|
+
const markers = [
|
|
387
|
+
/usage limit reached/i,
|
|
388
|
+
/rate_limit_exceeded/i,
|
|
389
|
+
/\brate limit\b/i,
|
|
390
|
+
/\b429\b/,
|
|
391
|
+
/5-hour limit/i,
|
|
392
|
+
/\blimit reached\b/i,
|
|
393
|
+
];
|
|
394
|
+
return markers.some((p) => p.test(envelope)) ? 'quota' : 'unknown';
|
|
395
|
+
}
|
|
259
396
|
//# sourceMappingURL=claude-adapter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-adapter.js","sourceRoot":"","sources":["../../src/cli-adapters/claude-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AAKpD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,
|
|
1
|
+
{"version":3,"file":"claude-adapter.js","sourceRoot":"","sources":["../../src/cli-adapters/claude-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AAKpD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,0BAA0B,EAC1B,wBAAwB,GACzB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;GAeG;AACH,SAAS,sBAAsB,CAC7B,SAAmB,EACnB,GAAqB;IAErB,IAAI,OAAO,qBAAqB,KAAK,UAAU,EAAE,CAAC;QAChD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,YAAY,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IACD,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACrB,GAAG,CAAC,IAAI,CAAC,6BAA6B,EAAE;YACtC,YAAY,EAAE,YAAY;YAC1B,UAAU,EAAE,IAAI,CAAC,MAAM;SACxB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,aAAa,GAAqB;IACtC,OAAO,EAAE,QAAQ;IACjB,uEAAuE;IACvE,uEAAuE;IACvE,qEAAqE;IACrE,oEAAoE;IACpE,iEAAiE;IACjE,WAAW,EAAE,CAAC,gBAAgB,EAAE,aAAa,CAAC;IAC9C,YAAY,EAAE,SAAS;IACvB,aAAa,EAAE,CAAC,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,wBAAwB,CAAC;IAC3F,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,iBAAiB,EAAE,aAAa,EAAE,WAAW,CAAC;IACpE,UAAU,EAAE;QACV,YAAY,EAAE,WAAW;QACzB,UAAU,EAAE,cAAc;QAC1B,UAAU,EAAE,qBAAqB;QACjC,eAAe,EAAE;YACf,MAAM,EAAE,kBAAkB;YAC1B,IAAI,EAAE,mBAAmB;YACzB,gEAAgE;YAChE,gDAAgD;YAChD,iEAAiE;YACjE,wDAAwD;YACxD,8DAA8D;YAC9D,+DAA+D;YAC/D,iEAAiE;YACjE,8DAA8D;YAC9D,yDAAyD;YACzD,oBAAoB;YACpB,KAAK,EAAE,8BAA8B;SACtC;KACF;CACF,CAAC;AAEF,MAAM,OAAO,aAAa;IACf,IAAI,GAAY,QAAQ,CAAC;IAElC,SAAS;QACP,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,UAAkB,EAClB,YAAoB,EACpB,OAAwB,EACxB,aAA4B,EAC5B,SAAiC;QAYjC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,UAAU,CAAC;QACtC,MAAM,MAAM,GAAG,aAAa,CAAC;QAC7B,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;QAEvE,aAAa;QACb,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;QACrC,MAAM,aAAa,GAAG,aAAa,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnF,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,CAAC;QAED,6EAA6E;QAC7E,4EAA4E;QAC5E,wEAAwE;QACxE,sEAAsE;QACtE,0EAA0E;QAC1E,yEAAyE;QACzE,2EAA2E;QAC3E,yEAAyE;QACzE,cAAc;QACd,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAC3F,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAC;QACtD,CAAC;QAED,gEAAgE;QAChE,gEAAgE;QAChE,sEAAsE;QACtE,+DAA+D;QAC/D,mEAAmE;QACnE,kEAAkE;QAClE,kEAAkE;QAClE,kEAAkE;QAClE,iCAAiC;QACjC,EAAE;QACF,gEAAgE;QAChE,qDAAqD;QACrD,IAAI,iBAAqC,CAAC;QAC1C,IAAI,UAAU,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACpC,4DAA4D;YAC5D,iDAAiD;YACjD,4BAA4B;YAC5B,MAAM,cAAc,GAAG,sBAAsB,CAAC,OAAO,CAAC,UAAW,EAAE,GAAG,CAAC,CAAC;YACxE,MAAM,OAAO,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;YAC/C,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAEzC,8DAA8D;YAC9D,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;gBACvB,MAAM,wBAAwB,EAAE,CAAC;YACnC,CAAC;YAED,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC;gBAC9B,iBAAiB,GAAG,MAAM,0BAA0B,CAAC,OAAO,CAAC,CAAC;gBAC9D,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAW,EAAE,iBAAiB,CAAC,CAAC;gBAC9C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAW,CAAC,CAAC;gBAE3B,GAAG,CAAC,IAAI,CAAC,sCAAsC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,+DAA+D;QAC/D,oEAAoE;QACpE,mEAAmE;QACnE,6DAA6D;QAC7D,MAAM,cAAc,GAAG,GAAG,YAAY,OAAO,UAAU,EAAE,CAAC;QAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC;YAClC,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE;SACnD,CAAC,GAAG,IAAI,CAAC;QAEV,uBAAuB;QACvB,MAAM,GAAG,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC;QAE7B,mEAAmE;QACnE,+DAA+D;QAC/D,gEAAgE;QAChE,gEAAgE;QAChE,qDAAqD;QACrD,MAAM,cAAc,GAAG,CAAC,mBAAmB,EAAE,yBAAyB,CAAC,CAAC;QACxE,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACjC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;QACrD,CAAC;QAED,8EAA8E;QAC9E,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACxC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;gBAC1C,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;QAED,GAAG,CAAC,oBAAoB,GAAG,GAAG,CAAC;QAE/B,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,iBAAiB,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;IAC9G,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CAAC,SAAiB,EAAE,IAAc,EAAE,GAAsB;QACpE,mEAAmE;QACnE,6BAA6B;QAC7B,+DAA+D;QAC/D,2DAA2D;QAC3D,iEAAiE;QACjE,uDAAuD;QACvD,iEAAiE;QACjE,8DAA8D;QAC9D,8DAA8D;QAC9D,EAAE;QACF,gEAAgE;QAChE,4DAA4D;QAC5D,+DAA+D;QAC/D,mCAAmC;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QACrD,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,2BAA2B,CAAC;QAClE,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC3D,OAAO,2BAA2B,CAAC;QACrC,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,CACJ,MAAc,EACd,OAAe,EACf,IAAc,EACd,GAAsB;QAEtB,oEAAoE;QACpE,8DAA8D;QAC9D,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;YACxE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACtC,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,CAAC;IACtD,CAAC;IAED;;;;;;;;OAQG;IACK,YAAY,CAAC,YAAoB,EAAE,GAAqB;QAC9D,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;YAC1C,GAAG,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;YAChD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QAC5C,CAAC;QAED,MAAM,MAAM,GAAG,WAAW,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAE9C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,GAAG,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;YACzE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QAChD,CAAC;QAED,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,IAAI,UAAU,GAAG,EAAE,CAAC;QACpB,0DAA0D;QAC1D,+DAA+D;QAC/D,8DAA8D;QAC9D,gEAAgE;QAChE,gEAAgE;QAChE,8DAA8D;QAC9D,mDAAmD;QACnD,2DAA2D;QAC3D,8DAA8D;QAC9D,4DAA4D;QAC5D,EAAE;QACF,kEAAkE;QAClE,2DAA2D;QAC3D,gEAAgE;QAChE,4DAA4D;QAC5D,6DAA6D;QAC7D,gDAAgD;QAChD,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,IAAI,UAA8B,CAAC;QACnC,IAAI,iBAAqC,CAAC;QAE1C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;gBAAE,SAAS;YAE1D,MAAM,UAAU,GAAG,KAA4B,CAAC;YAEhD,IAAI,UAAU,CAAC,IAAI,KAAK,WAAW,IAAI,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;gBACnE,2DAA2D;gBAC3D,oEAAoE;gBACpE,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC;gBAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC3B,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;wBAC3B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;4BACtC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBAC5B,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,UAAU,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACxC,gEAAgE;gBAChE,gEAAgE;gBAChE,6DAA6D;gBAC7D,0DAA0D;gBAC1D,6DAA6D;gBAC7D,sDAAsD;gBACtD,+DAA+D;gBAC/D,6CAA6C;gBAC7C,MAAM,OAAO,GAAG,OAAO,UAAU,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjF,MAAM,OAAO,GAAG,OAAO,KAAK,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAC7F,IAAI,OAAO,EAAE,CAAC;oBACZ,YAAY,GAAG,IAAI,CAAC;oBACpB,2DAA2D;oBAC3D,yDAAyD;oBACzD,iDAAiD;oBACjD,oCAAoC;oBACpC,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC;wBAC7B,CAAC,CAAC,OAAO;wBACT,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;oBACnD,+DAA+D;oBAC/D,8DAA8D;oBAC9D,0DAA0D;oBAC1D,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,IAAI,UAAU,CAAC,MAAM,CAAC;oBAC1D,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;wBACpC,iBAAiB,GAAG,WAAW,CAAC;oBAClC,CAAC;gBACH,CAAC;qBAAM,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;oBAC7B,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC;gBACjC,CAAC;YACH,CAAC;iBAAM,IAAI,UAAU,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;gBACjD,qDAAqD;gBACrD,8DAA8D;gBAC9D,+DAA+D;gBAC/D,8DAA8D;gBAC9D,iEAAiE;gBACjE,yDAAyD;gBACzD,gDAAgD;gBAChD,GAAG,CAAC,IAAI,CAAC,gEAAgE,EAAE;oBACzE,OAAO,EAAE,OAAO,UAAU,CAAC,OAAO,EAAE,OAAO,KAAK,QAAQ;wBACtD,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO;wBAC5B,CAAC,CAAC,SAAS;iBACd,CAAC,CAAC;YACL,CAAC;YACD,iEAAiE;YACjE,mDAAmD;YACnD,0DAA0D;YAC1D,iEAAiE;YACjE,4DAA4D;YAC5D,uDAAuD;QACzD,CAAC;QAED,mEAAmE;QACnE,+DAA+D;QAC/D,iEAAiE;QACjE,kCAAkC;QAClC,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,yBAAyB,CAAC,iBAAiB,CAAC,CAAC;YAC5D,GAAG,CAAC,KAAK,CAAC,sDAAsD,EAAE;gBAChE,YAAY,EAAE,IAAI;gBAClB,UAAU,EAAE,MAAM,CAAC,MAAM;gBACzB,UAAU,EAAE,UAAU,IAAI,SAAS;gBACnC,MAAM;aACP,CAAC,CAAC;YACH,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBACvB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;YAClE,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;QAClE,CAAC;QAED,yEAAyE;QACzE,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACtD,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QAC1C,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,qEAAqE,EAAE;YAC9E,UAAU,EAAE,MAAM,CAAC,MAAM;YACzB,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAE,CAAS,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;SAC7D,CAAC,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC5C,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAS,yBAAyB,CAAC,QAA4B;IAC7D,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChC,MAAM,OAAO,GAAG;QACd,sBAAsB;QACtB,sBAAsB;QACtB,iBAAiB;QACjB,SAAS;QACT,eAAe;QACf,oBAAoB;KACrB,CAAC;IACF,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACrE,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { StructuredLogger } from '../logger.js';
|
|
2
2
|
import type { CLIAgentOptions } from '../cli-agents.js';
|
|
3
3
|
import type { ModelResolver } from '../model-resolver.js';
|
|
4
|
-
import type { CLIProvider, CLIBuilderConfig, CLIName } from './index.js';
|
|
4
|
+
import type { CLIProvider, CLIBuilderConfig, CLIName, DecodeResult } from './index.js';
|
|
5
5
|
export declare class CodexAdapter implements CLIProvider {
|
|
6
6
|
readonly name: CLIName;
|
|
7
7
|
getConfig(): CLIBuilderConfig;
|
|
@@ -19,6 +19,23 @@ export declare class CodexAdapter implements CLIProvider {
|
|
|
19
19
|
* command_execution, and error events.
|
|
20
20
|
*/
|
|
21
21
|
decodeOutput(rawOutput: string, args: string[], log?: StructuredLogger): string;
|
|
22
|
+
decode(stdout: string, stderr: string, args: string[], log?: StructuredLogger): DecodeResult;
|
|
23
|
+
/**
|
|
24
|
+
* Structured decode of Codex --json output.
|
|
25
|
+
*
|
|
26
|
+
* Codex emits NDJSON `item.completed` events. Agent text comes in
|
|
27
|
+
* `item.type === 'agent_message'`. Codex error/quota state is NOT in
|
|
28
|
+
* the JSON event stream — per the inline comment in extractCodexAgentMessage
|
|
29
|
+
* ("error: will be in stderr"), it lands on stderr. So:
|
|
30
|
+
* - assistant text present → ok
|
|
31
|
+
* - no text + stderr matches anchored Codex quota markers → refused
|
|
32
|
+
* - no text + no markers → error (empty)
|
|
33
|
+
*
|
|
34
|
+
* Anchored markers operate only on stderr (the CLI's own error
|
|
35
|
+
* channel), never on assistant prose. Aligned with the discipline
|
|
36
|
+
* applied to Claude's error envelope.
|
|
37
|
+
*/
|
|
38
|
+
private decodeStream;
|
|
22
39
|
private extractCodexAgentMessage;
|
|
23
40
|
}
|
|
24
41
|
//# sourceMappingURL=codex-adapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-adapter.d.ts","sourceRoot":"","sources":["../../src/cli-adapters/codex-adapter.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"codex-adapter.d.ts","sourceRoot":"","sources":["../../src/cli-adapters/codex-adapter.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAoEvF,qBAAa,YAAa,YAAW,WAAW;IAC9C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAW;IAEjC,SAAS,IAAI,gBAAgB;IAIvB,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,eAAe,EACxB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC;QACT,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IA0EF;;;;OAIG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,MAAM;IAO/E,MAAM,CACJ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,CAAC,EAAE,gBAAgB,GACrB,YAAY;IAQf;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,YAAY;IAgCpB,OAAO,CAAC,wBAAwB;CAqCjC"}
|
|
@@ -141,11 +141,55 @@ export class CodexAdapter {
|
|
|
141
141
|
* command_execution, and error events.
|
|
142
142
|
*/
|
|
143
143
|
decodeOutput(rawOutput, args, log) {
|
|
144
|
-
//
|
|
144
|
+
// Legacy text-only API. Returns assistant text on success, empty
|
|
145
|
+
// string on refusal/error.
|
|
146
|
+
const result = this.decode(rawOutput, '', args, log);
|
|
147
|
+
return result.kind === 'ok' ? result.text : '';
|
|
148
|
+
}
|
|
149
|
+
decode(stdout, stderr, args, log) {
|
|
150
|
+
// Only structured-decode if Codex was run with --json
|
|
145
151
|
if (!args.includes('--json')) {
|
|
146
|
-
return
|
|
152
|
+
return { kind: 'ok', text: stdout };
|
|
153
|
+
}
|
|
154
|
+
return this.decodeStream(stdout, stderr, log ?? rootLogger);
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Structured decode of Codex --json output.
|
|
158
|
+
*
|
|
159
|
+
* Codex emits NDJSON `item.completed` events. Agent text comes in
|
|
160
|
+
* `item.type === 'agent_message'`. Codex error/quota state is NOT in
|
|
161
|
+
* the JSON event stream — per the inline comment in extractCodexAgentMessage
|
|
162
|
+
* ("error: will be in stderr"), it lands on stderr. So:
|
|
163
|
+
* - assistant text present → ok
|
|
164
|
+
* - no text + stderr matches anchored Codex quota markers → refused
|
|
165
|
+
* - no text + no markers → error (empty)
|
|
166
|
+
*
|
|
167
|
+
* Anchored markers operate only on stderr (the CLI's own error
|
|
168
|
+
* channel), never on assistant prose. Aligned with the discipline
|
|
169
|
+
* applied to Claude's error envelope.
|
|
170
|
+
*/
|
|
171
|
+
decodeStream(jsonOutput, stderr, log) {
|
|
172
|
+
if (!jsonOutput || !jsonOutput.trim()) {
|
|
173
|
+
// No stdout at all — could be a refusal that printed only to
|
|
174
|
+
// stderr. Check anchored markers there before declaring empty.
|
|
175
|
+
const refusalFromStderr = classifyCodexStderrReason(stderr);
|
|
176
|
+
if (refusalFromStderr === 'quota') {
|
|
177
|
+
return { kind: 'refused', reason: 'quota' };
|
|
178
|
+
}
|
|
179
|
+
log.debug('extractCodexAgentMessage: empty input');
|
|
180
|
+
return { kind: 'error', reason: 'empty' };
|
|
147
181
|
}
|
|
148
|
-
|
|
182
|
+
const text = this.extractCodexAgentMessage(jsonOutput, log);
|
|
183
|
+
if (text.length > 0) {
|
|
184
|
+
return { kind: 'ok', text };
|
|
185
|
+
}
|
|
186
|
+
// No agent_message extracted. Examine stderr for anchored Codex
|
|
187
|
+
// refusal markers — the only place codex puts quota state.
|
|
188
|
+
const refusalFromStderr = classifyCodexStderrReason(stderr);
|
|
189
|
+
if (refusalFromStderr === 'quota') {
|
|
190
|
+
return { kind: 'refused', reason: 'quota' };
|
|
191
|
+
}
|
|
192
|
+
return { kind: 'error', reason: 'empty' };
|
|
149
193
|
}
|
|
150
194
|
extractCodexAgentMessage(jsonOutput, log) {
|
|
151
195
|
if (!jsonOutput || !jsonOutput.trim()) {
|
|
@@ -179,4 +223,43 @@ export class CodexAdapter {
|
|
|
179
223
|
return result;
|
|
180
224
|
}
|
|
181
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Classify Codex stderr against anchored OpenAI/Codex quota markers.
|
|
228
|
+
* Operates only on stderr (the CLI's own error channel), never on
|
|
229
|
+
* assistant prose. Returns 'quota' on a positive match, 'unknown'
|
|
230
|
+
* otherwise.
|
|
231
|
+
*
|
|
232
|
+
* Anchored markers chosen against the literal strings Codex / the
|
|
233
|
+
* OpenAI API surface in error envelopes:
|
|
234
|
+
* - "rate_limit_exceeded" — API error code
|
|
235
|
+
* - "insufficient_quota" — API error code
|
|
236
|
+
* - "quota_exceeded" — alt error code
|
|
237
|
+
* - "429" — HTTP status
|
|
238
|
+
* - "Too Many Requests" — HTTP reason phrase
|
|
239
|
+
* - "usage cap" — ChatGPT plan cap phrasing
|
|
240
|
+
* - "ChatGPT Plus" + "limit" — paired marker for plan caps
|
|
241
|
+
*
|
|
242
|
+
* No loose `quota`/`limit`/`rate limit` patterns — those bit us in
|
|
243
|
+
* Phase 1. Stay anchored to literal vendor error strings.
|
|
244
|
+
*/
|
|
245
|
+
function classifyCodexStderrReason(stderr) {
|
|
246
|
+
if (!stderr)
|
|
247
|
+
return 'unknown';
|
|
248
|
+
const markers = [
|
|
249
|
+
/rate_limit_exceeded/i,
|
|
250
|
+
/insufficient_quota/i,
|
|
251
|
+
/quota_exceeded/i,
|
|
252
|
+
/\b429\b/,
|
|
253
|
+
/Too Many Requests/i,
|
|
254
|
+
/usage cap/i,
|
|
255
|
+
];
|
|
256
|
+
if (markers.some((p) => p.test(stderr)))
|
|
257
|
+
return 'quota';
|
|
258
|
+
// Paired marker — "ChatGPT Plus" alongside "limit" indicates the plan
|
|
259
|
+
// cap. Required as a pair so the word "limit" alone never fires.
|
|
260
|
+
if (/ChatGPT (?:Plus|Pro|Team|Enterprise)/i.test(stderr) && /\blimit\b/i.test(stderr)) {
|
|
261
|
+
return 'quota';
|
|
262
|
+
}
|
|
263
|
+
return 'unknown';
|
|
264
|
+
}
|
|
182
265
|
//# sourceMappingURL=codex-adapter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-adapter.js","sourceRoot":"","sources":["../../src/cli-adapters/codex-adapter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"codex-adapter.js","sourceRoot":"","sources":["../../src/cli-adapters/codex-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { StructuredLogger } from '../logger.js';
|
|
2
2
|
import type { CLIAgentOptions } from '../cli-agents.js';
|
|
3
3
|
import type { ModelResolver } from '../model-resolver.js';
|
|
4
|
-
import type { CLIProvider, CLIBuilderConfig, CLIName } from './index.js';
|
|
4
|
+
import type { CLIProvider, CLIBuilderConfig, CLIName, DecodeResult } from './index.js';
|
|
5
5
|
/**
|
|
6
6
|
* Frontier Gemini model chain.
|
|
7
7
|
*
|
|
@@ -58,6 +58,27 @@ export declare class GeminiAdapter implements CLIProvider {
|
|
|
58
58
|
* Parses a single JSON object and returns the `response` field.
|
|
59
59
|
*/
|
|
60
60
|
decodeOutput(rawOutput: string, args: string[], log?: StructuredLogger): string;
|
|
61
|
+
decode(stdout: string, stderr: string, args: string[], log?: StructuredLogger): DecodeResult;
|
|
62
|
+
/**
|
|
63
|
+
* Structured decode of Gemini --output-format json output.
|
|
64
|
+
*
|
|
65
|
+
* Gemini exits 0 on quota and bakes the refusal text into the
|
|
66
|
+
* `response` field itself — there is no envelope-level signal in the
|
|
67
|
+
* stdout JSON to distinguish a real answer from a refusal. So:
|
|
68
|
+
* - parse stdout; non-empty `response` → ok (best-effort; we can't
|
|
69
|
+
* tell the difference here without prose matching, which we
|
|
70
|
+
* explicitly refuse to do)
|
|
71
|
+
* - empty/missing `response`, or unparseable stdout, AND stderr
|
|
72
|
+
* matches anchored Google API quota markers → refused (quota)
|
|
73
|
+
* - empty + no anchored markers → error (empty/malformed)
|
|
74
|
+
*
|
|
75
|
+
* Per the user direction for Phase 2: anchored stderr markers only.
|
|
76
|
+
* No fallback to loose patterns. The honest residual is that a
|
|
77
|
+
* gemini quota that prints ONLY to `response` (no stderr signal)
|
|
78
|
+
* passes through as a normal response — surfaced to the caller as
|
|
79
|
+
* agent output. That is documented and accepted.
|
|
80
|
+
*/
|
|
81
|
+
private decodeJson;
|
|
61
82
|
private extractGeminiResponse;
|
|
62
83
|
}
|
|
63
84
|
//# sourceMappingURL=gemini-adapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini-adapter.d.ts","sourceRoot":"","sources":["../../src/cli-adapters/gemini-adapter.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"gemini-adapter.d.ts","sourceRoot":"","sources":["../../src/cli-adapters/gemini-adapter.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAkEvF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAIjD,CAAC;AAIH,qBAAa,aAAc,YAAW,WAAW;IAC/C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAY;IAElC,SAAS,IAAI,gBAAgB;IAIvB,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,eAAe,EACxB,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC;QACT,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IA6DF;;;OAGG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,MAAM;IAM/E,MAAM,CACJ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,CAAC,EAAE,gBAAgB,GACrB,YAAY;IAQf;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,UAAU;IA6ClB,OAAO,CAAC,qBAAqB;CA2B9B"}
|