llm-cli-gateway 1.1.0 → 1.5.4

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/README.md +226 -9
  3. package/dist/approval-manager.d.ts +1 -1
  4. package/dist/async-job-manager.d.ts +75 -4
  5. package/dist/async-job-manager.js +303 -19
  6. package/dist/auth.d.ts +15 -0
  7. package/dist/auth.js +46 -0
  8. package/dist/cli-updater.d.ts +55 -0
  9. package/dist/cli-updater.js +248 -0
  10. package/dist/codex-json-parser.d.ts +34 -0
  11. package/dist/codex-json-parser.js +105 -0
  12. package/dist/doctor.d.ts +110 -0
  13. package/dist/doctor.js +280 -0
  14. package/dist/endpoint-exposure.d.ts +22 -0
  15. package/dist/endpoint-exposure.js +231 -0
  16. package/dist/executor.d.ts +2 -0
  17. package/dist/executor.js +2 -2
  18. package/dist/flight-recorder.d.ts +3 -1
  19. package/dist/flight-recorder.js +31 -2
  20. package/dist/gateway-server.d.ts +2 -0
  21. package/dist/gateway-server.js +1 -0
  22. package/dist/gemini-json-parser.d.ts +21 -0
  23. package/dist/gemini-json-parser.js +47 -0
  24. package/dist/health.d.ts +7 -0
  25. package/dist/health.js +22 -0
  26. package/dist/http-transport.d.ts +22 -0
  27. package/dist/http-transport.js +164 -0
  28. package/dist/index.d.ts +210 -2
  29. package/dist/index.js +2880 -1037
  30. package/dist/job-store.d.ts +84 -0
  31. package/dist/job-store.js +251 -0
  32. package/dist/logger.d.ts +9 -0
  33. package/dist/logger.js +14 -0
  34. package/dist/model-registry.d.ts +14 -0
  35. package/dist/model-registry.js +478 -134
  36. package/dist/provider-login-guidance.d.ts +21 -0
  37. package/dist/provider-login-guidance.js +98 -0
  38. package/dist/provider-status.d.ts +41 -0
  39. package/dist/provider-status.js +203 -0
  40. package/dist/request-helpers.d.ts +525 -4
  41. package/dist/request-helpers.js +653 -0
  42. package/dist/resources.js +88 -0
  43. package/dist/session-manager-pg.js +2 -0
  44. package/dist/session-manager.d.ts +1 -1
  45. package/dist/session-manager.js +3 -1
  46. package/dist/validation-normalizer.d.ts +23 -0
  47. package/dist/validation-normalizer.js +79 -0
  48. package/dist/validation-orchestrator.d.ts +47 -0
  49. package/dist/validation-orchestrator.js +145 -0
  50. package/dist/validation-prompts.d.ts +15 -0
  51. package/dist/validation-prompts.js +52 -0
  52. package/dist/validation-report.d.ts +57 -0
  53. package/dist/validation-report.js +129 -0
  54. package/dist/validation-tools.d.ts +7 -0
  55. package/dist/validation-tools.js +198 -0
  56. package/package.json +16 -6
  57. package/setup/status.schema.json +271 -0
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Parser for Gemini CLI `-o json` output.
3
+ *
4
+ * Gemini emits a single JSON object with:
5
+ * - `response`: string final model output
6
+ * - `usageMetadata`: { promptTokenCount, candidatesTokenCount,
7
+ * cachedContentTokenCount?, totalTokenCount }
8
+ *
9
+ * Returns null when stdout is not parseable as JSON. Returns an object with
10
+ * only `response` when usageMetadata is missing.
11
+ */
12
+ export function parseGeminiJson(stdout) {
13
+ const trimmed = stdout.trim();
14
+ if (!trimmed) {
15
+ return null;
16
+ }
17
+ let parsed;
18
+ try {
19
+ parsed = JSON.parse(trimmed);
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ if (!parsed || typeof parsed !== "object") {
25
+ return null;
26
+ }
27
+ const result = {};
28
+ if (typeof parsed.response === "string") {
29
+ result.response = parsed.response;
30
+ }
31
+ const meta = parsed.usageMetadata;
32
+ if (meta && typeof meta === "object") {
33
+ const input = typeof meta.promptTokenCount === "number" ? meta.promptTokenCount : undefined;
34
+ const output = typeof meta.candidatesTokenCount === "number" ? meta.candidatesTokenCount : undefined;
35
+ if (input !== undefined || output !== undefined) {
36
+ const usage = {
37
+ input_tokens: input ?? 0,
38
+ output_tokens: output ?? 0,
39
+ };
40
+ if (typeof meta.cachedContentTokenCount === "number") {
41
+ usage.cache_read_tokens = meta.cachedContentTokenCount;
42
+ }
43
+ result.usage = usage;
44
+ }
45
+ }
46
+ return result;
47
+ }
package/dist/health.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { DatabaseConnection } from "./db.js";
2
+ import { type ProviderRuntimeStatus } from "./provider-status.js";
2
3
  export interface HealthStatus {
3
4
  status: "healthy" | "degraded" | "unhealthy";
4
5
  postgres: {
@@ -11,6 +12,11 @@ export interface HealthStatus {
11
12
  };
12
13
  timestamp: string;
13
14
  }
15
+ export interface ProviderRuntimeHealth {
16
+ status: "healthy" | "degraded" | "unhealthy";
17
+ providers: Record<string, Pick<ProviderRuntimeStatus, "installed" | "version" | "loginStatus" | "loginCheck">>;
18
+ timestamp: string;
19
+ }
14
20
  /**
15
21
  * Check health status of PostgreSQL and Redis
16
22
  * - Both up → healthy
@@ -18,3 +24,4 @@ export interface HealthStatus {
18
24
  * - PostgreSQL down → unhealthy (critical failure)
19
25
  */
20
26
  export declare function checkHealth(db: DatabaseConnection): Promise<HealthStatus>;
27
+ export declare function checkProviderRuntimeHealth(): ProviderRuntimeHealth;
package/dist/health.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { listProviderRuntimeStatuses } from "./provider-status.js";
1
2
  /**
2
3
  * Check health status of PostgreSQL and Redis
3
4
  * - Both up → healthy
@@ -30,3 +31,24 @@ export async function checkHealth(db) {
30
31
  }
31
32
  return health;
32
33
  }
34
+ export function checkProviderRuntimeHealth() {
35
+ const providers = listProviderRuntimeStatuses();
36
+ const projected = Object.fromEntries(Object.entries(providers).map(([name, provider]) => [
37
+ name,
38
+ {
39
+ installed: provider.installed,
40
+ version: provider.version,
41
+ loginStatus: provider.loginStatus,
42
+ loginCheck: provider.loginCheck,
43
+ },
44
+ ]));
45
+ const statuses = Object.values(providers);
46
+ const installedCount = statuses.filter(provider => provider.installed).length;
47
+ const authenticatedCount = statuses.filter(provider => provider.loginStatus === "authenticated").length;
48
+ const status = installedCount === 0 ? "unhealthy" : authenticatedCount === 0 ? "degraded" : "healthy";
49
+ return {
50
+ status,
51
+ providers: projected,
52
+ timestamp: new Date().toISOString(),
53
+ };
54
+ }
@@ -0,0 +1,22 @@
1
+ import { type Server } from "node:http";
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import type { GatewayServerDeps } from "./index.js";
4
+ export interface HttpTransportOptions {
5
+ host?: string;
6
+ port?: number;
7
+ path?: string;
8
+ deps?: GatewayServerDeps;
9
+ createGatewayServer: (deps?: GatewayServerDeps) => McpServer;
10
+ logger?: {
11
+ info: (...args: any[]) => void;
12
+ error: (...args: any[]) => void;
13
+ debug: (...args: any[]) => void;
14
+ };
15
+ }
16
+ export interface HttpGatewayHandle {
17
+ server: Server;
18
+ url: string;
19
+ close: () => Promise<void>;
20
+ sessionCount: () => number;
21
+ }
22
+ export declare function startHttpGateway(options: HttpTransportOptions): Promise<HttpGatewayHandle>;
@@ -0,0 +1,164 @@
1
+ import { createServer } from "node:http";
2
+ import { randomUUID } from "node:crypto";
3
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
4
+ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
5
+ import { authorizeBearerRequest, getRequiredBearerToken, writeAuthFailure } from "./auth.js";
6
+ const noopLogger = {
7
+ info: (..._args) => { },
8
+ error: (..._args) => { },
9
+ debug: (..._args) => { },
10
+ };
11
+ function readBody(req) {
12
+ return new Promise((resolve, reject) => {
13
+ const chunks = [];
14
+ req.on("data", chunk => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
15
+ req.on("error", reject);
16
+ req.on("end", () => {
17
+ if (chunks.length === 0) {
18
+ resolve(undefined);
19
+ return;
20
+ }
21
+ const raw = Buffer.concat(chunks).toString("utf8");
22
+ try {
23
+ resolve(JSON.parse(raw));
24
+ }
25
+ catch (error) {
26
+ reject(error);
27
+ }
28
+ });
29
+ });
30
+ }
31
+ function methodNotAllowed(res) {
32
+ res.writeHead(405, { allow: "GET, POST, DELETE", "content-type": "application/json" });
33
+ res.end(JSON.stringify({ error: "Method not allowed" }));
34
+ }
35
+ function jsonError(res, status, message) {
36
+ res.writeHead(status, { "content-type": "application/json" });
37
+ res.end(JSON.stringify({ error: message }));
38
+ }
39
+ export async function startHttpGateway(options) {
40
+ const host = options.host ?? process.env.LLM_GATEWAY_HTTP_HOST ?? "127.0.0.1";
41
+ const port = options.port ?? Number(process.env.LLM_GATEWAY_HTTP_PORT ?? 3333);
42
+ const path = options.path ?? process.env.LLM_GATEWAY_HTTP_PATH ?? "/mcp";
43
+ const logger = options.logger ?? noopLogger;
44
+ const sessions = new Map();
45
+ const token = getRequiredBearerToken();
46
+ async function closeSession(sessionId) {
47
+ const entry = sessions.get(sessionId);
48
+ if (!entry)
49
+ return;
50
+ sessions.delete(sessionId);
51
+ await entry.transport
52
+ .close()
53
+ .catch(error => logger.error("HTTP transport close failed", error));
54
+ await entry.server.close().catch(error => logger.error("HTTP MCP server close failed", error));
55
+ }
56
+ async function createSession() {
57
+ const gatewayServer = options.createGatewayServer(options.deps);
58
+ const transport = new StreamableHTTPServerTransport({
59
+ sessionIdGenerator: () => randomUUID(),
60
+ onsessioninitialized: sessionId => {
61
+ sessions.set(sessionId, { server: gatewayServer, transport });
62
+ },
63
+ });
64
+ transport.onclose = () => {
65
+ if (transport.sessionId) {
66
+ sessions.delete(transport.sessionId);
67
+ }
68
+ };
69
+ transport.onerror = error => logger.error("HTTP MCP transport error", error);
70
+ await gatewayServer.connect(transport);
71
+ return { server: gatewayServer, transport };
72
+ }
73
+ const httpServer = createServer(async (req, res) => {
74
+ try {
75
+ const url = new URL(req.url || "/", `http://${req.headers.host || `${host}:${port}`}`);
76
+ if (url.pathname === "/healthz") {
77
+ res.writeHead(200, { "content-type": "application/json" });
78
+ res.end(JSON.stringify({ ok: true, sessions: sessions.size }));
79
+ return;
80
+ }
81
+ if (url.pathname !== path) {
82
+ jsonError(res, 404, "Not found");
83
+ return;
84
+ }
85
+ const auth = authorizeBearerRequest(req, token);
86
+ if (!auth.ok) {
87
+ writeAuthFailure(res, auth);
88
+ return;
89
+ }
90
+ if (req.method !== "GET" && req.method !== "POST" && req.method !== "DELETE") {
91
+ methodNotAllowed(res);
92
+ return;
93
+ }
94
+ const sessionId = req.headers["mcp-session-id"];
95
+ const normalizedSessionId = Array.isArray(sessionId) ? sessionId[0] : sessionId;
96
+ if (req.method === "DELETE") {
97
+ if (!normalizedSessionId) {
98
+ jsonError(res, 400, "Missing mcp-session-id");
99
+ return;
100
+ }
101
+ await closeSession(normalizedSessionId);
102
+ res.writeHead(204);
103
+ res.end();
104
+ return;
105
+ }
106
+ if (normalizedSessionId) {
107
+ const entry = sessions.get(normalizedSessionId);
108
+ if (!entry) {
109
+ jsonError(res, 404, "Unknown MCP session");
110
+ return;
111
+ }
112
+ const body = req.method === "POST" ? await readBody(req) : undefined;
113
+ await entry.transport.handleRequest(req, res, body);
114
+ return;
115
+ }
116
+ if (req.method !== "POST") {
117
+ if (req.method === "GET") {
118
+ methodNotAllowed(res);
119
+ return;
120
+ }
121
+ jsonError(res, 400, "Missing mcp-session-id");
122
+ return;
123
+ }
124
+ const body = await readBody(req);
125
+ if (!isInitializeRequest(body)) {
126
+ jsonError(res, 400, "First request must be initialize");
127
+ return;
128
+ }
129
+ const entry = await createSession();
130
+ await entry.transport.handleRequest(req, res, body);
131
+ }
132
+ catch (error) {
133
+ logger.error("HTTP transport request failed", error);
134
+ if (!res.headersSent) {
135
+ jsonError(res, 500, "Internal server error");
136
+ }
137
+ else {
138
+ res.end();
139
+ }
140
+ }
141
+ });
142
+ await new Promise((resolve, reject) => {
143
+ httpServer.once("error", reject);
144
+ httpServer.listen(port, host, () => {
145
+ httpServer.off("error", reject);
146
+ resolve();
147
+ });
148
+ });
149
+ const address = httpServer.address();
150
+ const actualPort = typeof address === "object" && address ? address.port : port;
151
+ const url = `http://${host}:${actualPort}${path}`;
152
+ logger.info(`HTTP MCP transport listening at ${url}`);
153
+ return {
154
+ server: httpServer,
155
+ url,
156
+ close: async () => {
157
+ await Promise.all([...sessions.keys()].map(closeSession));
158
+ await new Promise((resolve, reject) => {
159
+ httpServer.close(error => (error ? reject(error) : resolve()));
160
+ });
161
+ },
162
+ sessionCount: () => sessions.size,
163
+ };
164
+ }
package/dist/index.d.ts CHANGED
@@ -1,9 +1,16 @@
1
1
  #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { z } from "zod";
2
4
  import { ISessionManager } from "./session-manager.js";
5
+ import { ResourceProvider } from "./resources.js";
6
+ import { PerformanceMetrics } from "./metrics.js";
7
+ import { DatabaseConnection } from "./db.js";
3
8
  import { AsyncJobManager } from "./async-job-manager.js";
4
- import { ApprovalRecord } from "./approval-manager.js";
9
+ import { ApprovalManager, ApprovalRecord } from "./approval-manager.js";
5
10
  import { ReviewIntegrityResult } from "./review-integrity.js";
6
- import { ClaudeMcpServerName } from "./claude-mcp-config.js";
11
+ import { ClaudeMcpConfigResult, ClaudeMcpServerName } from "./claude-mcp-config.js";
12
+ import { type MistralAgentMode, type ClaudePermissionMode, type CodexSandboxMode, type CodexAskForApproval, type ClaudeEffortLevel } from "./request-helpers.js";
13
+ import { FlightRecorderLike } from "./flight-recorder.js";
7
14
  type ExtendedToolResponse = {
8
15
  content: {
9
16
  type: "text";
@@ -21,6 +28,135 @@ type ExtendedToolResponse = {
21
28
  };
22
29
  reviewIntegrity?: ReviewIntegrityResult;
23
30
  };
31
+ declare const logger: {
32
+ info: (message: string, ...args: any[]) => void;
33
+ warn: (message: string, ...args: any[]) => void;
34
+ error: (message: string, ...args: any[]) => void;
35
+ debug: (message: string, ...args: any[]) => void;
36
+ };
37
+ type GatewayLogger = typeof logger;
38
+ export declare const SESSION_PROVIDER_VALUES: readonly ["claude", "codex", "gemini", "grok", "mistral"];
39
+ export declare const SESSION_PROVIDER_ENUM: z.ZodEnum<["claude", "codex", "gemini", "grok", "mistral"]>;
40
+ export type SessionProvider = (typeof SESSION_PROVIDER_VALUES)[number];
41
+ export interface GatewayServerDeps {
42
+ sessionManager?: ISessionManager;
43
+ resourceProvider?: ResourceProvider;
44
+ db?: DatabaseConnection | null;
45
+ performanceMetrics?: PerformanceMetrics;
46
+ asyncJobManager?: AsyncJobManager;
47
+ approvalManager?: ApprovalManager;
48
+ flightRecorder?: FlightRecorderLike;
49
+ logger?: GatewayLogger;
50
+ }
51
+ interface GatewayServerRuntime {
52
+ sessionManager: ISessionManager;
53
+ resourceProvider: ResourceProvider;
54
+ db: DatabaseConnection | null;
55
+ performanceMetrics: PerformanceMetrics;
56
+ asyncJobManager: AsyncJobManager;
57
+ approvalManager: ApprovalManager;
58
+ flightRecorder: FlightRecorderLike;
59
+ logger: GatewayLogger;
60
+ }
61
+ interface CliRequestPrep {
62
+ corrId: string;
63
+ effectivePrompt: string;
64
+ resolvedModel: string | undefined;
65
+ requestedMcpServers: ClaudeMcpServerName[];
66
+ mcpConfig?: ClaudeMcpConfigResult;
67
+ approvalDecision: ApprovalRecord | null;
68
+ reviewIntegrity?: ReviewIntegrityResult;
69
+ args: string[];
70
+ }
71
+ export declare function prepareClaudeRequest(params: {
72
+ prompt: string;
73
+ model?: string;
74
+ outputFormat: "text" | "json" | "stream-json";
75
+ allowedTools?: string[];
76
+ disallowedTools?: string[];
77
+ dangerouslySkipPermissions: boolean;
78
+ permissionMode?: ClaudePermissionMode;
79
+ approvalStrategy: "legacy" | "mcp_managed";
80
+ approvalPolicy?: string;
81
+ mcpServers?: ClaudeMcpServerName[];
82
+ strictMcpConfig: boolean;
83
+ correlationId?: string;
84
+ optimizePrompt: boolean;
85
+ operation: string;
86
+ agent?: string;
87
+ agents?: Record<string, unknown>;
88
+ forkSession?: boolean;
89
+ systemPrompt?: string;
90
+ appendSystemPrompt?: string;
91
+ maxBudgetUsd?: number;
92
+ maxTurns?: number;
93
+ effort?: ClaudeEffortLevel;
94
+ excludeDynamicSystemPromptSections?: boolean;
95
+ }, runtime?: GatewayServerRuntime): CliRequestPrep | ExtendedToolResponse;
96
+ export interface CodexRequestPrep extends CliRequestPrep {
97
+ /**
98
+ * U26: Cleanup hook for any `outputSchema` temp file written during prep.
99
+ * Callers MUST invoke this in a `finally` block (regardless of whether the
100
+ * spawn succeeded, failed, or never ran) to avoid leaking the 0o600 temp
101
+ * file into `os.tmpdir()`.
102
+ */
103
+ cleanup?: () => void;
104
+ }
105
+ export declare function prepareCodexRequest(params: {
106
+ prompt: string;
107
+ model?: string;
108
+ fullAuto: boolean;
109
+ sandboxMode?: CodexSandboxMode;
110
+ askForApproval?: CodexAskForApproval;
111
+ useLegacyFullAutoFlag?: boolean;
112
+ dangerouslyBypassApprovalsAndSandbox: boolean;
113
+ approvalStrategy: "legacy" | "mcp_managed";
114
+ approvalPolicy?: string;
115
+ mcpServers?: ClaudeMcpServerName[];
116
+ sessionId?: string;
117
+ resumeLatest?: boolean;
118
+ createNewSession?: boolean;
119
+ correlationId?: string;
120
+ optimizePrompt: boolean;
121
+ operation: string;
122
+ /**
123
+ * U23: output format. When set to "json", emits `--json` so Codex streams
124
+ * the JSONL event format that `parseCodexJsonStream` (and downstream
125
+ * `extractUsageAndCost`) can consume. Defaults to "text".
126
+ */
127
+ outputFormat?: "text" | "json";
128
+ outputSchema?: string | Record<string, unknown>;
129
+ search?: boolean;
130
+ profile?: string;
131
+ configOverrides?: Record<string, string>;
132
+ ephemeral?: boolean;
133
+ images?: string[];
134
+ ignoreUserConfig?: boolean;
135
+ ignoreRules?: boolean;
136
+ }, runtime?: GatewayServerRuntime): CodexRequestPrep | ExtendedToolResponse;
137
+ export declare function prepareGeminiRequest(params: {
138
+ prompt: string;
139
+ model?: string;
140
+ approvalMode?: string;
141
+ approvalStrategy: "legacy" | "mcp_managed";
142
+ approvalPolicy?: string;
143
+ allowedTools?: string[];
144
+ includeDirs?: string[];
145
+ mcpServers?: ClaudeMcpServerName[];
146
+ correlationId?: string;
147
+ optimizePrompt: boolean;
148
+ operation: string;
149
+ /**
150
+ * U23: output format. When set to "json", emits `-o json` so Gemini emits
151
+ * the JSON object containing usageMetadata that `parseGeminiJson` (and
152
+ * downstream `extractUsageAndCost`) can consume. Defaults to "text".
153
+ */
154
+ outputFormat?: "text" | "json";
155
+ sandbox?: boolean;
156
+ policyFiles?: string[];
157
+ adminPolicyFiles?: string[];
158
+ attachments?: string[];
159
+ }, runtime?: GatewayServerRuntime): CliRequestPrep | ExtendedToolResponse;
24
160
  export interface GeminiRequestParams {
25
161
  prompt: string;
26
162
  model?: string;
@@ -37,32 +173,104 @@ export interface GeminiRequestParams {
37
173
  optimizePrompt: boolean;
38
174
  optimizeResponse?: boolean;
39
175
  idleTimeoutMs?: number;
176
+ forceRefresh?: boolean;
177
+ /** U23: "json" emits `-o json` so token usage is parsed and reported. */
178
+ outputFormat?: "text" | "json";
179
+ sandbox?: boolean;
180
+ policyFiles?: string[];
181
+ adminPolicyFiles?: string[];
182
+ attachments?: string[];
40
183
  }
41
184
  export interface HandlerDeps {
42
185
  sessionManager: ISessionManager;
43
186
  logger: {
44
187
  info: (...args: any[]) => void;
188
+ warn?: (...args: any[]) => void;
45
189
  error: (...args: any[]) => void;
46
190
  debug: (...args: any[]) => void;
47
191
  };
192
+ runtime?: GatewayServerRuntime;
48
193
  }
49
194
  export interface AsyncHandlerDeps extends HandlerDeps {
50
195
  asyncJobManager: AsyncJobManager;
51
196
  }
52
197
  export declare function handleGeminiRequest(deps: HandlerDeps, params: GeminiRequestParams): Promise<ExtendedToolResponse>;
53
198
  export declare function handleGeminiRequestAsync(deps: AsyncHandlerDeps, params: Omit<GeminiRequestParams, "optimizeResponse">): Promise<ExtendedToolResponse>;
199
+ export interface GrokRequestParams {
200
+ prompt: string;
201
+ model?: string;
202
+ outputFormat?: string;
203
+ sessionId?: string;
204
+ resumeLatest: boolean;
205
+ createNewSession: boolean;
206
+ alwaysApprove?: boolean;
207
+ permissionMode?: string;
208
+ effort?: string;
209
+ reasoningEffort?: string;
210
+ approvalStrategy: "legacy" | "mcp_managed";
211
+ approvalPolicy?: string;
212
+ mcpServers?: ClaudeMcpServerName[];
213
+ allowedTools?: string[];
214
+ disallowedTools?: string[];
215
+ correlationId?: string;
216
+ optimizePrompt: boolean;
217
+ optimizeResponse?: boolean;
218
+ idleTimeoutMs?: number;
219
+ forceRefresh?: boolean;
220
+ }
221
+ export declare function handleGrokRequest(deps: HandlerDeps, params: GrokRequestParams): Promise<ExtendedToolResponse>;
222
+ export declare function handleGrokRequestAsync(deps: AsyncHandlerDeps, params: Omit<GrokRequestParams, "optimizeResponse">): Promise<ExtendedToolResponse>;
223
+ export interface MistralRequestParams {
224
+ prompt: string;
225
+ model?: string;
226
+ outputFormat?: string;
227
+ sessionId?: string;
228
+ resumeLatest: boolean;
229
+ createNewSession: boolean;
230
+ permissionMode?: MistralAgentMode;
231
+ effort?: string;
232
+ reasoningEffort?: string;
233
+ approvalStrategy: "legacy" | "mcp_managed";
234
+ approvalPolicy?: string;
235
+ mcpServers?: ClaudeMcpServerName[];
236
+ allowedTools?: string[];
237
+ disallowedTools?: string[];
238
+ correlationId?: string;
239
+ optimizePrompt: boolean;
240
+ optimizeResponse?: boolean;
241
+ idleTimeoutMs?: number;
242
+ forceRefresh?: boolean;
243
+ }
244
+ export declare function handleMistralRequest(deps: HandlerDeps, params: MistralRequestParams): Promise<ExtendedToolResponse>;
245
+ export declare function handleMistralRequestAsync(deps: AsyncHandlerDeps, params: Omit<MistralRequestParams, "optimizeResponse">): Promise<ExtendedToolResponse>;
54
246
  export declare function handleCodexRequestAsync(deps: AsyncHandlerDeps, params: {
55
247
  prompt: string;
56
248
  model?: string;
57
249
  fullAuto: boolean;
250
+ sandboxMode?: CodexSandboxMode;
251
+ askForApproval?: CodexAskForApproval;
252
+ useLegacyFullAutoFlag?: boolean;
58
253
  dangerouslyBypassApprovalsAndSandbox: boolean;
59
254
  approvalStrategy: "legacy" | "mcp_managed";
60
255
  approvalPolicy?: string;
61
256
  mcpServers?: ClaudeMcpServerName[];
62
257
  sessionId?: string;
258
+ resumeLatest?: boolean;
63
259
  createNewSession: boolean;
64
260
  correlationId?: string;
65
261
  optimizePrompt: boolean;
66
262
  idleTimeoutMs?: number;
263
+ forceRefresh?: boolean;
264
+ /** U23: when "json", emits Codex `--json` so the parser is reachable. */
265
+ outputFormat?: "text" | "json";
266
+ outputSchema?: string | Record<string, unknown>;
267
+ search?: boolean;
268
+ profile?: string;
269
+ configOverrides?: Record<string, string>;
270
+ ephemeral?: boolean;
271
+ images?: string[];
272
+ ignoreUserConfig?: boolean;
273
+ ignoreRules?: boolean;
67
274
  }): Promise<ExtendedToolResponse>;
275
+ export declare function createGatewayServer(deps?: GatewayServerDeps): McpServer;
68
276
  export {};