llm-cli-gateway 2.11.0 → 2.12.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/.agents/skills/async-job-orchestration/SKILL.md +288 -0
- package/.agents/skills/implement-review-fix/SKILL.md +154 -0
- package/.agents/skills/multi-llm-review/SKILL.md +174 -0
- package/.agents/skills/public-demo-session/SKILL.md +100 -0
- package/.agents/skills/secure-orchestration/SKILL.md +227 -0
- package/.agents/skills/session-workflow/SKILL.md +271 -0
- package/CHANGELOG.md +63 -1
- package/README.md +86 -27
- package/dist/acp/provider-registry.js +6 -6
- package/dist/api-provider.d.ts +7 -0
- package/dist/api-provider.js +7 -0
- package/dist/api-request.js +1 -0
- package/dist/async-job-manager.d.ts +11 -1
- package/dist/async-job-manager.js +44 -3
- package/dist/config.d.ts +2 -0
- package/dist/config.js +3 -0
- package/dist/index.d.ts +40 -4
- package/dist/index.js +611 -158
- package/dist/job-store.d.ts +48 -1
- package/dist/job-store.js +184 -0
- package/dist/provider-codegen.js +3 -0
- package/dist/provider-tool-capabilities.d.ts +4 -0
- package/dist/provider-tool-capabilities.js +16 -13
- package/dist/upstream-contracts.d.ts +1 -0
- package/dist/upstream-contracts.js +202 -45
- package/dist/validation-orchestrator.d.ts +5 -2
- package/dist/validation-orchestrator.js +71 -5
- package/dist/validation-receipt.d.ts +68 -0
- package/dist/validation-receipt.js +245 -0
- package/dist/validation-report.d.ts +4 -2
- package/dist/validation-report.js +18 -1
- package/dist/validation-tools.js +58 -9
- package/npm-shrinkwrap.json +5 -5
- package/package.json +10 -4
- package/dist/xai-api-provider.d.ts +0 -43
- package/dist/xai-api-provider.js +0 -191
|
@@ -2,12 +2,12 @@ import { randomUUID } from "crypto";
|
|
|
2
2
|
import { envWithExtendedPath, getExtendedPath, killProcessGroup, providerCommandName, spawnCliProcess, unregisterProcessGroup, } from "./executor.js";
|
|
3
3
|
import { noopLogger, logWarn } from "./logger.js";
|
|
4
4
|
import { ProcessMonitor } from "./process-monitor.js";
|
|
5
|
-
import { computeRequestKey } from "./job-store.js";
|
|
5
|
+
import { computeRequestKey, isValidationRunStore } from "./job-store.js";
|
|
6
6
|
import { NoopFlightRecorder, } from "./flight-recorder.js";
|
|
7
7
|
import { codexFrResponse } from "./codex-json-parser.js";
|
|
8
8
|
import { getRequestContext, resolveOwnerPrincipal } from "./request-context.js";
|
|
9
9
|
import { runApiRequest, ApiHttpError, } from "./api-provider.js";
|
|
10
|
-
function extractApiHttpStatus(error) {
|
|
10
|
+
export function extractApiHttpStatus(error) {
|
|
11
11
|
for (const candidate of [error, error?.cause]) {
|
|
12
12
|
if (candidate instanceof ApiHttpError && typeof candidate.status === "number") {
|
|
13
13
|
return candidate.status;
|
|
@@ -18,6 +18,14 @@ function extractApiHttpStatus(error) {
|
|
|
18
18
|
}
|
|
19
19
|
return null;
|
|
20
20
|
}
|
|
21
|
+
export function extractApiErrorBody(error) {
|
|
22
|
+
for (const candidate of [error, error?.cause]) {
|
|
23
|
+
if (candidate instanceof ApiHttpError && candidate.responseText) {
|
|
24
|
+
return candidate.responseText;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
21
29
|
const MAX_OUTPUT_SIZE = 50 * 1024 * 1024;
|
|
22
30
|
const JOB_TTL_MS = 60 * 60 * 1000;
|
|
23
31
|
const EVICTION_INTERVAL_MS = 5 * 60 * 1000;
|
|
@@ -173,6 +181,9 @@ export class AsyncJobManager {
|
|
|
173
181
|
hasStore() {
|
|
174
182
|
return this.store !== null;
|
|
175
183
|
}
|
|
184
|
+
getValidationRunStore() {
|
|
185
|
+
return this.store && isValidationRunStore(this.store) ? this.store : null;
|
|
186
|
+
}
|
|
176
187
|
emitMetrics(job) {
|
|
177
188
|
if (job.metricsRecorded)
|
|
178
189
|
return;
|
|
@@ -404,6 +415,9 @@ export class AsyncJobManager {
|
|
|
404
415
|
job.stdout = result.text;
|
|
405
416
|
job.httpStatus = result.httpStatus;
|
|
406
417
|
job.exitCode = 0;
|
|
418
|
+
job.apiUsage = result.usage;
|
|
419
|
+
job.apiResponseId = result.responseId ?? null;
|
|
420
|
+
job.apiModel = result.model;
|
|
407
421
|
}
|
|
408
422
|
else {
|
|
409
423
|
job.status = "failed";
|
|
@@ -413,6 +427,7 @@ export class AsyncJobManager {
|
|
|
413
427
|
job.stderr = message;
|
|
414
428
|
job.error = message;
|
|
415
429
|
job.exitCode = 1;
|
|
430
|
+
job.apiErrorBody = extractApiErrorBody(error);
|
|
416
431
|
}
|
|
417
432
|
job.finishedAt = new Date().toISOString();
|
|
418
433
|
job.exited = true;
|
|
@@ -443,7 +458,13 @@ export class AsyncJobManager {
|
|
|
443
458
|
if (job.flightRecorderComplete)
|
|
444
459
|
return;
|
|
445
460
|
const durationMs = Math.max(0, Date.now() - new Date(job.startedAt).getTime());
|
|
446
|
-
const usage = finalStatus
|
|
461
|
+
const usage = finalStatus !== "completed"
|
|
462
|
+
? {}
|
|
463
|
+
: job.transport === "http"
|
|
464
|
+
? this.httpUsage(job)
|
|
465
|
+
: job.extractUsage
|
|
466
|
+
? this.safeExtractUsage(job)
|
|
467
|
+
: {};
|
|
447
468
|
const isFailure = finalStatus === "failed";
|
|
448
469
|
let response;
|
|
449
470
|
if (job.transport === "process" && job.cli === "codex") {
|
|
@@ -491,6 +512,17 @@ export class AsyncJobManager {
|
|
|
491
512
|
return {};
|
|
492
513
|
}
|
|
493
514
|
}
|
|
515
|
+
httpUsage(job) {
|
|
516
|
+
const u = job.apiUsage;
|
|
517
|
+
if (!u)
|
|
518
|
+
return {};
|
|
519
|
+
return {
|
|
520
|
+
inputTokens: u.inputTokens,
|
|
521
|
+
outputTokens: u.outputTokens,
|
|
522
|
+
cacheReadTokens: u.cacheReadTokens,
|
|
523
|
+
costUsd: u.costUsd,
|
|
524
|
+
};
|
|
525
|
+
}
|
|
494
526
|
armFlightCompleteForDeferral(jobId) {
|
|
495
527
|
const job = this.jobs.get(jobId);
|
|
496
528
|
if (!job)
|
|
@@ -846,6 +878,15 @@ export class AsyncJobManager {
|
|
|
846
878
|
stderr: stderr.text,
|
|
847
879
|
stdoutTruncated: stdout.truncated,
|
|
848
880
|
stderrTruncated: stderr.truncated,
|
|
881
|
+
...(job.transport === "http"
|
|
882
|
+
? {
|
|
883
|
+
apiUsage: job.apiUsage,
|
|
884
|
+
httpStatus: job.httpStatus,
|
|
885
|
+
responseId: job.apiResponseId,
|
|
886
|
+
model: job.apiModel,
|
|
887
|
+
errorBody: job.apiErrorBody,
|
|
888
|
+
}
|
|
889
|
+
: {}),
|
|
849
890
|
};
|
|
850
891
|
}
|
|
851
892
|
cancelJob(jobId) {
|
package/dist/config.d.ts
CHANGED
|
@@ -76,6 +76,7 @@ export interface ApiProviderConfig {
|
|
|
76
76
|
baseUrl: string;
|
|
77
77
|
defaultModel: string;
|
|
78
78
|
models?: string[];
|
|
79
|
+
usageInclude?: boolean;
|
|
79
80
|
}
|
|
80
81
|
export interface ApiProviderRuntime {
|
|
81
82
|
name: string;
|
|
@@ -83,6 +84,7 @@ export interface ApiProviderRuntime {
|
|
|
83
84
|
baseUrl: string;
|
|
84
85
|
defaultModel: string;
|
|
85
86
|
models?: string[];
|
|
87
|
+
usageInclude?: boolean;
|
|
86
88
|
apiKey: string;
|
|
87
89
|
}
|
|
88
90
|
export interface ProvidersConfig {
|
package/dist/config.js
CHANGED
|
@@ -301,6 +301,7 @@ const ApiProviderSchema = z
|
|
|
301
301
|
api_key_env: z.string().min(1).optional(),
|
|
302
302
|
default_model: z.string().min(1),
|
|
303
303
|
models: z.array(z.string().min(1)).nonempty().optional(),
|
|
304
|
+
usage_include: z.boolean().optional(),
|
|
304
305
|
})
|
|
305
306
|
.strict();
|
|
306
307
|
function readProvidersFile(configPath, logger) {
|
|
@@ -369,6 +370,7 @@ export function loadProvidersConfig(logger = noopLogger) {
|
|
|
369
370
|
baseUrl: parsed.data.base_url,
|
|
370
371
|
defaultModel: parsed.data.default_model,
|
|
371
372
|
models: parsed.data.models ? [...parsed.data.models] : undefined,
|
|
373
|
+
usageInclude: parsed.data.usage_include,
|
|
372
374
|
};
|
|
373
375
|
}
|
|
374
376
|
return { xai, providers, sources: { configFile: sourcePath } };
|
|
@@ -395,6 +397,7 @@ export function enabledApiProviders(config, env = process.env) {
|
|
|
395
397
|
baseUrl: provider.baseUrl,
|
|
396
398
|
defaultModel: provider.defaultModel,
|
|
397
399
|
models: provider.models,
|
|
400
|
+
usageInclude: provider.usageInclude,
|
|
398
401
|
apiKey: resolveProviderKey(provider.apiKeyEnv, env) ?? "",
|
|
399
402
|
});
|
|
400
403
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,6 @@ import { ISessionManager, type CliType, type ProviderType } from "./session-mana
|
|
|
5
5
|
import { ResourceProvider } from "./resources.js";
|
|
6
6
|
import { PerformanceMetrics } from "./metrics.js";
|
|
7
7
|
import { type PersistenceConfig, type CacheAwarenessConfig, type ProvidersConfig, type ApiProviderRuntime, type AcpConfig } from "./config.js";
|
|
8
|
-
import { type XaiReasoningEffort } from "./xai-api-provider.js";
|
|
9
8
|
import { DatabaseConnection } from "./db.js";
|
|
10
9
|
import { AsyncJobManager } from "./async-job-manager.js";
|
|
11
10
|
import { ApprovalManager, ApprovalRecord } from "./approval-manager.js";
|
|
@@ -63,6 +62,7 @@ export declare const WORKTREE_SCHEMA: z.ZodUnion<[z.ZodBoolean, z.ZodObject<{
|
|
|
63
62
|
export declare const WORKSPACE_ALIAS_SCHEMA: z.ZodString;
|
|
64
63
|
export declare const SESSION_PROVIDER_VALUES: readonly ["claude", "codex", "gemini", "grok", "mistral", "devin", "grok-api"];
|
|
65
64
|
export declare const SESSION_PROVIDER_ENUM: z.ZodEnum<["claude", "codex", "gemini", "grok", "mistral", "devin", "grok-api"]>;
|
|
65
|
+
export declare function sessionProviderValuesFor(providers: ProvidersConfig): string[];
|
|
66
66
|
export type SessionProvider = ProviderType;
|
|
67
67
|
export interface GatewayServerDeps {
|
|
68
68
|
sessionManager?: ISessionManager;
|
|
@@ -120,6 +120,25 @@ export declare function resolveWorktreeForRequest(worktreeOpt: boolean | {
|
|
|
120
120
|
workspaceRoot?: string;
|
|
121
121
|
}): Promise<ResolvedWorktree>;
|
|
122
122
|
export declare function formatWorktreePrefix(worktreePath?: string): string;
|
|
123
|
+
export declare function createErrorResponse(cli: string, code: number, stderr: string, correlationId?: string, error?: Error, apiError?: {
|
|
124
|
+
httpStatus?: number | null;
|
|
125
|
+
responseBody?: string;
|
|
126
|
+
}): {
|
|
127
|
+
content: {
|
|
128
|
+
type: "text";
|
|
129
|
+
text: string;
|
|
130
|
+
}[];
|
|
131
|
+
isError: boolean;
|
|
132
|
+
structuredContent: {
|
|
133
|
+
httpStatus?: number | undefined;
|
|
134
|
+
responseBody?: string | undefined;
|
|
135
|
+
response: string;
|
|
136
|
+
correlationId: string | null;
|
|
137
|
+
cli: string;
|
|
138
|
+
exitCode: number;
|
|
139
|
+
errorCategory: string;
|
|
140
|
+
};
|
|
141
|
+
};
|
|
123
142
|
export declare function extractUsageAndCost(cli: "claude" | "codex" | "gemini" | "grok" | "mistral" | "devin", output: string, outputFormat?: string, ctx?: {
|
|
124
143
|
sessionId?: string;
|
|
125
144
|
home?: string;
|
|
@@ -232,6 +251,8 @@ export declare function prepareGeminiRequest(params: {
|
|
|
232
251
|
attachments?: string[];
|
|
233
252
|
skipTrust?: boolean;
|
|
234
253
|
yolo?: boolean;
|
|
254
|
+
project?: string;
|
|
255
|
+
newProject?: boolean;
|
|
235
256
|
}, runtime?: GatewayServerRuntime): CliRequestPrep | ExtendedToolResponse;
|
|
236
257
|
export declare function prepareGrokRequest(params: {
|
|
237
258
|
prompt?: string;
|
|
@@ -278,6 +299,9 @@ export declare function prepareGrokRequest(params: {
|
|
|
278
299
|
restoreCode?: boolean;
|
|
279
300
|
leaderSocket?: string;
|
|
280
301
|
nativeWorktree?: boolean | string;
|
|
302
|
+
worktreeRef?: string;
|
|
303
|
+
forkSession?: boolean;
|
|
304
|
+
jsonSchema?: string | Record<string, unknown>;
|
|
281
305
|
}, runtime?: GatewayServerRuntime): CliRequestPrep | ExtendedToolResponse;
|
|
282
306
|
export declare function prepareMistralRequest(params: {
|
|
283
307
|
prompt?: string;
|
|
@@ -309,6 +333,7 @@ export declare function buildMistralRetryPrep(params: Pick<MistralRequestParams,
|
|
|
309
333
|
env: Record<string, string>;
|
|
310
334
|
ignoredDisallowedTools: boolean;
|
|
311
335
|
};
|
|
336
|
+
export declare function buildCliResponse(cli: "claude" | "codex" | "gemini" | "grok" | "mistral" | "devin", stdout: string, optimizeResponse: boolean, corrId: string, sessionId: string | undefined, prep: CliRequestPrep, durationMs: number, resumable?: boolean, outputFormat?: string, warnings?: WarningEntry[]): ExtendedToolResponse;
|
|
312
337
|
export interface GrokApiRequestParams {
|
|
313
338
|
prompt?: string;
|
|
314
339
|
promptParts?: PromptParts;
|
|
@@ -321,12 +346,13 @@ export interface GrokApiRequestParams {
|
|
|
321
346
|
maxOutputTokens?: number;
|
|
322
347
|
temperature?: number;
|
|
323
348
|
topP?: number;
|
|
324
|
-
reasoningEffort?:
|
|
349
|
+
reasoningEffort?: "none" | "low" | "medium" | "high";
|
|
325
350
|
timeoutMs?: number;
|
|
326
351
|
}
|
|
327
352
|
export declare function handleGrokApiRequest(deps: HandlerDeps, params: GrokApiRequestParams): Promise<ExtendedToolResponse>;
|
|
328
353
|
interface ApiProviderToolParams {
|
|
329
354
|
prompt?: string;
|
|
355
|
+
promptParts?: PromptParts;
|
|
330
356
|
system?: string;
|
|
331
357
|
model?: string;
|
|
332
358
|
correlationId?: string;
|
|
@@ -335,6 +361,11 @@ interface ApiProviderToolParams {
|
|
|
335
361
|
topP?: number;
|
|
336
362
|
reasoningEffort?: "none" | "low" | "medium" | "high";
|
|
337
363
|
timeoutMs?: number;
|
|
364
|
+
optimizePrompt?: boolean;
|
|
365
|
+
optimizeResponse?: boolean;
|
|
366
|
+
forceRefresh?: boolean;
|
|
367
|
+
sessionId?: string;
|
|
368
|
+
createNewSession?: boolean;
|
|
338
369
|
}
|
|
339
370
|
export declare function handleApiProviderRequest(runtimeArg: GatewayServerRuntime, providerRuntime: ApiProviderRuntime, params: ApiProviderToolParams): Promise<ExtendedToolResponse>;
|
|
340
371
|
export declare function handleApiProviderRequestAsync(runtimeArg: GatewayServerRuntime, providerRuntime: ApiProviderRuntime, params: ApiProviderToolParams): ExtendedToolResponse;
|
|
@@ -364,6 +395,8 @@ export interface GeminiRequestParams {
|
|
|
364
395
|
attachments?: string[];
|
|
365
396
|
skipTrust?: boolean;
|
|
366
397
|
yolo?: boolean;
|
|
398
|
+
project?: string;
|
|
399
|
+
newProject?: boolean;
|
|
367
400
|
workspace?: string;
|
|
368
401
|
worktree?: boolean | {
|
|
369
402
|
name?: string;
|
|
@@ -437,6 +470,9 @@ export interface GrokRequestParams {
|
|
|
437
470
|
restoreCode?: boolean;
|
|
438
471
|
leaderSocket?: string;
|
|
439
472
|
nativeWorktree?: boolean | string;
|
|
473
|
+
worktreeRef?: string;
|
|
474
|
+
forkSession?: boolean;
|
|
475
|
+
jsonSchema?: string | Record<string, unknown>;
|
|
440
476
|
workspace?: string;
|
|
441
477
|
worktree?: boolean | {
|
|
442
478
|
name?: string;
|
|
@@ -448,7 +484,7 @@ export declare function handleGrokRequestAsync(deps: AsyncHandlerDeps, params: O
|
|
|
448
484
|
export interface DevinRequestParams {
|
|
449
485
|
prompt?: string;
|
|
450
486
|
model?: string;
|
|
451
|
-
permissionMode?: "
|
|
487
|
+
permissionMode?: "auto" | "smart" | "dangerous";
|
|
452
488
|
promptFile?: string;
|
|
453
489
|
transport?: "cli" | "acp";
|
|
454
490
|
sessionId?: string;
|
|
@@ -463,7 +499,7 @@ export interface DevinRequestParams {
|
|
|
463
499
|
export declare function prepareDevinRequest(params: {
|
|
464
500
|
prompt?: string;
|
|
465
501
|
model?: string;
|
|
466
|
-
permissionMode?:
|
|
502
|
+
permissionMode?: DevinRequestParams["permissionMode"];
|
|
467
503
|
promptFile?: string;
|
|
468
504
|
correlationId?: string;
|
|
469
505
|
optimizePrompt: boolean;
|