@brutalist/mcp 1.8.1 → 1.9.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/README.md +26 -0
- package/dist/brutalist-server.d.ts +31 -9
- package/dist/brutalist-server.d.ts.map +1 -1
- package/dist/brutalist-server.js +107 -673
- package/dist/brutalist-server.js.map +1 -1
- package/dist/cli-adapters/claude-adapter.d.ts +25 -0
- package/dist/cli-adapters/claude-adapter.d.ts.map +1 -0
- package/dist/cli-adapters/claude-adapter.js +245 -0
- package/dist/cli-adapters/claude-adapter.js.map +1 -0
- package/dist/cli-adapters/codex-adapter.d.ts +23 -0
- package/dist/cli-adapters/codex-adapter.d.ts.map +1 -0
- package/dist/cli-adapters/codex-adapter.js +173 -0
- package/dist/cli-adapters/codex-adapter.js.map +1 -0
- package/dist/cli-adapters/gemini-adapter.d.ts +50 -0
- package/dist/cli-adapters/gemini-adapter.d.ts.map +1 -0
- package/dist/cli-adapters/gemini-adapter.js +196 -0
- package/dist/cli-adapters/gemini-adapter.js.map +1 -0
- package/dist/cli-adapters/index.d.ts +75 -0
- package/dist/cli-adapters/index.d.ts.map +1 -0
- package/dist/cli-adapters/index.js +29 -0
- package/dist/cli-adapters/index.js.map +1 -0
- package/dist/cli-adapters/shared.d.ts +12 -0
- package/dist/cli-adapters/shared.d.ts.map +1 -0
- package/dist/cli-adapters/shared.js +99 -0
- package/dist/cli-adapters/shared.js.map +1 -0
- package/dist/cli-agents.d.ts +64 -2
- package/dist/cli-agents.d.ts.map +1 -1
- package/dist/cli-agents.js +341 -394
- package/dist/cli-agents.js.map +1 -1
- package/dist/debate/constitutional.d.ts +27 -0
- package/dist/debate/constitutional.d.ts.map +1 -0
- package/dist/debate/constitutional.js +74 -0
- package/dist/debate/constitutional.js.map +1 -0
- package/dist/debate/debate-orchestrator.d.ts +154 -0
- package/dist/debate/debate-orchestrator.d.ts.map +1 -0
- package/dist/debate/debate-orchestrator.js +699 -0
- package/dist/debate/debate-orchestrator.js.map +1 -0
- package/dist/debate/index.d.ts +18 -0
- package/dist/debate/index.d.ts.map +1 -0
- package/dist/debate/index.js +18 -0
- package/dist/debate/index.js.map +1 -0
- package/dist/debate/refusal-detection.d.ts +27 -0
- package/dist/debate/refusal-detection.d.ts.map +1 -0
- package/dist/debate/refusal-detection.js +62 -0
- package/dist/debate/refusal-detection.js.map +1 -0
- package/dist/debate/synthesis.d.ts +22 -0
- package/dist/debate/synthesis.d.ts.map +1 -0
- package/dist/debate/synthesis.js +117 -0
- package/dist/debate/synthesis.js.map +1 -0
- package/dist/logger.d.ts +204 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +398 -18
- package/dist/logger.js.map +1 -1
- package/dist/metrics/counter.d.ts +24 -0
- package/dist/metrics/counter.d.ts.map +1 -0
- package/dist/metrics/counter.js +60 -0
- package/dist/metrics/counter.js.map +1 -0
- package/dist/metrics/histogram.d.ts +42 -0
- package/dist/metrics/histogram.d.ts.map +1 -0
- package/dist/metrics/histogram.js +114 -0
- package/dist/metrics/histogram.js.map +1 -0
- package/dist/metrics/index.d.ts +26 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +22 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/registry.d.ts +96 -0
- package/dist/metrics/registry.d.ts.map +1 -0
- package/dist/metrics/registry.js +113 -0
- package/dist/metrics/registry.js.map +1 -0
- package/dist/metrics/safe-metric.d.ts +25 -0
- package/dist/metrics/safe-metric.d.ts.map +1 -0
- package/dist/metrics/safe-metric.js +41 -0
- package/dist/metrics/safe-metric.js.map +1 -0
- package/dist/metrics/types.d.ts +82 -0
- package/dist/metrics/types.d.ts.map +1 -0
- package/dist/metrics/types.js +121 -0
- package/dist/metrics/types.js.map +1 -0
- package/dist/registry/argument-spaces.d.ts.map +1 -1
- package/dist/registry/argument-spaces.js +20 -0
- package/dist/registry/argument-spaces.js.map +1 -1
- package/dist/registry/domains.d.ts.map +1 -1
- package/dist/registry/domains.js +17 -1
- package/dist/registry/domains.js.map +1 -1
- package/dist/streaming/circuit-breaker.d.ts +13 -1
- package/dist/streaming/circuit-breaker.d.ts.map +1 -1
- package/dist/streaming/circuit-breaker.js +13 -1
- package/dist/streaming/circuit-breaker.js.map +1 -1
- package/dist/streaming/intelligent-buffer.d.ts +13 -1
- package/dist/streaming/intelligent-buffer.d.ts.map +1 -1
- package/dist/streaming/intelligent-buffer.js +13 -1
- package/dist/streaming/intelligent-buffer.js.map +1 -1
- package/dist/streaming/output-parser.d.ts +16 -2
- package/dist/streaming/output-parser.d.ts.map +1 -1
- package/dist/streaming/output-parser.js +16 -2
- package/dist/streaming/output-parser.js.map +1 -1
- package/dist/streaming/progress-tracker.d.ts +14 -1
- package/dist/streaming/progress-tracker.d.ts.map +1 -1
- package/dist/streaming/progress-tracker.js +14 -1
- package/dist/streaming/progress-tracker.js.map +1 -1
- package/dist/streaming/session-manager.d.ts +14 -1
- package/dist/streaming/session-manager.d.ts.map +1 -1
- package/dist/streaming/session-manager.js +14 -1
- package/dist/streaming/session-manager.js.map +1 -1
- package/dist/streaming/sse-transport.d.ts +12 -1
- package/dist/streaming/sse-transport.d.ts.map +1 -1
- package/dist/streaming/sse-transport.js +12 -1
- package/dist/streaming/sse-transport.js.map +1 -1
- package/dist/streaming/streaming-orchestrator.d.ts +15 -1
- package/dist/streaming/streaming-orchestrator.d.ts.map +1 -1
- package/dist/streaming/streaming-orchestrator.js +15 -1
- package/dist/streaming/streaming-orchestrator.js.map +1 -1
- package/dist/system-prompts.d.ts.map +1 -1
- package/dist/system-prompts.js +490 -4
- package/dist/system-prompts.js.map +1 -1
- package/dist/tool-definitions-generated.d.ts.map +1 -1
- package/dist/tool-definitions-generated.js +3 -1
- package/dist/tool-definitions-generated.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-adapter.js","sourceRoot":"","sources":["../../src/cli-adapters/codex-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { StructuredLogger } from '../logger.js';
|
|
2
|
+
import type { CLIAgentOptions } from '../cli-agents.js';
|
|
3
|
+
import type { ModelResolver } from '../model-resolver.js';
|
|
4
|
+
import type { CLIProvider, CLIBuilderConfig, CLIName } from './index.js';
|
|
5
|
+
/**
|
|
6
|
+
* Frontier Gemini model chain.
|
|
7
|
+
*
|
|
8
|
+
* Ordered by preference: newest frontier preview → previous frontier preview
|
|
9
|
+
* → stable last-gen frontier. The orchestrator rotates through this chain
|
|
10
|
+
* on saturation failures (429 / "No capacity available"), trading "freshest
|
|
11
|
+
* capability" for "delivered response" as preview tiers are exhausted.
|
|
12
|
+
*
|
|
13
|
+
* Rationale: Gemini CLI's default Auto routing resolves to
|
|
14
|
+
* `gemini-2.5-flash-lite` for prompts the router classifies as "simple" —
|
|
15
|
+
* a classification our full adversarial verification protocol apparently
|
|
16
|
+
* does not escape. flash-lite lacks the capacity to maintain URL/quote
|
|
17
|
+
* source-provenance across 5+ citation verification loads, so it
|
|
18
|
+
* fabricates. Pinning the heaviest tier-3 model trades the Auto router's
|
|
19
|
+
* variable downselect for predictable frontier capacity; rotation handles
|
|
20
|
+
* the preview tier's variable availability.
|
|
21
|
+
*
|
|
22
|
+
* Probe-tested 2026-04-21 in Gemini CLI 0.30: the strings below are the
|
|
23
|
+
* only ones the CLI accepts for the tier-3 frontier. `gemini-3-pro`,
|
|
24
|
+
* `gemini-3.1-pro`, `gemini-3.0-pro`, `gemini-3-flash`, `gemini-3-pro-exp`,
|
|
25
|
+
* `gemini-3-pro-002`, and `gemini-pro-3` all return ModelNotFoundError.
|
|
26
|
+
* The `-preview` suffix is required for the 3.x tier.
|
|
27
|
+
*
|
|
28
|
+
* Override the whole chain with a single model via BRUTALIST_GEMINI_MODEL=...
|
|
29
|
+
* (disables rotation — operator takes responsibility for availability).
|
|
30
|
+
* Passing `models.gemini` on a tool call similarly disables rotation.
|
|
31
|
+
*/
|
|
32
|
+
export declare const GEMINI_FRONTIER_CHAIN: readonly string[];
|
|
33
|
+
export declare class GeminiAdapter implements CLIProvider {
|
|
34
|
+
readonly name: CLIName;
|
|
35
|
+
getConfig(): CLIBuilderConfig;
|
|
36
|
+
buildCommand(userPrompt: string, systemPrompt: string, options: CLIAgentOptions, modelResolver: ModelResolver, secureEnv: Record<string, string>): Promise<{
|
|
37
|
+
command: string;
|
|
38
|
+
args: string[];
|
|
39
|
+
input: string;
|
|
40
|
+
env: Record<string, string>;
|
|
41
|
+
tempMcpConfigPath?: string;
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* Extract response text from Gemini --output-format json output.
|
|
45
|
+
* Parses a single JSON object and returns the `response` field.
|
|
46
|
+
*/
|
|
47
|
+
decodeOutput(rawOutput: string, args: string[], log?: StructuredLogger): string;
|
|
48
|
+
private extractGeminiResponse;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=gemini-adapter.d.ts.map
|
|
@@ -0,0 +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;AAkEzE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;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;KAC5B,CAAC;IA6DF;;;OAGG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,MAAM;IAQ/E,OAAO,CAAC,qBAAqB;CA2B9B"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gemini CLI Adapter
|
|
3
|
+
*
|
|
4
|
+
* Encapsulates Gemini-specific CLI configuration, command construction,
|
|
5
|
+
* and output decoding (JSON response field extraction).
|
|
6
|
+
*
|
|
7
|
+
* Pattern A (integrate-observability): logger is threaded via
|
|
8
|
+
* CLIAgentOptions.log (buildCommand) and the optional `log` parameter on
|
|
9
|
+
* decodeOutput. Falls back to the root logger singleton when absent so
|
|
10
|
+
* legacy test proxies keep working.
|
|
11
|
+
*/
|
|
12
|
+
import { logger as rootLogger } from '../logger.js';
|
|
13
|
+
import { resolveServers, listRegisteredServers, ensureGeminiMCPServers, } from '../mcp-registry.js';
|
|
14
|
+
/**
|
|
15
|
+
* Cycle 4 Task T19 (F10 — security): pre-filter caller-supplied MCP
|
|
16
|
+
* server names against the registry-known set BEFORE handing them to
|
|
17
|
+
* `resolveServers`. Unknown names must not reach
|
|
18
|
+
* `mcp-registry.ts:75` where they would be interpolated raw into the
|
|
19
|
+
* warning message. Emits only bounded metadata (counts) via the
|
|
20
|
+
* adapter's scoped logger — never the unknown-name strings
|
|
21
|
+
* themselves, which crossed the trust boundary from the MCP tool
|
|
22
|
+
* caller.
|
|
23
|
+
*
|
|
24
|
+
* Guarded via `typeof listRegisteredServers === 'function'` so that
|
|
25
|
+
* test harnesses which mock the mcp-registry module with a narrower
|
|
26
|
+
* surface (omitting listRegisteredServers) fall through the filter
|
|
27
|
+
* transparently. In production, `listRegisteredServers` is always a
|
|
28
|
+
* function, and the filter runs as intended.
|
|
29
|
+
*/
|
|
30
|
+
function sanitizeMcpServerNames(requested, log) {
|
|
31
|
+
if (typeof listRegisteredServers !== 'function') {
|
|
32
|
+
return requested;
|
|
33
|
+
}
|
|
34
|
+
const known = new Set(listRegisteredServers());
|
|
35
|
+
const kept = [];
|
|
36
|
+
let droppedCount = 0;
|
|
37
|
+
for (const name of requested) {
|
|
38
|
+
if (known.has(name)) {
|
|
39
|
+
kept.push(name);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
droppedCount++;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (droppedCount > 0) {
|
|
46
|
+
log.warn('Unknown MCP servers skipped', {
|
|
47
|
+
unknownCount: droppedCount,
|
|
48
|
+
knownCount: kept.length,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return kept;
|
|
52
|
+
}
|
|
53
|
+
const GEMINI_CONFIG = {
|
|
54
|
+
command: 'gemini',
|
|
55
|
+
defaultArgs: ['--output-format', 'json'],
|
|
56
|
+
modelArgName: '--model',
|
|
57
|
+
envExtras: { TERM: 'dumb', NO_COLOR: '1', CI: 'true' },
|
|
58
|
+
mpcEnvCleanup: ['GEMINI_MCP_CONFIG', 'MCP_ENABLED'],
|
|
59
|
+
mcpSupport: {
|
|
60
|
+
configMethod: 'server-whitelist',
|
|
61
|
+
whitelistFlag: '--allowed-mcp-server-names',
|
|
62
|
+
writeProtection: {
|
|
63
|
+
method: 'approval-mode',
|
|
64
|
+
flag: '--approval-mode',
|
|
65
|
+
value: 'plan',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Frontier Gemini model chain.
|
|
71
|
+
*
|
|
72
|
+
* Ordered by preference: newest frontier preview → previous frontier preview
|
|
73
|
+
* → stable last-gen frontier. The orchestrator rotates through this chain
|
|
74
|
+
* on saturation failures (429 / "No capacity available"), trading "freshest
|
|
75
|
+
* capability" for "delivered response" as preview tiers are exhausted.
|
|
76
|
+
*
|
|
77
|
+
* Rationale: Gemini CLI's default Auto routing resolves to
|
|
78
|
+
* `gemini-2.5-flash-lite` for prompts the router classifies as "simple" —
|
|
79
|
+
* a classification our full adversarial verification protocol apparently
|
|
80
|
+
* does not escape. flash-lite lacks the capacity to maintain URL/quote
|
|
81
|
+
* source-provenance across 5+ citation verification loads, so it
|
|
82
|
+
* fabricates. Pinning the heaviest tier-3 model trades the Auto router's
|
|
83
|
+
* variable downselect for predictable frontier capacity; rotation handles
|
|
84
|
+
* the preview tier's variable availability.
|
|
85
|
+
*
|
|
86
|
+
* Probe-tested 2026-04-21 in Gemini CLI 0.30: the strings below are the
|
|
87
|
+
* only ones the CLI accepts for the tier-3 frontier. `gemini-3-pro`,
|
|
88
|
+
* `gemini-3.1-pro`, `gemini-3.0-pro`, `gemini-3-flash`, `gemini-3-pro-exp`,
|
|
89
|
+
* `gemini-3-pro-002`, and `gemini-pro-3` all return ModelNotFoundError.
|
|
90
|
+
* The `-preview` suffix is required for the 3.x tier.
|
|
91
|
+
*
|
|
92
|
+
* Override the whole chain with a single model via BRUTALIST_GEMINI_MODEL=...
|
|
93
|
+
* (disables rotation — operator takes responsibility for availability).
|
|
94
|
+
* Passing `models.gemini` on a tool call similarly disables rotation.
|
|
95
|
+
*/
|
|
96
|
+
export const GEMINI_FRONTIER_CHAIN = Object.freeze([
|
|
97
|
+
'gemini-3.1-pro-preview', // newest frontier, preview-tier (capacity-limited)
|
|
98
|
+
'gemini-3-pro-preview', // previous frontier, preview-tier
|
|
99
|
+
'gemini-2.5-pro', // stable last-gen frontier, ~always available
|
|
100
|
+
]);
|
|
101
|
+
const GEMINI_FRONTIER_MODEL = process.env.BRUTALIST_GEMINI_MODEL || GEMINI_FRONTIER_CHAIN[0];
|
|
102
|
+
export class GeminiAdapter {
|
|
103
|
+
name = 'gemini';
|
|
104
|
+
getConfig() {
|
|
105
|
+
return GEMINI_CONFIG;
|
|
106
|
+
}
|
|
107
|
+
async buildCommand(userPrompt, systemPrompt, options, modelResolver, secureEnv) {
|
|
108
|
+
const log = options.log ?? rootLogger;
|
|
109
|
+
const config = GEMINI_CONFIG;
|
|
110
|
+
const mcpEnabled = options.mcpServers && options.mcpServers.length > 0;
|
|
111
|
+
// Build args
|
|
112
|
+
const args = [...config.defaultArgs];
|
|
113
|
+
// Priority: caller-specified > env override > frontier default.
|
|
114
|
+
// We always pass --model to prevent Gemini CLI's Auto router from
|
|
115
|
+
// silently downselecting to flash-lite under verification load.
|
|
116
|
+
const resolvedModel = modelResolver.resolveModel('gemini', options.models?.gemini) || GEMINI_FRONTIER_MODEL;
|
|
117
|
+
args.push(config.modelArgName, resolvedModel);
|
|
118
|
+
// MCP configuration
|
|
119
|
+
if (mcpEnabled && config.mcpSupport) {
|
|
120
|
+
// Pre-filter via sanitizeMcpServerNames — unknown names are
|
|
121
|
+
// dropped before they reach `mcp-registry.ts:75`
|
|
122
|
+
// (Cycle 4 Task T19 / F10).
|
|
123
|
+
const sanitizedNames = sanitizeMcpServerNames(options.mcpServers, log);
|
|
124
|
+
const servers = resolveServers(sanitizedNames);
|
|
125
|
+
const serverNames = Object.keys(servers);
|
|
126
|
+
if (serverNames.length > 0) {
|
|
127
|
+
const mcp = config.mcpSupport;
|
|
128
|
+
// Gemini: --allowed-mcp-server-names <names> --approval-mode plan
|
|
129
|
+
await ensureGeminiMCPServers(servers);
|
|
130
|
+
args.push(mcp.whitelistFlag, ...serverNames);
|
|
131
|
+
args.push(mcp.writeProtection.flag, mcp.writeProtection.value);
|
|
132
|
+
log.info(`\u{1F50C} MCP enabled for gemini: [${serverNames.join(', ')}]`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Build prompt -- no promptWrapper for Gemini
|
|
136
|
+
const combinedPrompt = `${systemPrompt}\n\n${userPrompt}`;
|
|
137
|
+
// Add CLI-specific env extras
|
|
138
|
+
const env = { ...secureEnv };
|
|
139
|
+
if (config.envExtras) {
|
|
140
|
+
Object.assign(env, config.envExtras);
|
|
141
|
+
}
|
|
142
|
+
// Add required API keys
|
|
143
|
+
const apiKeys = ['GOOGLE_API_KEY', 'GEMINI_API_KEY'];
|
|
144
|
+
for (const key of apiKeys) {
|
|
145
|
+
if (process.env[key])
|
|
146
|
+
env[key] = process.env[key];
|
|
147
|
+
}
|
|
148
|
+
// Clean up MPC env vars that could cause deadlock -- SKIP when MCP is enabled
|
|
149
|
+
if (!mcpEnabled && config.mpcEnvCleanup) {
|
|
150
|
+
for (const envVar of config.mpcEnvCleanup) {
|
|
151
|
+
delete env[envVar];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
env.BRUTALIST_SUBPROCESS = '1';
|
|
155
|
+
return { command: config.command, args, input: combinedPrompt, env };
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Extract response text from Gemini --output-format json output.
|
|
159
|
+
* Parses a single JSON object and returns the `response` field.
|
|
160
|
+
*/
|
|
161
|
+
decodeOutput(rawOutput, args, log) {
|
|
162
|
+
// Only decode if Gemini was run with --output-format json
|
|
163
|
+
if (!(args.includes('--output-format') && args.includes('json'))) {
|
|
164
|
+
return rawOutput;
|
|
165
|
+
}
|
|
166
|
+
return this.extractGeminiResponse(rawOutput, log ?? rootLogger);
|
|
167
|
+
}
|
|
168
|
+
extractGeminiResponse(jsonOutput, log) {
|
|
169
|
+
if (!jsonOutput || !jsonOutput.trim()) {
|
|
170
|
+
log.debug('extractGeminiResponse: empty input');
|
|
171
|
+
return '';
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const parsed = JSON.parse(jsonOutput);
|
|
175
|
+
if (parsed.response && typeof parsed.response === 'string') {
|
|
176
|
+
log.info(`\u2705 extractGeminiResponse: extracted response with ${parsed.response.length} chars`);
|
|
177
|
+
return parsed.response;
|
|
178
|
+
}
|
|
179
|
+
log.warn('extractGeminiResponse: no response field in JSON output', {
|
|
180
|
+
keys: Object.keys(parsed)
|
|
181
|
+
});
|
|
182
|
+
return '';
|
|
183
|
+
}
|
|
184
|
+
catch (e) {
|
|
185
|
+
// Redacted: raw jsonOutput is never emitted — only its length plus
|
|
186
|
+
// the parse error reason. Prevents prompt / response leakage
|
|
187
|
+
// through log aggregators.
|
|
188
|
+
log.warn('extractGeminiResponse: failed to parse JSON, returning raw output', {
|
|
189
|
+
error: e instanceof Error ? e.message : String(e),
|
|
190
|
+
length: jsonOutput.length
|
|
191
|
+
});
|
|
192
|
+
return '';
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=gemini-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-adapter.js","sourceRoot":"","sources":["../../src/cli-adapters/gemini-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Provider Adapter Interface and Registry
|
|
3
|
+
*
|
|
4
|
+
* Defines the CLIProvider contract that all per-provider adapters implement,
|
|
5
|
+
* and provides a factory for resolving providers by name.
|
|
6
|
+
*/
|
|
7
|
+
import type { CLIAgentOptions } from '../cli-agents.js';
|
|
8
|
+
import type { ModelResolver } from '../model-resolver.js';
|
|
9
|
+
import type { StructuredLogger } from '../logger.js';
|
|
10
|
+
export { parseNDJSON } from './shared.js';
|
|
11
|
+
export type CLIName = 'claude' | 'codex' | 'gemini';
|
|
12
|
+
export interface MCPSupportConfig {
|
|
13
|
+
/** How this CLI receives MCP server configuration */
|
|
14
|
+
configMethod: 'flag-file' | 'config-override' | 'server-whitelist';
|
|
15
|
+
configFlag?: string;
|
|
16
|
+
strictFlag?: string;
|
|
17
|
+
configOverrideKey?: string;
|
|
18
|
+
whitelistFlag?: string;
|
|
19
|
+
/** Hard write-prevention mechanism native to this CLI */
|
|
20
|
+
writeProtection: {
|
|
21
|
+
method: 'disallowed-tools' | 'sandbox' | 'approval-mode';
|
|
22
|
+
flag: string;
|
|
23
|
+
value: string;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface CLIBuilderConfig {
|
|
27
|
+
command: string;
|
|
28
|
+
defaultArgs: string[];
|
|
29
|
+
modelArgName: string;
|
|
30
|
+
promptWrapper?: (system: string, user: string) => string;
|
|
31
|
+
envExtras?: Record<string, string>;
|
|
32
|
+
jsonFlag?: string;
|
|
33
|
+
streamingArgs?: (options: CLIAgentOptions) => string[];
|
|
34
|
+
mpcEnvCleanup?: string[];
|
|
35
|
+
mcpSupport?: MCPSupportConfig;
|
|
36
|
+
}
|
|
37
|
+
export interface CLIProvider {
|
|
38
|
+
readonly name: CLIName;
|
|
39
|
+
/** Return the static configuration for this provider */
|
|
40
|
+
getConfig(): CLIBuilderConfig;
|
|
41
|
+
/**
|
|
42
|
+
* Build CLI command args, environment, and input for this provider.
|
|
43
|
+
* The orchestrator calls this instead of the old buildCLICommand method.
|
|
44
|
+
*/
|
|
45
|
+
buildCommand(userPrompt: string, systemPrompt: string, options: CLIAgentOptions, modelResolver: ModelResolver, secureEnv: Record<string, string>): Promise<{
|
|
46
|
+
command: string;
|
|
47
|
+
args: string[];
|
|
48
|
+
input: string;
|
|
49
|
+
env: Record<string, string>;
|
|
50
|
+
tempMcpConfigPath?: string;
|
|
51
|
+
}>;
|
|
52
|
+
/**
|
|
53
|
+
* Decode raw CLI output into clean text.
|
|
54
|
+
* Claude decodes stream-json NDJSON, Codex extracts agent_messages,
|
|
55
|
+
* Gemini extracts the response field from JSON.
|
|
56
|
+
*
|
|
57
|
+
* Pattern A: `log` is optional. When provided (passed from the
|
|
58
|
+
* orchestrator via `this.log?.forOperation('<cli>_spawn')`), adapter
|
|
59
|
+
* warnings/errors during decode emit with the scoped logger. When
|
|
60
|
+
* absent, adapters fall back to the root logger so the legacy test
|
|
61
|
+
* proxies (cli-agents.ts decodeClaudeStreamJson / extractCodexAgentMessage
|
|
62
|
+
* / extractGeminiResponse) keep working with no args.
|
|
63
|
+
*/
|
|
64
|
+
decodeOutput(rawOutput: string, args: string[], log?: StructuredLogger): string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get a provider adapter by name.
|
|
68
|
+
* Throws if the provider name is not recognized.
|
|
69
|
+
*/
|
|
70
|
+
export declare function getProvider(name: CLIName): CLIProvider;
|
|
71
|
+
/**
|
|
72
|
+
* Get all registered provider names.
|
|
73
|
+
*/
|
|
74
|
+
export declare function getProviderNames(): CLIName[];
|
|
75
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli-adapters/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI1C,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEpD,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,YAAY,EAAE,WAAW,GAAG,iBAAiB,GAAG,kBAAkB,CAAC;IAGnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAG3B,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,yDAAyD;IACzD,eAAe,EAAE;QACf,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,eAAe,CAAC;QACzD,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,MAAM,EAAE,CAAC;IACvD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAID,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAEvB,wDAAwD;IACxD,SAAS,IAAI,gBAAgB,CAAC;IAE9B;;;OAGG;IACH,YAAY,CACV,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;KAC5B,CAAC,CAAC;IAEH;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;CACjF;AAcD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,CAMtD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,EAAE,CAE5C"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Re-export shared utilities
|
|
2
|
+
export { parseNDJSON } from './shared.js';
|
|
3
|
+
// ── Provider Registry ──────────────────────────────────────────────────────
|
|
4
|
+
import { ClaudeAdapter } from './claude-adapter.js';
|
|
5
|
+
import { CodexAdapter } from './codex-adapter.js';
|
|
6
|
+
import { GeminiAdapter } from './gemini-adapter.js';
|
|
7
|
+
const providers = {
|
|
8
|
+
claude: new ClaudeAdapter(),
|
|
9
|
+
codex: new CodexAdapter(),
|
|
10
|
+
gemini: new GeminiAdapter(),
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Get a provider adapter by name.
|
|
14
|
+
* Throws if the provider name is not recognized.
|
|
15
|
+
*/
|
|
16
|
+
export function getProvider(name) {
|
|
17
|
+
const provider = providers[name];
|
|
18
|
+
if (!provider) {
|
|
19
|
+
throw new Error(`Unknown CLI provider: ${name}`);
|
|
20
|
+
}
|
|
21
|
+
return provider;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get all registered provider names.
|
|
25
|
+
*/
|
|
26
|
+
export function getProviderNames() {
|
|
27
|
+
return Object.keys(providers);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli-adapters/index.ts"],"names":[],"mappings":"AAUA,6BAA6B;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAiF1C,8EAA8E;AAE9E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,SAAS,GAAiC;IAC9C,MAAM,EAAE,IAAI,aAAa,EAAE;IAC3B,KAAK,EAAE,IAAI,YAAY,EAAE;IACzB,MAAM,EAAE,IAAI,aAAa,EAAE;CAC5B,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAAa;IACvC,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAc,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { StructuredLogger } from '../logger.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse NDJSON with proper JSON boundary detection.
|
|
4
|
+
* Handles JSON objects that contain embedded newlines without data loss.
|
|
5
|
+
*
|
|
6
|
+
* Known quirk: when two valid JSON objects are separated by non-JSON text
|
|
7
|
+
* (e.g., "NOT_JSON"), the second object is lost because the parser's start
|
|
8
|
+
* pointer stays past the first object and the slice for the second object
|
|
9
|
+
* includes the garbage prefix, causing JSON.parse to fail.
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseNDJSON(input: string, log?: StructuredLogger): object[];
|
|
12
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/cli-adapters/shared.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAgF3E"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for CLI provider adapters.
|
|
3
|
+
*
|
|
4
|
+
* parseNDJSON is the canonical NDJSON parser used by Claude and Codex decoders.
|
|
5
|
+
* It preserves the known second-object edge case (loss of second object when
|
|
6
|
+
* separated by non-JSON text) captured by characterization tests.
|
|
7
|
+
*
|
|
8
|
+
* Pattern A (integrate-observability): an optional StructuredLogger may be
|
|
9
|
+
* threaded in by callers that have a scoped logger available. When absent
|
|
10
|
+
* the root logger is used as the fallback — keeping the existing
|
|
11
|
+
* characterization-test call path (which supplies no logger) working
|
|
12
|
+
* unchanged.
|
|
13
|
+
*/
|
|
14
|
+
import { logger } from '../logger.js';
|
|
15
|
+
/**
|
|
16
|
+
* Parse NDJSON with proper JSON boundary detection.
|
|
17
|
+
* Handles JSON objects that contain embedded newlines without data loss.
|
|
18
|
+
*
|
|
19
|
+
* Known quirk: when two valid JSON objects are separated by non-JSON text
|
|
20
|
+
* (e.g., "NOT_JSON"), the second object is lost because the parser's start
|
|
21
|
+
* pointer stays past the first object and the slice for the second object
|
|
22
|
+
* includes the garbage prefix, causing JSON.parse to fail.
|
|
23
|
+
*/
|
|
24
|
+
export function parseNDJSON(input, log) {
|
|
25
|
+
const emit = log ?? logger;
|
|
26
|
+
if (!input || !input.trim()) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const results = [];
|
|
30
|
+
let depth = 0;
|
|
31
|
+
let inString = false;
|
|
32
|
+
let escape = false;
|
|
33
|
+
let start = 0;
|
|
34
|
+
for (let i = 0; i < input.length; i++) {
|
|
35
|
+
const char = input[i];
|
|
36
|
+
// Handle escape sequences
|
|
37
|
+
if (escape) {
|
|
38
|
+
escape = false;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (char === '\\') {
|
|
42
|
+
escape = true;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
// Track string boundaries
|
|
46
|
+
if (char === '"') {
|
|
47
|
+
inString = !inString;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
// Only count braces/brackets outside of strings
|
|
51
|
+
if (inString)
|
|
52
|
+
continue;
|
|
53
|
+
// Track depth
|
|
54
|
+
if (char === '{' || char === '[') {
|
|
55
|
+
depth++;
|
|
56
|
+
}
|
|
57
|
+
else if (char === '}' || char === ']') {
|
|
58
|
+
depth--;
|
|
59
|
+
// When depth returns to 0, we've found a complete JSON object
|
|
60
|
+
if (depth === 0) {
|
|
61
|
+
const jsonStr = input.slice(start, i + 1).trim();
|
|
62
|
+
if (jsonStr) {
|
|
63
|
+
try {
|
|
64
|
+
const parsed = JSON.parse(jsonStr);
|
|
65
|
+
results.push(parsed);
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
// Log unparseable segments (not silent). Redacted: the raw
|
|
69
|
+
// segment text is never emitted — only its length plus the
|
|
70
|
+
// parse error reason. This avoids leaking prompt / response
|
|
71
|
+
// content through log aggregators.
|
|
72
|
+
emit.warn(`Failed to parse JSON segment at position ${start}-${i + 1}:`, {
|
|
73
|
+
length: jsonStr.length,
|
|
74
|
+
error: e instanceof Error ? e.message : String(e)
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Move start pointer past this object and any whitespace
|
|
79
|
+
start = i + 1;
|
|
80
|
+
while (start < input.length && /\s/.test(input[start])) {
|
|
81
|
+
start++;
|
|
82
|
+
}
|
|
83
|
+
i = start - 1; // Will be incremented by loop
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Warn about incomplete JSON at end of input. Redacted: emit length
|
|
88
|
+
// only — the raw tail text is never forwarded to the logger.
|
|
89
|
+
if (start < input.length) {
|
|
90
|
+
const remaining = input.slice(start).trim();
|
|
91
|
+
if (remaining) {
|
|
92
|
+
emit.warn(`Incomplete JSON at end of input:`, {
|
|
93
|
+
length: remaining.length
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return results;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/cli-adapters/shared.ts"],"names":[],"mappings":"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"}
|
package/dist/cli-agents.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { StructuredLogger } from './logger.js';
|
|
1
2
|
import { CLIAgentResponse } from './types/brutalist.js';
|
|
2
3
|
import { ModelResolver } from './model-resolver.js';
|
|
3
|
-
|
|
4
|
+
import type { MetricsRegistry } from './metrics/index.js';
|
|
5
|
+
export type BrutalistPromptType = 'code' | 'codebase' | 'architecture' | 'idea' | 'research' | 'data' | 'security' | 'product' | 'infrastructure' | 'debate' | 'dependencies' | 'fileStructure' | 'gitHistory' | 'testCoverage' | 'design' | 'legal';
|
|
4
6
|
export declare const CLAUDE_ALIASES: readonly ["opus", "sonnet", "haiku"];
|
|
5
7
|
export interface CLIAgentOptions {
|
|
6
8
|
workingDirectory?: string;
|
|
@@ -19,6 +21,27 @@ export interface CLIAgentOptions {
|
|
|
19
21
|
requestId?: string;
|
|
20
22
|
debateMode?: boolean;
|
|
21
23
|
mcpServers?: string[];
|
|
24
|
+
/**
|
|
25
|
+
* Optional scoped logger threaded into provider.buildCommand / decodeOutput.
|
|
26
|
+
* When present, adapters emit via this logger (narrowed with forOperation)
|
|
27
|
+
* instead of the root logger import. Absent → fall back to root logger.
|
|
28
|
+
* Pattern A per phase.md: preserves stateless adapter singletons in
|
|
29
|
+
* cli-adapters/index.ts.
|
|
30
|
+
*/
|
|
31
|
+
log?: StructuredLogger;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Constructor-deps bag for CLIAgentOrchestrator.
|
|
35
|
+
*
|
|
36
|
+
* All fields optional — characterization tests construct
|
|
37
|
+
* `new CLIAgentOrchestrator()` with no args. In production the
|
|
38
|
+
* composition root passes the full set; in tests, instrumentation is a
|
|
39
|
+
* no-op and `this.log` falls back to the root logger via emitLog().
|
|
40
|
+
*/
|
|
41
|
+
export interface CLIAgentOrchestratorDeps {
|
|
42
|
+
modelResolver?: ModelResolver;
|
|
43
|
+
metrics?: MetricsRegistry;
|
|
44
|
+
log?: StructuredLogger;
|
|
22
45
|
}
|
|
23
46
|
export interface StreamingEvent {
|
|
24
47
|
type: 'agent_start' | 'agent_progress' | 'agent_complete' | 'agent_error';
|
|
@@ -41,12 +64,37 @@ export declare class CLIAgentOrchestrator {
|
|
|
41
64
|
private runningCLIs;
|
|
42
65
|
private readonly MAX_CONCURRENT_CLIS;
|
|
43
66
|
readonly modelResolver: ModelResolver;
|
|
67
|
+
private readonly metrics?;
|
|
68
|
+
private readonly log?;
|
|
44
69
|
private streamingBuffers;
|
|
45
70
|
private readonly STREAMING_FLUSH_INTERVAL;
|
|
46
71
|
private readonly MAX_CHUNK_SIZE;
|
|
47
72
|
private readonly HEARTBEAT_INTERVAL;
|
|
48
73
|
private lastHeartbeat;
|
|
49
|
-
|
|
74
|
+
/**
|
|
75
|
+
* Accepts a deps bag OR a bare `ModelResolver` (legacy positional form)
|
|
76
|
+
* OR nothing (characterization-test harnesses). The `instanceof ModelResolver`
|
|
77
|
+
* branch preserves the pre-observability signature.
|
|
78
|
+
*/
|
|
79
|
+
constructor(deps?: CLIAgentOrchestratorDeps | ModelResolver);
|
|
80
|
+
/**
|
|
81
|
+
* Return the injected scoped logger if present, otherwise the root
|
|
82
|
+
* logger singleton. Keeps un-injected (test) instances working while
|
|
83
|
+
* scoping production emissions with `module='cli-orchestrator'`.
|
|
84
|
+
*/
|
|
85
|
+
private emitLog;
|
|
86
|
+
/**
|
|
87
|
+
* Heuristic for classifying a spawnAsync error as a timeout.
|
|
88
|
+
* Centralized so all outcome paths share the same detection logic.
|
|
89
|
+
*
|
|
90
|
+
* Matches any of:
|
|
91
|
+
* - execError.code === 'ETIMEDOUT' (Node's timeout code on some paths)
|
|
92
|
+
* - execError.killed === true (child_process kill after SIGTERM/SIGKILL
|
|
93
|
+
* escalation when the timeout timer fired — see spawnAsync timer block)
|
|
94
|
+
* - execError.message matching /timed out|timeout/i (spawnAsync rejects
|
|
95
|
+
* with "Command timed out after ..." on timer expiry)
|
|
96
|
+
*/
|
|
97
|
+
private isTimeoutError;
|
|
50
98
|
private parseNDJSON;
|
|
51
99
|
private decodeClaudeStreamJson;
|
|
52
100
|
private extractCodexAgentMessage;
|
|
@@ -60,6 +108,20 @@ export declare class CLIAgentOrchestrator {
|
|
|
60
108
|
executeCodex(userPrompt: string, systemPromptSpec: string, options?: CLIAgentOptions): Promise<CLIAgentResponse>;
|
|
61
109
|
executeGemini(userPrompt: string, systemPromptSpec: string, options?: CLIAgentOptions): Promise<CLIAgentResponse>;
|
|
62
110
|
executeSingleCLI(cli: 'claude' | 'codex' | 'gemini', userPrompt: string, systemPromptSpec: string, options?: CLIAgentOptions): Promise<CLIAgentResponse>;
|
|
111
|
+
/**
|
|
112
|
+
* Gemini frontier rotation - iterate through GEMINI_FRONTIER_CHAIN on
|
|
113
|
+
* saturation failures.
|
|
114
|
+
*
|
|
115
|
+
* Only active when neither caller nor operator has chosen a model. Each
|
|
116
|
+
* attempt injects the model via options.models.gemini. Per-attempt
|
|
117
|
+
* saturation is detected via the existing quota-pattern detection in
|
|
118
|
+
* _executeCLI - saturation produces success=false with an error matching
|
|
119
|
+
* /\b429\b/ or quota-family patterns. On non-saturation failure,
|
|
120
|
+
* rotation stops immediately (a different model will not fix prompt
|
|
121
|
+
* errors, subprocess crashes, or auth failures). On chain exhaustion,
|
|
122
|
+
* the last failing response is returned.
|
|
123
|
+
*/
|
|
124
|
+
private _executeGeminiWithRotation;
|
|
63
125
|
private waitForAvailableSlot;
|
|
64
126
|
executeCLIAgents(cliAgents: string[], systemPrompt: string, userPrompt: string, options?: CLIAgentOptions): Promise<CLIAgentResponse[]>;
|
|
65
127
|
executeCLIAgent(agent: string, systemPrompt: string, userPrompt: string, options?: CLIAgentOptions): Promise<CLIAgentResponse>;
|
package/dist/cli-agents.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-agents.d.ts","sourceRoot":"","sources":["../src/cli-agents.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli-agents.d.ts","sourceRoot":"","sources":["../src/cli-agents.ts"],"names":[],"mappings":"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"}
|