llm-cli-gateway 1.17.4 → 1.17.6
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/CHANGELOG.md +35 -0
- package/README.md +1 -1
- package/dist/approval-manager.js +0 -8
- package/dist/async-job-manager.d.ts +0 -113
- package/dist/async-job-manager.js +6 -124
- package/dist/cache-stats.d.ts +0 -89
- package/dist/cache-stats.js +0 -62
- package/dist/claude-mcp-config.js +0 -1
- package/dist/cli-updater.d.ts +0 -8
- package/dist/cli-updater.js +0 -12
- package/dist/codex-json-parser.d.ts +0 -20
- package/dist/codex-json-parser.js +0 -21
- package/dist/config.d.ts +0 -31
- package/dist/config.js +2 -72
- package/dist/db.d.ts +0 -18
- package/dist/db.js +0 -22
- package/dist/doctor.d.ts +0 -49
- package/dist/doctor.js +0 -47
- package/dist/endpoint-exposure.js +0 -1
- package/dist/executor.d.ts +0 -19
- package/dist/executor.js +3 -38
- package/dist/flight-recorder.d.ts +0 -26
- package/dist/flight-recorder.js +1 -70
- package/dist/gemini-json-parser.d.ts +0 -25
- package/dist/gemini-json-parser.js +0 -28
- package/dist/health.d.ts +0 -3
- package/dist/health.js +0 -3
- package/dist/index.d.ts +1 -221
- package/dist/index.js +14 -563
- package/dist/job-store.d.ts +0 -74
- package/dist/job-store.js +1 -73
- package/dist/logger.d.ts +0 -7
- package/dist/logger.js +0 -6
- package/dist/migrate-sessions.d.ts +0 -3
- package/dist/migrate-sessions.js +0 -16
- package/dist/migrate.js +1 -18
- package/dist/mistral-meta-json-parser.js +0 -67
- package/dist/model-registry.js +0 -13
- package/dist/pricing.d.ts +0 -46
- package/dist/pricing.js +0 -47
- package/dist/process-monitor.d.ts +0 -15
- package/dist/process-monitor.js +2 -31
- package/dist/prompt-parts.d.ts +0 -25
- package/dist/prompt-parts.js +0 -11
- package/dist/provider-status.d.ts +0 -8
- package/dist/provider-status.js +0 -11
- package/dist/request-helpers.d.ts +0 -334
- package/dist/request-helpers.js +1 -229
- package/dist/resources.d.ts +0 -20
- package/dist/resources.js +1 -34
- package/dist/retry.d.ts +0 -45
- package/dist/retry.js +3 -40
- package/dist/session-manager-pg.d.ts +0 -32
- package/dist/session-manager-pg.js +0 -32
- package/dist/session-manager.d.ts +0 -21
- package/dist/session-manager.js +1 -15
- package/dist/stream-json-parser.d.ts +0 -18
- package/dist/stream-json-parser.js +0 -22
- package/dist/upstream-contracts.d.ts +0 -55
- package/dist/upstream-contracts.js +0 -77
- package/dist/validation-orchestrator.js +0 -3
- package/dist/worktree-manager.d.ts +0 -9
- package/dist/worktree-manager.js +0 -21
- package/package.json +1 -1
package/dist/request-helpers.js
CHANGED
|
@@ -1,33 +1,14 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure, side-effect-free helpers for request argument planning.
|
|
3
|
-
* Zero I/O, zero dependencies on index-scoped collaborators.
|
|
4
|
-
*/
|
|
5
1
|
import { existsSync, unlinkSync, writeFileSync } from "fs";
|
|
6
2
|
import { tmpdir } from "os";
|
|
7
3
|
import { join, isAbsolute } from "path";
|
|
8
4
|
import { randomUUID } from "crypto";
|
|
9
5
|
import { z } from "zod/v3";
|
|
10
|
-
/** Prefix for gateway-generated session IDs. Enforces provenance structurally. */
|
|
11
6
|
export const GATEWAY_SESSION_PREFIX = "gw-";
|
|
12
|
-
/**
|
|
13
|
-
* Validate that a user-provided sessionId doesn't use the reserved gateway prefix.
|
|
14
|
-
* Throws if the ID starts with "gw-" — this namespace is reserved for gateway-generated IDs.
|
|
15
|
-
*/
|
|
16
7
|
export function validateSessionId(sessionId) {
|
|
17
8
|
if (sessionId.startsWith(GATEWAY_SESSION_PREFIX)) {
|
|
18
9
|
throw new Error(`Session ID "${sessionId}" uses reserved prefix "${GATEWAY_SESSION_PREFIX}". Gateway-generated session IDs cannot be used for --resume.`);
|
|
19
10
|
}
|
|
20
11
|
}
|
|
21
|
-
/**
|
|
22
|
-
* Pure function: determine --resume args and session provenance from request flags.
|
|
23
|
-
* Does NOT perform any session I/O — callers handle create/update separately.
|
|
24
|
-
*/
|
|
25
|
-
/**
|
|
26
|
-
* Reject CLI arg values that start with "-" to prevent argument injection.
|
|
27
|
-
* spawn() doesn't invoke a shell so there's no shell injection, but a value
|
|
28
|
-
* like "--dangerously-skip-permissions" passed as a tool name would be
|
|
29
|
-
* interpreted as a flag by the child CLI.
|
|
30
|
-
*/
|
|
31
12
|
export function sanitizeCliArgValues(values, fieldName) {
|
|
32
13
|
for (const v of values) {
|
|
33
14
|
if (v.startsWith("-")) {
|
|
@@ -70,12 +51,6 @@ export function resolveCodexSessionArgs(opts) {
|
|
|
70
51
|
}
|
|
71
52
|
return { mode: "new" };
|
|
72
53
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Grok-specific resume args. Grok accepts `--resume <id>` to resume a named session,
|
|
75
|
-
* and `--continue` to resume the most recent session for the current working directory.
|
|
76
|
-
* Unlike `resolveSessionResumeArgs`, "resume latest" maps to `--continue` (not `--resume latest`)
|
|
77
|
-
* because Grok would interpret a literal "latest" as a session ID.
|
|
78
|
-
*/
|
|
79
54
|
export function resolveGrokSessionArgs(opts) {
|
|
80
55
|
if (opts.createNewSession) {
|
|
81
56
|
return { resumeArgs: [], effectiveSessionId: undefined, userProvidedSession: false };
|
|
@@ -97,16 +72,6 @@ export function resolveGrokSessionArgs(opts) {
|
|
|
97
72
|
}
|
|
98
73
|
return { resumeArgs: [], effectiveSessionId: undefined, userProvidedSession: false };
|
|
99
74
|
}
|
|
100
|
-
/**
|
|
101
|
-
* Mistral Vibe-specific resume args.
|
|
102
|
-
*
|
|
103
|
-
* Current Vibe defaults session logging on; older configs can explicitly set
|
|
104
|
-
* `[session_logging] enabled = false`. The doctor checks that toggle before
|
|
105
|
-
* callers rely on session continuity; this pure helper just emits the args.
|
|
106
|
-
*
|
|
107
|
-
* The args shape mirrors Grok (`--continue` for latest, `--resume <id>` for a
|
|
108
|
-
* specific session) because Vibe exposes the same surface for its session log.
|
|
109
|
-
*/
|
|
110
75
|
export function resolveMistralSessionArgs(opts) {
|
|
111
76
|
if (opts.createNewSession) {
|
|
112
77
|
return { resumeArgs: [], effectiveSessionId: undefined, userProvidedSession: false };
|
|
@@ -128,13 +93,6 @@ export function resolveMistralSessionArgs(opts) {
|
|
|
128
93
|
}
|
|
129
94
|
return { resumeArgs: [], effectiveSessionId: undefined, userProvidedSession: false };
|
|
130
95
|
}
|
|
131
|
-
/**
|
|
132
|
-
* Vibe-specific permission mode mapping. Vibe replaces Grok's `--always-approve`
|
|
133
|
-
* with an `--agent <mode>` enum. When the caller does not set a permissionMode,
|
|
134
|
-
* the gateway emits `--agent auto-approve` explicitly: omitting the flag would
|
|
135
|
-
* let Vibe pick its own default which may not be auto-approve, surprising
|
|
136
|
-
* programmatic callers.
|
|
137
|
-
*/
|
|
138
96
|
export const MISTRAL_AGENT_MODES = [
|
|
139
97
|
"default",
|
|
140
98
|
"plan",
|
|
@@ -145,16 +103,6 @@ export const MISTRAL_AGENT_MODES = [
|
|
|
145
103
|
"lean",
|
|
146
104
|
];
|
|
147
105
|
export const MISTRAL_DEFAULT_AGENT_MODE = "auto-approve";
|
|
148
|
-
/**
|
|
149
|
-
* Pure helper that builds Vibe's argv and env.
|
|
150
|
-
*
|
|
151
|
-
* - Model is selected via `VIBE_ACTIVE_MODEL` env var (NOT a `--model` flag).
|
|
152
|
-
* - Permission mode emits `--agent <mode>` (defaults to `auto-approve` when unset).
|
|
153
|
-
* - Allowed tools emit `--enabled-tools <tool>` once per tool (allowlist only).
|
|
154
|
-
* - Output format emits `--output <text|json|streaming>` (legacy gateway
|
|
155
|
-
* aliases `plain` and `stream-json` are normalized before spawn).
|
|
156
|
-
* - Disallowed tools are accepted but ignored at the CLI boundary.
|
|
157
|
-
*/
|
|
158
106
|
export function prepareMistralRequest(input) {
|
|
159
107
|
const args = ["-p", input.prompt];
|
|
160
108
|
const env = {};
|
|
@@ -166,8 +114,6 @@ export function prepareMistralRequest(input) {
|
|
|
166
114
|
}
|
|
167
115
|
const mode = input.permissionMode ?? MISTRAL_DEFAULT_AGENT_MODE;
|
|
168
116
|
args.push("--agent", mode);
|
|
169
|
-
// No reasoning-effort surface on vibe: --effort / --reasoning-effort are not
|
|
170
|
-
// emitted (the CLI rejects them; see upstream-contracts.ts mistral block).
|
|
171
117
|
if (input.allowedTools && input.allowedTools.length > 0) {
|
|
172
118
|
sanitizeCliArgValues(input.allowedTools, "allowedTools");
|
|
173
119
|
for (const tool of input.allowedTools) {
|
|
@@ -204,14 +150,6 @@ function normalizeMistralOutputFormat(format) {
|
|
|
204
150
|
return "streaming";
|
|
205
151
|
return format;
|
|
206
152
|
}
|
|
207
|
-
//──────────────────────────────────────────────────────────────────────────────
|
|
208
|
-
// U24: Permission / approval mode parity helpers
|
|
209
|
-
//──────────────────────────────────────────────────────────────────────────────
|
|
210
|
-
/**
|
|
211
|
-
* Claude `--permission-mode` values. `default` is a no-op (no flag emitted) —
|
|
212
|
-
* matches the CLI's behavior when the flag is absent, and avoids hard-coding an
|
|
213
|
-
* undocumented literal.
|
|
214
|
-
*/
|
|
215
153
|
export const CLAUDE_PERMISSION_MODES = [
|
|
216
154
|
"default",
|
|
217
155
|
"acceptEdits",
|
|
@@ -220,16 +158,6 @@ export const CLAUDE_PERMISSION_MODES = [
|
|
|
220
158
|
"dontAsk",
|
|
221
159
|
"bypassPermissions",
|
|
222
160
|
];
|
|
223
|
-
/**
|
|
224
|
-
* Resolve Claude's `--permission-mode` args.
|
|
225
|
-
*
|
|
226
|
-
* Precedence:
|
|
227
|
-
* 1. If `permissionMode` is set, it wins. A warning is returned when
|
|
228
|
-
* `dangerouslySkipPermissions: true` is also set (legacy + new conflict).
|
|
229
|
-
* 2. Else if `dangerouslySkipPermissions: true`, emit `--permission-mode
|
|
230
|
-
* bypassPermissions`.
|
|
231
|
-
* 3. Else (or `permissionMode === "default"`) emit nothing.
|
|
232
|
-
*/
|
|
233
161
|
export function resolveClaudePermissionFlags(input) {
|
|
234
162
|
const { permissionMode, dangerouslySkipPermissions } = input;
|
|
235
163
|
let warning;
|
|
@@ -248,33 +176,9 @@ export function resolveClaudePermissionFlags(input) {
|
|
|
248
176
|
}
|
|
249
177
|
return { args: [] };
|
|
250
178
|
}
|
|
251
|
-
/**
|
|
252
|
-
* Gemini `--approval-mode` values. Preserves existing values (`default`,
|
|
253
|
-
* `auto_edit`, `yolo`) and adds `plan` for parity with Claude's plan mode.
|
|
254
|
-
*/
|
|
255
179
|
export const GEMINI_APPROVAL_MODES = ["default", "auto_edit", "yolo", "plan"];
|
|
256
|
-
/**
|
|
257
|
-
* Codex sandbox modes (for `--sandbox <mode>`).
|
|
258
|
-
*/
|
|
259
180
|
export const CODEX_SANDBOX_MODES = ["read-only", "workspace-write", "danger-full-access"];
|
|
260
|
-
/**
|
|
261
|
-
* Deprecated Codex approval modes. Current Codex no longer exposes an
|
|
262
|
-
* `--ask-for-approval` flag; the MCP input is temporarily retained so older
|
|
263
|
-
* callers do not fail schema validation, but it emits no CLI argv.
|
|
264
|
-
*/
|
|
265
181
|
export const CODEX_ASK_FOR_APPROVAL_MODES = ["untrusted", "on-request", "never"];
|
|
266
|
-
/**
|
|
267
|
-
* Resolve current Codex sandbox args from the modern params + legacy
|
|
268
|
-
* `fullAuto` shorthand. Current Codex exposes `--sandbox`, but no longer
|
|
269
|
-
* exposes `--ask-for-approval` or `--full-auto`.
|
|
270
|
-
*
|
|
271
|
-
* Precedence:
|
|
272
|
-
* 1. Explicit `sandboxMode` emits `--sandbox <mode>`.
|
|
273
|
-
* 2. Else if `fullAuto: true`, expand to `--sandbox workspace-write`.
|
|
274
|
-
* 3. Deprecated `askForApproval` and `useLegacyFullAutoFlag` emit no argv
|
|
275
|
-
* and return warnings for callers to surface/log.
|
|
276
|
-
* 4. Else emit nothing.
|
|
277
|
-
*/
|
|
278
182
|
export function resolveCodexSandboxFlags(input) {
|
|
279
183
|
const { sandboxMode, askForApproval, fullAuto, useLegacyFullAutoFlag } = input;
|
|
280
184
|
const args = [];
|
|
@@ -296,17 +200,6 @@ export function resolveCodexSandboxFlags(input) {
|
|
|
296
200
|
}
|
|
297
201
|
return { args, warning: warnings.length > 0 ? warnings.join(" ") : undefined };
|
|
298
202
|
}
|
|
299
|
-
/**
|
|
300
|
-
* Flags that `codex exec resume` rejects (the original session's policy is
|
|
301
|
-
* inherited). Callers must drop these when building resume argv.
|
|
302
|
-
*
|
|
303
|
-
* Verified against `codex exec resume --help` (codex-cli 0.135.0):
|
|
304
|
-
* `--sandbox`, `--add-dir`, `-C`, `--cd`, `--profile`, and `--search` are rejected.
|
|
305
|
-
* Deprecated `--full-auto` / `--ask-for-approval` are kept here defensively so
|
|
306
|
-
* legacy pre-filtered segments are stripped instead of reaching spawn.
|
|
307
|
-
* `--output-schema` and `-c key=value` ARE accepted on resume and therefore are
|
|
308
|
-
* NOT in this filter (Phase 4 slice α restored the previously-silent drop of those two).
|
|
309
|
-
*/
|
|
310
203
|
export const CODEX_RESUME_FILTERED_FLAGS = new Set([
|
|
311
204
|
"--full-auto",
|
|
312
205
|
"--sandbox",
|
|
@@ -317,10 +210,6 @@ export const CODEX_RESUME_FILTERED_FLAGS = new Set([
|
|
|
317
210
|
"--profile",
|
|
318
211
|
"--search",
|
|
319
212
|
]);
|
|
320
|
-
/**
|
|
321
|
-
* Codex flags that take exactly one value (consumed together with the flag).
|
|
322
|
-
* `--full-auto` and `--search` are bare booleans and intentionally absent.
|
|
323
|
-
*/
|
|
324
213
|
const CODEX_RESUME_FILTERED_FLAGS_WITH_VALUE = new Set([
|
|
325
214
|
"--sandbox",
|
|
326
215
|
"--ask-for-approval",
|
|
@@ -329,13 +218,6 @@ const CODEX_RESUME_FILTERED_FLAGS_WITH_VALUE = new Set([
|
|
|
329
218
|
"--cd",
|
|
330
219
|
"--profile",
|
|
331
220
|
]);
|
|
332
|
-
/**
|
|
333
|
-
* Strip resume-incompatible flag/value pairs from a Codex argv segment.
|
|
334
|
-
*
|
|
335
|
-
* Bare flags (`--full-auto`, `--search`) drop without consuming a value.
|
|
336
|
-
* Value-taking flags (`--sandbox`, `--ask-for-approval`, `--add-dir`, `-C`, `--cd`,
|
|
337
|
-
* `--profile`) drop together with their immediately-following value.
|
|
338
|
-
*/
|
|
339
221
|
export function filterCodexResumeFlags(args) {
|
|
340
222
|
const out = [];
|
|
341
223
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -345,26 +227,12 @@ export function filterCodexResumeFlags(args) {
|
|
|
345
227
|
continue;
|
|
346
228
|
}
|
|
347
229
|
if (CODEX_RESUME_FILTERED_FLAGS_WITH_VALUE.has(a)) {
|
|
348
|
-
i += 1;
|
|
230
|
+
i += 1;
|
|
349
231
|
}
|
|
350
232
|
}
|
|
351
233
|
return out;
|
|
352
234
|
}
|
|
353
|
-
//──────────────────────────────────────────────────────────────────────────────
|
|
354
|
-
// U25: Claude high-impact features
|
|
355
|
-
//──────────────────────────────────────────────────────────────────────────────
|
|
356
|
-
/**
|
|
357
|
-
* Claude `--effort` enum values. Mirrors the model-side effort axis.
|
|
358
|
-
*/
|
|
359
235
|
export const CLAUDE_EFFORT_LEVELS = ["low", "medium", "high", "xhigh", "max"];
|
|
360
|
-
/**
|
|
361
|
-
* Standalone Zod object for U25's high-impact param subset. Enforces the
|
|
362
|
-
* `systemPrompt` / `appendSystemPrompt` mutual-exclusion via `.refine(...)`.
|
|
363
|
-
*
|
|
364
|
-
* The MCP SDK's `server.tool` takes a raw shape (no top-level refine), so the
|
|
365
|
-
* tool callback re-checks the constraint and returns an error response. This
|
|
366
|
-
* exported schema is what tests use to verify Zod-level enforcement.
|
|
367
|
-
*/
|
|
368
236
|
export const CLAUDE_HIGH_IMPACT_PARAMS_SCHEMA = z
|
|
369
237
|
.object({
|
|
370
238
|
agent: z.string().optional(),
|
|
@@ -381,12 +249,6 @@ export const CLAUDE_HIGH_IMPACT_PARAMS_SCHEMA = z
|
|
|
381
249
|
message: "systemPrompt and appendSystemPrompt are mutually exclusive; use one or the other (not both).",
|
|
382
250
|
path: ["appendSystemPrompt"],
|
|
383
251
|
});
|
|
384
|
-
/**
|
|
385
|
-
* Minimal Anthropic agent-definition schema. Mirrors the shape expected by
|
|
386
|
-
* Claude CLI's `--agents` inline JSON argument. We validate the *required*
|
|
387
|
-
* keys (`description`, `prompt`) up-front so a malformed payload fails fast
|
|
388
|
-
* with an actionable error instead of producing an opaque CLI exit.
|
|
389
|
-
*/
|
|
390
252
|
export const CLAUDE_AGENT_DEFINITION_SCHEMA = z
|
|
391
253
|
.object({
|
|
392
254
|
description: z.string().min(1, "agent.description must be a non-empty string"),
|
|
@@ -395,13 +257,6 @@ export const CLAUDE_AGENT_DEFINITION_SCHEMA = z
|
|
|
395
257
|
model: z.string().optional(),
|
|
396
258
|
})
|
|
397
259
|
.passthrough();
|
|
398
|
-
/**
|
|
399
|
-
* Validate an `agents` map against {@link CLAUDE_AGENT_DEFINITION_SCHEMA}.
|
|
400
|
-
*
|
|
401
|
-
* Returns `{ ok: true, value }` on success and `{ ok: false, agentKey, message }`
|
|
402
|
-
* on the first failing entry. The caller is responsible for turning the failure
|
|
403
|
-
* into a tool-level error response (e.g. via `createErrorResponse`).
|
|
404
|
-
*/
|
|
405
260
|
export function validateClaudeAgentsMap(agents) {
|
|
406
261
|
const validated = {};
|
|
407
262
|
for (const [key, raw] of Object.entries(agents)) {
|
|
@@ -419,13 +274,6 @@ export function validateClaudeAgentsMap(agents) {
|
|
|
419
274
|
}
|
|
420
275
|
return { ok: true, value: validated };
|
|
421
276
|
}
|
|
422
|
-
/**
|
|
423
|
-
* Emit Claude high-impact feature flags (U25) as a flat argv segment.
|
|
424
|
-
*
|
|
425
|
-
* Mutual-exclusion of `systemPrompt`/`appendSystemPrompt` is enforced upstream
|
|
426
|
-
* at the Zod schema (`.refine(...)`); this helper does *not* re-check it, so
|
|
427
|
-
* tests can exercise either flag in isolation.
|
|
428
|
-
*/
|
|
429
277
|
export function prepareClaudeHighImpactFlags(input) {
|
|
430
278
|
const args = [];
|
|
431
279
|
if (input.agent) {
|
|
@@ -477,27 +325,10 @@ export function prepareClaudeHighImpactFlags(input) {
|
|
|
477
325
|
args.push("--settings", input.settings);
|
|
478
326
|
}
|
|
479
327
|
if (input.tools && input.tools.length > 0) {
|
|
480
|
-
// Single variadic flag (mirrors --allowed-tools emission). `[""]` → `--tools ""`
|
|
481
|
-
// which disables all built-in tools per `claude --help`.
|
|
482
328
|
args.push("--tools", ...input.tools);
|
|
483
329
|
}
|
|
484
330
|
return args;
|
|
485
331
|
}
|
|
486
|
-
//──────────────────────────────────────────────────────────────────────────────
|
|
487
|
-
// U26: Codex high-impact features
|
|
488
|
-
//──────────────────────────────────────────────────────────────────────────────
|
|
489
|
-
/**
|
|
490
|
-
* Zod schema for Codex `configOverrides` map.
|
|
491
|
-
*
|
|
492
|
-
* Hard requirements (argv-injection prevention):
|
|
493
|
-
* - Keys MUST match /^[a-zA-Z0-9._]+$/ (no whitespace, no equals, no flag-like prefixes).
|
|
494
|
-
* - Values MUST NOT contain CR or LF — newlines could be re-interpreted by the
|
|
495
|
-
* CLI's TOML parser as new keys.
|
|
496
|
-
*
|
|
497
|
-
* The CLI consumes overrides as `-c key=value`. We rely on `spawn(..., args)`
|
|
498
|
-
* passing argv directly without a shell, so we forbid shape-breaking
|
|
499
|
-
* characters rather than shell-escaping values.
|
|
500
|
-
*/
|
|
501
332
|
export const CODEX_CONFIG_OVERRIDES_SCHEMA = z
|
|
502
333
|
.record(z
|
|
503
334
|
.string()
|
|
@@ -505,10 +336,6 @@ export const CODEX_CONFIG_OVERRIDES_SCHEMA = z
|
|
|
505
336
|
message: "configOverrides values must not contain CR or LF characters",
|
|
506
337
|
}))
|
|
507
338
|
.optional();
|
|
508
|
-
/**
|
|
509
|
-
* Emit `-c key=value` pairs for each override. Caller MUST have validated the
|
|
510
|
-
* map with {@link CODEX_CONFIG_OVERRIDES_SCHEMA} first.
|
|
511
|
-
*/
|
|
512
339
|
export function emitCodexConfigOverrideArgs(overrides) {
|
|
513
340
|
if (!overrides)
|
|
514
341
|
return [];
|
|
@@ -536,15 +363,10 @@ export function prepareCodexOutputSchema(outputSchema) {
|
|
|
536
363
|
unlinkSync(path);
|
|
537
364
|
}
|
|
538
365
|
catch {
|
|
539
|
-
// Best-effort: if the file is already gone, ignore.
|
|
540
366
|
}
|
|
541
367
|
};
|
|
542
368
|
return { path, cleanup };
|
|
543
369
|
}
|
|
544
|
-
/**
|
|
545
|
-
* Validate that every image path exists on disk. Returns the first missing
|
|
546
|
-
* path on failure; `null` on success.
|
|
547
|
-
*/
|
|
548
370
|
export function findMissingImagePath(images) {
|
|
549
371
|
if (!images || images.length === 0)
|
|
550
372
|
return null;
|
|
@@ -554,11 +376,6 @@ export function findMissingImagePath(images) {
|
|
|
554
376
|
}
|
|
555
377
|
return null;
|
|
556
378
|
}
|
|
557
|
-
/**
|
|
558
|
-
* Zod schema for the U26 Codex high-impact feature subset. Used by the
|
|
559
|
-
* `codex_request` / `codex_request_async` tool schemas to validate the new
|
|
560
|
-
* params before they reach `prepareCodexRequest`.
|
|
561
|
-
*/
|
|
562
379
|
export const CODEX_HIGH_IMPACT_PARAMS_SCHEMA = z.object({
|
|
563
380
|
outputSchema: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),
|
|
564
381
|
search: z.boolean().optional(),
|
|
@@ -569,14 +386,6 @@ export const CODEX_HIGH_IMPACT_PARAMS_SCHEMA = z.object({
|
|
|
569
386
|
ignoreUserConfig: z.boolean().optional(),
|
|
570
387
|
ignoreRules: z.boolean().optional(),
|
|
571
388
|
});
|
|
572
|
-
/**
|
|
573
|
-
* Build the U26 argv segment AND any required side-effect handles.
|
|
574
|
-
*
|
|
575
|
-
* IMPORTANT: When this function writes a temp file for `outputSchema`, the
|
|
576
|
-
* returned `cleanup` function MUST be invoked by the caller (typically in a
|
|
577
|
-
* `finally` block around the spawn). Failing to do so leaks `0o600` temp
|
|
578
|
-
* files into `os.tmpdir()`.
|
|
579
|
-
*/
|
|
580
389
|
export function prepareCodexHighImpactFlags(input) {
|
|
581
390
|
const missingImagePath = findMissingImagePath(input.images);
|
|
582
391
|
if (missingImagePath) {
|
|
@@ -631,20 +440,9 @@ export function prepareCodexForkRequest(input) {
|
|
|
631
440
|
if (forkLast) {
|
|
632
441
|
return { args: ["fork", "--last", prompt] };
|
|
633
442
|
}
|
|
634
|
-
// sessionId path
|
|
635
443
|
validateSessionId(sessionId);
|
|
636
444
|
return { args: ["fork", sessionId, prompt] };
|
|
637
445
|
}
|
|
638
|
-
//──────────────────────────────────────────────────────────────────────────────
|
|
639
|
-
// U27: Gemini high-impact features
|
|
640
|
-
//──────────────────────────────────────────────────────────────────────────────
|
|
641
|
-
/**
|
|
642
|
-
* Prepend `@<abs-path>` tokens to a Gemini prompt so the CLI's attachment
|
|
643
|
-
* resolver picks them up. Each path MUST be absolute and exist on disk.
|
|
644
|
-
*
|
|
645
|
-
* Returns the mutated prompt. Throws on validation failure so the caller can
|
|
646
|
-
* convert to a `createErrorResponse`.
|
|
647
|
-
*/
|
|
648
446
|
export function prependGeminiAttachments(prompt, attachments) {
|
|
649
447
|
if (!attachments || attachments.length === 0)
|
|
650
448
|
return prompt;
|
|
@@ -658,10 +456,6 @@ export function prependGeminiAttachments(prompt, attachments) {
|
|
|
658
456
|
validateGeminiAttachmentTokenPath(p);
|
|
659
457
|
}
|
|
660
458
|
const tokens = attachments.map(p => `@${p}`).join(" ");
|
|
661
|
-
// Gemini attachments are prompt-level @path tokens rather than shell
|
|
662
|
-
// commands. Paths are absolute, existing, and token-safe before this join.
|
|
663
|
-
//
|
|
664
|
-
// codeql[js/shell-command-constructed-from-input]
|
|
665
459
|
return `${tokens} ${prompt}`;
|
|
666
460
|
}
|
|
667
461
|
function validateGeminiAttachmentTokenPath(path) {
|
|
@@ -671,14 +465,6 @@ function validateGeminiAttachmentTokenPath(path) {
|
|
|
671
465
|
}
|
|
672
466
|
}
|
|
673
467
|
}
|
|
674
|
-
/**
|
|
675
|
-
* Zod schema for the U27 Gemini high-impact feature subset. Used by the
|
|
676
|
-
* `gemini_request` / `gemini_request_async` tool schemas to validate the new
|
|
677
|
-
* params before they reach `prepareGeminiRequest`.
|
|
678
|
-
*
|
|
679
|
-
* `attachments` paths are validated to be absolute at the Zod layer; existence
|
|
680
|
-
* is enforced at execution time via `prependGeminiAttachments`.
|
|
681
|
-
*/
|
|
682
468
|
export const GEMINI_HIGH_IMPACT_PARAMS_SCHEMA = z.object({
|
|
683
469
|
sandbox: z.boolean().optional(),
|
|
684
470
|
policyFiles: z.array(z.string()).optional(),
|
|
@@ -689,15 +475,6 @@ export const GEMINI_HIGH_IMPACT_PARAMS_SCHEMA = z.object({
|
|
|
689
475
|
}))
|
|
690
476
|
.optional(),
|
|
691
477
|
});
|
|
692
|
-
/**
|
|
693
|
-
* Emit Gemini U27 high-impact flags. Policy paths are existence-checked here
|
|
694
|
-
* so a missing file fails fast with an actionable error rather than producing
|
|
695
|
-
* an opaque CLI exit.
|
|
696
|
-
*
|
|
697
|
-
* Does NOT handle `attachments` — those are mutated into the prompt string
|
|
698
|
-
* via {@link prependGeminiAttachments} BEFORE the `-p <prompt>` pair is
|
|
699
|
-
* emitted, preserving the U21 `-p` ordering invariant.
|
|
700
|
-
*/
|
|
701
478
|
export function prepareGeminiHighImpactFlags(input) {
|
|
702
479
|
if (input.policyFiles) {
|
|
703
480
|
for (const p of input.policyFiles) {
|
|
@@ -733,11 +510,6 @@ export function prepareGeminiHighImpactFlags(input) {
|
|
|
733
510
|
}
|
|
734
511
|
return { args, missingPolicyPath: null, missingPolicyField: null };
|
|
735
512
|
}
|
|
736
|
-
/**
|
|
737
|
-
* Resolve Gemini session args. Gemini CLI 0.43 exposes `--resume` but not a
|
|
738
|
-
* supported `--session-id` flag for fresh sessions, so new-session requests
|
|
739
|
-
* intentionally emit no session flag and let the CLI create its own session.
|
|
740
|
-
*/
|
|
741
513
|
export function resolveGeminiSessionPlan(opts) {
|
|
742
514
|
if (opts.sessionId && !opts.createNewSession) {
|
|
743
515
|
validateSessionId(opts.sessionId);
|
package/dist/resources.d.ts
CHANGED
|
@@ -26,31 +26,11 @@ export declare class ResourceProvider {
|
|
|
26
26
|
private flightRecorder;
|
|
27
27
|
private cacheAwareness;
|
|
28
28
|
constructor(sessionManager: ISessionManager, performanceMetrics: PerformanceMetrics, flightRecorder?: FlightRecorderQuery, cacheAwareness?: CacheAwarenessConfig | null);
|
|
29
|
-
/** Read-only flight-recorder accessor for cache-state resource readers. */
|
|
30
29
|
getFlightRecorderQuery(): FlightRecorderQuery;
|
|
31
|
-
/**
|
|
32
|
-
* cache_state://global — aggregates across the entire flight recorder.
|
|
33
|
-
* Optionally restrict to a recent window via `lastNHours`. Returns
|
|
34
|
-
* tokens/hashes/aggregates ONLY — no prompt text fields. The redaction is
|
|
35
|
-
* structural: the response shape (GlobalCacheStats) has no `prompt`,
|
|
36
|
-
* `response`, `system`, or `task` field by construction.
|
|
37
|
-
*/
|
|
38
30
|
readCacheStateGlobal(opts?: {
|
|
39
31
|
lastNHours?: number;
|
|
40
32
|
}): GlobalCacheStats;
|
|
41
|
-
/**
|
|
42
|
-
* cache_state://session/{sessionId} — per-session aggregates. Returns
|
|
43
|
-
* empty defaults when the session has no rows. Token/hash fields only.
|
|
44
|
-
*
|
|
45
|
-
* Slice 3: populates `ttlRemainingMs` by applying the configured TTL
|
|
46
|
-
* policy. Null for non-claude sessions or when the gateway has no
|
|
47
|
-
* cache-awareness config loaded (defaults to 5-min policy).
|
|
48
|
-
*/
|
|
49
33
|
readCacheStateSession(sessionId: string): SessionCacheStats;
|
|
50
|
-
/**
|
|
51
|
-
* cache_state://prefix/{hash} — per-stable-prefix-hash aggregates.
|
|
52
|
-
* Returns empty defaults for unknown hashes. Token/hash fields only.
|
|
53
|
-
*/
|
|
54
34
|
readCacheStateForPrefix(stablePrefixHash: string): PrefixCacheStats;
|
|
55
35
|
listResources(): ResourceDefinition[];
|
|
56
36
|
readResource(uri: string): Promise<ResourceContents | null>;
|
package/dist/resources.js
CHANGED
|
@@ -5,43 +5,18 @@ export class ResourceProvider {
|
|
|
5
5
|
performanceMetrics;
|
|
6
6
|
flightRecorder;
|
|
7
7
|
cacheAwareness;
|
|
8
|
-
constructor(sessionManager, performanceMetrics,
|
|
9
|
-
// Optional read access to the flight recorder. Used by cache-state
|
|
10
|
-
// resources (slice 2). Falls back to a stub returning [] when not
|
|
11
|
-
// injected so existing call sites continue to work without changes.
|
|
12
|
-
flightRecorder = { queryRequests: () => [] },
|
|
13
|
-
// Slice 3: optional cache-awareness config. When present, drives the
|
|
14
|
-
// TTL policy applied to ttlRemainingMs on session-scoped reads.
|
|
15
|
-
// When absent, the default Anthropic 5-min TTL applies (matches the
|
|
16
|
-
// 1.x default of `[cache_awareness].anthropic_ttl_seconds = 300`).
|
|
17
|
-
cacheAwareness = null) {
|
|
8
|
+
constructor(sessionManager, performanceMetrics, flightRecorder = { queryRequests: () => [] }, cacheAwareness = null) {
|
|
18
9
|
this.sessionManager = sessionManager;
|
|
19
10
|
this.performanceMetrics = performanceMetrics;
|
|
20
11
|
this.flightRecorder = flightRecorder;
|
|
21
12
|
this.cacheAwareness = cacheAwareness;
|
|
22
13
|
}
|
|
23
|
-
/** Read-only flight-recorder accessor for cache-state resource readers. */
|
|
24
14
|
getFlightRecorderQuery() {
|
|
25
15
|
return this.flightRecorder;
|
|
26
16
|
}
|
|
27
|
-
/**
|
|
28
|
-
* cache_state://global — aggregates across the entire flight recorder.
|
|
29
|
-
* Optionally restrict to a recent window via `lastNHours`. Returns
|
|
30
|
-
* tokens/hashes/aggregates ONLY — no prompt text fields. The redaction is
|
|
31
|
-
* structural: the response shape (GlobalCacheStats) has no `prompt`,
|
|
32
|
-
* `response`, `system`, or `task` field by construction.
|
|
33
|
-
*/
|
|
34
17
|
readCacheStateGlobal(opts = {}) {
|
|
35
18
|
return computeGlobalCacheStats(this.flightRecorder, opts);
|
|
36
19
|
}
|
|
37
|
-
/**
|
|
38
|
-
* cache_state://session/{sessionId} — per-session aggregates. Returns
|
|
39
|
-
* empty defaults when the session has no rows. Token/hash fields only.
|
|
40
|
-
*
|
|
41
|
-
* Slice 3: populates `ttlRemainingMs` by applying the configured TTL
|
|
42
|
-
* policy. Null for non-claude sessions or when the gateway has no
|
|
43
|
-
* cache-awareness config loaded (defaults to 5-min policy).
|
|
44
|
-
*/
|
|
45
20
|
readCacheStateSession(sessionId) {
|
|
46
21
|
const stats = computeSessionCacheStats(this.flightRecorder, sessionId);
|
|
47
22
|
const ttlSeconds = this.cacheAwareness?.anthropicTtlSeconds ?? 300;
|
|
@@ -50,14 +25,9 @@ export class ResourceProvider {
|
|
|
50
25
|
});
|
|
51
26
|
return stats;
|
|
52
27
|
}
|
|
53
|
-
/**
|
|
54
|
-
* cache_state://prefix/{hash} — per-stable-prefix-hash aggregates.
|
|
55
|
-
* Returns empty defaults for unknown hashes. Token/hash fields only.
|
|
56
|
-
*/
|
|
57
28
|
readCacheStateForPrefix(stablePrefixHash) {
|
|
58
29
|
return computePrefixCacheStats(this.flightRecorder, stablePrefixHash);
|
|
59
30
|
}
|
|
60
|
-
// List all available resources
|
|
61
31
|
listResources() {
|
|
62
32
|
return [
|
|
63
33
|
{
|
|
@@ -195,9 +165,7 @@ export class ResourceProvider {
|
|
|
195
165
|
},
|
|
196
166
|
];
|
|
197
167
|
}
|
|
198
|
-
// Read a specific resource by URI
|
|
199
168
|
async readResource(uri) {
|
|
200
|
-
// Session resources
|
|
201
169
|
if (uri === "sessions://all") {
|
|
202
170
|
const sessions = await this.sessionManager.listSessions();
|
|
203
171
|
return {
|
|
@@ -287,7 +255,6 @@ export class ResourceProvider {
|
|
|
287
255
|
}, null, 2),
|
|
288
256
|
};
|
|
289
257
|
}
|
|
290
|
-
// Model capability resources
|
|
291
258
|
if (uri === "models://claude") {
|
|
292
259
|
const cliInfo = getAvailableCliInfo();
|
|
293
260
|
return {
|
package/dist/retry.d.ts
CHANGED
|
@@ -1,23 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A module for adding retry and circuit breaker logic to asynchronous operations.
|
|
3
|
-
*
|
|
4
|
-
* @module retry
|
|
5
|
-
*/
|
|
6
1
|
import type { Logger } from "./logger.js";
|
|
7
|
-
/**
|
|
8
|
-
* Defines the possible states of the circuit breaker.
|
|
9
|
-
*/
|
|
10
2
|
export declare enum CircuitBreakerState {
|
|
11
|
-
/** The circuit is closed and allows operations to execute. */
|
|
12
3
|
CLOSED = "CLOSED",
|
|
13
|
-
/** The circuit is open and fails operations immediately. */
|
|
14
4
|
OPEN = "OPEN",
|
|
15
|
-
/** The circuit is half-open and allows a single trial operation. */
|
|
16
5
|
HALF_OPEN = "HALF_OPEN"
|
|
17
6
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Represents the state and configuration of a circuit breaker.
|
|
20
|
-
*/
|
|
21
7
|
export interface CircuitBreaker {
|
|
22
8
|
state: CircuitBreakerState;
|
|
23
9
|
failures: number;
|
|
@@ -26,47 +12,16 @@ export interface CircuitBreaker {
|
|
|
26
12
|
readonly failureThreshold: number;
|
|
27
13
|
onStateChange?: (newState: CircuitBreakerState, error?: Error) => void;
|
|
28
14
|
}
|
|
29
|
-
/**
|
|
30
|
-
* Configuration options for the retry logic.
|
|
31
|
-
*/
|
|
32
15
|
export interface RetryOptions {
|
|
33
|
-
/** The initial delay in milliseconds before the first retry. */
|
|
34
16
|
initialDelay: number;
|
|
35
|
-
/** The maximum delay in milliseconds between retries. */
|
|
36
17
|
maxDelay: number;
|
|
37
|
-
/** The exponential backoff factor. */
|
|
38
18
|
factor: number;
|
|
39
|
-
/**
|
|
40
|
-
* A function that determines if an error is transient and should be retried.
|
|
41
|
-
* @param error The error to check.
|
|
42
|
-
* @returns `true` if the error is transient, otherwise `false`.
|
|
43
|
-
*/
|
|
44
19
|
isTransient: (error: any) => boolean;
|
|
45
|
-
/**
|
|
46
|
-
* A callback function executed on each retry attempt.
|
|
47
|
-
* @param error The error that caused the retry.
|
|
48
|
-
* @param attempt The current retry attempt number.
|
|
49
|
-
* @param delay The delay in milliseconds before the next attempt.
|
|
50
|
-
*/
|
|
51
20
|
onRetry: (error: any, attempt: number, delay: number) => void;
|
|
52
21
|
}
|
|
53
|
-
/**
|
|
54
|
-
* Creates a new CircuitBreaker instance with default settings.
|
|
55
|
-
* @param options Partial options to override defaults.
|
|
56
|
-
* @returns A new CircuitBreaker instance.
|
|
57
|
-
*/
|
|
58
22
|
export declare function createCircuitBreaker(options?: {
|
|
59
23
|
resetTimeout?: number;
|
|
60
24
|
failureThreshold?: number;
|
|
61
25
|
onStateChange?: (newState: CircuitBreakerState, error?: Error) => void;
|
|
62
26
|
}): CircuitBreaker;
|
|
63
|
-
/**
|
|
64
|
-
* Wraps an asynchronous operation with retry and circuit breaker logic.
|
|
65
|
-
*
|
|
66
|
-
* @template T The return type of the operation.
|
|
67
|
-
* @param {() => Promise<T>} operation The asynchronous operation to execute.
|
|
68
|
-
* @param {CircuitBreaker} circuitBreaker The circuit breaker instance to use.
|
|
69
|
-
* @param {Partial<RetryOptions>} [retryOptions] Options for retry behavior.
|
|
70
|
-
* @returns {Promise<T>} A promise that resolves with the result of the operation.
|
|
71
|
-
*/
|
|
72
27
|
export declare function withRetry<T>(operation: () => Promise<T>, circuitBreaker: CircuitBreaker, retryOptions?: Partial<RetryOptions>, logger?: Logger): Promise<T>;
|