@the-open-engine/zeroshot 6.4.0 → 6.5.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.
Files changed (144) hide show
  1. package/cli/commands/providers.js +11 -5
  2. package/cli/index.js +79 -16
  3. package/cli/lib/first-run.js +14 -3
  4. package/docker/zeroshot-cluster/Dockerfile +11 -1
  5. package/lib/agent-cli-provider/acp-stdio-runner.d.ts +4 -0
  6. package/lib/agent-cli-provider/acp-stdio-runner.d.ts.map +1 -0
  7. package/lib/agent-cli-provider/acp-stdio-runner.js +259 -0
  8. package/lib/agent-cli-provider/acp-stdio-runner.js.map +1 -0
  9. package/lib/agent-cli-provider/adapters/acp.d.ts +23 -0
  10. package/lib/agent-cli-provider/adapters/acp.d.ts.map +1 -0
  11. package/lib/agent-cli-provider/adapters/acp.js +373 -0
  12. package/lib/agent-cli-provider/adapters/acp.js.map +1 -0
  13. package/lib/agent-cli-provider/adapters/claude.d.ts.map +1 -1
  14. package/lib/agent-cli-provider/adapters/claude.js +2 -29
  15. package/lib/agent-cli-provider/adapters/claude.js.map +1 -1
  16. package/lib/agent-cli-provider/adapters/copilot-parser.d.ts +3 -0
  17. package/lib/agent-cli-provider/adapters/copilot-parser.d.ts.map +1 -0
  18. package/lib/agent-cli-provider/adapters/copilot-parser.js +154 -0
  19. package/lib/agent-cli-provider/adapters/copilot-parser.js.map +1 -0
  20. package/lib/agent-cli-provider/adapters/copilot.d.ts +3 -0
  21. package/lib/agent-cli-provider/adapters/copilot.d.ts.map +1 -0
  22. package/lib/agent-cli-provider/adapters/copilot.js +176 -0
  23. package/lib/agent-cli-provider/adapters/copilot.js.map +1 -0
  24. package/lib/agent-cli-provider/adapters/gateway.d.ts +6 -0
  25. package/lib/agent-cli-provider/adapters/gateway.d.ts.map +1 -0
  26. package/lib/agent-cli-provider/adapters/gateway.js +161 -0
  27. package/lib/agent-cli-provider/adapters/gateway.js.map +1 -0
  28. package/lib/agent-cli-provider/adapters/gemini.d.ts.map +1 -1
  29. package/lib/agent-cli-provider/adapters/gemini.js +9 -2
  30. package/lib/agent-cli-provider/adapters/gemini.js.map +1 -1
  31. package/lib/agent-cli-provider/adapters/index.d.ts.map +1 -1
  32. package/lib/agent-cli-provider/adapters/index.js +6 -34
  33. package/lib/agent-cli-provider/adapters/index.js.map +1 -1
  34. package/lib/agent-cli-provider/adapters/opencode.d.ts.map +1 -1
  35. package/lib/agent-cli-provider/adapters/opencode.js +5 -1
  36. package/lib/agent-cli-provider/adapters/opencode.js.map +1 -1
  37. package/lib/agent-cli-provider/adapters/pi.d.ts +3 -0
  38. package/lib/agent-cli-provider/adapters/pi.d.ts.map +1 -0
  39. package/lib/agent-cli-provider/adapters/pi.js +331 -0
  40. package/lib/agent-cli-provider/adapters/pi.js.map +1 -0
  41. package/lib/agent-cli-provider/claude-command.d.ts +6 -0
  42. package/lib/agent-cli-provider/claude-command.d.ts.map +1 -0
  43. package/lib/agent-cli-provider/claude-command.js +43 -0
  44. package/lib/agent-cli-provider/claude-command.js.map +1 -0
  45. package/lib/agent-cli-provider/contract-actions.d.ts.map +1 -1
  46. package/lib/agent-cli-provider/contract-actions.js +13 -17
  47. package/lib/agent-cli-provider/contract-actions.js.map +1 -1
  48. package/lib/agent-cli-provider/contract-invoke.d.ts.map +1 -1
  49. package/lib/agent-cli-provider/contract-invoke.js +10 -3
  50. package/lib/agent-cli-provider/contract-invoke.js.map +1 -1
  51. package/lib/agent-cli-provider/contract-options.d.ts.map +1 -1
  52. package/lib/agent-cli-provider/contract-options.js +57 -2
  53. package/lib/agent-cli-provider/contract-options.js.map +1 -1
  54. package/lib/agent-cli-provider/contract-support.d.ts +1 -0
  55. package/lib/agent-cli-provider/contract-support.d.ts.map +1 -1
  56. package/lib/agent-cli-provider/contract-support.js +25 -3
  57. package/lib/agent-cli-provider/contract-support.js.map +1 -1
  58. package/lib/agent-cli-provider/errors.d.ts +1 -0
  59. package/lib/agent-cli-provider/errors.d.ts.map +1 -1
  60. package/lib/agent-cli-provider/errors.js +14 -5
  61. package/lib/agent-cli-provider/errors.js.map +1 -1
  62. package/lib/agent-cli-provider/gateway-client.d.ts +32 -0
  63. package/lib/agent-cli-provider/gateway-client.d.ts.map +1 -0
  64. package/lib/agent-cli-provider/gateway-client.js +135 -0
  65. package/lib/agent-cli-provider/gateway-client.js.map +1 -0
  66. package/lib/agent-cli-provider/gateway-runner.d.ts +9 -0
  67. package/lib/agent-cli-provider/gateway-runner.d.ts.map +1 -0
  68. package/lib/agent-cli-provider/gateway-runner.js +294 -0
  69. package/lib/agent-cli-provider/gateway-runner.js.map +1 -0
  70. package/lib/agent-cli-provider/gateway-tools.d.ts +14 -0
  71. package/lib/agent-cli-provider/gateway-tools.d.ts.map +1 -0
  72. package/lib/agent-cli-provider/gateway-tools.js +495 -0
  73. package/lib/agent-cli-provider/gateway-tools.js.map +1 -0
  74. package/lib/agent-cli-provider/index.d.ts +3 -2
  75. package/lib/agent-cli-provider/index.d.ts.map +1 -1
  76. package/lib/agent-cli-provider/index.js +14 -1
  77. package/lib/agent-cli-provider/index.js.map +1 -1
  78. package/lib/agent-cli-provider/invoke-evidence.d.ts +2 -2
  79. package/lib/agent-cli-provider/invoke-evidence.d.ts.map +1 -1
  80. package/lib/agent-cli-provider/invoke-evidence.js +17 -3
  81. package/lib/agent-cli-provider/invoke-evidence.js.map +1 -1
  82. package/lib/agent-cli-provider/provider-registry.d.ts +437 -0
  83. package/lib/agent-cli-provider/provider-registry.d.ts.map +1 -0
  84. package/lib/agent-cli-provider/provider-registry.js +411 -0
  85. package/lib/agent-cli-provider/provider-registry.js.map +1 -0
  86. package/lib/agent-cli-provider/single-agent-runtime.d.ts +7 -0
  87. package/lib/agent-cli-provider/single-agent-runtime.d.ts.map +1 -1
  88. package/lib/agent-cli-provider/single-agent-runtime.js +139 -19
  89. package/lib/agent-cli-provider/single-agent-runtime.js.map +1 -1
  90. package/lib/agent-cli-provider/types.d.ts +106 -4
  91. package/lib/agent-cli-provider/types.d.ts.map +1 -1
  92. package/lib/agent-cli-provider/types.js.map +1 -1
  93. package/lib/docker-config.js +24 -13
  94. package/lib/provider-defaults.js +15 -4
  95. package/lib/provider-detection.js +2 -0
  96. package/lib/provider-names.js +32 -12
  97. package/lib/repo-settings.js +15 -1
  98. package/lib/settings/claude-auth.js +3 -6
  99. package/lib/settings.js +17 -2
  100. package/lib/setup-apply.js +300 -0
  101. package/lib/setup-journal.js +109 -0
  102. package/lib/setup-plan.js +406 -0
  103. package/lib/setup-undo.js +88 -0
  104. package/lib/start-cluster.js +12 -1
  105. package/lib/stream-json-parser.js +7 -5
  106. package/package.json +29 -1
  107. package/scripts/live-provider-smoke.js +221 -0
  108. package/src/agent/agent-lifecycle.js +5 -4
  109. package/src/agent/agent-quality-gate-schema.js +2 -2
  110. package/src/agent/agent-task-executor.js +41 -2
  111. package/src/agent-cli-provider/acp-stdio-runner.ts +314 -0
  112. package/src/agent-cli-provider/adapters/acp.ts +493 -0
  113. package/src/agent-cli-provider/adapters/claude.ts +2 -32
  114. package/src/agent-cli-provider/adapters/copilot-parser.ts +166 -0
  115. package/src/agent-cli-provider/adapters/copilot.ts +231 -0
  116. package/src/agent-cli-provider/adapters/gateway.ts +186 -0
  117. package/src/agent-cli-provider/adapters/gemini.ts +9 -2
  118. package/src/agent-cli-provider/adapters/index.ts +5 -36
  119. package/src/agent-cli-provider/adapters/opencode.ts +4 -1
  120. package/src/agent-cli-provider/adapters/pi.ts +410 -0
  121. package/src/agent-cli-provider/claude-command.ts +47 -0
  122. package/src/agent-cli-provider/contract-actions.ts +14 -17
  123. package/src/agent-cli-provider/contract-invoke.ts +12 -3
  124. package/src/agent-cli-provider/contract-options.ts +72 -3
  125. package/src/agent-cli-provider/contract-support.ts +30 -3
  126. package/src/agent-cli-provider/errors.ts +14 -4
  127. package/src/agent-cli-provider/gateway-client.ts +170 -0
  128. package/src/agent-cli-provider/gateway-runner.ts +353 -0
  129. package/src/agent-cli-provider/gateway-tools.ts +616 -0
  130. package/src/agent-cli-provider/index.ts +28 -0
  131. package/src/agent-cli-provider/invoke-evidence.ts +24 -3
  132. package/src/agent-cli-provider/provider-registry.ts +515 -0
  133. package/src/agent-cli-provider/single-agent-runtime.ts +192 -18
  134. package/src/agent-cli-provider/types.ts +145 -4
  135. package/src/config-validator.js +33 -15
  136. package/src/isolation-manager.js +124 -19
  137. package/src/orchestrator.js +23 -10
  138. package/src/preflight.js +83 -30
  139. package/src/providers/capabilities.js +15 -42
  140. package/src/providers/index.js +52 -72
  141. package/src/worktree-claude-config.js +17 -0
  142. package/task-lib/commands/run.js +1 -0
  143. package/task-lib/provider-helper-runtime.js +11 -0
  144. package/task-lib/runner.js +7 -0
