agentv 0.2.11 → 0.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.
- package/README.md +141 -45
- package/dist/{chunk-7MGIZBZG.js → chunk-THVRLL37.js} +1692 -371
- package/dist/chunk-THVRLL37.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-7MGIZBZG.js.map +0 -1
- package/dist/chunk-JT3E7T7V.js +0 -14744
- package/dist/chunk-JT3E7T7V.js.map +0 -1
|
@@ -585,7 +585,7 @@ var require_utc = __commonJS({
|
|
|
585
585
|
import { Command } from "commander";
|
|
586
586
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
587
587
|
|
|
588
|
-
// ../../packages/core/dist/chunk-
|
|
588
|
+
// ../../packages/core/dist/chunk-NL7K4CAK.js
|
|
589
589
|
import { constants } from "node:fs";
|
|
590
590
|
import { access } from "node:fs/promises";
|
|
591
591
|
import path from "node:path";
|
|
@@ -692,6 +692,8 @@ var KNOWN_PROVIDERS = [
|
|
|
692
692
|
"azure",
|
|
693
693
|
"anthropic",
|
|
694
694
|
"gemini",
|
|
695
|
+
"codex",
|
|
696
|
+
"cli",
|
|
695
697
|
"mock",
|
|
696
698
|
"vscode",
|
|
697
699
|
"vscode-insiders"
|
|
@@ -703,6 +705,8 @@ var PROVIDER_ALIASES = [
|
|
|
703
705
|
// alias for "gemini"
|
|
704
706
|
"google-gemini",
|
|
705
707
|
// alias for "gemini"
|
|
708
|
+
"codex-cli",
|
|
709
|
+
// alias for "codex"
|
|
706
710
|
"openai",
|
|
707
711
|
// legacy/future support
|
|
708
712
|
"bedrock",
|
|
@@ -5031,6 +5035,11 @@ var _c = pr();
|
|
|
5031
5035
|
var ya = new Error("Agent description must be at least 20 characters (explain in detail what the agent does)");
|
|
5032
5036
|
var ba = new Error("Agent definition is the prompt you give to the LLM for the agent. It must be detailed and at least 100 characters");
|
|
5033
5037
|
|
|
5038
|
+
// ../../packages/core/dist/index.js
|
|
5039
|
+
import { exec as execWithCallback } from "node:child_process";
|
|
5040
|
+
import path22 from "node:path";
|
|
5041
|
+
import { promisify as promisify2 } from "node:util";
|
|
5042
|
+
|
|
5034
5043
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
|
|
5035
5044
|
var external_exports = {};
|
|
5036
5045
|
__export(external_exports, {
|
|
@@ -9074,7 +9083,7 @@ var NEVER = INVALID;
|
|
|
9074
9083
|
|
|
9075
9084
|
// ../../packages/core/dist/index.js
|
|
9076
9085
|
import { readFile as readFile22 } from "node:fs/promises";
|
|
9077
|
-
import
|
|
9086
|
+
import path32 from "node:path";
|
|
9078
9087
|
|
|
9079
9088
|
// ../../node_modules/.pnpm/subagent@0.4.6/node_modules/subagent/dist/vscode/agentDispatch.js
|
|
9080
9089
|
import { exec, spawn } from "child_process";
|
|
@@ -11012,14 +11021,21 @@ async function provisionSubagents(options) {
|
|
|
11012
11021
|
}
|
|
11013
11022
|
|
|
11014
11023
|
// ../../packages/core/dist/index.js
|
|
11024
|
+
import { exec as execCallback, spawn as spawn2 } from "node:child_process";
|
|
11015
11025
|
import { constants as constants22 } from "node:fs";
|
|
11016
|
-
import { access as access22,
|
|
11017
|
-
import
|
|
11026
|
+
import { access as access22, copyFile as copyFile2, mkdtemp, mkdir as mkdir3, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
|
|
11027
|
+
import { tmpdir } from "node:os";
|
|
11028
|
+
import path52 from "node:path";
|
|
11029
|
+
import { promisify as promisify22 } from "node:util";
|
|
11030
|
+
import path42 from "node:path";
|
|
11031
|
+
import { constants as constants32 } from "node:fs";
|
|
11032
|
+
import { access as access32, readFile as readFile3 } from "node:fs/promises";
|
|
11033
|
+
import path62 from "node:path";
|
|
11018
11034
|
import { parse as parse22 } from "yaml";
|
|
11019
11035
|
import { randomUUID } from "node:crypto";
|
|
11020
11036
|
import { createHash, randomUUID as randomUUID2 } from "node:crypto";
|
|
11021
|
-
import { mkdir as
|
|
11022
|
-
import
|
|
11037
|
+
import { mkdir as mkdir22, readFile as readFile4, writeFile as writeFile22 } from "node:fs/promises";
|
|
11038
|
+
import path72 from "node:path";
|
|
11023
11039
|
var TEST_MESSAGE_ROLE_VALUES = ["system", "user", "assistant", "tool"];
|
|
11024
11040
|
var TEST_MESSAGE_ROLE_SET = new Set(TEST_MESSAGE_ROLE_VALUES);
|
|
11025
11041
|
function isTestMessageRole(value) {
|
|
@@ -11059,10 +11075,10 @@ function isTestMessage(value) {
|
|
|
11059
11075
|
}
|
|
11060
11076
|
return candidate.content.every(isJsonObject);
|
|
11061
11077
|
}
|
|
11062
|
-
var
|
|
11063
|
-
var
|
|
11064
|
-
function
|
|
11065
|
-
return typeof value === "string" &&
|
|
11078
|
+
var EVALUATOR_KIND_VALUES = ["code", "llm_judge"];
|
|
11079
|
+
var EVALUATOR_KIND_SET = new Set(EVALUATOR_KIND_VALUES);
|
|
11080
|
+
function isEvaluatorKind(value) {
|
|
11081
|
+
return typeof value === "string" && EVALUATOR_KIND_SET.has(value);
|
|
11066
11082
|
}
|
|
11067
11083
|
var CODE_BLOCK_PATTERN = /```[\s\S]*?```/g;
|
|
11068
11084
|
var ANSI_YELLOW = "\x1B[33m";
|
|
@@ -11159,7 +11175,7 @@ Please add '$schema: ${SCHEMA_EVAL_V2}' at the top of the file.`;
|
|
|
11159
11175
|
if (!Array.isArray(rawTestcases)) {
|
|
11160
11176
|
throw new Error(`Invalid test file format: ${evalFilePath} - missing 'evalcases' field`);
|
|
11161
11177
|
}
|
|
11162
|
-
const
|
|
11178
|
+
const globalEvaluator = coerceEvaluator(suite.evaluator, "global") ?? "llm_judge";
|
|
11163
11179
|
const results = [];
|
|
11164
11180
|
for (const rawEvalcase of rawTestcases) {
|
|
11165
11181
|
if (!isJsonObject(rawEvalcase)) {
|
|
@@ -11282,7 +11298,8 @@ Please add '$schema: ${SCHEMA_EVAL_V2}' at the top of the file.`;
|
|
|
11282
11298
|
const assistantContent = assistantMessages[0]?.content;
|
|
11283
11299
|
const expectedAssistantRaw = await resolveAssistantContent(assistantContent, searchRoots, verbose);
|
|
11284
11300
|
const userTextPrompt = userTextParts.map((part) => part.trim()).filter((part) => part.length > 0).join(" ");
|
|
11285
|
-
const
|
|
11301
|
+
const testCaseEvaluatorKind = coerceEvaluator(evalcase.evaluator, id) ?? globalEvaluator;
|
|
11302
|
+
const evaluators = await parseEvaluators(evalcase, searchRoots, id ?? "unknown");
|
|
11286
11303
|
const userFilePaths = [];
|
|
11287
11304
|
for (const segment of userSegments) {
|
|
11288
11305
|
if (segment.type === "file" && typeof segment.resolvedPath === "string") {
|
|
@@ -11305,7 +11322,8 @@ Please add '$schema: ${SCHEMA_EVAL_V2}' at the top of the file.`;
|
|
|
11305
11322
|
file_paths: allFilePaths,
|
|
11306
11323
|
code_snippets: codeSnippets,
|
|
11307
11324
|
outcome,
|
|
11308
|
-
|
|
11325
|
+
evaluator: testCaseEvaluatorKind,
|
|
11326
|
+
evaluators
|
|
11309
11327
|
};
|
|
11310
11328
|
if (verbose) {
|
|
11311
11329
|
console.log(`
|
|
@@ -11466,14 +11484,88 @@ async function resolveAssistantContent(content, searchRoots, verbose) {
|
|
|
11466
11484
|
}
|
|
11467
11485
|
return parts.join(" ");
|
|
11468
11486
|
}
|
|
11469
|
-
function
|
|
11487
|
+
async function parseEvaluators(rawEvalCase, searchRoots, evalId) {
|
|
11488
|
+
const execution = rawEvalCase.execution;
|
|
11489
|
+
const candidateEvaluators = isJsonObject(execution) ? execution.evaluators ?? rawEvalCase.evaluators : rawEvalCase.evaluators;
|
|
11490
|
+
if (candidateEvaluators === void 0) {
|
|
11491
|
+
return void 0;
|
|
11492
|
+
}
|
|
11493
|
+
if (!Array.isArray(candidateEvaluators)) {
|
|
11494
|
+
logWarning(`Skipping evaluators for '${evalId}': expected array`);
|
|
11495
|
+
return void 0;
|
|
11496
|
+
}
|
|
11497
|
+
const evaluators = [];
|
|
11498
|
+
for (const rawEvaluator of candidateEvaluators) {
|
|
11499
|
+
if (!isJsonObject(rawEvaluator)) {
|
|
11500
|
+
logWarning(`Skipping invalid evaluator entry for '${evalId}' (expected object)`);
|
|
11501
|
+
continue;
|
|
11502
|
+
}
|
|
11503
|
+
const name = asString(rawEvaluator.name);
|
|
11504
|
+
const typeValue = rawEvaluator.type;
|
|
11505
|
+
if (!name || !isEvaluatorKind(typeValue)) {
|
|
11506
|
+
logWarning(`Skipping evaluator with invalid name/type in '${evalId}'`);
|
|
11507
|
+
continue;
|
|
11508
|
+
}
|
|
11509
|
+
if (typeValue === "code") {
|
|
11510
|
+
const script = asString(rawEvaluator.script);
|
|
11511
|
+
if (!script) {
|
|
11512
|
+
logWarning(`Skipping code evaluator '${name}' in '${evalId}': missing script`);
|
|
11513
|
+
continue;
|
|
11514
|
+
}
|
|
11515
|
+
const cwd = asString(rawEvaluator.cwd);
|
|
11516
|
+
let resolvedCwd;
|
|
11517
|
+
if (cwd) {
|
|
11518
|
+
const resolved = await resolveFileReference(cwd, searchRoots);
|
|
11519
|
+
if (resolved.resolvedPath) {
|
|
11520
|
+
resolvedCwd = path8.resolve(resolved.resolvedPath);
|
|
11521
|
+
} else {
|
|
11522
|
+
logWarning(
|
|
11523
|
+
`Code evaluator '${name}' in '${evalId}': cwd not found (${resolved.displayPath})`,
|
|
11524
|
+
resolved.attempted.length > 0 ? resolved.attempted.map((attempt) => ` Tried: ${attempt}`) : void 0
|
|
11525
|
+
);
|
|
11526
|
+
}
|
|
11527
|
+
}
|
|
11528
|
+
evaluators.push({
|
|
11529
|
+
name,
|
|
11530
|
+
type: "code",
|
|
11531
|
+
script,
|
|
11532
|
+
cwd,
|
|
11533
|
+
resolvedCwd
|
|
11534
|
+
});
|
|
11535
|
+
continue;
|
|
11536
|
+
}
|
|
11537
|
+
const prompt = asString(rawEvaluator.prompt);
|
|
11538
|
+
let promptPath;
|
|
11539
|
+
if (prompt) {
|
|
11540
|
+
const resolved = await resolveFileReference(prompt, searchRoots);
|
|
11541
|
+
if (resolved.resolvedPath) {
|
|
11542
|
+
promptPath = path8.resolve(resolved.resolvedPath);
|
|
11543
|
+
} else {
|
|
11544
|
+
logWarning(
|
|
11545
|
+
`Inline prompt used for evaluator '${name}' in '${evalId}' (file not found: ${resolved.displayPath})`,
|
|
11546
|
+
resolved.attempted.length > 0 ? resolved.attempted.map((attempt) => ` Tried: ${attempt}`) : void 0
|
|
11547
|
+
);
|
|
11548
|
+
}
|
|
11549
|
+
}
|
|
11550
|
+
const model = asString(rawEvaluator.model);
|
|
11551
|
+
evaluators.push({
|
|
11552
|
+
name,
|
|
11553
|
+
type: "llm_judge",
|
|
11554
|
+
prompt,
|
|
11555
|
+
promptPath,
|
|
11556
|
+
model
|
|
11557
|
+
});
|
|
11558
|
+
}
|
|
11559
|
+
return evaluators.length > 0 ? evaluators : void 0;
|
|
11560
|
+
}
|
|
11561
|
+
function coerceEvaluator(candidate, contextId) {
|
|
11470
11562
|
if (typeof candidate !== "string") {
|
|
11471
11563
|
return void 0;
|
|
11472
11564
|
}
|
|
11473
|
-
if (
|
|
11565
|
+
if (isEvaluatorKind(candidate)) {
|
|
11474
11566
|
return candidate;
|
|
11475
11567
|
}
|
|
11476
|
-
logWarning(`Unknown
|
|
11568
|
+
logWarning(`Unknown evaluator '${candidate}' in ${contextId}, falling back to default`);
|
|
11477
11569
|
return void 0;
|
|
11478
11570
|
}
|
|
11479
11571
|
function logWarning(message, details) {
|
|
@@ -11665,6 +11757,209 @@ var GeminiProvider = class {
|
|
|
11665
11757
|
return mapResponse(ensureChatResponse(response));
|
|
11666
11758
|
}
|
|
11667
11759
|
};
|
|
11760
|
+
var execAsync2 = promisify2(execWithCallback);
|
|
11761
|
+
var DEFAULT_MAX_BUFFER = 10 * 1024 * 1024;
|
|
11762
|
+
async function defaultCommandRunner(command, options) {
|
|
11763
|
+
const execOptions = {
|
|
11764
|
+
cwd: options.cwd,
|
|
11765
|
+
env: options.env,
|
|
11766
|
+
timeout: options.timeoutMs,
|
|
11767
|
+
signal: options.signal,
|
|
11768
|
+
maxBuffer: DEFAULT_MAX_BUFFER,
|
|
11769
|
+
shell: process.platform === "win32" ? "powershell.exe" : void 0
|
|
11770
|
+
};
|
|
11771
|
+
try {
|
|
11772
|
+
const { stdout, stderr } = await execAsync2(command, execOptions);
|
|
11773
|
+
return {
|
|
11774
|
+
stdout,
|
|
11775
|
+
stderr,
|
|
11776
|
+
exitCode: 0,
|
|
11777
|
+
failed: false,
|
|
11778
|
+
timedOut: false,
|
|
11779
|
+
signal: null
|
|
11780
|
+
};
|
|
11781
|
+
} catch (error) {
|
|
11782
|
+
const execError = error;
|
|
11783
|
+
return {
|
|
11784
|
+
stdout: execError.stdout ?? "",
|
|
11785
|
+
stderr: execError.stderr ?? "",
|
|
11786
|
+
exitCode: typeof execError.code === "number" ? execError.code : null,
|
|
11787
|
+
failed: true,
|
|
11788
|
+
timedOut: execError.timedOut === true || execError.killed === true,
|
|
11789
|
+
signal: execError.signal ?? null
|
|
11790
|
+
};
|
|
11791
|
+
}
|
|
11792
|
+
}
|
|
11793
|
+
var CliProvider = class {
|
|
11794
|
+
id;
|
|
11795
|
+
kind = "cli";
|
|
11796
|
+
targetName;
|
|
11797
|
+
supportsBatch = false;
|
|
11798
|
+
config;
|
|
11799
|
+
runCommand;
|
|
11800
|
+
healthcheckPromise;
|
|
11801
|
+
constructor(targetName, config, runner = defaultCommandRunner) {
|
|
11802
|
+
this.targetName = targetName;
|
|
11803
|
+
this.id = `cli:${targetName}`;
|
|
11804
|
+
this.config = config;
|
|
11805
|
+
this.runCommand = runner;
|
|
11806
|
+
}
|
|
11807
|
+
async invoke(request) {
|
|
11808
|
+
if (request.signal?.aborted) {
|
|
11809
|
+
throw new Error("CLI provider request was aborted before execution");
|
|
11810
|
+
}
|
|
11811
|
+
await this.ensureHealthy(request.signal);
|
|
11812
|
+
const templateValues = buildTemplateValues(request, this.config);
|
|
11813
|
+
const renderedCommand = renderTemplate(this.config.commandTemplate, templateValues);
|
|
11814
|
+
const env = this.config.env ? { ...process.env, ...this.config.env } : process.env;
|
|
11815
|
+
const result = await this.runCommand(renderedCommand, {
|
|
11816
|
+
cwd: this.config.cwd,
|
|
11817
|
+
env,
|
|
11818
|
+
timeoutMs: this.config.timeoutMs,
|
|
11819
|
+
signal: request.signal
|
|
11820
|
+
});
|
|
11821
|
+
if (result.failed || (result.exitCode ?? 0) !== 0) {
|
|
11822
|
+
if (request.signal?.aborted) {
|
|
11823
|
+
throw new Error("CLI provider request was aborted");
|
|
11824
|
+
}
|
|
11825
|
+
if (result.timedOut) {
|
|
11826
|
+
throw new Error(
|
|
11827
|
+
`CLI provider timed out${formatTimeoutSuffix(this.config.timeoutMs ?? void 0)}`
|
|
11828
|
+
);
|
|
11829
|
+
}
|
|
11830
|
+
const codeText = result.exitCode !== null ? result.exitCode : "unknown";
|
|
11831
|
+
const detail = result.stderr.trim() || result.stdout.trim();
|
|
11832
|
+
const message = detail ? `${detail} (exit code ${codeText})` : `CLI exited with code ${codeText}`;
|
|
11833
|
+
throw new Error(message);
|
|
11834
|
+
}
|
|
11835
|
+
return {
|
|
11836
|
+
text: result.stdout,
|
|
11837
|
+
raw: {
|
|
11838
|
+
command: renderedCommand,
|
|
11839
|
+
stderr: result.stderr,
|
|
11840
|
+
exitCode: result.exitCode ?? 0,
|
|
11841
|
+
cwd: this.config.cwd
|
|
11842
|
+
}
|
|
11843
|
+
};
|
|
11844
|
+
}
|
|
11845
|
+
async ensureHealthy(signal) {
|
|
11846
|
+
if (!this.config.healthcheck) {
|
|
11847
|
+
return;
|
|
11848
|
+
}
|
|
11849
|
+
if (!this.healthcheckPromise) {
|
|
11850
|
+
this.healthcheckPromise = this.runHealthcheck(this.config.healthcheck, signal);
|
|
11851
|
+
}
|
|
11852
|
+
return this.healthcheckPromise;
|
|
11853
|
+
}
|
|
11854
|
+
async runHealthcheck(healthcheck, signal) {
|
|
11855
|
+
if (!healthcheck) {
|
|
11856
|
+
return;
|
|
11857
|
+
}
|
|
11858
|
+
const timeoutMs = healthcheck.timeoutMs ?? this.config.timeoutMs;
|
|
11859
|
+
if (healthcheck.type === "http") {
|
|
11860
|
+
const controller = new AbortController();
|
|
11861
|
+
const timer = timeoutMs ? setTimeout(() => controller.abort(), timeoutMs) : void 0;
|
|
11862
|
+
signal?.addEventListener("abort", () => controller.abort(), { once: true });
|
|
11863
|
+
try {
|
|
11864
|
+
const response = await fetch(healthcheck.url, { method: "GET", signal: controller.signal });
|
|
11865
|
+
if (!response.ok) {
|
|
11866
|
+
throw new Error(`HTTP ${response.status} ${response.statusText}`);
|
|
11867
|
+
}
|
|
11868
|
+
} catch (error) {
|
|
11869
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
11870
|
+
throw new Error(`CLI healthcheck failed for '${this.targetName}': ${reason}`);
|
|
11871
|
+
} finally {
|
|
11872
|
+
if (timer !== void 0) {
|
|
11873
|
+
clearTimeout(timer);
|
|
11874
|
+
}
|
|
11875
|
+
}
|
|
11876
|
+
return;
|
|
11877
|
+
}
|
|
11878
|
+
const renderedCommand = renderTemplate(
|
|
11879
|
+
healthcheck.commandTemplate,
|
|
11880
|
+
buildTemplateValues(
|
|
11881
|
+
{
|
|
11882
|
+
prompt: "",
|
|
11883
|
+
guidelines: "",
|
|
11884
|
+
inputFiles: [],
|
|
11885
|
+
evalCaseId: "",
|
|
11886
|
+
attempt: 0
|
|
11887
|
+
},
|
|
11888
|
+
this.config
|
|
11889
|
+
)
|
|
11890
|
+
);
|
|
11891
|
+
const env = this.config.env ? { ...process.env, ...this.config.env } : process.env;
|
|
11892
|
+
const result = await this.runCommand(renderedCommand, {
|
|
11893
|
+
cwd: healthcheck.cwd ?? this.config.cwd,
|
|
11894
|
+
env,
|
|
11895
|
+
timeoutMs,
|
|
11896
|
+
signal
|
|
11897
|
+
});
|
|
11898
|
+
if (result.failed || (result.exitCode ?? 0) !== 0) {
|
|
11899
|
+
const codeText = result.exitCode !== null ? result.exitCode : "unknown";
|
|
11900
|
+
const detail = result.stderr.trim() || result.stdout.trim();
|
|
11901
|
+
const message = detail ? `${detail} (exit code ${codeText})` : `CLI healthcheck command exited with code ${codeText}`;
|
|
11902
|
+
throw new Error(`CLI healthcheck failed for '${this.targetName}': ${message}`);
|
|
11903
|
+
}
|
|
11904
|
+
}
|
|
11905
|
+
};
|
|
11906
|
+
function buildTemplateValues(request, config) {
|
|
11907
|
+
const inputFiles = normalizeInputFiles(request.inputFiles);
|
|
11908
|
+
return {
|
|
11909
|
+
PROMPT: shellEscape(request.prompt ?? ""),
|
|
11910
|
+
GUIDELINES: shellEscape(request.guidelines ?? ""),
|
|
11911
|
+
EVAL_ID: shellEscape(request.evalCaseId ?? ""),
|
|
11912
|
+
ATTEMPT: shellEscape(String(request.attempt ?? 0)),
|
|
11913
|
+
FILES: formatFileList(inputFiles, config.filesFormat)
|
|
11914
|
+
};
|
|
11915
|
+
}
|
|
11916
|
+
function normalizeInputFiles(inputFiles) {
|
|
11917
|
+
if (!inputFiles || inputFiles.length === 0) {
|
|
11918
|
+
return void 0;
|
|
11919
|
+
}
|
|
11920
|
+
const unique = /* @__PURE__ */ new Map();
|
|
11921
|
+
for (const inputFile of inputFiles) {
|
|
11922
|
+
const absolutePath = path22.resolve(inputFile);
|
|
11923
|
+
if (!unique.has(absolutePath)) {
|
|
11924
|
+
unique.set(absolutePath, absolutePath);
|
|
11925
|
+
}
|
|
11926
|
+
}
|
|
11927
|
+
return Array.from(unique.values());
|
|
11928
|
+
}
|
|
11929
|
+
function formatFileList(files, template) {
|
|
11930
|
+
if (!files || files.length === 0) {
|
|
11931
|
+
return "";
|
|
11932
|
+
}
|
|
11933
|
+
const formatter = template ?? "{path}";
|
|
11934
|
+
return files.map((filePath) => {
|
|
11935
|
+
const escapedPath = shellEscape(filePath);
|
|
11936
|
+
const escapedName = shellEscape(path22.basename(filePath));
|
|
11937
|
+
return formatter.replaceAll("{path}", escapedPath).replaceAll("{basename}", escapedName);
|
|
11938
|
+
}).join(" ");
|
|
11939
|
+
}
|
|
11940
|
+
function renderTemplate(template, values) {
|
|
11941
|
+
return template.replace(/\{([A-Z_]+)\}/g, (match, key2) => {
|
|
11942
|
+
const replacement = values[key2];
|
|
11943
|
+
return replacement !== void 0 ? replacement : match;
|
|
11944
|
+
});
|
|
11945
|
+
}
|
|
11946
|
+
function shellEscape(value) {
|
|
11947
|
+
if (value.length === 0) {
|
|
11948
|
+
return "''";
|
|
11949
|
+
}
|
|
11950
|
+
if (process.platform === "win32") {
|
|
11951
|
+
const escaped = value.replace(/"/g, '\\"');
|
|
11952
|
+
return `"${escaped}"`;
|
|
11953
|
+
}
|
|
11954
|
+
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
11955
|
+
}
|
|
11956
|
+
function formatTimeoutSuffix(timeoutMs) {
|
|
11957
|
+
if (!timeoutMs || timeoutMs <= 0) {
|
|
11958
|
+
return "";
|
|
11959
|
+
}
|
|
11960
|
+
const seconds = Math.ceil(timeoutMs / 1e3);
|
|
11961
|
+
return ` after ${seconds}s`;
|
|
11962
|
+
}
|
|
11668
11963
|
var DEFAULT_MOCK_RESPONSE = '{"answer":"Mock provider response. Configure targets.yaml to supply a custom value."}';
|
|
11669
11964
|
var MockProvider = class {
|
|
11670
11965
|
id;
|
|
@@ -11704,6 +11999,7 @@ var MockProvider = class {
|
|
|
11704
11999
|
return this.delayMs;
|
|
11705
12000
|
}
|
|
11706
12001
|
};
|
|
12002
|
+
var CLI_PLACEHOLDERS = /* @__PURE__ */ new Set(["PROMPT", "GUIDELINES", "EVAL_ID", "ATTEMPT", "FILES"]);
|
|
11707
12003
|
var BASE_TARGET_SCHEMA = external_exports.object({
|
|
11708
12004
|
name: external_exports.string().min(1, "target name is required"),
|
|
11709
12005
|
provider: external_exports.string().min(1, "provider is required"),
|
|
@@ -11760,6 +12056,16 @@ function resolveTargetDefinition(definition, env = process.env) {
|
|
|
11760
12056
|
providerBatching,
|
|
11761
12057
|
config: resolveGeminiConfig(parsed, env)
|
|
11762
12058
|
};
|
|
12059
|
+
case "codex":
|
|
12060
|
+
case "codex-cli":
|
|
12061
|
+
return {
|
|
12062
|
+
kind: "codex",
|
|
12063
|
+
name: parsed.name,
|
|
12064
|
+
judgeTarget: parsed.judge_target,
|
|
12065
|
+
workers: parsed.workers,
|
|
12066
|
+
providerBatching,
|
|
12067
|
+
config: resolveCodexConfig(parsed, env)
|
|
12068
|
+
};
|
|
11763
12069
|
case "mock":
|
|
11764
12070
|
return {
|
|
11765
12071
|
kind: "mock",
|
|
@@ -11779,6 +12085,15 @@ function resolveTargetDefinition(definition, env = process.env) {
|
|
|
11779
12085
|
providerBatching,
|
|
11780
12086
|
config: resolveVSCodeConfig(parsed, env, provider === "vscode-insiders")
|
|
11781
12087
|
};
|
|
12088
|
+
case "cli":
|
|
12089
|
+
return {
|
|
12090
|
+
kind: "cli",
|
|
12091
|
+
name: parsed.name,
|
|
12092
|
+
judgeTarget: parsed.judge_target,
|
|
12093
|
+
workers: parsed.workers,
|
|
12094
|
+
providerBatching,
|
|
12095
|
+
config: resolveCliConfig(parsed, env)
|
|
12096
|
+
};
|
|
11782
12097
|
default:
|
|
11783
12098
|
throw new Error(`Unsupported provider '${parsed.provider}' in target '${parsed.name}'`);
|
|
11784
12099
|
}
|
|
@@ -11846,6 +12161,29 @@ function resolveGeminiConfig(target, env) {
|
|
|
11846
12161
|
maxOutputTokens: resolveOptionalNumber(maxTokensSource, `${target.name} max output tokens`)
|
|
11847
12162
|
};
|
|
11848
12163
|
}
|
|
12164
|
+
function resolveCodexConfig(target, env) {
|
|
12165
|
+
const settings = target.settings ?? {};
|
|
12166
|
+
const executableSource = settings.executable ?? settings.command ?? settings.binary;
|
|
12167
|
+
const argsSource = settings.args ?? settings.arguments;
|
|
12168
|
+
const cwdSource = settings.cwd;
|
|
12169
|
+
const timeoutSource = settings.timeout_seconds ?? settings.timeoutSeconds;
|
|
12170
|
+
const executable = resolveOptionalString(executableSource, env, `${target.name} codex executable`, {
|
|
12171
|
+
allowLiteral: true,
|
|
12172
|
+
optionalEnv: true
|
|
12173
|
+
}) ?? "codex";
|
|
12174
|
+
const args = resolveOptionalStringArray(argsSource, env, `${target.name} codex args`);
|
|
12175
|
+
const cwd = resolveOptionalString(cwdSource, env, `${target.name} codex cwd`, {
|
|
12176
|
+
allowLiteral: true,
|
|
12177
|
+
optionalEnv: true
|
|
12178
|
+
});
|
|
12179
|
+
const timeoutMs = resolveTimeoutMs(timeoutSource, `${target.name} codex timeout`);
|
|
12180
|
+
return {
|
|
12181
|
+
executable,
|
|
12182
|
+
args,
|
|
12183
|
+
cwd,
|
|
12184
|
+
timeoutMs
|
|
12185
|
+
};
|
|
12186
|
+
}
|
|
11849
12187
|
function resolveMockConfig(target) {
|
|
11850
12188
|
const settings = target.settings ?? {};
|
|
11851
12189
|
const response = typeof settings.response === "string" ? settings.response : void 0;
|
|
@@ -11875,6 +12213,125 @@ function resolveVSCodeConfig(target, env, insiders) {
|
|
|
11875
12213
|
workspaceTemplate
|
|
11876
12214
|
};
|
|
11877
12215
|
}
|
|
12216
|
+
function resolveCliConfig(target, env) {
|
|
12217
|
+
const settings = target.settings ?? {};
|
|
12218
|
+
const commandTemplateSource = settings.command_template ?? settings.commandTemplate;
|
|
12219
|
+
const filesFormat = resolveOptionalLiteralString(
|
|
12220
|
+
settings.files_format ?? settings.filesFormat ?? settings.attachments_format ?? settings.attachmentsFormat
|
|
12221
|
+
);
|
|
12222
|
+
const cwd = resolveOptionalString(settings.cwd, env, `${target.name} working directory`, {
|
|
12223
|
+
allowLiteral: true,
|
|
12224
|
+
optionalEnv: true
|
|
12225
|
+
});
|
|
12226
|
+
const envOverrides = resolveEnvOverrides(settings.env, env, target.name);
|
|
12227
|
+
const timeoutMs = resolveTimeoutMs(settings.timeout_seconds ?? settings.timeoutSeconds, `${target.name} timeout`);
|
|
12228
|
+
const healthcheck = resolveCliHealthcheck(settings.healthcheck, env, target.name);
|
|
12229
|
+
const commandTemplate = resolveString(
|
|
12230
|
+
commandTemplateSource,
|
|
12231
|
+
env,
|
|
12232
|
+
`${target.name} CLI command template`,
|
|
12233
|
+
true
|
|
12234
|
+
);
|
|
12235
|
+
assertSupportedCliPlaceholders(commandTemplate, `${target.name} CLI command template`);
|
|
12236
|
+
return {
|
|
12237
|
+
commandTemplate,
|
|
12238
|
+
filesFormat,
|
|
12239
|
+
cwd,
|
|
12240
|
+
env: envOverrides,
|
|
12241
|
+
timeoutMs,
|
|
12242
|
+
healthcheck
|
|
12243
|
+
};
|
|
12244
|
+
}
|
|
12245
|
+
function resolveEnvOverrides(source2, env, targetName) {
|
|
12246
|
+
if (source2 === void 0 || source2 === null) {
|
|
12247
|
+
return void 0;
|
|
12248
|
+
}
|
|
12249
|
+
if (typeof source2 !== "object" || Array.isArray(source2)) {
|
|
12250
|
+
throw new Error(`${targetName} env overrides must be an object map of strings`);
|
|
12251
|
+
}
|
|
12252
|
+
const entries = Object.entries(source2);
|
|
12253
|
+
const resolved = {};
|
|
12254
|
+
for (const [key2, value] of entries) {
|
|
12255
|
+
if (typeof value !== "string") {
|
|
12256
|
+
throw new Error(`${targetName} env override '${key2}' must be a string`);
|
|
12257
|
+
}
|
|
12258
|
+
const resolvedValue = resolveString(value, env, `${targetName} env override '${key2}'`);
|
|
12259
|
+
resolved[key2] = resolvedValue;
|
|
12260
|
+
}
|
|
12261
|
+
return Object.keys(resolved).length > 0 ? resolved : void 0;
|
|
12262
|
+
}
|
|
12263
|
+
function resolveTimeoutMs(source2, description) {
|
|
12264
|
+
const seconds = resolveOptionalNumber(source2, `${description} (seconds)`);
|
|
12265
|
+
if (seconds === void 0) {
|
|
12266
|
+
return void 0;
|
|
12267
|
+
}
|
|
12268
|
+
if (seconds <= 0) {
|
|
12269
|
+
throw new Error(`${description} must be greater than zero seconds`);
|
|
12270
|
+
}
|
|
12271
|
+
return Math.floor(seconds * 1e3);
|
|
12272
|
+
}
|
|
12273
|
+
function resolveCliHealthcheck(source2, env, targetName) {
|
|
12274
|
+
if (source2 === void 0 || source2 === null) {
|
|
12275
|
+
return void 0;
|
|
12276
|
+
}
|
|
12277
|
+
if (typeof source2 !== "object" || Array.isArray(source2)) {
|
|
12278
|
+
throw new Error(`${targetName} healthcheck must be an object`);
|
|
12279
|
+
}
|
|
12280
|
+
const candidate = source2;
|
|
12281
|
+
const type = candidate.type;
|
|
12282
|
+
const timeoutMs = resolveTimeoutMs(
|
|
12283
|
+
candidate.timeout_seconds ?? candidate.timeoutSeconds,
|
|
12284
|
+
`${targetName} healthcheck timeout`
|
|
12285
|
+
);
|
|
12286
|
+
if (type === "http") {
|
|
12287
|
+
const url = resolveString(candidate.url, env, `${targetName} healthcheck URL`);
|
|
12288
|
+
return {
|
|
12289
|
+
type: "http",
|
|
12290
|
+
url,
|
|
12291
|
+
timeoutMs
|
|
12292
|
+
};
|
|
12293
|
+
}
|
|
12294
|
+
if (type === "command") {
|
|
12295
|
+
const commandTemplate = resolveString(
|
|
12296
|
+
candidate.command_template ?? candidate.commandTemplate,
|
|
12297
|
+
env,
|
|
12298
|
+
`${targetName} healthcheck command template`,
|
|
12299
|
+
true
|
|
12300
|
+
);
|
|
12301
|
+
assertSupportedCliPlaceholders(commandTemplate, `${targetName} healthcheck command template`);
|
|
12302
|
+
const cwd = resolveOptionalString(candidate.cwd, env, `${targetName} healthcheck cwd`, {
|
|
12303
|
+
allowLiteral: true,
|
|
12304
|
+
optionalEnv: true
|
|
12305
|
+
});
|
|
12306
|
+
return {
|
|
12307
|
+
type: "command",
|
|
12308
|
+
commandTemplate,
|
|
12309
|
+
timeoutMs,
|
|
12310
|
+
cwd
|
|
12311
|
+
};
|
|
12312
|
+
}
|
|
12313
|
+
throw new Error(`${targetName} healthcheck type must be 'http' or 'command'`);
|
|
12314
|
+
}
|
|
12315
|
+
function assertSupportedCliPlaceholders(template, description) {
|
|
12316
|
+
const placeholders = extractCliPlaceholders(template);
|
|
12317
|
+
for (const placeholder of placeholders) {
|
|
12318
|
+
if (!CLI_PLACEHOLDERS.has(placeholder)) {
|
|
12319
|
+
throw new Error(
|
|
12320
|
+
`${description} includes unsupported placeholder '{${placeholder}}'. Supported placeholders: ${Array.from(CLI_PLACEHOLDERS).join(", ")}`
|
|
12321
|
+
);
|
|
12322
|
+
}
|
|
12323
|
+
}
|
|
12324
|
+
}
|
|
12325
|
+
function extractCliPlaceholders(template) {
|
|
12326
|
+
const matches = template.matchAll(/\{([A-Z_]+)\}/g);
|
|
12327
|
+
const results = [];
|
|
12328
|
+
for (const match of matches) {
|
|
12329
|
+
if (match[1]) {
|
|
12330
|
+
results.push(match[1]);
|
|
12331
|
+
}
|
|
12332
|
+
}
|
|
12333
|
+
return results;
|
|
12334
|
+
}
|
|
11878
12335
|
function resolveString(source2, env, description, allowLiteral = false) {
|
|
11879
12336
|
const value = resolveOptionalString(source2, env, description, {
|
|
11880
12337
|
allowLiteral,
|
|
@@ -11905,11 +12362,14 @@ function resolveOptionalString(source2, env, description, options) {
|
|
|
11905
12362
|
}
|
|
11906
12363
|
const allowLiteral = options?.allowLiteral ?? false;
|
|
11907
12364
|
const optionalEnv = options?.optionalEnv ?? false;
|
|
11908
|
-
|
|
12365
|
+
const looksLikeEnv = isLikelyEnvReference(trimmed);
|
|
12366
|
+
if (looksLikeEnv) {
|
|
11909
12367
|
if (optionalEnv) {
|
|
11910
12368
|
return void 0;
|
|
11911
12369
|
}
|
|
11912
|
-
|
|
12370
|
+
if (!allowLiteral) {
|
|
12371
|
+
throw new Error(`Environment variable '${trimmed}' required for ${description} is not set`);
|
|
12372
|
+
}
|
|
11913
12373
|
}
|
|
11914
12374
|
return trimmed;
|
|
11915
12375
|
}
|
|
@@ -11959,6 +12419,38 @@ function resolveOptionalBoolean(source2) {
|
|
|
11959
12419
|
function isLikelyEnvReference(value) {
|
|
11960
12420
|
return /^[A-Z0-9_]+$/.test(value);
|
|
11961
12421
|
}
|
|
12422
|
+
function resolveOptionalStringArray(source2, env, description) {
|
|
12423
|
+
if (source2 === void 0 || source2 === null) {
|
|
12424
|
+
return void 0;
|
|
12425
|
+
}
|
|
12426
|
+
if (!Array.isArray(source2)) {
|
|
12427
|
+
throw new Error(`${description} must be an array of strings`);
|
|
12428
|
+
}
|
|
12429
|
+
if (source2.length === 0) {
|
|
12430
|
+
return void 0;
|
|
12431
|
+
}
|
|
12432
|
+
const resolved = [];
|
|
12433
|
+
for (let i6 = 0; i6 < source2.length; i6++) {
|
|
12434
|
+
const item = source2[i6];
|
|
12435
|
+
if (typeof item !== "string") {
|
|
12436
|
+
throw new Error(`${description}[${i6}] must be a string`);
|
|
12437
|
+
}
|
|
12438
|
+
const trimmed = item.trim();
|
|
12439
|
+
if (trimmed.length === 0) {
|
|
12440
|
+
throw new Error(`${description}[${i6}] cannot be empty`);
|
|
12441
|
+
}
|
|
12442
|
+
const envValue = env[trimmed];
|
|
12443
|
+
if (envValue !== void 0) {
|
|
12444
|
+
if (envValue.trim().length === 0) {
|
|
12445
|
+
throw new Error(`Environment variable '${trimmed}' for ${description}[${i6}] is empty`);
|
|
12446
|
+
}
|
|
12447
|
+
resolved.push(envValue);
|
|
12448
|
+
} else {
|
|
12449
|
+
resolved.push(trimmed);
|
|
12450
|
+
}
|
|
12451
|
+
}
|
|
12452
|
+
return resolved.length > 0 ? resolved : void 0;
|
|
12453
|
+
}
|
|
11962
12454
|
var VSCodeProvider = class {
|
|
11963
12455
|
id;
|
|
11964
12456
|
kind;
|
|
@@ -11975,12 +12467,11 @@ var VSCodeProvider = class {
|
|
|
11975
12467
|
if (request.signal?.aborted) {
|
|
11976
12468
|
throw new Error("VS Code provider request was aborted before dispatch");
|
|
11977
12469
|
}
|
|
11978
|
-
const
|
|
11979
|
-
const promptContent = buildPromptDocument(request,
|
|
12470
|
+
const inputFiles = normalizeAttachments(request.inputFiles);
|
|
12471
|
+
const promptContent = buildPromptDocument(request, inputFiles, request.guideline_patterns);
|
|
11980
12472
|
const session = await dispatchAgentSession({
|
|
11981
12473
|
userQuery: promptContent,
|
|
11982
|
-
|
|
11983
|
-
extraAttachments: attachments,
|
|
12474
|
+
extraAttachments: inputFiles,
|
|
11984
12475
|
wait: this.config.waitForResponse,
|
|
11985
12476
|
dryRun: this.config.dryRun,
|
|
11986
12477
|
vscodeCmd: this.config.command,
|
|
@@ -11997,7 +12488,7 @@ var VSCodeProvider = class {
|
|
|
11997
12488
|
text: "",
|
|
11998
12489
|
raw: {
|
|
11999
12490
|
session,
|
|
12000
|
-
|
|
12491
|
+
inputFiles
|
|
12001
12492
|
}
|
|
12002
12493
|
};
|
|
12003
12494
|
}
|
|
@@ -12006,7 +12497,7 @@ var VSCodeProvider = class {
|
|
|
12006
12497
|
text: responseText,
|
|
12007
12498
|
raw: {
|
|
12008
12499
|
session,
|
|
12009
|
-
|
|
12500
|
+
inputFiles
|
|
12010
12501
|
}
|
|
12011
12502
|
};
|
|
12012
12503
|
}
|
|
@@ -12016,17 +12507,17 @@ var VSCodeProvider = class {
|
|
|
12016
12507
|
}
|
|
12017
12508
|
const normalizedRequests = requests.map((req) => ({
|
|
12018
12509
|
request: req,
|
|
12019
|
-
|
|
12510
|
+
inputFiles: normalizeAttachments(req.inputFiles)
|
|
12020
12511
|
}));
|
|
12021
|
-
const
|
|
12022
|
-
normalizedRequests.map(({
|
|
12512
|
+
const combinedInputFiles = mergeAttachments(
|
|
12513
|
+
normalizedRequests.map(({ inputFiles }) => inputFiles)
|
|
12023
12514
|
);
|
|
12024
12515
|
const userQueries = normalizedRequests.map(
|
|
12025
|
-
({ request,
|
|
12516
|
+
({ request, inputFiles }) => buildPromptDocument(request, inputFiles, request.guideline_patterns)
|
|
12026
12517
|
);
|
|
12027
12518
|
const session = await dispatchBatchAgent({
|
|
12028
12519
|
userQueries,
|
|
12029
|
-
extraAttachments:
|
|
12520
|
+
extraAttachments: combinedInputFiles,
|
|
12030
12521
|
wait: this.config.waitForResponse,
|
|
12031
12522
|
dryRun: this.config.dryRun,
|
|
12032
12523
|
vscodeCmd: this.config.command,
|
|
@@ -12039,12 +12530,12 @@ var VSCodeProvider = class {
|
|
|
12039
12530
|
throw new Error(failure);
|
|
12040
12531
|
}
|
|
12041
12532
|
if (this.config.dryRun) {
|
|
12042
|
-
return normalizedRequests.map(({
|
|
12533
|
+
return normalizedRequests.map(({ inputFiles }) => ({
|
|
12043
12534
|
text: "",
|
|
12044
12535
|
raw: {
|
|
12045
12536
|
session,
|
|
12046
|
-
|
|
12047
|
-
|
|
12537
|
+
inputFiles,
|
|
12538
|
+
allInputFiles: combinedInputFiles
|
|
12048
12539
|
}
|
|
12049
12540
|
}));
|
|
12050
12541
|
}
|
|
@@ -12060,8 +12551,8 @@ var VSCodeProvider = class {
|
|
|
12060
12551
|
text: responseText,
|
|
12061
12552
|
raw: {
|
|
12062
12553
|
session,
|
|
12063
|
-
|
|
12064
|
-
|
|
12554
|
+
inputFiles: normalizedRequests[index]?.inputFiles,
|
|
12555
|
+
allInputFiles: combinedInputFiles,
|
|
12065
12556
|
responseFile
|
|
12066
12557
|
}
|
|
12067
12558
|
});
|
|
@@ -12088,7 +12579,7 @@ function buildMandatoryPrereadBlock(guidelineFiles, attachmentFiles) {
|
|
|
12088
12579
|
return "";
|
|
12089
12580
|
}
|
|
12090
12581
|
const buildList = (files) => files.map((absolutePath) => {
|
|
12091
|
-
const fileName =
|
|
12582
|
+
const fileName = path32.basename(absolutePath);
|
|
12092
12583
|
const fileUri = pathToFileUri2(absolutePath);
|
|
12093
12584
|
return `* [${fileName}](${fileUri})`;
|
|
12094
12585
|
});
|
|
@@ -12113,8 +12604,8 @@ function collectGuidelineFiles(attachments, guidelinePatterns) {
|
|
|
12113
12604
|
}
|
|
12114
12605
|
const unique = /* @__PURE__ */ new Map();
|
|
12115
12606
|
for (const attachment of attachments) {
|
|
12116
|
-
const absolutePath =
|
|
12117
|
-
const normalized = absolutePath.split(
|
|
12607
|
+
const absolutePath = path32.resolve(attachment);
|
|
12608
|
+
const normalized = absolutePath.split(path32.sep).join("/");
|
|
12118
12609
|
if (isGuidelineFile(normalized, guidelinePatterns)) {
|
|
12119
12610
|
if (!unique.has(absolutePath)) {
|
|
12120
12611
|
unique.set(absolutePath, absolutePath);
|
|
@@ -12129,7 +12620,7 @@ function collectAttachmentFiles(attachments) {
|
|
|
12129
12620
|
}
|
|
12130
12621
|
const unique = /* @__PURE__ */ new Map();
|
|
12131
12622
|
for (const attachment of attachments) {
|
|
12132
|
-
const absolutePath =
|
|
12623
|
+
const absolutePath = path32.resolve(attachment);
|
|
12133
12624
|
if (!unique.has(absolutePath)) {
|
|
12134
12625
|
unique.set(absolutePath, absolutePath);
|
|
12135
12626
|
}
|
|
@@ -12137,7 +12628,7 @@ function collectAttachmentFiles(attachments) {
|
|
|
12137
12628
|
return Array.from(unique.values());
|
|
12138
12629
|
}
|
|
12139
12630
|
function pathToFileUri2(filePath) {
|
|
12140
|
-
const absolutePath =
|
|
12631
|
+
const absolutePath = path32.isAbsolute(filePath) ? filePath : path32.resolve(filePath);
|
|
12141
12632
|
const normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
12142
12633
|
if (/^[a-zA-Z]:\//.test(normalizedPath)) {
|
|
12143
12634
|
return `file:///${normalizedPath}`;
|
|
@@ -12150,7 +12641,7 @@ function normalizeAttachments(attachments) {
|
|
|
12150
12641
|
}
|
|
12151
12642
|
const deduped = /* @__PURE__ */ new Set();
|
|
12152
12643
|
for (const attachment of attachments) {
|
|
12153
|
-
deduped.add(
|
|
12644
|
+
deduped.add(path32.resolve(attachment));
|
|
12154
12645
|
}
|
|
12155
12646
|
return Array.from(deduped);
|
|
12156
12647
|
}
|
|
@@ -12158,8 +12649,8 @@ function mergeAttachments(all) {
|
|
|
12158
12649
|
const deduped = /* @__PURE__ */ new Set();
|
|
12159
12650
|
for (const list of all) {
|
|
12160
12651
|
if (!list) continue;
|
|
12161
|
-
for (const
|
|
12162
|
-
deduped.add(
|
|
12652
|
+
for (const inputFile of list) {
|
|
12653
|
+
deduped.add(path32.resolve(inputFile));
|
|
12163
12654
|
}
|
|
12164
12655
|
}
|
|
12165
12656
|
return deduped.size > 0 ? Array.from(deduped) : void 0;
|
|
@@ -12202,53 +12693,616 @@ total unlocked subagents available: ${result.created.length + result.skippedExis
|
|
|
12202
12693
|
};
|
|
12203
12694
|
}
|
|
12204
12695
|
}
|
|
12205
|
-
function
|
|
12206
|
-
|
|
12207
|
-
|
|
12208
|
-
|
|
12209
|
-
|
|
12210
|
-
|
|
12211
|
-
|
|
12212
|
-
|
|
12213
|
-
|
|
12214
|
-
)
|
|
12696
|
+
function buildPromptDocument2(request, inputFiles, options) {
|
|
12697
|
+
const parts = [];
|
|
12698
|
+
const guidelineFiles = collectGuidelineFiles2(
|
|
12699
|
+
inputFiles,
|
|
12700
|
+
options?.guidelinePatterns ?? request.guideline_patterns,
|
|
12701
|
+
options?.guidelineOverrides
|
|
12702
|
+
);
|
|
12703
|
+
const inputFilesList = collectInputFiles(inputFiles);
|
|
12704
|
+
const nonGuidelineInputFiles = inputFilesList.filter(
|
|
12705
|
+
(file) => !guidelineFiles.includes(file)
|
|
12706
|
+
);
|
|
12707
|
+
const prereadBlock = buildMandatoryPrereadBlock2(guidelineFiles, nonGuidelineInputFiles);
|
|
12708
|
+
if (prereadBlock.length > 0) {
|
|
12709
|
+
parts.push("\n", prereadBlock);
|
|
12215
12710
|
}
|
|
12216
|
-
|
|
12217
|
-
|
|
12218
|
-
|
|
12219
|
-
|
|
12220
|
-
|
|
12711
|
+
parts.push("\n[[ ## user_query ## ]]\n", request.prompt.trim());
|
|
12712
|
+
return parts.join("\n").trim();
|
|
12713
|
+
}
|
|
12714
|
+
function normalizeInputFiles2(inputFiles) {
|
|
12715
|
+
if (!inputFiles || inputFiles.length === 0) {
|
|
12716
|
+
return void 0;
|
|
12221
12717
|
}
|
|
12222
|
-
|
|
12223
|
-
|
|
12224
|
-
|
|
12225
|
-
|
|
12226
|
-
|
|
12718
|
+
const deduped = /* @__PURE__ */ new Map();
|
|
12719
|
+
for (const inputFile of inputFiles) {
|
|
12720
|
+
const absolutePath = path42.resolve(inputFile);
|
|
12721
|
+
if (!deduped.has(absolutePath)) {
|
|
12722
|
+
deduped.set(absolutePath, absolutePath);
|
|
12723
|
+
}
|
|
12227
12724
|
}
|
|
12725
|
+
return Array.from(deduped.values());
|
|
12228
12726
|
}
|
|
12229
|
-
function
|
|
12230
|
-
|
|
12231
|
-
|
|
12232
|
-
throw new Error(`targets.yaml at ${absolutePath} must have a 'targets' array`);
|
|
12727
|
+
function collectGuidelineFiles2(inputFiles, guidelinePatterns, overrides) {
|
|
12728
|
+
if (!inputFiles || inputFiles.length === 0) {
|
|
12729
|
+
return [];
|
|
12233
12730
|
}
|
|
12234
|
-
|
|
12731
|
+
const unique = /* @__PURE__ */ new Map();
|
|
12732
|
+
for (const inputFile of inputFiles) {
|
|
12733
|
+
const absolutePath = path42.resolve(inputFile);
|
|
12734
|
+
if (overrides?.has(absolutePath)) {
|
|
12735
|
+
if (!unique.has(absolutePath)) {
|
|
12736
|
+
unique.set(absolutePath, absolutePath);
|
|
12737
|
+
}
|
|
12738
|
+
continue;
|
|
12739
|
+
}
|
|
12740
|
+
const normalized = absolutePath.split(path42.sep).join("/");
|
|
12741
|
+
if (isGuidelineFile(normalized, guidelinePatterns)) {
|
|
12742
|
+
if (!unique.has(absolutePath)) {
|
|
12743
|
+
unique.set(absolutePath, absolutePath);
|
|
12744
|
+
}
|
|
12745
|
+
}
|
|
12746
|
+
}
|
|
12747
|
+
return Array.from(unique.values());
|
|
12235
12748
|
}
|
|
12236
|
-
function
|
|
12237
|
-
if (!
|
|
12238
|
-
|
|
12749
|
+
function collectInputFiles(inputFiles) {
|
|
12750
|
+
if (!inputFiles || inputFiles.length === 0) {
|
|
12751
|
+
return [];
|
|
12239
12752
|
}
|
|
12240
|
-
const
|
|
12241
|
-
const
|
|
12242
|
-
|
|
12243
|
-
|
|
12244
|
-
|
|
12245
|
-
|
|
12753
|
+
const unique = /* @__PURE__ */ new Map();
|
|
12754
|
+
for (const inputFile of inputFiles) {
|
|
12755
|
+
const absolutePath = path42.resolve(inputFile);
|
|
12756
|
+
if (!unique.has(absolutePath)) {
|
|
12757
|
+
unique.set(absolutePath, absolutePath);
|
|
12758
|
+
}
|
|
12246
12759
|
}
|
|
12247
|
-
|
|
12248
|
-
|
|
12760
|
+
return Array.from(unique.values());
|
|
12761
|
+
}
|
|
12762
|
+
function buildMandatoryPrereadBlock2(guidelineFiles, inputFiles) {
|
|
12763
|
+
if (guidelineFiles.length === 0 && inputFiles.length === 0) {
|
|
12764
|
+
return "";
|
|
12249
12765
|
}
|
|
12250
|
-
|
|
12251
|
-
|
|
12766
|
+
const buildList = (files) => files.map((absolutePath) => {
|
|
12767
|
+
const fileName = path42.basename(absolutePath);
|
|
12768
|
+
const fileUri = pathToFileUri22(absolutePath);
|
|
12769
|
+
return `* [${fileName}](${fileUri})`;
|
|
12770
|
+
});
|
|
12771
|
+
const sections = [];
|
|
12772
|
+
if (guidelineFiles.length > 0) {
|
|
12773
|
+
sections.push(`Read all guideline files:
|
|
12774
|
+
${buildList(guidelineFiles).join("\n")}.`);
|
|
12775
|
+
}
|
|
12776
|
+
if (inputFiles.length > 0) {
|
|
12777
|
+
sections.push(`Read all input files:
|
|
12778
|
+
${buildList(inputFiles).join("\n")}.`);
|
|
12779
|
+
}
|
|
12780
|
+
sections.push(
|
|
12781
|
+
"If any file is missing, fail with ERROR: missing-file <filename> and stop.",
|
|
12782
|
+
"Then apply system_instructions on the user query below."
|
|
12783
|
+
);
|
|
12784
|
+
return sections.join("\n");
|
|
12785
|
+
}
|
|
12786
|
+
function pathToFileUri22(filePath) {
|
|
12787
|
+
const absolutePath = path42.isAbsolute(filePath) ? filePath : path42.resolve(filePath);
|
|
12788
|
+
const normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
12789
|
+
if (/^[a-zA-Z]:\//.test(normalizedPath)) {
|
|
12790
|
+
return `file:///${normalizedPath}`;
|
|
12791
|
+
}
|
|
12792
|
+
return `file://${normalizedPath}`;
|
|
12793
|
+
}
|
|
12794
|
+
var execAsync22 = promisify22(execCallback);
|
|
12795
|
+
var WORKSPACE_PREFIX = "agentv-codex-";
|
|
12796
|
+
var PROMPT_FILENAME = "prompt.md";
|
|
12797
|
+
var FILES_DIR = "files";
|
|
12798
|
+
var JSONL_TYPE_ITEM_COMPLETED = "item.completed";
|
|
12799
|
+
var CodexProvider = class {
|
|
12800
|
+
id;
|
|
12801
|
+
kind = "codex";
|
|
12802
|
+
targetName;
|
|
12803
|
+
supportsBatch = false;
|
|
12804
|
+
config;
|
|
12805
|
+
runCodex;
|
|
12806
|
+
environmentCheck;
|
|
12807
|
+
resolvedExecutable;
|
|
12808
|
+
constructor(targetName, config, runner = defaultCodexRunner) {
|
|
12809
|
+
this.id = `codex:${targetName}`;
|
|
12810
|
+
this.targetName = targetName;
|
|
12811
|
+
this.config = config;
|
|
12812
|
+
this.runCodex = runner;
|
|
12813
|
+
}
|
|
12814
|
+
async invoke(request) {
|
|
12815
|
+
if (request.signal?.aborted) {
|
|
12816
|
+
throw new Error("Codex provider request was aborted before execution");
|
|
12817
|
+
}
|
|
12818
|
+
await this.ensureEnvironmentReady();
|
|
12819
|
+
const inputFiles = normalizeInputFiles2(request.inputFiles);
|
|
12820
|
+
const originalGuidelines = new Set(
|
|
12821
|
+
collectGuidelineFiles2(inputFiles, request.guideline_patterns).map((file) => path52.resolve(file))
|
|
12822
|
+
);
|
|
12823
|
+
const workspaceRoot = await this.createWorkspace();
|
|
12824
|
+
try {
|
|
12825
|
+
const { mirroredInputFiles, guidelineMirrors } = await this.mirrorInputFiles(
|
|
12826
|
+
inputFiles,
|
|
12827
|
+
workspaceRoot,
|
|
12828
|
+
originalGuidelines
|
|
12829
|
+
);
|
|
12830
|
+
const promptContent = buildPromptDocument2(request, mirroredInputFiles, {
|
|
12831
|
+
guidelinePatterns: request.guideline_patterns,
|
|
12832
|
+
guidelineOverrides: guidelineMirrors
|
|
12833
|
+
});
|
|
12834
|
+
const promptFile = path52.join(workspaceRoot, PROMPT_FILENAME);
|
|
12835
|
+
await writeFile3(promptFile, promptContent, "utf8");
|
|
12836
|
+
const args = this.buildCodexArgs();
|
|
12837
|
+
const cwd = this.resolveCwd(workspaceRoot);
|
|
12838
|
+
const result = await this.executeCodex(args, cwd, promptContent, request.signal);
|
|
12839
|
+
if (result.timedOut) {
|
|
12840
|
+
throw new Error(
|
|
12841
|
+
`Codex CLI timed out${formatTimeoutSuffix2(this.config.timeoutMs ?? void 0)}`
|
|
12842
|
+
);
|
|
12843
|
+
}
|
|
12844
|
+
if (result.exitCode !== 0) {
|
|
12845
|
+
const detail = pickDetail(result.stderr, result.stdout);
|
|
12846
|
+
const prefix = `Codex CLI exited with code ${result.exitCode}`;
|
|
12847
|
+
throw new Error(detail ? `${prefix}: ${detail}` : prefix);
|
|
12848
|
+
}
|
|
12849
|
+
const parsed = parseCodexJson(result.stdout);
|
|
12850
|
+
const assistantText = extractAssistantText(parsed);
|
|
12851
|
+
return {
|
|
12852
|
+
text: assistantText,
|
|
12853
|
+
raw: {
|
|
12854
|
+
response: parsed,
|
|
12855
|
+
stdout: result.stdout,
|
|
12856
|
+
stderr: result.stderr,
|
|
12857
|
+
exitCode: result.exitCode,
|
|
12858
|
+
args,
|
|
12859
|
+
executable: this.resolvedExecutable ?? this.config.executable,
|
|
12860
|
+
promptFile,
|
|
12861
|
+
workspace: workspaceRoot,
|
|
12862
|
+
inputFiles: mirroredInputFiles
|
|
12863
|
+
}
|
|
12864
|
+
};
|
|
12865
|
+
} finally {
|
|
12866
|
+
await this.cleanupWorkspace(workspaceRoot);
|
|
12867
|
+
}
|
|
12868
|
+
}
|
|
12869
|
+
async ensureEnvironmentReady() {
|
|
12870
|
+
if (!this.environmentCheck) {
|
|
12871
|
+
this.environmentCheck = this.validateEnvironment();
|
|
12872
|
+
}
|
|
12873
|
+
await this.environmentCheck;
|
|
12874
|
+
}
|
|
12875
|
+
async validateEnvironment() {
|
|
12876
|
+
this.resolvedExecutable = await locateExecutable(this.config.executable);
|
|
12877
|
+
}
|
|
12878
|
+
resolveCwd(workspaceRoot) {
|
|
12879
|
+
if (!this.config.cwd) {
|
|
12880
|
+
return workspaceRoot;
|
|
12881
|
+
}
|
|
12882
|
+
return path52.resolve(this.config.cwd);
|
|
12883
|
+
}
|
|
12884
|
+
buildCodexArgs() {
|
|
12885
|
+
const args = ["--ask-for-approval", "never", "exec", "--json", "--color", "never", "--skip-git-repo-check"];
|
|
12886
|
+
if (this.config.args && this.config.args.length > 0) {
|
|
12887
|
+
args.push(...this.config.args);
|
|
12888
|
+
}
|
|
12889
|
+
args.push("-");
|
|
12890
|
+
return args;
|
|
12891
|
+
}
|
|
12892
|
+
async executeCodex(args, cwd, promptContent, signal) {
|
|
12893
|
+
try {
|
|
12894
|
+
return await this.runCodex({
|
|
12895
|
+
executable: this.resolvedExecutable ?? this.config.executable,
|
|
12896
|
+
args,
|
|
12897
|
+
cwd,
|
|
12898
|
+
prompt: promptContent,
|
|
12899
|
+
timeoutMs: this.config.timeoutMs,
|
|
12900
|
+
env: process.env,
|
|
12901
|
+
signal
|
|
12902
|
+
});
|
|
12903
|
+
} catch (error) {
|
|
12904
|
+
const err = error;
|
|
12905
|
+
if (err.code === "ENOENT") {
|
|
12906
|
+
throw new Error(
|
|
12907
|
+
`Codex executable '${this.config.executable}' was not found. Update the target settings.executable or add it to PATH.`
|
|
12908
|
+
);
|
|
12909
|
+
}
|
|
12910
|
+
throw error;
|
|
12911
|
+
}
|
|
12912
|
+
}
|
|
12913
|
+
async mirrorInputFiles(inputFiles, workspaceRoot, guidelineOriginals) {
|
|
12914
|
+
if (!inputFiles || inputFiles.length === 0) {
|
|
12915
|
+
return {
|
|
12916
|
+
mirroredInputFiles: void 0,
|
|
12917
|
+
guidelineMirrors: /* @__PURE__ */ new Set()
|
|
12918
|
+
};
|
|
12919
|
+
}
|
|
12920
|
+
const filesRoot = path52.join(workspaceRoot, FILES_DIR);
|
|
12921
|
+
await mkdir3(filesRoot, { recursive: true });
|
|
12922
|
+
const mirrored = [];
|
|
12923
|
+
const guidelineMirrors = /* @__PURE__ */ new Set();
|
|
12924
|
+
const nameCounts = /* @__PURE__ */ new Map();
|
|
12925
|
+
for (const inputFile of inputFiles) {
|
|
12926
|
+
const absoluteSource = path52.resolve(inputFile);
|
|
12927
|
+
const baseName = path52.basename(absoluteSource);
|
|
12928
|
+
const count = nameCounts.get(baseName) ?? 0;
|
|
12929
|
+
nameCounts.set(baseName, count + 1);
|
|
12930
|
+
const finalName = count === 0 ? baseName : `${baseName}.${count}`;
|
|
12931
|
+
const destination = path52.join(filesRoot, finalName);
|
|
12932
|
+
await copyFile2(absoluteSource, destination);
|
|
12933
|
+
const resolvedDestination = path52.resolve(destination);
|
|
12934
|
+
mirrored.push(resolvedDestination);
|
|
12935
|
+
if (guidelineOriginals.has(absoluteSource)) {
|
|
12936
|
+
guidelineMirrors.add(resolvedDestination);
|
|
12937
|
+
}
|
|
12938
|
+
}
|
|
12939
|
+
return {
|
|
12940
|
+
mirroredInputFiles: mirrored,
|
|
12941
|
+
guidelineMirrors
|
|
12942
|
+
};
|
|
12943
|
+
}
|
|
12944
|
+
async createWorkspace() {
|
|
12945
|
+
return await mkdtemp(path52.join(tmpdir(), WORKSPACE_PREFIX));
|
|
12946
|
+
}
|
|
12947
|
+
async cleanupWorkspace(workspaceRoot) {
|
|
12948
|
+
try {
|
|
12949
|
+
await rm2(workspaceRoot, { recursive: true, force: true });
|
|
12950
|
+
} catch {
|
|
12951
|
+
}
|
|
12952
|
+
}
|
|
12953
|
+
};
|
|
12954
|
+
async function locateExecutable(candidate) {
|
|
12955
|
+
const includesPathSeparator = candidate.includes("/") || candidate.includes("\\");
|
|
12956
|
+
if (includesPathSeparator) {
|
|
12957
|
+
const resolved = path52.isAbsolute(candidate) ? candidate : path52.resolve(candidate);
|
|
12958
|
+
const executablePath = await ensureWindowsExecutableVariant(resolved);
|
|
12959
|
+
await access22(executablePath, constants22.F_OK);
|
|
12960
|
+
return executablePath;
|
|
12961
|
+
}
|
|
12962
|
+
const locator = process.platform === "win32" ? "where" : "which";
|
|
12963
|
+
try {
|
|
12964
|
+
const { stdout } = await execAsync22(`${locator} ${candidate}`);
|
|
12965
|
+
const lines = stdout.split(/\r?\n/).map((line2) => line2.trim()).filter((line2) => line2.length > 0);
|
|
12966
|
+
const preferred = selectExecutableCandidate(lines);
|
|
12967
|
+
if (preferred) {
|
|
12968
|
+
const executablePath = await ensureWindowsExecutableVariant(preferred);
|
|
12969
|
+
await access22(executablePath, constants22.F_OK);
|
|
12970
|
+
return executablePath;
|
|
12971
|
+
}
|
|
12972
|
+
} catch {
|
|
12973
|
+
}
|
|
12974
|
+
throw new Error(`Codex executable '${candidate}' was not found on PATH`);
|
|
12975
|
+
}
|
|
12976
|
+
function selectExecutableCandidate(candidates) {
|
|
12977
|
+
if (candidates.length === 0) {
|
|
12978
|
+
return void 0;
|
|
12979
|
+
}
|
|
12980
|
+
if (process.platform !== "win32") {
|
|
12981
|
+
return candidates[0];
|
|
12982
|
+
}
|
|
12983
|
+
const extensions = getWindowsExecutableExtensions();
|
|
12984
|
+
for (const ext of extensions) {
|
|
12985
|
+
const match = candidates.find((candidate) => candidate.toLowerCase().endsWith(ext));
|
|
12986
|
+
if (match) {
|
|
12987
|
+
return match;
|
|
12988
|
+
}
|
|
12989
|
+
}
|
|
12990
|
+
return candidates[0];
|
|
12991
|
+
}
|
|
12992
|
+
async function ensureWindowsExecutableVariant(candidate) {
|
|
12993
|
+
if (process.platform !== "win32") {
|
|
12994
|
+
return candidate;
|
|
12995
|
+
}
|
|
12996
|
+
if (hasExecutableExtension(candidate)) {
|
|
12997
|
+
return candidate;
|
|
12998
|
+
}
|
|
12999
|
+
const extensions = getWindowsExecutableExtensions();
|
|
13000
|
+
for (const ext of extensions) {
|
|
13001
|
+
const withExtension = `${candidate}${ext}`;
|
|
13002
|
+
try {
|
|
13003
|
+
await access22(withExtension, constants22.F_OK);
|
|
13004
|
+
return withExtension;
|
|
13005
|
+
} catch {
|
|
13006
|
+
}
|
|
13007
|
+
}
|
|
13008
|
+
return candidate;
|
|
13009
|
+
}
|
|
13010
|
+
function hasExecutableExtension(candidate) {
|
|
13011
|
+
const lower = candidate.toLowerCase();
|
|
13012
|
+
return getWindowsExecutableExtensions().some((ext) => lower.endsWith(ext));
|
|
13013
|
+
}
|
|
13014
|
+
var DEFAULT_WINDOWS_EXTENSIONS = [".com", ".exe", ".bat", ".cmd", ".ps1"];
|
|
13015
|
+
function getWindowsExecutableExtensions() {
|
|
13016
|
+
if (process.platform !== "win32") {
|
|
13017
|
+
return [];
|
|
13018
|
+
}
|
|
13019
|
+
const fromEnv = process.env.PATHEXT?.split(";").map((ext) => ext.trim().toLowerCase()).filter((ext) => ext.length > 0);
|
|
13020
|
+
return fromEnv && fromEnv.length > 0 ? fromEnv : DEFAULT_WINDOWS_EXTENSIONS;
|
|
13021
|
+
}
|
|
13022
|
+
function parseCodexJson(output) {
|
|
13023
|
+
const trimmed = output.trim();
|
|
13024
|
+
if (trimmed.length === 0) {
|
|
13025
|
+
throw new Error("Codex CLI produced no output in --json mode");
|
|
13026
|
+
}
|
|
13027
|
+
try {
|
|
13028
|
+
return JSON.parse(trimmed);
|
|
13029
|
+
} catch {
|
|
13030
|
+
const lineObjects = parseJsonLines(trimmed);
|
|
13031
|
+
if (lineObjects) {
|
|
13032
|
+
return lineObjects;
|
|
13033
|
+
}
|
|
13034
|
+
const lastBrace = trimmed.lastIndexOf("{");
|
|
13035
|
+
if (lastBrace >= 0) {
|
|
13036
|
+
const candidate = trimmed.slice(lastBrace);
|
|
13037
|
+
try {
|
|
13038
|
+
return JSON.parse(candidate);
|
|
13039
|
+
} catch {
|
|
13040
|
+
}
|
|
13041
|
+
}
|
|
13042
|
+
const preview = trimmed.slice(0, 200);
|
|
13043
|
+
throw new Error(`Codex CLI emitted invalid JSON: ${preview}${trimmed.length > 200 ? "\u2026" : ""}`);
|
|
13044
|
+
}
|
|
13045
|
+
}
|
|
13046
|
+
function extractAssistantText(parsed) {
|
|
13047
|
+
if (Array.isArray(parsed)) {
|
|
13048
|
+
const text = extractFromEventStream(parsed);
|
|
13049
|
+
if (text) {
|
|
13050
|
+
return text;
|
|
13051
|
+
}
|
|
13052
|
+
}
|
|
13053
|
+
if (!parsed || typeof parsed !== "object") {
|
|
13054
|
+
throw new Error("Codex CLI JSON response did not include an assistant message");
|
|
13055
|
+
}
|
|
13056
|
+
const record = parsed;
|
|
13057
|
+
const eventText = extractFromEvent(record);
|
|
13058
|
+
if (eventText) {
|
|
13059
|
+
return eventText;
|
|
13060
|
+
}
|
|
13061
|
+
const messages = Array.isArray(record.messages) ? record.messages : void 0;
|
|
13062
|
+
if (messages) {
|
|
13063
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
13064
|
+
const entry = messages[index];
|
|
13065
|
+
if (!entry || typeof entry !== "object") {
|
|
13066
|
+
continue;
|
|
13067
|
+
}
|
|
13068
|
+
const role = entry.role;
|
|
13069
|
+
if (role !== "assistant") {
|
|
13070
|
+
continue;
|
|
13071
|
+
}
|
|
13072
|
+
const content = entry.content;
|
|
13073
|
+
const flattened = flattenContent(content);
|
|
13074
|
+
if (flattened) {
|
|
13075
|
+
return flattened;
|
|
13076
|
+
}
|
|
13077
|
+
}
|
|
13078
|
+
}
|
|
13079
|
+
const response = record.response;
|
|
13080
|
+
if (response && typeof response === "object") {
|
|
13081
|
+
const content = response.content;
|
|
13082
|
+
const flattened = flattenContent(content);
|
|
13083
|
+
if (flattened) {
|
|
13084
|
+
return flattened;
|
|
13085
|
+
}
|
|
13086
|
+
}
|
|
13087
|
+
const output = record.output;
|
|
13088
|
+
const flattenedOutput = flattenContent(output);
|
|
13089
|
+
if (flattenedOutput) {
|
|
13090
|
+
return flattenedOutput;
|
|
13091
|
+
}
|
|
13092
|
+
throw new Error("Codex CLI JSON response did not include an assistant message");
|
|
13093
|
+
}
|
|
13094
|
+
function extractFromEventStream(events) {
|
|
13095
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
13096
|
+
const candidate = events[index];
|
|
13097
|
+
const text = extractFromEvent(candidate);
|
|
13098
|
+
if (text) {
|
|
13099
|
+
return text;
|
|
13100
|
+
}
|
|
13101
|
+
}
|
|
13102
|
+
return void 0;
|
|
13103
|
+
}
|
|
13104
|
+
function extractFromEvent(event) {
|
|
13105
|
+
if (!event || typeof event !== "object") {
|
|
13106
|
+
return void 0;
|
|
13107
|
+
}
|
|
13108
|
+
const record = event;
|
|
13109
|
+
const type = typeof record.type === "string" ? record.type : void 0;
|
|
13110
|
+
if (type === JSONL_TYPE_ITEM_COMPLETED) {
|
|
13111
|
+
const item = record.item;
|
|
13112
|
+
const text = extractFromItem(item);
|
|
13113
|
+
if (text) {
|
|
13114
|
+
return text;
|
|
13115
|
+
}
|
|
13116
|
+
}
|
|
13117
|
+
const output = record.output ?? record.content;
|
|
13118
|
+
const flattened = flattenContent(output);
|
|
13119
|
+
if (flattened) {
|
|
13120
|
+
return flattened;
|
|
13121
|
+
}
|
|
13122
|
+
return void 0;
|
|
13123
|
+
}
|
|
13124
|
+
function extractFromItem(item) {
|
|
13125
|
+
if (!item || typeof item !== "object") {
|
|
13126
|
+
return void 0;
|
|
13127
|
+
}
|
|
13128
|
+
const record = item;
|
|
13129
|
+
const itemType = typeof record.type === "string" ? record.type : void 0;
|
|
13130
|
+
if (itemType === "agent_message" || itemType === "response" || itemType === "output") {
|
|
13131
|
+
const text = flattenContent(record.text ?? record.content ?? record.output);
|
|
13132
|
+
if (text) {
|
|
13133
|
+
return text;
|
|
13134
|
+
}
|
|
13135
|
+
}
|
|
13136
|
+
return void 0;
|
|
13137
|
+
}
|
|
13138
|
+
function flattenContent(value) {
|
|
13139
|
+
if (typeof value === "string") {
|
|
13140
|
+
return value;
|
|
13141
|
+
}
|
|
13142
|
+
if (Array.isArray(value)) {
|
|
13143
|
+
const parts = value.map((segment) => {
|
|
13144
|
+
if (typeof segment === "string") {
|
|
13145
|
+
return segment;
|
|
13146
|
+
}
|
|
13147
|
+
if (segment && typeof segment === "object" && "text" in segment) {
|
|
13148
|
+
const text = segment.text;
|
|
13149
|
+
return typeof text === "string" ? text : void 0;
|
|
13150
|
+
}
|
|
13151
|
+
return void 0;
|
|
13152
|
+
}).filter((part) => typeof part === "string" && part.length > 0);
|
|
13153
|
+
return parts.length > 0 ? parts.join(" \n") : void 0;
|
|
13154
|
+
}
|
|
13155
|
+
if (value && typeof value === "object" && "text" in value) {
|
|
13156
|
+
const text = value.text;
|
|
13157
|
+
return typeof text === "string" ? text : void 0;
|
|
13158
|
+
}
|
|
13159
|
+
return void 0;
|
|
13160
|
+
}
|
|
13161
|
+
function parseJsonLines(output) {
|
|
13162
|
+
const lines = output.split(/\r?\n/).map((line2) => line2.trim()).filter((line2) => line2.length > 0);
|
|
13163
|
+
if (lines.length <= 1) {
|
|
13164
|
+
return void 0;
|
|
13165
|
+
}
|
|
13166
|
+
const parsed = [];
|
|
13167
|
+
for (const line2 of lines) {
|
|
13168
|
+
try {
|
|
13169
|
+
parsed.push(JSON.parse(line2));
|
|
13170
|
+
} catch {
|
|
13171
|
+
return void 0;
|
|
13172
|
+
}
|
|
13173
|
+
}
|
|
13174
|
+
return parsed;
|
|
13175
|
+
}
|
|
13176
|
+
function pickDetail(stderr, stdout) {
|
|
13177
|
+
const errorText = stderr.trim();
|
|
13178
|
+
if (errorText.length > 0) {
|
|
13179
|
+
return errorText;
|
|
13180
|
+
}
|
|
13181
|
+
const stdoutText = stdout.trim();
|
|
13182
|
+
return stdoutText.length > 0 ? stdoutText : void 0;
|
|
13183
|
+
}
|
|
13184
|
+
function formatTimeoutSuffix2(timeoutMs) {
|
|
13185
|
+
if (!timeoutMs || timeoutMs <= 0) {
|
|
13186
|
+
return "";
|
|
13187
|
+
}
|
|
13188
|
+
const seconds = Math.ceil(timeoutMs / 1e3);
|
|
13189
|
+
return ` after ${seconds}s`;
|
|
13190
|
+
}
|
|
13191
|
+
async function defaultCodexRunner(options) {
|
|
13192
|
+
return await new Promise((resolve, reject) => {
|
|
13193
|
+
const child = spawn2(options.executable, options.args, {
|
|
13194
|
+
cwd: options.cwd,
|
|
13195
|
+
env: options.env,
|
|
13196
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
13197
|
+
shell: shouldShellExecute(options.executable)
|
|
13198
|
+
});
|
|
13199
|
+
let stdout = "";
|
|
13200
|
+
let stderr = "";
|
|
13201
|
+
let timedOut = false;
|
|
13202
|
+
const onAbort = () => {
|
|
13203
|
+
child.kill("SIGTERM");
|
|
13204
|
+
};
|
|
13205
|
+
if (options.signal) {
|
|
13206
|
+
if (options.signal.aborted) {
|
|
13207
|
+
onAbort();
|
|
13208
|
+
} else {
|
|
13209
|
+
options.signal.addEventListener("abort", onAbort, { once: true });
|
|
13210
|
+
}
|
|
13211
|
+
}
|
|
13212
|
+
let timeoutHandle;
|
|
13213
|
+
if (options.timeoutMs && options.timeoutMs > 0) {
|
|
13214
|
+
timeoutHandle = setTimeout(() => {
|
|
13215
|
+
timedOut = true;
|
|
13216
|
+
child.kill("SIGTERM");
|
|
13217
|
+
}, options.timeoutMs);
|
|
13218
|
+
timeoutHandle.unref?.();
|
|
13219
|
+
}
|
|
13220
|
+
child.stdout.setEncoding("utf8");
|
|
13221
|
+
child.stdout.on("data", (chunk) => {
|
|
13222
|
+
stdout += chunk;
|
|
13223
|
+
});
|
|
13224
|
+
child.stderr.setEncoding("utf8");
|
|
13225
|
+
child.stderr.on("data", (chunk) => {
|
|
13226
|
+
stderr += chunk;
|
|
13227
|
+
});
|
|
13228
|
+
child.stdin.end(options.prompt);
|
|
13229
|
+
const cleanup = () => {
|
|
13230
|
+
if (timeoutHandle) {
|
|
13231
|
+
clearTimeout(timeoutHandle);
|
|
13232
|
+
}
|
|
13233
|
+
if (options.signal) {
|
|
13234
|
+
options.signal.removeEventListener("abort", onAbort);
|
|
13235
|
+
}
|
|
13236
|
+
};
|
|
13237
|
+
child.on("error", (error) => {
|
|
13238
|
+
cleanup();
|
|
13239
|
+
reject(error);
|
|
13240
|
+
});
|
|
13241
|
+
child.on("close", (code) => {
|
|
13242
|
+
cleanup();
|
|
13243
|
+
resolve({
|
|
13244
|
+
stdout,
|
|
13245
|
+
stderr,
|
|
13246
|
+
exitCode: typeof code === "number" ? code : -1,
|
|
13247
|
+
timedOut
|
|
13248
|
+
});
|
|
13249
|
+
});
|
|
13250
|
+
});
|
|
13251
|
+
}
|
|
13252
|
+
function shouldShellExecute(executable) {
|
|
13253
|
+
if (process.platform !== "win32") {
|
|
13254
|
+
return false;
|
|
13255
|
+
}
|
|
13256
|
+
const lower = executable.toLowerCase();
|
|
13257
|
+
return lower.endsWith(".cmd") || lower.endsWith(".bat") || lower.endsWith(".ps1");
|
|
13258
|
+
}
|
|
13259
|
+
function isRecord(value) {
|
|
13260
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13261
|
+
}
|
|
13262
|
+
function checkSchema(parsed, absolutePath) {
|
|
13263
|
+
const schema = parsed.$schema;
|
|
13264
|
+
if (schema === void 0) {
|
|
13265
|
+
throw new Error(
|
|
13266
|
+
`Missing $schema field in targets.yaml at ${absolutePath}.
|
|
13267
|
+
Please add '$schema: ${TARGETS_SCHEMA_V2}' at the top of the file.`
|
|
13268
|
+
);
|
|
13269
|
+
}
|
|
13270
|
+
if (typeof schema !== "string") {
|
|
13271
|
+
throw new Error(
|
|
13272
|
+
`Invalid $schema field in targets.yaml at ${absolutePath}.
|
|
13273
|
+
Expected a string value '${TARGETS_SCHEMA_V2}'.`
|
|
13274
|
+
);
|
|
13275
|
+
}
|
|
13276
|
+
if (schema !== TARGETS_SCHEMA_V2) {
|
|
13277
|
+
throw new Error(
|
|
13278
|
+
`Invalid $schema '${schema}' in targets.yaml at ${absolutePath}.
|
|
13279
|
+
Expected '${TARGETS_SCHEMA_V2}'.`
|
|
13280
|
+
);
|
|
13281
|
+
}
|
|
13282
|
+
}
|
|
13283
|
+
function extractTargetsArray(parsed, absolutePath) {
|
|
13284
|
+
const targets = parsed.targets;
|
|
13285
|
+
if (!Array.isArray(targets)) {
|
|
13286
|
+
throw new Error(`targets.yaml at ${absolutePath} must have a 'targets' array`);
|
|
13287
|
+
}
|
|
13288
|
+
return targets;
|
|
13289
|
+
}
|
|
13290
|
+
function assertTargetDefinition(value, index, filePath) {
|
|
13291
|
+
if (!isRecord(value)) {
|
|
13292
|
+
throw new Error(`targets.yaml entry at index ${index} in ${filePath} must be an object`);
|
|
13293
|
+
}
|
|
13294
|
+
const name = value.name;
|
|
13295
|
+
const provider = value.provider;
|
|
13296
|
+
const settings = value.settings;
|
|
13297
|
+
const judgeTarget = value.judge_target;
|
|
13298
|
+
if (typeof name !== "string" || name.trim().length === 0) {
|
|
13299
|
+
throw new Error(`targets.yaml entry at index ${index} in ${filePath} is missing a valid 'name'`);
|
|
13300
|
+
}
|
|
13301
|
+
if (typeof provider !== "string" || provider.trim().length === 0) {
|
|
13302
|
+
throw new Error(`targets.yaml entry '${name}' in ${filePath} is missing a valid 'provider'`);
|
|
13303
|
+
}
|
|
13304
|
+
return {
|
|
13305
|
+
name,
|
|
12252
13306
|
provider,
|
|
12253
13307
|
settings: isRecord(settings) ? settings : void 0,
|
|
12254
13308
|
judge_target: typeof judgeTarget === "string" ? judgeTarget : void 0
|
|
@@ -12256,14 +13310,14 @@ function assertTargetDefinition(value, index, filePath) {
|
|
|
12256
13310
|
}
|
|
12257
13311
|
async function fileExists3(filePath) {
|
|
12258
13312
|
try {
|
|
12259
|
-
await
|
|
13313
|
+
await access32(filePath, constants32.F_OK);
|
|
12260
13314
|
return true;
|
|
12261
13315
|
} catch {
|
|
12262
13316
|
return false;
|
|
12263
13317
|
}
|
|
12264
13318
|
}
|
|
12265
13319
|
async function readTargetDefinitions(filePath) {
|
|
12266
|
-
const absolutePath =
|
|
13320
|
+
const absolutePath = path62.resolve(filePath);
|
|
12267
13321
|
if (!await fileExists3(absolutePath)) {
|
|
12268
13322
|
throw new Error(`targets.yaml not found at ${absolutePath}`);
|
|
12269
13323
|
}
|
|
@@ -12288,6 +13342,10 @@ function createProvider(target) {
|
|
|
12288
13342
|
return new AnthropicProvider(target.name, target.config);
|
|
12289
13343
|
case "gemini":
|
|
12290
13344
|
return new GeminiProvider(target.name, target.config);
|
|
13345
|
+
case "cli":
|
|
13346
|
+
return new CliProvider(target.name, target.config);
|
|
13347
|
+
case "codex":
|
|
13348
|
+
return new CodexProvider(target.name, target.config);
|
|
12291
13349
|
case "mock":
|
|
12292
13350
|
return new MockProvider(target.name, target.config);
|
|
12293
13351
|
case "vscode":
|
|
@@ -12299,222 +13357,28 @@ function createProvider(target) {
|
|
|
12299
13357
|
}
|
|
12300
13358
|
}
|
|
12301
13359
|
}
|
|
12302
|
-
var
|
|
12303
|
-
var ACTION_WORDS = /* @__PURE__ */ new Set([
|
|
12304
|
-
"use",
|
|
12305
|
-
"avoid",
|
|
12306
|
-
"prefer",
|
|
12307
|
-
"replace",
|
|
12308
|
-
"consider",
|
|
12309
|
-
"ensure",
|
|
12310
|
-
"remove",
|
|
12311
|
-
"add"
|
|
12312
|
-
]);
|
|
12313
|
-
var STOP_WORDS = /* @__PURE__ */ new Set([
|
|
12314
|
-
"the",
|
|
12315
|
-
"a",
|
|
12316
|
-
"an",
|
|
12317
|
-
"and",
|
|
12318
|
-
"or",
|
|
12319
|
-
"but",
|
|
12320
|
-
"in",
|
|
12321
|
-
"on",
|
|
12322
|
-
"at",
|
|
12323
|
-
"to",
|
|
12324
|
-
"for",
|
|
12325
|
-
"of",
|
|
12326
|
-
"with",
|
|
12327
|
-
"by",
|
|
12328
|
-
"is",
|
|
12329
|
-
"are",
|
|
12330
|
-
"was",
|
|
12331
|
-
"were",
|
|
12332
|
-
"be",
|
|
12333
|
-
"been",
|
|
12334
|
-
"being",
|
|
12335
|
-
"have",
|
|
12336
|
-
"has",
|
|
12337
|
-
"had",
|
|
12338
|
-
"do",
|
|
12339
|
-
"does",
|
|
12340
|
-
"did",
|
|
12341
|
-
"will",
|
|
12342
|
-
"would",
|
|
12343
|
-
"could",
|
|
12344
|
-
"should"
|
|
12345
|
-
]);
|
|
12346
|
-
var ERROR_PREFIXES = [
|
|
12347
|
-
"error:",
|
|
12348
|
-
"err:",
|
|
12349
|
-
"vs code command failed",
|
|
12350
|
-
"exception",
|
|
12351
|
-
"traceback",
|
|
12352
|
-
"no response file was generated",
|
|
12353
|
-
"timed out",
|
|
12354
|
-
"cli not found"
|
|
12355
|
-
];
|
|
12356
|
-
function extractAspects(expectedResponse) {
|
|
12357
|
-
const lines = expectedResponse.split(/\r?\n/).map((line2) => line2.trim());
|
|
12358
|
-
const aspects = [];
|
|
12359
|
-
for (const line2 of lines) {
|
|
12360
|
-
if (line2.length === 0) {
|
|
12361
|
-
continue;
|
|
12362
|
-
}
|
|
12363
|
-
const bulletMatch = /^([-*•]|[0-9]+\.)\s*(.+)$/.exec(line2);
|
|
12364
|
-
if (bulletMatch) {
|
|
12365
|
-
const normalized = normalizeAspect(bulletMatch[2]);
|
|
12366
|
-
if (normalized.length > 0) {
|
|
12367
|
-
aspects.push(normalized);
|
|
12368
|
-
}
|
|
12369
|
-
continue;
|
|
12370
|
-
}
|
|
12371
|
-
const lowered = line2.toLowerCase();
|
|
12372
|
-
if (Array.from(ACTION_WORDS).some((word) => lowered.startsWith(word))) {
|
|
12373
|
-
const normalized = normalizeAspect(line2);
|
|
12374
|
-
if (normalized.length > 0) {
|
|
12375
|
-
aspects.push(normalized);
|
|
12376
|
-
}
|
|
12377
|
-
}
|
|
12378
|
-
}
|
|
12379
|
-
return aspects;
|
|
12380
|
-
}
|
|
12381
|
-
function calculateHits(candidateResponse, expectedAspects) {
|
|
12382
|
-
const { normalizedText, words } = normalizeCandidate(candidateResponse);
|
|
12383
|
-
const hits = [];
|
|
12384
|
-
for (const aspect of expectedAspects) {
|
|
12385
|
-
if (matchesAspect(aspect, normalizedText, words)) {
|
|
12386
|
-
hits.push(aspect);
|
|
12387
|
-
}
|
|
12388
|
-
}
|
|
12389
|
-
return hits;
|
|
12390
|
-
}
|
|
12391
|
-
function scoreCandidateResponse(candidateResponse, expectedAspects) {
|
|
12392
|
-
if (expectedAspects.length === 0) {
|
|
12393
|
-
if (isErrorLike(candidateResponse)) {
|
|
12394
|
-
return {
|
|
12395
|
-
score: 0,
|
|
12396
|
-
hits: [],
|
|
12397
|
-
misses: ["Model produced an error instead of an answer."],
|
|
12398
|
-
hitCount: 0,
|
|
12399
|
-
totalAspects: 0,
|
|
12400
|
-
rawAspects: []
|
|
12401
|
-
};
|
|
12402
|
-
}
|
|
12403
|
-
return {
|
|
12404
|
-
score: 1,
|
|
12405
|
-
hits: [],
|
|
12406
|
-
misses: [],
|
|
12407
|
-
hitCount: 0,
|
|
12408
|
-
totalAspects: 0,
|
|
12409
|
-
rawAspects: []
|
|
12410
|
-
};
|
|
12411
|
-
}
|
|
12412
|
-
const hits = calculateHits(candidateResponse, expectedAspects);
|
|
12413
|
-
const misses = expectedAspects.filter((aspect) => !hits.includes(aspect));
|
|
12414
|
-
const score = expectedAspects.length > 0 ? hits.length / expectedAspects.length : 0;
|
|
12415
|
-
return {
|
|
12416
|
-
score,
|
|
12417
|
-
hits,
|
|
12418
|
-
misses,
|
|
12419
|
-
hitCount: hits.length,
|
|
12420
|
-
totalAspects: expectedAspects.length,
|
|
12421
|
-
rawAspects: expectedAspects
|
|
12422
|
-
};
|
|
12423
|
-
}
|
|
12424
|
-
function isErrorLike(text) {
|
|
12425
|
-
if (!text) {
|
|
12426
|
-
return false;
|
|
12427
|
-
}
|
|
12428
|
-
const lowered = text.trim().toLowerCase();
|
|
12429
|
-
return ERROR_PREFIXES.some((prefix) => lowered.startsWith(prefix));
|
|
12430
|
-
}
|
|
12431
|
-
function normalizeAspect(aspect) {
|
|
12432
|
-
const sanitized = aspect.toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
12433
|
-
return sanitized;
|
|
12434
|
-
}
|
|
12435
|
-
function normalizeCandidate(candidate) {
|
|
12436
|
-
const lowered = candidate.toLowerCase();
|
|
12437
|
-
const normalizedText = lowered.replace(/[^\w\s]/g, " ");
|
|
12438
|
-
const words = new Set(normalizedText.split(/\s+/).filter((word) => word.length > 0));
|
|
12439
|
-
return { normalizedText, words };
|
|
12440
|
-
}
|
|
12441
|
-
function matchesAspect(aspect, candidateNormalized, candidateWords) {
|
|
12442
|
-
const keyTerms = extractKeyTerms(aspect);
|
|
12443
|
-
if (keyTerms.length === 0) {
|
|
12444
|
-
return false;
|
|
12445
|
-
}
|
|
12446
|
-
const matches = keyTerms.filter((term) => candidateWords.has(term)).length;
|
|
12447
|
-
const ratio = matches / keyTerms.length;
|
|
12448
|
-
if (ratio >= KEY_TERM_MATCH_THRESHOLD) {
|
|
12449
|
-
return true;
|
|
12450
|
-
}
|
|
12451
|
-
const aspectWords = aspect.split(" ");
|
|
12452
|
-
if (aspectWords.length >= 2) {
|
|
12453
|
-
for (let index = 0; index < aspectWords.length - 1; index += 1) {
|
|
12454
|
-
const phrase = `${aspectWords[index]} ${aspectWords[index + 1]}`;
|
|
12455
|
-
if (candidateNormalized.includes(phrase)) {
|
|
12456
|
-
return true;
|
|
12457
|
-
}
|
|
12458
|
-
}
|
|
12459
|
-
}
|
|
12460
|
-
return false;
|
|
12461
|
-
}
|
|
12462
|
-
function extractKeyTerms(aspect, maxTerms = 5) {
|
|
12463
|
-
const terms = [];
|
|
12464
|
-
const words = aspect.split(" ");
|
|
12465
|
-
for (const word of words) {
|
|
12466
|
-
if (word.length <= 2) {
|
|
12467
|
-
continue;
|
|
12468
|
-
}
|
|
12469
|
-
if (STOP_WORDS.has(word)) {
|
|
12470
|
-
continue;
|
|
12471
|
-
}
|
|
12472
|
-
terms.push(word);
|
|
12473
|
-
if (terms.length >= maxTerms) {
|
|
12474
|
-
break;
|
|
12475
|
-
}
|
|
12476
|
-
}
|
|
12477
|
-
return terms;
|
|
12478
|
-
}
|
|
12479
|
-
var HeuristicGrader = class {
|
|
12480
|
-
kind = "heuristic";
|
|
12481
|
-
grade(context2) {
|
|
12482
|
-
const expectedAspects = extractAspects(context2.evalCase.expected_assistant_raw);
|
|
12483
|
-
const result = scoreCandidateResponse(context2.candidate, expectedAspects);
|
|
12484
|
-
const misses = [...result.misses];
|
|
12485
|
-
if (expectedAspects.length === 0 && isErrorLike(context2.candidate)) {
|
|
12486
|
-
const firstLine = context2.candidate.split(/\r?\n/)[0]?.trim();
|
|
12487
|
-
if (firstLine && !misses.includes(firstLine)) {
|
|
12488
|
-
misses.unshift(firstLine);
|
|
12489
|
-
}
|
|
12490
|
-
}
|
|
12491
|
-
return {
|
|
12492
|
-
score: result.score,
|
|
12493
|
-
hits: result.hits,
|
|
12494
|
-
misses,
|
|
12495
|
-
expectedAspectCount: result.totalAspects,
|
|
12496
|
-
rawAspects: result.rawAspects
|
|
12497
|
-
};
|
|
12498
|
-
}
|
|
12499
|
-
};
|
|
12500
|
-
var QualityGrader = class {
|
|
13360
|
+
var LlmJudgeEvaluator = class {
|
|
12501
13361
|
kind = "llm_judge";
|
|
12502
13362
|
resolveJudgeProvider;
|
|
12503
13363
|
maxOutputTokens;
|
|
12504
13364
|
temperature;
|
|
13365
|
+
customPrompt;
|
|
12505
13366
|
constructor(options) {
|
|
12506
13367
|
this.resolveJudgeProvider = options.resolveJudgeProvider;
|
|
12507
13368
|
this.maxOutputTokens = options.maxOutputTokens;
|
|
12508
13369
|
this.temperature = options.temperature;
|
|
13370
|
+
this.customPrompt = options.customPrompt;
|
|
12509
13371
|
}
|
|
12510
|
-
async
|
|
13372
|
+
async evaluate(context2) {
|
|
12511
13373
|
const judgeProvider = await this.resolveJudgeProvider(context2);
|
|
12512
13374
|
if (!judgeProvider) {
|
|
12513
13375
|
throw new Error("No judge provider available for LLM grading");
|
|
12514
13376
|
}
|
|
12515
13377
|
const prompt = buildQualityPrompt(context2.evalCase, context2.candidate);
|
|
13378
|
+
const systemPrompt = context2.systemPrompt ?? this.customPrompt ?? QUALITY_SYSTEM_PROMPT;
|
|
12516
13379
|
const metadata = {
|
|
12517
|
-
systemPrompt:
|
|
13380
|
+
...systemPrompt !== void 0 ? { systemPrompt } : {},
|
|
13381
|
+
...context2.judgeModel !== void 0 ? { model: context2.judgeModel } : {}
|
|
12518
13382
|
};
|
|
12519
13383
|
const response = await judgeProvider.invoke({
|
|
12520
13384
|
prompt,
|
|
@@ -12529,12 +13393,13 @@ var QualityGrader = class {
|
|
|
12529
13393
|
const hits = Array.isArray(parsed.hits) ? parsed.hits.filter(isNonEmptyString).slice(0, 4) : [];
|
|
12530
13394
|
const misses = Array.isArray(parsed.misses) ? parsed.misses.filter(isNonEmptyString).slice(0, 4) : [];
|
|
12531
13395
|
const reasoning = parsed.reasoning ?? response.reasoning;
|
|
12532
|
-
const
|
|
13396
|
+
const evaluatorRawRequest = {
|
|
12533
13397
|
id: randomUUID(),
|
|
12534
13398
|
provider: judgeProvider.id,
|
|
12535
13399
|
prompt,
|
|
12536
|
-
|
|
12537
|
-
|
|
13400
|
+
target: context2.target.name,
|
|
13401
|
+
...systemPrompt !== void 0 ? { systemPrompt } : {},
|
|
13402
|
+
...context2.judgeModel !== void 0 ? { model: context2.judgeModel } : {}
|
|
12538
13403
|
};
|
|
12539
13404
|
return {
|
|
12540
13405
|
score,
|
|
@@ -12542,7 +13407,7 @@ var QualityGrader = class {
|
|
|
12542
13407
|
misses,
|
|
12543
13408
|
expectedAspectCount: hits.length + misses.length || 1,
|
|
12544
13409
|
reasoning,
|
|
12545
|
-
|
|
13410
|
+
evaluatorRawRequest
|
|
12546
13411
|
};
|
|
12547
13412
|
}
|
|
12548
13413
|
};
|
|
@@ -12660,6 +13525,112 @@ function extractJsonBlob(text) {
|
|
|
12660
13525
|
function isNonEmptyString(value) {
|
|
12661
13526
|
return typeof value === "string" && value.trim().length > 0;
|
|
12662
13527
|
}
|
|
13528
|
+
var CodeEvaluator = class {
|
|
13529
|
+
kind = "code";
|
|
13530
|
+
script;
|
|
13531
|
+
cwd;
|
|
13532
|
+
agentTimeoutMs;
|
|
13533
|
+
constructor(options) {
|
|
13534
|
+
this.script = options.script;
|
|
13535
|
+
this.cwd = options.cwd;
|
|
13536
|
+
this.agentTimeoutMs = options.agentTimeoutMs;
|
|
13537
|
+
}
|
|
13538
|
+
async evaluate(context2) {
|
|
13539
|
+
const inputPayload = JSON.stringify(
|
|
13540
|
+
{
|
|
13541
|
+
task: context2.evalCase.task,
|
|
13542
|
+
outcome: context2.evalCase.outcome,
|
|
13543
|
+
expected: context2.evalCase.expected_assistant_raw,
|
|
13544
|
+
output: context2.candidate,
|
|
13545
|
+
system_message: context2.promptInputs.systemMessage ?? "",
|
|
13546
|
+
guideline_paths: context2.evalCase.guideline_paths,
|
|
13547
|
+
attachments: context2.evalCase.file_paths,
|
|
13548
|
+
user_segments: context2.evalCase.user_segments
|
|
13549
|
+
},
|
|
13550
|
+
null,
|
|
13551
|
+
2
|
|
13552
|
+
);
|
|
13553
|
+
try {
|
|
13554
|
+
const stdout = await executeScript(this.script, inputPayload, this.agentTimeoutMs, this.cwd);
|
|
13555
|
+
const parsed = parseJsonSafe(stdout);
|
|
13556
|
+
const score = clampScore(typeof parsed?.score === "number" ? parsed.score : 0);
|
|
13557
|
+
const hits = Array.isArray(parsed?.hits) ? parsed.hits.filter(isNonEmptyString) : [];
|
|
13558
|
+
const misses = Array.isArray(parsed?.misses) ? parsed.misses.filter(isNonEmptyString) : [];
|
|
13559
|
+
const reasoning = typeof parsed?.reasoning === "string" ? parsed.reasoning : void 0;
|
|
13560
|
+
return {
|
|
13561
|
+
score,
|
|
13562
|
+
hits,
|
|
13563
|
+
misses,
|
|
13564
|
+
expectedAspectCount: hits.length + misses.length || 1,
|
|
13565
|
+
reasoning,
|
|
13566
|
+
evaluatorRawRequest: {
|
|
13567
|
+
script: this.script,
|
|
13568
|
+
...this.cwd ? { cwd: this.cwd } : {}
|
|
13569
|
+
}
|
|
13570
|
+
};
|
|
13571
|
+
} catch (error) {
|
|
13572
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
13573
|
+
return {
|
|
13574
|
+
score: 0,
|
|
13575
|
+
hits: [],
|
|
13576
|
+
misses: [`Code evaluator failed: ${message}`],
|
|
13577
|
+
expectedAspectCount: 1,
|
|
13578
|
+
reasoning: message,
|
|
13579
|
+
evaluatorRawRequest: {
|
|
13580
|
+
script: this.script,
|
|
13581
|
+
...this.cwd ? { cwd: this.cwd } : {},
|
|
13582
|
+
error: message
|
|
13583
|
+
}
|
|
13584
|
+
};
|
|
13585
|
+
}
|
|
13586
|
+
}
|
|
13587
|
+
};
|
|
13588
|
+
async function executeScript(scriptPath, input, agentTimeoutMs, cwd) {
|
|
13589
|
+
const { spawn: spawn22 } = await import("node:child_process");
|
|
13590
|
+
return await new Promise((resolve, reject) => {
|
|
13591
|
+
const child = spawn22(scriptPath, {
|
|
13592
|
+
shell: true,
|
|
13593
|
+
cwd
|
|
13594
|
+
});
|
|
13595
|
+
let stdout = "";
|
|
13596
|
+
let stderr = "";
|
|
13597
|
+
const timeout = agentTimeoutMs ? setTimeout(() => {
|
|
13598
|
+
child.kill();
|
|
13599
|
+
reject(new Error(`Code evaluator timed out after ${agentTimeoutMs}ms`));
|
|
13600
|
+
}, agentTimeoutMs) : void 0;
|
|
13601
|
+
child.stdout?.on("data", (data) => {
|
|
13602
|
+
stdout += data.toString();
|
|
13603
|
+
});
|
|
13604
|
+
child.stderr?.on("data", (data) => {
|
|
13605
|
+
stderr += data.toString();
|
|
13606
|
+
});
|
|
13607
|
+
child.on("error", (error) => {
|
|
13608
|
+
if (timeout !== void 0) {
|
|
13609
|
+
clearTimeout(timeout);
|
|
13610
|
+
}
|
|
13611
|
+
reject(error);
|
|
13612
|
+
});
|
|
13613
|
+
child.on("exit", (code) => {
|
|
13614
|
+
if (timeout !== void 0) {
|
|
13615
|
+
clearTimeout(timeout);
|
|
13616
|
+
}
|
|
13617
|
+
if (code && code !== 0 && stderr.length > 0) {
|
|
13618
|
+
reject(new Error(`Code evaluator exited with code ${code}: ${stderr.trim()}`));
|
|
13619
|
+
return;
|
|
13620
|
+
}
|
|
13621
|
+
resolve(stdout.trim());
|
|
13622
|
+
});
|
|
13623
|
+
child.stdin?.write(input);
|
|
13624
|
+
child.stdin?.end();
|
|
13625
|
+
});
|
|
13626
|
+
}
|
|
13627
|
+
function parseJsonSafe(payload) {
|
|
13628
|
+
try {
|
|
13629
|
+
return JSON.parse(payload);
|
|
13630
|
+
} catch {
|
|
13631
|
+
return void 0;
|
|
13632
|
+
}
|
|
13633
|
+
}
|
|
12663
13634
|
var Node = class {
|
|
12664
13635
|
value;
|
|
12665
13636
|
next;
|
|
@@ -12800,7 +13771,7 @@ async function runEvaluation(options) {
|
|
|
12800
13771
|
targets,
|
|
12801
13772
|
env,
|
|
12802
13773
|
providerFactory,
|
|
12803
|
-
|
|
13774
|
+
evaluators,
|
|
12804
13775
|
maxRetries,
|
|
12805
13776
|
agentTimeoutMs,
|
|
12806
13777
|
promptDumpDir,
|
|
@@ -12859,7 +13830,7 @@ async function runEvaluation(options) {
|
|
|
12859
13830
|
}
|
|
12860
13831
|
return getOrCreateProvider(resolvedJudge);
|
|
12861
13832
|
};
|
|
12862
|
-
const
|
|
13833
|
+
const evaluatorRegistry = buildEvaluatorRegistry(evaluators, resolveJudgeProvider);
|
|
12863
13834
|
const primaryProvider = getOrCreateProvider(target);
|
|
12864
13835
|
const providerSupportsBatch = target.providerBatching === true && primaryProvider.supportsBatch === true && typeof primaryProvider.invokeBatch === "function";
|
|
12865
13836
|
if (target.providerBatching && !providerSupportsBatch && verbose) {
|
|
@@ -12882,13 +13853,14 @@ async function runEvaluation(options) {
|
|
|
12882
13853
|
evalCases: filteredEvalCases,
|
|
12883
13854
|
provider: primaryProvider,
|
|
12884
13855
|
target,
|
|
12885
|
-
|
|
13856
|
+
evaluatorRegistry,
|
|
12886
13857
|
promptDumpDir,
|
|
12887
13858
|
nowFn: now ?? (() => /* @__PURE__ */ new Date()),
|
|
12888
13859
|
onProgress,
|
|
12889
13860
|
onResult,
|
|
12890
13861
|
verbose,
|
|
12891
|
-
resolveJudgeProvider
|
|
13862
|
+
resolveJudgeProvider,
|
|
13863
|
+
agentTimeoutMs
|
|
12892
13864
|
});
|
|
12893
13865
|
} catch (error) {
|
|
12894
13866
|
if (verbose) {
|
|
@@ -12919,7 +13891,7 @@ async function runEvaluation(options) {
|
|
|
12919
13891
|
evalCase,
|
|
12920
13892
|
provider: primaryProvider,
|
|
12921
13893
|
target,
|
|
12922
|
-
|
|
13894
|
+
evaluators: evaluatorRegistry,
|
|
12923
13895
|
maxRetries,
|
|
12924
13896
|
agentTimeoutMs,
|
|
12925
13897
|
promptDumpDir,
|
|
@@ -12985,12 +13957,13 @@ async function runBatchEvaluation(options) {
|
|
|
12985
13957
|
evalCases,
|
|
12986
13958
|
provider,
|
|
12987
13959
|
target,
|
|
12988
|
-
|
|
13960
|
+
evaluatorRegistry,
|
|
12989
13961
|
promptDumpDir,
|
|
12990
13962
|
nowFn,
|
|
12991
13963
|
onProgress,
|
|
12992
13964
|
onResult,
|
|
12993
|
-
resolveJudgeProvider
|
|
13965
|
+
resolveJudgeProvider,
|
|
13966
|
+
agentTimeoutMs
|
|
12994
13967
|
} = options;
|
|
12995
13968
|
const promptInputsList = [];
|
|
12996
13969
|
for (const evalCase of evalCases) {
|
|
@@ -13006,7 +13979,7 @@ async function runBatchEvaluation(options) {
|
|
|
13006
13979
|
prompt: promptInputs.request,
|
|
13007
13980
|
guidelines: promptInputs.guidelines,
|
|
13008
13981
|
guideline_patterns: evalCase.guideline_patterns,
|
|
13009
|
-
|
|
13982
|
+
inputFiles: evalCase.file_paths,
|
|
13010
13983
|
evalCaseId: evalCase.id,
|
|
13011
13984
|
metadata: {
|
|
13012
13985
|
systemPrompt: promptInputs.systemMessage ?? ""
|
|
@@ -13038,23 +14011,19 @@ async function runBatchEvaluation(options) {
|
|
|
13038
14011
|
const evalCase = evalCases[i6];
|
|
13039
14012
|
const promptInputs = promptInputsList[i6];
|
|
13040
14013
|
const providerResponse = batchResponse[i6];
|
|
13041
|
-
|
|
13042
|
-
const graderKind = evalCase.grader ?? "heuristic";
|
|
13043
|
-
const activeGrader = graderRegistry[graderKind] ?? graderRegistry.heuristic;
|
|
13044
|
-
if (!activeGrader) {
|
|
13045
|
-
throw new Error(`No grader registered for kind '${graderKind}'`);
|
|
13046
|
-
}
|
|
13047
|
-
let grade;
|
|
14014
|
+
let result;
|
|
13048
14015
|
try {
|
|
13049
|
-
|
|
14016
|
+
result = await evaluateCandidate({
|
|
13050
14017
|
evalCase,
|
|
13051
14018
|
candidate: providerResponse.text ?? "",
|
|
13052
14019
|
target,
|
|
13053
14020
|
provider,
|
|
13054
|
-
|
|
14021
|
+
evaluators: evaluatorRegistry,
|
|
13055
14022
|
promptInputs,
|
|
13056
|
-
|
|
13057
|
-
|
|
14023
|
+
nowFn,
|
|
14024
|
+
attempt: 0,
|
|
14025
|
+
judgeProvider: await resolveJudgeProvider(target),
|
|
14026
|
+
agentTimeoutMs
|
|
13058
14027
|
});
|
|
13059
14028
|
} catch (error) {
|
|
13060
14029
|
const errorResult = buildErrorResult(evalCase, target.name, nowFn(), error, promptInputs);
|
|
@@ -13073,28 +14042,6 @@ async function runBatchEvaluation(options) {
|
|
|
13073
14042
|
}
|
|
13074
14043
|
continue;
|
|
13075
14044
|
}
|
|
13076
|
-
const completedAt = nowFn();
|
|
13077
|
-
const rawRequest = {
|
|
13078
|
-
request: promptInputs.request,
|
|
13079
|
-
guidelines: promptInputs.guidelines,
|
|
13080
|
-
guideline_paths: evalCase.guideline_paths,
|
|
13081
|
-
system_message: promptInputs.systemMessage ?? ""
|
|
13082
|
-
};
|
|
13083
|
-
const result = {
|
|
13084
|
-
eval_id: evalCase.id,
|
|
13085
|
-
conversation_id: evalCase.conversation_id,
|
|
13086
|
-
score: grade.score,
|
|
13087
|
-
hits: grade.hits,
|
|
13088
|
-
misses: grade.misses,
|
|
13089
|
-
model_answer: providerResponse.text ?? "",
|
|
13090
|
-
expected_aspect_count: grade.expectedAspectCount,
|
|
13091
|
-
target: target.name,
|
|
13092
|
-
timestamp: completedAt.toISOString(),
|
|
13093
|
-
reasoning: grade.reasoning,
|
|
13094
|
-
raw_aspects: grade.rawAspects,
|
|
13095
|
-
raw_request: rawRequest,
|
|
13096
|
-
grader_raw_request: grade.graderRawRequest
|
|
13097
|
-
};
|
|
13098
14045
|
results.push(result);
|
|
13099
14046
|
if (onResult) {
|
|
13100
14047
|
await onResult(result);
|
|
@@ -13116,7 +14063,7 @@ async function runEvalCase(options) {
|
|
|
13116
14063
|
evalCase,
|
|
13117
14064
|
provider,
|
|
13118
14065
|
target,
|
|
13119
|
-
|
|
14066
|
+
evaluators,
|
|
13120
14067
|
now,
|
|
13121
14068
|
maxRetries,
|
|
13122
14069
|
agentTimeoutMs,
|
|
@@ -13171,27 +14118,49 @@ async function runEvalCase(options) {
|
|
|
13171
14118
|
if (cacheKey && cache && !cachedResponse) {
|
|
13172
14119
|
await cache.set(cacheKey, providerResponse);
|
|
13173
14120
|
}
|
|
13174
|
-
const graderKind = evalCase.grader ?? "heuristic";
|
|
13175
|
-
const activeGrader = graders[graderKind] ?? graders.heuristic;
|
|
13176
|
-
if (!activeGrader) {
|
|
13177
|
-
throw new Error(`No grader registered for kind '${graderKind}'`);
|
|
13178
|
-
}
|
|
13179
|
-
let grade;
|
|
13180
14121
|
try {
|
|
13181
|
-
|
|
13182
|
-
grade = await activeGrader.grade({
|
|
14122
|
+
return await evaluateCandidate({
|
|
13183
14123
|
evalCase,
|
|
13184
14124
|
candidate: providerResponse.text ?? "",
|
|
13185
14125
|
target,
|
|
13186
14126
|
provider,
|
|
13187
|
-
|
|
14127
|
+
evaluators,
|
|
13188
14128
|
promptInputs,
|
|
13189
|
-
|
|
13190
|
-
|
|
14129
|
+
nowFn,
|
|
14130
|
+
attempt,
|
|
14131
|
+
judgeProvider,
|
|
14132
|
+
agentTimeoutMs
|
|
13191
14133
|
});
|
|
13192
14134
|
} catch (error) {
|
|
13193
14135
|
return buildErrorResult(evalCase, target.name, nowFn(), error, promptInputs);
|
|
13194
14136
|
}
|
|
14137
|
+
}
|
|
14138
|
+
async function evaluateCandidate(options) {
|
|
14139
|
+
const {
|
|
14140
|
+
evalCase,
|
|
14141
|
+
candidate,
|
|
14142
|
+
target,
|
|
14143
|
+
provider,
|
|
14144
|
+
evaluators,
|
|
14145
|
+
promptInputs,
|
|
14146
|
+
nowFn,
|
|
14147
|
+
attempt,
|
|
14148
|
+
judgeProvider,
|
|
14149
|
+
agentTimeoutMs
|
|
14150
|
+
} = options;
|
|
14151
|
+
const gradeTimestamp = nowFn();
|
|
14152
|
+
const { score, evaluatorResults } = await runEvaluatorsForCase({
|
|
14153
|
+
evalCase,
|
|
14154
|
+
candidate,
|
|
14155
|
+
target,
|
|
14156
|
+
provider,
|
|
14157
|
+
evaluators,
|
|
14158
|
+
attempt,
|
|
14159
|
+
promptInputs,
|
|
14160
|
+
now: gradeTimestamp,
|
|
14161
|
+
judgeProvider,
|
|
14162
|
+
agentTimeoutMs
|
|
14163
|
+
});
|
|
13195
14164
|
const completedAt = nowFn();
|
|
13196
14165
|
const rawRequest = {
|
|
13197
14166
|
request: promptInputs.request,
|
|
@@ -13202,28 +14171,200 @@ async function runEvalCase(options) {
|
|
|
13202
14171
|
return {
|
|
13203
14172
|
eval_id: evalCase.id,
|
|
13204
14173
|
conversation_id: evalCase.conversation_id,
|
|
13205
|
-
score:
|
|
13206
|
-
hits:
|
|
13207
|
-
misses:
|
|
13208
|
-
model_answer:
|
|
13209
|
-
expected_aspect_count:
|
|
14174
|
+
score: score.score,
|
|
14175
|
+
hits: score.hits,
|
|
14176
|
+
misses: score.misses,
|
|
14177
|
+
model_answer: candidate,
|
|
14178
|
+
expected_aspect_count: score.expectedAspectCount,
|
|
13210
14179
|
target: target.name,
|
|
13211
14180
|
timestamp: completedAt.toISOString(),
|
|
13212
|
-
reasoning:
|
|
13213
|
-
raw_aspects:
|
|
14181
|
+
reasoning: score.reasoning,
|
|
14182
|
+
raw_aspects: score.rawAspects,
|
|
13214
14183
|
raw_request: rawRequest,
|
|
13215
|
-
|
|
14184
|
+
evaluator_raw_request: evaluatorResults ? void 0 : score.evaluatorRawRequest,
|
|
14185
|
+
evaluator_results: evaluatorResults
|
|
13216
14186
|
};
|
|
13217
14187
|
}
|
|
14188
|
+
async function runEvaluatorsForCase(options) {
|
|
14189
|
+
const { evalCase, candidate, target, provider, evaluators, attempt, promptInputs, now, judgeProvider, agentTimeoutMs } = options;
|
|
14190
|
+
if (evalCase.evaluators && evalCase.evaluators.length > 0) {
|
|
14191
|
+
return runEvaluatorList({
|
|
14192
|
+
evalCase,
|
|
14193
|
+
evaluators: evalCase.evaluators,
|
|
14194
|
+
candidate,
|
|
14195
|
+
target,
|
|
14196
|
+
provider,
|
|
14197
|
+
evaluatorRegistry: evaluators,
|
|
14198
|
+
attempt,
|
|
14199
|
+
promptInputs,
|
|
14200
|
+
now,
|
|
14201
|
+
judgeProvider,
|
|
14202
|
+
agentTimeoutMs
|
|
14203
|
+
});
|
|
14204
|
+
}
|
|
14205
|
+
const evaluatorKind = evalCase.evaluator ?? "llm_judge";
|
|
14206
|
+
const activeEvaluator = evaluators[evaluatorKind] ?? evaluators.llm_judge;
|
|
14207
|
+
if (!activeEvaluator) {
|
|
14208
|
+
throw new Error(`No evaluator registered for kind '${evaluatorKind}'`);
|
|
14209
|
+
}
|
|
14210
|
+
const score = await activeEvaluator.evaluate({
|
|
14211
|
+
evalCase,
|
|
14212
|
+
candidate,
|
|
14213
|
+
target,
|
|
14214
|
+
provider,
|
|
14215
|
+
attempt,
|
|
14216
|
+
promptInputs,
|
|
14217
|
+
now,
|
|
14218
|
+
judgeProvider
|
|
14219
|
+
});
|
|
14220
|
+
return { score };
|
|
14221
|
+
}
|
|
14222
|
+
async function runEvaluatorList(options) {
|
|
14223
|
+
const {
|
|
14224
|
+
evalCase,
|
|
14225
|
+
evaluators,
|
|
14226
|
+
candidate,
|
|
14227
|
+
target,
|
|
14228
|
+
provider,
|
|
14229
|
+
evaluatorRegistry,
|
|
14230
|
+
attempt,
|
|
14231
|
+
promptInputs,
|
|
14232
|
+
now,
|
|
14233
|
+
judgeProvider,
|
|
14234
|
+
agentTimeoutMs
|
|
14235
|
+
} = options;
|
|
14236
|
+
const scored = [];
|
|
14237
|
+
const evaluatorResults = [];
|
|
14238
|
+
for (const evaluator of evaluators ?? []) {
|
|
14239
|
+
try {
|
|
14240
|
+
if (evaluator.type === "llm_judge") {
|
|
14241
|
+
const score2 = await runLlmJudgeEvaluator({
|
|
14242
|
+
config: evaluator,
|
|
14243
|
+
evalCase,
|
|
14244
|
+
candidate,
|
|
14245
|
+
target,
|
|
14246
|
+
provider,
|
|
14247
|
+
evaluatorRegistry,
|
|
14248
|
+
attempt,
|
|
14249
|
+
promptInputs,
|
|
14250
|
+
now,
|
|
14251
|
+
judgeProvider
|
|
14252
|
+
});
|
|
14253
|
+
scored.push({ score: score2, name: evaluator.name, type: evaluator.type });
|
|
14254
|
+
evaluatorResults.push({
|
|
14255
|
+
name: evaluator.name,
|
|
14256
|
+
type: evaluator.type,
|
|
14257
|
+
score: score2.score,
|
|
14258
|
+
hits: score2.hits,
|
|
14259
|
+
misses: score2.misses,
|
|
14260
|
+
reasoning: score2.reasoning,
|
|
14261
|
+
evaluator_raw_request: score2.evaluatorRawRequest
|
|
14262
|
+
});
|
|
14263
|
+
continue;
|
|
14264
|
+
}
|
|
14265
|
+
if (evaluator.type === "code") {
|
|
14266
|
+
const codeEvaluator = new CodeEvaluator({
|
|
14267
|
+
script: evaluator.script,
|
|
14268
|
+
cwd: evaluator.resolvedCwd ?? evaluator.cwd,
|
|
14269
|
+
agentTimeoutMs
|
|
14270
|
+
});
|
|
14271
|
+
const score2 = await codeEvaluator.evaluate({
|
|
14272
|
+
evalCase,
|
|
14273
|
+
candidate,
|
|
14274
|
+
target,
|
|
14275
|
+
provider,
|
|
14276
|
+
attempt,
|
|
14277
|
+
promptInputs,
|
|
14278
|
+
now
|
|
14279
|
+
});
|
|
14280
|
+
scored.push({ score: score2, name: evaluator.name, type: evaluator.type });
|
|
14281
|
+
evaluatorResults.push({
|
|
14282
|
+
name: evaluator.name,
|
|
14283
|
+
type: evaluator.type,
|
|
14284
|
+
score: score2.score,
|
|
14285
|
+
hits: score2.hits,
|
|
14286
|
+
misses: score2.misses,
|
|
14287
|
+
reasoning: score2.reasoning,
|
|
14288
|
+
evaluator_raw_request: score2.evaluatorRawRequest
|
|
14289
|
+
});
|
|
14290
|
+
continue;
|
|
14291
|
+
}
|
|
14292
|
+
} catch (error) {
|
|
14293
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
14294
|
+
const fallbackScore = {
|
|
14295
|
+
score: 0,
|
|
14296
|
+
hits: [],
|
|
14297
|
+
misses: [`Evaluator '${evaluator.name}' failed: ${message}`],
|
|
14298
|
+
expectedAspectCount: 1,
|
|
14299
|
+
reasoning: message
|
|
14300
|
+
};
|
|
14301
|
+
scored.push({ score: fallbackScore, name: evaluator.name ?? "unknown", type: evaluator.type ?? "unknown" });
|
|
14302
|
+
evaluatorResults.push({
|
|
14303
|
+
name: evaluator.name ?? "unknown",
|
|
14304
|
+
type: evaluator.type ?? "unknown",
|
|
14305
|
+
score: 0,
|
|
14306
|
+
hits: [],
|
|
14307
|
+
misses: [`Evaluator '${evaluator.name ?? "unknown"}' failed: ${message}`],
|
|
14308
|
+
reasoning: message
|
|
14309
|
+
});
|
|
14310
|
+
}
|
|
14311
|
+
}
|
|
14312
|
+
const aggregateScore = scored.length > 0 ? scored.reduce((total, entry) => total + entry.score.score, 0) / scored.length : 0;
|
|
14313
|
+
const hits = scored.flatMap((entry) => entry.score.hits);
|
|
14314
|
+
const misses = scored.flatMap((entry) => entry.score.misses);
|
|
14315
|
+
const expectedAspectCount = scored.reduce((total, entry) => total + (entry.score.expectedAspectCount ?? 0), 0);
|
|
14316
|
+
const rawAspects = scored.flatMap((entry) => entry.score.rawAspects ?? []);
|
|
14317
|
+
const reasoningParts = scored.map((entry) => entry.score.reasoning ? `${entry.name}: ${entry.score.reasoning}` : void 0).filter(isNonEmptyString2);
|
|
14318
|
+
const reasoning = reasoningParts.length > 0 ? reasoningParts.join(" | ") : void 0;
|
|
14319
|
+
const score = {
|
|
14320
|
+
score: aggregateScore,
|
|
14321
|
+
hits,
|
|
14322
|
+
misses,
|
|
14323
|
+
expectedAspectCount,
|
|
14324
|
+
reasoning,
|
|
14325
|
+
rawAspects: rawAspects.length > 0 ? rawAspects : void 0
|
|
14326
|
+
};
|
|
14327
|
+
return { score, evaluatorResults };
|
|
14328
|
+
}
|
|
14329
|
+
async function runLlmJudgeEvaluator(options) {
|
|
14330
|
+
const { config, evalCase, candidate, target, provider, evaluatorRegistry, attempt, promptInputs, now, judgeProvider } = options;
|
|
14331
|
+
const customPrompt = await resolveCustomPrompt(config);
|
|
14332
|
+
return evaluatorRegistry.llm_judge.evaluate({
|
|
14333
|
+
evalCase,
|
|
14334
|
+
candidate,
|
|
14335
|
+
target,
|
|
14336
|
+
provider,
|
|
14337
|
+
attempt,
|
|
14338
|
+
promptInputs,
|
|
14339
|
+
now,
|
|
14340
|
+
judgeProvider,
|
|
14341
|
+
systemPrompt: customPrompt,
|
|
14342
|
+
evaluator: config,
|
|
14343
|
+
judgeModel: config.model
|
|
14344
|
+
});
|
|
14345
|
+
}
|
|
14346
|
+
async function resolveCustomPrompt(config) {
|
|
14347
|
+
if (config.promptPath) {
|
|
14348
|
+
try {
|
|
14349
|
+
return await readFile4(config.promptPath, "utf8");
|
|
14350
|
+
} catch (error) {
|
|
14351
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
14352
|
+
console.warn(`Could not read custom prompt at ${config.promptPath}: ${message}`);
|
|
14353
|
+
}
|
|
14354
|
+
}
|
|
14355
|
+
return config.prompt;
|
|
14356
|
+
}
|
|
14357
|
+
function isNonEmptyString2(value) {
|
|
14358
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
14359
|
+
}
|
|
13218
14360
|
function filterEvalCases(evalCases, evalId) {
|
|
13219
14361
|
if (!evalId) {
|
|
13220
14362
|
return evalCases;
|
|
13221
14363
|
}
|
|
13222
14364
|
return evalCases.filter((evalCase) => evalCase.id === evalId);
|
|
13223
14365
|
}
|
|
13224
|
-
function
|
|
13225
|
-
const
|
|
13226
|
-
const llmJudge = overrides?.llm_judge ?? new QualityGrader({
|
|
14366
|
+
function buildEvaluatorRegistry(overrides, resolveJudgeProvider) {
|
|
14367
|
+
const llmJudge = overrides?.llm_judge ?? new LlmJudgeEvaluator({
|
|
13227
14368
|
resolveJudgeProvider: async (context2) => {
|
|
13228
14369
|
if (context2.judgeProvider) {
|
|
13229
14370
|
return context2.judgeProvider;
|
|
@@ -13233,15 +14374,14 @@ function buildGraderRegistry(overrides, resolveJudgeProvider) {
|
|
|
13233
14374
|
});
|
|
13234
14375
|
return {
|
|
13235
14376
|
...overrides,
|
|
13236
|
-
heuristic,
|
|
13237
14377
|
llm_judge: llmJudge
|
|
13238
14378
|
};
|
|
13239
14379
|
}
|
|
13240
14380
|
async function dumpPrompt(directory, evalCase, promptInputs) {
|
|
13241
14381
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
13242
14382
|
const filename = `${timestamp}_${sanitizeFilename(evalCase.id)}.json`;
|
|
13243
|
-
const filePath =
|
|
13244
|
-
await
|
|
14383
|
+
const filePath = path72.resolve(directory, filename);
|
|
14384
|
+
await mkdir22(path72.dirname(filePath), { recursive: true });
|
|
13245
14385
|
const payload = {
|
|
13246
14386
|
eval_id: evalCase.id,
|
|
13247
14387
|
request: promptInputs.request,
|
|
@@ -13258,7 +14398,7 @@ function sanitizeFilename(value) {
|
|
|
13258
14398
|
return sanitized.length > 0 ? sanitized : randomUUID2();
|
|
13259
14399
|
}
|
|
13260
14400
|
async function invokeProvider(provider, options) {
|
|
13261
|
-
const { evalCase,
|
|
14401
|
+
const { evalCase, promptInputs, attempt, agentTimeoutMs, signal } = options;
|
|
13262
14402
|
const controller = new AbortController();
|
|
13263
14403
|
const timeout = agentTimeoutMs ? setTimeout(() => controller.abort(), agentTimeoutMs) : void 0;
|
|
13264
14404
|
if (signal) {
|
|
@@ -13269,7 +14409,7 @@ async function invokeProvider(provider, options) {
|
|
|
13269
14409
|
prompt: promptInputs.request,
|
|
13270
14410
|
guidelines: promptInputs.guidelines,
|
|
13271
14411
|
guideline_patterns: evalCase.guideline_patterns,
|
|
13272
|
-
|
|
14412
|
+
inputFiles: evalCase.file_paths,
|
|
13273
14413
|
evalCaseId: evalCase.id,
|
|
13274
14414
|
attempt,
|
|
13275
14415
|
metadata: {
|
|
@@ -13980,7 +15120,7 @@ function formatEvaluationSummary(summary) {
|
|
|
13980
15120
|
|
|
13981
15121
|
// src/commands/eval/targets.ts
|
|
13982
15122
|
import { constants as constants5 } from "node:fs";
|
|
13983
|
-
import { access as access5, readFile as
|
|
15123
|
+
import { access as access5, readFile as readFile5 } from "node:fs/promises";
|
|
13984
15124
|
import path12 from "node:path";
|
|
13985
15125
|
import { parse as parse4 } from "yaml";
|
|
13986
15126
|
var TARGET_FILE_CANDIDATES = [
|
|
@@ -13999,7 +15139,7 @@ async function fileExists5(filePath) {
|
|
|
13999
15139
|
}
|
|
14000
15140
|
async function readTestSuiteTarget(testFilePath) {
|
|
14001
15141
|
try {
|
|
14002
|
-
const raw = await
|
|
15142
|
+
const raw = await readFile5(path12.resolve(testFilePath), "utf8");
|
|
14003
15143
|
const parsed = parse4(raw);
|
|
14004
15144
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
14005
15145
|
const targetValue = parsed.target;
|
|
@@ -14453,6 +15593,15 @@ Files installed to ${path15.relative(targetPath, githubDir)}:`);
|
|
|
14453
15593
|
console.log("\nYou can now create eval files using the schema and prompt templates.");
|
|
14454
15594
|
}
|
|
14455
15595
|
|
|
15596
|
+
// src/commands/status.ts
|
|
15597
|
+
function registerStatusCommand(program) {
|
|
15598
|
+
program.command("status").description("Show the latest AgentV kernel status").action(() => {
|
|
15599
|
+
const kernel = createAgentKernel();
|
|
15600
|
+
console.log(`Kernel status: ${kernel.status}`);
|
|
15601
|
+
});
|
|
15602
|
+
return program;
|
|
15603
|
+
}
|
|
15604
|
+
|
|
14456
15605
|
// src/commands/validate/format-output.ts
|
|
14457
15606
|
var ANSI_RED = "\x1B[31m";
|
|
14458
15607
|
var ANSI_YELLOW2 = "\x1B[33m";
|
|
@@ -14525,7 +15674,7 @@ function isTTY() {
|
|
|
14525
15674
|
}
|
|
14526
15675
|
|
|
14527
15676
|
// ../../packages/core/dist/evaluation/validation/index.js
|
|
14528
|
-
import { readFile as
|
|
15677
|
+
import { readFile as readFile6 } from "node:fs/promises";
|
|
14529
15678
|
import { parse as parse5 } from "yaml";
|
|
14530
15679
|
import { readFile as readFile23 } from "node:fs/promises";
|
|
14531
15680
|
import path16 from "node:path";
|
|
@@ -14543,7 +15692,7 @@ var SCHEMA_TARGETS_V2 = "agentv-targets-v2";
|
|
|
14543
15692
|
var SCHEMA_CONFIG_V22 = "agentv-config-v2";
|
|
14544
15693
|
async function detectFileType(filePath) {
|
|
14545
15694
|
try {
|
|
14546
|
-
const content = await
|
|
15695
|
+
const content = await readFile6(filePath, "utf8");
|
|
14547
15696
|
const parsed = parse5(content);
|
|
14548
15697
|
if (typeof parsed !== "object" || parsed === null) {
|
|
14549
15698
|
return "unknown";
|
|
@@ -14762,6 +15911,7 @@ function validateMessages(messages, location, filePath, errors) {
|
|
|
14762
15911
|
function isObject2(value) {
|
|
14763
15912
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14764
15913
|
}
|
|
15914
|
+
var CLI_PLACEHOLDERS2 = /* @__PURE__ */ new Set(["PROMPT", "GUIDELINES", "EVAL_ID", "ATTEMPT", "FILES"]);
|
|
14765
15915
|
async function validateTargetsFile(filePath) {
|
|
14766
15916
|
const errors = [];
|
|
14767
15917
|
const absolutePath = path23.resolve(filePath);
|
|
@@ -14782,6 +15932,182 @@ async function validateTargetsFile(filePath) {
|
|
|
14782
15932
|
errors
|
|
14783
15933
|
};
|
|
14784
15934
|
}
|
|
15935
|
+
function validateCliSettings(settings, absolutePath2, location, errors2) {
|
|
15936
|
+
if (!isObject2(settings)) {
|
|
15937
|
+
errors2.push({
|
|
15938
|
+
severity: "error",
|
|
15939
|
+
filePath: absolutePath2,
|
|
15940
|
+
location,
|
|
15941
|
+
message: "CLI provider requires a 'settings' object"
|
|
15942
|
+
});
|
|
15943
|
+
return;
|
|
15944
|
+
}
|
|
15945
|
+
const commandTemplate = settings["command_template"] ?? settings["commandTemplate"];
|
|
15946
|
+
if (typeof commandTemplate !== "string" || commandTemplate.trim().length === 0) {
|
|
15947
|
+
errors2.push({
|
|
15948
|
+
severity: "error",
|
|
15949
|
+
filePath: absolutePath2,
|
|
15950
|
+
location: `${location}.commandTemplate`,
|
|
15951
|
+
message: "CLI provider requires 'commandTemplate' as a non-empty string"
|
|
15952
|
+
});
|
|
15953
|
+
} else {
|
|
15954
|
+
recordUnknownPlaceholders(commandTemplate, absolutePath2, `${location}.commandTemplate`, errors2);
|
|
15955
|
+
}
|
|
15956
|
+
const attachmentsFormat = settings["attachments_format"] ?? settings["attachmentsFormat"];
|
|
15957
|
+
if (attachmentsFormat !== void 0 && typeof attachmentsFormat !== "string") {
|
|
15958
|
+
errors2.push({
|
|
15959
|
+
severity: "error",
|
|
15960
|
+
filePath: absolutePath2,
|
|
15961
|
+
location: `${location}.attachmentsFormat`,
|
|
15962
|
+
message: "'attachmentsFormat' must be a string when provided"
|
|
15963
|
+
});
|
|
15964
|
+
}
|
|
15965
|
+
const filesFormat = settings["files_format"] ?? settings["filesFormat"];
|
|
15966
|
+
if (filesFormat !== void 0 && typeof filesFormat !== "string") {
|
|
15967
|
+
errors2.push({
|
|
15968
|
+
severity: "error",
|
|
15969
|
+
filePath: absolutePath2,
|
|
15970
|
+
location: `${location}.filesFormat`,
|
|
15971
|
+
message: "'filesFormat' must be a string when provided"
|
|
15972
|
+
});
|
|
15973
|
+
}
|
|
15974
|
+
const cwd = settings["cwd"];
|
|
15975
|
+
if (cwd !== void 0 && typeof cwd !== "string") {
|
|
15976
|
+
errors2.push({
|
|
15977
|
+
severity: "error",
|
|
15978
|
+
filePath: absolutePath2,
|
|
15979
|
+
location: `${location}.cwd`,
|
|
15980
|
+
message: "'cwd' must be a string when provided"
|
|
15981
|
+
});
|
|
15982
|
+
}
|
|
15983
|
+
const timeoutSeconds = settings["timeout_seconds"] ?? settings["timeoutSeconds"];
|
|
15984
|
+
if (timeoutSeconds !== void 0) {
|
|
15985
|
+
const numericTimeout = Number(timeoutSeconds);
|
|
15986
|
+
if (!Number.isFinite(numericTimeout) || numericTimeout <= 0) {
|
|
15987
|
+
errors2.push({
|
|
15988
|
+
severity: "error",
|
|
15989
|
+
filePath: absolutePath2,
|
|
15990
|
+
location: `${location}.timeoutSeconds`,
|
|
15991
|
+
message: "'timeoutSeconds' must be a positive number when provided"
|
|
15992
|
+
});
|
|
15993
|
+
}
|
|
15994
|
+
}
|
|
15995
|
+
const envOverrides = settings["env"];
|
|
15996
|
+
if (envOverrides !== void 0) {
|
|
15997
|
+
if (!isObject2(envOverrides)) {
|
|
15998
|
+
errors2.push({
|
|
15999
|
+
severity: "error",
|
|
16000
|
+
filePath: absolutePath2,
|
|
16001
|
+
location: `${location}.env`,
|
|
16002
|
+
message: "'env' must be an object with string values"
|
|
16003
|
+
});
|
|
16004
|
+
} else {
|
|
16005
|
+
for (const [key2, value] of Object.entries(envOverrides)) {
|
|
16006
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
16007
|
+
errors2.push({
|
|
16008
|
+
severity: "error",
|
|
16009
|
+
filePath: absolutePath2,
|
|
16010
|
+
location: `${location}.env.${key2}`,
|
|
16011
|
+
message: `Environment override '${key2}' must be a non-empty string`
|
|
16012
|
+
});
|
|
16013
|
+
}
|
|
16014
|
+
}
|
|
16015
|
+
}
|
|
16016
|
+
}
|
|
16017
|
+
const healthcheck = settings["healthcheck"];
|
|
16018
|
+
if (healthcheck !== void 0) {
|
|
16019
|
+
validateCliHealthcheck(healthcheck, absolutePath2, `${location}.healthcheck`, errors2);
|
|
16020
|
+
}
|
|
16021
|
+
}
|
|
16022
|
+
function validateCliHealthcheck(healthcheck, absolutePath2, location, errors2) {
|
|
16023
|
+
if (!isObject2(healthcheck)) {
|
|
16024
|
+
errors2.push({
|
|
16025
|
+
severity: "error",
|
|
16026
|
+
filePath: absolutePath2,
|
|
16027
|
+
location,
|
|
16028
|
+
message: "'healthcheck' must be an object when provided"
|
|
16029
|
+
});
|
|
16030
|
+
return;
|
|
16031
|
+
}
|
|
16032
|
+
const type = healthcheck["type"];
|
|
16033
|
+
if (type !== "http" && type !== "command") {
|
|
16034
|
+
errors2.push({
|
|
16035
|
+
severity: "error",
|
|
16036
|
+
filePath: absolutePath2,
|
|
16037
|
+
location: `${location}.type`,
|
|
16038
|
+
message: "healthcheck.type must be either 'http' or 'command'"
|
|
16039
|
+
});
|
|
16040
|
+
return;
|
|
16041
|
+
}
|
|
16042
|
+
const timeoutSeconds = healthcheck["timeout_seconds"] ?? healthcheck["timeoutSeconds"];
|
|
16043
|
+
if (timeoutSeconds !== void 0) {
|
|
16044
|
+
const numericTimeout = Number(timeoutSeconds);
|
|
16045
|
+
if (!Number.isFinite(numericTimeout) || numericTimeout <= 0) {
|
|
16046
|
+
errors2.push({
|
|
16047
|
+
severity: "error",
|
|
16048
|
+
filePath: absolutePath2,
|
|
16049
|
+
location: `${location}.timeoutSeconds`,
|
|
16050
|
+
message: "healthcheck.timeoutSeconds must be a positive number when provided"
|
|
16051
|
+
});
|
|
16052
|
+
}
|
|
16053
|
+
}
|
|
16054
|
+
if (type === "http") {
|
|
16055
|
+
const url = healthcheck["url"];
|
|
16056
|
+
if (typeof url !== "string" || url.trim().length === 0) {
|
|
16057
|
+
errors2.push({
|
|
16058
|
+
severity: "error",
|
|
16059
|
+
filePath: absolutePath2,
|
|
16060
|
+
location: `${location}.url`,
|
|
16061
|
+
message: "healthcheck.url must be a non-empty string for http checks"
|
|
16062
|
+
});
|
|
16063
|
+
}
|
|
16064
|
+
return;
|
|
16065
|
+
}
|
|
16066
|
+
const commandTemplate = healthcheck["command_template"] ?? healthcheck["commandTemplate"];
|
|
16067
|
+
if (typeof commandTemplate !== "string" || commandTemplate.trim().length === 0) {
|
|
16068
|
+
errors2.push({
|
|
16069
|
+
severity: "error",
|
|
16070
|
+
filePath: absolutePath2,
|
|
16071
|
+
location: `${location}.commandTemplate`,
|
|
16072
|
+
message: "healthcheck.commandTemplate must be a non-empty string for command checks"
|
|
16073
|
+
});
|
|
16074
|
+
} else {
|
|
16075
|
+
recordUnknownPlaceholders(commandTemplate, absolutePath2, `${location}.commandTemplate`, errors2);
|
|
16076
|
+
}
|
|
16077
|
+
const cwd = healthcheck["cwd"];
|
|
16078
|
+
if (cwd !== void 0 && typeof cwd !== "string") {
|
|
16079
|
+
errors2.push({
|
|
16080
|
+
severity: "error",
|
|
16081
|
+
filePath: absolutePath2,
|
|
16082
|
+
location: `${location}.cwd`,
|
|
16083
|
+
message: "healthcheck.cwd must be a string when provided"
|
|
16084
|
+
});
|
|
16085
|
+
}
|
|
16086
|
+
}
|
|
16087
|
+
function recordUnknownPlaceholders(template, absolutePath2, location, errors2) {
|
|
16088
|
+
const placeholders = extractPlaceholders(template);
|
|
16089
|
+
for (const placeholder of placeholders) {
|
|
16090
|
+
if (!CLI_PLACEHOLDERS2.has(placeholder)) {
|
|
16091
|
+
errors2.push({
|
|
16092
|
+
severity: "error",
|
|
16093
|
+
filePath: absolutePath2,
|
|
16094
|
+
location,
|
|
16095
|
+
message: `Unknown CLI placeholder '{${placeholder}}'. Supported placeholders: ${Array.from(CLI_PLACEHOLDERS2).join(", ")}`
|
|
16096
|
+
});
|
|
16097
|
+
}
|
|
16098
|
+
}
|
|
16099
|
+
}
|
|
16100
|
+
function extractPlaceholders(template) {
|
|
16101
|
+
const matches = template.matchAll(/\{([A-Z_]+)\}/g);
|
|
16102
|
+
const result = [];
|
|
16103
|
+
for (const match of matches) {
|
|
16104
|
+
const placeholder = match[1];
|
|
16105
|
+
if (placeholder) {
|
|
16106
|
+
result.push(placeholder);
|
|
16107
|
+
}
|
|
16108
|
+
}
|
|
16109
|
+
return result;
|
|
16110
|
+
}
|
|
14785
16111
|
if (!isObject2(parsed)) {
|
|
14786
16112
|
errors.push({
|
|
14787
16113
|
severity: "error",
|
|
@@ -14843,6 +16169,7 @@ async function validateTargetsFile(filePath) {
|
|
|
14843
16169
|
});
|
|
14844
16170
|
}
|
|
14845
16171
|
const provider = target["provider"];
|
|
16172
|
+
const providerValue = typeof provider === "string" ? provider.trim().toLowerCase() : void 0;
|
|
14846
16173
|
if (typeof provider !== "string" || provider.trim().length === 0) {
|
|
14847
16174
|
errors.push({
|
|
14848
16175
|
severity: "error",
|
|
@@ -14859,7 +16186,7 @@ async function validateTargetsFile(filePath) {
|
|
|
14859
16186
|
});
|
|
14860
16187
|
}
|
|
14861
16188
|
const settings = target["settings"];
|
|
14862
|
-
if (settings !== void 0 && !isObject2(settings)) {
|
|
16189
|
+
if (providerValue !== "cli" && settings !== void 0 && !isObject2(settings)) {
|
|
14863
16190
|
errors.push({
|
|
14864
16191
|
severity: "error",
|
|
14865
16192
|
filePath: absolutePath,
|
|
@@ -14867,6 +16194,9 @@ async function validateTargetsFile(filePath) {
|
|
|
14867
16194
|
message: "Invalid 'settings' field (must be an object)"
|
|
14868
16195
|
});
|
|
14869
16196
|
}
|
|
16197
|
+
if (providerValue === "cli") {
|
|
16198
|
+
validateCliSettings(settings, absolutePath, `${location}.settings`, errors);
|
|
16199
|
+
}
|
|
14870
16200
|
const judgeTarget = target["judge_target"];
|
|
14871
16201
|
if (judgeTarget !== void 0 && typeof judgeTarget !== "string") {
|
|
14872
16202
|
errors.push({
|
|
@@ -15198,15 +16528,6 @@ function registerValidateCommand(program) {
|
|
|
15198
16528
|
return program;
|
|
15199
16529
|
}
|
|
15200
16530
|
|
|
15201
|
-
// src/commands/status.ts
|
|
15202
|
-
function registerStatusCommand(program) {
|
|
15203
|
-
program.command("status").description("Show the latest AgentV kernel status").action(() => {
|
|
15204
|
-
const kernel = createAgentKernel();
|
|
15205
|
-
console.log(`Kernel status: ${kernel.status}`);
|
|
15206
|
-
});
|
|
15207
|
-
return program;
|
|
15208
|
-
}
|
|
15209
|
-
|
|
15210
16531
|
// src/index.ts
|
|
15211
16532
|
var packageJson = JSON.parse(readFileSync2(new URL("../package.json", import.meta.url), "utf8"));
|
|
15212
16533
|
function createProgram() {
|
|
@@ -15235,4 +16556,4 @@ export {
|
|
|
15235
16556
|
createProgram,
|
|
15236
16557
|
runCli
|
|
15237
16558
|
};
|
|
15238
|
-
//# sourceMappingURL=chunk-
|
|
16559
|
+
//# sourceMappingURL=chunk-THVRLL37.js.map
|