@agentv/core 2.14.2 → 2.14.3
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/dist/index.cjs +390 -229
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +373 -217
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -234,7 +234,7 @@ async function resolveFileReference2(ref, evalFileDir) {
|
|
|
234
234
|
const rawPath = extractFilePath(ref);
|
|
235
235
|
const absolutePattern = path.resolve(evalFileDir, rawPath);
|
|
236
236
|
if (isGlobPattern(rawPath)) {
|
|
237
|
-
const matches = await fg(absolutePattern, {
|
|
237
|
+
const matches = await fg(absolutePattern.replaceAll("\\", "/"), {
|
|
238
238
|
onlyFiles: true,
|
|
239
239
|
absolute: true
|
|
240
240
|
});
|
|
@@ -5049,7 +5049,7 @@ import { arch, platform } from "node:os";
|
|
|
5049
5049
|
import path13 from "node:path";
|
|
5050
5050
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
5051
5051
|
function resolvePlatformCliPath() {
|
|
5052
|
-
const
|
|
5052
|
+
const os3 = platform();
|
|
5053
5053
|
const cpu = arch();
|
|
5054
5054
|
const platformMap = {
|
|
5055
5055
|
linux: "linux",
|
|
@@ -5060,13 +5060,13 @@ function resolvePlatformCliPath() {
|
|
|
5060
5060
|
x64: "x64",
|
|
5061
5061
|
arm64: "arm64"
|
|
5062
5062
|
};
|
|
5063
|
-
const osPart = platformMap[
|
|
5063
|
+
const osPart = platformMap[os3];
|
|
5064
5064
|
const archPart = archMap[cpu];
|
|
5065
5065
|
if (!osPart || !archPart) {
|
|
5066
5066
|
return void 0;
|
|
5067
5067
|
}
|
|
5068
5068
|
const packageName = `@github/copilot-${osPart}-${archPart}`;
|
|
5069
|
-
const binaryName =
|
|
5069
|
+
const binaryName = os3 === "win32" ? "copilot.exe" : "copilot";
|
|
5070
5070
|
try {
|
|
5071
5071
|
const resolved = import.meta.resolve(`${packageName}/package.json`);
|
|
5072
5072
|
const packageJsonPath = resolved.startsWith("file:") ? fileURLToPath2(resolved) : resolved;
|
|
@@ -6868,12 +6868,12 @@ var ProviderRegistry = class {
|
|
|
6868
6868
|
// src/evaluation/providers/vscode-provider.ts
|
|
6869
6869
|
import { exec as exec2 } from "node:child_process";
|
|
6870
6870
|
import { constants as constants3, access as access3, stat as stat4 } from "node:fs/promises";
|
|
6871
|
-
import
|
|
6871
|
+
import path28 from "node:path";
|
|
6872
6872
|
import { promisify as promisify3 } from "node:util";
|
|
6873
6873
|
|
|
6874
6874
|
// src/evaluation/providers/vscode/dispatch/agentDispatch.ts
|
|
6875
6875
|
import { stat as stat3, writeFile as writeFile4 } from "node:fs/promises";
|
|
6876
|
-
import
|
|
6876
|
+
import path26 from "node:path";
|
|
6877
6877
|
|
|
6878
6878
|
// src/evaluation/providers/vscode/utils/fs.ts
|
|
6879
6879
|
import { constants as constants2 } from "node:fs";
|
|
@@ -7141,17 +7141,46 @@ async function waitForBatchResponses(responseFilesFinal, pollInterval = 1e3, sil
|
|
|
7141
7141
|
// src/evaluation/providers/vscode/dispatch/vscodeProcess.ts
|
|
7142
7142
|
import { exec, spawn as spawn3 } from "node:child_process";
|
|
7143
7143
|
import { mkdir as mkdir7, writeFile as writeFile2 } from "node:fs/promises";
|
|
7144
|
-
import
|
|
7144
|
+
import path23 from "node:path";
|
|
7145
7145
|
import { promisify as promisify2 } from "node:util";
|
|
7146
7146
|
|
|
7147
7147
|
// src/evaluation/providers/vscode/dispatch/constants.ts
|
|
7148
|
+
import path22 from "node:path";
|
|
7149
|
+
|
|
7150
|
+
// src/paths.ts
|
|
7148
7151
|
import os2 from "node:os";
|
|
7149
7152
|
import path21 from "node:path";
|
|
7153
|
+
var logged = false;
|
|
7154
|
+
function getAgentvHome() {
|
|
7155
|
+
const envHome = process.env.AGENTV_HOME;
|
|
7156
|
+
if (envHome) {
|
|
7157
|
+
if (!logged) {
|
|
7158
|
+
logged = true;
|
|
7159
|
+
console.warn(`Using AGENTV_HOME: ${envHome}`);
|
|
7160
|
+
}
|
|
7161
|
+
return envHome;
|
|
7162
|
+
}
|
|
7163
|
+
return path21.join(os2.homedir(), ".agentv");
|
|
7164
|
+
}
|
|
7165
|
+
function getWorkspacesRoot() {
|
|
7166
|
+
return path21.join(getAgentvHome(), "workspaces");
|
|
7167
|
+
}
|
|
7168
|
+
function getGitCacheRoot() {
|
|
7169
|
+
return path21.join(getAgentvHome(), "git-cache");
|
|
7170
|
+
}
|
|
7171
|
+
function getSubagentsRoot() {
|
|
7172
|
+
return path21.join(getAgentvHome(), "subagents");
|
|
7173
|
+
}
|
|
7174
|
+
function getTraceStateRoot() {
|
|
7175
|
+
return path21.join(getAgentvHome(), "trace-state");
|
|
7176
|
+
}
|
|
7177
|
+
|
|
7178
|
+
// src/evaluation/providers/vscode/dispatch/constants.ts
|
|
7150
7179
|
var DEFAULT_LOCK_NAME = "subagent.lock";
|
|
7151
7180
|
var DEFAULT_ALIVE_FILENAME = ".alive";
|
|
7152
7181
|
function getDefaultSubagentRoot(vscodeCmd = "code") {
|
|
7153
7182
|
const folder = vscodeCmd === "code-insiders" ? "vscode-insiders-agents" : "vscode-agents";
|
|
7154
|
-
return
|
|
7183
|
+
return path22.join(getSubagentsRoot(), folder);
|
|
7155
7184
|
}
|
|
7156
7185
|
var DEFAULT_SUBAGENT_ROOT = getDefaultSubagentRoot();
|
|
7157
7186
|
|
|
@@ -7165,12 +7194,19 @@ description: 'Wake-up Signal'
|
|
|
7165
7194
|
model: Grok Code Fast 1 (copilot)
|
|
7166
7195
|
---`;
|
|
7167
7196
|
function spawnVsCode(vscodeCmd, args, options) {
|
|
7168
|
-
const
|
|
7197
|
+
const useShell = options?.shell ?? true;
|
|
7198
|
+
const command = useShell ? shellQuote(vscodeCmd) : vscodeCmd;
|
|
7199
|
+
const child = spawn3(command, args, {
|
|
7169
7200
|
windowsHide: true,
|
|
7170
|
-
shell:
|
|
7201
|
+
shell: useShell,
|
|
7171
7202
|
detached: false
|
|
7172
7203
|
});
|
|
7173
|
-
child.on("error", () => {
|
|
7204
|
+
child.on("error", (error) => {
|
|
7205
|
+
const label = options?.label ?? "spawn";
|
|
7206
|
+
const renderedArgs = args.map((value) => JSON.stringify(value)).join(" ");
|
|
7207
|
+
console.error(
|
|
7208
|
+
`[vscode] ${label} failed: command=${JSON.stringify(vscodeCmd)} args=${renderedArgs} error=${error.message}`
|
|
7209
|
+
);
|
|
7174
7210
|
});
|
|
7175
7211
|
return child;
|
|
7176
7212
|
}
|
|
@@ -7207,16 +7243,20 @@ async function checkWorkspaceOpened(workspaceName, vscodeCmd) {
|
|
|
7207
7243
|
async function ensureWorkspaceFocused(workspacePath, workspaceName, subagentDir, vscodeCmd, pollInterval = 1, timeout = 60) {
|
|
7208
7244
|
const alreadyOpen = await checkWorkspaceOpened(workspaceName, vscodeCmd);
|
|
7209
7245
|
if (alreadyOpen) {
|
|
7210
|
-
spawnVsCode(
|
|
7246
|
+
const child = spawnVsCode(vscodeCmd, [workspacePath], { label: "focus-existing-workspace" });
|
|
7247
|
+
await raceSpawnError(child);
|
|
7211
7248
|
return true;
|
|
7212
7249
|
}
|
|
7213
|
-
const aliveFile =
|
|
7250
|
+
const aliveFile = path23.join(subagentDir, DEFAULT_ALIVE_FILENAME);
|
|
7214
7251
|
await removeIfExists(aliveFile);
|
|
7215
|
-
const githubAgentsDir =
|
|
7252
|
+
const githubAgentsDir = path23.join(subagentDir, ".github", "agents");
|
|
7216
7253
|
await mkdir7(githubAgentsDir, { recursive: true });
|
|
7217
|
-
const wakeupDst =
|
|
7254
|
+
const wakeupDst = path23.join(githubAgentsDir, "wakeup.md");
|
|
7218
7255
|
await writeFile2(wakeupDst, DEFAULT_WAKEUP_CONTENT, "utf8");
|
|
7219
|
-
spawnVsCode(
|
|
7256
|
+
const workspaceChild = spawnVsCode(vscodeCmd, [workspacePath], {
|
|
7257
|
+
label: "open-workspace"
|
|
7258
|
+
});
|
|
7259
|
+
await raceSpawnError(workspaceChild);
|
|
7220
7260
|
await sleep2(100);
|
|
7221
7261
|
const wakeupChatId = "wakeup";
|
|
7222
7262
|
const chatArgs = [
|
|
@@ -7224,9 +7264,10 @@ async function ensureWorkspaceFocused(workspacePath, workspaceName, subagentDir,
|
|
|
7224
7264
|
"chat",
|
|
7225
7265
|
"-m",
|
|
7226
7266
|
wakeupChatId,
|
|
7227
|
-
`create a file named .alive in the ${
|
|
7267
|
+
`create a file named .alive in the ${path23.basename(subagentDir)} folder`
|
|
7228
7268
|
];
|
|
7229
|
-
spawnVsCode(
|
|
7269
|
+
const wakeupChild = spawnVsCode(vscodeCmd, chatArgs, { label: "send-wakeup-chat" });
|
|
7270
|
+
await raceSpawnError(wakeupChild);
|
|
7230
7271
|
const start = Date.now();
|
|
7231
7272
|
while (!await pathExists(aliveFile)) {
|
|
7232
7273
|
if (Date.now() - start > timeout * 1e3) {
|
|
@@ -7238,10 +7279,10 @@ async function ensureWorkspaceFocused(workspacePath, workspaceName, subagentDir,
|
|
|
7238
7279
|
return true;
|
|
7239
7280
|
}
|
|
7240
7281
|
async function launchVsCodeWithChat(subagentDir, chatId, attachmentPaths, requestInstructions, timestamp, vscodeCmd) {
|
|
7241
|
-
const workspacePath =
|
|
7242
|
-
const messagesDir =
|
|
7282
|
+
const workspacePath = path23.join(subagentDir, `${path23.basename(subagentDir)}.code-workspace`);
|
|
7283
|
+
const messagesDir = path23.join(subagentDir, "messages");
|
|
7243
7284
|
await mkdir7(messagesDir, { recursive: true });
|
|
7244
|
-
const reqFile =
|
|
7285
|
+
const reqFile = path23.join(messagesDir, `${timestamp}_req.md`);
|
|
7245
7286
|
await writeFile2(reqFile, requestInstructions, { encoding: "utf8" });
|
|
7246
7287
|
const reqUri = pathToFileUri2(reqFile);
|
|
7247
7288
|
const chatArgs = ["-r", "chat", "-m", chatId];
|
|
@@ -7249,25 +7290,25 @@ async function launchVsCodeWithChat(subagentDir, chatId, attachmentPaths, reques
|
|
|
7249
7290
|
chatArgs.push("-a", attachment);
|
|
7250
7291
|
}
|
|
7251
7292
|
chatArgs.push("-a", reqFile);
|
|
7252
|
-
chatArgs.push(`Follow instructions in [${
|
|
7293
|
+
chatArgs.push(`Follow instructions in [${path23.basename(reqFile)}](${reqUri})`);
|
|
7253
7294
|
const workspaceReady = await ensureWorkspaceFocused(
|
|
7254
7295
|
workspacePath,
|
|
7255
|
-
|
|
7296
|
+
path23.basename(subagentDir),
|
|
7256
7297
|
subagentDir,
|
|
7257
7298
|
vscodeCmd
|
|
7258
7299
|
);
|
|
7259
7300
|
if (!workspaceReady) {
|
|
7260
7301
|
throw new Error(
|
|
7261
|
-
`VS Code workspace '${
|
|
7302
|
+
`VS Code workspace '${path23.basename(subagentDir)}' failed to become ready within the timeout. Check that '${vscodeCmd}' can open workspaces.`
|
|
7262
7303
|
);
|
|
7263
7304
|
}
|
|
7264
7305
|
await sleep2(500);
|
|
7265
|
-
const child = spawnVsCode(
|
|
7306
|
+
const child = spawnVsCode(vscodeCmd, chatArgs, { label: "send-chat" });
|
|
7266
7307
|
await raceSpawnError(child);
|
|
7267
7308
|
}
|
|
7268
7309
|
async function launchVsCodeWithBatchChat(subagentDir, chatId, attachmentPaths, chatInstruction, vscodeCmd) {
|
|
7269
|
-
const workspacePath =
|
|
7270
|
-
const messagesDir =
|
|
7310
|
+
const workspacePath = path23.join(subagentDir, `${path23.basename(subagentDir)}.code-workspace`);
|
|
7311
|
+
const messagesDir = path23.join(subagentDir, "messages");
|
|
7271
7312
|
await mkdir7(messagesDir, { recursive: true });
|
|
7272
7313
|
const chatArgs = ["-r", "chat", "-m", chatId];
|
|
7273
7314
|
for (const attachment of attachmentPaths) {
|
|
@@ -7276,26 +7317,26 @@ async function launchVsCodeWithBatchChat(subagentDir, chatId, attachmentPaths, c
|
|
|
7276
7317
|
chatArgs.push(chatInstruction);
|
|
7277
7318
|
const workspaceReady = await ensureWorkspaceFocused(
|
|
7278
7319
|
workspacePath,
|
|
7279
|
-
|
|
7320
|
+
path23.basename(subagentDir),
|
|
7280
7321
|
subagentDir,
|
|
7281
7322
|
vscodeCmd
|
|
7282
7323
|
);
|
|
7283
7324
|
if (!workspaceReady) {
|
|
7284
7325
|
throw new Error(
|
|
7285
|
-
`VS Code workspace '${
|
|
7326
|
+
`VS Code workspace '${path23.basename(subagentDir)}' failed to become ready within the timeout. Check that '${vscodeCmd}' can open workspaces.`
|
|
7286
7327
|
);
|
|
7287
7328
|
}
|
|
7288
7329
|
await sleep2(500);
|
|
7289
|
-
const child = spawnVsCode(
|
|
7330
|
+
const child = spawnVsCode(vscodeCmd, chatArgs, { label: "send-batch-chat" });
|
|
7290
7331
|
await raceSpawnError(child);
|
|
7291
7332
|
}
|
|
7292
7333
|
|
|
7293
7334
|
// src/evaluation/providers/vscode/dispatch/workspaceManager.ts
|
|
7294
7335
|
import { copyFile, mkdir as mkdir8, readFile as readFile9, readdir as readdir2, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
|
|
7295
|
-
import
|
|
7336
|
+
import path25 from "node:path";
|
|
7296
7337
|
|
|
7297
7338
|
// src/evaluation/providers/vscode/utils/workspace.ts
|
|
7298
|
-
import
|
|
7339
|
+
import path24 from "node:path";
|
|
7299
7340
|
import JSON5 from "json5";
|
|
7300
7341
|
function transformWorkspacePaths(workspaceContent, templateDir) {
|
|
7301
7342
|
let workspace;
|
|
@@ -7312,10 +7353,10 @@ function transformWorkspacePaths(workspaceContent, templateDir) {
|
|
|
7312
7353
|
}
|
|
7313
7354
|
const transformedFolders = workspace.folders.map((folder) => {
|
|
7314
7355
|
const folderPath = folder.path;
|
|
7315
|
-
if (
|
|
7356
|
+
if (path24.isAbsolute(folderPath)) {
|
|
7316
7357
|
return folder;
|
|
7317
7358
|
}
|
|
7318
|
-
const absolutePath =
|
|
7359
|
+
const absolutePath = path24.resolve(templateDir, folderPath);
|
|
7319
7360
|
return {
|
|
7320
7361
|
...folder,
|
|
7321
7362
|
path: absolutePath
|
|
@@ -7337,19 +7378,19 @@ function transformWorkspacePaths(workspaceContent, templateDir) {
|
|
|
7337
7378
|
if (locationMap && typeof locationMap === "object") {
|
|
7338
7379
|
const transformedMap = {};
|
|
7339
7380
|
for (const [locationPath, value] of Object.entries(locationMap)) {
|
|
7340
|
-
const isAbsolute =
|
|
7381
|
+
const isAbsolute = path24.isAbsolute(locationPath);
|
|
7341
7382
|
if (isAbsolute) {
|
|
7342
7383
|
transformedMap[locationPath] = value;
|
|
7343
7384
|
} else {
|
|
7344
7385
|
const firstGlobIndex = locationPath.search(/[*]/);
|
|
7345
7386
|
if (firstGlobIndex === -1) {
|
|
7346
|
-
const resolvedPath =
|
|
7387
|
+
const resolvedPath = path24.resolve(templateDir, locationPath).replace(/\\/g, "/");
|
|
7347
7388
|
transformedMap[resolvedPath] = value;
|
|
7348
7389
|
} else {
|
|
7349
7390
|
const basePathEnd = locationPath.lastIndexOf("/", firstGlobIndex);
|
|
7350
7391
|
const basePath = basePathEnd !== -1 ? locationPath.substring(0, basePathEnd) : ".";
|
|
7351
7392
|
const patternPath = locationPath.substring(basePathEnd !== -1 ? basePathEnd : 0);
|
|
7352
|
-
const resolvedPath = (
|
|
7393
|
+
const resolvedPath = (path24.resolve(templateDir, basePath) + patternPath).replace(
|
|
7353
7394
|
/\\/g,
|
|
7354
7395
|
"/"
|
|
7355
7396
|
);
|
|
@@ -7390,7 +7431,7 @@ async function findUnlockedSubagent(subagentRoot) {
|
|
|
7390
7431
|
number: Number.parseInt(entry.name.split("-")[1] ?? "", 10)
|
|
7391
7432
|
})).filter((entry) => Number.isInteger(entry.number)).sort((a, b) => a.number - b.number);
|
|
7392
7433
|
for (const subagent of subagents) {
|
|
7393
|
-
const lockFile =
|
|
7434
|
+
const lockFile = path25.join(subagent.absolutePath, DEFAULT_LOCK_NAME);
|
|
7394
7435
|
if (!await pathExists(lockFile)) {
|
|
7395
7436
|
return subagent.absolutePath;
|
|
7396
7437
|
}
|
|
@@ -7400,7 +7441,7 @@ async function findUnlockedSubagent(subagentRoot) {
|
|
|
7400
7441
|
async function copyAgentConfig(subagentDir, workspaceTemplate, cwd) {
|
|
7401
7442
|
let workspaceContent;
|
|
7402
7443
|
if (workspaceTemplate) {
|
|
7403
|
-
const workspaceSrc =
|
|
7444
|
+
const workspaceSrc = path25.resolve(workspaceTemplate);
|
|
7404
7445
|
if (!await pathExists(workspaceSrc)) {
|
|
7405
7446
|
throw new Error(`workspace template not found: ${workspaceSrc}`);
|
|
7406
7447
|
}
|
|
@@ -7413,13 +7454,13 @@ async function copyAgentConfig(subagentDir, workspaceTemplate, cwd) {
|
|
|
7413
7454
|
} else {
|
|
7414
7455
|
workspaceContent = DEFAULT_WORKSPACE_TEMPLATE;
|
|
7415
7456
|
}
|
|
7416
|
-
const workspaceName = `${
|
|
7417
|
-
const workspaceDst =
|
|
7418
|
-
const templateDir = workspaceTemplate ?
|
|
7457
|
+
const workspaceName = `${path25.basename(subagentDir)}.code-workspace`;
|
|
7458
|
+
const workspaceDst = path25.join(subagentDir, workspaceName);
|
|
7459
|
+
const templateDir = workspaceTemplate ? path25.dirname(path25.resolve(workspaceTemplate)) : subagentDir;
|
|
7419
7460
|
const workspaceJson = JSON.stringify(workspaceContent, null, 2);
|
|
7420
7461
|
let transformedContent = transformWorkspacePaths(workspaceJson, templateDir);
|
|
7421
7462
|
if (cwd) {
|
|
7422
|
-
const absCwd =
|
|
7463
|
+
const absCwd = path25.resolve(cwd);
|
|
7423
7464
|
const parsed = JSON.parse(transformedContent);
|
|
7424
7465
|
const alreadyPresent = parsed.folders.some((f) => f.path === absCwd);
|
|
7425
7466
|
if (!alreadyPresent) {
|
|
@@ -7428,35 +7469,35 @@ async function copyAgentConfig(subagentDir, workspaceTemplate, cwd) {
|
|
|
7428
7469
|
}
|
|
7429
7470
|
}
|
|
7430
7471
|
await writeFile3(workspaceDst, transformedContent, "utf8");
|
|
7431
|
-
const messagesDir =
|
|
7472
|
+
const messagesDir = path25.join(subagentDir, "messages");
|
|
7432
7473
|
await mkdir8(messagesDir, { recursive: true });
|
|
7433
7474
|
return { workspace: workspaceDst, messagesDir };
|
|
7434
7475
|
}
|
|
7435
7476
|
async function createSubagentLock(subagentDir) {
|
|
7436
|
-
const messagesDir =
|
|
7477
|
+
const messagesDir = path25.join(subagentDir, "messages");
|
|
7437
7478
|
if (await pathExists(messagesDir)) {
|
|
7438
7479
|
const files = await readdir2(messagesDir);
|
|
7439
7480
|
await Promise.all(
|
|
7440
7481
|
files.map(async (file) => {
|
|
7441
|
-
const target =
|
|
7482
|
+
const target = path25.join(messagesDir, file);
|
|
7442
7483
|
await removeIfExists(target);
|
|
7443
7484
|
})
|
|
7444
7485
|
);
|
|
7445
7486
|
}
|
|
7446
|
-
const githubAgentsDir =
|
|
7487
|
+
const githubAgentsDir = path25.join(subagentDir, ".github", "agents");
|
|
7447
7488
|
if (await pathExists(githubAgentsDir)) {
|
|
7448
7489
|
const agentFiles = await readdir2(githubAgentsDir);
|
|
7449
7490
|
const preservedFiles = /* @__PURE__ */ new Set(["wakeup.md", "subagent.md"]);
|
|
7450
7491
|
await Promise.all(
|
|
7451
|
-
agentFiles.filter((file) => file.endsWith(".md") && !preservedFiles.has(file)).map((file) => removeIfExists(
|
|
7492
|
+
agentFiles.filter((file) => file.endsWith(".md") && !preservedFiles.has(file)).map((file) => removeIfExists(path25.join(githubAgentsDir, file)))
|
|
7452
7493
|
);
|
|
7453
7494
|
}
|
|
7454
|
-
const lockFile =
|
|
7495
|
+
const lockFile = path25.join(subagentDir, DEFAULT_LOCK_NAME);
|
|
7455
7496
|
await writeFile3(lockFile, "", { encoding: "utf8" });
|
|
7456
7497
|
return lockFile;
|
|
7457
7498
|
}
|
|
7458
7499
|
async function removeSubagentLock(subagentDir) {
|
|
7459
|
-
const lockFile =
|
|
7500
|
+
const lockFile = path25.join(subagentDir, DEFAULT_LOCK_NAME);
|
|
7460
7501
|
await removeIfExists(lockFile);
|
|
7461
7502
|
}
|
|
7462
7503
|
async function prepareSubagentDirectory(subagentDir, promptFile, chatId, workspaceTemplate, dryRun, cwd) {
|
|
@@ -7476,9 +7517,9 @@ async function prepareSubagentDirectory(subagentDir, promptFile, chatId, workspa
|
|
|
7476
7517
|
return 1;
|
|
7477
7518
|
}
|
|
7478
7519
|
if (promptFile) {
|
|
7479
|
-
const githubAgentsDir =
|
|
7520
|
+
const githubAgentsDir = path25.join(subagentDir, ".github", "agents");
|
|
7480
7521
|
await mkdir8(githubAgentsDir, { recursive: true });
|
|
7481
|
-
const agentFile =
|
|
7522
|
+
const agentFile = path25.join(githubAgentsDir, `${chatId}.md`);
|
|
7482
7523
|
try {
|
|
7483
7524
|
await copyFile(promptFile, agentFile);
|
|
7484
7525
|
} catch (error) {
|
|
@@ -7497,7 +7538,7 @@ async function resolvePromptFile(promptFile) {
|
|
|
7497
7538
|
if (!promptFile) {
|
|
7498
7539
|
return void 0;
|
|
7499
7540
|
}
|
|
7500
|
-
const resolvedPrompt =
|
|
7541
|
+
const resolvedPrompt = path26.resolve(promptFile);
|
|
7501
7542
|
if (!await pathExists(resolvedPrompt)) {
|
|
7502
7543
|
throw new Error(`Prompt file not found: ${resolvedPrompt}`);
|
|
7503
7544
|
}
|
|
@@ -7513,7 +7554,7 @@ async function resolveAttachments(extraAttachments) {
|
|
|
7513
7554
|
}
|
|
7514
7555
|
const resolved = [];
|
|
7515
7556
|
for (const attachment of extraAttachments) {
|
|
7516
|
-
const resolvedPath =
|
|
7557
|
+
const resolvedPath = path26.resolve(attachment);
|
|
7517
7558
|
if (!await pathExists(resolvedPath)) {
|
|
7518
7559
|
throw new Error(`Attachment not found: ${resolvedPath}`);
|
|
7519
7560
|
}
|
|
@@ -7555,7 +7596,7 @@ async function dispatchAgentSession(options) {
|
|
|
7555
7596
|
error: "No unlocked subagents available. Provision additional subagents with: subagent code provision --subagents <desired_total>"
|
|
7556
7597
|
};
|
|
7557
7598
|
}
|
|
7558
|
-
const subagentName =
|
|
7599
|
+
const subagentName = path26.basename(subagentDir);
|
|
7559
7600
|
const chatId = Math.random().toString(16).slice(2, 10);
|
|
7560
7601
|
const preparationResult = await prepareSubagentDirectory(
|
|
7561
7602
|
subagentDir,
|
|
@@ -7583,9 +7624,9 @@ async function dispatchAgentSession(options) {
|
|
|
7583
7624
|
};
|
|
7584
7625
|
}
|
|
7585
7626
|
const timestamp = generateTimestamp();
|
|
7586
|
-
const messagesDir =
|
|
7587
|
-
const responseFileTmp =
|
|
7588
|
-
const responseFileFinal =
|
|
7627
|
+
const messagesDir = path26.join(subagentDir, "messages");
|
|
7628
|
+
const responseFileTmp = path26.join(messagesDir, `${timestamp}_res.tmp.md`);
|
|
7629
|
+
const responseFileFinal = path26.join(messagesDir, `${timestamp}_res.md`);
|
|
7589
7630
|
const requestInstructions = createRequestPrompt(
|
|
7590
7631
|
userQuery,
|
|
7591
7632
|
responseFileTmp,
|
|
@@ -7690,7 +7731,7 @@ async function dispatchBatchAgent(options) {
|
|
|
7690
7731
|
error: "No unlocked subagents available. Provision additional subagents with: subagent code provision --subagents <desired_total>"
|
|
7691
7732
|
};
|
|
7692
7733
|
}
|
|
7693
|
-
subagentName =
|
|
7734
|
+
subagentName = path26.basename(subagentDir);
|
|
7694
7735
|
const chatId = Math.random().toString(16).slice(2, 10);
|
|
7695
7736
|
const preparationResult = await prepareSubagentDirectory(
|
|
7696
7737
|
subagentDir,
|
|
@@ -7721,17 +7762,17 @@ async function dispatchBatchAgent(options) {
|
|
|
7721
7762
|
};
|
|
7722
7763
|
}
|
|
7723
7764
|
const timestamp = generateTimestamp();
|
|
7724
|
-
const messagesDir =
|
|
7765
|
+
const messagesDir = path26.join(subagentDir, "messages");
|
|
7725
7766
|
requestFiles = userQueries.map(
|
|
7726
|
-
(_, index) =>
|
|
7767
|
+
(_, index) => path26.join(messagesDir, `${timestamp}_${index}_req.md`)
|
|
7727
7768
|
);
|
|
7728
7769
|
const responseTmpFiles = userQueries.map(
|
|
7729
|
-
(_, index) =>
|
|
7770
|
+
(_, index) => path26.join(messagesDir, `${timestamp}_${index}_res.tmp.md`)
|
|
7730
7771
|
);
|
|
7731
7772
|
responseFilesFinal = userQueries.map(
|
|
7732
|
-
(_, index) =>
|
|
7773
|
+
(_, index) => path26.join(messagesDir, `${timestamp}_${index}_res.md`)
|
|
7733
7774
|
);
|
|
7734
|
-
const orchestratorFile =
|
|
7775
|
+
const orchestratorFile = path26.join(messagesDir, `${timestamp}_orchestrator.md`);
|
|
7735
7776
|
if (!dryRun) {
|
|
7736
7777
|
await Promise.all(
|
|
7737
7778
|
userQueries.map((query, index) => {
|
|
@@ -7817,7 +7858,7 @@ async function dispatchBatchAgent(options) {
|
|
|
7817
7858
|
|
|
7818
7859
|
// src/evaluation/providers/vscode/dispatch/provision.ts
|
|
7819
7860
|
import { writeFile as writeFile5 } from "node:fs/promises";
|
|
7820
|
-
import
|
|
7861
|
+
import path27 from "node:path";
|
|
7821
7862
|
var DEFAULT_WORKSPACE_TEMPLATE2 = {
|
|
7822
7863
|
folders: [
|
|
7823
7864
|
{
|
|
@@ -7848,7 +7889,7 @@ async function provisionSubagents(options) {
|
|
|
7848
7889
|
if (!Number.isInteger(subagents) || subagents < 1) {
|
|
7849
7890
|
throw new Error("subagents must be a positive integer");
|
|
7850
7891
|
}
|
|
7851
|
-
const targetPath =
|
|
7892
|
+
const targetPath = path27.resolve(targetRoot);
|
|
7852
7893
|
if (!dryRun) {
|
|
7853
7894
|
await ensureDir(targetPath);
|
|
7854
7895
|
}
|
|
@@ -7868,7 +7909,7 @@ async function provisionSubagents(options) {
|
|
|
7868
7909
|
continue;
|
|
7869
7910
|
}
|
|
7870
7911
|
highestNumber = Math.max(highestNumber, parsed);
|
|
7871
|
-
const lockFile =
|
|
7912
|
+
const lockFile = path27.join(entry.absolutePath, lockName);
|
|
7872
7913
|
const locked = await pathExists(lockFile);
|
|
7873
7914
|
if (locked) {
|
|
7874
7915
|
lockedSubagents.add(entry.absolutePath);
|
|
@@ -7885,10 +7926,10 @@ async function provisionSubagents(options) {
|
|
|
7885
7926
|
break;
|
|
7886
7927
|
}
|
|
7887
7928
|
const subagentDir = subagent.absolutePath;
|
|
7888
|
-
const githubAgentsDir =
|
|
7889
|
-
const lockFile =
|
|
7890
|
-
const workspaceDst =
|
|
7891
|
-
const wakeupDst =
|
|
7929
|
+
const githubAgentsDir = path27.join(subagentDir, ".github", "agents");
|
|
7930
|
+
const lockFile = path27.join(subagentDir, lockName);
|
|
7931
|
+
const workspaceDst = path27.join(subagentDir, `${path27.basename(subagentDir)}.code-workspace`);
|
|
7932
|
+
const wakeupDst = path27.join(githubAgentsDir, "wakeup.md");
|
|
7892
7933
|
const isLocked = await pathExists(lockFile);
|
|
7893
7934
|
if (isLocked && !force) {
|
|
7894
7935
|
continue;
|
|
@@ -7926,10 +7967,10 @@ async function provisionSubagents(options) {
|
|
|
7926
7967
|
let nextIndex = highestNumber;
|
|
7927
7968
|
while (subagentsProvisioned < subagents) {
|
|
7928
7969
|
nextIndex += 1;
|
|
7929
|
-
const subagentDir =
|
|
7930
|
-
const githubAgentsDir =
|
|
7931
|
-
const workspaceDst =
|
|
7932
|
-
const wakeupDst =
|
|
7970
|
+
const subagentDir = path27.join(targetPath, `subagent-${nextIndex}`);
|
|
7971
|
+
const githubAgentsDir = path27.join(subagentDir, ".github", "agents");
|
|
7972
|
+
const workspaceDst = path27.join(subagentDir, `${path27.basename(subagentDir)}.code-workspace`);
|
|
7973
|
+
const wakeupDst = path27.join(githubAgentsDir, "wakeup.md");
|
|
7933
7974
|
if (!dryRun) {
|
|
7934
7975
|
await ensureDir(subagentDir);
|
|
7935
7976
|
await ensureDir(githubAgentsDir);
|
|
@@ -8123,7 +8164,7 @@ var VSCodeProvider = class {
|
|
|
8123
8164
|
async function locateVSCodeExecutable(candidate) {
|
|
8124
8165
|
const includesPathSeparator = candidate.includes("/") || candidate.includes("\\");
|
|
8125
8166
|
if (includesPathSeparator) {
|
|
8126
|
-
const resolved =
|
|
8167
|
+
const resolved = path28.isAbsolute(candidate) ? candidate : path28.resolve(candidate);
|
|
8127
8168
|
try {
|
|
8128
8169
|
await access3(resolved, constants3.F_OK);
|
|
8129
8170
|
return resolved;
|
|
@@ -8152,7 +8193,7 @@ async function resolveWorkspaceTemplateFile(template) {
|
|
|
8152
8193
|
return void 0;
|
|
8153
8194
|
}
|
|
8154
8195
|
try {
|
|
8155
|
-
const stats = await stat4(
|
|
8196
|
+
const stats = await stat4(path28.resolve(template));
|
|
8156
8197
|
return stats.isFile() ? template : void 0;
|
|
8157
8198
|
} catch {
|
|
8158
8199
|
return template;
|
|
@@ -8178,7 +8219,7 @@ function buildMandatoryPrereadBlock2(guidelineFiles, attachmentFiles) {
|
|
|
8178
8219
|
return "";
|
|
8179
8220
|
}
|
|
8180
8221
|
const buildList = (files) => files.map((absolutePath) => {
|
|
8181
|
-
const fileName =
|
|
8222
|
+
const fileName = path28.basename(absolutePath);
|
|
8182
8223
|
const fileUri = pathToFileUri3(absolutePath);
|
|
8183
8224
|
return `* [${fileName}](${fileUri})`;
|
|
8184
8225
|
});
|
|
@@ -8203,8 +8244,8 @@ function collectGuidelineFiles2(attachments, guidelinePatterns) {
|
|
|
8203
8244
|
}
|
|
8204
8245
|
const unique = /* @__PURE__ */ new Map();
|
|
8205
8246
|
for (const attachment of attachments) {
|
|
8206
|
-
const absolutePath =
|
|
8207
|
-
const normalized = absolutePath.split(
|
|
8247
|
+
const absolutePath = path28.resolve(attachment);
|
|
8248
|
+
const normalized = absolutePath.split(path28.sep).join("/");
|
|
8208
8249
|
if (isGuidelineFile(normalized, guidelinePatterns)) {
|
|
8209
8250
|
if (!unique.has(absolutePath)) {
|
|
8210
8251
|
unique.set(absolutePath, absolutePath);
|
|
@@ -8219,7 +8260,7 @@ function collectAttachmentFiles(attachments) {
|
|
|
8219
8260
|
}
|
|
8220
8261
|
const unique = /* @__PURE__ */ new Map();
|
|
8221
8262
|
for (const attachment of attachments) {
|
|
8222
|
-
const absolutePath =
|
|
8263
|
+
const absolutePath = path28.resolve(attachment);
|
|
8223
8264
|
if (!unique.has(absolutePath)) {
|
|
8224
8265
|
unique.set(absolutePath, absolutePath);
|
|
8225
8266
|
}
|
|
@@ -8227,7 +8268,7 @@ function collectAttachmentFiles(attachments) {
|
|
|
8227
8268
|
return Array.from(unique.values());
|
|
8228
8269
|
}
|
|
8229
8270
|
function pathToFileUri3(filePath) {
|
|
8230
|
-
const absolutePath =
|
|
8271
|
+
const absolutePath = path28.isAbsolute(filePath) ? filePath : path28.resolve(filePath);
|
|
8231
8272
|
const normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
8232
8273
|
if (/^[a-zA-Z]:\//.test(normalizedPath)) {
|
|
8233
8274
|
return `file:///${normalizedPath}`;
|
|
@@ -8240,7 +8281,7 @@ function normalizeAttachments(attachments) {
|
|
|
8240
8281
|
}
|
|
8241
8282
|
const deduped = /* @__PURE__ */ new Set();
|
|
8242
8283
|
for (const attachment of attachments) {
|
|
8243
|
-
deduped.add(
|
|
8284
|
+
deduped.add(path28.resolve(attachment));
|
|
8244
8285
|
}
|
|
8245
8286
|
return Array.from(deduped);
|
|
8246
8287
|
}
|
|
@@ -8249,7 +8290,7 @@ function mergeAttachments(all) {
|
|
|
8249
8290
|
for (const list of all) {
|
|
8250
8291
|
if (!list) continue;
|
|
8251
8292
|
for (const inputFile of list) {
|
|
8252
|
-
deduped.add(
|
|
8293
|
+
deduped.add(path28.resolve(inputFile));
|
|
8253
8294
|
}
|
|
8254
8295
|
}
|
|
8255
8296
|
return deduped.size > 0 ? Array.from(deduped) : void 0;
|
|
@@ -8298,7 +8339,7 @@ total unlocked subagents available: ${result.created.length + result.skippedExis
|
|
|
8298
8339
|
// src/evaluation/providers/targets-file.ts
|
|
8299
8340
|
import { constants as constants4 } from "node:fs";
|
|
8300
8341
|
import { access as access4, readFile as readFile10 } from "node:fs/promises";
|
|
8301
|
-
import
|
|
8342
|
+
import path29 from "node:path";
|
|
8302
8343
|
import { parse as parse3 } from "yaml";
|
|
8303
8344
|
function isRecord(value) {
|
|
8304
8345
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -8335,7 +8376,7 @@ async function fileExists3(filePath) {
|
|
|
8335
8376
|
}
|
|
8336
8377
|
}
|
|
8337
8378
|
async function readTargetDefinitions(filePath) {
|
|
8338
|
-
const absolutePath =
|
|
8379
|
+
const absolutePath = path29.resolve(filePath);
|
|
8339
8380
|
if (!await fileExists3(absolutePath)) {
|
|
8340
8381
|
throw new Error(`targets.yaml not found at ${absolutePath}`);
|
|
8341
8382
|
}
|
|
@@ -8355,16 +8396,16 @@ function listTargetNames(definitions) {
|
|
|
8355
8396
|
}
|
|
8356
8397
|
|
|
8357
8398
|
// src/evaluation/providers/provider-discovery.ts
|
|
8358
|
-
import
|
|
8399
|
+
import path30 from "node:path";
|
|
8359
8400
|
import fg2 from "fast-glob";
|
|
8360
8401
|
async function discoverProviders(registry, baseDir) {
|
|
8361
8402
|
const patterns = ["*.ts", "*.js", "*.mts", "*.mjs"];
|
|
8362
8403
|
const candidateDirs = [];
|
|
8363
|
-
let dir =
|
|
8364
|
-
const root =
|
|
8404
|
+
let dir = path30.resolve(baseDir);
|
|
8405
|
+
const root = path30.parse(dir).root;
|
|
8365
8406
|
while (dir !== root) {
|
|
8366
|
-
candidateDirs.push(
|
|
8367
|
-
dir =
|
|
8407
|
+
candidateDirs.push(path30.join(dir, ".agentv", "providers"));
|
|
8408
|
+
dir = path30.dirname(dir);
|
|
8368
8409
|
}
|
|
8369
8410
|
let files = [];
|
|
8370
8411
|
for (const providersDir of candidateDirs) {
|
|
@@ -8380,7 +8421,7 @@ async function discoverProviders(registry, baseDir) {
|
|
|
8380
8421
|
}
|
|
8381
8422
|
const discoveredKinds = [];
|
|
8382
8423
|
for (const filePath of files) {
|
|
8383
|
-
const basename =
|
|
8424
|
+
const basename = path30.basename(filePath);
|
|
8384
8425
|
const kindName = basename.replace(/\.(ts|js|mts|mjs)$/, "");
|
|
8385
8426
|
if (registry.has(kindName)) {
|
|
8386
8427
|
continue;
|
|
@@ -8589,13 +8630,13 @@ async function execFileWithStdinNode(argv, stdinPayload, options) {
|
|
|
8589
8630
|
async function execShellWithStdin(command, stdinPayload, options = {}) {
|
|
8590
8631
|
const { mkdir: mkdir14, readFile: readFile12, rm: rm6, writeFile: writeFile9 } = await import("node:fs/promises");
|
|
8591
8632
|
const { tmpdir: tmpdir3 } = await import("node:os");
|
|
8592
|
-
const
|
|
8633
|
+
const path41 = await import("node:path");
|
|
8593
8634
|
const { randomUUID: randomUUID8 } = await import("node:crypto");
|
|
8594
|
-
const dir =
|
|
8635
|
+
const dir = path41.join(tmpdir3(), `agentv-exec-${randomUUID8()}`);
|
|
8595
8636
|
await mkdir14(dir, { recursive: true });
|
|
8596
|
-
const stdinPath =
|
|
8597
|
-
const stdoutPath =
|
|
8598
|
-
const stderrPath =
|
|
8637
|
+
const stdinPath = path41.join(dir, "stdin.txt");
|
|
8638
|
+
const stdoutPath = path41.join(dir, "stdout.txt");
|
|
8639
|
+
const stderrPath = path41.join(dir, "stderr.txt");
|
|
8599
8640
|
await writeFile9(stdinPath, stdinPayload, "utf8");
|
|
8600
8641
|
const wrappedCommand = process.platform === "win32" ? `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}` : `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}`;
|
|
8601
8642
|
const { spawn: spawn4 } = await import("node:child_process");
|
|
@@ -8947,7 +8988,7 @@ var CodeEvaluator = class {
|
|
|
8947
8988
|
outputPath,
|
|
8948
8989
|
guidelineFiles: context.evalCase.guideline_paths,
|
|
8949
8990
|
inputFiles: context.evalCase.file_paths.filter(
|
|
8950
|
-
(
|
|
8991
|
+
(path41) => !context.evalCase.guideline_paths.includes(path41)
|
|
8951
8992
|
),
|
|
8952
8993
|
input: context.evalCase.input,
|
|
8953
8994
|
trace: context.trace ?? null,
|
|
@@ -10145,115 +10186,115 @@ var FieldAccuracyEvaluator = class {
|
|
|
10145
10186
|
* Evaluate a single field against the expected value.
|
|
10146
10187
|
*/
|
|
10147
10188
|
evaluateField(fieldConfig, candidateData, expectedData) {
|
|
10148
|
-
const { path:
|
|
10149
|
-
const candidateValue = resolvePath(candidateData,
|
|
10150
|
-
const expectedValue = resolvePath(expectedData,
|
|
10189
|
+
const { path: path41, match, required = true, weight = 1 } = fieldConfig;
|
|
10190
|
+
const candidateValue = resolvePath(candidateData, path41);
|
|
10191
|
+
const expectedValue = resolvePath(expectedData, path41);
|
|
10151
10192
|
if (expectedValue === void 0) {
|
|
10152
10193
|
return {
|
|
10153
|
-
path:
|
|
10194
|
+
path: path41,
|
|
10154
10195
|
score: 1,
|
|
10155
10196
|
// No expected value means no comparison needed
|
|
10156
10197
|
weight,
|
|
10157
10198
|
hit: true,
|
|
10158
|
-
message: `${
|
|
10199
|
+
message: `${path41}: no expected value`
|
|
10159
10200
|
};
|
|
10160
10201
|
}
|
|
10161
10202
|
if (candidateValue === void 0) {
|
|
10162
10203
|
if (required) {
|
|
10163
10204
|
return {
|
|
10164
|
-
path:
|
|
10205
|
+
path: path41,
|
|
10165
10206
|
score: 0,
|
|
10166
10207
|
weight,
|
|
10167
10208
|
hit: false,
|
|
10168
|
-
message: `${
|
|
10209
|
+
message: `${path41} (required, missing)`
|
|
10169
10210
|
};
|
|
10170
10211
|
}
|
|
10171
10212
|
return {
|
|
10172
|
-
path:
|
|
10213
|
+
path: path41,
|
|
10173
10214
|
score: 1,
|
|
10174
10215
|
// Don't penalize missing optional fields
|
|
10175
10216
|
weight: 0,
|
|
10176
10217
|
// Zero weight means it won't affect the score
|
|
10177
10218
|
hit: true,
|
|
10178
|
-
message: `${
|
|
10219
|
+
message: `${path41}: optional field missing`
|
|
10179
10220
|
};
|
|
10180
10221
|
}
|
|
10181
10222
|
switch (match) {
|
|
10182
10223
|
case "exact":
|
|
10183
|
-
return this.compareExact(
|
|
10224
|
+
return this.compareExact(path41, candidateValue, expectedValue, weight);
|
|
10184
10225
|
case "numeric_tolerance":
|
|
10185
10226
|
return this.compareNumericTolerance(
|
|
10186
|
-
|
|
10227
|
+
path41,
|
|
10187
10228
|
candidateValue,
|
|
10188
10229
|
expectedValue,
|
|
10189
10230
|
fieldConfig,
|
|
10190
10231
|
weight
|
|
10191
10232
|
);
|
|
10192
10233
|
case "date":
|
|
10193
|
-
return this.compareDate(
|
|
10234
|
+
return this.compareDate(path41, candidateValue, expectedValue, fieldConfig, weight);
|
|
10194
10235
|
default:
|
|
10195
10236
|
return {
|
|
10196
|
-
path:
|
|
10237
|
+
path: path41,
|
|
10197
10238
|
score: 0,
|
|
10198
10239
|
weight,
|
|
10199
10240
|
hit: false,
|
|
10200
|
-
message: `${
|
|
10241
|
+
message: `${path41}: unknown match type "${match}"`
|
|
10201
10242
|
};
|
|
10202
10243
|
}
|
|
10203
10244
|
}
|
|
10204
10245
|
/**
|
|
10205
10246
|
* Exact equality comparison.
|
|
10206
10247
|
*/
|
|
10207
|
-
compareExact(
|
|
10248
|
+
compareExact(path41, candidateValue, expectedValue, weight) {
|
|
10208
10249
|
if (deepEqual(candidateValue, expectedValue)) {
|
|
10209
10250
|
return {
|
|
10210
|
-
path:
|
|
10251
|
+
path: path41,
|
|
10211
10252
|
score: 1,
|
|
10212
10253
|
weight,
|
|
10213
10254
|
hit: true,
|
|
10214
|
-
message:
|
|
10255
|
+
message: path41
|
|
10215
10256
|
};
|
|
10216
10257
|
}
|
|
10217
10258
|
if (typeof candidateValue !== typeof expectedValue) {
|
|
10218
10259
|
return {
|
|
10219
|
-
path:
|
|
10260
|
+
path: path41,
|
|
10220
10261
|
score: 0,
|
|
10221
10262
|
weight,
|
|
10222
10263
|
hit: false,
|
|
10223
|
-
message: `${
|
|
10264
|
+
message: `${path41} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
|
|
10224
10265
|
};
|
|
10225
10266
|
}
|
|
10226
10267
|
return {
|
|
10227
|
-
path:
|
|
10268
|
+
path: path41,
|
|
10228
10269
|
score: 0,
|
|
10229
10270
|
weight,
|
|
10230
10271
|
hit: false,
|
|
10231
|
-
message: `${
|
|
10272
|
+
message: `${path41} (value mismatch)`
|
|
10232
10273
|
};
|
|
10233
10274
|
}
|
|
10234
10275
|
/**
|
|
10235
10276
|
* Numeric comparison with absolute or relative tolerance.
|
|
10236
10277
|
*/
|
|
10237
|
-
compareNumericTolerance(
|
|
10278
|
+
compareNumericTolerance(path41, candidateValue, expectedValue, fieldConfig, weight) {
|
|
10238
10279
|
const { tolerance = 0, relative = false } = fieldConfig;
|
|
10239
10280
|
const candidateNum = toNumber2(candidateValue);
|
|
10240
10281
|
const expectedNum = toNumber2(expectedValue);
|
|
10241
10282
|
if (candidateNum === null || expectedNum === null) {
|
|
10242
10283
|
return {
|
|
10243
|
-
path:
|
|
10284
|
+
path: path41,
|
|
10244
10285
|
score: 0,
|
|
10245
10286
|
weight,
|
|
10246
10287
|
hit: false,
|
|
10247
|
-
message: `${
|
|
10288
|
+
message: `${path41} (non-numeric value)`
|
|
10248
10289
|
};
|
|
10249
10290
|
}
|
|
10250
10291
|
if (!Number.isFinite(candidateNum) || !Number.isFinite(expectedNum)) {
|
|
10251
10292
|
return {
|
|
10252
|
-
path:
|
|
10293
|
+
path: path41,
|
|
10253
10294
|
score: 0,
|
|
10254
10295
|
weight,
|
|
10255
10296
|
hit: false,
|
|
10256
|
-
message: `${
|
|
10297
|
+
message: `${path41} (invalid numeric value)`
|
|
10257
10298
|
};
|
|
10258
10299
|
}
|
|
10259
10300
|
const diff = Math.abs(candidateNum - expectedNum);
|
|
@@ -10266,61 +10307,61 @@ var FieldAccuracyEvaluator = class {
|
|
|
10266
10307
|
}
|
|
10267
10308
|
if (withinTolerance) {
|
|
10268
10309
|
return {
|
|
10269
|
-
path:
|
|
10310
|
+
path: path41,
|
|
10270
10311
|
score: 1,
|
|
10271
10312
|
weight,
|
|
10272
10313
|
hit: true,
|
|
10273
|
-
message: `${
|
|
10314
|
+
message: `${path41} (within tolerance: diff=${diff.toFixed(2)})`
|
|
10274
10315
|
};
|
|
10275
10316
|
}
|
|
10276
10317
|
return {
|
|
10277
|
-
path:
|
|
10318
|
+
path: path41,
|
|
10278
10319
|
score: 0,
|
|
10279
10320
|
weight,
|
|
10280
10321
|
hit: false,
|
|
10281
|
-
message: `${
|
|
10322
|
+
message: `${path41} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
|
|
10282
10323
|
};
|
|
10283
10324
|
}
|
|
10284
10325
|
/**
|
|
10285
10326
|
* Date comparison with format normalization.
|
|
10286
10327
|
*/
|
|
10287
|
-
compareDate(
|
|
10328
|
+
compareDate(path41, candidateValue, expectedValue, fieldConfig, weight) {
|
|
10288
10329
|
const formats = fieldConfig.formats ?? DEFAULT_DATE_FORMATS;
|
|
10289
10330
|
const candidateDate = parseDate(String(candidateValue), formats);
|
|
10290
10331
|
const expectedDate = parseDate(String(expectedValue), formats);
|
|
10291
10332
|
if (candidateDate === null) {
|
|
10292
10333
|
return {
|
|
10293
|
-
path:
|
|
10334
|
+
path: path41,
|
|
10294
10335
|
score: 0,
|
|
10295
10336
|
weight,
|
|
10296
10337
|
hit: false,
|
|
10297
|
-
message: `${
|
|
10338
|
+
message: `${path41} (unparseable candidate date)`
|
|
10298
10339
|
};
|
|
10299
10340
|
}
|
|
10300
10341
|
if (expectedDate === null) {
|
|
10301
10342
|
return {
|
|
10302
|
-
path:
|
|
10343
|
+
path: path41,
|
|
10303
10344
|
score: 0,
|
|
10304
10345
|
weight,
|
|
10305
10346
|
hit: false,
|
|
10306
|
-
message: `${
|
|
10347
|
+
message: `${path41} (unparseable expected date)`
|
|
10307
10348
|
};
|
|
10308
10349
|
}
|
|
10309
10350
|
if (candidateDate.getFullYear() === expectedDate.getFullYear() && candidateDate.getMonth() === expectedDate.getMonth() && candidateDate.getDate() === expectedDate.getDate()) {
|
|
10310
10351
|
return {
|
|
10311
|
-
path:
|
|
10352
|
+
path: path41,
|
|
10312
10353
|
score: 1,
|
|
10313
10354
|
weight,
|
|
10314
10355
|
hit: true,
|
|
10315
|
-
message:
|
|
10356
|
+
message: path41
|
|
10316
10357
|
};
|
|
10317
10358
|
}
|
|
10318
10359
|
return {
|
|
10319
|
-
path:
|
|
10360
|
+
path: path41,
|
|
10320
10361
|
score: 0,
|
|
10321
10362
|
weight,
|
|
10322
10363
|
hit: false,
|
|
10323
|
-
message: `${
|
|
10364
|
+
message: `${path41} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
|
|
10324
10365
|
};
|
|
10325
10366
|
}
|
|
10326
10367
|
/**
|
|
@@ -10361,11 +10402,11 @@ var FieldAccuracyEvaluator = class {
|
|
|
10361
10402
|
};
|
|
10362
10403
|
}
|
|
10363
10404
|
};
|
|
10364
|
-
function resolvePath(obj,
|
|
10365
|
-
if (!
|
|
10405
|
+
function resolvePath(obj, path41) {
|
|
10406
|
+
if (!path41 || !obj) {
|
|
10366
10407
|
return void 0;
|
|
10367
10408
|
}
|
|
10368
|
-
const parts =
|
|
10409
|
+
const parts = path41.split(/\.|\[|\]/).filter((p) => p.length > 0);
|
|
10369
10410
|
let current = obj;
|
|
10370
10411
|
for (const part of parts) {
|
|
10371
10412
|
if (current === null || current === void 0) {
|
|
@@ -10497,7 +10538,7 @@ var LatencyEvaluator = class {
|
|
|
10497
10538
|
|
|
10498
10539
|
// src/evaluation/evaluators/agent-judge.ts
|
|
10499
10540
|
import fs2 from "node:fs/promises";
|
|
10500
|
-
import
|
|
10541
|
+
import path31 from "node:path";
|
|
10501
10542
|
import { generateText as generateText4, stepCountIs, tool } from "ai";
|
|
10502
10543
|
import { z as z4 } from "zod";
|
|
10503
10544
|
var DEFAULT_MAX_STEPS = 10;
|
|
@@ -10846,8 +10887,8 @@ ${outputSchema}`;
|
|
|
10846
10887
|
}
|
|
10847
10888
|
};
|
|
10848
10889
|
function resolveSandboxed(basePath, relativePath) {
|
|
10849
|
-
const resolved =
|
|
10850
|
-
if (!resolved.startsWith(basePath +
|
|
10890
|
+
const resolved = path31.resolve(basePath, relativePath);
|
|
10891
|
+
if (!resolved.startsWith(basePath + path31.sep) && resolved !== basePath) {
|
|
10851
10892
|
throw new Error(`Path '${relativePath}' is outside the workspace`);
|
|
10852
10893
|
}
|
|
10853
10894
|
return resolved;
|
|
@@ -10930,11 +10971,11 @@ async function searchDirectory(dirPath, workspacePath, regex, matches) {
|
|
|
10930
10971
|
for (const entry of entries) {
|
|
10931
10972
|
if (matches.length >= MAX_SEARCH_MATCHES) return;
|
|
10932
10973
|
if (SEARCH_SKIP_DIRS.has(entry.name)) continue;
|
|
10933
|
-
const fullPath =
|
|
10974
|
+
const fullPath = path31.join(dirPath, entry.name);
|
|
10934
10975
|
if (entry.isDirectory()) {
|
|
10935
10976
|
await searchDirectory(fullPath, workspacePath, regex, matches);
|
|
10936
10977
|
} else if (entry.isFile()) {
|
|
10937
|
-
const ext =
|
|
10978
|
+
const ext = path31.extname(entry.name).toLowerCase();
|
|
10938
10979
|
if (BINARY_EXTENSIONS.has(ext)) continue;
|
|
10939
10980
|
try {
|
|
10940
10981
|
const stat8 = await fs2.stat(fullPath);
|
|
@@ -10946,7 +10987,7 @@ async function searchDirectory(dirPath, workspacePath, regex, matches) {
|
|
|
10946
10987
|
regex.lastIndex = 0;
|
|
10947
10988
|
if (regex.test(lines[i])) {
|
|
10948
10989
|
matches.push({
|
|
10949
|
-
file:
|
|
10990
|
+
file: path31.relative(workspacePath, fullPath),
|
|
10950
10991
|
line: i + 1,
|
|
10951
10992
|
text: lines[i].substring(0, 200)
|
|
10952
10993
|
});
|
|
@@ -11183,8 +11224,8 @@ var TokenUsageEvaluator = class {
|
|
|
11183
11224
|
};
|
|
11184
11225
|
|
|
11185
11226
|
// src/evaluation/evaluators/tool-trajectory.ts
|
|
11186
|
-
function getNestedValue(obj,
|
|
11187
|
-
const parts =
|
|
11227
|
+
function getNestedValue(obj, path41) {
|
|
11228
|
+
const parts = path41.split(".");
|
|
11188
11229
|
let current = obj;
|
|
11189
11230
|
for (const part of parts) {
|
|
11190
11231
|
if (current === null || current === void 0 || typeof current !== "object") {
|
|
@@ -11747,7 +11788,7 @@ function runEqualsAssertion(output, value) {
|
|
|
11747
11788
|
// src/evaluation/orchestrator.ts
|
|
11748
11789
|
import { createHash as createHash2, randomUUID as randomUUID7 } from "node:crypto";
|
|
11749
11790
|
import { mkdir as mkdir12, stat as stat7 } from "node:fs/promises";
|
|
11750
|
-
import
|
|
11791
|
+
import path38 from "node:path";
|
|
11751
11792
|
import micromatch4 from "micromatch";
|
|
11752
11793
|
|
|
11753
11794
|
// ../../node_modules/.bun/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
|
|
@@ -11938,7 +11979,7 @@ var DeterministicAssertionEvaluator = class {
|
|
|
11938
11979
|
import { readFileSync } from "node:fs";
|
|
11939
11980
|
|
|
11940
11981
|
// src/evaluation/evaluators/prompt-resolution.ts
|
|
11941
|
-
import
|
|
11982
|
+
import path32 from "node:path";
|
|
11942
11983
|
async function resolveCustomPrompt(promptConfig, context, timeoutMs) {
|
|
11943
11984
|
if (promptConfig.resolvedPromptScript && promptConfig.resolvedPromptScript.length > 0) {
|
|
11944
11985
|
if (!context) {
|
|
@@ -11987,7 +12028,7 @@ async function executePromptTemplate(script, context, config, timeoutMs) {
|
|
|
11987
12028
|
};
|
|
11988
12029
|
const inputJson = JSON.stringify(toSnakeCaseDeep(payload), null, 2);
|
|
11989
12030
|
const scriptPath = script[script.length - 1];
|
|
11990
|
-
const cwd =
|
|
12031
|
+
const cwd = path32.dirname(scriptPath);
|
|
11991
12032
|
try {
|
|
11992
12033
|
const stdout = await executeScript(script, inputJson, timeoutMs, cwd);
|
|
11993
12034
|
const prompt = stdout.trim();
|
|
@@ -12280,16 +12321,16 @@ function createBuiltinRegistry() {
|
|
|
12280
12321
|
}
|
|
12281
12322
|
|
|
12282
12323
|
// src/evaluation/registry/assertion-discovery.ts
|
|
12283
|
-
import
|
|
12324
|
+
import path33 from "node:path";
|
|
12284
12325
|
import fg3 from "fast-glob";
|
|
12285
12326
|
async function discoverAssertions(registry, baseDir) {
|
|
12286
12327
|
const patterns = ["*.ts", "*.js", "*.mts", "*.mjs"];
|
|
12287
12328
|
const candidateDirs = [];
|
|
12288
|
-
let dir =
|
|
12289
|
-
const root =
|
|
12329
|
+
let dir = path33.resolve(baseDir);
|
|
12330
|
+
const root = path33.parse(dir).root;
|
|
12290
12331
|
while (dir !== root) {
|
|
12291
|
-
candidateDirs.push(
|
|
12292
|
-
dir =
|
|
12332
|
+
candidateDirs.push(path33.join(dir, ".agentv", "assertions"));
|
|
12333
|
+
dir = path33.dirname(dir);
|
|
12293
12334
|
}
|
|
12294
12335
|
let files = [];
|
|
12295
12336
|
for (const assertionsDir of candidateDirs) {
|
|
@@ -12305,7 +12346,7 @@ async function discoverAssertions(registry, baseDir) {
|
|
|
12305
12346
|
}
|
|
12306
12347
|
const discoveredTypes = [];
|
|
12307
12348
|
for (const filePath of files) {
|
|
12308
|
-
const basename =
|
|
12349
|
+
const basename = path33.basename(filePath);
|
|
12309
12350
|
const typeName = basename.replace(/\.(ts|js|mts|mjs)$/, "");
|
|
12310
12351
|
if (registry.has(typeName)) {
|
|
12311
12352
|
continue;
|
|
@@ -12465,7 +12506,7 @@ function getTCritical(df) {
|
|
|
12465
12506
|
// src/evaluation/workspace/file-changes.ts
|
|
12466
12507
|
import { exec as execCallback } from "node:child_process";
|
|
12467
12508
|
import { readdirSync as readdirSync2, statSync } from "node:fs";
|
|
12468
|
-
import
|
|
12509
|
+
import path34 from "node:path";
|
|
12469
12510
|
import { promisify as promisify4 } from "node:util";
|
|
12470
12511
|
var execAsync4 = promisify4(execCallback);
|
|
12471
12512
|
function gitExecOpts(workspacePath) {
|
|
@@ -12499,10 +12540,10 @@ async function stageNestedRepoChanges(workspacePath) {
|
|
|
12499
12540
|
}
|
|
12500
12541
|
for (const entry of entries) {
|
|
12501
12542
|
if (entry === ".git" || entry === "node_modules") continue;
|
|
12502
|
-
const childPath =
|
|
12543
|
+
const childPath = path34.join(workspacePath, entry);
|
|
12503
12544
|
try {
|
|
12504
12545
|
if (!statSync(childPath).isDirectory()) continue;
|
|
12505
|
-
if (!statSync(
|
|
12546
|
+
if (!statSync(path34.join(childPath, ".git")).isDirectory()) continue;
|
|
12506
12547
|
} catch {
|
|
12507
12548
|
continue;
|
|
12508
12549
|
}
|
|
@@ -12513,9 +12554,7 @@ async function stageNestedRepoChanges(workspacePath) {
|
|
|
12513
12554
|
|
|
12514
12555
|
// src/evaluation/workspace/manager.ts
|
|
12515
12556
|
import { cp, mkdir as mkdir10, readdir as readdir3, rm as rm4, stat as stat5 } from "node:fs/promises";
|
|
12516
|
-
import
|
|
12517
|
-
import path34 from "node:path";
|
|
12518
|
-
var DEFAULT_WORKSPACE_ROOT = path34.join(os3.homedir(), ".agentv", "workspaces");
|
|
12557
|
+
import path35 from "node:path";
|
|
12519
12558
|
var TemplateNotFoundError = class extends Error {
|
|
12520
12559
|
constructor(templatePath) {
|
|
12521
12560
|
super(`Workspace template not found: ${templatePath}`);
|
|
@@ -12544,15 +12583,15 @@ async function isDirectory(filePath) {
|
|
|
12544
12583
|
}
|
|
12545
12584
|
}
|
|
12546
12585
|
function getWorkspacePath(evalRunId, caseId, workspaceRoot) {
|
|
12547
|
-
const root = workspaceRoot ??
|
|
12548
|
-
return
|
|
12586
|
+
const root = workspaceRoot ?? getWorkspacesRoot();
|
|
12587
|
+
return path35.join(root, evalRunId, caseId);
|
|
12549
12588
|
}
|
|
12550
12589
|
async function copyDirectoryRecursive(src, dest) {
|
|
12551
12590
|
await mkdir10(dest, { recursive: true });
|
|
12552
12591
|
const entries = await readdir3(src, { withFileTypes: true });
|
|
12553
12592
|
for (const entry of entries) {
|
|
12554
|
-
const srcPath =
|
|
12555
|
-
const destPath =
|
|
12593
|
+
const srcPath = path35.join(src, entry.name);
|
|
12594
|
+
const destPath = path35.join(dest, entry.name);
|
|
12556
12595
|
if (entry.name === ".git") {
|
|
12557
12596
|
continue;
|
|
12558
12597
|
}
|
|
@@ -12564,7 +12603,7 @@ async function copyDirectoryRecursive(src, dest) {
|
|
|
12564
12603
|
}
|
|
12565
12604
|
}
|
|
12566
12605
|
async function createTempWorkspace(templatePath, evalRunId, caseId, workspaceRoot) {
|
|
12567
|
-
const resolvedTemplatePath =
|
|
12606
|
+
const resolvedTemplatePath = path35.resolve(templatePath);
|
|
12568
12607
|
if (!await fileExists(resolvedTemplatePath)) {
|
|
12569
12608
|
throw new TemplateNotFoundError(resolvedTemplatePath);
|
|
12570
12609
|
}
|
|
@@ -12612,8 +12651,8 @@ async function cleanupWorkspace(workspacePath) {
|
|
|
12612
12651
|
}
|
|
12613
12652
|
}
|
|
12614
12653
|
async function cleanupEvalWorkspaces(evalRunId, workspaceRoot) {
|
|
12615
|
-
const root = workspaceRoot ??
|
|
12616
|
-
const evalDir =
|
|
12654
|
+
const root = workspaceRoot ?? getWorkspacesRoot();
|
|
12655
|
+
const evalDir = path35.join(root, evalRunId);
|
|
12617
12656
|
if (await fileExists(evalDir)) {
|
|
12618
12657
|
await rm4(evalDir, { recursive: true, force: true });
|
|
12619
12658
|
}
|
|
@@ -12624,11 +12663,9 @@ import { execFile } from "node:child_process";
|
|
|
12624
12663
|
import { createHash } from "node:crypto";
|
|
12625
12664
|
import { existsSync as existsSync2 } from "node:fs";
|
|
12626
12665
|
import { mkdir as mkdir11, rm as rm5, unlink, writeFile as writeFile7 } from "node:fs/promises";
|
|
12627
|
-
import
|
|
12628
|
-
import path35 from "node:path";
|
|
12666
|
+
import path36 from "node:path";
|
|
12629
12667
|
import { promisify as promisify5 } from "node:util";
|
|
12630
12668
|
var execFileAsync = promisify5(execFile);
|
|
12631
|
-
var DEFAULT_CACHE_DIR = path35.join(os4.homedir(), ".agentv", "git-cache");
|
|
12632
12669
|
var DEFAULT_TIMEOUT_MS2 = 3e5;
|
|
12633
12670
|
var LOCK_TIMEOUT_MS = 6e4;
|
|
12634
12671
|
function gitEnv() {
|
|
@@ -12686,8 +12723,35 @@ async function releaseLock(lockPath) {
|
|
|
12686
12723
|
}
|
|
12687
12724
|
var RepoManager = class {
|
|
12688
12725
|
cacheDir;
|
|
12689
|
-
|
|
12690
|
-
|
|
12726
|
+
verbose;
|
|
12727
|
+
constructor(cacheDir, verbose = false) {
|
|
12728
|
+
this.cacheDir = cacheDir ?? getGitCacheRoot();
|
|
12729
|
+
this.verbose = verbose;
|
|
12730
|
+
}
|
|
12731
|
+
async runGit(args, opts) {
|
|
12732
|
+
const startedAt = Date.now();
|
|
12733
|
+
if (this.verbose) {
|
|
12734
|
+
console.log(
|
|
12735
|
+
`[repo] git start cwd=${opts?.cwd ?? process.cwd()} args=${args.join(" ")}`
|
|
12736
|
+
);
|
|
12737
|
+
}
|
|
12738
|
+
try {
|
|
12739
|
+
const output = await git(args, opts);
|
|
12740
|
+
if (this.verbose) {
|
|
12741
|
+
console.log(
|
|
12742
|
+
`[repo] git ok durationMs=${Date.now() - startedAt} args=${args.join(" ")}`
|
|
12743
|
+
);
|
|
12744
|
+
}
|
|
12745
|
+
return output;
|
|
12746
|
+
} catch (error) {
|
|
12747
|
+
if (this.verbose) {
|
|
12748
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
12749
|
+
console.log(
|
|
12750
|
+
`[repo] git fail durationMs=${Date.now() - startedAt} args=${args.join(" ")} error=${message}`
|
|
12751
|
+
);
|
|
12752
|
+
}
|
|
12753
|
+
throw error;
|
|
12754
|
+
}
|
|
12691
12755
|
}
|
|
12692
12756
|
/**
|
|
12693
12757
|
* Ensure a bare mirror cache exists for the given source.
|
|
@@ -12696,11 +12760,19 @@ var RepoManager = class {
|
|
|
12696
12760
|
*/
|
|
12697
12761
|
async ensureCache(source, depth, resolve) {
|
|
12698
12762
|
const key = cacheKey(source);
|
|
12699
|
-
const cachePath =
|
|
12763
|
+
const cachePath = path36.join(this.cacheDir, key);
|
|
12700
12764
|
const lockPath = `${cachePath}.lock`;
|
|
12701
|
-
const cacheExists = existsSync2(
|
|
12765
|
+
const cacheExists = existsSync2(path36.join(cachePath, "HEAD"));
|
|
12766
|
+
if (this.verbose) {
|
|
12767
|
+
console.log(
|
|
12768
|
+
`[repo] ensureCache source=${getSourceUrl(source)} resolve=${resolve ?? "remote"} cache=${cachePath}`
|
|
12769
|
+
);
|
|
12770
|
+
}
|
|
12702
12771
|
if (resolve === "local") {
|
|
12703
12772
|
if (cacheExists) {
|
|
12773
|
+
if (this.verbose) {
|
|
12774
|
+
console.log(`[repo] using existing local cache ${cachePath}`);
|
|
12775
|
+
}
|
|
12704
12776
|
return cachePath;
|
|
12705
12777
|
}
|
|
12706
12778
|
const url = getSourceUrl(source);
|
|
@@ -12709,15 +12781,27 @@ var RepoManager = class {
|
|
|
12709
12781
|
);
|
|
12710
12782
|
}
|
|
12711
12783
|
await mkdir11(this.cacheDir, { recursive: true });
|
|
12784
|
+
const lockStartedAt = Date.now();
|
|
12712
12785
|
await acquireLock(lockPath);
|
|
12786
|
+
if (this.verbose) {
|
|
12787
|
+
console.log(
|
|
12788
|
+
`[repo] lock acquired path=${lockPath} waitedMs=${Date.now() - lockStartedAt}`
|
|
12789
|
+
);
|
|
12790
|
+
}
|
|
12713
12791
|
try {
|
|
12714
12792
|
if (cacheExists) {
|
|
12793
|
+
if (this.verbose) {
|
|
12794
|
+
console.log(`[repo] refreshing existing cache ${cachePath}`);
|
|
12795
|
+
}
|
|
12715
12796
|
const fetchArgs = ["fetch", "--prune"];
|
|
12716
12797
|
if (depth) {
|
|
12717
12798
|
fetchArgs.push("--depth", String(depth));
|
|
12718
12799
|
}
|
|
12719
|
-
await
|
|
12800
|
+
await this.runGit(fetchArgs, { cwd: cachePath });
|
|
12720
12801
|
} else {
|
|
12802
|
+
if (this.verbose) {
|
|
12803
|
+
console.log(`[repo] creating new cache ${cachePath}`);
|
|
12804
|
+
}
|
|
12721
12805
|
const cloneArgs = ["clone", "--mirror", "--bare"];
|
|
12722
12806
|
if (depth) {
|
|
12723
12807
|
cloneArgs.push("--depth", String(depth));
|
|
@@ -12725,10 +12809,13 @@ var RepoManager = class {
|
|
|
12725
12809
|
const sourceUrl = getSourceUrl(source);
|
|
12726
12810
|
const cloneUrl = depth && source.type === "local" ? `file://${sourceUrl}` : sourceUrl;
|
|
12727
12811
|
cloneArgs.push(cloneUrl, cachePath);
|
|
12728
|
-
await
|
|
12812
|
+
await this.runGit(cloneArgs);
|
|
12729
12813
|
}
|
|
12730
12814
|
} finally {
|
|
12731
12815
|
await releaseLock(lockPath);
|
|
12816
|
+
if (this.verbose) {
|
|
12817
|
+
console.log(`[repo] lock released path=${lockPath}`);
|
|
12818
|
+
}
|
|
12732
12819
|
}
|
|
12733
12820
|
return cachePath;
|
|
12734
12821
|
}
|
|
@@ -12737,7 +12824,13 @@ var RepoManager = class {
|
|
|
12737
12824
|
* Handles checkout, ref resolution, ancestor walking, shallow clone, sparse checkout.
|
|
12738
12825
|
*/
|
|
12739
12826
|
async materialize(repo, workspacePath) {
|
|
12740
|
-
const targetDir =
|
|
12827
|
+
const targetDir = path36.join(workspacePath, repo.path);
|
|
12828
|
+
const startedAt = Date.now();
|
|
12829
|
+
if (this.verbose) {
|
|
12830
|
+
console.log(
|
|
12831
|
+
`[repo] materialize start path=${repo.path} source=${getSourceUrl(repo.source)} workspace=${workspacePath}`
|
|
12832
|
+
);
|
|
12833
|
+
}
|
|
12741
12834
|
const cachePath = await this.ensureCache(
|
|
12742
12835
|
repo.source,
|
|
12743
12836
|
repo.clone?.depth,
|
|
@@ -12753,10 +12846,10 @@ var RepoManager = class {
|
|
|
12753
12846
|
cloneArgs.push("--no-checkout");
|
|
12754
12847
|
const cloneUrl = repo.clone?.depth || repo.clone?.filter ? `file://${cachePath}` : cachePath;
|
|
12755
12848
|
cloneArgs.push(cloneUrl, targetDir);
|
|
12756
|
-
await
|
|
12849
|
+
await this.runGit(cloneArgs);
|
|
12757
12850
|
if (repo.clone?.sparse?.length) {
|
|
12758
|
-
await
|
|
12759
|
-
await
|
|
12851
|
+
await this.runGit(["sparse-checkout", "init", "--cone"], { cwd: targetDir });
|
|
12852
|
+
await this.runGit(["sparse-checkout", "set", ...repo.clone.sparse], { cwd: targetDir });
|
|
12760
12853
|
}
|
|
12761
12854
|
const ref = repo.checkout?.ref ?? "HEAD";
|
|
12762
12855
|
const resolve = repo.checkout?.resolve ?? "remote";
|
|
@@ -12764,7 +12857,7 @@ var RepoManager = class {
|
|
|
12764
12857
|
if (resolve === "remote" && repo.source.type === "git") {
|
|
12765
12858
|
const url = getSourceUrl(repo.source);
|
|
12766
12859
|
try {
|
|
12767
|
-
const lsOutput = await
|
|
12860
|
+
const lsOutput = await this.runGit(["ls-remote", url, ref]);
|
|
12768
12861
|
const match = lsOutput.split(" ")[0];
|
|
12769
12862
|
if (!match) {
|
|
12770
12863
|
throw new Error(`Ref '${ref}' not found on remote ${url}`);
|
|
@@ -12777,17 +12870,26 @@ var RepoManager = class {
|
|
|
12777
12870
|
} else {
|
|
12778
12871
|
resolvedSha = ref;
|
|
12779
12872
|
}
|
|
12780
|
-
|
|
12873
|
+
if (this.verbose) {
|
|
12874
|
+
console.log(
|
|
12875
|
+
`[repo] checkout path=${repo.path} ref=${ref} resolved=${resolvedSha} resolve=${resolve}`
|
|
12876
|
+
);
|
|
12877
|
+
}
|
|
12878
|
+
await this.runGit(["checkout", resolvedSha], { cwd: targetDir });
|
|
12781
12879
|
const ancestor = repo.checkout?.ancestor ?? 0;
|
|
12782
12880
|
if (ancestor > 0) {
|
|
12783
12881
|
try {
|
|
12784
|
-
const ancestorSha = await
|
|
12785
|
-
|
|
12882
|
+
const ancestorSha = await this.runGit(["rev-parse", `HEAD~${ancestor}`], {
|
|
12883
|
+
cwd: targetDir
|
|
12884
|
+
});
|
|
12885
|
+
await this.runGit(["checkout", ancestorSha], { cwd: targetDir });
|
|
12786
12886
|
} catch {
|
|
12787
12887
|
if (repo.clone?.depth) {
|
|
12788
|
-
await
|
|
12789
|
-
const ancestorSha = await
|
|
12790
|
-
|
|
12888
|
+
await this.runGit(["fetch", "--deepen", String(ancestor)], { cwd: targetDir });
|
|
12889
|
+
const ancestorSha = await this.runGit(["rev-parse", `HEAD~${ancestor}`], {
|
|
12890
|
+
cwd: targetDir
|
|
12891
|
+
});
|
|
12892
|
+
await this.runGit(["checkout", ancestorSha], { cwd: targetDir });
|
|
12791
12893
|
} else {
|
|
12792
12894
|
throw new Error(
|
|
12793
12895
|
`Cannot resolve ancestor ${ancestor} of ref '${ref}'. If using shallow clone, increase clone.depth to at least ${ancestor + 1}.`
|
|
@@ -12795,27 +12897,38 @@ var RepoManager = class {
|
|
|
12795
12897
|
}
|
|
12796
12898
|
}
|
|
12797
12899
|
}
|
|
12900
|
+
if (this.verbose) {
|
|
12901
|
+
console.log(
|
|
12902
|
+
`[repo] materialize done path=${repo.path} target=${targetDir} durationMs=${Date.now() - startedAt}`
|
|
12903
|
+
);
|
|
12904
|
+
}
|
|
12798
12905
|
}
|
|
12799
12906
|
/** Materialize all repos into the workspace. */
|
|
12800
12907
|
async materializeAll(repos, workspacePath) {
|
|
12908
|
+
if (this.verbose) {
|
|
12909
|
+
console.log(`[repo] materializeAll count=${repos.length} workspace=${workspacePath}`);
|
|
12910
|
+
}
|
|
12801
12911
|
for (const repo of repos) {
|
|
12802
12912
|
await this.materialize(repo, workspacePath);
|
|
12803
12913
|
}
|
|
12914
|
+
if (this.verbose) {
|
|
12915
|
+
console.log("[repo] materializeAll complete");
|
|
12916
|
+
}
|
|
12804
12917
|
}
|
|
12805
12918
|
/** Reset repos in workspace to their checkout state. */
|
|
12806
12919
|
async reset(repos, workspacePath, strategy) {
|
|
12807
12920
|
if (strategy === "recreate") {
|
|
12808
12921
|
for (const repo of repos) {
|
|
12809
|
-
const targetDir =
|
|
12922
|
+
const targetDir = path36.join(workspacePath, repo.path);
|
|
12810
12923
|
await rm5(targetDir, { recursive: true, force: true });
|
|
12811
12924
|
}
|
|
12812
12925
|
await this.materializeAll(repos, workspacePath);
|
|
12813
12926
|
return;
|
|
12814
12927
|
}
|
|
12815
12928
|
for (const repo of repos) {
|
|
12816
|
-
const targetDir =
|
|
12817
|
-
await
|
|
12818
|
-
await
|
|
12929
|
+
const targetDir = path36.join(workspacePath, repo.path);
|
|
12930
|
+
await this.runGit(["reset", "--hard", "HEAD"], { cwd: targetDir });
|
|
12931
|
+
await this.runGit(["clean", "-fd"], { cwd: targetDir });
|
|
12819
12932
|
}
|
|
12820
12933
|
}
|
|
12821
12934
|
/**
|
|
@@ -12825,12 +12938,12 @@ var RepoManager = class {
|
|
|
12825
12938
|
async seedCache(localPath, remoteUrl, opts) {
|
|
12826
12939
|
const source = { type: "git", url: remoteUrl };
|
|
12827
12940
|
const key = cacheKey(source);
|
|
12828
|
-
const cachePath =
|
|
12941
|
+
const cachePath = path36.join(this.cacheDir, key);
|
|
12829
12942
|
const lockPath = `${cachePath}.lock`;
|
|
12830
12943
|
await mkdir11(this.cacheDir, { recursive: true });
|
|
12831
12944
|
await acquireLock(lockPath);
|
|
12832
12945
|
try {
|
|
12833
|
-
if (existsSync2(
|
|
12946
|
+
if (existsSync2(path36.join(cachePath, "HEAD"))) {
|
|
12834
12947
|
if (!opts?.force) {
|
|
12835
12948
|
throw new Error(
|
|
12836
12949
|
`Cache already exists for ${remoteUrl} at ${cachePath}. Use force to overwrite.`
|
|
@@ -12853,16 +12966,16 @@ var RepoManager = class {
|
|
|
12853
12966
|
|
|
12854
12967
|
// src/evaluation/workspace/resolve.ts
|
|
12855
12968
|
import { readdir as readdir4, stat as stat6 } from "node:fs/promises";
|
|
12856
|
-
import
|
|
12969
|
+
import path37 from "node:path";
|
|
12857
12970
|
async function resolveWorkspaceTemplate(templatePath) {
|
|
12858
12971
|
if (!templatePath) {
|
|
12859
12972
|
return void 0;
|
|
12860
12973
|
}
|
|
12861
|
-
const resolved =
|
|
12974
|
+
const resolved = path37.resolve(templatePath);
|
|
12862
12975
|
const stats = await stat6(resolved);
|
|
12863
12976
|
if (stats.isFile()) {
|
|
12864
12977
|
return {
|
|
12865
|
-
dir:
|
|
12978
|
+
dir: path37.dirname(resolved),
|
|
12866
12979
|
workspaceFile: resolved
|
|
12867
12980
|
};
|
|
12868
12981
|
}
|
|
@@ -12874,14 +12987,14 @@ async function resolveWorkspaceTemplate(templatePath) {
|
|
|
12874
12987
|
if (workspaceFiles.length === 1) {
|
|
12875
12988
|
return {
|
|
12876
12989
|
dir: resolved,
|
|
12877
|
-
workspaceFile:
|
|
12990
|
+
workspaceFile: path37.join(resolved, workspaceFiles[0])
|
|
12878
12991
|
};
|
|
12879
12992
|
}
|
|
12880
12993
|
if (workspaceFiles.length > 1) {
|
|
12881
12994
|
const conventionFile = workspaceFiles.find((f) => f === "template.code-workspace");
|
|
12882
12995
|
return {
|
|
12883
12996
|
dir: resolved,
|
|
12884
|
-
workspaceFile: conventionFile ?
|
|
12997
|
+
workspaceFile: conventionFile ? path37.join(resolved, conventionFile) : void 0
|
|
12885
12998
|
};
|
|
12886
12999
|
}
|
|
12887
13000
|
return { dir: resolved };
|
|
@@ -13037,7 +13150,7 @@ async function runEvaluation(options) {
|
|
|
13037
13150
|
];
|
|
13038
13151
|
const evaluatorRegistry = buildEvaluatorRegistry(evaluators, resolveJudgeProvider);
|
|
13039
13152
|
const typeRegistry = createBuiltinRegistry();
|
|
13040
|
-
const discoveryBaseDir = evalFilePath ?
|
|
13153
|
+
const discoveryBaseDir = evalFilePath ? path38.dirname(path38.resolve(evalFilePath)) : process.cwd();
|
|
13041
13154
|
const evalDir = discoveryBaseDir;
|
|
13042
13155
|
await discoverAssertions(typeRegistry, discoveryBaseDir);
|
|
13043
13156
|
const providerRegistry = createBuiltinProviderRegistry();
|
|
@@ -13093,10 +13206,18 @@ async function runEvaluation(options) {
|
|
|
13093
13206
|
const resolvedTemplate = await resolveWorkspaceTemplate(rawTemplate);
|
|
13094
13207
|
const workspaceTemplate = resolvedTemplate?.dir;
|
|
13095
13208
|
let suiteWorkspaceFile = resolvedTemplate?.workspaceFile;
|
|
13209
|
+
const setupLog = (message) => {
|
|
13210
|
+
if (verbose) {
|
|
13211
|
+
console.log(`[setup] ${message}`);
|
|
13212
|
+
}
|
|
13213
|
+
};
|
|
13096
13214
|
const isPerTestIsolation = suiteWorkspace?.isolation === "per_test";
|
|
13097
13215
|
const hasSharedWorkspace = !!(workspaceTemplate || suiteWorkspace?.before_all || suiteWorkspace?.repos?.length && !isPerTestIsolation);
|
|
13098
13216
|
const requestedWorkers = options.maxConcurrency ?? target.workers ?? 1;
|
|
13099
13217
|
const workers = hasSharedWorkspace ? 1 : requestedWorkers;
|
|
13218
|
+
setupLog(
|
|
13219
|
+
`sharedWorkspace=${hasSharedWorkspace} perTestIsolation=${isPerTestIsolation} requestedWorkers=${requestedWorkers} effectiveWorkers=${workers}`
|
|
13220
|
+
);
|
|
13100
13221
|
if (hasSharedWorkspace && requestedWorkers > 1) {
|
|
13101
13222
|
console.warn(
|
|
13102
13223
|
`Warning: Shared workspace requires sequential execution. Overriding workers from ${requestedWorkers} to 1.`
|
|
@@ -13107,14 +13228,16 @@ async function runEvaluation(options) {
|
|
|
13107
13228
|
let sharedBaselineCommit;
|
|
13108
13229
|
let beforeAllOutput;
|
|
13109
13230
|
if (workspaceTemplate) {
|
|
13231
|
+
setupLog(`creating shared workspace from template: ${workspaceTemplate}`);
|
|
13110
13232
|
try {
|
|
13111
13233
|
sharedWorkspacePath = await createTempWorkspace(workspaceTemplate, evalRunId, "shared");
|
|
13234
|
+
setupLog(`shared workspace created at: ${sharedWorkspacePath}`);
|
|
13112
13235
|
} catch (error) {
|
|
13113
13236
|
const message = error instanceof Error ? error.message : String(error);
|
|
13114
13237
|
throw new Error(`Failed to create shared workspace: ${message}`);
|
|
13115
13238
|
}
|
|
13116
13239
|
if (suiteWorkspaceFile && sharedWorkspacePath) {
|
|
13117
|
-
const copiedWorkspaceFile =
|
|
13240
|
+
const copiedWorkspaceFile = path38.join(sharedWorkspacePath, path38.basename(suiteWorkspaceFile));
|
|
13118
13241
|
try {
|
|
13119
13242
|
await stat7(copiedWorkspaceFile);
|
|
13120
13243
|
suiteWorkspaceFile = copiedWorkspaceFile;
|
|
@@ -13124,11 +13247,14 @@ async function runEvaluation(options) {
|
|
|
13124
13247
|
} else if (suiteWorkspace?.before_all || suiteWorkspace?.repos?.length && !isPerTestIsolation) {
|
|
13125
13248
|
sharedWorkspacePath = getWorkspacePath(evalRunId, "shared");
|
|
13126
13249
|
await mkdir12(sharedWorkspacePath, { recursive: true });
|
|
13250
|
+
setupLog(`created empty shared workspace at: ${sharedWorkspacePath}`);
|
|
13127
13251
|
}
|
|
13128
|
-
const repoManager = suiteWorkspace?.repos?.length ? new RepoManager() : void 0;
|
|
13252
|
+
const repoManager = suiteWorkspace?.repos?.length ? new RepoManager(void 0, verbose) : void 0;
|
|
13129
13253
|
if (repoManager && sharedWorkspacePath && suiteWorkspace?.repos && !isPerTestIsolation) {
|
|
13254
|
+
setupLog(`materializing ${suiteWorkspace.repos.length} shared repo(s) into ${sharedWorkspacePath}`);
|
|
13130
13255
|
try {
|
|
13131
13256
|
await repoManager.materializeAll(suiteWorkspace.repos, sharedWorkspacePath);
|
|
13257
|
+
setupLog("shared repo materialization complete");
|
|
13132
13258
|
} catch (error) {
|
|
13133
13259
|
const message = error instanceof Error ? error.message : String(error);
|
|
13134
13260
|
if (sharedWorkspacePath) {
|
|
@@ -13139,6 +13265,10 @@ async function runEvaluation(options) {
|
|
|
13139
13265
|
}
|
|
13140
13266
|
}
|
|
13141
13267
|
if (sharedWorkspacePath && suiteWorkspace?.before_all) {
|
|
13268
|
+
const beforeAllCommand = (suiteWorkspace.before_all.command ?? suiteWorkspace.before_all.script ?? []).join(" ");
|
|
13269
|
+
setupLog(
|
|
13270
|
+
`running shared before_all in cwd=${suiteWorkspace.before_all.cwd ?? evalDir} command=${beforeAllCommand}`
|
|
13271
|
+
);
|
|
13142
13272
|
const scriptContext = {
|
|
13143
13273
|
workspacePath: sharedWorkspacePath,
|
|
13144
13274
|
testId: "__before_all__",
|
|
@@ -13147,6 +13277,7 @@ async function runEvaluation(options) {
|
|
|
13147
13277
|
};
|
|
13148
13278
|
try {
|
|
13149
13279
|
beforeAllOutput = await executeWorkspaceScript(suiteWorkspace.before_all, scriptContext);
|
|
13280
|
+
setupLog("shared before_all completed");
|
|
13150
13281
|
} catch (error) {
|
|
13151
13282
|
const message = error instanceof Error ? error.message : String(error);
|
|
13152
13283
|
if (sharedWorkspacePath) {
|
|
@@ -13159,7 +13290,9 @@ async function runEvaluation(options) {
|
|
|
13159
13290
|
if (sharedWorkspacePath) {
|
|
13160
13291
|
try {
|
|
13161
13292
|
sharedBaselineCommit = await initializeBaseline(sharedWorkspacePath);
|
|
13293
|
+
setupLog(`shared baseline initialized: ${sharedBaselineCommit}`);
|
|
13162
13294
|
} catch {
|
|
13295
|
+
setupLog("shared baseline initialization skipped (non-fatal)");
|
|
13163
13296
|
}
|
|
13164
13297
|
}
|
|
13165
13298
|
let nextWorkerId = 1;
|
|
@@ -13563,6 +13696,7 @@ async function runEvalCase(options) {
|
|
|
13563
13696
|
repoManager,
|
|
13564
13697
|
evalDir
|
|
13565
13698
|
} = options;
|
|
13699
|
+
const setupDebug = process.env.AGENTV_SETUP_DEBUG === "1";
|
|
13566
13700
|
const formattingMode = usesFileReferencePrompt(provider) ? "agent" : "lm";
|
|
13567
13701
|
const promptInputs = await buildPromptInputs(evalCase, formattingMode);
|
|
13568
13702
|
const typeRegistry = providedTypeRegistry ?? createBuiltinRegistry();
|
|
@@ -13600,7 +13734,7 @@ async function runEvalCase(options) {
|
|
|
13600
13734
|
);
|
|
13601
13735
|
}
|
|
13602
13736
|
if (caseWorkspaceFile && workspacePath) {
|
|
13603
|
-
const copiedFile =
|
|
13737
|
+
const copiedFile = path38.join(workspacePath, path38.basename(caseWorkspaceFile));
|
|
13604
13738
|
try {
|
|
13605
13739
|
await stat7(copiedFile);
|
|
13606
13740
|
caseWorkspaceFile = copiedFile;
|
|
@@ -13613,9 +13747,17 @@ async function runEvalCase(options) {
|
|
|
13613
13747
|
await mkdir12(workspacePath, { recursive: true });
|
|
13614
13748
|
}
|
|
13615
13749
|
if (evalCase.workspace?.repos?.length && workspacePath) {
|
|
13616
|
-
const perCaseRepoManager = new RepoManager();
|
|
13750
|
+
const perCaseRepoManager = new RepoManager(void 0, setupDebug);
|
|
13617
13751
|
try {
|
|
13752
|
+
if (setupDebug) {
|
|
13753
|
+
console.log(
|
|
13754
|
+
`[setup] test=${evalCase.id} materializing ${evalCase.workspace.repos.length} per-test repo(s) into ${workspacePath}`
|
|
13755
|
+
);
|
|
13756
|
+
}
|
|
13618
13757
|
await perCaseRepoManager.materializeAll(evalCase.workspace.repos, workspacePath);
|
|
13758
|
+
if (setupDebug) {
|
|
13759
|
+
console.log(`[setup] test=${evalCase.id} per-test repo materialization complete`);
|
|
13760
|
+
}
|
|
13619
13761
|
} catch (error) {
|
|
13620
13762
|
const message = error instanceof Error ? error.message : String(error);
|
|
13621
13763
|
return buildErrorResult(
|
|
@@ -13631,6 +13773,12 @@ async function runEvalCase(options) {
|
|
|
13631
13773
|
}
|
|
13632
13774
|
}
|
|
13633
13775
|
if (workspacePath && evalCase.workspace?.before_all) {
|
|
13776
|
+
const beforeAllCommand = (evalCase.workspace.before_all.command ?? evalCase.workspace.before_all.script ?? []).join(" ");
|
|
13777
|
+
if (setupDebug) {
|
|
13778
|
+
console.log(
|
|
13779
|
+
`[setup] test=${evalCase.id} running before_all in cwd=${evalCase.workspace.before_all.cwd ?? evalDir} command=${beforeAllCommand}`
|
|
13780
|
+
);
|
|
13781
|
+
}
|
|
13634
13782
|
const scriptContext = {
|
|
13635
13783
|
workspacePath,
|
|
13636
13784
|
testId: evalCase.id,
|
|
@@ -13644,6 +13792,9 @@ async function runEvalCase(options) {
|
|
|
13644
13792
|
evalCase.workspace.before_all,
|
|
13645
13793
|
scriptContext
|
|
13646
13794
|
);
|
|
13795
|
+
if (setupDebug) {
|
|
13796
|
+
console.log(`[setup] test=${evalCase.id} before_all completed`);
|
|
13797
|
+
}
|
|
13647
13798
|
} catch (error) {
|
|
13648
13799
|
const message = error instanceof Error ? error.message : String(error);
|
|
13649
13800
|
if (forceCleanup && workspacePath) {
|
|
@@ -14193,7 +14344,7 @@ async function runEvaluatorList(options) {
|
|
|
14193
14344
|
fileChanges,
|
|
14194
14345
|
workspacePath
|
|
14195
14346
|
};
|
|
14196
|
-
const evalFileDir = evalCase.guideline_paths[0] ?
|
|
14347
|
+
const evalFileDir = evalCase.guideline_paths[0] ? path38.dirname(evalCase.guideline_paths[0]) : process.cwd();
|
|
14197
14348
|
const dispatchContext = {
|
|
14198
14349
|
judgeProvider,
|
|
14199
14350
|
targetResolver,
|
|
@@ -14496,7 +14647,7 @@ function computeWeightedMean(entries) {
|
|
|
14496
14647
|
|
|
14497
14648
|
// src/evaluation/evaluate.ts
|
|
14498
14649
|
import { existsSync as existsSync3 } from "node:fs";
|
|
14499
|
-
import
|
|
14650
|
+
import path39 from "node:path";
|
|
14500
14651
|
async function evaluate(config) {
|
|
14501
14652
|
const startTime = Date.now();
|
|
14502
14653
|
if (config.tests && config.specFile) {
|
|
@@ -14518,13 +14669,13 @@ async function evaluate(config) {
|
|
|
14518
14669
|
let evalCases;
|
|
14519
14670
|
let testFilePath;
|
|
14520
14671
|
if (config.specFile) {
|
|
14521
|
-
testFilePath =
|
|
14672
|
+
testFilePath = path39.resolve(config.specFile);
|
|
14522
14673
|
evalCases = await loadTests(testFilePath, repoRoot, {
|
|
14523
14674
|
verbose: config.verbose,
|
|
14524
14675
|
filter: config.filter
|
|
14525
14676
|
});
|
|
14526
14677
|
} else {
|
|
14527
|
-
testFilePath =
|
|
14678
|
+
testFilePath = path39.join(process.cwd(), "__programmatic__.yaml");
|
|
14528
14679
|
evalCases = (config.tests ?? []).map((test) => {
|
|
14529
14680
|
const input = typeof test.input === "string" ? [{ role: "user", content: test.input }] : test.input;
|
|
14530
14681
|
const question = typeof test.input === "string" ? test.input : test.input.find((m) => m.role === "user")?.content ?? "";
|
|
@@ -14610,10 +14761,10 @@ function computeSummary(results, durationMs) {
|
|
|
14610
14761
|
var TARGET_FILE_CANDIDATES = [".agentv/targets.yaml", ".agentv/targets.yml"];
|
|
14611
14762
|
async function discoverDefaultTarget(repoRoot) {
|
|
14612
14763
|
const cwd = process.cwd();
|
|
14613
|
-
const chain = buildDirectoryChain(
|
|
14764
|
+
const chain = buildDirectoryChain(path39.join(cwd, "_placeholder"), repoRoot);
|
|
14614
14765
|
for (const dir of chain) {
|
|
14615
14766
|
for (const candidate of TARGET_FILE_CANDIDATES) {
|
|
14616
|
-
const targetsPath =
|
|
14767
|
+
const targetsPath = path39.join(dir, candidate);
|
|
14617
14768
|
if (!existsSync3(targetsPath)) continue;
|
|
14618
14769
|
try {
|
|
14619
14770
|
const definitions = await readTargetDefinitions(targetsPath);
|
|
@@ -14628,10 +14779,10 @@ async function discoverDefaultTarget(repoRoot) {
|
|
|
14628
14779
|
async function loadEnvHierarchy(repoRoot) {
|
|
14629
14780
|
const { readFileSync: readFileSync2 } = await import("node:fs");
|
|
14630
14781
|
const cwd = process.cwd();
|
|
14631
|
-
const chain = buildDirectoryChain(
|
|
14782
|
+
const chain = buildDirectoryChain(path39.join(cwd, "_placeholder"), repoRoot);
|
|
14632
14783
|
const envFiles = [];
|
|
14633
14784
|
for (const dir of chain) {
|
|
14634
|
-
const envPath =
|
|
14785
|
+
const envPath = path39.join(dir, ".env");
|
|
14635
14786
|
if (existsSync3(envPath)) envFiles.push(envPath);
|
|
14636
14787
|
}
|
|
14637
14788
|
for (let i = envFiles.length - 1; i >= 0; i--) {
|
|
@@ -14813,7 +14964,7 @@ function buildPrompt(criteria, question, referenceAnswer) {
|
|
|
14813
14964
|
|
|
14814
14965
|
// src/evaluation/cache/response-cache.ts
|
|
14815
14966
|
import { mkdir as mkdir13, readFile as readFile11, writeFile as writeFile8 } from "node:fs/promises";
|
|
14816
|
-
import
|
|
14967
|
+
import path40 from "node:path";
|
|
14817
14968
|
var DEFAULT_CACHE_PATH = ".agentv/cache";
|
|
14818
14969
|
var ResponseCache = class {
|
|
14819
14970
|
cachePath;
|
|
@@ -14831,13 +14982,13 @@ var ResponseCache = class {
|
|
|
14831
14982
|
}
|
|
14832
14983
|
async set(key, value) {
|
|
14833
14984
|
const filePath = this.keyToPath(key);
|
|
14834
|
-
const dir =
|
|
14985
|
+
const dir = path40.dirname(filePath);
|
|
14835
14986
|
await mkdir13(dir, { recursive: true });
|
|
14836
14987
|
await writeFile8(filePath, JSON.stringify(value, null, 2), "utf8");
|
|
14837
14988
|
}
|
|
14838
14989
|
keyToPath(key) {
|
|
14839
14990
|
const prefix = key.slice(0, 2);
|
|
14840
|
-
return
|
|
14991
|
+
return path40.join(this.cachePath, prefix, `${key}.json`);
|
|
14841
14992
|
}
|
|
14842
14993
|
};
|
|
14843
14994
|
function shouldEnableCache(params) {
|
|
@@ -15364,8 +15515,13 @@ export {
|
|
|
15364
15515
|
findGitRoot,
|
|
15365
15516
|
freeformEvaluationSchema,
|
|
15366
15517
|
generateRubrics,
|
|
15518
|
+
getAgentvHome,
|
|
15519
|
+
getGitCacheRoot,
|
|
15367
15520
|
getHitCount,
|
|
15521
|
+
getSubagentsRoot,
|
|
15522
|
+
getTraceStateRoot,
|
|
15368
15523
|
getWorkspacePath,
|
|
15524
|
+
getWorkspacesRoot,
|
|
15369
15525
|
initializeBaseline,
|
|
15370
15526
|
isEvaluatorKind,
|
|
15371
15527
|
isGuidelineFile,
|