llm-cli-gateway 2.13.2 → 2.14.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/CHANGELOG.md +139 -0
- package/README.md +68 -29
- package/dist/acp/client.d.ts +29 -1
- package/dist/acp/client.js +78 -4
- package/dist/acp/errors.d.ts +9 -1
- package/dist/acp/errors.js +19 -0
- package/dist/acp/event-normalizer.d.ts +12 -0
- package/dist/acp/event-normalizer.js +16 -0
- package/dist/acp/flight-redaction.d.ts +3 -0
- package/dist/acp/flight-redaction.js +3 -0
- package/dist/acp/permission-bridge.js +11 -5
- package/dist/acp/process-manager.d.ts +2 -1
- package/dist/acp/process-manager.js +43 -4
- package/dist/acp/provider-registry.js +19 -11
- package/dist/acp/runtime.d.ts +8 -0
- package/dist/acp/runtime.js +47 -4
- package/dist/acp/types.d.ts +3083 -55
- package/dist/acp/types.js +242 -5
- package/dist/async-job-manager.d.ts +38 -1
- package/dist/async-job-manager.js +287 -20
- package/dist/codex-json-parser.d.ts +1 -0
- package/dist/codex-json-parser.js +6 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.js +84 -1
- package/dist/flight-recorder.d.ts +2 -0
- package/dist/flight-recorder.js +20 -0
- package/dist/gemini-json-parser.d.ts +2 -0
- package/dist/gemini-json-parser.js +45 -8
- package/dist/grok-json-parser.d.ts +14 -0
- package/dist/grok-json-parser.js +156 -0
- package/dist/index.d.ts +47 -2
- package/dist/index.js +504 -122
- package/dist/job-store.d.ts +119 -11
- package/dist/job-store.js +372 -42
- package/dist/model-registry.d.ts +1 -0
- package/dist/model-registry.js +46 -0
- package/dist/oauth.js +2 -2
- package/dist/postgres-job-store-worker.d.ts +1 -0
- package/dist/postgres-job-store-worker.js +444 -0
- package/dist/pricing.d.ts +3 -2
- package/dist/provider-acp-capabilities.d.ts +52 -0
- package/dist/provider-acp-capabilities.js +101 -0
- package/dist/provider-admin-tools.d.ts +100 -0
- package/dist/provider-admin-tools.js +572 -0
- package/dist/provider-capability-cache.d.ts +46 -0
- package/dist/provider-capability-cache.js +248 -0
- package/dist/provider-capability-discovery.d.ts +85 -0
- package/dist/provider-capability-discovery.js +461 -0
- package/dist/provider-capability-resolver.d.ts +29 -0
- package/dist/provider-capability-resolver.js +92 -0
- package/dist/provider-definition-assertions.d.ts +9 -0
- package/dist/provider-definition-assertions.js +147 -0
- package/dist/provider-definitions.d.ts +127 -0
- package/dist/provider-definitions.js +758 -0
- package/dist/provider-help-parser.d.ts +34 -0
- package/dist/provider-help-parser.js +203 -0
- package/dist/provider-model-discovery.d.ts +30 -0
- package/dist/provider-model-discovery.js +229 -0
- package/dist/provider-output-metadata.d.ts +7 -0
- package/dist/provider-output-metadata.js +68 -0
- package/dist/provider-schema-builder.d.ts +22 -0
- package/dist/provider-schema-builder.js +55 -0
- package/dist/provider-surface-generator.d.ts +98 -0
- package/dist/provider-surface-generator.js +140 -0
- package/dist/provider-tool-capabilities.d.ts +3 -2
- package/dist/provider-tool-capabilities.js +77 -62
- package/dist/request-helpers.d.ts +37 -4
- package/dist/request-helpers.js +134 -0
- package/dist/resources.d.ts +6 -1
- package/dist/resources.js +64 -192
- package/dist/session-manager.js +18 -11
- package/dist/sqlite-driver.d.ts +1 -1
- package/dist/sqlite-driver.js +2 -1
- package/dist/stream-json-parser.d.ts +1 -0
- package/dist/stream-json-parser.js +3 -0
- package/dist/upstream-contracts.d.ts +17 -1
- package/dist/upstream-contracts.js +209 -36
- package/npm-shrinkwrap.json +2 -2
- package/package.json +8 -3
package/dist/request-helpers.js
CHANGED
|
@@ -176,6 +176,86 @@ export function resolveClaudePermissionFlags(input) {
|
|
|
176
176
|
export const GEMINI_APPROVAL_MODES = ["default", "auto_edit", "yolo", "plan"];
|
|
177
177
|
export const CODEX_SANDBOX_MODES = ["read-only", "workspace-write", "danger-full-access"];
|
|
178
178
|
export const CODEX_ASK_FOR_APPROVAL_MODES = ["untrusted", "on-request", "never"];
|
|
179
|
+
export const CODEX_LOCAL_PROVIDERS = ["lmstudio", "ollama"];
|
|
180
|
+
export const CODEX_COLOR_MODES = ["always", "never", "auto"];
|
|
181
|
+
export const CLAUDE_UNEXPOSED_CLI_FLAGS = [
|
|
182
|
+
{
|
|
183
|
+
flag: "--tmux",
|
|
184
|
+
reason: "interactive-only",
|
|
185
|
+
detail: "Creates an attached tmux/iTerm2 session for a worktree (requires --worktree); incompatible with headless --print.",
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
flag: "--background",
|
|
189
|
+
reason: "gateway-managed",
|
|
190
|
+
detail: "Starts a detached background agent (managed via `claude agents`); conflicts with the gateway's own async-job model.",
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
flag: "--remote-control",
|
|
194
|
+
reason: "gateway-managed",
|
|
195
|
+
detail: "Starts an interactive Remote Control session; a stateful/remote surface deferred to the gateway-managed transport.",
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
flag: "--remote",
|
|
199
|
+
reason: "admin-deferred",
|
|
200
|
+
detail: "No bare --remote exists in installed Claude help; the only remote surface is --remote-control (gateway-managed).",
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
flag: "--worktree",
|
|
204
|
+
reason: "gateway-managed",
|
|
205
|
+
detail: "claude --help advertises -w, --worktree [name], but gateway worktrees are owned by slice λ (worktree-manager); the native --worktree is intentionally never emitted so the gateway owns the checkout lifecycle.",
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
flag: "--resume",
|
|
209
|
+
reason: "gateway-managed",
|
|
210
|
+
detail: "claude --help advertises -r, --resume [value] for interactive resume; the gateway session model maps continuity onto --continue (continueSession) and --session-id (sessionId), so the raw --resume passthrough is intentionally not wired.",
|
|
211
|
+
},
|
|
212
|
+
];
|
|
213
|
+
export const CODEX_UNEXPOSED_CLI_FLAGS = [
|
|
214
|
+
{
|
|
215
|
+
flag: "--remote",
|
|
216
|
+
reason: "admin-deferred",
|
|
217
|
+
detail: "TUI-only (top-level `codex` help, not `codex exec`): connects the TUI to a remote app-server endpoint; not a headless exec flag.",
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
flag: "--remote-auth-token-env",
|
|
221
|
+
reason: "admin-deferred",
|
|
222
|
+
detail: "TUI-only companion to --remote (bearer-token env var for the remote app-server websocket); not a headless exec flag.",
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
flag: "--ask-for-approval",
|
|
226
|
+
reason: "admin-deferred",
|
|
227
|
+
detail: "Removed from the installed `codex exec` upstream: current codex exec no longer accepts --ask-for-approval. The askForApproval MCP input is retained for back-compat but warns and emits no argv (accepted-but-ignored); classified here because the flag is not present in the installed headless help.",
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
flag: "--search",
|
|
231
|
+
reason: "admin-deferred",
|
|
232
|
+
detail: "Removed from the installed `codex exec` upstream: current codex exec no longer accepts --search. The search MCP input is retained for back-compat but warns and emits no argv (accepted-but-ignored); classified here because the flag is not present in the installed headless help.",
|
|
233
|
+
},
|
|
234
|
+
];
|
|
235
|
+
export const GEMINI_UNEXPOSED_CLI_FLAGS = [
|
|
236
|
+
{
|
|
237
|
+
flag: "--prompt-interactive",
|
|
238
|
+
reason: "interactive-only",
|
|
239
|
+
detail: "Runs an initial prompt then continues in an attached interactive session (short alias -i); incompatible with the headless --print run mode the gateway drives.",
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
flag: "--log-file",
|
|
243
|
+
reason: "admin-deferred",
|
|
244
|
+
detail: "Overrides agy's internal CLI log file path (a diagnostic/maintenance surface); the gateway flight recorder is the request-logging surface, so this is deferred to a later admin phase.",
|
|
245
|
+
},
|
|
246
|
+
];
|
|
247
|
+
export const MISTRAL_UNEXPOSED_CLI_FLAGS = [
|
|
248
|
+
{
|
|
249
|
+
flag: "--setup",
|
|
250
|
+
reason: "admin-deferred",
|
|
251
|
+
detail: "Vibe `--setup` configures the API key and exits; a credential/setup maintenance op, not a headless run flag. Deferred to the phase-6 admin surface.",
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
flag: "--check-upgrade",
|
|
255
|
+
reason: "admin-deferred",
|
|
256
|
+
detail: "Vibe `--check-upgrade` checks for a Vibe update, prompts to install, and exits; a maintenance op, not a headless run flag. Deferred to the phase-6 admin surface.",
|
|
257
|
+
},
|
|
258
|
+
];
|
|
179
259
|
export function resolveCodexSandboxFlags(input) {
|
|
180
260
|
const { sandboxMode, askForApproval, fullAuto, useLegacyFullAutoFlag } = input;
|
|
181
261
|
const args = [];
|
|
@@ -324,6 +404,48 @@ export function prepareClaudeHighImpactFlags(input) {
|
|
|
324
404
|
if (input.tools && input.tools.length > 0) {
|
|
325
405
|
args.push("--tools", ...input.tools);
|
|
326
406
|
}
|
|
407
|
+
if (input.includeHookEvents) {
|
|
408
|
+
args.push("--include-hook-events");
|
|
409
|
+
}
|
|
410
|
+
if (input.replayUserMessages) {
|
|
411
|
+
args.push("--replay-user-messages");
|
|
412
|
+
}
|
|
413
|
+
if (input.systemPromptFile !== undefined) {
|
|
414
|
+
args.push("--system-prompt-file", input.systemPromptFile);
|
|
415
|
+
}
|
|
416
|
+
if (input.appendSystemPromptFile !== undefined) {
|
|
417
|
+
args.push("--append-system-prompt-file", input.appendSystemPromptFile);
|
|
418
|
+
}
|
|
419
|
+
if (input.name !== undefined) {
|
|
420
|
+
args.push("--name", input.name);
|
|
421
|
+
}
|
|
422
|
+
if (input.pluginDir && input.pluginDir.length > 0) {
|
|
423
|
+
for (const dir of input.pluginDir) {
|
|
424
|
+
args.push("--plugin-dir", dir);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
if (input.pluginUrl && input.pluginUrl.length > 0) {
|
|
428
|
+
for (const url of input.pluginUrl) {
|
|
429
|
+
args.push("--plugin-url", url);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
if (input.safeMode) {
|
|
433
|
+
args.push("--safe-mode");
|
|
434
|
+
}
|
|
435
|
+
if (input.bare) {
|
|
436
|
+
args.push("--bare");
|
|
437
|
+
}
|
|
438
|
+
if (input.debug !== undefined && input.debug !== false) {
|
|
439
|
+
if (typeof input.debug === "string") {
|
|
440
|
+
args.push("--debug", input.debug);
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
args.push("--debug");
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
if (input.debugFile !== undefined) {
|
|
447
|
+
args.push("--debug-file", input.debugFile);
|
|
448
|
+
}
|
|
327
449
|
return args;
|
|
328
450
|
}
|
|
329
451
|
export const CODEX_CONFIG_OVERRIDES_SCHEMA = z
|
|
@@ -382,6 +504,8 @@ export const CODEX_HIGH_IMPACT_PARAMS_SCHEMA = z.object({
|
|
|
382
504
|
images: z.array(z.string()).optional(),
|
|
383
505
|
ignoreUserConfig: z.boolean().optional(),
|
|
384
506
|
ignoreRules: z.boolean().optional(),
|
|
507
|
+
enable: z.array(z.string()).optional(),
|
|
508
|
+
disable: z.array(z.string()).optional(),
|
|
385
509
|
});
|
|
386
510
|
export function prepareCodexHighImpactFlags(input) {
|
|
387
511
|
const missingImagePath = findMissingImagePath(input.images);
|
|
@@ -417,6 +541,16 @@ export function prepareCodexHighImpactFlags(input) {
|
|
|
417
541
|
if (input.ignoreRules) {
|
|
418
542
|
args.push("--ignore-rules");
|
|
419
543
|
}
|
|
544
|
+
if (input.enable && input.enable.length > 0) {
|
|
545
|
+
for (const feature of input.enable) {
|
|
546
|
+
args.push("--enable", feature);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
if (input.disable && input.disable.length > 0) {
|
|
550
|
+
for (const feature of input.disable) {
|
|
551
|
+
args.push("--disable", feature);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
420
554
|
return {
|
|
421
555
|
args,
|
|
422
556
|
cleanup,
|
package/dist/resources.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { ISessionManager } from "./session-manager.js";
|
|
2
|
+
import { type CliType } from "./session-manager.js";
|
|
2
3
|
import { PerformanceMetrics } from "./metrics.js";
|
|
3
4
|
import { FlightRecorderQuery } from "./flight-recorder.js";
|
|
4
5
|
import { type GlobalCacheStats, type PrefixCacheStats, type SessionCacheStats } from "./cache-stats.js";
|
|
5
6
|
import { type CacheAwarenessConfig, type ProvidersConfig } from "./config.js";
|
|
7
|
+
import type { AcpConfig } from "./config.js";
|
|
8
|
+
import { type ResolvedProviderCapability } from "./provider-capability-resolver.js";
|
|
6
9
|
export interface ResourceDefinition {
|
|
7
10
|
uri: string;
|
|
8
11
|
name: string;
|
|
@@ -26,7 +29,9 @@ export declare class ResourceProvider {
|
|
|
26
29
|
private flightRecorder;
|
|
27
30
|
private cacheAwareness;
|
|
28
31
|
private providers;
|
|
29
|
-
|
|
32
|
+
private capabilityPeek;
|
|
33
|
+
private acpConfig;
|
|
34
|
+
constructor(sessionManager: ISessionManager, performanceMetrics: PerformanceMetrics, flightRecorder?: FlightRecorderQuery, cacheAwareness?: CacheAwarenessConfig | null, providers?: ProvidersConfig | null, capabilityPeek?: (id: CliType) => ResolvedProviderCapability | null, acpConfig?: AcpConfig | null);
|
|
30
35
|
getFlightRecorderQuery(): FlightRecorderQuery;
|
|
31
36
|
private apiRuntimes;
|
|
32
37
|
private continuityTrackedApiRuntimes;
|
package/dist/resources.js
CHANGED
|
@@ -8,18 +8,26 @@ import { apiContinuityForKind } from "./api-provider.js";
|
|
|
8
8
|
import { apiProviderCatalogEntry } from "./api-request.js";
|
|
9
9
|
import { buildProviderSubcommandsCompactCatalog, getCliSubcommandContract, serializeCliSubcommandContract, } from "./upstream-contracts.js";
|
|
10
10
|
import { getOneProviderToolCapabilities, getProviderToolCapabilities, knownProviderCapabilityIds, providerCapabilityIds, } from "./provider-tool-capabilities.js";
|
|
11
|
+
import { generateProviderAcpDescriptors, generateResourceDescriptors, parseModelsResourceUri, parseProviderAcpResourceUri, parseSessionsResourceUri, } from "./provider-surface-generator.js";
|
|
12
|
+
import { getProviderDefinition } from "./provider-definitions.js";
|
|
13
|
+
import { buildProviderAcpCapabilityRecord } from "./provider-acp-capabilities.js";
|
|
14
|
+
import { buildProviderDiscoveredView, peekProviderCapabilitySet, } from "./provider-capability-resolver.js";
|
|
11
15
|
export class ResourceProvider {
|
|
12
16
|
sessionManager;
|
|
13
17
|
performanceMetrics;
|
|
14
18
|
flightRecorder;
|
|
15
19
|
cacheAwareness;
|
|
16
20
|
providers;
|
|
17
|
-
|
|
21
|
+
capabilityPeek;
|
|
22
|
+
acpConfig;
|
|
23
|
+
constructor(sessionManager, performanceMetrics, flightRecorder = { queryRequests: () => [] }, cacheAwareness = null, providers = null, capabilityPeek = peekProviderCapabilitySet, acpConfig = null) {
|
|
18
24
|
this.sessionManager = sessionManager;
|
|
19
25
|
this.performanceMetrics = performanceMetrics;
|
|
20
26
|
this.flightRecorder = flightRecorder;
|
|
21
27
|
this.cacheAwareness = cacheAwareness;
|
|
22
28
|
this.providers = providers;
|
|
29
|
+
this.capabilityPeek = capabilityPeek;
|
|
30
|
+
this.acpConfig = acpConfig;
|
|
23
31
|
}
|
|
24
32
|
getFlightRecorderQuery() {
|
|
25
33
|
return this.flightRecorder;
|
|
@@ -61,61 +69,19 @@ export class ResourceProvider {
|
|
|
61
69
|
lastModified: new Date().toISOString(),
|
|
62
70
|
},
|
|
63
71
|
},
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
audience: ["user", "assistant"],
|
|
72
|
-
priority: 0.6,
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
uri: "sessions://codex",
|
|
77
|
-
name: "Codex Sessions",
|
|
78
|
-
title: "💻 Codex Sessions",
|
|
79
|
-
description: "List of Codex conversation sessions",
|
|
80
|
-
mimeType: "application/json",
|
|
81
|
-
annotations: {
|
|
82
|
-
audience: ["user", "assistant"],
|
|
83
|
-
priority: 0.6,
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
uri: "sessions://gemini",
|
|
88
|
-
name: "Gemini Sessions",
|
|
89
|
-
title: "✨ Gemini Sessions",
|
|
90
|
-
description: "List of Gemini conversation sessions",
|
|
91
|
-
mimeType: "application/json",
|
|
92
|
-
annotations: {
|
|
93
|
-
audience: ["user", "assistant"],
|
|
94
|
-
priority: 0.6,
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
uri: "sessions://grok",
|
|
99
|
-
name: "Grok Sessions",
|
|
100
|
-
title: "⚡ Grok Sessions",
|
|
101
|
-
description: "List of Grok conversation sessions",
|
|
72
|
+
...generateResourceDescriptors()
|
|
73
|
+
.filter(descriptor => descriptor.exposesSessionsResource)
|
|
74
|
+
.map(descriptor => ({
|
|
75
|
+
uri: descriptor.sessionsUri,
|
|
76
|
+
name: `${descriptor.sessionLabel}s`,
|
|
77
|
+
title: `${descriptor.icon} ${descriptor.sessionLabel}s`,
|
|
78
|
+
description: `List of ${descriptor.displayName} conversation sessions`,
|
|
102
79
|
mimeType: "application/json",
|
|
103
80
|
annotations: {
|
|
104
81
|
audience: ["user", "assistant"],
|
|
105
82
|
priority: 0.6,
|
|
106
83
|
},
|
|
107
|
-
},
|
|
108
|
-
{
|
|
109
|
-
uri: "sessions://mistral",
|
|
110
|
-
name: "Mistral Sessions",
|
|
111
|
-
title: "🌬 Mistral Sessions",
|
|
112
|
-
description: "List of Mistral Vibe conversation sessions",
|
|
113
|
-
mimeType: "application/json",
|
|
114
|
-
annotations: {
|
|
115
|
-
audience: ["user", "assistant"],
|
|
116
|
-
priority: 0.6,
|
|
117
|
-
},
|
|
118
|
-
},
|
|
84
|
+
})),
|
|
119
85
|
...this.continuityTrackedApiRuntimes().map(rt => ({
|
|
120
86
|
uri: `sessions://${rt.name}`,
|
|
121
87
|
name: `${rt.name} Sessions`,
|
|
@@ -127,61 +93,19 @@ export class ResourceProvider {
|
|
|
127
93
|
priority: 0.6,
|
|
128
94
|
},
|
|
129
95
|
})),
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
audience: ["user", "assistant"],
|
|
138
|
-
priority: 0.8,
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
uri: "models://codex",
|
|
143
|
-
name: "Codex Models",
|
|
144
|
-
title: "🔧 Codex Models & Capabilities",
|
|
145
|
-
description: "Available Codex models and their capabilities",
|
|
146
|
-
mimeType: "application/json",
|
|
147
|
-
annotations: {
|
|
148
|
-
audience: ["user", "assistant"],
|
|
149
|
-
priority: 0.8,
|
|
150
|
-
},
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
uri: "models://gemini",
|
|
154
|
-
name: "Gemini Models",
|
|
155
|
-
title: "🌟 Gemini Models & Capabilities",
|
|
156
|
-
description: "Available Gemini models and their capabilities",
|
|
157
|
-
mimeType: "application/json",
|
|
158
|
-
annotations: {
|
|
159
|
-
audience: ["user", "assistant"],
|
|
160
|
-
priority: 0.8,
|
|
161
|
-
},
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
uri: "models://grok",
|
|
165
|
-
name: "Grok Models",
|
|
166
|
-
title: "⚡ Grok Models & Capabilities",
|
|
167
|
-
description: "Available Grok models and their capabilities",
|
|
168
|
-
mimeType: "application/json",
|
|
169
|
-
annotations: {
|
|
170
|
-
audience: ["user", "assistant"],
|
|
171
|
-
priority: 0.8,
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
uri: "models://mistral",
|
|
176
|
-
name: "Mistral Models",
|
|
177
|
-
title: "🌬 Mistral Models & Capabilities",
|
|
178
|
-
description: "Available Mistral Vibe models and their capabilities",
|
|
96
|
+
...generateResourceDescriptors()
|
|
97
|
+
.filter(descriptor => descriptor.exposesModelsResource)
|
|
98
|
+
.map(descriptor => ({
|
|
99
|
+
uri: descriptor.modelsUri,
|
|
100
|
+
name: `${descriptor.displayName} Models`,
|
|
101
|
+
title: `${descriptor.icon} ${descriptor.displayName} Models & Capabilities`,
|
|
102
|
+
description: `Available ${descriptor.displayName} models and their capabilities`,
|
|
179
103
|
mimeType: "application/json",
|
|
180
104
|
annotations: {
|
|
181
105
|
audience: ["user", "assistant"],
|
|
182
106
|
priority: 0.8,
|
|
183
107
|
},
|
|
184
|
-
},
|
|
108
|
+
})),
|
|
185
109
|
...this.apiRuntimes().map(rt => ({
|
|
186
110
|
uri: `models://${rt.name}`,
|
|
187
111
|
name: `${rt.name} Models`,
|
|
@@ -237,6 +161,17 @@ export class ResourceProvider {
|
|
|
237
161
|
priority: 0.8,
|
|
238
162
|
},
|
|
239
163
|
})),
|
|
164
|
+
...generateProviderAcpDescriptors().map(descriptor => ({
|
|
165
|
+
uri: descriptor.acpUri,
|
|
166
|
+
name: `${descriptor.displayName} ACP Capabilities`,
|
|
167
|
+
title: `${descriptor.icon} ${descriptor.displayName} ACP Capabilities`,
|
|
168
|
+
description: `Native ACP entrypoint, negotiated capabilities, supported session methods, and host-service policy for ${descriptor.displayName}`,
|
|
169
|
+
mimeType: "application/json",
|
|
170
|
+
annotations: {
|
|
171
|
+
audience: ["user", "assistant"],
|
|
172
|
+
priority: 0.7,
|
|
173
|
+
},
|
|
174
|
+
})),
|
|
240
175
|
];
|
|
241
176
|
}
|
|
242
177
|
ownedSessions(sessions) {
|
|
@@ -271,109 +206,28 @@ export class ResourceProvider {
|
|
|
271
206
|
}, null, 2),
|
|
272
207
|
};
|
|
273
208
|
}
|
|
274
|
-
|
|
275
|
-
|
|
209
|
+
const sessionProvider = parseSessionsResourceUri(uri);
|
|
210
|
+
if (sessionProvider) {
|
|
211
|
+
const sessions = this.ownedSessions(await this.sessionManager.listSessions(sessionProvider));
|
|
276
212
|
return {
|
|
277
213
|
uri,
|
|
278
214
|
mimeType: "application/json",
|
|
279
215
|
text: JSON.stringify({
|
|
280
|
-
cli:
|
|
216
|
+
cli: sessionProvider,
|
|
281
217
|
total: sessions.length,
|
|
282
218
|
sessions,
|
|
283
|
-
activeSession: await this.ownedActiveId(
|
|
219
|
+
activeSession: await this.ownedActiveId(sessionProvider),
|
|
284
220
|
}, null, 2),
|
|
285
221
|
};
|
|
286
222
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return {
|
|
290
|
-
uri,
|
|
291
|
-
mimeType: "application/json",
|
|
292
|
-
text: JSON.stringify({
|
|
293
|
-
cli: "codex",
|
|
294
|
-
total: sessions.length,
|
|
295
|
-
sessions,
|
|
296
|
-
activeSession: await this.ownedActiveId("codex"),
|
|
297
|
-
}, null, 2),
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
if (uri === "sessions://gemini") {
|
|
301
|
-
const sessions = this.ownedSessions(await this.sessionManager.listSessions("gemini"));
|
|
302
|
-
return {
|
|
303
|
-
uri,
|
|
304
|
-
mimeType: "application/json",
|
|
305
|
-
text: JSON.stringify({
|
|
306
|
-
cli: "gemini",
|
|
307
|
-
total: sessions.length,
|
|
308
|
-
sessions,
|
|
309
|
-
activeSession: await this.ownedActiveId("gemini"),
|
|
310
|
-
}, null, 2),
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
if (uri === "sessions://grok") {
|
|
314
|
-
const sessions = this.ownedSessions(await this.sessionManager.listSessions("grok"));
|
|
315
|
-
return {
|
|
316
|
-
uri,
|
|
317
|
-
mimeType: "application/json",
|
|
318
|
-
text: JSON.stringify({
|
|
319
|
-
cli: "grok",
|
|
320
|
-
total: sessions.length,
|
|
321
|
-
sessions,
|
|
322
|
-
activeSession: await this.ownedActiveId("grok"),
|
|
323
|
-
}, null, 2),
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
if (uri === "sessions://mistral") {
|
|
327
|
-
const sessions = this.ownedSessions(await this.sessionManager.listSessions("mistral"));
|
|
328
|
-
return {
|
|
329
|
-
uri,
|
|
330
|
-
mimeType: "application/json",
|
|
331
|
-
text: JSON.stringify({
|
|
332
|
-
cli: "mistral",
|
|
333
|
-
total: sessions.length,
|
|
334
|
-
sessions,
|
|
335
|
-
activeSession: await this.ownedActiveId("mistral"),
|
|
336
|
-
}, null, 2),
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
if (uri === "models://claude") {
|
|
223
|
+
const modelProvider = parseModelsResourceUri(uri);
|
|
224
|
+
if (modelProvider) {
|
|
340
225
|
const cliInfo = getAvailableCliInfo();
|
|
226
|
+
const discovered = buildProviderDiscoveredView(getProviderDefinition(modelProvider), cliInfo[modelProvider], this.capabilityPeek);
|
|
341
227
|
return {
|
|
342
228
|
uri,
|
|
343
229
|
mimeType: "application/json",
|
|
344
|
-
text: JSON.stringify(cliInfo
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
if (uri === "models://codex") {
|
|
348
|
-
const cliInfo = getAvailableCliInfo();
|
|
349
|
-
return {
|
|
350
|
-
uri,
|
|
351
|
-
mimeType: "application/json",
|
|
352
|
-
text: JSON.stringify(cliInfo.codex, null, 2),
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
if (uri === "models://gemini") {
|
|
356
|
-
const cliInfo = getAvailableCliInfo();
|
|
357
|
-
return {
|
|
358
|
-
uri,
|
|
359
|
-
mimeType: "application/json",
|
|
360
|
-
text: JSON.stringify(cliInfo.gemini, null, 2),
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
if (uri === "models://grok") {
|
|
364
|
-
const cliInfo = getAvailableCliInfo();
|
|
365
|
-
return {
|
|
366
|
-
uri,
|
|
367
|
-
mimeType: "application/json",
|
|
368
|
-
text: JSON.stringify(cliInfo.grok, null, 2),
|
|
369
|
-
};
|
|
370
|
-
}
|
|
371
|
-
if (uri === "models://mistral") {
|
|
372
|
-
const cliInfo = getAvailableCliInfo();
|
|
373
|
-
return {
|
|
374
|
-
uri,
|
|
375
|
-
mimeType: "application/json",
|
|
376
|
-
text: JSON.stringify(cliInfo.mistral, null, 2),
|
|
230
|
+
text: JSON.stringify({ ...cliInfo[modelProvider], discovered }, null, 2),
|
|
377
231
|
};
|
|
378
232
|
}
|
|
379
233
|
if (uri.startsWith("models://")) {
|
|
@@ -420,7 +274,10 @@ export class ResourceProvider {
|
|
|
420
274
|
return {
|
|
421
275
|
uri,
|
|
422
276
|
mimeType: "application/json",
|
|
423
|
-
text: JSON.stringify(getProviderToolCapabilities({
|
|
277
|
+
text: JSON.stringify(getProviderToolCapabilities({
|
|
278
|
+
providersConfig: this.providers ?? undefined,
|
|
279
|
+
acpConfig: this.acpConfig ?? undefined,
|
|
280
|
+
}), null, 2),
|
|
424
281
|
};
|
|
425
282
|
}
|
|
426
283
|
const providerToolsResource = parseProviderToolsUri(uri, this.providerCapabilityIds());
|
|
@@ -430,9 +287,24 @@ export class ResourceProvider {
|
|
|
430
287
|
mimeType: "application/json",
|
|
431
288
|
text: JSON.stringify(getOneProviderToolCapabilities(providerToolsResource.provider, {
|
|
432
289
|
providersConfig: this.providers ?? undefined,
|
|
290
|
+
acpConfig: this.acpConfig ?? undefined,
|
|
433
291
|
}), null, 2),
|
|
434
292
|
};
|
|
435
293
|
}
|
|
294
|
+
const acpProvider = parseProviderAcpResourceUri(uri);
|
|
295
|
+
if (acpProvider) {
|
|
296
|
+
const resolved = this.capabilityPeek(acpProvider);
|
|
297
|
+
const record = buildProviderAcpCapabilityRecord(acpProvider, {
|
|
298
|
+
discovered: resolved?.set.acpInitialize ?? null,
|
|
299
|
+
discoveredDegraded: resolved?.degraded ?? false,
|
|
300
|
+
acpConfig: this.acpConfig,
|
|
301
|
+
});
|
|
302
|
+
return {
|
|
303
|
+
uri,
|
|
304
|
+
mimeType: "application/json",
|
|
305
|
+
text: JSON.stringify(record, null, 2),
|
|
306
|
+
};
|
|
307
|
+
}
|
|
436
308
|
const subcommandResource = parseProviderSubcommandUri(uri);
|
|
437
309
|
if (subcommandResource) {
|
|
438
310
|
const contract = getCliSubcommandContract(subcommandResource.provider, subcommandResource.commandPath);
|
package/dist/session-manager.js
CHANGED
|
@@ -6,6 +6,7 @@ import { DEFAULT_SESSION_TTL_SECONDS } from "./config.js";
|
|
|
6
6
|
import { noopLogger } from "./logger.js";
|
|
7
7
|
import { getRequestContext, resolveOwnerPrincipal } from "./request-context.js";
|
|
8
8
|
import { API_PROVIDER_TYPES, CLI_TYPES, } from "./provider-types.js";
|
|
9
|
+
import { getAllProviderDefinitions } from "./provider-definitions.js";
|
|
9
10
|
export { API_PROVIDER_TYPES, CLI_TYPES };
|
|
10
11
|
export const PROVIDER_TYPES = [...CLI_TYPES, ...API_PROVIDER_TYPES];
|
|
11
12
|
export function isCliType(provider) {
|
|
@@ -15,13 +16,7 @@ export function providerKind(provider) {
|
|
|
15
16
|
return isCliType(provider) ? "cli" : "api";
|
|
16
17
|
}
|
|
17
18
|
const KNOWN_SESSION_DESCRIPTIONS = {
|
|
18
|
-
|
|
19
|
-
codex: "Codex Session",
|
|
20
|
-
gemini: "Gemini Session",
|
|
21
|
-
grok: "Grok Session",
|
|
22
|
-
mistral: "Mistral Session",
|
|
23
|
-
devin: "Devin Session",
|
|
24
|
-
cursor: "Cursor Session",
|
|
19
|
+
...Object.fromEntries(getAllProviderDefinitions().map(def => [def.id, def.sessionLabel])),
|
|
25
20
|
"grok-api": "Grok API Session",
|
|
26
21
|
};
|
|
27
22
|
export function defaultSessionDescription(provider) {
|
|
@@ -33,11 +28,23 @@ export function remoteSafeSession(session) {
|
|
|
33
28
|
if (!metadata)
|
|
34
29
|
return session;
|
|
35
30
|
const next = { ...metadata };
|
|
31
|
+
const root = typeof next.workspaceRoot === "string" ? next.workspaceRoot : undefined;
|
|
32
|
+
const reducePath = (absolute) => {
|
|
33
|
+
const rel = root ? pathRelative(root, absolute) : "";
|
|
34
|
+
return rel && !rel.startsWith("..") && !pathIsAbsolute(rel) ? rel : pathBasename(absolute);
|
|
35
|
+
};
|
|
36
36
|
if (typeof next.worktreePath === "string") {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
next.worktreePath = reducePath(next.worktreePath);
|
|
38
|
+
}
|
|
39
|
+
if (next.acp && typeof next.acp === "object" && !Array.isArray(next.acp)) {
|
|
40
|
+
const acp = { ...next.acp };
|
|
41
|
+
if (typeof acp.cwd === "string")
|
|
42
|
+
acp.cwd = reducePath(acp.cwd);
|
|
43
|
+
if (typeof acp.worktreePath === "string")
|
|
44
|
+
acp.worktreePath = reducePath(acp.worktreePath);
|
|
45
|
+
if ("sessionId" in acp)
|
|
46
|
+
delete acp.sessionId;
|
|
47
|
+
next.acp = acp;
|
|
41
48
|
}
|
|
42
49
|
if (typeof next.workspaceRoot === "string")
|
|
43
50
|
delete next.workspaceRoot;
|
package/dist/sqlite-driver.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export interface GatewayStatement {
|
|
|
9
9
|
export interface GatewayDatabase {
|
|
10
10
|
exec(sql: string): void;
|
|
11
11
|
prepare(sql: string): GatewayStatement;
|
|
12
|
-
withTransaction<A extends unknown[]>(fn: (...args: A) =>
|
|
12
|
+
withTransaction<A extends unknown[], R = void>(fn: (...args: A) => R): (...args: A) => R;
|
|
13
13
|
close(): void;
|
|
14
14
|
}
|
|
15
15
|
export declare function openDatabase(dbPath: string): GatewayDatabase;
|
package/dist/sqlite-driver.js
CHANGED
|
@@ -51,6 +51,7 @@ export function parseStreamJson(stdout) {
|
|
|
51
51
|
durationApiMs: numberOrNull(resultEvent.duration_api_ms),
|
|
52
52
|
isError: resultEvent.is_error === true,
|
|
53
53
|
numTurns: numberOrNull(resultEvent.num_turns),
|
|
54
|
+
stopReason: stringOrNull(resultEvent.stop_reason) ?? stringOrNull(assistantEvent?.message?.stop_reason),
|
|
54
55
|
};
|
|
55
56
|
}
|
|
56
57
|
if (assistantEvent) {
|
|
@@ -74,6 +75,7 @@ export function parseStreamJson(stdout) {
|
|
|
74
75
|
durationApiMs: null,
|
|
75
76
|
isError: false,
|
|
76
77
|
numTurns: null,
|
|
78
|
+
stopReason: stringOrNull(message?.stop_reason),
|
|
77
79
|
};
|
|
78
80
|
}
|
|
79
81
|
return {
|
|
@@ -85,5 +87,6 @@ export function parseStreamJson(stdout) {
|
|
|
85
87
|
durationApiMs: null,
|
|
86
88
|
isError: false,
|
|
87
89
|
numTurns: null,
|
|
90
|
+
stopReason: null,
|
|
88
91
|
};
|
|
89
92
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type CliType } from "./provider-definitions.js";
|
|
2
2
|
export type CliFlagArity = "none" | "one" | "optional" | "variadic";
|
|
3
3
|
export interface CliFlagContract {
|
|
4
4
|
arity: CliFlagArity;
|
|
@@ -199,3 +199,19 @@ export declare function buildUpstreamContractReport(options?: {
|
|
|
199
199
|
cli?: CliType;
|
|
200
200
|
probeInstalled?: boolean;
|
|
201
201
|
}): Record<string, unknown>;
|
|
202
|
+
export interface DiscoveryContractDrift {
|
|
203
|
+
cli: CliType;
|
|
204
|
+
version: string;
|
|
205
|
+
contractTargetVersion: string;
|
|
206
|
+
versionMatchesContract: boolean;
|
|
207
|
+
missingContractFlags: string[];
|
|
208
|
+
newDiscoveredFlags: string[];
|
|
209
|
+
discoveredUnmappedCount: number;
|
|
210
|
+
status: "clean" | "drift" | "degraded";
|
|
211
|
+
}
|
|
212
|
+
export declare function computeDiscoveryContractDrift(cli: CliType, discovered: {
|
|
213
|
+
version: string;
|
|
214
|
+
discoveredFlagNames: readonly string[];
|
|
215
|
+
discoveredUnmappedCount: number;
|
|
216
|
+
status: "ok" | "degraded" | "error";
|
|
217
|
+
}): DiscoveryContractDrift;
|