@the-open-engine/zeroshot 6.15.0 → 6.17.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/README.md +10 -7
- package/cli/commands/providers.js +1 -0
- package/cli/index.js +45 -4
- package/lib/agent-cli-provider/adapters/codex.d.ts.map +1 -1
- package/lib/agent-cli-provider/adapters/codex.js +14 -2
- package/lib/agent-cli-provider/adapters/codex.js.map +1 -1
- package/lib/agent-cli-provider/adapters/common.d.ts +1 -0
- package/lib/agent-cli-provider/adapters/common.d.ts.map +1 -1
- package/lib/agent-cli-provider/adapters/common.js +14 -0
- package/lib/agent-cli-provider/adapters/common.js.map +1 -1
- package/lib/agent-cli-provider/adapters/index.d.ts.map +1 -1
- package/lib/agent-cli-provider/adapters/index.js +6 -1
- package/lib/agent-cli-provider/adapters/index.js.map +1 -1
- package/lib/agent-cli-provider/adapters/omp.d.ts +3 -0
- package/lib/agent-cli-provider/adapters/omp.d.ts.map +1 -0
- package/lib/agent-cli-provider/adapters/omp.js +356 -0
- package/lib/agent-cli-provider/adapters/omp.js.map +1 -0
- package/lib/agent-cli-provider/adapters/opencode.d.ts.map +1 -1
- package/lib/agent-cli-provider/adapters/opencode.js +52 -3
- package/lib/agent-cli-provider/adapters/opencode.js.map +1 -1
- package/lib/agent-cli-provider/contract-actions.d.ts.map +1 -1
- package/lib/agent-cli-provider/contract-actions.js +19 -8
- package/lib/agent-cli-provider/contract-actions.js.map +1 -1
- package/lib/agent-cli-provider/contract-fallback.d.ts.map +1 -1
- package/lib/agent-cli-provider/contract-fallback.js +9 -0
- package/lib/agent-cli-provider/contract-fallback.js.map +1 -1
- package/lib/agent-cli-provider/contract-options.d.ts.map +1 -1
- package/lib/agent-cli-provider/contract-options.js +7 -0
- package/lib/agent-cli-provider/contract-options.js.map +1 -1
- package/lib/agent-cli-provider/errors.d.ts +7 -0
- package/lib/agent-cli-provider/errors.d.ts.map +1 -1
- package/lib/agent-cli-provider/errors.js +14 -0
- package/lib/agent-cli-provider/errors.js.map +1 -1
- package/lib/agent-cli-provider/index.d.ts +1 -1
- package/lib/agent-cli-provider/index.d.ts.map +1 -1
- package/lib/agent-cli-provider/index.js.map +1 -1
- package/lib/agent-cli-provider/provider-registry.d.ts +66 -3
- package/lib/agent-cli-provider/provider-registry.d.ts.map +1 -1
- package/lib/agent-cli-provider/provider-registry.js +54 -2
- package/lib/agent-cli-provider/provider-registry.js.map +1 -1
- package/lib/agent-cli-provider/single-agent-runtime.d.ts +14 -2
- package/lib/agent-cli-provider/single-agent-runtime.d.ts.map +1 -1
- package/lib/agent-cli-provider/single-agent-runtime.js +97 -22
- package/lib/agent-cli-provider/single-agent-runtime.js.map +1 -1
- package/lib/agent-cli-provider/types.d.ts +30 -2
- package/lib/agent-cli-provider/types.d.ts.map +1 -1
- package/lib/agent-cli-provider/types.js.map +1 -1
- package/package.json +1 -1
- package/src/agent/agent-lifecycle.js +52 -1
- package/src/agent/agent-task-executor.js +8 -3
- package/src/agent-cli-provider/adapters/codex.ts +23 -2
- package/src/agent-cli-provider/adapters/common.ts +14 -0
- package/src/agent-cli-provider/adapters/index.ts +16 -2
- package/src/agent-cli-provider/adapters/omp.ts +448 -0
- package/src/agent-cli-provider/adapters/opencode.ts +60 -4
- package/src/agent-cli-provider/contract-actions.ts +20 -9
- package/src/agent-cli-provider/contract-fallback.ts +9 -0
- package/src/agent-cli-provider/contract-options.ts +7 -0
- package/src/agent-cli-provider/errors.ts +14 -0
- package/src/agent-cli-provider/index.ts +2 -0
- package/src/agent-cli-provider/provider-registry.ts +59 -2
- package/src/agent-cli-provider/single-agent-runtime.ts +144 -24
- package/src/agent-cli-provider/types.ts +32 -1
- package/src/claude-task-runner.js +11 -0
- package/src/orchestrator.js +8 -3
- package/src/providers/index.js +6 -0
- package/src/task-run-model-args.js +58 -40
- package/src/task-spawn-cleanup-ownership.js +3 -0
- package/src/task-startup-error.js +68 -0
|
@@ -23,6 +23,10 @@ import type { ProcessRunner } from './process-runner';
|
|
|
23
23
|
|
|
24
24
|
function runBuildCommand(request: RequestData): ContractEnvelope {
|
|
25
25
|
const { adapter, commandSpec, options } = buildCommandSpec(request);
|
|
26
|
+
const webSearch = {
|
|
27
|
+
requested: options.webSearch === true,
|
|
28
|
+
effective: options.webSearch === true && options.cliFeatures?.supportsWebSearch === true,
|
|
29
|
+
};
|
|
26
30
|
return successEnvelope({
|
|
27
31
|
command: request.command ?? 'build-command',
|
|
28
32
|
adapter,
|
|
@@ -31,11 +35,13 @@ function runBuildCommand(request: RequestData): ContractEnvelope {
|
|
|
31
35
|
evidence: {
|
|
32
36
|
outputFormat: options.outputFormat ?? null,
|
|
33
37
|
schemaMode: schemaMode(options),
|
|
38
|
+
configuration: { webSearch },
|
|
34
39
|
},
|
|
35
40
|
result: {
|
|
36
41
|
commandSpec,
|
|
37
42
|
outputFormat: options.outputFormat ?? null,
|
|
38
43
|
schemaMode: schemaMode(options),
|
|
44
|
+
configuration: { webSearch },
|
|
39
45
|
},
|
|
40
46
|
});
|
|
41
47
|
}
|
|
@@ -43,11 +49,15 @@ function runBuildCommand(request: RequestData): ContractEnvelope {
|
|
|
43
49
|
function runProbe(request: RequestData): ContractEnvelope {
|
|
44
50
|
const adapter = adapterForProvider(request.provider);
|
|
45
51
|
const helpText = typeof request.raw.helpText === 'string' ? request.raw.helpText : null;
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
? adapter.
|
|
50
|
-
:
|
|
52
|
+
const versionText = typeof request.raw.versionText === 'string' ? request.raw.versionText : '';
|
|
53
|
+
const runtimeProbe =
|
|
54
|
+
helpText === null
|
|
55
|
+
? probeRuntimeProviderCli(adapter.id)
|
|
56
|
+
: probeRuntimeProviderCli(adapter.id, {
|
|
57
|
+
available: true,
|
|
58
|
+
helpText,
|
|
59
|
+
versionText,
|
|
60
|
+
});
|
|
51
61
|
return successEnvelope({
|
|
52
62
|
command: request.command ?? 'probe',
|
|
53
63
|
adapter,
|
|
@@ -60,10 +70,11 @@ function runProbe(request: RequestData): ContractEnvelope {
|
|
|
60
70
|
},
|
|
61
71
|
contractVersion: providerExecutableSchemaVersion,
|
|
62
72
|
adapterVersion: adapter.adapterVersion,
|
|
63
|
-
available: runtimeProbe
|
|
64
|
-
helpText: runtimeProbe
|
|
65
|
-
versionText: runtimeProbe
|
|
66
|
-
capabilities,
|
|
73
|
+
available: runtimeProbe.available,
|
|
74
|
+
helpText: runtimeProbe.helpText,
|
|
75
|
+
versionText: runtimeProbe.versionText,
|
|
76
|
+
capabilities: runtimeProbe.capabilities,
|
|
77
|
+
configuration: runtimeProbe.configuration,
|
|
67
78
|
credentials: adapter.credentialEnvKeys.map((key) => ({
|
|
68
79
|
key,
|
|
69
80
|
present: Boolean(request.env[key] ?? process.env[key]),
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type ContractErrorObject,
|
|
7
7
|
type ContractEnvelope,
|
|
8
8
|
} from './contract-envelope';
|
|
9
|
+
import { UnsupportedProviderCapabilityError } from './errors';
|
|
9
10
|
import { getString, isRecord, parseJson, unknownToMessage } from './json';
|
|
10
11
|
import { mergeRedactions, redactString } from './redaction';
|
|
11
12
|
import type { ProviderAdapter } from './types';
|
|
@@ -77,6 +78,14 @@ function errorObject(requestError: ContractRequestError): ContractErrorObject {
|
|
|
77
78
|
|
|
78
79
|
export function requestErrorFromUnknown(error: unknown): ContractRequestError {
|
|
79
80
|
if (error instanceof ContractRequestError) return error;
|
|
81
|
+
if (error instanceof UnsupportedProviderCapabilityError) {
|
|
82
|
+
return contractError({
|
|
83
|
+
code: error.code,
|
|
84
|
+
message: error.message,
|
|
85
|
+
exitCode: 4,
|
|
86
|
+
field: 'options.webSearch',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
80
89
|
return contractError({
|
|
81
90
|
code: 'internal-error',
|
|
82
91
|
message: unknownToMessage(error),
|
|
@@ -38,12 +38,18 @@ const CLI_FEATURE_FIELDS = [
|
|
|
38
38
|
'supportsNoPromptTemplates',
|
|
39
39
|
'supportsNoContextFiles',
|
|
40
40
|
'supportsNoApprove',
|
|
41
|
+
'supportsModeJson',
|
|
42
|
+
'supportsPrint',
|
|
43
|
+
'supportsThinking',
|
|
44
|
+
'supportsNoRules',
|
|
45
|
+
'supportsNoTitle',
|
|
41
46
|
'supportsJsonOutput',
|
|
42
47
|
'supportsAllowAll',
|
|
43
48
|
'supportsNoAskUser',
|
|
44
49
|
'supportsAddDir',
|
|
45
50
|
'supportsMcpConfig',
|
|
46
51
|
'supportsResume',
|
|
52
|
+
'supportsWebSearch',
|
|
47
53
|
'supportsBundledRunner',
|
|
48
54
|
'supportsAcpStdio',
|
|
49
55
|
'supportsPromptImages',
|
|
@@ -210,6 +216,7 @@ function normalizeBuildOptions(value: Record<string, unknown>): BuildProviderCom
|
|
|
210
216
|
'continueSession',
|
|
211
217
|
optionalBooleanValue(value.continueSession, 'options.continueSession')
|
|
212
218
|
);
|
|
219
|
+
addDefined(result, 'webSearch', optionalBooleanValue(value.webSearch, 'options.webSearch'));
|
|
213
220
|
addDefined(
|
|
214
221
|
result,
|
|
215
222
|
'claudeSettingsFile',
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import { getNumber, getRecord, getString, isRecord, unknownToMessage } from './json';
|
|
2
2
|
import type { ErrorClassification } from './types';
|
|
3
3
|
|
|
4
|
+
export class UnsupportedProviderCapabilityError extends Error {
|
|
5
|
+
readonly code = 'unsupported-capability';
|
|
6
|
+
readonly permanent = true;
|
|
7
|
+
readonly provider: string;
|
|
8
|
+
readonly capability: string;
|
|
9
|
+
|
|
10
|
+
constructor(provider: string, capability: string, message: string) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = 'UnsupportedProviderCapabilityError';
|
|
13
|
+
this.provider = provider;
|
|
14
|
+
this.capability = capability;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
4
18
|
const BASE_RETRYABLE_PATTERNS: readonly RegExp[] = [
|
|
5
19
|
/rate.?limit/i,
|
|
6
20
|
/\b429\b/i,
|
|
@@ -78,6 +78,7 @@ export type {
|
|
|
78
78
|
ModelCatalogEntry,
|
|
79
79
|
ModelLevel,
|
|
80
80
|
ModelSpec,
|
|
81
|
+
OmpCliFeatures,
|
|
81
82
|
OpencodeCliFeatures,
|
|
82
83
|
OutputEvent,
|
|
83
84
|
OutputFormat,
|
|
@@ -102,6 +103,7 @@ export type {
|
|
|
102
103
|
ToolCallEvent,
|
|
103
104
|
ToolResultEvent,
|
|
104
105
|
WarningMetadata,
|
|
106
|
+
WebSearchAttestation,
|
|
105
107
|
} from './types';
|
|
106
108
|
|
|
107
109
|
import type { AgentCliProviderHelperMetadata } from './types';
|
|
@@ -5,6 +5,7 @@ import { copilotAdapter } from './adapters/copilot';
|
|
|
5
5
|
import { gatewayAdapter, gatewaySettingsDefaults, validateGatewaySettings } from './adapters/gateway';
|
|
6
6
|
import { geminiAdapter } from './adapters/gemini';
|
|
7
7
|
import { opencodeAdapter } from './adapters/opencode';
|
|
8
|
+
import { ompAdapter } from './adapters/omp';
|
|
8
9
|
import { piAdapter } from './adapters/pi';
|
|
9
10
|
import { resolveClaudeCommand } from './claude-command';
|
|
10
11
|
import type { ModelLevel, ProviderAdapter } from './types';
|
|
@@ -20,6 +21,7 @@ export interface ProviderCapabilities {
|
|
|
20
21
|
readonly thinkingMode: ProviderCapabilityState;
|
|
21
22
|
readonly reasoningEffort: ProviderCapabilityState;
|
|
22
23
|
readonly sessionResume: ProviderCapabilityState;
|
|
24
|
+
readonly webSearch: ProviderCapabilityState;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
interface FixedProviderCommandSpec {
|
|
@@ -102,6 +104,7 @@ const STANDARD_CAPABILITIES: Readonly<
|
|
|
102
104
|
| 'streamJson'
|
|
103
105
|
| 'thinkingMode'
|
|
104
106
|
| 'sessionResume'
|
|
107
|
+
| 'webSearch'
|
|
105
108
|
>
|
|
106
109
|
> = {
|
|
107
110
|
dockerIsolation: true,
|
|
@@ -110,6 +113,7 @@ const STANDARD_CAPABILITIES: Readonly<
|
|
|
110
113
|
streamJson: true,
|
|
111
114
|
thinkingMode: true,
|
|
112
115
|
sessionResume: false,
|
|
116
|
+
webSearch: false,
|
|
113
117
|
};
|
|
114
118
|
|
|
115
119
|
const CLAUDE_DOCKER_ENV_PASSTHROUGH = [
|
|
@@ -203,12 +207,15 @@ export const providerRegistry = [
|
|
|
203
207
|
authInstructions: 'codex login',
|
|
204
208
|
credentialPaths: ['~/.config/codex', '~/.codex'],
|
|
205
209
|
credentialEnvKeys: codexAdapter.credentialEnvKeys,
|
|
206
|
-
settingsFields: [],
|
|
210
|
+
settingsFields: ['webSearch'],
|
|
211
|
+
settingsDefaults: { webSearch: false },
|
|
212
|
+
settingsValidator: (settings): string | null => validateWebSearchSettings('codex', settings),
|
|
207
213
|
capabilities: {
|
|
208
214
|
...STANDARD_CAPABILITIES,
|
|
209
215
|
jsonSchema: true,
|
|
210
216
|
reasoningEffort: true,
|
|
211
217
|
sessionResume: true,
|
|
218
|
+
webSearch: true,
|
|
212
219
|
},
|
|
213
220
|
docs: {
|
|
214
221
|
label: 'Codex',
|
|
@@ -326,11 +333,15 @@ export const providerRegistry = [
|
|
|
326
333
|
authInstructions: 'opencode auth login',
|
|
327
334
|
credentialPaths: ['~/.local/share/opencode'],
|
|
328
335
|
credentialEnvKeys: opencodeAdapter.credentialEnvKeys,
|
|
329
|
-
settingsFields: [],
|
|
336
|
+
settingsFields: ['webSearch'],
|
|
337
|
+
settingsDefaults: { webSearch: false },
|
|
338
|
+
settingsValidator: (settings): string | null => validateWebSearchSettings('opencode', settings),
|
|
330
339
|
capabilities: {
|
|
331
340
|
...STANDARD_CAPABILITIES,
|
|
332
341
|
jsonSchema: 'experimental',
|
|
333
342
|
reasoningEffort: true,
|
|
343
|
+
sessionResume: true,
|
|
344
|
+
webSearch: true,
|
|
334
345
|
},
|
|
335
346
|
docs: {
|
|
336
347
|
label: 'Opencode',
|
|
@@ -390,6 +401,44 @@ export const providerRegistry = [
|
|
|
390
401
|
},
|
|
391
402
|
adapter: piAdapter,
|
|
392
403
|
},
|
|
404
|
+
{
|
|
405
|
+
id: 'omp',
|
|
406
|
+
aliases: [],
|
|
407
|
+
displayName: 'OMP',
|
|
408
|
+
binary: 'omp',
|
|
409
|
+
command: { kind: 'fixed', command: 'omp', args: [] },
|
|
410
|
+
invoke: SPAWN_INVOKE,
|
|
411
|
+
installInstructions: 'npm install -g --ignore-scripts @oh-my-pi/pi-coding-agent',
|
|
412
|
+
authInstructions: 'omp\n/login',
|
|
413
|
+
credentialPaths: ['~/.omp'],
|
|
414
|
+
credentialEnvKeys: ompAdapter.credentialEnvKeys,
|
|
415
|
+
settingsFields: [],
|
|
416
|
+
availabilityProbe: 'help-or-version',
|
|
417
|
+
capabilities: {
|
|
418
|
+
...STANDARD_CAPABILITIES,
|
|
419
|
+
mcpServers: false,
|
|
420
|
+
jsonSchema: false,
|
|
421
|
+
reasoningEffort: true,
|
|
422
|
+
},
|
|
423
|
+
docs: {
|
|
424
|
+
label: 'OMP',
|
|
425
|
+
setupHeading: 'OMP Setup',
|
|
426
|
+
},
|
|
427
|
+
docker: {
|
|
428
|
+
mount: {
|
|
429
|
+
host: '~/.omp',
|
|
430
|
+
container: '$HOME/.omp',
|
|
431
|
+
readonly: true,
|
|
432
|
+
},
|
|
433
|
+
envPassthrough: [],
|
|
434
|
+
},
|
|
435
|
+
defaultLevels: {
|
|
436
|
+
min: ompAdapter.defaultMinLevel,
|
|
437
|
+
default: ompAdapter.defaultLevel,
|
|
438
|
+
max: ompAdapter.defaultMaxLevel,
|
|
439
|
+
},
|
|
440
|
+
adapter: ompAdapter,
|
|
441
|
+
},
|
|
393
442
|
{
|
|
394
443
|
id: 'kiro',
|
|
395
444
|
aliases: [],
|
|
@@ -472,6 +521,14 @@ export const providerRegistry = [
|
|
|
472
521
|
},
|
|
473
522
|
] as const satisfies readonly ProviderRegistryEntry[];
|
|
474
523
|
|
|
524
|
+
function validateWebSearchSettings(
|
|
525
|
+
provider: 'codex' | 'opencode',
|
|
526
|
+
settings: Record<string, unknown>
|
|
527
|
+
): string | null {
|
|
528
|
+
if (settings.webSearch === undefined || typeof settings.webSearch === 'boolean') return null;
|
|
529
|
+
return `providerSettings.${provider}.webSearch must be a boolean`;
|
|
530
|
+
}
|
|
531
|
+
|
|
475
532
|
type RegistryProviderId = (typeof providerRegistry)[number]['id'];
|
|
476
533
|
type RegistryProviderAlias = (typeof providerRegistry)[number]['aliases'][number];
|
|
477
534
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getProviderAdapter } from './adapters';
|
|
2
|
+
import { UnsupportedProviderCapabilityError } from './errors';
|
|
2
3
|
import { normalizeGatewayBuildOptions, resolveGatewayConfiguration } from './gateway-tools';
|
|
3
4
|
import { isRecord } from './json';
|
|
4
5
|
import {
|
|
@@ -19,6 +20,7 @@ import type {
|
|
|
19
20
|
ProviderId,
|
|
20
21
|
ResolvedGatewayBuildOptions,
|
|
21
22
|
ReasoningEffort,
|
|
23
|
+
WebSearchAttestation,
|
|
22
24
|
} from './types';
|
|
23
25
|
|
|
24
26
|
type UnknownFunction = (...args: readonly unknown[]) => unknown;
|
|
@@ -32,6 +34,7 @@ interface RuntimeProviderSettings {
|
|
|
32
34
|
readonly defaultLevel?: ModelLevel;
|
|
33
35
|
readonly levelOverrides: LevelOverrides;
|
|
34
36
|
readonly gateway?: GatewayBuildOptions;
|
|
37
|
+
readonly webSearch?: boolean;
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
interface RuntimeCommandContext {
|
|
@@ -50,6 +53,9 @@ export interface PreparedSingleAgentProviderCommand {
|
|
|
50
53
|
readonly commandSpec: CommandSpec;
|
|
51
54
|
readonly options: BuildProviderCommandOptions;
|
|
52
55
|
readonly cliFeatures: CliFeatureOverrides;
|
|
56
|
+
readonly configuration: {
|
|
57
|
+
readonly webSearch: WebSearchAttestation;
|
|
58
|
+
};
|
|
53
59
|
}
|
|
54
60
|
|
|
55
61
|
export interface RuntimeProviderProbe {
|
|
@@ -57,6 +63,15 @@ export interface RuntimeProviderProbe {
|
|
|
57
63
|
readonly helpText: string;
|
|
58
64
|
readonly versionText: string;
|
|
59
65
|
readonly capabilities: ProviderCliFeatures;
|
|
66
|
+
readonly configuration: {
|
|
67
|
+
readonly webSearch: WebSearchAttestation;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface RuntimeProbeEvidence {
|
|
72
|
+
readonly available?: boolean;
|
|
73
|
+
readonly helpText: string;
|
|
74
|
+
readonly versionText: string;
|
|
60
75
|
}
|
|
61
76
|
|
|
62
77
|
type MutableModelSpec = {
|
|
@@ -91,7 +106,13 @@ export function prepareSingleAgentProviderCommand(
|
|
|
91
106
|
adapter.id,
|
|
92
107
|
baseOptions.cwd ?? process.cwd()
|
|
93
108
|
);
|
|
94
|
-
const
|
|
109
|
+
const requestedWebSearch = baseOptions.webSearch ?? providerSettings.webSearch;
|
|
110
|
+
assertWebSearchDeclared(adapter.id, requestedWebSearch);
|
|
111
|
+
const cliFeatures = resolveRuntimeCliFeatures(
|
|
112
|
+
adapter.id,
|
|
113
|
+
baseOptions.cliFeatures,
|
|
114
|
+
requestedWebSearch === true
|
|
115
|
+
);
|
|
95
116
|
const authEnv = baseOptions.authEnv ?? resolveRuntimeAuthEnv(adapter.id, settings);
|
|
96
117
|
const options = buildRuntimeOptions(baseOptions, adapter, providerSettings, {
|
|
97
118
|
cliFeatures,
|
|
@@ -101,6 +122,9 @@ export function prepareSingleAgentProviderCommand(
|
|
|
101
122
|
adapter,
|
|
102
123
|
options,
|
|
103
124
|
cliFeatures,
|
|
125
|
+
configuration: {
|
|
126
|
+
webSearch: webSearchAttestation(options),
|
|
127
|
+
},
|
|
104
128
|
commandSpec: adapter.buildCommand(input.context, options),
|
|
105
129
|
};
|
|
106
130
|
}
|
|
@@ -111,22 +135,35 @@ export function detectRuntimeProviderCliFeatures(provider: string): ProviderCliF
|
|
|
111
135
|
|
|
112
136
|
function resolveRuntimeCliFeatures(
|
|
113
137
|
provider: ProviderId,
|
|
114
|
-
overrides: CliFeatureOverrides | undefined
|
|
138
|
+
overrides: CliFeatureOverrides | undefined,
|
|
139
|
+
webSearchRequested: boolean
|
|
115
140
|
): CliFeatureOverrides {
|
|
116
141
|
if (provider === 'gateway') {
|
|
142
|
+
const detected = detectRuntimeProviderCliFeatures(provider);
|
|
117
143
|
return {
|
|
118
|
-
...
|
|
144
|
+
...detected,
|
|
119
145
|
...overrides,
|
|
120
146
|
supportsBundledRunner: true,
|
|
147
|
+
supportsWebSearch: false,
|
|
121
148
|
};
|
|
122
149
|
}
|
|
123
|
-
if (getProviderRegistryEntry(provider).invoke.lane
|
|
124
|
-
|
|
150
|
+
if (getProviderRegistryEntry(provider).invoke.lane === 'acp-stdio') {
|
|
151
|
+
const detected = detectRuntimeProviderCliFeatures(provider);
|
|
152
|
+
if (overrides === undefined) return detected;
|
|
153
|
+
return mergeAcpFailClosedCliFeatures(detected, overrides);
|
|
125
154
|
}
|
|
126
|
-
|
|
155
|
+
if (overrides === undefined) return detectRuntimeProviderCliFeatures(provider);
|
|
156
|
+
if (!webSearchRequested) return overrides;
|
|
127
157
|
const detected = detectRuntimeProviderCliFeatures(provider);
|
|
128
|
-
|
|
129
|
-
|
|
158
|
+
return {
|
|
159
|
+
...overrides,
|
|
160
|
+
supportsResume:
|
|
161
|
+
'supportsResume' in detected &&
|
|
162
|
+
detected.supportsResume === true &&
|
|
163
|
+
overrides.supportsResume !== false,
|
|
164
|
+
supportsWebSearch:
|
|
165
|
+
detected.supportsWebSearch === true && overrides.supportsWebSearch !== false,
|
|
166
|
+
};
|
|
130
167
|
}
|
|
131
168
|
|
|
132
169
|
function mergeAcpFailClosedCliFeatures(
|
|
@@ -154,33 +191,61 @@ function mergeAcpFailClosedCliFeatures(
|
|
|
154
191
|
};
|
|
155
192
|
}
|
|
156
193
|
|
|
157
|
-
export function probeRuntimeProviderCli(
|
|
194
|
+
export function probeRuntimeProviderCli(
|
|
195
|
+
provider: string,
|
|
196
|
+
evidence?: RuntimeProbeEvidence
|
|
197
|
+
): RuntimeProviderProbe {
|
|
158
198
|
const adapter = getProviderAdapter(provider);
|
|
159
199
|
if (adapter.id === 'gateway') {
|
|
160
200
|
return probeGatewayProvider(adapter);
|
|
161
201
|
}
|
|
202
|
+
const requested = getProviderRegistryEntry(adapter.id).settingsFields.includes('webSearch')
|
|
203
|
+
? runtimeProviderSettings(loadRuntimeSettings(), adapter.id, process.cwd()).webSearch === true
|
|
204
|
+
: false;
|
|
162
205
|
const helpCommand = runtimeHelpCommand(adapter.id);
|
|
163
|
-
const commandAvailable =
|
|
206
|
+
const commandAvailable =
|
|
207
|
+
evidence === undefined
|
|
208
|
+
? booleanResult(commandExistsFn(helpCommand.command))
|
|
209
|
+
: evidence.available !== false;
|
|
164
210
|
if (!commandAvailable) {
|
|
211
|
+
const capabilities = attestedCliFeatures(adapter, '', '');
|
|
165
212
|
return {
|
|
166
213
|
available: false,
|
|
167
214
|
helpText: '',
|
|
168
215
|
versionText: '',
|
|
169
|
-
capabilities
|
|
216
|
+
capabilities,
|
|
217
|
+
configuration: {
|
|
218
|
+
webSearch: webSearchAttestation({ webSearch: requested, cliFeatures: capabilities }),
|
|
219
|
+
},
|
|
170
220
|
};
|
|
171
221
|
}
|
|
172
222
|
|
|
173
|
-
const helpText =
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
223
|
+
const helpText =
|
|
224
|
+
evidence?.helpText ??
|
|
225
|
+
stringResult(getHelpOutputFn(helpCommand.command, helpCommand.args)).trim();
|
|
226
|
+
const versionText =
|
|
227
|
+
evidence?.versionText ??
|
|
228
|
+
stringResult(
|
|
229
|
+
getVersionOutputFn(
|
|
230
|
+
helpCommand.command,
|
|
231
|
+
getProviderRegistryEntry(adapter.id).capabilities.webSearch === true
|
|
232
|
+
? []
|
|
233
|
+
: helpCommand.args
|
|
234
|
+
)
|
|
235
|
+
).trim();
|
|
177
236
|
const availabilityProbe = getProviderRegistryEntry(adapter.id).availabilityProbe ?? 'command';
|
|
237
|
+
const capabilities = attestedCliFeatures(adapter, helpText, versionText);
|
|
178
238
|
|
|
179
239
|
return {
|
|
180
|
-
available:
|
|
240
|
+
available:
|
|
241
|
+
evidence?.available ??
|
|
242
|
+
(availabilityProbe === 'help-or-version' ? Boolean(helpText || versionText) : true),
|
|
181
243
|
helpText,
|
|
182
244
|
versionText,
|
|
183
|
-
capabilities
|
|
245
|
+
capabilities,
|
|
246
|
+
configuration: {
|
|
247
|
+
webSearch: webSearchAttestation({ webSearch: requested, cliFeatures: capabilities }),
|
|
248
|
+
},
|
|
184
249
|
};
|
|
185
250
|
}
|
|
186
251
|
|
|
@@ -197,10 +262,13 @@ function buildRuntimeOptions(
|
|
|
197
262
|
providerSettings,
|
|
198
263
|
modelSpec
|
|
199
264
|
);
|
|
265
|
+
const webSearch = baseOptions.webSearch ?? providerSettings.webSearch;
|
|
266
|
+
assertWebSearchDeclared(adapter.id, webSearch);
|
|
200
267
|
const resolved = {
|
|
201
268
|
...baseOptions,
|
|
202
269
|
modelSpec,
|
|
203
270
|
...(gateway === undefined ? {} : { gateway }),
|
|
271
|
+
...(webSearch === undefined ? {} : { webSearch }),
|
|
204
272
|
cliFeatures: runtime.cliFeatures,
|
|
205
273
|
};
|
|
206
274
|
if (baseOptions.jsonSchema && !supportsProviderCapability(adapter.id, 'jsonSchema')) {
|
|
@@ -320,16 +388,20 @@ function runtimeProviderSettings(
|
|
|
320
388
|
providerSettings.levelOverrides,
|
|
321
389
|
`settings.providerSettings.${provider}.levelOverrides`
|
|
322
390
|
);
|
|
391
|
+
const webSearch = optionalBoolean(
|
|
392
|
+
providerSettings.webSearch,
|
|
393
|
+
`settings.providerSettings.${provider}.webSearch`
|
|
394
|
+
);
|
|
323
395
|
const gateway =
|
|
324
396
|
provider === 'gateway'
|
|
325
397
|
? normalizeGatewayBuildOptions(providerSettings, 'settings.providerSettings.gateway', cwd)
|
|
326
398
|
: undefined;
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
399
|
+
const base = {
|
|
400
|
+
levelOverrides,
|
|
401
|
+
...(gateway === undefined ? {} : { gateway }),
|
|
402
|
+
...(webSearch === undefined ? {} : { webSearch }),
|
|
403
|
+
};
|
|
404
|
+
return defaultLevel === undefined ? base : { ...base, defaultLevel };
|
|
333
405
|
}
|
|
334
406
|
|
|
335
407
|
function runtimeHelpCommand(provider: ProviderId): CommandParts {
|
|
@@ -340,7 +412,7 @@ function runtimeHelpCommand(provider: ProviderId): CommandParts {
|
|
|
340
412
|
}
|
|
341
413
|
|
|
342
414
|
function probeGatewayProvider(adapter: ProviderAdapter): RuntimeProviderProbe {
|
|
343
|
-
const capabilities = adapter
|
|
415
|
+
const capabilities = attestedCliFeatures(adapter, '', '');
|
|
344
416
|
try {
|
|
345
417
|
const settings = loadRuntimeSettings();
|
|
346
418
|
const providerSettings = runtimeProviderSettings(settings, 'gateway', process.cwd());
|
|
@@ -354,6 +426,9 @@ function probeGatewayProvider(adapter: ProviderAdapter): RuntimeProviderProbe {
|
|
|
354
426
|
helpText: 'Bundled gateway runner',
|
|
355
427
|
versionText: process.version,
|
|
356
428
|
capabilities,
|
|
429
|
+
configuration: {
|
|
430
|
+
webSearch: { requested: false, effective: false },
|
|
431
|
+
},
|
|
357
432
|
};
|
|
358
433
|
} catch {
|
|
359
434
|
return {
|
|
@@ -361,10 +436,49 @@ function probeGatewayProvider(adapter: ProviderAdapter): RuntimeProviderProbe {
|
|
|
361
436
|
helpText: 'Bundled gateway runner',
|
|
362
437
|
versionText: process.version,
|
|
363
438
|
capabilities,
|
|
439
|
+
configuration: {
|
|
440
|
+
webSearch: { requested: false, effective: false },
|
|
441
|
+
},
|
|
364
442
|
};
|
|
365
443
|
}
|
|
366
444
|
}
|
|
367
445
|
|
|
446
|
+
function attestedCliFeatures(
|
|
447
|
+
adapter: ProviderAdapter,
|
|
448
|
+
helpText: string,
|
|
449
|
+
versionText: string
|
|
450
|
+
): ProviderCliFeatures {
|
|
451
|
+
const detected = adapter.detectCliFeatures(helpText, versionText);
|
|
452
|
+
return {
|
|
453
|
+
...detected,
|
|
454
|
+
supportsWebSearch:
|
|
455
|
+
getProviderRegistryEntry(adapter.id).capabilities.webSearch === true &&
|
|
456
|
+
detected.supportsWebSearch === true,
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
function webSearchAttestation(options: {
|
|
461
|
+
readonly webSearch?: boolean;
|
|
462
|
+
readonly cliFeatures?: CliFeatureOverrides;
|
|
463
|
+
}): WebSearchAttestation {
|
|
464
|
+
const requested = options.webSearch === true;
|
|
465
|
+
return {
|
|
466
|
+
requested,
|
|
467
|
+
effective: requested && options.cliFeatures?.supportsWebSearch === true,
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
function assertWebSearchDeclared(provider: ProviderId, requested: boolean | undefined): void {
|
|
472
|
+
if (requested === undefined || getProviderRegistryEntry(provider).capabilities.webSearch === true) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
throw new UnsupportedProviderCapabilityError(
|
|
476
|
+
provider,
|
|
477
|
+
'webSearch',
|
|
478
|
+
`Provider ${provider} does not expose provider-controlled native web search; remove options.webSearch.`
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
|
|
368
482
|
function loadRuntimeSettings(): Record<string, unknown> {
|
|
369
483
|
if (Object.prototype.hasOwnProperty.call(process.env, LEGACY_ISOLATED_PROVIDER_SETTINGS_ENV)) {
|
|
370
484
|
throw new Error(
|
|
@@ -439,6 +553,12 @@ function addReasoningEffort(result: MutableModelSpec, value: unknown, field: str
|
|
|
439
553
|
if (effort !== undefined) result.reasoningEffort = effort;
|
|
440
554
|
}
|
|
441
555
|
|
|
556
|
+
function optionalBoolean(value: unknown, field: string): boolean | undefined {
|
|
557
|
+
if (value === undefined) return undefined;
|
|
558
|
+
if (typeof value === 'boolean') return value;
|
|
559
|
+
throw new Error(`${field} must be a boolean.`);
|
|
560
|
+
}
|
|
561
|
+
|
|
442
562
|
function optionalModelLevel(value: unknown, field: string): ModelLevel | undefined {
|
|
443
563
|
if (value === undefined) return undefined;
|
|
444
564
|
if (value === 'level1' || value === 'level2' || value === 'level3') return value;
|
|
@@ -89,6 +89,7 @@ export interface ResolvedGatewayBuildOptions {
|
|
|
89
89
|
export interface BaseCliFeatures {
|
|
90
90
|
readonly provider?: ProviderId;
|
|
91
91
|
readonly unknown?: boolean;
|
|
92
|
+
readonly supportsWebSearch?: boolean;
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
export interface ClaudeCliFeatures extends BaseCliFeatures {
|
|
@@ -116,6 +117,7 @@ export interface CodexCliFeatures extends BaseCliFeatures {
|
|
|
116
117
|
readonly supportsModel: boolean;
|
|
117
118
|
readonly supportsSkipGitRepoCheck: boolean;
|
|
118
119
|
readonly supportsResume: boolean;
|
|
120
|
+
readonly supportsWebSearch: boolean;
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
export interface GeminiCliFeatures extends BaseCliFeatures {
|
|
@@ -134,6 +136,8 @@ export interface OpencodeCliFeatures extends BaseCliFeatures {
|
|
|
134
136
|
readonly supportsDir: boolean;
|
|
135
137
|
readonly supportsCwd: boolean;
|
|
136
138
|
readonly supportsAutoApprove: false;
|
|
139
|
+
readonly supportsResume: boolean;
|
|
140
|
+
readonly supportsWebSearch: boolean;
|
|
137
141
|
}
|
|
138
142
|
|
|
139
143
|
export interface PiCliFeatures extends BaseCliFeatures {
|
|
@@ -148,6 +152,20 @@ export interface PiCliFeatures extends BaseCliFeatures {
|
|
|
148
152
|
readonly supportsNoApprove: boolean;
|
|
149
153
|
}
|
|
150
154
|
|
|
155
|
+
export interface OmpCliFeatures extends BaseCliFeatures {
|
|
156
|
+
readonly provider: 'omp';
|
|
157
|
+
readonly supportsModeJson: boolean;
|
|
158
|
+
readonly supportsPrint: boolean;
|
|
159
|
+
readonly supportsCwd: boolean;
|
|
160
|
+
readonly supportsAutoApprove: boolean;
|
|
161
|
+
readonly supportsModel: boolean;
|
|
162
|
+
readonly supportsThinking: boolean;
|
|
163
|
+
readonly supportsNoExtensions: boolean;
|
|
164
|
+
readonly supportsNoSkills: boolean;
|
|
165
|
+
readonly supportsNoRules: boolean;
|
|
166
|
+
readonly supportsNoTitle: boolean;
|
|
167
|
+
}
|
|
168
|
+
|
|
151
169
|
export interface CopilotCliFeatures extends BaseCliFeatures {
|
|
152
170
|
readonly provider: 'copilot';
|
|
153
171
|
readonly supportsJsonOutput: boolean;
|
|
@@ -184,6 +202,7 @@ export type ProviderCliFeatures =
|
|
|
184
202
|
| GeminiCliFeatures
|
|
185
203
|
| OpencodeCliFeatures
|
|
186
204
|
| PiCliFeatures
|
|
205
|
+
| OmpCliFeatures
|
|
187
206
|
| CopilotCliFeatures
|
|
188
207
|
| GatewayCliFeatures
|
|
189
208
|
| AcpCliFeatures;
|
|
@@ -212,12 +231,18 @@ export interface CliFeatureOverrides {
|
|
|
212
231
|
readonly supportsNoPromptTemplates?: boolean;
|
|
213
232
|
readonly supportsNoContextFiles?: boolean;
|
|
214
233
|
readonly supportsNoApprove?: boolean;
|
|
234
|
+
readonly supportsModeJson?: boolean;
|
|
235
|
+
readonly supportsPrint?: boolean;
|
|
236
|
+
readonly supportsThinking?: boolean;
|
|
237
|
+
readonly supportsNoRules?: boolean;
|
|
238
|
+
readonly supportsNoTitle?: boolean;
|
|
215
239
|
readonly supportsJsonOutput?: boolean;
|
|
216
240
|
readonly supportsAllowAll?: boolean;
|
|
217
241
|
readonly supportsNoAskUser?: boolean;
|
|
218
242
|
readonly supportsAddDir?: boolean;
|
|
219
243
|
readonly supportsMcpConfig?: boolean;
|
|
220
244
|
readonly supportsResume?: boolean;
|
|
245
|
+
readonly supportsWebSearch?: boolean;
|
|
221
246
|
readonly supportsBundledRunner?: boolean;
|
|
222
247
|
readonly supportsAcpStdio?: boolean;
|
|
223
248
|
readonly supportsPromptImages?: boolean;
|
|
@@ -252,6 +277,11 @@ export interface RedactionMetadata {
|
|
|
252
277
|
readonly source?: string;
|
|
253
278
|
}
|
|
254
279
|
|
|
280
|
+
export interface WebSearchAttestation {
|
|
281
|
+
readonly requested: boolean;
|
|
282
|
+
readonly effective: boolean;
|
|
283
|
+
}
|
|
284
|
+
|
|
255
285
|
export interface CommandSpec {
|
|
256
286
|
readonly binary: string;
|
|
257
287
|
readonly args: readonly string[];
|
|
@@ -272,6 +302,7 @@ export interface BuildProviderCommandOptions {
|
|
|
272
302
|
readonly autoApprove?: boolean;
|
|
273
303
|
readonly resumeSessionId?: string;
|
|
274
304
|
readonly continueSession?: boolean;
|
|
305
|
+
readonly webSearch?: boolean;
|
|
275
306
|
readonly claudeSettingsFile?: string;
|
|
276
307
|
readonly cliFeatures?: CliFeatureOverrides;
|
|
277
308
|
readonly authEnv?: Readonly<Record<string, string>>;
|
|
@@ -373,7 +404,7 @@ export interface ProviderAdapter {
|
|
|
373
404
|
readonly defaultLevel: ModelLevel;
|
|
374
405
|
readonly defaultMaxLevel: ModelLevel;
|
|
375
406
|
readonly defaultMinLevel: ModelLevel;
|
|
376
|
-
detectCliFeatures(helpText?: string | null): ProviderCliFeatures;
|
|
407
|
+
detectCliFeatures(helpText?: string | null, versionText?: string | null): ProviderCliFeatures;
|
|
377
408
|
buildCommand(context: string, options?: BuildProviderCommandOptions): CommandSpec;
|
|
378
409
|
extractSessionId?(line: string): string | null;
|
|
379
410
|
parseEvent(line: string, state: ProviderParserState): ProviderParseResult;
|