@agentv/core 0.7.3 → 0.7.5

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.
@@ -0,0 +1,645 @@
1
+ // src/evaluation/file-utils.ts
2
+ import { constants } from "node:fs";
3
+ import { access, readFile } from "node:fs/promises";
4
+ import path from "node:path";
5
+ async function fileExists(filePath) {
6
+ try {
7
+ await access(filePath, constants.F_OK);
8
+ return true;
9
+ } catch {
10
+ return false;
11
+ }
12
+ }
13
+ function normalizeLineEndings(content) {
14
+ return content.replace(/\r\n/g, "\n");
15
+ }
16
+ async function readTextFile(filePath) {
17
+ const content = await readFile(filePath, "utf8");
18
+ return normalizeLineEndings(content);
19
+ }
20
+ async function findGitRoot(startPath) {
21
+ let currentDir = path.dirname(path.resolve(startPath));
22
+ const root = path.parse(currentDir).root;
23
+ while (currentDir !== root) {
24
+ const gitPath = path.join(currentDir, ".git");
25
+ if (await fileExists(gitPath)) {
26
+ return currentDir;
27
+ }
28
+ const parentDir = path.dirname(currentDir);
29
+ if (parentDir === currentDir) {
30
+ break;
31
+ }
32
+ currentDir = parentDir;
33
+ }
34
+ return null;
35
+ }
36
+ function buildDirectoryChain(filePath, repoRoot) {
37
+ const directories = [];
38
+ const seen = /* @__PURE__ */ new Set();
39
+ const boundary = path.resolve(repoRoot);
40
+ let current = path.resolve(path.dirname(filePath));
41
+ while (current !== void 0) {
42
+ if (!seen.has(current)) {
43
+ directories.push(current);
44
+ seen.add(current);
45
+ }
46
+ if (current === boundary) {
47
+ break;
48
+ }
49
+ const parent = path.dirname(current);
50
+ if (parent === current) {
51
+ break;
52
+ }
53
+ current = parent;
54
+ }
55
+ if (!seen.has(boundary)) {
56
+ directories.push(boundary);
57
+ }
58
+ return directories;
59
+ }
60
+ function buildSearchRoots(evalPath, repoRoot) {
61
+ const uniqueRoots = [];
62
+ const addRoot = (root) => {
63
+ const normalized = path.resolve(root);
64
+ if (!uniqueRoots.includes(normalized)) {
65
+ uniqueRoots.push(normalized);
66
+ }
67
+ };
68
+ let currentDir = path.dirname(evalPath);
69
+ let reachedBoundary = false;
70
+ while (!reachedBoundary) {
71
+ addRoot(currentDir);
72
+ const parentDir = path.dirname(currentDir);
73
+ if (currentDir === repoRoot || parentDir === currentDir) {
74
+ reachedBoundary = true;
75
+ } else {
76
+ currentDir = parentDir;
77
+ }
78
+ }
79
+ addRoot(repoRoot);
80
+ addRoot(process.cwd());
81
+ return uniqueRoots;
82
+ }
83
+ function trimLeadingSeparators(value) {
84
+ const trimmed = value.replace(/^[/\\]+/, "");
85
+ return trimmed.length > 0 ? trimmed : value;
86
+ }
87
+ async function resolveFileReference(rawValue, searchRoots) {
88
+ const displayPath = trimLeadingSeparators(rawValue);
89
+ const potentialPaths = [];
90
+ if (path.isAbsolute(rawValue)) {
91
+ potentialPaths.push(path.normalize(rawValue));
92
+ }
93
+ for (const base of searchRoots) {
94
+ potentialPaths.push(path.resolve(base, displayPath));
95
+ }
96
+ const attempted = [];
97
+ const seen = /* @__PURE__ */ new Set();
98
+ for (const candidate of potentialPaths) {
99
+ const absoluteCandidate = path.resolve(candidate);
100
+ if (seen.has(absoluteCandidate)) {
101
+ continue;
102
+ }
103
+ seen.add(absoluteCandidate);
104
+ attempted.push(absoluteCandidate);
105
+ if (await fileExists(absoluteCandidate)) {
106
+ return { displayPath, resolvedPath: absoluteCandidate, attempted };
107
+ }
108
+ }
109
+ return { displayPath, attempted };
110
+ }
111
+
112
+ // src/evaluation/providers/targets.ts
113
+ import { z } from "zod";
114
+ var CLI_PLACEHOLDERS = /* @__PURE__ */ new Set(["PROMPT", "GUIDELINES", "EVAL_ID", "ATTEMPT", "FILES", "OUTPUT_FILE"]);
115
+ var BASE_TARGET_SCHEMA = z.object({
116
+ name: z.string().min(1, "target name is required"),
117
+ provider: z.string().min(1, "provider is required"),
118
+ settings: z.record(z.unknown()).optional(),
119
+ judge_target: z.string().optional(),
120
+ workers: z.number().int().min(1).optional()
121
+ });
122
+ var DEFAULT_AZURE_API_VERSION = "2024-10-01-preview";
123
+ function normalizeAzureApiVersion(value) {
124
+ if (!value) {
125
+ return DEFAULT_AZURE_API_VERSION;
126
+ }
127
+ const trimmed = value.trim();
128
+ if (trimmed.length === 0) {
129
+ return DEFAULT_AZURE_API_VERSION;
130
+ }
131
+ const withoutPrefix = trimmed.replace(/^api[-_]?version\s*=\s*/i, "").trim();
132
+ return withoutPrefix.length > 0 ? withoutPrefix : DEFAULT_AZURE_API_VERSION;
133
+ }
134
+ function resolveTargetDefinition(definition, env = process.env) {
135
+ const parsed = BASE_TARGET_SCHEMA.parse(definition);
136
+ const provider = parsed.provider.toLowerCase();
137
+ const providerBatching = resolveOptionalBoolean(
138
+ parsed.settings?.provider_batching ?? parsed.settings?.providerBatching
139
+ );
140
+ switch (provider) {
141
+ case "azure":
142
+ case "azure-openai":
143
+ return {
144
+ kind: "azure",
145
+ name: parsed.name,
146
+ judgeTarget: parsed.judge_target,
147
+ workers: parsed.workers,
148
+ providerBatching,
149
+ config: resolveAzureConfig(parsed, env)
150
+ };
151
+ case "anthropic":
152
+ return {
153
+ kind: "anthropic",
154
+ name: parsed.name,
155
+ judgeTarget: parsed.judge_target,
156
+ workers: parsed.workers,
157
+ providerBatching,
158
+ config: resolveAnthropicConfig(parsed, env)
159
+ };
160
+ case "gemini":
161
+ case "google":
162
+ case "google-gemini":
163
+ return {
164
+ kind: "gemini",
165
+ name: parsed.name,
166
+ judgeTarget: parsed.judge_target,
167
+ workers: parsed.workers,
168
+ providerBatching,
169
+ config: resolveGeminiConfig(parsed, env)
170
+ };
171
+ case "codex":
172
+ case "codex-cli":
173
+ return {
174
+ kind: "codex",
175
+ name: parsed.name,
176
+ judgeTarget: parsed.judge_target,
177
+ workers: parsed.workers,
178
+ providerBatching,
179
+ config: resolveCodexConfig(parsed, env)
180
+ };
181
+ case "mock":
182
+ return {
183
+ kind: "mock",
184
+ name: parsed.name,
185
+ judgeTarget: parsed.judge_target,
186
+ workers: parsed.workers,
187
+ providerBatching,
188
+ config: resolveMockConfig(parsed)
189
+ };
190
+ case "vscode":
191
+ case "vscode-insiders":
192
+ return {
193
+ kind: provider,
194
+ name: parsed.name,
195
+ judgeTarget: parsed.judge_target,
196
+ workers: parsed.workers,
197
+ providerBatching,
198
+ config: resolveVSCodeConfig(parsed, env, provider === "vscode-insiders")
199
+ };
200
+ case "cli":
201
+ return {
202
+ kind: "cli",
203
+ name: parsed.name,
204
+ judgeTarget: parsed.judge_target,
205
+ workers: parsed.workers,
206
+ providerBatching,
207
+ config: resolveCliConfig(parsed, env)
208
+ };
209
+ default:
210
+ throw new Error(`Unsupported provider '${parsed.provider}' in target '${parsed.name}'`);
211
+ }
212
+ }
213
+ function resolveAzureConfig(target, env) {
214
+ const settings = target.settings ?? {};
215
+ const endpointSource = settings.endpoint ?? settings.resource ?? settings.resourceName;
216
+ const apiKeySource = settings.api_key ?? settings.apiKey;
217
+ const deploymentSource = settings.deployment ?? settings.deploymentName ?? settings.model;
218
+ const versionSource = settings.version ?? settings.api_version;
219
+ const temperatureSource = settings.temperature;
220
+ const maxTokensSource = settings.max_output_tokens ?? settings.maxTokens;
221
+ const resourceName = resolveString(endpointSource, env, `${target.name} endpoint`);
222
+ const apiKey = resolveString(apiKeySource, env, `${target.name} api key`);
223
+ const deploymentName = resolveString(deploymentSource, env, `${target.name} deployment`);
224
+ const version = normalizeAzureApiVersion(
225
+ resolveOptionalString(versionSource, env, `${target.name} api version`)
226
+ );
227
+ const temperature = resolveOptionalNumber(temperatureSource, `${target.name} temperature`);
228
+ const maxOutputTokens = resolveOptionalNumber(
229
+ maxTokensSource,
230
+ `${target.name} max output tokens`
231
+ );
232
+ return {
233
+ resourceName,
234
+ deploymentName,
235
+ apiKey,
236
+ version,
237
+ temperature,
238
+ maxOutputTokens
239
+ };
240
+ }
241
+ function resolveAnthropicConfig(target, env) {
242
+ const settings = target.settings ?? {};
243
+ const apiKeySource = settings.api_key ?? settings.apiKey;
244
+ const modelSource = settings.model ?? settings.deployment ?? settings.variant;
245
+ const temperatureSource = settings.temperature;
246
+ const maxTokensSource = settings.max_output_tokens ?? settings.maxTokens;
247
+ const thinkingBudgetSource = settings.thinking_budget ?? settings.thinkingBudget;
248
+ const apiKey = resolveString(apiKeySource, env, `${target.name} Anthropic api key`);
249
+ const model = resolveString(modelSource, env, `${target.name} Anthropic model`);
250
+ return {
251
+ apiKey,
252
+ model,
253
+ temperature: resolveOptionalNumber(temperatureSource, `${target.name} temperature`),
254
+ maxOutputTokens: resolveOptionalNumber(maxTokensSource, `${target.name} max output tokens`),
255
+ thinkingBudget: resolveOptionalNumber(thinkingBudgetSource, `${target.name} thinking budget`)
256
+ };
257
+ }
258
+ function resolveGeminiConfig(target, env) {
259
+ const settings = target.settings ?? {};
260
+ const apiKeySource = settings.api_key ?? settings.apiKey;
261
+ const modelSource = settings.model ?? settings.deployment ?? settings.variant;
262
+ const temperatureSource = settings.temperature;
263
+ const maxTokensSource = settings.max_output_tokens ?? settings.maxTokens;
264
+ const apiKey = resolveString(apiKeySource, env, `${target.name} Google API key`);
265
+ const model = resolveOptionalString(modelSource, env, `${target.name} Gemini model`, {
266
+ allowLiteral: true,
267
+ optionalEnv: true
268
+ }) ?? "gemini-2.5-flash";
269
+ return {
270
+ apiKey,
271
+ model,
272
+ temperature: resolveOptionalNumber(temperatureSource, `${target.name} temperature`),
273
+ maxOutputTokens: resolveOptionalNumber(maxTokensSource, `${target.name} max output tokens`)
274
+ };
275
+ }
276
+ function resolveCodexConfig(target, env) {
277
+ const settings = target.settings ?? {};
278
+ const executableSource = settings.executable ?? settings.command ?? settings.binary;
279
+ const argsSource = settings.args ?? settings.arguments;
280
+ const cwdSource = settings.cwd;
281
+ const timeoutSource = settings.timeout_seconds ?? settings.timeoutSeconds;
282
+ const logDirSource = settings.log_dir ?? settings.logDir ?? settings.log_directory ?? settings.logDirectory;
283
+ const logFormatSource = settings.log_format ?? settings.logFormat ?? settings.log_output_format ?? settings.logOutputFormat ?? env.AGENTV_CODEX_LOG_FORMAT;
284
+ const executable = resolveOptionalString(executableSource, env, `${target.name} codex executable`, {
285
+ allowLiteral: true,
286
+ optionalEnv: true
287
+ }) ?? "codex";
288
+ const args = resolveOptionalStringArray(argsSource, env, `${target.name} codex args`);
289
+ const cwd = resolveOptionalString(cwdSource, env, `${target.name} codex cwd`, {
290
+ allowLiteral: true,
291
+ optionalEnv: true
292
+ });
293
+ const timeoutMs = resolveTimeoutMs(timeoutSource, `${target.name} codex timeout`);
294
+ const logDir = resolveOptionalString(logDirSource, env, `${target.name} codex log directory`, {
295
+ allowLiteral: true,
296
+ optionalEnv: true
297
+ });
298
+ const logFormat = normalizeCodexLogFormat(logFormatSource);
299
+ return {
300
+ executable,
301
+ args,
302
+ cwd,
303
+ timeoutMs,
304
+ logDir,
305
+ logFormat
306
+ };
307
+ }
308
+ function normalizeCodexLogFormat(value) {
309
+ if (value === void 0 || value === null) {
310
+ return void 0;
311
+ }
312
+ if (typeof value !== "string") {
313
+ throw new Error("codex log format must be 'summary' or 'json'");
314
+ }
315
+ const normalized = value.trim().toLowerCase();
316
+ if (normalized === "json" || normalized === "summary") {
317
+ return normalized;
318
+ }
319
+ throw new Error("codex log format must be 'summary' or 'json'");
320
+ }
321
+ function resolveMockConfig(target) {
322
+ const settings = target.settings ?? {};
323
+ const response = typeof settings.response === "string" ? settings.response : void 0;
324
+ return { response };
325
+ }
326
+ function resolveVSCodeConfig(target, env, insiders) {
327
+ const settings = target.settings ?? {};
328
+ const workspaceTemplateEnvVar = resolveOptionalLiteralString(settings.workspace_template ?? settings.workspaceTemplate);
329
+ const workspaceTemplate = workspaceTemplateEnvVar ? resolveOptionalString(workspaceTemplateEnvVar, env, `${target.name} workspace template path`, {
330
+ allowLiteral: false,
331
+ optionalEnv: true
332
+ }) : void 0;
333
+ const commandSource = settings.vscode_cmd ?? settings.command;
334
+ const waitSource = settings.wait;
335
+ const dryRunSource = settings.dry_run ?? settings.dryRun;
336
+ const subagentRootSource = settings.subagent_root ?? settings.subagentRoot;
337
+ const defaultCommand = insiders ? "code-insiders" : "code";
338
+ const command = resolveOptionalLiteralString(commandSource) ?? defaultCommand;
339
+ return {
340
+ command,
341
+ waitForResponse: resolveOptionalBoolean(waitSource) ?? true,
342
+ dryRun: resolveOptionalBoolean(dryRunSource) ?? false,
343
+ subagentRoot: resolveOptionalString(subagentRootSource, env, `${target.name} subagent root`, {
344
+ allowLiteral: true,
345
+ optionalEnv: true
346
+ }),
347
+ workspaceTemplate
348
+ };
349
+ }
350
+ function resolveCliConfig(target, env) {
351
+ const settings = target.settings ?? {};
352
+ const commandTemplateSource = settings.command_template ?? settings.commandTemplate;
353
+ const filesFormat = resolveOptionalLiteralString(
354
+ settings.files_format ?? settings.filesFormat ?? settings.attachments_format ?? settings.attachmentsFormat
355
+ );
356
+ const cwd = resolveOptionalString(settings.cwd, env, `${target.name} working directory`, {
357
+ allowLiteral: true,
358
+ optionalEnv: true
359
+ });
360
+ const envOverrides = resolveEnvOverrides(settings.env, env, target.name);
361
+ const timeoutMs = resolveTimeoutMs(settings.timeout_seconds ?? settings.timeoutSeconds, `${target.name} timeout`);
362
+ const healthcheck = resolveCliHealthcheck(settings.healthcheck, env, target.name);
363
+ const commandTemplate = resolveString(
364
+ commandTemplateSource,
365
+ env,
366
+ `${target.name} CLI command template`,
367
+ true
368
+ );
369
+ assertSupportedCliPlaceholders(commandTemplate, `${target.name} CLI command template`);
370
+ return {
371
+ commandTemplate,
372
+ filesFormat,
373
+ cwd,
374
+ env: envOverrides,
375
+ timeoutMs,
376
+ healthcheck
377
+ };
378
+ }
379
+ function resolveEnvOverrides(source, env, targetName) {
380
+ if (source === void 0 || source === null) {
381
+ return void 0;
382
+ }
383
+ if (typeof source !== "object" || Array.isArray(source)) {
384
+ throw new Error(`${targetName} env overrides must be an object map of strings`);
385
+ }
386
+ const entries = Object.entries(source);
387
+ const resolved = {};
388
+ for (const [key, value] of entries) {
389
+ if (typeof value !== "string") {
390
+ throw new Error(`${targetName} env override '${key}' must be a string`);
391
+ }
392
+ const resolvedValue = resolveString(value, env, `${targetName} env override '${key}'`);
393
+ resolved[key] = resolvedValue;
394
+ }
395
+ return Object.keys(resolved).length > 0 ? resolved : void 0;
396
+ }
397
+ function resolveTimeoutMs(source, description) {
398
+ const seconds = resolveOptionalNumber(source, `${description} (seconds)`);
399
+ if (seconds === void 0) {
400
+ return void 0;
401
+ }
402
+ if (seconds <= 0) {
403
+ throw new Error(`${description} must be greater than zero seconds`);
404
+ }
405
+ return Math.floor(seconds * 1e3);
406
+ }
407
+ function resolveCliHealthcheck(source, env, targetName) {
408
+ if (source === void 0 || source === null) {
409
+ return void 0;
410
+ }
411
+ if (typeof source !== "object" || Array.isArray(source)) {
412
+ throw new Error(`${targetName} healthcheck must be an object`);
413
+ }
414
+ const candidate = source;
415
+ const type = candidate.type;
416
+ const timeoutMs = resolveTimeoutMs(
417
+ candidate.timeout_seconds ?? candidate.timeoutSeconds,
418
+ `${targetName} healthcheck timeout`
419
+ );
420
+ if (type === "http") {
421
+ const url = resolveString(candidate.url, env, `${targetName} healthcheck URL`);
422
+ return {
423
+ type: "http",
424
+ url,
425
+ timeoutMs
426
+ };
427
+ }
428
+ if (type === "command") {
429
+ const commandTemplate = resolveString(
430
+ candidate.command_template ?? candidate.commandTemplate,
431
+ env,
432
+ `${targetName} healthcheck command template`,
433
+ true
434
+ );
435
+ assertSupportedCliPlaceholders(commandTemplate, `${targetName} healthcheck command template`);
436
+ const cwd = resolveOptionalString(candidate.cwd, env, `${targetName} healthcheck cwd`, {
437
+ allowLiteral: true,
438
+ optionalEnv: true
439
+ });
440
+ return {
441
+ type: "command",
442
+ commandTemplate,
443
+ timeoutMs,
444
+ cwd
445
+ };
446
+ }
447
+ throw new Error(`${targetName} healthcheck type must be 'http' or 'command'`);
448
+ }
449
+ function assertSupportedCliPlaceholders(template, description) {
450
+ const placeholders = extractCliPlaceholders(template);
451
+ for (const placeholder of placeholders) {
452
+ if (!CLI_PLACEHOLDERS.has(placeholder)) {
453
+ throw new Error(
454
+ `${description} includes unsupported placeholder '{${placeholder}}'. Supported placeholders: ${Array.from(CLI_PLACEHOLDERS).join(", ")}`
455
+ );
456
+ }
457
+ }
458
+ }
459
+ function extractCliPlaceholders(template) {
460
+ const matches = template.matchAll(/\{([A-Z_]+)\}/g);
461
+ const results = [];
462
+ for (const match of matches) {
463
+ if (match[1]) {
464
+ results.push(match[1]);
465
+ }
466
+ }
467
+ return results;
468
+ }
469
+ function resolveString(source, env, description, allowLiteral = false) {
470
+ const value = resolveOptionalString(source, env, description, {
471
+ allowLiteral,
472
+ optionalEnv: false
473
+ });
474
+ if (value === void 0) {
475
+ throw new Error(`${description} is required`);
476
+ }
477
+ return value;
478
+ }
479
+ function resolveOptionalString(source, env, description, options) {
480
+ if (source === void 0 || source === null) {
481
+ return void 0;
482
+ }
483
+ if (typeof source !== "string") {
484
+ throw new Error(`${description} must be a string`);
485
+ }
486
+ const trimmed = source.trim();
487
+ if (trimmed.length === 0) {
488
+ return void 0;
489
+ }
490
+ const envVarMatch = trimmed.match(/^\$\{\{\s*([A-Z0-9_]+)\s*\}\}$/i);
491
+ if (envVarMatch) {
492
+ const varName = envVarMatch[1];
493
+ const envValue = env[varName];
494
+ if (envValue !== void 0) {
495
+ if (envValue.trim().length === 0) {
496
+ throw new Error(`Environment variable '${varName}' for ${description} is empty`);
497
+ }
498
+ return envValue;
499
+ }
500
+ const optionalEnv = options?.optionalEnv ?? false;
501
+ if (optionalEnv) {
502
+ return void 0;
503
+ }
504
+ throw new Error(`Environment variable '${varName}' required for ${description} is not set`);
505
+ }
506
+ const allowLiteral = options?.allowLiteral ?? false;
507
+ if (!allowLiteral) {
508
+ throw new Error(`${description} must use \${{ VARIABLE_NAME }} syntax for environment variables or be marked as allowing literals`);
509
+ }
510
+ return trimmed;
511
+ }
512
+ function resolveOptionalLiteralString(source) {
513
+ if (source === void 0 || source === null) {
514
+ return void 0;
515
+ }
516
+ if (typeof source !== "string") {
517
+ throw new Error("expected string value");
518
+ }
519
+ const trimmed = source.trim();
520
+ return trimmed.length > 0 ? trimmed : void 0;
521
+ }
522
+ function resolveOptionalNumber(source, description) {
523
+ if (source === void 0 || source === null || source === "") {
524
+ return void 0;
525
+ }
526
+ if (typeof source === "number") {
527
+ return Number.isFinite(source) ? source : void 0;
528
+ }
529
+ if (typeof source === "string") {
530
+ const numeric = Number(source);
531
+ if (Number.isFinite(numeric)) {
532
+ return numeric;
533
+ }
534
+ }
535
+ throw new Error(`${description} must be a number`);
536
+ }
537
+ function resolveOptionalBoolean(source) {
538
+ if (source === void 0 || source === null || source === "") {
539
+ return void 0;
540
+ }
541
+ if (typeof source === "boolean") {
542
+ return source;
543
+ }
544
+ if (typeof source === "string") {
545
+ const lowered = source.trim().toLowerCase();
546
+ if (lowered === "true" || lowered === "1") {
547
+ return true;
548
+ }
549
+ if (lowered === "false" || lowered === "0") {
550
+ return false;
551
+ }
552
+ }
553
+ throw new Error("expected boolean value");
554
+ }
555
+ function resolveOptionalStringArray(source, env, description) {
556
+ if (source === void 0 || source === null) {
557
+ return void 0;
558
+ }
559
+ if (!Array.isArray(source)) {
560
+ throw new Error(`${description} must be an array of strings`);
561
+ }
562
+ if (source.length === 0) {
563
+ return void 0;
564
+ }
565
+ const resolved = [];
566
+ for (let i = 0; i < source.length; i++) {
567
+ const item = source[i];
568
+ if (typeof item !== "string") {
569
+ throw new Error(`${description}[${i}] must be a string`);
570
+ }
571
+ const trimmed = item.trim();
572
+ if (trimmed.length === 0) {
573
+ throw new Error(`${description}[${i}] cannot be empty`);
574
+ }
575
+ const envVarMatch = trimmed.match(/^\$\{\{\s*([A-Z0-9_]+)\s*\}\}$/i);
576
+ if (envVarMatch) {
577
+ const varName = envVarMatch[1];
578
+ const envValue = env[varName];
579
+ if (envValue !== void 0) {
580
+ if (envValue.trim().length === 0) {
581
+ throw new Error(`Environment variable '${varName}' for ${description}[${i}] is empty`);
582
+ }
583
+ resolved.push(envValue);
584
+ continue;
585
+ }
586
+ throw new Error(`Environment variable '${varName}' for ${description}[${i}] is not set`);
587
+ }
588
+ resolved.push(trimmed);
589
+ }
590
+ return resolved.length > 0 ? resolved : void 0;
591
+ }
592
+
593
+ // src/evaluation/providers/types.ts
594
+ var AGENT_PROVIDER_KINDS = [
595
+ "codex",
596
+ "vscode",
597
+ "vscode-insiders"
598
+ ];
599
+ var KNOWN_PROVIDERS = [
600
+ "azure",
601
+ "anthropic",
602
+ "gemini",
603
+ "codex",
604
+ "cli",
605
+ "mock",
606
+ "vscode",
607
+ "vscode-insiders"
608
+ ];
609
+ var PROVIDER_ALIASES = [
610
+ "azure-openai",
611
+ // alias for "azure"
612
+ "google",
613
+ // alias for "gemini"
614
+ "google-gemini",
615
+ // alias for "gemini"
616
+ "codex-cli",
617
+ // alias for "codex"
618
+ "openai",
619
+ // legacy/future support
620
+ "bedrock",
621
+ // legacy/future support
622
+ "vertex"
623
+ // legacy/future support
624
+ ];
625
+ var TARGETS_SCHEMA_V2 = "agentv-targets-v2.1";
626
+ function isAgentProvider(provider) {
627
+ return provider ? AGENT_PROVIDER_KINDS.includes(provider.kind) : false;
628
+ }
629
+
630
+ export {
631
+ fileExists,
632
+ normalizeLineEndings,
633
+ readTextFile,
634
+ findGitRoot,
635
+ buildDirectoryChain,
636
+ buildSearchRoots,
637
+ resolveFileReference,
638
+ CLI_PLACEHOLDERS,
639
+ resolveTargetDefinition,
640
+ KNOWN_PROVIDERS,
641
+ PROVIDER_ALIASES,
642
+ TARGETS_SCHEMA_V2,
643
+ isAgentProvider
644
+ };
645
+ //# sourceMappingURL=chunk-7XM7HYRS.js.map