@@ -1,15 +1,23 @@
1
1
  import { getProviderAdapter } from './adapters';
2
+ import { normalizeGatewayBuildOptions, resolveGatewayConfiguration } from './gateway-tools';
2
3
  import { isRecord } from './json';
4
+ import {
5
+ getProviderRegistryEntry,
6
+ resolveProviderCommand,
7
+ supportsProviderCapability,
8
+ } from './provider-registry';
3
9
  import type {
4
10
  BuildProviderCommandOptions,
5
11
  CliFeatureOverrides,
6
12
  CommandSpec,
13
+ GatewayBuildOptions,
7
14
  LevelOverrides,
8
15
  ModelLevel,
9
16
  ModelSpec,
10
17
  ProviderAdapter,
11
18
  ProviderCliFeatures,
12
19
  ProviderId,
20
+ ResolvedGatewayBuildOptions,
13
21
  ReasoningEffort,
14
22
  } from './types';
15
23
 
@@ -23,6 +31,7 @@ interface CommandParts {
23
31
  interface RuntimeProviderSettings {
24
32
  readonly defaultLevel?: ModelLevel;
25
33
  readonly levelOverrides: LevelOverrides;
34
+ readonly gateway?: GatewayBuildOptions;
26
35
  }
27
36
 
28
37
  export interface SingleAgentProviderCommandInput {
@@ -38,6 +47,13 @@ export interface PreparedSingleAgentProviderCommand {
38
47
  readonly cliFeatures: CliFeatureOverrides;
39
48
  }
40
49
 
50
+ export interface RuntimeProviderProbe {
51
+ readonly available: boolean;
52
+ readonly helpText: string;
53
+ readonly versionText: string;
54
+ readonly capabilities: ProviderCliFeatures;
55
+ }
56
+
41
57
  type MutableModelSpec = {
42
58
  level?: ModelLevel;
43
59
  model?: string | null;
@@ -46,24 +62,29 @@ type MutableModelSpec = {
46
62
 
47
63
  const MODEL_LEVELS: readonly ModelLevel[] = ['level1', 'level2', 'level3'];
48
64
  const REASONING_EFFORTS: readonly ReasoningEffort[] = ['low', 'medium', 'high', 'xhigh'];
49
-
50
65
  const settingsModule: unknown = require('../../lib/settings');
51
66
  const providerDetectionModule: unknown = require('../../lib/provider-detection');
52
67
  const claudeAuthModule: unknown = require('../../lib/settings/claude-auth');
53
68
 
54
69
  const loadSettingsFn = moduleFunction(settingsModule, 'loadSettings');
55
70
  const getClaudeCommandFn = moduleFunction(settingsModule, 'getClaudeCommand');
71
+ const commandExistsFn = moduleFunction(providerDetectionModule, 'commandExists');
56
72
  const getHelpOutputFn = moduleFunction(providerDetectionModule, 'getHelpOutput');
73
+ const getVersionOutputFn = moduleFunction(providerDetectionModule, 'getVersionOutput');
57
74
  const resolveClaudeAuthFn = moduleFunction(claudeAuthModule, 'resolveClaudeAuth');
58
75
 
59
76
  export function prepareSingleAgentProviderCommand(
60
77
  input: SingleAgentProviderCommandInput
61
78
  ): PreparedSingleAgentProviderCommand {
79
+ const baseOptions = input.options ?? {};
62
80
  const settings = loadRuntimeSettings();
63
81
  const adapter = adapterForRuntimeInput(input.provider, settings);
64
- const providerSettings = runtimeProviderSettings(settings, adapter.id);
65
- const baseOptions = input.options ?? {};
66
- const cliFeatures = baseOptions.cliFeatures ?? detectRuntimeProviderCliFeatures(adapter.id);
82
+ const providerSettings = runtimeProviderSettings(
83
+ settings,
84
+ adapter.id,
85
+ baseOptions.cwd ?? process.cwd()
86
+ );
87
+ const cliFeatures = resolveRuntimeCliFeatures(adapter.id, baseOptions.cliFeatures);
67
88
  const authEnv = baseOptions.authEnv ?? resolveRuntimeAuthEnv(adapter.id, settings);
68
89
  const options = buildRuntimeOptions(baseOptions, adapter, providerSettings, cliFeatures, authEnv);
69
90
  return {
@@ -75,10 +96,81 @@ export function prepareSingleAgentProviderCommand(
75
96
  }
76
97
 
77
98
  export function detectRuntimeProviderCliFeatures(provider: string): ProviderCliFeatures {
99
+ return probeRuntimeProviderCli(provider).capabilities;
100
+ }
101
+
102
+ function resolveRuntimeCliFeatures(
103
+ provider: ProviderId,
104
+ overrides: CliFeatureOverrides | undefined
105
+ ): CliFeatureOverrides {
106
+ if (provider === 'gateway') {
107
+ return {
108
+ ...detectRuntimeProviderCliFeatures(provider),
109
+ ...overrides,
110
+ supportsBundledRunner: true,
111
+ };
112
+ }
113
+ if (getProviderRegistryEntry(provider).invoke.lane !== 'acp-stdio') {
114
+ return overrides ?? detectRuntimeProviderCliFeatures(provider);
115
+ }
116
+
117
+ const detected = detectRuntimeProviderCliFeatures(provider);
118
+ if (overrides === undefined) return detected;
119
+ return mergeAcpFailClosedCliFeatures(detected, overrides);
120
+ }
121
+
122
+ function mergeAcpFailClosedCliFeatures(
123
+ detected: ProviderCliFeatures,
124
+ overrides: CliFeatureOverrides
125
+ ): CliFeatureOverrides {
126
+ if (!('supportsAcpStdio' in detected)) return overrides;
127
+ return {
128
+ ...detected,
129
+ ...overrides,
130
+ supportsAcpStdio: detected.supportsAcpStdio && overrides.supportsAcpStdio !== false,
131
+ supportsPromptImages:
132
+ detected.supportsPromptImages && overrides.supportsPromptImages !== false,
133
+ supportsLoadSession: detected.supportsLoadSession && overrides.supportsLoadSession !== false,
134
+ supportsSessionCancel:
135
+ detected.supportsSessionCancel && overrides.supportsSessionCancel !== false,
136
+ supportsSessionSetModel:
137
+ detected.supportsSessionSetModel && overrides.supportsSessionSetModel !== false,
138
+ supportsSessionSetMode:
139
+ detected.supportsSessionSetMode && overrides.supportsSessionSetMode !== false,
140
+ supportsRemoteTransport: false,
141
+ supportsCustomTransport: false,
142
+ supportsPermissionRequests: false,
143
+ supportsFsTools: false,
144
+ supportsTerminalTools: false,
145
+ };
146
+ }
147
+
148
+ export function probeRuntimeProviderCli(provider: string): RuntimeProviderProbe {
78
149
  const adapter = getProviderAdapter(provider);
150
+ if (adapter.id === 'gateway') {
151
+ return probeGatewayProvider(adapter);
152
+ }
79
153
  const helpCommand = runtimeHelpCommand(adapter.id);
80
- const helpText = stringResult(getHelpOutputFn(helpCommand.command, helpCommand.args));
81
- return adapter.detectCliFeatures(helpText);
154
+ const commandAvailable = booleanResult(commandExistsFn(helpCommand.command));
155
+ if (!commandAvailable) {
156
+ return {
157
+ available: false,
158
+ helpText: '',
159
+ versionText: '',
160
+ capabilities: adapter.detectCliFeatures(''),
161
+ };
162
+ }
163
+
164
+ const helpText = stringResult(getHelpOutputFn(helpCommand.command, helpCommand.args)).trim();
165
+ const versionText = stringResult(getVersionOutputFn(helpCommand.command, helpCommand.args)).trim();
166
+ const availabilityProbe = getProviderRegistryEntry(adapter.id).availabilityProbe ?? 'command';
167
+
168
+ return {
169
+ available: availabilityProbe === 'help-or-version' ? Boolean(helpText || versionText) : true,
170
+ helpText,
171
+ versionText,
172
+ capabilities: adapter.detectCliFeatures(helpText),
173
+ };
82
174
  }
83
175
 
84
176
  function buildRuntimeOptions(
@@ -88,15 +180,63 @@ function buildRuntimeOptions(
88
180
  cliFeatures: CliFeatureOverrides,
89
181
  authEnv: Readonly<Record<string, string>>
90
182
  ): BuildProviderCommandOptions {
183
+ const modelSpec = resolveRuntimeModelSpec(adapter, baseOptions.modelSpec, providerSettings);
184
+ const gateway = resolveRuntimeGatewayOptions(
185
+ adapter.id,
186
+ baseOptions,
187
+ providerSettings,
188
+ modelSpec
189
+ );
91
190
  const resolved = {
92
191
  ...baseOptions,
93
- modelSpec: resolveRuntimeModelSpec(adapter, baseOptions.modelSpec, providerSettings),
192
+ modelSpec,
193
+ ...(gateway === undefined ? {} : { gateway }),
94
194
  cliFeatures,
95
195
  };
196
+ if (baseOptions.jsonSchema && !supportsProviderCapability(adapter.id, 'jsonSchema')) {
197
+ if (!shouldIncludeAuthEnv(baseOptions, authEnv)) {
198
+ return { ...resolved, strictSchema: false };
199
+ }
200
+ return { ...resolved, authEnv, strictSchema: false };
201
+ }
96
202
  if (!shouldIncludeAuthEnv(baseOptions, authEnv)) return resolved;
97
203
  return { ...resolved, authEnv };
98
204
  }
99
205
 
206
+ function resolveRuntimeGatewayOptions(
207
+ provider: ProviderId,
208
+ baseOptions: BuildProviderCommandOptions,
209
+ providerSettings: RuntimeProviderSettings,
210
+ modelSpec: ModelSpec
211
+ ): ResolvedGatewayBuildOptions | undefined {
212
+ if (provider !== 'gateway') return undefined;
213
+ const cwd = baseOptions.cwd ?? process.cwd();
214
+ const settingsGateway = providerSettings.gateway ?? {};
215
+ const requestGateway = baseOptions.gateway ?? {};
216
+ const mergedHeaders =
217
+ requestGateway.headers === undefined
218
+ ? settingsGateway.headers
219
+ : { ...(settingsGateway.headers ?? {}), ...requestGateway.headers };
220
+ const mergedGateway: GatewayBuildOptions = {
221
+ ...(requestGateway.baseUrl ?? settingsGateway.baseUrl
222
+ ? { baseUrl: requestGateway.baseUrl ?? settingsGateway.baseUrl }
223
+ : {}),
224
+ ...(requestGateway.apiKey ?? settingsGateway.apiKey
225
+ ? { apiKey: requestGateway.apiKey ?? settingsGateway.apiKey }
226
+ : {}),
227
+ ...(mergedHeaders === undefined ? {} : { headers: mergedHeaders }),
228
+ model: requestGateway.model ?? modelSpec.model ?? settingsGateway.model ?? null,
229
+ ...(requestGateway.toolPolicy ?? settingsGateway.toolPolicy
230
+ ? { toolPolicy: requestGateway.toolPolicy ?? settingsGateway.toolPolicy }
231
+ : {}),
232
+ };
233
+ return resolveGatewayConfiguration(
234
+ mergedGateway,
235
+ 'options.gateway',
236
+ cwd
237
+ );
238
+ }
239
+
100
240
  function shouldIncludeAuthEnv(
101
241
  baseOptions: BuildProviderCommandOptions,
102
242
  authEnv: Readonly<Record<string, string>>
@@ -152,7 +292,8 @@ function adapterForRuntimeInput(
152
292
 
153
293
  function runtimeProviderSettings(
154
294
  settings: Record<string, unknown>,
155
- provider: ProviderId
295
+ provider: ProviderId,
296
+ cwd: string
156
297
  ): RuntimeProviderSettings {
157
298
  const allSettings = optionalRecord(settings.providerSettings, 'settings.providerSettings');
158
299
  const providerValue = allSettings?.[provider];
@@ -166,19 +307,47 @@ function runtimeProviderSettings(
166
307
  providerSettings.levelOverrides,
167
308
  `settings.providerSettings.${provider}.levelOverrides`
168
309
  );
169
- if (defaultLevel === undefined) return { levelOverrides };
170
- return { defaultLevel, levelOverrides };
310
+ const gateway =
311
+ provider === 'gateway'
312
+ ? normalizeGatewayBuildOptions(
313
+ providerSettings,
314
+ 'settings.providerSettings.gateway',
315
+ cwd
316
+ )
317
+ : undefined;
318
+ if (defaultLevel === undefined) {
319
+ return gateway === undefined ? { levelOverrides } : { levelOverrides, gateway };
320
+ }
321
+ return gateway === undefined ? { defaultLevel, levelOverrides } : { defaultLevel, levelOverrides, gateway };
171
322
  }
172
323
 
173
324
  function runtimeHelpCommand(provider: ProviderId): CommandParts {
174
- if (provider === 'claude') return getClaudeRuntimeCommand();
175
- if (provider === 'codex') return { command: 'codex', args: ['exec'] };
176
- if (provider === 'opencode') return { command: 'opencode', args: ['run'] };
177
- return { command: 'gemini', args: [] };
178
- }
179
-
180
- function getClaudeRuntimeCommand(): CommandParts {
181
- return commandPartsFromUnknown(getClaudeCommandFn(), 'getClaudeCommand');
325
+ if (provider === 'claude') {
326
+ return commandPartsFromUnknown(getClaudeCommandFn(), 'getClaudeCommand');
327
+ }
328
+ return resolveProviderCommand(provider);
329
+ }
330
+
331
+ function probeGatewayProvider(adapter: ProviderAdapter): RuntimeProviderProbe {
332
+ const capabilities = adapter.detectCliFeatures('');
333
+ try {
334
+ const settings = loadRuntimeSettings();
335
+ const providerSettings = runtimeProviderSettings(settings, 'gateway', process.cwd());
336
+ resolveGatewayConfiguration(providerSettings.gateway, 'settings.providerSettings.gateway', process.cwd());
337
+ return {
338
+ available: true,
339
+ helpText: 'Bundled gateway runner',
340
+ versionText: process.version,
341
+ capabilities,
342
+ };
343
+ } catch {
344
+ return {
345
+ available: false,
346
+ helpText: 'Bundled gateway runner',
347
+ versionText: process.version,
348
+ capabilities,
349
+ };
350
+ }
182
351
  }
183
352
 
184
353
  function loadRuntimeSettings(): Record<string, unknown> {
@@ -309,3 +478,8 @@ function stringResult(value: unknown): string {
309
478
  if (typeof value === 'string') return value;
310
479
  throw new Error('Provider help output must be a string.');
311
480
  }
481
+
482
+ function booleanResult(value: unknown): boolean {
483
+ if (typeof value === 'boolean') return value;
484
+ throw new Error('Provider availability probe must return a boolean.');
485
+ }
@@ -1,9 +1,32 @@
1
- export type ProviderId = 'claude' | 'codex' | 'gemini' | 'opencode';
2
- export type ProviderAlias = 'anthropic' | 'openai' | 'google';
1
+ import type {
2
+ providerAliases,
3
+ providerIds,
4
+ ProviderCapabilities,
5
+ ProviderCapabilityState,
6
+ ProviderCommandSpec,
7
+ ProviderDockerMetadata,
8
+ ProviderDockerMountPreset,
9
+ ProviderDocsMetadata,
10
+ ProviderInvokeSpec,
11
+ ProviderRegistryEntry,
12
+ } from './provider-registry';
13
+
14
+ export type ProviderId = (typeof providerIds)[number];
15
+ export type ProviderAlias = (typeof providerAliases)[number];
3
16
  export type KnownProviderName = ProviderId | ProviderAlias;
4
17
  export type ModelLevel = 'level1' | 'level2' | 'level3';
5
18
  export type ReasoningEffort = 'low' | 'medium' | 'high' | 'xhigh';
6
19
  export type OutputFormat = 'text' | 'json' | 'stream-json';
20
+ export type {
21
+ ProviderCapabilities,
22
+ ProviderCapabilityState,
23
+ ProviderCommandSpec,
24
+ ProviderDockerMetadata,
25
+ ProviderDockerMountPreset,
26
+ ProviderDocsMetadata,
27
+ ProviderInvokeSpec,
28
+ ProviderRegistryEntry,
29
+ };
7
30
 
8
31
  export interface AgentCliProviderHelperMetadata {
9
32
  readonly packageName: '@the-open-engine/zeroshot';
@@ -36,6 +59,28 @@ export interface ResolvedModelSpec {
36
59
 
37
60
  export type LevelOverrides = Readonly<Partial<Record<ModelLevel, ModelSpec>>>;
38
61
 
62
+ export interface GatewayToolPolicy {
63
+ readonly roots: readonly string[];
64
+ readonly commands: readonly string[];
65
+ readonly commandTimeoutMs?: number;
66
+ }
67
+
68
+ export interface GatewayBuildOptions {
69
+ readonly baseUrl?: string;
70
+ readonly apiKey?: string;
71
+ readonly headers?: Readonly<Record<string, string>>;
72
+ readonly model?: string | null;
73
+ readonly toolPolicy?: GatewayToolPolicy;
74
+ }
75
+
76
+ export interface ResolvedGatewayBuildOptions {
77
+ readonly baseUrl: string;
78
+ readonly apiKey: string;
79
+ readonly headers: Readonly<Record<string, string>>;
80
+ readonly model: string;
81
+ readonly toolPolicy: GatewayToolPolicy;
82
+ }
83
+
39
84
  export interface BaseCliFeatures {
40
85
  readonly provider?: ProviderId;
41
86
  readonly unknown?: boolean;
@@ -76,15 +121,62 @@ export interface OpencodeCliFeatures extends BaseCliFeatures {
76
121
  readonly supportsJson: boolean;
77
122
  readonly supportsModel: boolean;
78
123
  readonly supportsVariant: boolean;
124
+ readonly supportsDir: boolean;
79
125
  readonly supportsCwd: boolean;
80
126
  readonly supportsAutoApprove: false;
81
127
  }
82
128
 
129
+ export interface PiCliFeatures extends BaseCliFeatures {
130
+ readonly provider: 'pi';
131
+ readonly supportsJsonMode: boolean;
132
+ readonly supportsModel: boolean;
133
+ readonly supportsNoSession: boolean;
134
+ readonly supportsNoExtensions: boolean;
135
+ readonly supportsNoSkills: boolean;
136
+ readonly supportsNoPromptTemplates: boolean;
137
+ readonly supportsNoContextFiles: boolean;
138
+ readonly supportsNoApprove: boolean;
139
+ }
140
+
141
+ export interface CopilotCliFeatures extends BaseCliFeatures {
142
+ readonly provider: 'copilot';
143
+ readonly supportsJsonOutput: boolean;
144
+ readonly supportsModel: boolean;
145
+ readonly supportsAllowAll: boolean;
146
+ readonly supportsNoAskUser: boolean;
147
+ readonly supportsAddDir: boolean;
148
+ readonly supportsMcpConfig: boolean;
149
+ }
150
+
151
+ export interface GatewayCliFeatures extends BaseCliFeatures {
152
+ readonly provider: 'gateway';
153
+ readonly supportsBundledRunner: true;
154
+ }
155
+
156
+ export interface AcpCliFeatures extends BaseCliFeatures {
157
+ readonly provider: ProviderId;
158
+ readonly supportsAcpStdio: boolean;
159
+ readonly supportsPromptImages: boolean;
160
+ readonly supportsLoadSession: boolean;
161
+ readonly supportsSessionCancel: boolean;
162
+ readonly supportsSessionSetModel: boolean;
163
+ readonly supportsSessionSetMode: boolean;
164
+ readonly supportsRemoteTransport: false;
165
+ readonly supportsCustomTransport: false;
166
+ readonly supportsPermissionRequests: false;
167
+ readonly supportsFsTools: false;
168
+ readonly supportsTerminalTools: false;
169
+ }
170
+
83
171
  export type ProviderCliFeatures =
84
172
  | ClaudeCliFeatures
85
173
  | CodexCliFeatures
86
174
  | GeminiCliFeatures
87
- | OpencodeCliFeatures;
175
+ | OpencodeCliFeatures
176
+ | PiCliFeatures
177
+ | CopilotCliFeatures
178
+ | GatewayCliFeatures
179
+ | AcpCliFeatures;
88
180
 
89
181
  export interface CliFeatureOverrides {
90
182
  readonly supportsOutputFormat?: boolean;
@@ -96,10 +188,35 @@ export interface CliFeatureOverrides {
96
188
  readonly supportsModel?: boolean;
97
189
  readonly supportsJson?: boolean;
98
190
  readonly supportsOutputSchema?: boolean;
191
+ readonly supportsDir?: boolean;
99
192
  readonly supportsCwd?: boolean;
100
193
  readonly supportsConfigOverride?: boolean;
101
194
  readonly supportsSkipGitRepoCheck?: boolean;
102
195
  readonly supportsVariant?: boolean;
196
+ readonly supportsJsonMode?: boolean;
197
+ readonly supportsNoSession?: boolean;
198
+ readonly supportsNoExtensions?: boolean;
199
+ readonly supportsNoSkills?: boolean;
200
+ readonly supportsNoPromptTemplates?: boolean;
201
+ readonly supportsNoContextFiles?: boolean;
202
+ readonly supportsNoApprove?: boolean;
203
+ readonly supportsJsonOutput?: boolean;
204
+ readonly supportsAllowAll?: boolean;
205
+ readonly supportsNoAskUser?: boolean;
206
+ readonly supportsAddDir?: boolean;
207
+ readonly supportsMcpConfig?: boolean;
208
+ readonly supportsBundledRunner?: boolean;
209
+ readonly supportsAcpStdio?: boolean;
210
+ readonly supportsPromptImages?: boolean;
211
+ readonly supportsLoadSession?: boolean;
212
+ readonly supportsSessionCancel?: boolean;
213
+ readonly supportsSessionSetModel?: boolean;
214
+ readonly supportsSessionSetMode?: boolean;
215
+ readonly supportsRemoteTransport?: false;
216
+ readonly supportsCustomTransport?: false;
217
+ readonly supportsPermissionRequests?: false;
218
+ readonly supportsFsTools?: false;
219
+ readonly supportsTerminalTools?: false;
103
220
  readonly unknown?: boolean;
104
221
  }
105
222
 
@@ -144,6 +261,12 @@ export interface BuildProviderCommandOptions {
144
261
  readonly cliFeatures?: CliFeatureOverrides;
145
262
  readonly authEnv?: Readonly<Record<string, string>>;
146
263
  readonly strictSchema?: boolean;
264
+ readonly gateway?: GatewayBuildOptions;
265
+ // MCP server configs forwarded to providers that accept an MCP config CLI flag (currently
266
+ // Copilot's `--additional-mcp-config`). Each entry is an inline JSON string (the standard
267
+ // `{"mcpServers": {...}}` envelope) or an `@<path>` file reference; adapters emit one flag per
268
+ // entry. Providers whose adapter models no MCP flag ignore this field.
269
+ readonly mcpConfig?: readonly string[];
147
270
  }
148
271
 
149
272
  export interface TextEvent {
@@ -189,8 +312,26 @@ export type OutputEvent = TextEvent | ThinkingEvent | ToolCallEvent | ToolResult
189
312
  export type ProviderParseResult = OutputEvent | readonly OutputEvent[] | null;
190
313
 
191
314
  export interface ProviderParserState {
192
- provider: ProviderId;
315
+ readonly provider: ProviderId;
193
316
  lastToolId: string | null | undefined;
317
+ lastAssistantText?: string;
318
+ lastAssistantThinking?: string;
319
+ messagePhaseById?: Map<string, string>;
320
+ assistantTextByMessageId?: Map<string, string>;
321
+ assistantThinkingByMessageId?: Map<string, string>;
322
+ toolCalls?: Map<
323
+ string,
324
+ {
325
+ name: string | null | undefined;
326
+ input: unknown;
327
+ }
328
+ >;
329
+ usage?: {
330
+ inputTokens?: number;
331
+ outputTokens?: number;
332
+ cacheReadInputTokens?: number;
333
+ cacheCreationInputTokens?: number;
334
+ } | null;
194
335
  }
195
336
 
196
337
  export type ErrorClassificationKind =
@@ -12,7 +12,11 @@
12
12
  */
13
13
 
14
14
  const { loadSettings } = require('../lib/settings');
15
- const { VALID_PROVIDERS, normalizeProviderName } = require('../lib/provider-names');
15
+ const {
16
+ VALID_PROVIDERS,
17
+ normalizeProviderName,
18
+ providerSupportsCapability,
19
+ } = require('../lib/provider-names');
16
20
  const { getProvider } = require('./providers');
17
21
  const { CAPABILITIES } = require('./providers/capabilities');
18
22
  const { GUIDANCE_TOPICS } = require('./guidance-topics');
@@ -2026,6 +2030,10 @@ function validateProviderSettings(provider, providerSettings) {
2026
2030
  const providerModule = getProvider(provider);
2027
2031
  const levels = providerModule.getLevelMapping();
2028
2032
  const settings = providerSettings || {};
2033
+ const providerError = providerModule.validateSettings(settings);
2034
+ if (providerError) {
2035
+ throw new Error(providerError);
2036
+ }
2029
2037
 
2030
2038
  const minLevel = settings.minLevel || providerModule.getDefaultMinLevel?.();
2031
2039
  const maxLevel = settings.maxLevel || providerModule.getDefaultMaxLevel?.();
@@ -2042,7 +2050,10 @@ function validateProviderSettings(provider, providerSettings) {
2042
2050
  `Invalid model override (must be non-empty string) for provider "${provider}"`
2043
2051
  );
2044
2052
  }
2045
- if (override?.reasoningEffort && !['codex', 'opencode'].includes(provider)) {
2053
+ if (override?.model) {
2054
+ providerModule.validateModelId(override.model);
2055
+ }
2056
+ if (override?.reasoningEffort && !providerSupportsCapability(provider, 'reasoningEffort')) {
2046
2057
  throw new Error(`reasoningEffort overrides are only supported for Codex and Opencode`);
2047
2058
  }
2048
2059
  if (
@@ -2068,7 +2079,6 @@ function resolveAgentProvider(agent, config, settings, errors) {
2068
2079
  function buildProviderContext(provider, settings) {
2069
2080
  const providerModule = getProvider(provider);
2070
2081
  const levels = providerModule.getLevelMapping();
2071
- const catalog = providerModule.getModelCatalog();
2072
2082
  const providerSettings = settings.providerSettings?.[provider] || {};
2073
2083
  const minLevel = providerSettings.minLevel;
2074
2084
  const maxLevel = providerSettings.maxLevel;
@@ -2077,7 +2087,6 @@ function buildProviderContext(provider, settings) {
2077
2087
  return {
2078
2088
  providerModule,
2079
2089
  levels,
2080
- catalog,
2081
2090
  providerSettings,
2082
2091
  minLevel,
2083
2092
  maxLevel,
@@ -2109,10 +2118,12 @@ function validateModelLevelSupport(agent, provider, levels, warnings) {
2109
2118
  }
2110
2119
 
2111
2120
  function validateModelSelection(agent, context, warnings) {
2112
- const { provider, catalog, minLevel, maxLevel, rank } = context;
2121
+ const { provider, providerModule, minLevel, maxLevel, rank } = context;
2113
2122
 
2114
2123
  if (agent.model) {
2115
- if (!catalog[agent.model]) {
2124
+ try {
2125
+ providerModule.validateModelId(agent.model);
2126
+ } catch {
2116
2127
  warnings.push(
2117
2128
  `Agent "${agent.id}" uses model "${agent.model}" which is not valid for ${provider}`
2118
2129
  );
@@ -2137,7 +2148,7 @@ function validateModelSelection(agent, context, warnings) {
2137
2148
  }
2138
2149
  }
2139
2150
 
2140
- function validateModelRulesSupport(agent, provider, catalog, levels, warnings) {
2151
+ function validateModelRulesSupport(agent, provider, providerModule, levels, warnings) {
2141
2152
  if (!agent.modelRules || !Array.isArray(agent.modelRules)) return;
2142
2153
 
2143
2154
  for (const rule of agent.modelRules) {
@@ -2146,16 +2157,20 @@ function validateModelRulesSupport(agent, provider, catalog, levels, warnings) {
2146
2157
  `Agent "${agent.id}" uses modelLevel "${rule.modelLevel}" in modelRules which is not valid for ${provider}`
2147
2158
  );
2148
2159
  }
2149
- if (rule.model && !catalog[rule.model]) {
2150
- warnings.push(
2151
- `Agent "${agent.id}" uses model "${rule.model}" in modelRules which is not valid for ${provider}`
2152
- );
2160
+ if (rule.model) {
2161
+ try {
2162
+ providerModule.validateModelId(rule.model);
2163
+ } catch {
2164
+ warnings.push(
2165
+ `Agent "${agent.id}" uses model "${rule.model}" in modelRules which is not valid for ${provider}`
2166
+ );
2167
+ }
2153
2168
  }
2154
2169
  }
2155
2170
  }
2156
2171
 
2157
2172
  function validateReasoningEffortSupport(agent, provider, warnings) {
2158
- if (agent.reasoningEffort && !['codex', 'opencode'].includes(provider)) {
2173
+ if (agent.reasoningEffort && !providerSupportsCapability(provider, 'reasoningEffort')) {
2159
2174
  warnings.push(`Agent "${agent.id}" sets reasoningEffort but ${provider} does not support it`);
2160
2175
  } else if (
2161
2176
  agent.reasoningEffort &&
@@ -2193,10 +2208,13 @@ function validateProviderFeatures(config, settings) {
2193
2208
  const provider = resolveAgentProvider(agent, config, settings, errors);
2194
2209
  if (!provider) continue;
2195
2210
 
2196
- const { levels, catalog, minLevel, maxLevel, rank } = buildProviderContext(provider, settings);
2211
+ const { providerModule, levels, minLevel, maxLevel, rank } = buildProviderContext(
2212
+ provider,
2213
+ settings
2214
+ );
2197
2215
  const modelSelectionContext = {
2198
2216
  provider,
2199
- catalog,
2217
+ providerModule,
2200
2218
  minLevel,
2201
2219
  maxLevel,
2202
2220
  rank,
@@ -2205,7 +2223,7 @@ function validateProviderFeatures(config, settings) {
2205
2223
  validateJsonSchemaSupport(agent, provider, warnings);
2206
2224
  validateModelLevelSupport(agent, provider, levels, warnings);
2207
2225
  validateModelSelection(agent, modelSelectionContext, warnings);
2208
- validateModelRulesSupport(agent, provider, catalog, levels, warnings);
2226
+ validateModelRulesSupport(agent, provider, providerModule, levels, warnings);
2209
2227
  validateReasoningEffortSupport(agent, provider, warnings);
2210
2228
  }
2211
2229