agentv 3.10.3 → 3.11.1
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/{agentv-provider-NFFLXG5M-TJAWCWCX.js → agentv-provider-MIDKLYIH-6LIYKQRP.js} +2 -1
- package/dist/chunk-2QFWRIYL.js +186 -0
- package/dist/chunk-2QFWRIYL.js.map +1 -0
- package/dist/chunk-2RMPO6LY.js +747 -0
- package/dist/chunk-2RMPO6LY.js.map +1 -0
- package/dist/chunk-3Q7WIXT4.js +4846 -0
- package/dist/chunk-3Q7WIXT4.js.map +1 -0
- package/dist/chunk-73O2DCJP.js +1274 -0
- package/dist/chunk-73O2DCJP.js.map +1 -0
- package/dist/chunk-AUKF3Y3W.js +212 -0
- package/dist/chunk-AUKF3Y3W.js.map +1 -0
- package/dist/{chunk-XOSNETAV.js → chunk-BAUNAXHT.js} +1 -1
- package/dist/chunk-BRH7SIDP.js +133 -0
- package/dist/chunk-BRH7SIDP.js.map +1 -0
- package/dist/chunk-BXM4I3BM.js +526 -0
- package/dist/chunk-BXM4I3BM.js.map +1 -0
- package/dist/{chunk-U556GRI3.js → chunk-CKMAM2GD.js} +76 -34
- package/dist/chunk-CKMAM2GD.js.map +1 -0
- package/dist/chunk-FHTURHTY.js +546 -0
- package/dist/chunk-FHTURHTY.js.map +1 -0
- package/dist/chunk-GJFXQQWG.js +21 -0
- package/dist/chunk-GJFXQQWG.js.map +1 -0
- package/dist/chunk-HKMLG4KF.js +38 -0
- package/dist/chunk-HKMLG4KF.js.map +1 -0
- package/dist/chunk-JGU3PVA4.js +133 -0
- package/dist/chunk-JGU3PVA4.js.map +1 -0
- package/dist/chunk-LHU5FGVZ.js +4804 -0
- package/dist/chunk-LHU5FGVZ.js.map +1 -0
- package/dist/chunk-OL2WGI6E.js +149 -0
- package/dist/chunk-OL2WGI6E.js.map +1 -0
- package/dist/chunk-ONETZL6N.js +15 -0
- package/dist/chunk-ONETZL6N.js.map +1 -0
- package/dist/{chunk-JUQCB3ZW.js → chunk-OYD2NB55.js} +1292 -896
- package/dist/chunk-OYD2NB55.js.map +1 -0
- package/dist/chunk-QV4UGEN6.js +320 -0
- package/dist/chunk-QV4UGEN6.js.map +1 -0
- package/dist/chunk-QXLDKGF3.js +46 -0
- package/dist/chunk-QXLDKGF3.js.map +1 -0
- package/dist/chunk-U6VEM66A.js +63 -0
- package/dist/chunk-U6VEM66A.js.map +1 -0
- package/dist/chunk-UALXHIMX.js +48 -0
- package/dist/chunk-UALXHIMX.js.map +1 -0
- package/dist/chunk-UGXG73VF.js +55 -0
- package/dist/chunk-UGXG73VF.js.map +1 -0
- package/dist/chunk-UHP5KEDL.js +38 -0
- package/dist/chunk-UHP5KEDL.js.map +1 -0
- package/dist/{chunk-7LC3VNOC.js → chunk-V2S5CZU3.js} +1141 -60
- package/dist/chunk-V2S5CZU3.js.map +1 -0
- package/dist/chunk-WVSXFZWP.js +204 -0
- package/dist/chunk-WVSXFZWP.js.map +1 -0
- package/dist/chunk-XSUMCWKO.js +30 -0
- package/dist/chunk-XSUMCWKO.js.map +1 -0
- package/dist/chunk-XUO7ZEHU.js +181 -0
- package/dist/chunk-XUO7ZEHU.js.map +1 -0
- package/dist/chunk-YSGUX5JT.js +1002 -0
- package/dist/chunk-YSGUX5JT.js.map +1 -0
- package/dist/cli.js +5 -4
- package/dist/cli.js.map +1 -1
- package/dist/dist-3PCP5TNF-RYMVLILE.js +25785 -0
- package/dist/dist-3PCP5TNF-RYMVLILE.js.map +1 -0
- package/dist/dist-BOIN5LC5-T5UWUK43.js +76113 -0
- package/dist/dist-BOIN5LC5-T5UWUK43.js.map +1 -0
- package/dist/dist-LXPDQOBI-4V5J2WDS.js +13 -0
- package/dist/dist-LXPDQOBI-4V5J2WDS.js.map +1 -0
- package/dist/{dist-2X7A3TTC.js → dist-VUPMLHIV.js} +4 -3
- package/dist/dist-es-4WSJUIYR-XKIX65IH.js +69 -0
- package/dist/dist-es-4WSJUIYR-XKIX65IH.js.map +1 -0
- package/dist/dist-es-7K7MKRME-CCMAZOQC.js +355 -0
- package/dist/dist-es-7K7MKRME-CCMAZOQC.js.map +1 -0
- package/dist/dist-es-B2RTOKRI-VWZHK5RE.js +191 -0
- package/dist/dist-es-B2RTOKRI-VWZHK5RE.js.map +1 -0
- package/dist/dist-es-HHZ4FAXA-CRERHWKB.js +164 -0
- package/dist/dist-es-HHZ4FAXA-CRERHWKB.js.map +1 -0
- package/dist/dist-es-HVS3RPMX-AYJ3DW4L.js +355 -0
- package/dist/dist-es-HVS3RPMX-AYJ3DW4L.js.map +1 -0
- package/dist/dist-es-L6R4FPI5-IKIRYN45.js +472 -0
- package/dist/dist-es-L6R4FPI5-IKIRYN45.js.map +1 -0
- package/dist/dist-es-SRVEB5QV-Q4CTC2HX.js +24 -0
- package/dist/dist-es-TRIVUKV4-2J47CDXR.js +85 -0
- package/dist/dist-es-TRIVUKV4-2J47CDXR.js.map +1 -0
- package/dist/dist-es-UEEUAV34-IZQDTAMW.js +16 -0
- package/dist/{esm-5Q4BZALM-5REQWAUV.js → esm-OJ2BXJK4-YKEI3Z7E.js} +3 -2
- package/dist/{esm-5Q4BZALM-5REQWAUV.js.map → esm-OJ2BXJK4-YKEI3Z7E.js.map} +1 -1
- package/dist/{esm-CZAWIY6F.js → esm-UYZ3HJBU.js} +2 -2
- package/dist/event-streams-NZADSH5J-6MOSNEV3.js +247 -0
- package/dist/event-streams-NZADSH5J-6MOSNEV3.js.map +1 -0
- package/dist/index.js +5 -4
- package/dist/{interactive-CSA4KIND.js → interactive-FZJANO4A.js} +5 -4
- package/dist/{interactive-CSA4KIND.js.map → interactive-FZJANO4A.js.map} +1 -1
- package/dist/loadSso-IQZ5NB6C-DZJTORO3.js +738 -0
- package/dist/loadSso-IQZ5NB6C-DZJTORO3.js.map +1 -0
- package/dist/multipart-parser-IPYBIGNL-LFMNMM6D.js +387 -0
- package/dist/multipart-parser-IPYBIGNL-LFMNMM6D.js.map +1 -0
- package/dist/{otlp-json-file-exporter-77FDBRSY-EZAPHWP6.js → otlp-json-file-exporter-VN67MK3S-RQIM6EHY.js} +2 -1
- package/dist/otlp-json-file-exporter-VN67MK3S-RQIM6EHY.js.map +1 -0
- package/dist/signin-2ANR4DVS-K5VGBEJF.js +556 -0
- package/dist/signin-2ANR4DVS-K5VGBEJF.js.map +1 -0
- package/dist/{simple-trace-file-exporter-S76DMABU-5FCJESD2.js → simple-trace-file-exporter-XWZTIZR2-4JKATE5G.js} +2 -1
- package/dist/simple-trace-file-exporter-XWZTIZR2-4JKATE5G.js.map +1 -0
- package/dist/{src-ML4D2MC2.js → src-PXDA7QIS.js} +2 -2
- package/dist/src-SLOMUG7K-CV5JG263.js +1408 -0
- package/dist/src-SLOMUG7K-CV5JG263.js.map +1 -0
- package/dist/sso-oidc-HVCDATR2-CYP3BM5O.js +708 -0
- package/dist/sso-oidc-HVCDATR2-CYP3BM5O.js.map +1 -0
- package/dist/sts-X7JGSP4H-PDAAYDDH.js +2917 -0
- package/dist/sts-X7JGSP4H-PDAAYDDH.js.map +1 -0
- package/dist/templates/.agentv/config.yaml +4 -13
- package/dist/templates/.agentv/targets.yaml +0 -16
- package/dist/undici-VAR2VUJI-6PAOUXZC.js +23388 -0
- package/dist/undici-VAR2VUJI-6PAOUXZC.js.map +1 -0
- package/package.json +11 -3
- package/dist/chunk-7LC3VNOC.js.map +0 -1
- package/dist/chunk-JUQCB3ZW.js.map +0 -1
- package/dist/chunk-U556GRI3.js.map +0 -1
- package/dist/templates/.agentv/.env.example +0 -23
- /package/dist/{agentv-provider-NFFLXG5M-TJAWCWCX.js.map → agentv-provider-MIDKLYIH-6LIYKQRP.js.map} +0 -0
- /package/dist/{chunk-XOSNETAV.js.map → chunk-BAUNAXHT.js.map} +0 -0
- /package/dist/{dist-2X7A3TTC.js.map → dist-VUPMLHIV.js.map} +0 -0
- /package/dist/{esm-CZAWIY6F.js.map → dist-es-SRVEB5QV-Q4CTC2HX.js.map} +0 -0
- /package/dist/{otlp-json-file-exporter-77FDBRSY-EZAPHWP6.js.map → dist-es-UEEUAV34-IZQDTAMW.js.map} +0 -0
- /package/dist/{simple-trace-file-exporter-S76DMABU-5FCJESD2.js.map → esm-UYZ3HJBU.js.map} +0 -0
- /package/dist/{src-ML4D2MC2.js.map → src-PXDA7QIS.js.map} +0 -0
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
require_token_error
|
|
4
|
-
} from "./chunk-HQDCIXVH.js";
|
|
5
2
|
import {
|
|
6
3
|
AISDKError,
|
|
7
4
|
APICallError,
|
|
@@ -150,6 +147,9 @@ import {
|
|
|
150
147
|
withoutTrailingSlash,
|
|
151
148
|
zodSchema
|
|
152
149
|
} from "./chunk-BJV6MDBE.js";
|
|
150
|
+
import {
|
|
151
|
+
require_token_error
|
|
152
|
+
} from "./chunk-HQDCIXVH.js";
|
|
153
153
|
import {
|
|
154
154
|
SpanStatusCode,
|
|
155
155
|
context,
|
|
@@ -301,7 +301,7 @@ var require_dist = __commonJS({
|
|
|
301
301
|
}
|
|
302
302
|
});
|
|
303
303
|
|
|
304
|
-
// ../../packages/core/dist/chunk-
|
|
304
|
+
// ../../packages/core/dist/chunk-4XWPXNQM.js
|
|
305
305
|
import { constants } from "node:fs";
|
|
306
306
|
import { access, readFile } from "node:fs/promises";
|
|
307
307
|
import path from "node:path";
|
|
@@ -419,7 +419,7 @@ __export(external_exports2, {
|
|
|
419
419
|
void: () => voidType
|
|
420
420
|
});
|
|
421
421
|
|
|
422
|
-
// ../../packages/core/dist/chunk-
|
|
422
|
+
// ../../packages/core/dist/chunk-4XWPXNQM.js
|
|
423
423
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
424
424
|
import path3 from "node:path";
|
|
425
425
|
import fg from "fast-glob";
|
|
@@ -938,14 +938,14 @@ function resolveTargetDefinition(definition, env = process.env, evalFilePath) {
|
|
|
938
938
|
providerBatching,
|
|
939
939
|
config: resolvePiCodingAgentConfig(parsed, env, evalFilePath)
|
|
940
940
|
};
|
|
941
|
-
case "pi-
|
|
941
|
+
case "pi-cli":
|
|
942
942
|
return {
|
|
943
|
-
kind: "pi-
|
|
943
|
+
kind: "pi-cli",
|
|
944
944
|
name: parsed.name,
|
|
945
945
|
graderTarget: parsed.grader_target ?? parsed.judge_target,
|
|
946
946
|
workers: parsed.workers,
|
|
947
947
|
providerBatching,
|
|
948
|
-
config:
|
|
948
|
+
config: resolvePiCliConfig(parsed, env, evalFilePath)
|
|
949
949
|
};
|
|
950
950
|
case "claude":
|
|
951
951
|
case "claude-code":
|
|
@@ -1362,27 +1362,26 @@ function normalizeCopilotLogFormat(value) {
|
|
|
1362
1362
|
throw new Error("copilot log format must be 'summary' or 'json'");
|
|
1363
1363
|
}
|
|
1364
1364
|
function resolvePiCodingAgentConfig(target, env, evalFilePath) {
|
|
1365
|
-
const
|
|
1366
|
-
const providerSource = target.pi_provider ?? target.piProvider ?? target.llm_provider;
|
|
1365
|
+
const subproviderSource = target.subprovider;
|
|
1367
1366
|
const modelSource = target.model ?? target.pi_model ?? target.piModel;
|
|
1368
1367
|
const apiKeySource = target.api_key ?? target.apiKey;
|
|
1369
1368
|
const toolsSource = target.tools ?? target.pi_tools ?? target.piTools;
|
|
1370
1369
|
const thinkingSource = target.thinking ?? target.pi_thinking ?? target.piThinking;
|
|
1371
|
-
const argsSource = target.args ?? target.arguments;
|
|
1372
1370
|
const cwdSource = target.cwd;
|
|
1373
1371
|
const workspaceTemplateSource = target.workspace_template ?? target.workspaceTemplate;
|
|
1374
1372
|
const timeoutSource = target.timeout_seconds ?? target.timeoutSeconds;
|
|
1375
1373
|
const logDirSource = target.log_dir ?? target.logDir ?? target.log_directory ?? target.logDirectory;
|
|
1376
1374
|
const logFormatSource = target.log_format ?? target.logFormat;
|
|
1377
1375
|
const systemPromptSource = target.system_prompt ?? target.systemPrompt;
|
|
1378
|
-
const
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1376
|
+
const subprovider = resolveOptionalString(
|
|
1377
|
+
subproviderSource,
|
|
1378
|
+
env,
|
|
1379
|
+
`${target.name} pi subprovider`,
|
|
1380
|
+
{
|
|
1381
|
+
allowLiteral: true,
|
|
1382
|
+
optionalEnv: true
|
|
1383
|
+
}
|
|
1384
|
+
);
|
|
1386
1385
|
const model = resolveOptionalString(modelSource, env, `${target.name} pi model`, {
|
|
1387
1386
|
allowLiteral: true,
|
|
1388
1387
|
optionalEnv: true
|
|
@@ -1399,7 +1398,6 @@ function resolvePiCodingAgentConfig(target, env, evalFilePath) {
|
|
|
1399
1398
|
allowLiteral: true,
|
|
1400
1399
|
optionalEnv: true
|
|
1401
1400
|
});
|
|
1402
|
-
const args = resolveOptionalStringArray(argsSource, env, `${target.name} pi args`);
|
|
1403
1401
|
const cwd = resolveOptionalString(cwdSource, env, `${target.name} pi cwd`, {
|
|
1404
1402
|
allowLiteral: true,
|
|
1405
1403
|
optionalEnv: true
|
|
@@ -1429,13 +1427,11 @@ function resolvePiCodingAgentConfig(target, env, evalFilePath) {
|
|
|
1429
1427
|
const logFormat = logFormatSource === "json" || logFormatSource === "summary" ? logFormatSource : void 0;
|
|
1430
1428
|
const systemPrompt = typeof systemPromptSource === "string" && systemPromptSource.trim().length > 0 ? systemPromptSource.trim() : void 0;
|
|
1431
1429
|
return {
|
|
1432
|
-
|
|
1433
|
-
provider,
|
|
1430
|
+
subprovider,
|
|
1434
1431
|
model,
|
|
1435
1432
|
apiKey,
|
|
1436
1433
|
tools,
|
|
1437
1434
|
thinking,
|
|
1438
|
-
args,
|
|
1439
1435
|
cwd,
|
|
1440
1436
|
workspaceTemplate,
|
|
1441
1437
|
timeoutMs,
|
|
@@ -1444,36 +1440,83 @@ function resolvePiCodingAgentConfig(target, env, evalFilePath) {
|
|
|
1444
1440
|
systemPrompt
|
|
1445
1441
|
};
|
|
1446
1442
|
}
|
|
1447
|
-
function
|
|
1448
|
-
const
|
|
1443
|
+
function resolvePiCliConfig(target, env, evalFilePath) {
|
|
1444
|
+
const executableSource = target.executable ?? target.command ?? target.binary;
|
|
1445
|
+
const subproviderSource = target.subprovider;
|
|
1449
1446
|
const modelSource = target.model ?? target.pi_model ?? target.piModel;
|
|
1450
1447
|
const apiKeySource = target.api_key ?? target.apiKey;
|
|
1448
|
+
const toolsSource = target.tools ?? target.pi_tools ?? target.piTools;
|
|
1449
|
+
const thinkingSource = target.thinking ?? target.pi_thinking ?? target.piThinking;
|
|
1450
|
+
const cwdSource = target.cwd;
|
|
1451
|
+
const workspaceTemplateSource = target.workspace_template ?? target.workspaceTemplate;
|
|
1451
1452
|
const timeoutSource = target.timeout_seconds ?? target.timeoutSeconds;
|
|
1453
|
+
const logDirSource = target.log_dir ?? target.logDir ?? target.log_directory ?? target.logDirectory;
|
|
1454
|
+
const logFormatSource = target.log_format ?? target.logFormat;
|
|
1452
1455
|
const systemPromptSource = target.system_prompt ?? target.systemPrompt;
|
|
1453
|
-
const
|
|
1454
|
-
|
|
1456
|
+
const executable = resolveOptionalString(executableSource, env, `${target.name} pi-cli executable`, {
|
|
1457
|
+
allowLiteral: true,
|
|
1458
|
+
optionalEnv: true
|
|
1459
|
+
}) ?? "pi";
|
|
1460
|
+
const subprovider = resolveOptionalString(
|
|
1461
|
+
subproviderSource,
|
|
1455
1462
|
env,
|
|
1456
|
-
`${target.name} pi-
|
|
1457
|
-
{
|
|
1458
|
-
allowLiteral: true,
|
|
1459
|
-
optionalEnv: true
|
|
1460
|
-
}
|
|
1463
|
+
`${target.name} pi-cli subprovider`,
|
|
1464
|
+
{ allowLiteral: true, optionalEnv: true }
|
|
1461
1465
|
);
|
|
1462
|
-
const model = resolveOptionalString(modelSource, env, `${target.name} pi-
|
|
1466
|
+
const model = resolveOptionalString(modelSource, env, `${target.name} pi-cli model`, {
|
|
1463
1467
|
allowLiteral: true,
|
|
1464
1468
|
optionalEnv: true
|
|
1465
1469
|
});
|
|
1466
|
-
const apiKey = resolveOptionalString(apiKeySource, env, `${target.name} pi-
|
|
1470
|
+
const apiKey = resolveOptionalString(apiKeySource, env, `${target.name} pi-cli api key`, {
|
|
1467
1471
|
allowLiteral: false,
|
|
1468
1472
|
optionalEnv: true
|
|
1469
1473
|
});
|
|
1470
|
-
const
|
|
1474
|
+
const tools = resolveOptionalString(toolsSource, env, `${target.name} pi-cli tools`, {
|
|
1475
|
+
allowLiteral: true,
|
|
1476
|
+
optionalEnv: true
|
|
1477
|
+
});
|
|
1478
|
+
const thinking = resolveOptionalString(thinkingSource, env, `${target.name} pi-cli thinking`, {
|
|
1479
|
+
allowLiteral: true,
|
|
1480
|
+
optionalEnv: true
|
|
1481
|
+
});
|
|
1482
|
+
const rawArgs = target.args ?? target.arguments;
|
|
1483
|
+
const args = resolveOptionalStringArray(rawArgs, env, `${target.name} pi-cli args`);
|
|
1484
|
+
const cwd = resolveOptionalString(cwdSource, env, `${target.name} pi-cli cwd`, {
|
|
1485
|
+
allowLiteral: true,
|
|
1486
|
+
optionalEnv: true
|
|
1487
|
+
});
|
|
1488
|
+
let workspaceTemplate = resolveOptionalString(
|
|
1489
|
+
workspaceTemplateSource,
|
|
1490
|
+
env,
|
|
1491
|
+
`${target.name} pi-cli workspace template`,
|
|
1492
|
+
{ allowLiteral: true, optionalEnv: true }
|
|
1493
|
+
);
|
|
1494
|
+
if (workspaceTemplate && evalFilePath && !path2.isAbsolute(workspaceTemplate)) {
|
|
1495
|
+
workspaceTemplate = path2.resolve(path2.dirname(path2.resolve(evalFilePath)), workspaceTemplate);
|
|
1496
|
+
}
|
|
1497
|
+
if (cwd && workspaceTemplate) {
|
|
1498
|
+
throw new Error(`${target.name}: 'cwd' and 'workspace_template' are mutually exclusive.`);
|
|
1499
|
+
}
|
|
1500
|
+
const timeoutMs = resolveTimeoutMs(timeoutSource, `${target.name} pi-cli timeout`);
|
|
1501
|
+
const logDir = resolveOptionalString(logDirSource, env, `${target.name} pi-cli log directory`, {
|
|
1502
|
+
allowLiteral: true,
|
|
1503
|
+
optionalEnv: true
|
|
1504
|
+
});
|
|
1505
|
+
const logFormat = logFormatSource === "json" || logFormatSource === "summary" ? logFormatSource : void 0;
|
|
1471
1506
|
const systemPrompt = typeof systemPromptSource === "string" && systemPromptSource.trim().length > 0 ? systemPromptSource.trim() : void 0;
|
|
1472
1507
|
return {
|
|
1473
|
-
|
|
1508
|
+
executable,
|
|
1509
|
+
subprovider,
|
|
1474
1510
|
model,
|
|
1475
1511
|
apiKey,
|
|
1512
|
+
tools,
|
|
1513
|
+
thinking,
|
|
1514
|
+
args,
|
|
1515
|
+
cwd,
|
|
1516
|
+
workspaceTemplate,
|
|
1476
1517
|
timeoutMs,
|
|
1518
|
+
logDir,
|
|
1519
|
+
logFormat,
|
|
1477
1520
|
systemPrompt
|
|
1478
1521
|
};
|
|
1479
1522
|
}
|
|
@@ -1603,8 +1646,8 @@ function resolveCliConfig(target, env, evalFilePath) {
|
|
|
1603
1646
|
const parseResult = CliTargetInputSchema.safeParse(target, { errorMap: cliErrorMap });
|
|
1604
1647
|
if (!parseResult.success) {
|
|
1605
1648
|
const firstError = parseResult.error.errors[0];
|
|
1606
|
-
const
|
|
1607
|
-
const prefix =
|
|
1649
|
+
const path45 = firstError?.path.join(".") || "";
|
|
1650
|
+
const prefix = path45 ? `${target.name} ${path45}: ` : `${target.name}: `;
|
|
1608
1651
|
throw new Error(`${prefix}${firstError?.message}`);
|
|
1609
1652
|
}
|
|
1610
1653
|
const normalized = normalizeCliTargetInput(parseResult.data, env, evalFilePath);
|
|
@@ -1944,7 +1987,7 @@ var AGENT_PROVIDER_KINDS = [
|
|
|
1944
1987
|
"copilot-sdk",
|
|
1945
1988
|
"copilot-cli",
|
|
1946
1989
|
"pi-coding-agent",
|
|
1947
|
-
"pi-
|
|
1990
|
+
"pi-cli",
|
|
1948
1991
|
"claude",
|
|
1949
1992
|
"claude-cli",
|
|
1950
1993
|
"claude-sdk",
|
|
@@ -1961,7 +2004,7 @@ var KNOWN_PROVIDERS = [
|
|
|
1961
2004
|
"copilot-sdk",
|
|
1962
2005
|
"copilot-cli",
|
|
1963
2006
|
"pi-coding-agent",
|
|
1964
|
-
"pi-
|
|
2007
|
+
"pi-cli",
|
|
1965
2008
|
"claude",
|
|
1966
2009
|
"claude-cli",
|
|
1967
2010
|
"claude-sdk",
|
|
@@ -2039,7 +2082,7 @@ import path8 from "node:path";
|
|
|
2039
2082
|
import { parse as parse3 } from "yaml";
|
|
2040
2083
|
import { createOpenAI } from "@ai-sdk/openai";
|
|
2041
2084
|
|
|
2042
|
-
// ../../node_modules/.bun/@openrouter+ai-sdk-provider@2.3.
|
|
2085
|
+
// ../../node_modules/.bun/@openrouter+ai-sdk-provider@2.3.3+3ab978b6804fd9e7/node_modules/@openrouter/ai-sdk-provider/dist/index.mjs
|
|
2043
2086
|
var __defProp = Object.defineProperty;
|
|
2044
2087
|
var __defProps = Object.defineProperties;
|
|
2045
2088
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
@@ -4202,11 +4245,13 @@ function isDefinedOrNotNull(value) {
|
|
|
4202
4245
|
var ReasoningFormat = /* @__PURE__ */ ((ReasoningFormat2) => {
|
|
4203
4246
|
ReasoningFormat2["Unknown"] = "unknown";
|
|
4204
4247
|
ReasoningFormat2["OpenAIResponsesV1"] = "openai-responses-v1";
|
|
4248
|
+
ReasoningFormat2["AzureOpenAIResponsesV1"] = "azure-openai-responses-v1";
|
|
4205
4249
|
ReasoningFormat2["XAIResponsesV1"] = "xai-responses-v1";
|
|
4206
4250
|
ReasoningFormat2["AnthropicClaudeV1"] = "anthropic-claude-v1";
|
|
4207
4251
|
ReasoningFormat2["GoogleGeminiV1"] = "google-gemini-v1";
|
|
4208
4252
|
return ReasoningFormat2;
|
|
4209
4253
|
})(ReasoningFormat || {});
|
|
4254
|
+
var DEFAULT_REASONING_FORMAT = "anthropic-claude-v1";
|
|
4210
4255
|
var CommonReasoningDetailSchema = external_exports.object({
|
|
4211
4256
|
id: external_exports.string().nullish(),
|
|
4212
4257
|
format: external_exports.enum(ReasoningFormat).nullish(),
|
|
@@ -4360,7 +4405,11 @@ var OpenRouterProviderMetadataSchema = external_exports.object({
|
|
|
4360
4405
|
}).catchall(external_exports.any());
|
|
4361
4406
|
var OpenRouterProviderOptionsSchema = external_exports.object({
|
|
4362
4407
|
openrouter: external_exports.object({
|
|
4363
|
-
|
|
4408
|
+
// Use ReasoningDetailArraySchema (with unknown fallback) instead of
|
|
4409
|
+
// z.array(ReasoningDetailUnionSchema) so that a single malformed entry
|
|
4410
|
+
// (e.g., a future format not yet in the enum) is individually dropped
|
|
4411
|
+
// rather than causing the entire array to fail parsing.
|
|
4412
|
+
reasoning_details: ReasoningDetailArraySchema.optional(),
|
|
4364
4413
|
annotations: external_exports.array(FileAnnotationSchema).optional()
|
|
4365
4414
|
}).optional()
|
|
4366
4415
|
}).optional();
|
|
@@ -4758,8 +4807,24 @@ function convertToOpenRouterChatMessages(prompt) {
|
|
|
4758
4807
|
const candidateReasoningDetails = messageReasoningDetails && Array.isArray(messageReasoningDetails) && messageReasoningDetails.length > 0 ? messageReasoningDetails : findFirstReasoningDetails(content);
|
|
4759
4808
|
let finalReasoningDetails;
|
|
4760
4809
|
if (candidateReasoningDetails && candidateReasoningDetails.length > 0) {
|
|
4810
|
+
const validDetails = candidateReasoningDetails.filter((detail) => {
|
|
4811
|
+
var _a173;
|
|
4812
|
+
if (detail.type !== "reasoning.text") {
|
|
4813
|
+
return true;
|
|
4814
|
+
}
|
|
4815
|
+
const format = (_a173 = detail.format) != null ? _a173 : DEFAULT_REASONING_FORMAT;
|
|
4816
|
+
if (format !== "anthropic-claude-v1") {
|
|
4817
|
+
return true;
|
|
4818
|
+
}
|
|
4819
|
+
return !!detail.signature;
|
|
4820
|
+
});
|
|
4821
|
+
if (validDetails.length < candidateReasoningDetails.length) {
|
|
4822
|
+
console.warn(
|
|
4823
|
+
"[openrouter] Some reasoning_details entries were removed because they were missing signatures. See https://github.com/OpenRouterTeam/ai-sdk-provider/issues/423 for more details."
|
|
4824
|
+
);
|
|
4825
|
+
}
|
|
4761
4826
|
const uniqueDetails = [];
|
|
4762
|
-
for (const detail of
|
|
4827
|
+
for (const detail of validDetails) {
|
|
4763
4828
|
if (reasoningDetailsTracker.upsert(detail)) {
|
|
4764
4829
|
uniqueDetails.push(detail);
|
|
4765
4830
|
}
|
|
@@ -4808,20 +4873,135 @@ function getToolResultContent(input) {
|
|
|
4808
4873
|
return input.output.value;
|
|
4809
4874
|
case "json":
|
|
4810
4875
|
case "error-json":
|
|
4811
|
-
case "content":
|
|
4812
4876
|
return JSON.stringify(input.output.value);
|
|
4877
|
+
case "content":
|
|
4878
|
+
return mapToolResultContentParts(input.output.value);
|
|
4813
4879
|
case "execution-denied":
|
|
4814
4880
|
return (_a163 = input.output.reason) != null ? _a163 : "Tool execution denied";
|
|
4815
4881
|
}
|
|
4816
4882
|
}
|
|
4883
|
+
function mapToolResultContentParts(parts) {
|
|
4884
|
+
return parts.map((part) => {
|
|
4885
|
+
var _a163, _b162, _c;
|
|
4886
|
+
switch (part.type) {
|
|
4887
|
+
case "text":
|
|
4888
|
+
return { type: "text", text: part.text };
|
|
4889
|
+
case "image-data":
|
|
4890
|
+
return {
|
|
4891
|
+
type: "image_url",
|
|
4892
|
+
image_url: {
|
|
4893
|
+
url: buildFileDataUrl({
|
|
4894
|
+
data: part.data,
|
|
4895
|
+
mediaType: part.mediaType,
|
|
4896
|
+
defaultMediaType: "image/jpeg"
|
|
4897
|
+
})
|
|
4898
|
+
}
|
|
4899
|
+
};
|
|
4900
|
+
case "image-url":
|
|
4901
|
+
return {
|
|
4902
|
+
type: "image_url",
|
|
4903
|
+
image_url: { url: part.url }
|
|
4904
|
+
};
|
|
4905
|
+
case "file-data": {
|
|
4906
|
+
const dataUrl = buildFileDataUrl({
|
|
4907
|
+
data: part.data,
|
|
4908
|
+
mediaType: part.mediaType,
|
|
4909
|
+
defaultMediaType: "application/octet-stream"
|
|
4910
|
+
});
|
|
4911
|
+
if ((_a163 = part.mediaType) == null ? void 0 : _a163.startsWith("image/")) {
|
|
4912
|
+
return {
|
|
4913
|
+
type: "image_url",
|
|
4914
|
+
image_url: { url: dataUrl }
|
|
4915
|
+
};
|
|
4916
|
+
}
|
|
4917
|
+
if ((_b162 = part.mediaType) == null ? void 0 : _b162.startsWith("audio/")) {
|
|
4918
|
+
const rawFormat = part.mediaType.replace("audio/", "");
|
|
4919
|
+
const format = MIME_TO_FORMAT[rawFormat];
|
|
4920
|
+
if (format !== void 0) {
|
|
4921
|
+
return {
|
|
4922
|
+
type: "input_audio",
|
|
4923
|
+
input_audio: {
|
|
4924
|
+
data: getBase64FromDataUrl(dataUrl),
|
|
4925
|
+
format
|
|
4926
|
+
}
|
|
4927
|
+
};
|
|
4928
|
+
}
|
|
4929
|
+
}
|
|
4930
|
+
return {
|
|
4931
|
+
type: "file",
|
|
4932
|
+
file: {
|
|
4933
|
+
filename: (_c = part.filename) != null ? _c : "",
|
|
4934
|
+
file_data: dataUrl
|
|
4935
|
+
}
|
|
4936
|
+
};
|
|
4937
|
+
}
|
|
4938
|
+
case "file-url": {
|
|
4939
|
+
if (looksLikeImageUrl(part.url)) {
|
|
4940
|
+
return {
|
|
4941
|
+
type: "image_url",
|
|
4942
|
+
image_url: { url: part.url }
|
|
4943
|
+
};
|
|
4944
|
+
}
|
|
4945
|
+
return {
|
|
4946
|
+
type: "file",
|
|
4947
|
+
file: {
|
|
4948
|
+
filename: filenameFromUrl(part.url),
|
|
4949
|
+
file_data: part.url
|
|
4950
|
+
}
|
|
4951
|
+
};
|
|
4952
|
+
}
|
|
4953
|
+
case "file-id":
|
|
4954
|
+
case "image-file-id":
|
|
4955
|
+
case "custom":
|
|
4956
|
+
return { type: "text", text: JSON.stringify(part) };
|
|
4957
|
+
default: {
|
|
4958
|
+
const _exhaustiveCheck = part;
|
|
4959
|
+
return { type: "text", text: JSON.stringify(_exhaustiveCheck) };
|
|
4960
|
+
}
|
|
4961
|
+
}
|
|
4962
|
+
});
|
|
4963
|
+
}
|
|
4964
|
+
var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
4965
|
+
"jpg",
|
|
4966
|
+
"jpeg",
|
|
4967
|
+
"png",
|
|
4968
|
+
"gif",
|
|
4969
|
+
"webp",
|
|
4970
|
+
"svg",
|
|
4971
|
+
"bmp",
|
|
4972
|
+
"ico",
|
|
4973
|
+
"tif",
|
|
4974
|
+
"tiff",
|
|
4975
|
+
"avif"
|
|
4976
|
+
]);
|
|
4977
|
+
function looksLikeImageUrl(url) {
|
|
4978
|
+
var _a163;
|
|
4979
|
+
try {
|
|
4980
|
+
const pathname = new URL(url).pathname;
|
|
4981
|
+
const ext = (_a163 = pathname.split(".").pop()) == null ? void 0 : _a163.toLowerCase();
|
|
4982
|
+
return ext !== void 0 && IMAGE_EXTENSIONS.has(ext);
|
|
4983
|
+
} catch (e) {
|
|
4984
|
+
return false;
|
|
4985
|
+
}
|
|
4986
|
+
}
|
|
4987
|
+
function filenameFromUrl(url) {
|
|
4988
|
+
try {
|
|
4989
|
+
const pathname = new URL(url).pathname;
|
|
4990
|
+
const last = pathname.split("/").pop();
|
|
4991
|
+
return (last == null ? void 0 : last.includes(".")) ? last : "";
|
|
4992
|
+
} catch (e) {
|
|
4993
|
+
return "";
|
|
4994
|
+
}
|
|
4995
|
+
}
|
|
4817
4996
|
function findFirstReasoningDetails(content) {
|
|
4818
|
-
var _a163, _b162, _c;
|
|
4997
|
+
var _a163, _b162, _c, _d;
|
|
4819
4998
|
for (const part of content) {
|
|
4820
4999
|
if (part.type === "tool-call") {
|
|
4821
|
-
const
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
5000
|
+
const parsed = OpenRouterProviderOptionsSchema.safeParse(
|
|
5001
|
+
part.providerOptions
|
|
5002
|
+
);
|
|
5003
|
+
if (parsed.success && ((_b162 = (_a163 = parsed.data) == null ? void 0 : _a163.openrouter) == null ? void 0 : _b162.reasoning_details) && parsed.data.openrouter.reasoning_details.length > 0) {
|
|
5004
|
+
return parsed.data.openrouter.reasoning_details;
|
|
4825
5005
|
}
|
|
4826
5006
|
}
|
|
4827
5007
|
}
|
|
@@ -4830,7 +5010,7 @@ function findFirstReasoningDetails(content) {
|
|
|
4830
5010
|
const parsed = OpenRouterProviderOptionsSchema.safeParse(
|
|
4831
5011
|
part.providerOptions
|
|
4832
5012
|
);
|
|
4833
|
-
if (parsed.success && ((
|
|
5013
|
+
if (parsed.success && ((_d = (_c = parsed.data) == null ? void 0 : _c.openrouter) == null ? void 0 : _d.reasoning_details) && parsed.data.openrouter.reasoning_details.length > 0) {
|
|
4834
5014
|
return parsed.data.openrouter.reasoning_details;
|
|
4835
5015
|
}
|
|
4836
5016
|
}
|
|
@@ -6490,7 +6670,7 @@ function withUserAgentSuffix22(headers, ...userAgentSuffixParts) {
|
|
|
6490
6670
|
"user-agent": userAgent
|
|
6491
6671
|
});
|
|
6492
6672
|
}
|
|
6493
|
-
var VERSION2 = false ? "0.0.0-test" : "2.3.
|
|
6673
|
+
var VERSION2 = false ? "0.0.0-test" : "2.3.3";
|
|
6494
6674
|
function createOpenRouter(options = {}) {
|
|
6495
6675
|
var _a163, _b162, _c;
|
|
6496
6676
|
const baseURL = (_b162 = withoutTrailingSlash2((_a163 = options.baseURL) != null ? _a163 : options.baseUrl)) != null ? _b162 : "https://openrouter.ai/api/v1";
|
|
@@ -6509,7 +6689,7 @@ function createOpenRouter(options = {}) {
|
|
|
6509
6689
|
);
|
|
6510
6690
|
const createChatModel = (modelId, settings = {}) => new OpenRouterChatLanguageModel(modelId, settings, {
|
|
6511
6691
|
provider: "openrouter.chat",
|
|
6512
|
-
url: ({ path:
|
|
6692
|
+
url: ({ path: path45 }) => `${baseURL}${path45}`,
|
|
6513
6693
|
headers: getHeaders,
|
|
6514
6694
|
compatibility,
|
|
6515
6695
|
fetch: options.fetch,
|
|
@@ -6517,7 +6697,7 @@ function createOpenRouter(options = {}) {
|
|
|
6517
6697
|
});
|
|
6518
6698
|
const createCompletionModel = (modelId, settings = {}) => new OpenRouterCompletionLanguageModel(modelId, settings, {
|
|
6519
6699
|
provider: "openrouter.completion",
|
|
6520
|
-
url: ({ path:
|
|
6700
|
+
url: ({ path: path45 }) => `${baseURL}${path45}`,
|
|
6521
6701
|
headers: getHeaders,
|
|
6522
6702
|
compatibility,
|
|
6523
6703
|
fetch: options.fetch,
|
|
@@ -6525,14 +6705,14 @@ function createOpenRouter(options = {}) {
|
|
|
6525
6705
|
});
|
|
6526
6706
|
const createEmbeddingModel = (modelId, settings = {}) => new OpenRouterEmbeddingModel(modelId, settings, {
|
|
6527
6707
|
provider: "openrouter.embedding",
|
|
6528
|
-
url: ({ path:
|
|
6708
|
+
url: ({ path: path45 }) => `${baseURL}${path45}`,
|
|
6529
6709
|
headers: getHeaders,
|
|
6530
6710
|
fetch: options.fetch,
|
|
6531
6711
|
extraBody: options.extraBody
|
|
6532
6712
|
});
|
|
6533
6713
|
const createImageModel = (modelId, settings = {}) => new OpenRouterImageModel(modelId, settings, {
|
|
6534
6714
|
provider: "openrouter.image",
|
|
6535
|
-
url: ({ path:
|
|
6715
|
+
url: ({ path: path45 }) => `${baseURL}${path45}`,
|
|
6536
6716
|
headers: getHeaders,
|
|
6537
6717
|
fetch: options.fetch,
|
|
6538
6718
|
extraBody: options.extraBody
|
|
@@ -14041,37 +14221,43 @@ import { createWriteStream as createWriteStream5 } from "node:fs";
|
|
|
14041
14221
|
import { mkdir as mkdir6, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
14042
14222
|
import { tmpdir } from "node:os";
|
|
14043
14223
|
import path17 from "node:path";
|
|
14224
|
+
import { execSync } from "node:child_process";
|
|
14225
|
+
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
14226
|
+
import { createWriteStream as createWriteStream6 } from "node:fs";
|
|
14227
|
+
import { mkdir as mkdir7 } from "node:fs/promises";
|
|
14228
|
+
import path18 from "node:path";
|
|
14229
|
+
import { createInterface } from "node:readline";
|
|
14044
14230
|
import { exec as exec2 } from "node:child_process";
|
|
14045
14231
|
import { constants as constants3, access as access3, stat as stat4 } from "node:fs/promises";
|
|
14046
|
-
import
|
|
14232
|
+
import path30 from "node:path";
|
|
14047
14233
|
import { promisify as promisify3 } from "node:util";
|
|
14048
14234
|
import { stat as stat3, writeFile as writeFile4 } from "node:fs/promises";
|
|
14049
|
-
import
|
|
14235
|
+
import path28 from "node:path";
|
|
14050
14236
|
import { constants as constants22 } from "node:fs";
|
|
14051
|
-
import { access as access22, mkdir as
|
|
14052
|
-
import path18 from "node:path";
|
|
14237
|
+
import { access as access22, mkdir as mkdir8, readdir, rm as rm2, stat } from "node:fs/promises";
|
|
14053
14238
|
import path19 from "node:path";
|
|
14054
14239
|
import path20 from "node:path";
|
|
14055
|
-
import { readFile as readFile7 } from "node:fs/promises";
|
|
14056
14240
|
import path21 from "node:path";
|
|
14241
|
+
import { readFile as readFile7 } from "node:fs/promises";
|
|
14242
|
+
import path222 from "node:path";
|
|
14057
14243
|
import { exec, spawn as spawn4 } from "node:child_process";
|
|
14058
|
-
import { mkdir as
|
|
14059
|
-
import
|
|
14244
|
+
import { mkdir as mkdir9, writeFile as writeFile2 } from "node:fs/promises";
|
|
14245
|
+
import path25 from "node:path";
|
|
14060
14246
|
import { promisify as promisify2 } from "node:util";
|
|
14061
|
-
import
|
|
14247
|
+
import path24 from "node:path";
|
|
14062
14248
|
import os2 from "node:os";
|
|
14063
|
-
import
|
|
14064
|
-
import { copyFile, mkdir as
|
|
14249
|
+
import path23 from "node:path";
|
|
14250
|
+
import { copyFile, mkdir as mkdir10, readFile as readFile8, readdir as readdir2, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
|
|
14251
|
+
import path27 from "node:path";
|
|
14065
14252
|
import path26 from "node:path";
|
|
14066
|
-
import path25 from "node:path";
|
|
14067
14253
|
import JSON5 from "json5";
|
|
14068
14254
|
import { writeFile as writeFile5 } from "node:fs/promises";
|
|
14069
|
-
import
|
|
14255
|
+
import path29 from "node:path";
|
|
14070
14256
|
import { constants as constants4 } from "node:fs";
|
|
14071
14257
|
import { access as access4, readFile as readFile9 } from "node:fs/promises";
|
|
14072
|
-
import path30 from "node:path";
|
|
14073
|
-
import { parse as parse4 } from "yaml";
|
|
14074
14258
|
import path31 from "node:path";
|
|
14259
|
+
import { parse as parse4 } from "yaml";
|
|
14260
|
+
import path322 from "node:path";
|
|
14075
14261
|
import fg2 from "fast-glob";
|
|
14076
14262
|
import { mkdtemp as mkdtemp2, rm as rm3, writeFile as writeFile6 } from "node:fs/promises";
|
|
14077
14263
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
@@ -14079,38 +14265,38 @@ import { dirname, join } from "node:path";
|
|
|
14079
14265
|
import { randomBytes } from "node:crypto";
|
|
14080
14266
|
import { createServer } from "node:http";
|
|
14081
14267
|
import fs2 from "node:fs/promises";
|
|
14082
|
-
import path322 from "node:path";
|
|
14083
|
-
import { createHash as createHash2, randomUUID as randomUUID8 } from "node:crypto";
|
|
14084
|
-
import { copyFile as copyFile2, mkdir as mkdir13, readdir as readdir6, stat as stat7 } from "node:fs/promises";
|
|
14085
|
-
import path41 from "node:path";
|
|
14086
|
-
import micromatch3 from "micromatch";
|
|
14087
14268
|
import path33 from "node:path";
|
|
14269
|
+
import { createHash as createHash2, randomUUID as randomUUID9 } from "node:crypto";
|
|
14270
|
+
import { copyFile as copyFile2, mkdir as mkdir14, readdir as readdir6, stat as stat7 } from "node:fs/promises";
|
|
14271
|
+
import path422 from "node:path";
|
|
14272
|
+
import micromatch3 from "micromatch";
|
|
14088
14273
|
import path34 from "node:path";
|
|
14089
|
-
import fg22 from "fast-glob";
|
|
14090
14274
|
import path35 from "node:path";
|
|
14275
|
+
import fg22 from "fast-glob";
|
|
14276
|
+
import path36 from "node:path";
|
|
14091
14277
|
import fg3 from "fast-glob";
|
|
14092
14278
|
import { exec as execCallback } from "node:child_process";
|
|
14093
14279
|
import { readdirSync as readdirSync2, statSync } from "node:fs";
|
|
14094
|
-
import path36 from "node:path";
|
|
14095
|
-
import { promisify as promisify4 } from "node:util";
|
|
14096
|
-
import { cp, mkdir as mkdir11, readdir as readdir3, rm as rm4, stat as stat5 } from "node:fs/promises";
|
|
14097
14280
|
import path37 from "node:path";
|
|
14281
|
+
import { promisify as promisify4 } from "node:util";
|
|
14282
|
+
import { cp, mkdir as mkdir12, readdir as readdir3, rm as rm4, stat as stat5 } from "node:fs/promises";
|
|
14283
|
+
import path38 from "node:path";
|
|
14098
14284
|
import { execFile } from "node:child_process";
|
|
14099
14285
|
import { createHash } from "node:crypto";
|
|
14100
14286
|
import { existsSync as existsSync2 } from "node:fs";
|
|
14101
|
-
import { cp as cp2, mkdir as
|
|
14102
|
-
import
|
|
14287
|
+
import { cp as cp2, mkdir as mkdir13, readFile as readFile10, readdir as readdir4, rm as rm5, unlink, writeFile as writeFile7 } from "node:fs/promises";
|
|
14288
|
+
import path39 from "node:path";
|
|
14103
14289
|
import { promisify as promisify5 } from "node:util";
|
|
14104
14290
|
import { execFile as execFile2 } from "node:child_process";
|
|
14105
14291
|
import { existsSync as existsSync3 } from "node:fs";
|
|
14106
|
-
import
|
|
14292
|
+
import path40 from "node:path";
|
|
14107
14293
|
import { promisify as promisify6 } from "node:util";
|
|
14108
14294
|
import { readdir as readdir5, stat as stat6 } from "node:fs/promises";
|
|
14109
|
-
import
|
|
14295
|
+
import path41 from "node:path";
|
|
14110
14296
|
import { existsSync as existsSync4 } from "node:fs";
|
|
14111
|
-
import path422 from "node:path";
|
|
14112
|
-
import { mkdir as mkdir14, readFile as readFile11, writeFile as writeFile8 } from "node:fs/promises";
|
|
14113
14297
|
import path43 from "node:path";
|
|
14298
|
+
import { mkdir as mkdir15, readFile as readFile11, writeFile as writeFile8 } from "node:fs/promises";
|
|
14299
|
+
import path44 from "node:path";
|
|
14114
14300
|
function computeTraceSummary(messages) {
|
|
14115
14301
|
const toolCallCounts = {};
|
|
14116
14302
|
const toolDurations = {};
|
|
@@ -14227,6 +14413,62 @@ function mergeExecutionMetrics(computed, metrics) {
|
|
|
14227
14413
|
endTime: metrics.endTime ?? computed.endTime
|
|
14228
14414
|
};
|
|
14229
14415
|
}
|
|
14416
|
+
function flattenInputMessages(messages) {
|
|
14417
|
+
return messages.flatMap((message) => extractContentSegments(message.content));
|
|
14418
|
+
}
|
|
14419
|
+
function collectResolvedInputFilePaths(messages) {
|
|
14420
|
+
const filePaths = [];
|
|
14421
|
+
for (const message of messages) {
|
|
14422
|
+
if (!Array.isArray(message.content)) {
|
|
14423
|
+
continue;
|
|
14424
|
+
}
|
|
14425
|
+
for (const segment of message.content) {
|
|
14426
|
+
if (isJsonObject(segment) && segment.type === "file" && typeof segment.resolvedPath === "string") {
|
|
14427
|
+
filePaths.push(segment.resolvedPath);
|
|
14428
|
+
}
|
|
14429
|
+
}
|
|
14430
|
+
}
|
|
14431
|
+
return filePaths;
|
|
14432
|
+
}
|
|
14433
|
+
function extractContentSegments(content) {
|
|
14434
|
+
if (typeof content === "string") {
|
|
14435
|
+
return content.trim().length > 0 ? [{ type: "text", value: content }] : [];
|
|
14436
|
+
}
|
|
14437
|
+
if (isJsonObject(content)) {
|
|
14438
|
+
const rendered = JSON.stringify(content, null, 2);
|
|
14439
|
+
return rendered.trim().length > 0 ? [{ type: "text", value: rendered }] : [];
|
|
14440
|
+
}
|
|
14441
|
+
if (!Array.isArray(content)) {
|
|
14442
|
+
return [];
|
|
14443
|
+
}
|
|
14444
|
+
const segments = [];
|
|
14445
|
+
for (const segment of content) {
|
|
14446
|
+
if (!isJsonObject(segment)) {
|
|
14447
|
+
continue;
|
|
14448
|
+
}
|
|
14449
|
+
segments.push(cloneJsonObject(segment));
|
|
14450
|
+
}
|
|
14451
|
+
return segments;
|
|
14452
|
+
}
|
|
14453
|
+
function cloneJsonObject(source) {
|
|
14454
|
+
const entries = Object.entries(source).map(([key, value]) => [key, cloneJsonValue(value)]);
|
|
14455
|
+
return Object.fromEntries(entries);
|
|
14456
|
+
}
|
|
14457
|
+
function cloneJsonValue(value) {
|
|
14458
|
+
if (value === null) {
|
|
14459
|
+
return null;
|
|
14460
|
+
}
|
|
14461
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
14462
|
+
return value;
|
|
14463
|
+
}
|
|
14464
|
+
if (Array.isArray(value)) {
|
|
14465
|
+
return value.map((item) => cloneJsonValue(item));
|
|
14466
|
+
}
|
|
14467
|
+
if (typeof value === "object") {
|
|
14468
|
+
return cloneJsonObject(value);
|
|
14469
|
+
}
|
|
14470
|
+
return value;
|
|
14471
|
+
}
|
|
14230
14472
|
var ANSI_RED = "\x1B[31m";
|
|
14231
14473
|
var ANSI_RESET2 = "\x1B[0m";
|
|
14232
14474
|
function logError(msg) {
|
|
@@ -14292,7 +14534,6 @@ function parseAgentSkillsEvals(parsed, source = "evals.json", baseDir) {
|
|
|
14292
14534
|
id: String(id),
|
|
14293
14535
|
question: prompt,
|
|
14294
14536
|
input: [{ role: "user", content: prompt }],
|
|
14295
|
-
input_segments: [{ type: "text", value: prompt }],
|
|
14296
14537
|
expected_output: evalCase.expected_output ? [{ role: "assistant", content: evalCase.expected_output }] : [],
|
|
14297
14538
|
reference_answer: evalCase.expected_output,
|
|
14298
14539
|
file_paths: filePaths,
|
|
@@ -14414,7 +14655,7 @@ async function loadConfig(evalFilePath, repoRoot) {
|
|
|
14414
14655
|
}
|
|
14415
14656
|
try {
|
|
14416
14657
|
const rawConfig = await readFile22(configPath, "utf8");
|
|
14417
|
-
const parsed = parse(rawConfig);
|
|
14658
|
+
const parsed = interpolateEnv(parse(rawConfig), process.env);
|
|
14418
14659
|
if (!isJsonObject(parsed)) {
|
|
14419
14660
|
logWarning(`Invalid .agentv/config.yaml format at ${configPath}`);
|
|
14420
14661
|
continue;
|
|
@@ -14632,6 +14873,27 @@ function parseExecutionDefaults(raw, configPath) {
|
|
|
14632
14873
|
} else if (otelFile !== void 0) {
|
|
14633
14874
|
logWarning(`Invalid execution.otel_file in ${configPath}, expected non-empty string`);
|
|
14634
14875
|
}
|
|
14876
|
+
if (typeof obj.export_otel === "boolean") {
|
|
14877
|
+
result.export_otel = obj.export_otel;
|
|
14878
|
+
} else if (obj.export_otel !== void 0) {
|
|
14879
|
+
logWarning(`Invalid execution.export_otel in ${configPath}, expected boolean`);
|
|
14880
|
+
}
|
|
14881
|
+
const otelBackend = obj.otel_backend;
|
|
14882
|
+
if (typeof otelBackend === "string" && otelBackend.trim().length > 0) {
|
|
14883
|
+
result.otel_backend = otelBackend.trim();
|
|
14884
|
+
} else if (otelBackend !== void 0) {
|
|
14885
|
+
logWarning(`Invalid execution.otel_backend in ${configPath}, expected non-empty string`);
|
|
14886
|
+
}
|
|
14887
|
+
if (typeof obj.otel_capture_content === "boolean") {
|
|
14888
|
+
result.otel_capture_content = obj.otel_capture_content;
|
|
14889
|
+
} else if (obj.otel_capture_content !== void 0) {
|
|
14890
|
+
logWarning(`Invalid execution.otel_capture_content in ${configPath}, expected boolean`);
|
|
14891
|
+
}
|
|
14892
|
+
if (typeof obj.otel_group_turns === "boolean") {
|
|
14893
|
+
result.otel_group_turns = obj.otel_group_turns;
|
|
14894
|
+
} else if (obj.otel_group_turns !== void 0) {
|
|
14895
|
+
logWarning(`Invalid execution.otel_group_turns in ${configPath}, expected boolean`);
|
|
14896
|
+
}
|
|
14635
14897
|
if (typeof obj.pool_workspaces === "boolean") {
|
|
14636
14898
|
result.pool_workspaces = obj.pool_workspaces;
|
|
14637
14899
|
} else if (obj.pool_workspaces !== void 0) {
|
|
@@ -16076,27 +16338,28 @@ var ANSI_YELLOW4 = "\x1B[33m";
|
|
|
16076
16338
|
var ANSI_RESET5 = "\x1B[0m";
|
|
16077
16339
|
async function processMessages(options) {
|
|
16078
16340
|
const { messages, searchRoots, repoRootPath, textParts, messageType, verbose } = options;
|
|
16079
|
-
const
|
|
16341
|
+
const processedMessages = [];
|
|
16080
16342
|
for (const message of messages) {
|
|
16081
16343
|
const content = message.content;
|
|
16082
16344
|
if (typeof content === "string") {
|
|
16083
|
-
segments.push({ type: "text", value: content });
|
|
16084
16345
|
if (textParts) {
|
|
16085
16346
|
textParts.push(content);
|
|
16086
16347
|
}
|
|
16348
|
+
processedMessages.push({ ...message, content });
|
|
16087
16349
|
continue;
|
|
16088
16350
|
}
|
|
16089
16351
|
if (isJsonObject(content)) {
|
|
16090
16352
|
const rendered = JSON.stringify(content, null, 2);
|
|
16091
|
-
segments.push({ type: "text", value: rendered });
|
|
16092
16353
|
if (textParts) {
|
|
16093
16354
|
textParts.push(rendered);
|
|
16094
16355
|
}
|
|
16356
|
+
processedMessages.push({ ...message, content: cloneJsonObject(content) });
|
|
16095
16357
|
continue;
|
|
16096
16358
|
}
|
|
16097
16359
|
if (!Array.isArray(content)) {
|
|
16098
16360
|
continue;
|
|
16099
16361
|
}
|
|
16362
|
+
const processedContent = [];
|
|
16100
16363
|
for (const rawSegment of content) {
|
|
16101
16364
|
if (!isJsonObject(rawSegment)) {
|
|
16102
16365
|
continue;
|
|
@@ -16119,8 +16382,8 @@ async function processMessages(options) {
|
|
|
16119
16382
|
}
|
|
16120
16383
|
try {
|
|
16121
16384
|
const fileContent = (await readFile4(resolvedPath, "utf8")).replace(/\r\n/g, "\n");
|
|
16122
|
-
|
|
16123
|
-
|
|
16385
|
+
processedContent.push({
|
|
16386
|
+
...cloneJsonObject(rawSegment),
|
|
16124
16387
|
path: displayPath,
|
|
16125
16388
|
text: fileContent,
|
|
16126
16389
|
resolvedPath: path5.resolve(resolvedPath)
|
|
@@ -16137,37 +16400,19 @@ async function processMessages(options) {
|
|
|
16137
16400
|
continue;
|
|
16138
16401
|
}
|
|
16139
16402
|
const clonedSegment = cloneJsonObject(rawSegment);
|
|
16140
|
-
|
|
16403
|
+
processedContent.push(clonedSegment);
|
|
16141
16404
|
const inlineValue = clonedSegment.value;
|
|
16142
16405
|
if (typeof inlineValue === "string" && textParts) {
|
|
16143
16406
|
textParts.push(inlineValue);
|
|
16144
16407
|
}
|
|
16145
16408
|
}
|
|
16409
|
+
processedMessages.push({ ...message, content: processedContent });
|
|
16146
16410
|
}
|
|
16147
|
-
return
|
|
16411
|
+
return processedMessages;
|
|
16148
16412
|
}
|
|
16149
16413
|
function asString3(value) {
|
|
16150
16414
|
return typeof value === "string" ? value : void 0;
|
|
16151
16415
|
}
|
|
16152
|
-
function cloneJsonObject(source) {
|
|
16153
|
-
const entries = Object.entries(source).map(([key, value]) => [key, cloneJsonValue(value)]);
|
|
16154
|
-
return Object.fromEntries(entries);
|
|
16155
|
-
}
|
|
16156
|
-
function cloneJsonValue(value) {
|
|
16157
|
-
if (value === null) {
|
|
16158
|
-
return null;
|
|
16159
|
-
}
|
|
16160
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
16161
|
-
return value;
|
|
16162
|
-
}
|
|
16163
|
-
if (Array.isArray(value)) {
|
|
16164
|
-
return value.map((item) => cloneJsonValue(item));
|
|
16165
|
-
}
|
|
16166
|
-
if (typeof value === "object") {
|
|
16167
|
-
return cloneJsonObject(value);
|
|
16168
|
-
}
|
|
16169
|
-
return value;
|
|
16170
|
-
}
|
|
16171
16416
|
function logWarning3(message, details) {
|
|
16172
16417
|
if (details && details.length > 0) {
|
|
16173
16418
|
const detailBlock = details.join("\n");
|
|
@@ -16412,10 +16657,10 @@ async function loadTestsFromJsonl(evalFilePath, repoRoot, options) {
|
|
|
16412
16657
|
);
|
|
16413
16658
|
}
|
|
16414
16659
|
}
|
|
16415
|
-
const
|
|
16660
|
+
const rawInputMessages = resolveInputMessages(evalcase);
|
|
16416
16661
|
const expectedMessages = resolveExpectedMessages(evalcase) ?? [];
|
|
16417
16662
|
const hasEvaluationSpec = !!outcome || expectedMessages.length > 0 || evalcase.assert !== void 0;
|
|
16418
|
-
if (!id || !hasEvaluationSpec || !
|
|
16663
|
+
if (!id || !hasEvaluationSpec || !rawInputMessages || rawInputMessages.length === 0) {
|
|
16419
16664
|
logError2(
|
|
16420
16665
|
`Skipping incomplete test at line ${lineNumber}: ${id ?? "unknown"}. Missing required fields: id, input, and at least one of criteria/expected_output/assert`
|
|
16421
16666
|
);
|
|
@@ -16423,8 +16668,8 @@ async function loadTestsFromJsonl(evalFilePath, repoRoot, options) {
|
|
|
16423
16668
|
}
|
|
16424
16669
|
const hasExpectedMessages = expectedMessages.length > 0;
|
|
16425
16670
|
const inputTextParts = [];
|
|
16426
|
-
const
|
|
16427
|
-
messages:
|
|
16671
|
+
const inputMessages = await processMessages({
|
|
16672
|
+
messages: rawInputMessages,
|
|
16428
16673
|
searchRoots,
|
|
16429
16674
|
repoRootPath,
|
|
16430
16675
|
textParts: inputTextParts,
|
|
@@ -16470,19 +16715,13 @@ async function loadTestsFromJsonl(evalFilePath, repoRoot, options) {
|
|
|
16470
16715
|
}
|
|
16471
16716
|
}
|
|
16472
16717
|
warnUnconsumedCriteria(outcome, evaluators, id ?? "unknown");
|
|
16473
|
-
const userFilePaths =
|
|
16474
|
-
for (const segment of inputSegments) {
|
|
16475
|
-
if (segment.type === "file" && typeof segment.resolvedPath === "string") {
|
|
16476
|
-
userFilePaths.push(segment.resolvedPath);
|
|
16477
|
-
}
|
|
16478
|
-
}
|
|
16718
|
+
const userFilePaths = collectResolvedInputFilePaths(inputMessages);
|
|
16479
16719
|
const testCase = {
|
|
16480
16720
|
id,
|
|
16481
16721
|
eval_set: evalSetName,
|
|
16482
16722
|
conversation_id: conversationId,
|
|
16483
16723
|
question,
|
|
16484
16724
|
input: inputMessages,
|
|
16485
|
-
input_segments: inputSegments,
|
|
16486
16725
|
expected_output: outputSegments,
|
|
16487
16726
|
reference_answer: referenceAnswer,
|
|
16488
16727
|
file_paths: userFilePaths,
|
|
@@ -16543,50 +16782,9 @@ function parseMetadata(suite) {
|
|
|
16543
16782
|
});
|
|
16544
16783
|
}
|
|
16545
16784
|
async function buildPromptInputs(testCase, mode = "lm") {
|
|
16546
|
-
const segmentsByMessage =
|
|
16547
|
-
|
|
16548
|
-
|
|
16549
|
-
if (segment.type === "file" && typeof segment.path === "string" && typeof segment.text === "string") {
|
|
16550
|
-
fileContentsByPath.set(segment.path, segment.text);
|
|
16551
|
-
}
|
|
16552
|
-
}
|
|
16553
|
-
for (const message of testCase.input) {
|
|
16554
|
-
const messageSegments = [];
|
|
16555
|
-
if (typeof message.content === "string") {
|
|
16556
|
-
if (message.content.trim().length > 0) {
|
|
16557
|
-
messageSegments.push({ type: "text", value: message.content });
|
|
16558
|
-
}
|
|
16559
|
-
} else if (Array.isArray(message.content)) {
|
|
16560
|
-
for (const segment of message.content) {
|
|
16561
|
-
if (typeof segment === "string") {
|
|
16562
|
-
if (segment.trim().length > 0) {
|
|
16563
|
-
messageSegments.push({ type: "text", value: segment });
|
|
16564
|
-
}
|
|
16565
|
-
} else if (isJsonObject(segment)) {
|
|
16566
|
-
const type = asString5(segment.type);
|
|
16567
|
-
if (type === "file") {
|
|
16568
|
-
const value = asString5(segment.value);
|
|
16569
|
-
if (!value) continue;
|
|
16570
|
-
const fileText = fileContentsByPath.get(value);
|
|
16571
|
-
if (fileText !== void 0) {
|
|
16572
|
-
messageSegments.push({ type: "file", text: fileText, path: value });
|
|
16573
|
-
}
|
|
16574
|
-
} else if (type === "text") {
|
|
16575
|
-
const textValue = asString5(segment.value);
|
|
16576
|
-
if (textValue && textValue.trim().length > 0) {
|
|
16577
|
-
messageSegments.push({ type: "text", value: textValue });
|
|
16578
|
-
}
|
|
16579
|
-
}
|
|
16580
|
-
}
|
|
16581
|
-
}
|
|
16582
|
-
} else if (isJsonObject(message.content)) {
|
|
16583
|
-
const rendered = JSON.stringify(message.content, null, 2);
|
|
16584
|
-
if (rendered.trim().length > 0) {
|
|
16585
|
-
messageSegments.push({ type: "text", value: rendered });
|
|
16586
|
-
}
|
|
16587
|
-
}
|
|
16588
|
-
segmentsByMessage.push(messageSegments);
|
|
16589
|
-
}
|
|
16785
|
+
const segmentsByMessage = testCase.input.map(
|
|
16786
|
+
(message) => extractContentSegments(message.content)
|
|
16787
|
+
);
|
|
16590
16788
|
const useRoleMarkers = needsRoleMarkers(testCase.input, segmentsByMessage);
|
|
16591
16789
|
let question;
|
|
16592
16790
|
if (useRoleMarkers) {
|
|
@@ -16614,7 +16812,7 @@ ${messageContent}`);
|
|
|
16614
16812
|
question = messageParts.join("\n\n");
|
|
16615
16813
|
} else {
|
|
16616
16814
|
const questionParts = [];
|
|
16617
|
-
for (const segment of testCase.
|
|
16815
|
+
for (const segment of flattenInputMessages(testCase.input)) {
|
|
16618
16816
|
const formattedContent = formatSegment(segment, mode);
|
|
16619
16817
|
if (formattedContent) {
|
|
16620
16818
|
questionParts.push(formattedContent);
|
|
@@ -16701,9 +16899,6 @@ function buildChatPromptFromSegments(options) {
|
|
|
16701
16899
|
}
|
|
16702
16900
|
return chatPrompt.length > 0 ? chatPrompt : void 0;
|
|
16703
16901
|
}
|
|
16704
|
-
function asString5(value) {
|
|
16705
|
-
return typeof value === "string" ? value : void 0;
|
|
16706
|
-
}
|
|
16707
16902
|
var ANSI_YELLOW6 = "\x1B[33m";
|
|
16708
16903
|
var ANSI_RED3 = "\x1B[31m";
|
|
16709
16904
|
var ANSI_RESET7 = "\x1B[0m";
|
|
@@ -16784,7 +16979,7 @@ async function loadTestsFromYaml(evalFilePath, repoRoot, options) {
|
|
|
16784
16979
|
throw new Error(`Invalid test file format: ${evalFilePath}`);
|
|
16785
16980
|
}
|
|
16786
16981
|
const suite = interpolated;
|
|
16787
|
-
const evalSetNameFromSuite =
|
|
16982
|
+
const evalSetNameFromSuite = asString5(suite.name)?.trim();
|
|
16788
16983
|
const fallbackEvalSet = path7.basename(absoluteTestPath).replace(/\.ya?ml$/i, "") || "eval";
|
|
16789
16984
|
const evalSetName = evalSetNameFromSuite && evalSetNameFromSuite.length > 0 ? evalSetNameFromSuite : fallbackEvalSet;
|
|
16790
16985
|
const rawTestcases = resolveTests(suite);
|
|
@@ -16803,7 +16998,7 @@ async function loadTestsFromYaml(evalFilePath, repoRoot, options) {
|
|
|
16803
16998
|
const suiteInputMessages = expandInputShorthand(suite.input);
|
|
16804
16999
|
const suiteInputFiles = suite.input_files;
|
|
16805
17000
|
const rawGlobalExecution = isJsonObject(suite.execution) ? suite.execution : void 0;
|
|
16806
|
-
const _globalTarget =
|
|
17001
|
+
const _globalTarget = asString5(rawGlobalExecution?.target) ?? asString5(suite.target);
|
|
16807
17002
|
const suiteAssertions = suite.assertions ?? suite.assert;
|
|
16808
17003
|
if (suite.assert !== void 0 && suite.assertions === void 0) {
|
|
16809
17004
|
logWarning5("'assert' is deprecated at the suite level. Use 'assertions' instead.");
|
|
@@ -16816,17 +17011,17 @@ async function loadTestsFromYaml(evalFilePath, repoRoot, options) {
|
|
|
16816
17011
|
continue;
|
|
16817
17012
|
}
|
|
16818
17013
|
const evalcase = rawEvalcase;
|
|
16819
|
-
const id =
|
|
17014
|
+
const id = asString5(evalcase.id);
|
|
16820
17015
|
if (filterPattern && (!id || !micromatch2.isMatch(id, filterPattern))) {
|
|
16821
17016
|
continue;
|
|
16822
17017
|
}
|
|
16823
|
-
const conversationId =
|
|
16824
|
-
let outcome =
|
|
17018
|
+
const conversationId = asString5(evalcase.conversation_id);
|
|
17019
|
+
let outcome = asString5(evalcase.criteria);
|
|
16825
17020
|
if (!outcome && evalcase.expected_outcome !== void 0) {
|
|
16826
|
-
outcome =
|
|
17021
|
+
outcome = asString5(evalcase.expected_outcome);
|
|
16827
17022
|
if (outcome) {
|
|
16828
17023
|
logWarning5(
|
|
16829
|
-
`Test '${
|
|
17024
|
+
`Test '${asString5(evalcase.id) ?? "unknown"}': 'expected_outcome' is deprecated. Use 'criteria' instead.`
|
|
16830
17025
|
);
|
|
16831
17026
|
}
|
|
16832
17027
|
}
|
|
@@ -16843,10 +17038,9 @@ async function loadTestsFromYaml(evalFilePath, repoRoot, options) {
|
|
|
16843
17038
|
continue;
|
|
16844
17039
|
}
|
|
16845
17040
|
const effectiveSuiteInputMessages = suiteInputMessages && !skipDefaults ? suiteInputMessages : void 0;
|
|
16846
|
-
const inputMessages = effectiveSuiteInputMessages ? [...effectiveSuiteInputMessages, ...testInputMessages] : testInputMessages;
|
|
16847
17041
|
const hasExpectedMessages = expectedMessages.length > 0;
|
|
16848
17042
|
const inputTextParts = [];
|
|
16849
|
-
const
|
|
17043
|
+
const suiteResolvedInputMessages = effectiveSuiteInputMessages ? await processMessages({
|
|
16850
17044
|
messages: effectiveSuiteInputMessages,
|
|
16851
17045
|
searchRoots,
|
|
16852
17046
|
repoRootPath,
|
|
@@ -16854,7 +17048,7 @@ async function loadTestsFromYaml(evalFilePath, repoRoot, options) {
|
|
|
16854
17048
|
messageType: "input",
|
|
16855
17049
|
verbose
|
|
16856
17050
|
}) : [];
|
|
16857
|
-
const
|
|
17051
|
+
const testResolvedInputMessages = await processMessages({
|
|
16858
17052
|
messages: testInputMessages,
|
|
16859
17053
|
searchRoots,
|
|
16860
17054
|
repoRootPath,
|
|
@@ -16862,7 +17056,7 @@ async function loadTestsFromYaml(evalFilePath, repoRoot, options) {
|
|
|
16862
17056
|
messageType: "input",
|
|
16863
17057
|
verbose
|
|
16864
17058
|
});
|
|
16865
|
-
const
|
|
17059
|
+
const inputMessages = [...suiteResolvedInputMessages, ...testResolvedInputMessages];
|
|
16866
17060
|
const outputSegments = hasExpectedMessages ? await processExpectedMessages({
|
|
16867
17061
|
messages: expectedMessages,
|
|
16868
17062
|
searchRoots,
|
|
@@ -16900,12 +17094,7 @@ async function loadTestsFromYaml(evalFilePath, repoRoot, options) {
|
|
|
16900
17094
|
}
|
|
16901
17095
|
}
|
|
16902
17096
|
warnUnconsumedCriteria(outcome, evaluators, id ?? "unknown");
|
|
16903
|
-
const userFilePaths =
|
|
16904
|
-
for (const segment of inputSegments) {
|
|
16905
|
-
if (segment.type === "file" && typeof segment.resolvedPath === "string") {
|
|
16906
|
-
userFilePaths.push(segment.resolvedPath);
|
|
16907
|
-
}
|
|
16908
|
-
}
|
|
17097
|
+
const userFilePaths = collectResolvedInputFilePaths(inputMessages);
|
|
16909
17098
|
const caseWorkspace = await resolveWorkspaceConfig(evalcase.workspace, evalFileDir);
|
|
16910
17099
|
const mergedWorkspace = mergeWorkspaceConfigs(suiteWorkspace, caseWorkspace);
|
|
16911
17100
|
const metadata = isJsonObject(evalcase.metadata) ? evalcase.metadata : void 0;
|
|
@@ -16916,7 +17105,6 @@ async function loadTestsFromYaml(evalFilePath, repoRoot, options) {
|
|
|
16916
17105
|
conversation_id: conversationId,
|
|
16917
17106
|
question,
|
|
16918
17107
|
input: inputMessages,
|
|
16919
|
-
input_segments: inputSegments,
|
|
16920
17108
|
expected_output: outputSegments,
|
|
16921
17109
|
reference_answer: referenceAnswer,
|
|
16922
17110
|
file_paths: userFilePaths,
|
|
@@ -17125,7 +17313,7 @@ function mergeWorkspaceConfigs(suiteLevel, caseLevel) {
|
|
|
17125
17313
|
path: caseLevel.path ?? suiteLevel.path
|
|
17126
17314
|
};
|
|
17127
17315
|
}
|
|
17128
|
-
function
|
|
17316
|
+
function asString5(value) {
|
|
17129
17317
|
return typeof value === "string" ? value : void 0;
|
|
17130
17318
|
}
|
|
17131
17319
|
function logWarning5(message, details) {
|
|
@@ -20727,260 +20915,6 @@ var MockProvider = class {
|
|
|
20727
20915
|
return this.delayMs;
|
|
20728
20916
|
}
|
|
20729
20917
|
};
|
|
20730
|
-
function extractPiTextContent(content) {
|
|
20731
|
-
if (typeof content === "string") {
|
|
20732
|
-
return content;
|
|
20733
|
-
}
|
|
20734
|
-
if (!Array.isArray(content)) {
|
|
20735
|
-
return void 0;
|
|
20736
|
-
}
|
|
20737
|
-
const textParts = [];
|
|
20738
|
-
for (const part of content) {
|
|
20739
|
-
if (!part || typeof part !== "object") {
|
|
20740
|
-
continue;
|
|
20741
|
-
}
|
|
20742
|
-
const p = part;
|
|
20743
|
-
if (p.type === "text" && typeof p.text === "string") {
|
|
20744
|
-
textParts.push(p.text);
|
|
20745
|
-
}
|
|
20746
|
-
}
|
|
20747
|
-
return textParts.length > 0 ? textParts.join("\n") : void 0;
|
|
20748
|
-
}
|
|
20749
|
-
function toFiniteNumber(value) {
|
|
20750
|
-
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
20751
|
-
return void 0;
|
|
20752
|
-
}
|
|
20753
|
-
var piAgentModule = null;
|
|
20754
|
-
var piAiModule = null;
|
|
20755
|
-
async function loadPiModules() {
|
|
20756
|
-
if (!piAgentModule || !piAiModule) {
|
|
20757
|
-
try {
|
|
20758
|
-
[piAgentModule, piAiModule] = await Promise.all([
|
|
20759
|
-
import("@mariozechner/pi-agent-core"),
|
|
20760
|
-
import("@mariozechner/pi-ai")
|
|
20761
|
-
]);
|
|
20762
|
-
} catch (error) {
|
|
20763
|
-
throw new Error(
|
|
20764
|
-
`Failed to load pi-agent-sdk dependencies. Please install them:
|
|
20765
|
-
npm install @mariozechner/pi-agent-core @mariozechner/pi-ai
|
|
20766
|
-
|
|
20767
|
-
Original error: ${error instanceof Error ? error.message : String(error)}`
|
|
20768
|
-
);
|
|
20769
|
-
}
|
|
20770
|
-
}
|
|
20771
|
-
return {
|
|
20772
|
-
Agent: piAgentModule.Agent,
|
|
20773
|
-
getModel: piAiModule.getModel,
|
|
20774
|
-
getEnvApiKey: piAiModule.getEnvApiKey
|
|
20775
|
-
};
|
|
20776
|
-
}
|
|
20777
|
-
var PiAgentSdkProvider = class {
|
|
20778
|
-
id;
|
|
20779
|
-
kind = "pi-agent-sdk";
|
|
20780
|
-
targetName;
|
|
20781
|
-
supportsBatch = false;
|
|
20782
|
-
config;
|
|
20783
|
-
constructor(targetName, config) {
|
|
20784
|
-
this.id = `pi-agent-sdk:${targetName}`;
|
|
20785
|
-
this.targetName = targetName;
|
|
20786
|
-
this.config = config;
|
|
20787
|
-
}
|
|
20788
|
-
async invoke(request) {
|
|
20789
|
-
if (request.signal?.aborted) {
|
|
20790
|
-
throw new Error("Pi agent SDK request was aborted before execution");
|
|
20791
|
-
}
|
|
20792
|
-
const { Agent, getModel, getEnvApiKey } = await loadPiModules();
|
|
20793
|
-
const startTimeIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
20794
|
-
const startMs = Date.now();
|
|
20795
|
-
const providerName = this.config.provider ?? "anthropic";
|
|
20796
|
-
const modelId = this.config.model ?? "claude-sonnet-4-20250514";
|
|
20797
|
-
const model = getModel(providerName, modelId);
|
|
20798
|
-
const systemPrompt = this.config.systemPrompt ?? "Answer directly and concisely.";
|
|
20799
|
-
const agent = new Agent({
|
|
20800
|
-
initialState: {
|
|
20801
|
-
systemPrompt,
|
|
20802
|
-
model,
|
|
20803
|
-
tools: [],
|
|
20804
|
-
// No tools for simple Q&A
|
|
20805
|
-
messages: []
|
|
20806
|
-
},
|
|
20807
|
-
getApiKey: async (provider) => {
|
|
20808
|
-
return this.config.apiKey ?? getEnvApiKey(provider) ?? void 0;
|
|
20809
|
-
}
|
|
20810
|
-
});
|
|
20811
|
-
let tokenUsage;
|
|
20812
|
-
let costUsd;
|
|
20813
|
-
const toolTrackers = /* @__PURE__ */ new Map();
|
|
20814
|
-
const completedToolResults = /* @__PURE__ */ new Map();
|
|
20815
|
-
const unsubscribe = agent.subscribe((event) => {
|
|
20816
|
-
switch (event.type) {
|
|
20817
|
-
case "message_end": {
|
|
20818
|
-
const msg = event.message;
|
|
20819
|
-
if (msg && typeof msg === "object" && "role" in msg && msg.role === "assistant" && "usage" in msg) {
|
|
20820
|
-
const usage = msg.usage;
|
|
20821
|
-
if (usage && typeof usage === "object") {
|
|
20822
|
-
const u = usage;
|
|
20823
|
-
const input = toFiniteNumber(u.input);
|
|
20824
|
-
const output = toFiniteNumber(u.output);
|
|
20825
|
-
const cached = toFiniteNumber(u.cacheRead);
|
|
20826
|
-
let callDelta;
|
|
20827
|
-
if (input !== void 0 || output !== void 0) {
|
|
20828
|
-
callDelta = {
|
|
20829
|
-
input: input ?? 0,
|
|
20830
|
-
output: output ?? 0,
|
|
20831
|
-
...cached !== void 0 ? { cached } : {}
|
|
20832
|
-
};
|
|
20833
|
-
tokenUsage = {
|
|
20834
|
-
input: (tokenUsage?.input ?? 0) + callDelta.input,
|
|
20835
|
-
output: (tokenUsage?.output ?? 0) + callDelta.output,
|
|
20836
|
-
...cached !== void 0 ? { cached: (tokenUsage?.cached ?? 0) + cached } : tokenUsage?.cached !== void 0 ? { cached: tokenUsage.cached } : {}
|
|
20837
|
-
};
|
|
20838
|
-
}
|
|
20839
|
-
const cost = u.cost;
|
|
20840
|
-
if (cost && typeof cost === "object") {
|
|
20841
|
-
const total = toFiniteNumber(cost.total);
|
|
20842
|
-
if (total !== void 0) {
|
|
20843
|
-
costUsd = (costUsd ?? 0) + total;
|
|
20844
|
-
}
|
|
20845
|
-
}
|
|
20846
|
-
request.streamCallbacks?.onLlmCallEnd?.(modelId, callDelta);
|
|
20847
|
-
}
|
|
20848
|
-
}
|
|
20849
|
-
break;
|
|
20850
|
-
}
|
|
20851
|
-
case "tool_execution_start": {
|
|
20852
|
-
toolTrackers.set(event.toolCallId, {
|
|
20853
|
-
toolCallId: event.toolCallId,
|
|
20854
|
-
toolName: event.toolName,
|
|
20855
|
-
args: event.args,
|
|
20856
|
-
startMs: Date.now(),
|
|
20857
|
-
startTime: (/* @__PURE__ */ new Date()).toISOString()
|
|
20858
|
-
});
|
|
20859
|
-
request.streamCallbacks?.onToolCallStart?.(event.toolName, event.toolCallId);
|
|
20860
|
-
break;
|
|
20861
|
-
}
|
|
20862
|
-
case "tool_execution_end": {
|
|
20863
|
-
const tracker = toolTrackers.get(event.toolCallId);
|
|
20864
|
-
const durationMs = tracker ? Date.now() - tracker.startMs : 0;
|
|
20865
|
-
completedToolResults.set(event.toolCallId, {
|
|
20866
|
-
output: event.result,
|
|
20867
|
-
durationMs
|
|
20868
|
-
});
|
|
20869
|
-
request.streamCallbacks?.onToolCallEnd?.(
|
|
20870
|
-
event.toolName,
|
|
20871
|
-
tracker?.args,
|
|
20872
|
-
event.result,
|
|
20873
|
-
durationMs,
|
|
20874
|
-
event.toolCallId
|
|
20875
|
-
);
|
|
20876
|
-
toolTrackers.delete(event.toolCallId);
|
|
20877
|
-
break;
|
|
20878
|
-
}
|
|
20879
|
-
}
|
|
20880
|
-
});
|
|
20881
|
-
try {
|
|
20882
|
-
if (this.config.timeoutMs) {
|
|
20883
|
-
const timeoutMs = this.config.timeoutMs;
|
|
20884
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
20885
|
-
setTimeout(
|
|
20886
|
-
() => reject(new Error(`Pi agent SDK timed out after ${timeoutMs}ms`)),
|
|
20887
|
-
timeoutMs
|
|
20888
|
-
);
|
|
20889
|
-
});
|
|
20890
|
-
await Promise.race([agent.prompt(request.question), timeoutPromise]);
|
|
20891
|
-
} else {
|
|
20892
|
-
await agent.prompt(request.question);
|
|
20893
|
-
}
|
|
20894
|
-
await agent.waitForIdle();
|
|
20895
|
-
const agentMessages = agent.state.messages;
|
|
20896
|
-
const output = [];
|
|
20897
|
-
for (const msg of agentMessages) {
|
|
20898
|
-
output.push(convertAgentMessage(msg, toolTrackers, completedToolResults));
|
|
20899
|
-
}
|
|
20900
|
-
const endTimeIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
20901
|
-
const durationMs = Date.now() - startMs;
|
|
20902
|
-
return {
|
|
20903
|
-
raw: {
|
|
20904
|
-
messages: agentMessages,
|
|
20905
|
-
systemPrompt,
|
|
20906
|
-
model: this.config.model,
|
|
20907
|
-
provider: this.config.provider
|
|
20908
|
-
},
|
|
20909
|
-
output,
|
|
20910
|
-
tokenUsage,
|
|
20911
|
-
costUsd,
|
|
20912
|
-
durationMs,
|
|
20913
|
-
startTime: startTimeIso,
|
|
20914
|
-
endTime: endTimeIso
|
|
20915
|
-
};
|
|
20916
|
-
} finally {
|
|
20917
|
-
unsubscribe();
|
|
20918
|
-
}
|
|
20919
|
-
}
|
|
20920
|
-
};
|
|
20921
|
-
function convertAgentMessage(message, toolTrackers, completedToolResults) {
|
|
20922
|
-
if (!message || typeof message !== "object") {
|
|
20923
|
-
return { role: "unknown", content: String(message) };
|
|
20924
|
-
}
|
|
20925
|
-
const msg = message;
|
|
20926
|
-
const role = typeof msg.role === "string" ? msg.role : "unknown";
|
|
20927
|
-
const content = extractPiTextContent(msg.content);
|
|
20928
|
-
const toolCalls = extractToolCalls3(msg.content, toolTrackers, completedToolResults);
|
|
20929
|
-
const startTime = typeof msg.timestamp === "number" ? new Date(msg.timestamp).toISOString() : typeof msg.timestamp === "string" ? msg.timestamp : void 0;
|
|
20930
|
-
let msgTokenUsage;
|
|
20931
|
-
if (msg.usage && typeof msg.usage === "object") {
|
|
20932
|
-
const u = msg.usage;
|
|
20933
|
-
const input = toFiniteNumber(u.input);
|
|
20934
|
-
const output = toFiniteNumber(u.output);
|
|
20935
|
-
if (input !== void 0 || output !== void 0) {
|
|
20936
|
-
msgTokenUsage = {
|
|
20937
|
-
input: input ?? 0,
|
|
20938
|
-
output: output ?? 0,
|
|
20939
|
-
...toFiniteNumber(u.cacheRead) !== void 0 ? { cached: toFiniteNumber(u.cacheRead) } : {}
|
|
20940
|
-
};
|
|
20941
|
-
}
|
|
20942
|
-
}
|
|
20943
|
-
const metadata = {};
|
|
20944
|
-
if (msg.api) metadata.api = msg.api;
|
|
20945
|
-
if (msg.provider) metadata.provider = msg.provider;
|
|
20946
|
-
if (msg.model) metadata.model = msg.model;
|
|
20947
|
-
if (msg.stopReason) metadata.stopReason = msg.stopReason;
|
|
20948
|
-
return {
|
|
20949
|
-
role,
|
|
20950
|
-
content,
|
|
20951
|
-
toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
20952
|
-
startTime,
|
|
20953
|
-
metadata: Object.keys(metadata).length > 0 ? metadata : void 0,
|
|
20954
|
-
tokenUsage: msgTokenUsage
|
|
20955
|
-
};
|
|
20956
|
-
}
|
|
20957
|
-
function extractToolCalls3(content, toolTrackers, completedToolResults) {
|
|
20958
|
-
if (!Array.isArray(content)) {
|
|
20959
|
-
return [];
|
|
20960
|
-
}
|
|
20961
|
-
const toolCalls = [];
|
|
20962
|
-
for (const part of content) {
|
|
20963
|
-
if (!part || typeof part !== "object") {
|
|
20964
|
-
continue;
|
|
20965
|
-
}
|
|
20966
|
-
const p = part;
|
|
20967
|
-
if (p.type === "toolCall" && typeof p.name === "string") {
|
|
20968
|
-
const id = typeof p.id === "string" ? p.id : void 0;
|
|
20969
|
-
const tracker = id ? toolTrackers.get(id) : void 0;
|
|
20970
|
-
const completed = id ? completedToolResults.get(id) : void 0;
|
|
20971
|
-
toolCalls.push({
|
|
20972
|
-
tool: p.name,
|
|
20973
|
-
input: p.arguments,
|
|
20974
|
-
id,
|
|
20975
|
-
output: completed?.output,
|
|
20976
|
-
durationMs: completed?.durationMs,
|
|
20977
|
-
startTime: tracker?.startTime,
|
|
20978
|
-
endTime: tracker?.startTime && completed?.durationMs !== void 0 ? new Date(new Date(tracker.startTime).getTime() + completed.durationMs).toISOString() : void 0
|
|
20979
|
-
});
|
|
20980
|
-
}
|
|
20981
|
-
}
|
|
20982
|
-
return toolCalls;
|
|
20983
|
-
}
|
|
20984
20918
|
var GLOBAL_LOGS_KEY5 = Symbol.for("agentv.piLogs");
|
|
20985
20919
|
var GLOBAL_SUBSCRIBERS_KEY5 = Symbol.for("agentv.piLogSubscribers");
|
|
20986
20920
|
function getPiLogStore() {
|
|
@@ -21032,24 +20966,47 @@ function subscribeToPiLogEntries(listener) {
|
|
|
21032
20966
|
store.delete(listener);
|
|
21033
20967
|
};
|
|
21034
20968
|
}
|
|
20969
|
+
function extractPiTextContent(content) {
|
|
20970
|
+
if (typeof content === "string") {
|
|
20971
|
+
return content;
|
|
20972
|
+
}
|
|
20973
|
+
if (!Array.isArray(content)) {
|
|
20974
|
+
return void 0;
|
|
20975
|
+
}
|
|
20976
|
+
const textParts = [];
|
|
20977
|
+
for (const part of content) {
|
|
20978
|
+
if (!part || typeof part !== "object") {
|
|
20979
|
+
continue;
|
|
20980
|
+
}
|
|
20981
|
+
const p = part;
|
|
20982
|
+
if (p.type === "text" && typeof p.text === "string") {
|
|
20983
|
+
textParts.push(p.text);
|
|
20984
|
+
}
|
|
20985
|
+
}
|
|
20986
|
+
return textParts.length > 0 ? textParts.join("\n") : void 0;
|
|
20987
|
+
}
|
|
20988
|
+
function toFiniteNumber(value) {
|
|
20989
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
20990
|
+
return void 0;
|
|
20991
|
+
}
|
|
21035
20992
|
var WORKSPACE_PREFIX = "agentv-pi-";
|
|
21036
20993
|
var PROMPT_FILENAME = "prompt.md";
|
|
21037
|
-
var
|
|
20994
|
+
var PiCliProvider = class {
|
|
21038
20995
|
id;
|
|
21039
|
-
kind = "pi-
|
|
20996
|
+
kind = "pi-cli";
|
|
21040
20997
|
targetName;
|
|
21041
20998
|
supportsBatch = false;
|
|
21042
20999
|
config;
|
|
21043
21000
|
runPi;
|
|
21044
21001
|
constructor(targetName, config, runner = defaultPiRunner) {
|
|
21045
|
-
this.id = `pi-
|
|
21002
|
+
this.id = `pi-cli:${targetName}`;
|
|
21046
21003
|
this.targetName = targetName;
|
|
21047
21004
|
this.config = config;
|
|
21048
21005
|
this.runPi = runner;
|
|
21049
21006
|
}
|
|
21050
21007
|
async invoke(request) {
|
|
21051
21008
|
if (request.signal?.aborted) {
|
|
21052
|
-
throw new Error("Pi
|
|
21009
|
+
throw new Error("Pi CLI request was aborted before execution");
|
|
21053
21010
|
}
|
|
21054
21011
|
const inputFiles = normalizeInputFiles(request.inputFiles);
|
|
21055
21012
|
const startTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -21059,17 +21016,17 @@ var PiCodingAgentProvider = class {
|
|
|
21059
21016
|
try {
|
|
21060
21017
|
const promptFile = path17.join(workspaceRoot, PROMPT_FILENAME);
|
|
21061
21018
|
await writeFile(promptFile, request.question, "utf8");
|
|
21062
|
-
const args = this.buildPiArgs(request.question, inputFiles
|
|
21019
|
+
const args = this.buildPiArgs(request.question, inputFiles);
|
|
21063
21020
|
const cwd = this.resolveCwd(workspaceRoot, request.cwd);
|
|
21064
21021
|
const result = await this.executePi(args, cwd, request.signal, logger);
|
|
21065
21022
|
if (result.timedOut) {
|
|
21066
21023
|
throw new Error(
|
|
21067
|
-
`Pi
|
|
21024
|
+
`Pi CLI timed out${formatTimeoutSuffix3(this.config.timeoutMs ?? void 0)}`
|
|
21068
21025
|
);
|
|
21069
21026
|
}
|
|
21070
21027
|
if (result.exitCode !== 0) {
|
|
21071
21028
|
const detail = pickDetail(result.stderr, result.stdout);
|
|
21072
|
-
const prefix = `Pi
|
|
21029
|
+
const prefix = `Pi CLI exited with code ${result.exitCode}`;
|
|
21073
21030
|
throw new Error(detail ? `${prefix}: ${detail}` : prefix);
|
|
21074
21031
|
}
|
|
21075
21032
|
const parsed = parsePiJsonl(result.stdout);
|
|
@@ -21126,10 +21083,10 @@ var PiCodingAgentProvider = class {
|
|
|
21126
21083
|
}
|
|
21127
21084
|
return path17.resolve(this.config.cwd);
|
|
21128
21085
|
}
|
|
21129
|
-
buildPiArgs(prompt, inputFiles
|
|
21086
|
+
buildPiArgs(prompt, inputFiles) {
|
|
21130
21087
|
const args = [];
|
|
21131
|
-
if (this.config.
|
|
21132
|
-
args.push("--provider", this.config.
|
|
21088
|
+
if (this.config.subprovider) {
|
|
21089
|
+
args.push("--provider", this.config.subprovider);
|
|
21133
21090
|
}
|
|
21134
21091
|
if (this.config.model) {
|
|
21135
21092
|
args.push("--model", this.config.model);
|
|
@@ -21178,7 +21135,7 @@ ${prompt}` : prompt;
|
|
|
21178
21135
|
const err = error;
|
|
21179
21136
|
if (err.code === "ENOENT") {
|
|
21180
21137
|
throw new Error(
|
|
21181
|
-
`Pi
|
|
21138
|
+
`Pi CLI executable '${this.config.executable}' was not found. Update the target executable or add it to PATH.`
|
|
21182
21139
|
);
|
|
21183
21140
|
}
|
|
21184
21141
|
throw error;
|
|
@@ -21187,27 +21144,19 @@ ${prompt}` : prompt;
|
|
|
21187
21144
|
buildEnv() {
|
|
21188
21145
|
const env = { ...process.env };
|
|
21189
21146
|
if (this.config.apiKey) {
|
|
21190
|
-
const provider = this.config.
|
|
21191
|
-
|
|
21192
|
-
|
|
21193
|
-
|
|
21194
|
-
|
|
21195
|
-
|
|
21196
|
-
|
|
21197
|
-
|
|
21198
|
-
|
|
21199
|
-
|
|
21200
|
-
|
|
21201
|
-
|
|
21202
|
-
|
|
21203
|
-
env.GROQ_API_KEY = this.config.apiKey;
|
|
21204
|
-
break;
|
|
21205
|
-
case "xai":
|
|
21206
|
-
env.XAI_API_KEY = this.config.apiKey;
|
|
21207
|
-
break;
|
|
21208
|
-
case "openrouter":
|
|
21209
|
-
env.OPENROUTER_API_KEY = this.config.apiKey;
|
|
21210
|
-
break;
|
|
21147
|
+
const provider = this.config.subprovider?.toLowerCase() ?? "google";
|
|
21148
|
+
const ENV_KEY_MAP = {
|
|
21149
|
+
google: "GEMINI_API_KEY",
|
|
21150
|
+
gemini: "GEMINI_API_KEY",
|
|
21151
|
+
anthropic: "ANTHROPIC_API_KEY",
|
|
21152
|
+
openai: "OPENAI_API_KEY",
|
|
21153
|
+
groq: "GROQ_API_KEY",
|
|
21154
|
+
xai: "XAI_API_KEY",
|
|
21155
|
+
openrouter: "OPENROUTER_API_KEY"
|
|
21156
|
+
};
|
|
21157
|
+
const envKey = ENV_KEY_MAP[provider];
|
|
21158
|
+
if (envKey) {
|
|
21159
|
+
env[envKey] = this.config.apiKey;
|
|
21211
21160
|
}
|
|
21212
21161
|
}
|
|
21213
21162
|
return env;
|
|
@@ -21225,7 +21174,7 @@ ${prompt}` : prompt;
|
|
|
21225
21174
|
if (this.config.logDir) {
|
|
21226
21175
|
return path17.resolve(this.config.logDir);
|
|
21227
21176
|
}
|
|
21228
|
-
return path17.join(process.cwd(), ".agentv", "logs", "pi-
|
|
21177
|
+
return path17.join(process.cwd(), ".agentv", "logs", "pi-cli");
|
|
21229
21178
|
}
|
|
21230
21179
|
async createStreamLogger(request) {
|
|
21231
21180
|
const logDir = this.resolveLogDirectory();
|
|
@@ -21277,7 +21226,7 @@ var PiStreamLogger = class _PiStreamLogger {
|
|
|
21277
21226
|
static async create(options) {
|
|
21278
21227
|
const logger = new _PiStreamLogger(options.filePath, options.format);
|
|
21279
21228
|
const header = [
|
|
21280
|
-
"# Pi
|
|
21229
|
+
"# Pi CLI stream log",
|
|
21281
21230
|
`# target: ${options.targetName}`,
|
|
21282
21231
|
options.evalCaseId ? `# eval: ${options.evalCaseId}` : void 0,
|
|
21283
21232
|
options.attempt !== void 0 ? `# attempt: ${options.attempt + 1}` : void 0,
|
|
@@ -21426,10 +21375,10 @@ function summarizePiEvent(event) {
|
|
|
21426
21375
|
return `${type}: ${role}`;
|
|
21427
21376
|
}
|
|
21428
21377
|
case "message_update": {
|
|
21429
|
-
const
|
|
21430
|
-
const eventType =
|
|
21378
|
+
const evt = record.assistantMessageEvent;
|
|
21379
|
+
const eventType = evt?.type;
|
|
21431
21380
|
if (eventType === "text_delta") {
|
|
21432
|
-
const delta =
|
|
21381
|
+
const delta = evt?.delta;
|
|
21433
21382
|
if (typeof delta === "string") {
|
|
21434
21383
|
const preview = delta.length > 50 ? `${delta.slice(0, 50)}...` : delta;
|
|
21435
21384
|
return `text_delta: ${preview}`;
|
|
@@ -21451,7 +21400,7 @@ function tryParseJsonValue(rawLine) {
|
|
|
21451
21400
|
function parsePiJsonl(output) {
|
|
21452
21401
|
const trimmed = output.trim();
|
|
21453
21402
|
if (trimmed.length === 0) {
|
|
21454
|
-
throw new Error("Pi
|
|
21403
|
+
throw new Error("Pi CLI produced no output");
|
|
21455
21404
|
}
|
|
21456
21405
|
const lines = trimmed.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
21457
21406
|
const parsed = [];
|
|
@@ -21462,131 +21411,646 @@ function parsePiJsonl(output) {
|
|
|
21462
21411
|
}
|
|
21463
21412
|
}
|
|
21464
21413
|
if (parsed.length === 0) {
|
|
21465
|
-
throw new Error("Pi
|
|
21414
|
+
throw new Error("Pi CLI produced no valid JSON output");
|
|
21466
21415
|
}
|
|
21467
21416
|
return parsed;
|
|
21468
21417
|
}
|
|
21469
21418
|
function extractMessages(events) {
|
|
21470
21419
|
for (let i = events.length - 1; i >= 0; i--) {
|
|
21471
21420
|
const event = events[i];
|
|
21472
|
-
if (!event || typeof event !== "object")
|
|
21473
|
-
continue;
|
|
21474
|
-
}
|
|
21421
|
+
if (!event || typeof event !== "object") continue;
|
|
21475
21422
|
const record = event;
|
|
21476
|
-
if (record.type !== "agent_end")
|
|
21477
|
-
continue;
|
|
21478
|
-
}
|
|
21423
|
+
if (record.type !== "agent_end") continue;
|
|
21479
21424
|
const messages = record.messages;
|
|
21480
|
-
if (!Array.isArray(messages))
|
|
21481
|
-
continue;
|
|
21482
|
-
}
|
|
21425
|
+
if (!Array.isArray(messages)) continue;
|
|
21483
21426
|
return messages.map(convertPiMessage).filter((m) => m !== void 0);
|
|
21484
21427
|
}
|
|
21485
21428
|
const output = [];
|
|
21486
21429
|
for (const event of events) {
|
|
21487
|
-
if (!event || typeof event !== "object")
|
|
21488
|
-
continue;
|
|
21489
|
-
}
|
|
21430
|
+
if (!event || typeof event !== "object") continue;
|
|
21490
21431
|
const record = event;
|
|
21491
21432
|
if (record.type === "turn_end") {
|
|
21492
|
-
const
|
|
21493
|
-
|
|
21494
|
-
|
|
21495
|
-
|
|
21433
|
+
const converted = convertPiMessage(record.message);
|
|
21434
|
+
if (converted) output.push(converted);
|
|
21435
|
+
}
|
|
21436
|
+
}
|
|
21437
|
+
return output;
|
|
21438
|
+
}
|
|
21439
|
+
function extractTokenUsage(events) {
|
|
21440
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
21441
|
+
const event = events[i];
|
|
21442
|
+
if (!event || typeof event !== "object") continue;
|
|
21443
|
+
const record = event;
|
|
21444
|
+
if (record.type !== "agent_end") continue;
|
|
21445
|
+
const usage = record.usage;
|
|
21446
|
+
if (usage && typeof usage === "object") {
|
|
21447
|
+
const u = usage;
|
|
21448
|
+
const input = toFiniteNumber(u.input_tokens ?? u.inputTokens ?? u.input);
|
|
21449
|
+
const output = toFiniteNumber(u.output_tokens ?? u.outputTokens ?? u.output);
|
|
21450
|
+
if (input !== void 0 || output !== void 0) {
|
|
21451
|
+
const result = { input: input ?? 0, output: output ?? 0 };
|
|
21452
|
+
const cached = toFiniteNumber(u.cache_read_input_tokens ?? u.cached ?? u.cachedTokens);
|
|
21453
|
+
const reasoning = toFiniteNumber(u.reasoning_tokens ?? u.reasoningTokens ?? u.reasoning);
|
|
21454
|
+
return {
|
|
21455
|
+
...result,
|
|
21456
|
+
...cached !== void 0 ? { cached } : {},
|
|
21457
|
+
...reasoning !== void 0 ? { reasoning } : {}
|
|
21458
|
+
};
|
|
21459
|
+
}
|
|
21460
|
+
}
|
|
21461
|
+
const messages = record.messages;
|
|
21462
|
+
if (Array.isArray(messages)) {
|
|
21463
|
+
return aggregateUsageFromMessages(messages);
|
|
21464
|
+
}
|
|
21465
|
+
}
|
|
21466
|
+
return void 0;
|
|
21467
|
+
}
|
|
21468
|
+
function aggregateUsageFromMessages(messages) {
|
|
21469
|
+
let totalInput = 0;
|
|
21470
|
+
let totalOutput = 0;
|
|
21471
|
+
let totalCached;
|
|
21472
|
+
let found = false;
|
|
21473
|
+
for (const msg of messages) {
|
|
21474
|
+
if (!msg || typeof msg !== "object") continue;
|
|
21475
|
+
const m = msg;
|
|
21476
|
+
const usage = m.usage;
|
|
21477
|
+
if (!usage || typeof usage !== "object") continue;
|
|
21478
|
+
const u = usage;
|
|
21479
|
+
const input = toFiniteNumber(u.input_tokens ?? u.inputTokens ?? u.input);
|
|
21480
|
+
const output = toFiniteNumber(u.output_tokens ?? u.outputTokens ?? u.output);
|
|
21481
|
+
if (input !== void 0 || output !== void 0) {
|
|
21482
|
+
found = true;
|
|
21483
|
+
totalInput += input ?? 0;
|
|
21484
|
+
totalOutput += output ?? 0;
|
|
21485
|
+
const cached = toFiniteNumber(u.cache_read_input_tokens ?? u.cached ?? u.cachedTokens);
|
|
21486
|
+
if (cached !== void 0) {
|
|
21487
|
+
totalCached = (totalCached ?? 0) + cached;
|
|
21496
21488
|
}
|
|
21497
21489
|
}
|
|
21498
21490
|
}
|
|
21499
|
-
return
|
|
21500
|
-
}
|
|
21501
|
-
|
|
21502
|
-
|
|
21503
|
-
|
|
21504
|
-
|
|
21491
|
+
if (!found) return void 0;
|
|
21492
|
+
const result = { input: totalInput, output: totalOutput };
|
|
21493
|
+
if (totalCached !== void 0) {
|
|
21494
|
+
return { ...result, cached: totalCached };
|
|
21495
|
+
}
|
|
21496
|
+
return result;
|
|
21497
|
+
}
|
|
21498
|
+
function convertPiMessage(message) {
|
|
21499
|
+
if (!message || typeof message !== "object") return void 0;
|
|
21500
|
+
const msg = message;
|
|
21501
|
+
const role = msg.role;
|
|
21502
|
+
if (typeof role !== "string") return void 0;
|
|
21503
|
+
const content = extractPiTextContent(msg.content);
|
|
21504
|
+
const toolCalls = extractToolCalls3(msg.content);
|
|
21505
|
+
const startTime = typeof msg.timestamp === "number" ? new Date(msg.timestamp).toISOString() : typeof msg.timestamp === "string" ? msg.timestamp : void 0;
|
|
21506
|
+
const metadata = {};
|
|
21507
|
+
if (msg.api) metadata.api = msg.api;
|
|
21508
|
+
if (msg.provider) metadata.provider = msg.provider;
|
|
21509
|
+
if (msg.model) metadata.model = msg.model;
|
|
21510
|
+
if (msg.usage) metadata.usage = msg.usage;
|
|
21511
|
+
if (msg.stopReason) metadata.stopReason = msg.stopReason;
|
|
21512
|
+
return {
|
|
21513
|
+
role,
|
|
21514
|
+
content,
|
|
21515
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
21516
|
+
startTime,
|
|
21517
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : void 0
|
|
21518
|
+
};
|
|
21519
|
+
}
|
|
21520
|
+
function extractToolCalls3(content) {
|
|
21521
|
+
if (!Array.isArray(content)) return [];
|
|
21522
|
+
const toolCalls = [];
|
|
21523
|
+
for (const part of content) {
|
|
21524
|
+
if (!part || typeof part !== "object") continue;
|
|
21525
|
+
const p = part;
|
|
21526
|
+
if (p.type === "tool_use" && typeof p.name === "string") {
|
|
21527
|
+
toolCalls.push({
|
|
21528
|
+
tool: p.name,
|
|
21529
|
+
input: p.input,
|
|
21530
|
+
id: typeof p.id === "string" ? p.id : void 0
|
|
21531
|
+
});
|
|
21532
|
+
}
|
|
21533
|
+
if (p.type === "toolCall" && typeof p.name === "string") {
|
|
21534
|
+
toolCalls.push({
|
|
21535
|
+
tool: p.name,
|
|
21536
|
+
input: p.arguments,
|
|
21537
|
+
id: typeof p.id === "string" ? p.id : void 0
|
|
21538
|
+
});
|
|
21539
|
+
}
|
|
21540
|
+
if (p.type === "tool_result" && typeof p.tool_use_id === "string") {
|
|
21541
|
+
const existing = toolCalls.find((tc) => tc.id === p.tool_use_id);
|
|
21542
|
+
if (existing) {
|
|
21543
|
+
const idx = toolCalls.indexOf(existing);
|
|
21544
|
+
toolCalls[idx] = { ...existing, output: p.content };
|
|
21545
|
+
}
|
|
21546
|
+
}
|
|
21547
|
+
}
|
|
21548
|
+
return toolCalls;
|
|
21549
|
+
}
|
|
21550
|
+
function escapeAtSymbols(prompt) {
|
|
21551
|
+
return prompt.replace(/@\[([^\]]+)\]:/g, "[[$1]]:");
|
|
21552
|
+
}
|
|
21553
|
+
function pickDetail(stderr, stdout) {
|
|
21554
|
+
const errorText = stderr.trim();
|
|
21555
|
+
if (errorText.length > 0) return errorText;
|
|
21556
|
+
const stdoutText = stdout.trim();
|
|
21557
|
+
return stdoutText.length > 0 ? stdoutText : void 0;
|
|
21558
|
+
}
|
|
21559
|
+
function formatTimeoutSuffix3(timeoutMs) {
|
|
21560
|
+
if (!timeoutMs || timeoutMs <= 0) return "";
|
|
21561
|
+
return ` after ${Math.ceil(timeoutMs / 1e3)}s`;
|
|
21562
|
+
}
|
|
21563
|
+
async function defaultPiRunner(options) {
|
|
21564
|
+
return await new Promise((resolve2, reject) => {
|
|
21565
|
+
const parts = options.executable.split(/\s+/);
|
|
21566
|
+
const executable = parts[0];
|
|
21567
|
+
const executableArgs = parts.slice(1);
|
|
21568
|
+
const allArgs = [...executableArgs, ...options.args];
|
|
21569
|
+
const child = spawn3(executable, allArgs, {
|
|
21570
|
+
cwd: options.cwd,
|
|
21571
|
+
env: options.env,
|
|
21572
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
21573
|
+
shell: false
|
|
21574
|
+
});
|
|
21575
|
+
let stdout = "";
|
|
21576
|
+
let stderr = "";
|
|
21577
|
+
let timedOut = false;
|
|
21578
|
+
const onAbort = () => {
|
|
21579
|
+
child.kill("SIGTERM");
|
|
21580
|
+
};
|
|
21581
|
+
if (options.signal) {
|
|
21582
|
+
if (options.signal.aborted) {
|
|
21583
|
+
onAbort();
|
|
21584
|
+
} else {
|
|
21585
|
+
options.signal.addEventListener("abort", onAbort, { once: true });
|
|
21586
|
+
}
|
|
21587
|
+
}
|
|
21588
|
+
let timeoutHandle;
|
|
21589
|
+
if (options.timeoutMs && options.timeoutMs > 0) {
|
|
21590
|
+
timeoutHandle = setTimeout(() => {
|
|
21591
|
+
timedOut = true;
|
|
21592
|
+
child.kill("SIGTERM");
|
|
21593
|
+
}, options.timeoutMs);
|
|
21594
|
+
timeoutHandle.unref?.();
|
|
21595
|
+
}
|
|
21596
|
+
child.stdout.setEncoding("utf8");
|
|
21597
|
+
child.stdout.on("data", (chunk) => {
|
|
21598
|
+
stdout += chunk;
|
|
21599
|
+
options.onStdoutChunk?.(chunk);
|
|
21600
|
+
});
|
|
21601
|
+
child.stderr.setEncoding("utf8");
|
|
21602
|
+
child.stderr.on("data", (chunk) => {
|
|
21603
|
+
stderr += chunk;
|
|
21604
|
+
options.onStderrChunk?.(chunk);
|
|
21605
|
+
});
|
|
21606
|
+
child.stdin.end();
|
|
21607
|
+
const cleanup = () => {
|
|
21608
|
+
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
21609
|
+
if (options.signal) options.signal.removeEventListener("abort", onAbort);
|
|
21610
|
+
};
|
|
21611
|
+
child.on("error", (error) => {
|
|
21612
|
+
cleanup();
|
|
21613
|
+
reject(error);
|
|
21614
|
+
});
|
|
21615
|
+
child.on("close", (code) => {
|
|
21616
|
+
cleanup();
|
|
21617
|
+
resolve2({
|
|
21618
|
+
stdout,
|
|
21619
|
+
stderr,
|
|
21620
|
+
exitCode: typeof code === "number" ? code : -1,
|
|
21621
|
+
timedOut
|
|
21622
|
+
});
|
|
21623
|
+
});
|
|
21624
|
+
});
|
|
21625
|
+
}
|
|
21626
|
+
var piCodingAgentModule = null;
|
|
21627
|
+
var piAiModule = null;
|
|
21628
|
+
async function promptInstall() {
|
|
21629
|
+
if (!process.stdout.isTTY) return false;
|
|
21630
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
21631
|
+
try {
|
|
21632
|
+
return await new Promise((resolve2) => {
|
|
21633
|
+
rl.question(
|
|
21634
|
+
"@mariozechner/pi-coding-agent is not installed. Install it now? (y/N) ",
|
|
21635
|
+
(answer) => resolve2(answer.trim().toLowerCase() === "y")
|
|
21636
|
+
);
|
|
21637
|
+
});
|
|
21638
|
+
} finally {
|
|
21639
|
+
rl.close();
|
|
21640
|
+
}
|
|
21641
|
+
}
|
|
21642
|
+
async function loadSdkModules() {
|
|
21643
|
+
if (!piCodingAgentModule || !piAiModule) {
|
|
21644
|
+
try {
|
|
21645
|
+
[piCodingAgentModule, piAiModule] = await Promise.all([
|
|
21646
|
+
import("@mariozechner/pi-coding-agent"),
|
|
21647
|
+
import("./dist-BOIN5LC5-T5UWUK43.js")
|
|
21648
|
+
]);
|
|
21649
|
+
} catch {
|
|
21650
|
+
if (await promptInstall()) {
|
|
21651
|
+
console.error("Installing @mariozechner/pi-coding-agent...");
|
|
21652
|
+
execSync("bun add @mariozechner/pi-coding-agent", { stdio: "inherit" });
|
|
21653
|
+
[piCodingAgentModule, piAiModule] = await Promise.all([
|
|
21654
|
+
import("@mariozechner/pi-coding-agent"),
|
|
21655
|
+
import("./dist-BOIN5LC5-T5UWUK43.js")
|
|
21656
|
+
]);
|
|
21657
|
+
} else {
|
|
21658
|
+
throw new Error(
|
|
21659
|
+
"pi-coding-agent SDK is not installed. Install it with:\n bun add @mariozechner/pi-coding-agent"
|
|
21660
|
+
);
|
|
21661
|
+
}
|
|
21662
|
+
}
|
|
21663
|
+
}
|
|
21664
|
+
const toolMap = {
|
|
21665
|
+
read: piCodingAgentModule.readTool,
|
|
21666
|
+
bash: piCodingAgentModule.bashTool,
|
|
21667
|
+
edit: piCodingAgentModule.editTool,
|
|
21668
|
+
write: piCodingAgentModule.writeTool,
|
|
21669
|
+
grep: piCodingAgentModule.grepTool,
|
|
21670
|
+
find: piCodingAgentModule.findTool,
|
|
21671
|
+
ls: piCodingAgentModule.lsTool
|
|
21672
|
+
};
|
|
21673
|
+
return {
|
|
21674
|
+
createAgentSession: piCodingAgentModule.createAgentSession,
|
|
21675
|
+
codingTools: piCodingAgentModule.codingTools,
|
|
21676
|
+
toolMap,
|
|
21677
|
+
SessionManager: piCodingAgentModule.SessionManager,
|
|
21678
|
+
getModel: piAiModule.getModel
|
|
21679
|
+
};
|
|
21680
|
+
}
|
|
21681
|
+
var PiCodingAgentProvider = class {
|
|
21682
|
+
id;
|
|
21683
|
+
kind = "pi-coding-agent";
|
|
21684
|
+
targetName;
|
|
21685
|
+
supportsBatch = false;
|
|
21686
|
+
config;
|
|
21687
|
+
constructor(targetName, config) {
|
|
21688
|
+
this.id = `pi-coding-agent:${targetName}`;
|
|
21689
|
+
this.targetName = targetName;
|
|
21690
|
+
this.config = config;
|
|
21691
|
+
}
|
|
21692
|
+
async invoke(request) {
|
|
21693
|
+
if (request.signal?.aborted) {
|
|
21694
|
+
throw new Error("Pi coding agent request was aborted before execution");
|
|
21695
|
+
}
|
|
21696
|
+
const inputFiles = normalizeInputFiles(request.inputFiles);
|
|
21697
|
+
const startTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
21698
|
+
const startMs = Date.now();
|
|
21699
|
+
const sdk = await loadSdkModules();
|
|
21700
|
+
const logger = await this.createStreamLogger(request).catch(() => void 0);
|
|
21701
|
+
try {
|
|
21702
|
+
const cwd = this.resolveCwd(request.cwd);
|
|
21703
|
+
const providerName = this.config.subprovider ?? "google";
|
|
21704
|
+
const modelId = this.config.model ?? "gemini-2.5-flash";
|
|
21705
|
+
this.setApiKeyEnv(providerName);
|
|
21706
|
+
const model = sdk.getModel(providerName, modelId);
|
|
21707
|
+
const tools = this.resolveTools(sdk);
|
|
21708
|
+
const { session } = await sdk.createAgentSession({
|
|
21709
|
+
cwd,
|
|
21710
|
+
model,
|
|
21711
|
+
tools,
|
|
21712
|
+
thinkingLevel: this.config.thinking,
|
|
21713
|
+
sessionManager: sdk.SessionManager.inMemory(cwd)
|
|
21714
|
+
});
|
|
21715
|
+
let tokenUsage;
|
|
21716
|
+
let costUsd;
|
|
21717
|
+
const toolTrackers = /* @__PURE__ */ new Map();
|
|
21718
|
+
const completedToolResults = /* @__PURE__ */ new Map();
|
|
21719
|
+
const unsubscribe = session.subscribe((event) => {
|
|
21720
|
+
logger?.handleEvent(event);
|
|
21721
|
+
switch (event.type) {
|
|
21722
|
+
case "message_end": {
|
|
21723
|
+
const msg = event.message;
|
|
21724
|
+
if (msg && typeof msg === "object" && "role" in msg && msg.role === "assistant" && "usage" in msg) {
|
|
21725
|
+
const usage = msg.usage;
|
|
21726
|
+
if (usage && typeof usage === "object") {
|
|
21727
|
+
const u = usage;
|
|
21728
|
+
const input = toFiniteNumber(u.input);
|
|
21729
|
+
const output = toFiniteNumber(u.output);
|
|
21730
|
+
const cached = toFiniteNumber(u.cacheRead);
|
|
21731
|
+
let callDelta;
|
|
21732
|
+
if (input !== void 0 || output !== void 0) {
|
|
21733
|
+
callDelta = {
|
|
21734
|
+
input: input ?? 0,
|
|
21735
|
+
output: output ?? 0,
|
|
21736
|
+
...cached !== void 0 ? { cached } : {}
|
|
21737
|
+
};
|
|
21738
|
+
tokenUsage = {
|
|
21739
|
+
input: (tokenUsage?.input ?? 0) + callDelta.input,
|
|
21740
|
+
output: (tokenUsage?.output ?? 0) + callDelta.output,
|
|
21741
|
+
...cached !== void 0 ? { cached: (tokenUsage?.cached ?? 0) + cached } : tokenUsage?.cached !== void 0 ? { cached: tokenUsage.cached } : {}
|
|
21742
|
+
};
|
|
21743
|
+
}
|
|
21744
|
+
const cost = u.cost;
|
|
21745
|
+
if (cost && typeof cost === "object") {
|
|
21746
|
+
const total = toFiniteNumber(cost.total);
|
|
21747
|
+
if (total !== void 0) {
|
|
21748
|
+
costUsd = (costUsd ?? 0) + total;
|
|
21749
|
+
}
|
|
21750
|
+
}
|
|
21751
|
+
request.streamCallbacks?.onLlmCallEnd?.(modelId, callDelta);
|
|
21752
|
+
}
|
|
21753
|
+
}
|
|
21754
|
+
break;
|
|
21755
|
+
}
|
|
21756
|
+
case "tool_execution_start": {
|
|
21757
|
+
toolTrackers.set(event.toolCallId, {
|
|
21758
|
+
toolCallId: event.toolCallId,
|
|
21759
|
+
toolName: event.toolName,
|
|
21760
|
+
args: event.args,
|
|
21761
|
+
startMs: Date.now(),
|
|
21762
|
+
startTime: (/* @__PURE__ */ new Date()).toISOString()
|
|
21763
|
+
});
|
|
21764
|
+
request.streamCallbacks?.onToolCallStart?.(event.toolName, event.toolCallId);
|
|
21765
|
+
break;
|
|
21766
|
+
}
|
|
21767
|
+
case "tool_execution_end": {
|
|
21768
|
+
const tracker = toolTrackers.get(event.toolCallId);
|
|
21769
|
+
const durationMs = tracker ? Date.now() - tracker.startMs : 0;
|
|
21770
|
+
completedToolResults.set(event.toolCallId, {
|
|
21771
|
+
output: event.result,
|
|
21772
|
+
durationMs
|
|
21773
|
+
});
|
|
21774
|
+
request.streamCallbacks?.onToolCallEnd?.(
|
|
21775
|
+
event.toolName,
|
|
21776
|
+
tracker?.args,
|
|
21777
|
+
event.result,
|
|
21778
|
+
durationMs,
|
|
21779
|
+
event.toolCallId
|
|
21780
|
+
);
|
|
21781
|
+
toolTrackers.delete(event.toolCallId);
|
|
21782
|
+
break;
|
|
21783
|
+
}
|
|
21784
|
+
}
|
|
21785
|
+
});
|
|
21786
|
+
try {
|
|
21787
|
+
const systemPrompt = this.config.systemPrompt;
|
|
21788
|
+
let prompt = request.question;
|
|
21789
|
+
if (systemPrompt) {
|
|
21790
|
+
prompt = `${systemPrompt}
|
|
21791
|
+
|
|
21792
|
+
${prompt}`;
|
|
21793
|
+
}
|
|
21794
|
+
if (inputFiles && inputFiles.length > 0) {
|
|
21795
|
+
const fileList = inputFiles.map((f) => `@${f}`).join("\n");
|
|
21796
|
+
prompt = `${prompt}
|
|
21797
|
+
|
|
21798
|
+
Files:
|
|
21799
|
+
${fileList}`;
|
|
21800
|
+
}
|
|
21801
|
+
if (this.config.timeoutMs) {
|
|
21802
|
+
const timeoutMs = this.config.timeoutMs;
|
|
21803
|
+
let timeoutId;
|
|
21804
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
21805
|
+
timeoutId = setTimeout(
|
|
21806
|
+
() => reject(
|
|
21807
|
+
new Error(`Pi coding agent timed out after ${Math.ceil(timeoutMs / 1e3)}s`)
|
|
21808
|
+
),
|
|
21809
|
+
timeoutMs
|
|
21810
|
+
);
|
|
21811
|
+
});
|
|
21812
|
+
try {
|
|
21813
|
+
await Promise.race([session.prompt(prompt), timeoutPromise]);
|
|
21814
|
+
} finally {
|
|
21815
|
+
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
21816
|
+
}
|
|
21817
|
+
} else {
|
|
21818
|
+
await session.prompt(prompt);
|
|
21819
|
+
}
|
|
21820
|
+
const agentMessages = session.agent.state.messages;
|
|
21821
|
+
const output = [];
|
|
21822
|
+
for (const msg of agentMessages) {
|
|
21823
|
+
output.push(convertAgentMessage(msg, toolTrackers, completedToolResults));
|
|
21824
|
+
}
|
|
21825
|
+
const endTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
21826
|
+
const durationMs = Date.now() - startMs;
|
|
21827
|
+
return {
|
|
21828
|
+
raw: {
|
|
21829
|
+
messages: agentMessages,
|
|
21830
|
+
model: this.config.model,
|
|
21831
|
+
provider: this.config.subprovider
|
|
21832
|
+
},
|
|
21833
|
+
output,
|
|
21834
|
+
tokenUsage,
|
|
21835
|
+
costUsd,
|
|
21836
|
+
durationMs,
|
|
21837
|
+
startTime,
|
|
21838
|
+
endTime
|
|
21839
|
+
};
|
|
21840
|
+
} finally {
|
|
21841
|
+
unsubscribe();
|
|
21842
|
+
session.dispose();
|
|
21843
|
+
}
|
|
21844
|
+
} finally {
|
|
21845
|
+
await logger?.close();
|
|
21846
|
+
}
|
|
21847
|
+
}
|
|
21848
|
+
/** Maps config apiKey to the provider-specific env var the SDK reads. */
|
|
21849
|
+
setApiKeyEnv(providerName) {
|
|
21850
|
+
if (!this.config.apiKey) return;
|
|
21851
|
+
const ENV_KEY_MAP = {
|
|
21852
|
+
google: "GEMINI_API_KEY",
|
|
21853
|
+
gemini: "GEMINI_API_KEY",
|
|
21854
|
+
anthropic: "ANTHROPIC_API_KEY",
|
|
21855
|
+
openai: "OPENAI_API_KEY",
|
|
21856
|
+
groq: "GROQ_API_KEY",
|
|
21857
|
+
xai: "XAI_API_KEY",
|
|
21858
|
+
openrouter: "OPENROUTER_API_KEY"
|
|
21859
|
+
};
|
|
21860
|
+
const envKey = ENV_KEY_MAP[providerName.toLowerCase()];
|
|
21861
|
+
if (envKey) {
|
|
21862
|
+
process.env[envKey] = this.config.apiKey;
|
|
21863
|
+
}
|
|
21864
|
+
}
|
|
21865
|
+
resolveCwd(cwdOverride) {
|
|
21866
|
+
if (cwdOverride) {
|
|
21867
|
+
return path18.resolve(cwdOverride);
|
|
21868
|
+
}
|
|
21869
|
+
if (this.config.cwd) {
|
|
21870
|
+
return path18.resolve(this.config.cwd);
|
|
21871
|
+
}
|
|
21872
|
+
return process.cwd();
|
|
21873
|
+
}
|
|
21874
|
+
resolveTools(sdk) {
|
|
21875
|
+
if (!this.config.tools) {
|
|
21876
|
+
return sdk.codingTools;
|
|
21877
|
+
}
|
|
21878
|
+
const toolNames = this.config.tools.split(",").map((t) => t.trim().toLowerCase());
|
|
21879
|
+
const selected = [];
|
|
21880
|
+
for (const name21 of toolNames) {
|
|
21881
|
+
if (name21 in sdk.toolMap) {
|
|
21882
|
+
selected.push(sdk.toolMap[name21]);
|
|
21883
|
+
}
|
|
21884
|
+
}
|
|
21885
|
+
return selected.length > 0 ? selected : sdk.codingTools;
|
|
21886
|
+
}
|
|
21887
|
+
resolveLogDirectory() {
|
|
21888
|
+
if (this.config.logDir) {
|
|
21889
|
+
return path18.resolve(this.config.logDir);
|
|
21890
|
+
}
|
|
21891
|
+
return path18.join(process.cwd(), ".agentv", "logs", "pi-coding-agent");
|
|
21892
|
+
}
|
|
21893
|
+
async createStreamLogger(request) {
|
|
21894
|
+
const logDir = this.resolveLogDirectory();
|
|
21895
|
+
if (!logDir) {
|
|
21896
|
+
return void 0;
|
|
21897
|
+
}
|
|
21898
|
+
try {
|
|
21899
|
+
await mkdir7(logDir, { recursive: true });
|
|
21900
|
+
} catch (error) {
|
|
21901
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
21902
|
+
console.warn(`Skipping Pi stream logging (could not create ${logDir}): ${message}`);
|
|
21903
|
+
return void 0;
|
|
21904
|
+
}
|
|
21905
|
+
const filePath = path18.join(logDir, buildLogFilename6(request, this.targetName));
|
|
21906
|
+
try {
|
|
21907
|
+
const logger = await PiStreamLogger2.create({
|
|
21908
|
+
filePath,
|
|
21909
|
+
targetName: this.targetName,
|
|
21910
|
+
evalCaseId: request.evalCaseId,
|
|
21911
|
+
attempt: request.attempt,
|
|
21912
|
+
format: this.config.logFormat ?? "summary"
|
|
21913
|
+
});
|
|
21914
|
+
recordPiLogEntry({
|
|
21915
|
+
filePath,
|
|
21916
|
+
targetName: this.targetName,
|
|
21917
|
+
evalCaseId: request.evalCaseId,
|
|
21918
|
+
attempt: request.attempt
|
|
21919
|
+
});
|
|
21920
|
+
return logger;
|
|
21921
|
+
} catch (error) {
|
|
21922
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
21923
|
+
console.warn(`Skipping Pi stream logging for ${filePath}: ${message}`);
|
|
21924
|
+
return void 0;
|
|
21925
|
+
}
|
|
21926
|
+
}
|
|
21927
|
+
};
|
|
21928
|
+
var PiStreamLogger2 = class _PiStreamLogger2 {
|
|
21929
|
+
filePath;
|
|
21930
|
+
stream;
|
|
21931
|
+
startedAt = Date.now();
|
|
21932
|
+
format;
|
|
21933
|
+
constructor(filePath, format) {
|
|
21934
|
+
this.filePath = filePath;
|
|
21935
|
+
this.format = format;
|
|
21936
|
+
this.stream = createWriteStream6(filePath, { flags: "a" });
|
|
21937
|
+
}
|
|
21938
|
+
static async create(options) {
|
|
21939
|
+
const logger = new _PiStreamLogger2(options.filePath, options.format);
|
|
21940
|
+
const header = [
|
|
21941
|
+
"# Pi Coding Agent stream log",
|
|
21942
|
+
`# target: ${options.targetName}`,
|
|
21943
|
+
options.evalCaseId ? `# eval: ${options.evalCaseId}` : void 0,
|
|
21944
|
+
options.attempt !== void 0 ? `# attempt: ${options.attempt + 1}` : void 0,
|
|
21945
|
+
`# started: ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
21946
|
+
""
|
|
21947
|
+
].filter((line) => Boolean(line));
|
|
21948
|
+
for (const line of header) {
|
|
21949
|
+
logger.stream.write(`${line}
|
|
21950
|
+
`);
|
|
21951
|
+
}
|
|
21952
|
+
return logger;
|
|
21953
|
+
}
|
|
21954
|
+
handleEvent(event) {
|
|
21955
|
+
if (!event || typeof event !== "object") return;
|
|
21505
21956
|
const record = event;
|
|
21506
|
-
|
|
21507
|
-
|
|
21508
|
-
|
|
21509
|
-
|
|
21510
|
-
|
|
21511
|
-
|
|
21512
|
-
if (input !== void 0 || output !== void 0) {
|
|
21513
|
-
const result = {
|
|
21514
|
-
input: input ?? 0,
|
|
21515
|
-
output: output ?? 0
|
|
21516
|
-
};
|
|
21517
|
-
const cached = toFiniteNumber(u.cache_read_input_tokens ?? u.cached ?? u.cachedTokens);
|
|
21518
|
-
const reasoning = toFiniteNumber(u.reasoning_tokens ?? u.reasoningTokens ?? u.reasoning);
|
|
21519
|
-
return {
|
|
21520
|
-
...result,
|
|
21521
|
-
...cached !== void 0 ? { cached } : {},
|
|
21522
|
-
...reasoning !== void 0 ? { reasoning } : {}
|
|
21523
|
-
};
|
|
21524
|
-
}
|
|
21525
|
-
}
|
|
21526
|
-
const messages = record.messages;
|
|
21527
|
-
if (Array.isArray(messages)) {
|
|
21528
|
-
return aggregateUsageFromMessages(messages);
|
|
21957
|
+
const type = typeof record.type === "string" ? record.type : void 0;
|
|
21958
|
+
if (!type) return;
|
|
21959
|
+
const message = this.format === "json" ? JSON.stringify(event, null, 2) : summarizeSdkEvent2(event);
|
|
21960
|
+
if (message) {
|
|
21961
|
+
this.stream.write(`[+${formatElapsed6(this.startedAt)}] ${message}
|
|
21962
|
+
`);
|
|
21529
21963
|
}
|
|
21530
21964
|
}
|
|
21531
|
-
|
|
21532
|
-
|
|
21533
|
-
|
|
21534
|
-
|
|
21535
|
-
|
|
21536
|
-
|
|
21537
|
-
|
|
21538
|
-
|
|
21539
|
-
|
|
21540
|
-
|
|
21541
|
-
|
|
21542
|
-
|
|
21543
|
-
|
|
21544
|
-
|
|
21545
|
-
|
|
21546
|
-
|
|
21547
|
-
|
|
21548
|
-
|
|
21549
|
-
|
|
21550
|
-
|
|
21551
|
-
|
|
21552
|
-
|
|
21553
|
-
}
|
|
21965
|
+
async close() {
|
|
21966
|
+
await new Promise((resolve2, reject) => {
|
|
21967
|
+
this.stream.once("error", reject);
|
|
21968
|
+
this.stream.end(() => resolve2());
|
|
21969
|
+
});
|
|
21970
|
+
}
|
|
21971
|
+
};
|
|
21972
|
+
function summarizeSdkEvent2(event) {
|
|
21973
|
+
if (!event || typeof event !== "object") return void 0;
|
|
21974
|
+
const record = event;
|
|
21975
|
+
const type = typeof record.type === "string" ? record.type : void 0;
|
|
21976
|
+
if (!type) return void 0;
|
|
21977
|
+
switch (type) {
|
|
21978
|
+
case "agent_start":
|
|
21979
|
+
case "agent_end":
|
|
21980
|
+
case "turn_start":
|
|
21981
|
+
case "turn_end":
|
|
21982
|
+
return type;
|
|
21983
|
+
case "message_start":
|
|
21984
|
+
case "message_end": {
|
|
21985
|
+
const msg = record.message;
|
|
21986
|
+
return `${type}: ${msg?.role ?? "unknown"}`;
|
|
21554
21987
|
}
|
|
21988
|
+
case "tool_execution_start":
|
|
21989
|
+
return `tool_start: ${record.toolName}`;
|
|
21990
|
+
case "tool_execution_end":
|
|
21991
|
+
return `tool_end: ${record.toolName}`;
|
|
21992
|
+
default:
|
|
21993
|
+
return type;
|
|
21555
21994
|
}
|
|
21556
|
-
|
|
21557
|
-
|
|
21558
|
-
|
|
21559
|
-
|
|
21995
|
+
}
|
|
21996
|
+
function buildLogFilename6(request, targetName) {
|
|
21997
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
21998
|
+
const evalId = sanitizeForFilename6(request.evalCaseId ?? "pi");
|
|
21999
|
+
const attemptSuffix = request.attempt !== void 0 ? `_attempt-${request.attempt + 1}` : "";
|
|
22000
|
+
const target = sanitizeForFilename6(targetName);
|
|
22001
|
+
return `${timestamp}_${target}_${evalId}${attemptSuffix}_${randomUUID8().slice(0, 8)}.log`;
|
|
22002
|
+
}
|
|
22003
|
+
function sanitizeForFilename6(value) {
|
|
22004
|
+
const sanitized = value.replace(/[^A-Za-z0-9._-]+/g, "_");
|
|
22005
|
+
return sanitized.length > 0 ? sanitized : "pi";
|
|
22006
|
+
}
|
|
22007
|
+
function formatElapsed6(startedAt) {
|
|
22008
|
+
const elapsedSeconds = Math.floor((Date.now() - startedAt) / 1e3);
|
|
22009
|
+
const hours = Math.floor(elapsedSeconds / 3600);
|
|
22010
|
+
const minutes = Math.floor(elapsedSeconds % 3600 / 60);
|
|
22011
|
+
const seconds = elapsedSeconds % 60;
|
|
22012
|
+
if (hours > 0) {
|
|
22013
|
+
return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
|
|
21560
22014
|
}
|
|
21561
|
-
return
|
|
22015
|
+
return `${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
|
|
21562
22016
|
}
|
|
21563
|
-
function
|
|
22017
|
+
function convertAgentMessage(message, toolTrackers, completedToolResults) {
|
|
21564
22018
|
if (!message || typeof message !== "object") {
|
|
21565
|
-
return
|
|
22019
|
+
return { role: "unknown", content: String(message) };
|
|
21566
22020
|
}
|
|
21567
22021
|
const msg = message;
|
|
21568
|
-
const role = msg.role;
|
|
21569
|
-
if (typeof role !== "string") {
|
|
21570
|
-
return void 0;
|
|
21571
|
-
}
|
|
22022
|
+
const role = typeof msg.role === "string" ? msg.role : "unknown";
|
|
21572
22023
|
const content = extractPiTextContent(msg.content);
|
|
21573
|
-
const toolCalls = extractToolCalls4(msg.content);
|
|
21574
|
-
const
|
|
22024
|
+
const toolCalls = extractToolCalls4(msg.content, toolTrackers, completedToolResults);
|
|
22025
|
+
const startTimeVal = typeof msg.timestamp === "number" ? new Date(msg.timestamp).toISOString() : typeof msg.timestamp === "string" ? msg.timestamp : void 0;
|
|
22026
|
+
let msgTokenUsage;
|
|
22027
|
+
if (msg.usage && typeof msg.usage === "object") {
|
|
22028
|
+
const u = msg.usage;
|
|
22029
|
+
const input = toFiniteNumber(u.input);
|
|
22030
|
+
const output = toFiniteNumber(u.output);
|
|
22031
|
+
if (input !== void 0 || output !== void 0) {
|
|
22032
|
+
msgTokenUsage = {
|
|
22033
|
+
input: input ?? 0,
|
|
22034
|
+
output: output ?? 0,
|
|
22035
|
+
...toFiniteNumber(u.cacheRead) !== void 0 ? { cached: toFiniteNumber(u.cacheRead) } : {}
|
|
22036
|
+
};
|
|
22037
|
+
}
|
|
22038
|
+
}
|
|
21575
22039
|
const metadata = {};
|
|
21576
22040
|
if (msg.api) metadata.api = msg.api;
|
|
21577
22041
|
if (msg.provider) metadata.provider = msg.provider;
|
|
21578
22042
|
if (msg.model) metadata.model = msg.model;
|
|
21579
|
-
if (msg.usage) metadata.usage = msg.usage;
|
|
21580
22043
|
if (msg.stopReason) metadata.stopReason = msg.stopReason;
|
|
21581
22044
|
return {
|
|
21582
22045
|
role,
|
|
21583
22046
|
content,
|
|
21584
22047
|
toolCalls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
21585
|
-
startTime,
|
|
21586
|
-
metadata: Object.keys(metadata).length > 0 ? metadata : void 0
|
|
22048
|
+
startTime: startTimeVal,
|
|
22049
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : void 0,
|
|
22050
|
+
tokenUsage: msgTokenUsage
|
|
21587
22051
|
};
|
|
21588
22052
|
}
|
|
21589
|
-
function extractToolCalls4(content) {
|
|
22053
|
+
function extractToolCalls4(content, toolTrackers, completedToolResults) {
|
|
21590
22054
|
if (!Array.isArray(content)) {
|
|
21591
22055
|
return [];
|
|
21592
22056
|
}
|
|
@@ -21596,118 +22060,23 @@ function extractToolCalls4(content) {
|
|
|
21596
22060
|
continue;
|
|
21597
22061
|
}
|
|
21598
22062
|
const p = part;
|
|
21599
|
-
if (p.type === "tool_use" && typeof p.name === "string") {
|
|
21600
|
-
toolCalls.push({
|
|
21601
|
-
tool: p.name,
|
|
21602
|
-
input: p.input,
|
|
21603
|
-
id: typeof p.id === "string" ? p.id : void 0
|
|
21604
|
-
});
|
|
21605
|
-
}
|
|
21606
22063
|
if (p.type === "toolCall" && typeof p.name === "string") {
|
|
22064
|
+
const id = typeof p.id === "string" ? p.id : void 0;
|
|
22065
|
+
const tracker = id ? toolTrackers.get(id) : void 0;
|
|
22066
|
+
const completed = id ? completedToolResults.get(id) : void 0;
|
|
21607
22067
|
toolCalls.push({
|
|
21608
22068
|
tool: p.name,
|
|
21609
22069
|
input: p.arguments,
|
|
21610
|
-
id
|
|
22070
|
+
id,
|
|
22071
|
+
output: completed?.output,
|
|
22072
|
+
durationMs: completed?.durationMs,
|
|
22073
|
+
startTime: tracker?.startTime,
|
|
22074
|
+
endTime: tracker?.startTime && completed?.durationMs !== void 0 ? new Date(new Date(tracker.startTime).getTime() + completed.durationMs).toISOString() : void 0
|
|
21611
22075
|
});
|
|
21612
22076
|
}
|
|
21613
|
-
if (p.type === "tool_result" && typeof p.tool_use_id === "string") {
|
|
21614
|
-
const existing = toolCalls.find((tc) => tc.id === p.tool_use_id);
|
|
21615
|
-
if (existing) {
|
|
21616
|
-
const idx = toolCalls.indexOf(existing);
|
|
21617
|
-
toolCalls[idx] = {
|
|
21618
|
-
...existing,
|
|
21619
|
-
output: p.content
|
|
21620
|
-
};
|
|
21621
|
-
}
|
|
21622
|
-
}
|
|
21623
22077
|
}
|
|
21624
22078
|
return toolCalls;
|
|
21625
22079
|
}
|
|
21626
|
-
function escapeAtSymbols(prompt) {
|
|
21627
|
-
return prompt.replace(/@\[([^\]]+)\]:/g, "[[$1]]:");
|
|
21628
|
-
}
|
|
21629
|
-
function pickDetail(stderr, stdout) {
|
|
21630
|
-
const errorText = stderr.trim();
|
|
21631
|
-
if (errorText.length > 0) {
|
|
21632
|
-
return errorText;
|
|
21633
|
-
}
|
|
21634
|
-
const stdoutText = stdout.trim();
|
|
21635
|
-
return stdoutText.length > 0 ? stdoutText : void 0;
|
|
21636
|
-
}
|
|
21637
|
-
function formatTimeoutSuffix3(timeoutMs) {
|
|
21638
|
-
if (!timeoutMs || timeoutMs <= 0) {
|
|
21639
|
-
return "";
|
|
21640
|
-
}
|
|
21641
|
-
const seconds = Math.ceil(timeoutMs / 1e3);
|
|
21642
|
-
return ` after ${seconds}s`;
|
|
21643
|
-
}
|
|
21644
|
-
async function defaultPiRunner(options) {
|
|
21645
|
-
return await new Promise((resolve2, reject) => {
|
|
21646
|
-
const parts = options.executable.split(/\s+/);
|
|
21647
|
-
const executable = parts[0];
|
|
21648
|
-
const executableArgs = parts.slice(1);
|
|
21649
|
-
const allArgs = [...executableArgs, ...options.args];
|
|
21650
|
-
const child = spawn3(executable, allArgs, {
|
|
21651
|
-
cwd: options.cwd,
|
|
21652
|
-
env: options.env,
|
|
21653
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
21654
|
-
shell: false
|
|
21655
|
-
});
|
|
21656
|
-
let stdout = "";
|
|
21657
|
-
let stderr = "";
|
|
21658
|
-
let timedOut = false;
|
|
21659
|
-
const onAbort = () => {
|
|
21660
|
-
child.kill("SIGTERM");
|
|
21661
|
-
};
|
|
21662
|
-
if (options.signal) {
|
|
21663
|
-
if (options.signal.aborted) {
|
|
21664
|
-
onAbort();
|
|
21665
|
-
} else {
|
|
21666
|
-
options.signal.addEventListener("abort", onAbort, { once: true });
|
|
21667
|
-
}
|
|
21668
|
-
}
|
|
21669
|
-
let timeoutHandle;
|
|
21670
|
-
if (options.timeoutMs && options.timeoutMs > 0) {
|
|
21671
|
-
timeoutHandle = setTimeout(() => {
|
|
21672
|
-
timedOut = true;
|
|
21673
|
-
child.kill("SIGTERM");
|
|
21674
|
-
}, options.timeoutMs);
|
|
21675
|
-
timeoutHandle.unref?.();
|
|
21676
|
-
}
|
|
21677
|
-
child.stdout.setEncoding("utf8");
|
|
21678
|
-
child.stdout.on("data", (chunk) => {
|
|
21679
|
-
stdout += chunk;
|
|
21680
|
-
options.onStdoutChunk?.(chunk);
|
|
21681
|
-
});
|
|
21682
|
-
child.stderr.setEncoding("utf8");
|
|
21683
|
-
child.stderr.on("data", (chunk) => {
|
|
21684
|
-
stderr += chunk;
|
|
21685
|
-
options.onStderrChunk?.(chunk);
|
|
21686
|
-
});
|
|
21687
|
-
child.stdin.end();
|
|
21688
|
-
const cleanup = () => {
|
|
21689
|
-
if (timeoutHandle) {
|
|
21690
|
-
clearTimeout(timeoutHandle);
|
|
21691
|
-
}
|
|
21692
|
-
if (options.signal) {
|
|
21693
|
-
options.signal.removeEventListener("abort", onAbort);
|
|
21694
|
-
}
|
|
21695
|
-
};
|
|
21696
|
-
child.on("error", (error) => {
|
|
21697
|
-
cleanup();
|
|
21698
|
-
reject(error);
|
|
21699
|
-
});
|
|
21700
|
-
child.on("close", (code) => {
|
|
21701
|
-
cleanup();
|
|
21702
|
-
resolve2({
|
|
21703
|
-
stdout,
|
|
21704
|
-
stderr,
|
|
21705
|
-
exitCode: typeof code === "number" ? code : -1,
|
|
21706
|
-
timedOut
|
|
21707
|
-
});
|
|
21708
|
-
});
|
|
21709
|
-
});
|
|
21710
|
-
}
|
|
21711
22080
|
var ProviderRegistry = class {
|
|
21712
22081
|
factories = /* @__PURE__ */ new Map();
|
|
21713
22082
|
/** Register a factory function for a provider kind. */
|
|
@@ -21750,13 +22119,13 @@ async function pathExists(target) {
|
|
|
21750
22119
|
}
|
|
21751
22120
|
}
|
|
21752
22121
|
async function ensureDir(target) {
|
|
21753
|
-
await
|
|
22122
|
+
await mkdir8(target, { recursive: true });
|
|
21754
22123
|
}
|
|
21755
22124
|
async function readDirEntries(target) {
|
|
21756
22125
|
const entries = await readdir(target, { withFileTypes: true });
|
|
21757
22126
|
return entries.map((entry) => ({
|
|
21758
22127
|
name: entry.name,
|
|
21759
|
-
absolutePath:
|
|
22128
|
+
absolutePath: path19.join(target, entry.name),
|
|
21760
22129
|
isDirectory: entry.isDirectory()
|
|
21761
22130
|
}));
|
|
21762
22131
|
}
|
|
@@ -21770,7 +22139,7 @@ async function removeIfExists(target) {
|
|
|
21770
22139
|
}
|
|
21771
22140
|
}
|
|
21772
22141
|
function pathToFileUri2(filePath) {
|
|
21773
|
-
const absolutePath =
|
|
22142
|
+
const absolutePath = path20.isAbsolute(filePath) ? filePath : path20.resolve(filePath);
|
|
21774
22143
|
const normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
21775
22144
|
if (/^[a-zA-Z]:\//.test(normalizedPath)) {
|
|
21776
22145
|
return `file:///${normalizedPath}`;
|
|
@@ -21862,8 +22231,8 @@ function createBatchRequestPrompt(userQuery, responseFileTmp, responseFileFinal,
|
|
|
21862
22231
|
});
|
|
21863
22232
|
}
|
|
21864
22233
|
function createBatchOrchestratorPrompt(requestFiles, responseFiles, templateContent) {
|
|
21865
|
-
const requestLines = requestFiles.map((file, index) => `${index + 1}. messages/${
|
|
21866
|
-
const responseList = responseFiles.map((file) => `"${
|
|
22234
|
+
const requestLines = requestFiles.map((file, index) => `${index + 1}. messages/${path21.basename(file)}`).join("\n");
|
|
22235
|
+
const responseList = responseFiles.map((file) => `"${path21.basename(file)}"`).join(", ");
|
|
21867
22236
|
return renderTemplate2(templateContent, {
|
|
21868
22237
|
requestFiles: requestLines,
|
|
21869
22238
|
responseList
|
|
@@ -21923,7 +22292,7 @@ async function waitForResponseOutput(responseFileFinal, pollInterval = 1e3, sile
|
|
|
21923
22292
|
}
|
|
21924
22293
|
async function waitForBatchResponses(responseFilesFinal, pollInterval = 1e3, silent = false, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
21925
22294
|
if (!silent) {
|
|
21926
|
-
const fileList = responseFilesFinal.map((file) =>
|
|
22295
|
+
const fileList = responseFilesFinal.map((file) => path222.basename(file)).join(", ");
|
|
21927
22296
|
console.error(`waiting for ${responseFilesFinal.length} batch response(s): ${fileList}`);
|
|
21928
22297
|
}
|
|
21929
22298
|
const deadline = Date.now() + timeoutMs;
|
|
@@ -21932,7 +22301,7 @@ async function waitForBatchResponses(responseFilesFinal, pollInterval = 1e3, sil
|
|
|
21932
22301
|
while (pending.size > 0) {
|
|
21933
22302
|
if (Date.now() >= deadline) {
|
|
21934
22303
|
if (!silent) {
|
|
21935
|
-
const remaining = [...pending].map((f) =>
|
|
22304
|
+
const remaining = [...pending].map((f) => path222.basename(f)).join(", ");
|
|
21936
22305
|
console.error(
|
|
21937
22306
|
`error: timed out after ${Math.round(timeoutMs / 1e3)}s waiting for batch responses. Still pending: ${remaining}`
|
|
21938
22307
|
);
|
|
@@ -21989,25 +22358,25 @@ function getAgentvHome() {
|
|
|
21989
22358
|
}
|
|
21990
22359
|
return envHome;
|
|
21991
22360
|
}
|
|
21992
|
-
return
|
|
22361
|
+
return path23.join(os2.homedir(), ".agentv");
|
|
21993
22362
|
}
|
|
21994
22363
|
function getWorkspacesRoot() {
|
|
21995
|
-
return
|
|
22364
|
+
return path23.join(getAgentvHome(), "workspaces");
|
|
21996
22365
|
}
|
|
21997
22366
|
function getSubagentsRoot() {
|
|
21998
|
-
return
|
|
22367
|
+
return path23.join(getAgentvHome(), "subagents");
|
|
21999
22368
|
}
|
|
22000
22369
|
function getTraceStateRoot() {
|
|
22001
|
-
return
|
|
22370
|
+
return path23.join(getAgentvHome(), "trace-state");
|
|
22002
22371
|
}
|
|
22003
22372
|
function getWorkspacePoolRoot() {
|
|
22004
|
-
return
|
|
22373
|
+
return path23.join(getAgentvHome(), "workspace-pool");
|
|
22005
22374
|
}
|
|
22006
22375
|
var DEFAULT_LOCK_NAME = "subagent.lock";
|
|
22007
22376
|
var DEFAULT_ALIVE_FILENAME = ".alive";
|
|
22008
22377
|
function getDefaultSubagentRoot(vscodeCmd = "code") {
|
|
22009
22378
|
const folder = vscodeCmd === "code-insiders" ? "vscode-insiders-agents" : "vscode-agents";
|
|
22010
|
-
return
|
|
22379
|
+
return path24.join(getSubagentsRoot(), folder);
|
|
22011
22380
|
}
|
|
22012
22381
|
var DEFAULT_SUBAGENT_ROOT = getDefaultSubagentRoot();
|
|
22013
22382
|
var execAsync2 = promisify2(exec);
|
|
@@ -22072,11 +22441,11 @@ async function ensureWorkspaceFocused(workspacePath, workspaceName, subagentDir,
|
|
|
22072
22441
|
await raceSpawnError(child);
|
|
22073
22442
|
return true;
|
|
22074
22443
|
}
|
|
22075
|
-
const aliveFile =
|
|
22444
|
+
const aliveFile = path25.join(subagentDir, DEFAULT_ALIVE_FILENAME);
|
|
22076
22445
|
await removeIfExists(aliveFile);
|
|
22077
|
-
const githubAgentsDir =
|
|
22078
|
-
await
|
|
22079
|
-
const wakeupDst =
|
|
22446
|
+
const githubAgentsDir = path25.join(subagentDir, ".github", "agents");
|
|
22447
|
+
await mkdir9(githubAgentsDir, { recursive: true });
|
|
22448
|
+
const wakeupDst = path25.join(githubAgentsDir, "wakeup.md");
|
|
22080
22449
|
await writeFile2(wakeupDst, DEFAULT_WAKEUP_CONTENT, "utf8");
|
|
22081
22450
|
const workspaceChild = spawnVsCode(vscodeCmd, [workspacePath], {
|
|
22082
22451
|
label: "open-workspace"
|
|
@@ -22089,7 +22458,7 @@ async function ensureWorkspaceFocused(workspacePath, workspaceName, subagentDir,
|
|
|
22089
22458
|
"chat",
|
|
22090
22459
|
"-m",
|
|
22091
22460
|
wakeupChatId,
|
|
22092
|
-
`create a file named .alive in the ${
|
|
22461
|
+
`create a file named .alive in the ${path25.basename(subagentDir)} folder`
|
|
22093
22462
|
];
|
|
22094
22463
|
const wakeupChild = spawnVsCode(vscodeCmd, chatArgs, { label: "send-wakeup-chat" });
|
|
22095
22464
|
await raceSpawnError(wakeupChild);
|
|
@@ -22104,10 +22473,10 @@ async function ensureWorkspaceFocused(workspacePath, workspaceName, subagentDir,
|
|
|
22104
22473
|
return true;
|
|
22105
22474
|
}
|
|
22106
22475
|
async function launchVsCodeWithChat(subagentDir, chatId, attachmentPaths, requestInstructions, timestamp, vscodeCmd) {
|
|
22107
|
-
const workspacePath =
|
|
22108
|
-
const messagesDir =
|
|
22109
|
-
await
|
|
22110
|
-
const reqFile =
|
|
22476
|
+
const workspacePath = path25.join(subagentDir, `${path25.basename(subagentDir)}.code-workspace`);
|
|
22477
|
+
const messagesDir = path25.join(subagentDir, "messages");
|
|
22478
|
+
await mkdir9(messagesDir, { recursive: true });
|
|
22479
|
+
const reqFile = path25.join(messagesDir, `${timestamp}_req.md`);
|
|
22111
22480
|
await writeFile2(reqFile, requestInstructions, { encoding: "utf8" });
|
|
22112
22481
|
const reqUri = pathToFileUri2(reqFile);
|
|
22113
22482
|
const chatArgs = ["-r", "chat", "-m", chatId];
|
|
@@ -22115,16 +22484,16 @@ async function launchVsCodeWithChat(subagentDir, chatId, attachmentPaths, reques
|
|
|
22115
22484
|
chatArgs.push("-a", attachment);
|
|
22116
22485
|
}
|
|
22117
22486
|
chatArgs.push("-a", reqFile);
|
|
22118
|
-
chatArgs.push(`Follow instructions in [${
|
|
22487
|
+
chatArgs.push(`Follow instructions in [${path25.basename(reqFile)}](${reqUri})`);
|
|
22119
22488
|
const workspaceReady = await ensureWorkspaceFocused(
|
|
22120
22489
|
workspacePath,
|
|
22121
|
-
|
|
22490
|
+
path25.basename(subagentDir),
|
|
22122
22491
|
subagentDir,
|
|
22123
22492
|
vscodeCmd
|
|
22124
22493
|
);
|
|
22125
22494
|
if (!workspaceReady) {
|
|
22126
22495
|
throw new Error(
|
|
22127
|
-
`VS Code workspace '${
|
|
22496
|
+
`VS Code workspace '${path25.basename(subagentDir)}' failed to become ready within the timeout. Check that '${vscodeCmd}' can open workspaces.`
|
|
22128
22497
|
);
|
|
22129
22498
|
}
|
|
22130
22499
|
await sleep2(500);
|
|
@@ -22132,9 +22501,9 @@ async function launchVsCodeWithChat(subagentDir, chatId, attachmentPaths, reques
|
|
|
22132
22501
|
await raceSpawnError(child);
|
|
22133
22502
|
}
|
|
22134
22503
|
async function launchVsCodeWithBatchChat(subagentDir, chatId, attachmentPaths, chatInstruction, vscodeCmd) {
|
|
22135
|
-
const workspacePath =
|
|
22136
|
-
const messagesDir =
|
|
22137
|
-
await
|
|
22504
|
+
const workspacePath = path25.join(subagentDir, `${path25.basename(subagentDir)}.code-workspace`);
|
|
22505
|
+
const messagesDir = path25.join(subagentDir, "messages");
|
|
22506
|
+
await mkdir9(messagesDir, { recursive: true });
|
|
22138
22507
|
const chatArgs = ["-r", "chat", "-m", chatId];
|
|
22139
22508
|
for (const attachment of attachmentPaths) {
|
|
22140
22509
|
chatArgs.push("-a", attachment);
|
|
@@ -22142,13 +22511,13 @@ async function launchVsCodeWithBatchChat(subagentDir, chatId, attachmentPaths, c
|
|
|
22142
22511
|
chatArgs.push(chatInstruction);
|
|
22143
22512
|
const workspaceReady = await ensureWorkspaceFocused(
|
|
22144
22513
|
workspacePath,
|
|
22145
|
-
|
|
22514
|
+
path25.basename(subagentDir),
|
|
22146
22515
|
subagentDir,
|
|
22147
22516
|
vscodeCmd
|
|
22148
22517
|
);
|
|
22149
22518
|
if (!workspaceReady) {
|
|
22150
22519
|
throw new Error(
|
|
22151
|
-
`VS Code workspace '${
|
|
22520
|
+
`VS Code workspace '${path25.basename(subagentDir)}' failed to become ready within the timeout. Check that '${vscodeCmd}' can open workspaces.`
|
|
22152
22521
|
);
|
|
22153
22522
|
}
|
|
22154
22523
|
await sleep2(500);
|
|
@@ -22170,10 +22539,10 @@ function transformWorkspacePaths(workspaceContent, templateDir) {
|
|
|
22170
22539
|
}
|
|
22171
22540
|
const transformedFolders = workspace.folders.map((folder) => {
|
|
22172
22541
|
const folderPath = folder.path;
|
|
22173
|
-
if (
|
|
22542
|
+
if (path26.isAbsolute(folderPath)) {
|
|
22174
22543
|
return folder;
|
|
22175
22544
|
}
|
|
22176
|
-
const absolutePath =
|
|
22545
|
+
const absolutePath = path26.resolve(templateDir, folderPath);
|
|
22177
22546
|
return {
|
|
22178
22547
|
...folder,
|
|
22179
22548
|
path: absolutePath
|
|
@@ -22195,19 +22564,19 @@ function transformWorkspacePaths(workspaceContent, templateDir) {
|
|
|
22195
22564
|
if (locationMap && typeof locationMap === "object") {
|
|
22196
22565
|
const transformedMap = {};
|
|
22197
22566
|
for (const [locationPath, value] of Object.entries(locationMap)) {
|
|
22198
|
-
const isAbsolute =
|
|
22567
|
+
const isAbsolute = path26.isAbsolute(locationPath);
|
|
22199
22568
|
if (isAbsolute) {
|
|
22200
22569
|
transformedMap[locationPath] = value;
|
|
22201
22570
|
} else {
|
|
22202
22571
|
const firstGlobIndex = locationPath.search(/[*]/);
|
|
22203
22572
|
if (firstGlobIndex === -1) {
|
|
22204
|
-
const resolvedPath =
|
|
22573
|
+
const resolvedPath = path26.resolve(templateDir, locationPath).replace(/\\/g, "/");
|
|
22205
22574
|
transformedMap[resolvedPath] = value;
|
|
22206
22575
|
} else {
|
|
22207
22576
|
const basePathEnd = locationPath.lastIndexOf("/", firstGlobIndex);
|
|
22208
22577
|
const basePath = basePathEnd !== -1 ? locationPath.substring(0, basePathEnd) : ".";
|
|
22209
22578
|
const patternPath = locationPath.substring(basePathEnd !== -1 ? basePathEnd : 0);
|
|
22210
|
-
const resolvedPath = (
|
|
22579
|
+
const resolvedPath = (path26.resolve(templateDir, basePath) + patternPath).replace(
|
|
22211
22580
|
/\\/g,
|
|
22212
22581
|
"/"
|
|
22213
22582
|
);
|
|
@@ -22246,7 +22615,7 @@ async function findUnlockedSubagent(subagentRoot) {
|
|
|
22246
22615
|
number: Number.parseInt(entry.name.split("-")[1] ?? "", 10)
|
|
22247
22616
|
})).filter((entry) => Number.isInteger(entry.number)).sort((a, b) => a.number - b.number);
|
|
22248
22617
|
for (const subagent of subagents) {
|
|
22249
|
-
const lockFile =
|
|
22618
|
+
const lockFile = path27.join(subagent.absolutePath, DEFAULT_LOCK_NAME);
|
|
22250
22619
|
if (!await pathExists(lockFile)) {
|
|
22251
22620
|
return subagent.absolutePath;
|
|
22252
22621
|
}
|
|
@@ -22256,7 +22625,7 @@ async function findUnlockedSubagent(subagentRoot) {
|
|
|
22256
22625
|
async function copyAgentConfig(subagentDir, workspaceTemplate, cwd) {
|
|
22257
22626
|
let workspaceContent;
|
|
22258
22627
|
if (workspaceTemplate) {
|
|
22259
|
-
const workspaceSrc =
|
|
22628
|
+
const workspaceSrc = path27.resolve(workspaceTemplate);
|
|
22260
22629
|
if (!await pathExists(workspaceSrc)) {
|
|
22261
22630
|
throw new Error(`workspace template not found: ${workspaceSrc}`);
|
|
22262
22631
|
}
|
|
@@ -22269,13 +22638,13 @@ async function copyAgentConfig(subagentDir, workspaceTemplate, cwd) {
|
|
|
22269
22638
|
} else {
|
|
22270
22639
|
workspaceContent = DEFAULT_WORKSPACE_TEMPLATE;
|
|
22271
22640
|
}
|
|
22272
|
-
const workspaceName = `${
|
|
22273
|
-
const workspaceDst =
|
|
22274
|
-
const templateDir = workspaceTemplate ?
|
|
22641
|
+
const workspaceName = `${path27.basename(subagentDir)}.code-workspace`;
|
|
22642
|
+
const workspaceDst = path27.join(subagentDir, workspaceName);
|
|
22643
|
+
const templateDir = workspaceTemplate ? path27.dirname(path27.resolve(workspaceTemplate)) : subagentDir;
|
|
22275
22644
|
const workspaceJson = JSON.stringify(workspaceContent, null, 2);
|
|
22276
22645
|
let transformedContent = transformWorkspacePaths(workspaceJson, templateDir);
|
|
22277
22646
|
if (cwd) {
|
|
22278
|
-
const absCwd =
|
|
22647
|
+
const absCwd = path27.resolve(cwd);
|
|
22279
22648
|
const parsed = JSON.parse(transformedContent);
|
|
22280
22649
|
const alreadyPresent = parsed.folders.some((f) => f.path === absCwd);
|
|
22281
22650
|
if (!alreadyPresent) {
|
|
@@ -22284,35 +22653,35 @@ async function copyAgentConfig(subagentDir, workspaceTemplate, cwd) {
|
|
|
22284
22653
|
}
|
|
22285
22654
|
}
|
|
22286
22655
|
await writeFile3(workspaceDst, transformedContent, "utf8");
|
|
22287
|
-
const messagesDir =
|
|
22288
|
-
await
|
|
22656
|
+
const messagesDir = path27.join(subagentDir, "messages");
|
|
22657
|
+
await mkdir10(messagesDir, { recursive: true });
|
|
22289
22658
|
return { workspace: workspaceDst, messagesDir };
|
|
22290
22659
|
}
|
|
22291
22660
|
async function createSubagentLock(subagentDir) {
|
|
22292
|
-
const messagesDir =
|
|
22661
|
+
const messagesDir = path27.join(subagentDir, "messages");
|
|
22293
22662
|
if (await pathExists(messagesDir)) {
|
|
22294
22663
|
const files = await readdir2(messagesDir);
|
|
22295
22664
|
await Promise.all(
|
|
22296
22665
|
files.map(async (file) => {
|
|
22297
|
-
const target =
|
|
22666
|
+
const target = path27.join(messagesDir, file);
|
|
22298
22667
|
await removeIfExists(target);
|
|
22299
22668
|
})
|
|
22300
22669
|
);
|
|
22301
22670
|
}
|
|
22302
|
-
const githubAgentsDir =
|
|
22671
|
+
const githubAgentsDir = path27.join(subagentDir, ".github", "agents");
|
|
22303
22672
|
if (await pathExists(githubAgentsDir)) {
|
|
22304
22673
|
const agentFiles = await readdir2(githubAgentsDir);
|
|
22305
22674
|
const preservedFiles = /* @__PURE__ */ new Set(["wakeup.md", "subagent.md"]);
|
|
22306
22675
|
await Promise.all(
|
|
22307
|
-
agentFiles.filter((file) => file.endsWith(".md") && !preservedFiles.has(file)).map((file) => removeIfExists(
|
|
22676
|
+
agentFiles.filter((file) => file.endsWith(".md") && !preservedFiles.has(file)).map((file) => removeIfExists(path27.join(githubAgentsDir, file)))
|
|
22308
22677
|
);
|
|
22309
22678
|
}
|
|
22310
|
-
const lockFile =
|
|
22679
|
+
const lockFile = path27.join(subagentDir, DEFAULT_LOCK_NAME);
|
|
22311
22680
|
await writeFile3(lockFile, "", { encoding: "utf8" });
|
|
22312
22681
|
return lockFile;
|
|
22313
22682
|
}
|
|
22314
22683
|
async function removeSubagentLock(subagentDir) {
|
|
22315
|
-
const lockFile =
|
|
22684
|
+
const lockFile = path27.join(subagentDir, DEFAULT_LOCK_NAME);
|
|
22316
22685
|
await removeIfExists(lockFile);
|
|
22317
22686
|
}
|
|
22318
22687
|
async function prepareSubagentDirectory(subagentDir, promptFile, chatId, workspaceTemplate, dryRun, cwd) {
|
|
@@ -22332,9 +22701,9 @@ async function prepareSubagentDirectory(subagentDir, promptFile, chatId, workspa
|
|
|
22332
22701
|
return 1;
|
|
22333
22702
|
}
|
|
22334
22703
|
if (promptFile) {
|
|
22335
|
-
const githubAgentsDir =
|
|
22336
|
-
await
|
|
22337
|
-
const agentFile =
|
|
22704
|
+
const githubAgentsDir = path27.join(subagentDir, ".github", "agents");
|
|
22705
|
+
await mkdir10(githubAgentsDir, { recursive: true });
|
|
22706
|
+
const agentFile = path27.join(githubAgentsDir, `${chatId}.md`);
|
|
22338
22707
|
try {
|
|
22339
22708
|
await copyFile(promptFile, agentFile);
|
|
22340
22709
|
} catch (error) {
|
|
@@ -22351,7 +22720,7 @@ async function resolvePromptFile(promptFile) {
|
|
|
22351
22720
|
if (!promptFile) {
|
|
22352
22721
|
return void 0;
|
|
22353
22722
|
}
|
|
22354
|
-
const resolvedPrompt =
|
|
22723
|
+
const resolvedPrompt = path28.resolve(promptFile);
|
|
22355
22724
|
if (!await pathExists(resolvedPrompt)) {
|
|
22356
22725
|
throw new Error(`Prompt file not found: ${resolvedPrompt}`);
|
|
22357
22726
|
}
|
|
@@ -22367,7 +22736,7 @@ async function resolveAttachments(extraAttachments) {
|
|
|
22367
22736
|
}
|
|
22368
22737
|
const resolved = [];
|
|
22369
22738
|
for (const attachment of extraAttachments) {
|
|
22370
|
-
const resolvedPath =
|
|
22739
|
+
const resolvedPath = path28.resolve(attachment);
|
|
22371
22740
|
if (!await pathExists(resolvedPath)) {
|
|
22372
22741
|
throw new Error(`Attachment not found: ${resolvedPath}`);
|
|
22373
22742
|
}
|
|
@@ -22409,7 +22778,7 @@ async function dispatchAgentSession(options) {
|
|
|
22409
22778
|
error: "No unlocked subagents available. Provision additional subagents with: subagent code provision --subagents <desired_total>"
|
|
22410
22779
|
};
|
|
22411
22780
|
}
|
|
22412
|
-
const subagentName =
|
|
22781
|
+
const subagentName = path28.basename(subagentDir);
|
|
22413
22782
|
const chatId = Math.random().toString(16).slice(2, 10);
|
|
22414
22783
|
const preparationResult = await prepareSubagentDirectory(
|
|
22415
22784
|
subagentDir,
|
|
@@ -22437,9 +22806,9 @@ async function dispatchAgentSession(options) {
|
|
|
22437
22806
|
};
|
|
22438
22807
|
}
|
|
22439
22808
|
const timestamp = generateTimestamp();
|
|
22440
|
-
const messagesDir =
|
|
22441
|
-
const responseFileTmp =
|
|
22442
|
-
const responseFileFinal =
|
|
22809
|
+
const messagesDir = path28.join(subagentDir, "messages");
|
|
22810
|
+
const responseFileTmp = path28.join(messagesDir, `${timestamp}_res.tmp.md`);
|
|
22811
|
+
const responseFileFinal = path28.join(messagesDir, `${timestamp}_res.md`);
|
|
22443
22812
|
const requestInstructions = createRequestPrompt(
|
|
22444
22813
|
userQuery,
|
|
22445
22814
|
responseFileTmp,
|
|
@@ -22544,7 +22913,7 @@ async function dispatchBatchAgent(options) {
|
|
|
22544
22913
|
error: "No unlocked subagents available. Provision additional subagents with: subagent code provision --subagents <desired_total>"
|
|
22545
22914
|
};
|
|
22546
22915
|
}
|
|
22547
|
-
subagentName =
|
|
22916
|
+
subagentName = path28.basename(subagentDir);
|
|
22548
22917
|
const chatId = Math.random().toString(16).slice(2, 10);
|
|
22549
22918
|
const preparationResult = await prepareSubagentDirectory(
|
|
22550
22919
|
subagentDir,
|
|
@@ -22575,17 +22944,17 @@ async function dispatchBatchAgent(options) {
|
|
|
22575
22944
|
};
|
|
22576
22945
|
}
|
|
22577
22946
|
const timestamp = generateTimestamp();
|
|
22578
|
-
const messagesDir =
|
|
22947
|
+
const messagesDir = path28.join(subagentDir, "messages");
|
|
22579
22948
|
requestFiles = userQueries.map(
|
|
22580
|
-
(_, index) =>
|
|
22949
|
+
(_, index) => path28.join(messagesDir, `${timestamp}_${index}_req.md`)
|
|
22581
22950
|
);
|
|
22582
22951
|
const responseTmpFiles = userQueries.map(
|
|
22583
|
-
(_, index) =>
|
|
22952
|
+
(_, index) => path28.join(messagesDir, `${timestamp}_${index}_res.tmp.md`)
|
|
22584
22953
|
);
|
|
22585
22954
|
responseFilesFinal = userQueries.map(
|
|
22586
|
-
(_, index) =>
|
|
22955
|
+
(_, index) => path28.join(messagesDir, `${timestamp}_${index}_res.md`)
|
|
22587
22956
|
);
|
|
22588
|
-
const orchestratorFile =
|
|
22957
|
+
const orchestratorFile = path28.join(messagesDir, `${timestamp}_orchestrator.md`);
|
|
22589
22958
|
if (!dryRun) {
|
|
22590
22959
|
await Promise.all(
|
|
22591
22960
|
userQueries.map((query, index) => {
|
|
@@ -22698,7 +23067,7 @@ async function provisionSubagents(options) {
|
|
|
22698
23067
|
if (!Number.isInteger(subagents) || subagents < 1) {
|
|
22699
23068
|
throw new Error("subagents must be a positive integer");
|
|
22700
23069
|
}
|
|
22701
|
-
const targetPath =
|
|
23070
|
+
const targetPath = path29.resolve(targetRoot);
|
|
22702
23071
|
if (!dryRun) {
|
|
22703
23072
|
await ensureDir(targetPath);
|
|
22704
23073
|
}
|
|
@@ -22718,7 +23087,7 @@ async function provisionSubagents(options) {
|
|
|
22718
23087
|
continue;
|
|
22719
23088
|
}
|
|
22720
23089
|
highestNumber = Math.max(highestNumber, parsed);
|
|
22721
|
-
const lockFile =
|
|
23090
|
+
const lockFile = path29.join(entry.absolutePath, lockName);
|
|
22722
23091
|
const locked = await pathExists(lockFile);
|
|
22723
23092
|
if (locked) {
|
|
22724
23093
|
lockedSubagents.add(entry.absolutePath);
|
|
@@ -22735,10 +23104,10 @@ async function provisionSubagents(options) {
|
|
|
22735
23104
|
break;
|
|
22736
23105
|
}
|
|
22737
23106
|
const subagentDir = subagent.absolutePath;
|
|
22738
|
-
const githubAgentsDir =
|
|
22739
|
-
const lockFile =
|
|
22740
|
-
const workspaceDst =
|
|
22741
|
-
const wakeupDst =
|
|
23107
|
+
const githubAgentsDir = path29.join(subagentDir, ".github", "agents");
|
|
23108
|
+
const lockFile = path29.join(subagentDir, lockName);
|
|
23109
|
+
const workspaceDst = path29.join(subagentDir, `${path29.basename(subagentDir)}.code-workspace`);
|
|
23110
|
+
const wakeupDst = path29.join(githubAgentsDir, "wakeup.md");
|
|
22742
23111
|
const isLocked = await pathExists(lockFile);
|
|
22743
23112
|
if (isLocked && !force) {
|
|
22744
23113
|
continue;
|
|
@@ -22776,10 +23145,10 @@ async function provisionSubagents(options) {
|
|
|
22776
23145
|
let nextIndex = highestNumber;
|
|
22777
23146
|
while (subagentsProvisioned < subagents) {
|
|
22778
23147
|
nextIndex += 1;
|
|
22779
|
-
const subagentDir =
|
|
22780
|
-
const githubAgentsDir =
|
|
22781
|
-
const workspaceDst =
|
|
22782
|
-
const wakeupDst =
|
|
23148
|
+
const subagentDir = path29.join(targetPath, `subagent-${nextIndex}`);
|
|
23149
|
+
const githubAgentsDir = path29.join(subagentDir, ".github", "agents");
|
|
23150
|
+
const workspaceDst = path29.join(subagentDir, `${path29.basename(subagentDir)}.code-workspace`);
|
|
23151
|
+
const wakeupDst = path29.join(githubAgentsDir, "wakeup.md");
|
|
22783
23152
|
if (!dryRun) {
|
|
22784
23153
|
await ensureDir(subagentDir);
|
|
22785
23154
|
await ensureDir(githubAgentsDir);
|
|
@@ -22965,7 +23334,7 @@ var VSCodeProvider = class {
|
|
|
22965
23334
|
async function locateVSCodeExecutable(candidate) {
|
|
22966
23335
|
const includesPathSeparator = candidate.includes("/") || candidate.includes("\\");
|
|
22967
23336
|
if (includesPathSeparator) {
|
|
22968
|
-
const resolved =
|
|
23337
|
+
const resolved = path30.isAbsolute(candidate) ? candidate : path30.resolve(candidate);
|
|
22969
23338
|
try {
|
|
22970
23339
|
await access3(resolved, constants3.F_OK);
|
|
22971
23340
|
return resolved;
|
|
@@ -22994,7 +23363,7 @@ async function resolveWorkspaceTemplateFile(template) {
|
|
|
22994
23363
|
return void 0;
|
|
22995
23364
|
}
|
|
22996
23365
|
try {
|
|
22997
|
-
const stats = await stat4(
|
|
23366
|
+
const stats = await stat4(path30.resolve(template));
|
|
22998
23367
|
return stats.isFile() ? template : void 0;
|
|
22999
23368
|
} catch {
|
|
23000
23369
|
return template;
|
|
@@ -23018,7 +23387,7 @@ function buildMandatoryPrereadBlock2(attachmentFiles) {
|
|
|
23018
23387
|
return "";
|
|
23019
23388
|
}
|
|
23020
23389
|
const buildList = (files) => files.map((absolutePath) => {
|
|
23021
|
-
const fileName =
|
|
23390
|
+
const fileName = path30.basename(absolutePath);
|
|
23022
23391
|
const fileUri = pathToFileUri3(absolutePath);
|
|
23023
23392
|
return `* [${fileName}](${fileUri})`;
|
|
23024
23393
|
});
|
|
@@ -23039,7 +23408,7 @@ function collectAttachmentFiles(attachments) {
|
|
|
23039
23408
|
}
|
|
23040
23409
|
const unique = /* @__PURE__ */ new Map();
|
|
23041
23410
|
for (const attachment of attachments) {
|
|
23042
|
-
const absolutePath =
|
|
23411
|
+
const absolutePath = path30.resolve(attachment);
|
|
23043
23412
|
if (!unique.has(absolutePath)) {
|
|
23044
23413
|
unique.set(absolutePath, absolutePath);
|
|
23045
23414
|
}
|
|
@@ -23047,7 +23416,7 @@ function collectAttachmentFiles(attachments) {
|
|
|
23047
23416
|
return Array.from(unique.values());
|
|
23048
23417
|
}
|
|
23049
23418
|
function pathToFileUri3(filePath) {
|
|
23050
|
-
const absolutePath =
|
|
23419
|
+
const absolutePath = path30.isAbsolute(filePath) ? filePath : path30.resolve(filePath);
|
|
23051
23420
|
const normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
23052
23421
|
if (/^[a-zA-Z]:\//.test(normalizedPath)) {
|
|
23053
23422
|
return `file:///${normalizedPath}`;
|
|
@@ -23060,7 +23429,7 @@ function normalizeAttachments(attachments) {
|
|
|
23060
23429
|
}
|
|
23061
23430
|
const deduped = /* @__PURE__ */ new Set();
|
|
23062
23431
|
for (const attachment of attachments) {
|
|
23063
|
-
deduped.add(
|
|
23432
|
+
deduped.add(path30.resolve(attachment));
|
|
23064
23433
|
}
|
|
23065
23434
|
return Array.from(deduped);
|
|
23066
23435
|
}
|
|
@@ -23069,7 +23438,7 @@ function mergeAttachments(all) {
|
|
|
23069
23438
|
for (const list of all) {
|
|
23070
23439
|
if (!list) continue;
|
|
23071
23440
|
for (const inputFile of list) {
|
|
23072
|
-
deduped.add(
|
|
23441
|
+
deduped.add(path30.resolve(inputFile));
|
|
23073
23442
|
}
|
|
23074
23443
|
}
|
|
23075
23444
|
return deduped.size > 0 ? Array.from(deduped) : void 0;
|
|
@@ -23149,7 +23518,7 @@ async function fileExists3(filePath) {
|
|
|
23149
23518
|
}
|
|
23150
23519
|
}
|
|
23151
23520
|
async function readTargetDefinitions(filePath) {
|
|
23152
|
-
const absolutePath =
|
|
23521
|
+
const absolutePath = path31.resolve(filePath);
|
|
23153
23522
|
if (!await fileExists3(absolutePath)) {
|
|
23154
23523
|
throw new Error(`targets.yaml not found at ${absolutePath}`);
|
|
23155
23524
|
}
|
|
@@ -23170,11 +23539,11 @@ function listTargetNames(definitions) {
|
|
|
23170
23539
|
async function discoverProviders(registry, baseDir) {
|
|
23171
23540
|
const patterns = ["*.ts", "*.js", "*.mts", "*.mjs"];
|
|
23172
23541
|
const candidateDirs = [];
|
|
23173
|
-
let dir =
|
|
23174
|
-
const root =
|
|
23542
|
+
let dir = path322.resolve(baseDir);
|
|
23543
|
+
const root = path322.parse(dir).root;
|
|
23175
23544
|
while (dir !== root) {
|
|
23176
|
-
candidateDirs.push(
|
|
23177
|
-
dir =
|
|
23545
|
+
candidateDirs.push(path322.join(dir, ".agentv", "providers"));
|
|
23546
|
+
dir = path322.dirname(dir);
|
|
23178
23547
|
}
|
|
23179
23548
|
let files = [];
|
|
23180
23549
|
for (const providersDir of candidateDirs) {
|
|
@@ -23190,7 +23559,7 @@ async function discoverProviders(registry, baseDir) {
|
|
|
23190
23559
|
}
|
|
23191
23560
|
const discoveredKinds = [];
|
|
23192
23561
|
for (const filePath of files) {
|
|
23193
|
-
const basename =
|
|
23562
|
+
const basename = path322.basename(filePath);
|
|
23194
23563
|
const kindName = basename.replace(/\.(ts|js|mts|mjs)$/, "");
|
|
23195
23564
|
if (registry.has(kindName)) {
|
|
23196
23565
|
continue;
|
|
@@ -23206,7 +23575,7 @@ async function discoverProviders(registry, baseDir) {
|
|
|
23206
23575
|
}
|
|
23207
23576
|
function createBuiltinProviderRegistry() {
|
|
23208
23577
|
const registry = new ProviderRegistry();
|
|
23209
|
-
registry.register("openai", (t) => new OpenAIProvider(t.name, t.config)).register("openrouter", (t) => new OpenRouterProvider(t.name, t.config)).register("azure", (t) => new AzureProvider(t.name, t.config)).register("anthropic", (t) => new AnthropicProvider(t.name, t.config)).register("gemini", (t) => new GeminiProvider(t.name, t.config)).register("cli", (t) => new CliProvider(t.name, t.config)).register("codex", (t) => new CodexProvider(t.name, t.config)).register("copilot-sdk", (t) => new CopilotSdkProvider(t.name, t.config)).register("copilot-cli", (t) => new CopilotCliProvider(t.name, t.config)).register("pi-coding-agent", (t) => new PiCodingAgentProvider(t.name, t.config)).register("pi-
|
|
23578
|
+
registry.register("openai", (t) => new OpenAIProvider(t.name, t.config)).register("openrouter", (t) => new OpenRouterProvider(t.name, t.config)).register("azure", (t) => new AzureProvider(t.name, t.config)).register("anthropic", (t) => new AnthropicProvider(t.name, t.config)).register("gemini", (t) => new GeminiProvider(t.name, t.config)).register("cli", (t) => new CliProvider(t.name, t.config)).register("codex", (t) => new CodexProvider(t.name, t.config)).register("copilot-sdk", (t) => new CopilotSdkProvider(t.name, t.config)).register("copilot-cli", (t) => new CopilotCliProvider(t.name, t.config)).register("pi-coding-agent", (t) => new PiCodingAgentProvider(t.name, t.config)).register("pi-cli", (t) => new PiCliProvider(t.name, t.config)).register("claude-cli", (t) => new ClaudeCliProvider(t.name, t.config)).register("claude", (t) => new ClaudeCliProvider(t.name, t.config)).register("claude-sdk", (t) => new ClaudeSdkProvider(t.name, t.config)).register("mock", (t) => new MockProvider(t.name, t.config)).register("agentv", (t) => new AgentvProvider(t.name, t.config)).register("vscode", (t) => new VSCodeProvider(t.name, t.config, "vscode")).register(
|
|
23210
23579
|
"vscode-insiders",
|
|
23211
23580
|
(t) => new VSCodeProvider(t.name, t.config, "vscode-insiders")
|
|
23212
23581
|
);
|
|
@@ -23388,15 +23757,15 @@ async function execFileWithStdinNode(argv, stdinPayload, options) {
|
|
|
23388
23757
|
});
|
|
23389
23758
|
}
|
|
23390
23759
|
async function execShellWithStdin(command, stdinPayload, options = {}) {
|
|
23391
|
-
const { mkdir:
|
|
23760
|
+
const { mkdir: mkdir16, readFile: readFile12, rm: rm6, writeFile: writeFile9 } = await import("node:fs/promises");
|
|
23392
23761
|
const { tmpdir: tmpdir3 } = await import("node:os");
|
|
23393
|
-
const
|
|
23394
|
-
const { randomUUID:
|
|
23395
|
-
const dir =
|
|
23396
|
-
await
|
|
23397
|
-
const stdinPath =
|
|
23398
|
-
const stdoutPath =
|
|
23399
|
-
const stderrPath =
|
|
23762
|
+
const path45 = await import("node:path");
|
|
23763
|
+
const { randomUUID: randomUUID10 } = await import("node:crypto");
|
|
23764
|
+
const dir = path45.join(tmpdir3(), `agentv-exec-${randomUUID10()}`);
|
|
23765
|
+
await mkdir16(dir, { recursive: true });
|
|
23766
|
+
const stdinPath = path45.join(dir, "stdin.txt");
|
|
23767
|
+
const stdoutPath = path45.join(dir, "stdout.txt");
|
|
23768
|
+
const stderrPath = path45.join(dir, "stderr.txt");
|
|
23400
23769
|
await writeFile9(stdinPath, stdinPayload, "utf8");
|
|
23401
23770
|
const wrappedCommand = process.platform === "win32" ? `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}` : `(${command}) < ${shellEscapePath(stdinPath)} > ${shellEscapePath(stdoutPath)} 2> ${shellEscapePath(stderrPath)}`;
|
|
23402
23771
|
const { spawn: spawn5 } = await import("node:child_process");
|
|
@@ -23921,7 +24290,8 @@ var freeformEvaluationSchema = external_exports2.object({
|
|
|
23921
24290
|
passed: external_exports2.boolean().describe("Whether this aspect was satisfied"),
|
|
23922
24291
|
evidence: external_exports2.string().describe("Concise evidence (1-2 sentences)").optional()
|
|
23923
24292
|
})
|
|
23924
|
-
).describe("Per-aspect evaluation results \u2014 one entry per aspect checked").optional()
|
|
24293
|
+
).describe("Per-aspect evaluation results \u2014 one entry per aspect checked").optional(),
|
|
24294
|
+
details: external_exports2.record(external_exports2.unknown()).describe("Optional structured metadata for domain-specific metrics").optional()
|
|
23925
24295
|
});
|
|
23926
24296
|
var rubricCheckResultSchema = external_exports2.object({
|
|
23927
24297
|
id: external_exports2.string().describe("The ID of the rubric item being checked"),
|
|
@@ -23983,7 +24353,7 @@ var LlmGraderEvaluator = class {
|
|
|
23983
24353
|
async evaluateFreeform(context2, graderProvider) {
|
|
23984
24354
|
const formattedQuestion = context2.promptInputs.question && context2.promptInputs.question.trim().length > 0 ? context2.promptInputs.question : context2.evalCase.question;
|
|
23985
24355
|
const variables = {
|
|
23986
|
-
[TEMPLATE_VARIABLES.INPUT]: JSON.stringify(context2.evalCase.
|
|
24356
|
+
[TEMPLATE_VARIABLES.INPUT]: JSON.stringify(context2.evalCase.input, null, 2),
|
|
23987
24357
|
[TEMPLATE_VARIABLES.EXPECTED_OUTPUT]: JSON.stringify(
|
|
23988
24358
|
context2.evalCase.expected_output,
|
|
23989
24359
|
null,
|
|
@@ -24026,6 +24396,7 @@ ${context2.fileChanges}`;
|
|
|
24026
24396
|
expectedAspectCount: Math.max(assertions.length, 1),
|
|
24027
24397
|
evaluatorRawRequest,
|
|
24028
24398
|
graderTarget: graderProvider.targetName,
|
|
24399
|
+
details: data.details,
|
|
24029
24400
|
tokenUsage
|
|
24030
24401
|
};
|
|
24031
24402
|
} catch (e) {
|
|
@@ -24445,7 +24816,7 @@ ${outputSchema2}`;
|
|
|
24445
24816
|
expectedAspectCount: Math.max(assertions.length, 1),
|
|
24446
24817
|
evaluatorRawRequest,
|
|
24447
24818
|
graderTarget,
|
|
24448
|
-
details
|
|
24819
|
+
details: data.details && Object.keys(data.details).length > 0 ? { ...details, ...data.details } : details
|
|
24449
24820
|
};
|
|
24450
24821
|
} catch {
|
|
24451
24822
|
return {
|
|
@@ -24592,7 +24963,8 @@ function buildOutputSchema() {
|
|
|
24592
24963
|
' "passed": <boolean>,',
|
|
24593
24964
|
' "evidence": "<concise evidence, 1-2 sentences, optional>"',
|
|
24594
24965
|
" }",
|
|
24595
|
-
" ]",
|
|
24966
|
+
" ],",
|
|
24967
|
+
' "details": {<optional object with domain-specific structured metrics>}',
|
|
24596
24968
|
"}"
|
|
24597
24969
|
].join("\n");
|
|
24598
24970
|
}
|
|
@@ -24710,8 +25082,8 @@ function calculateScoreRangeResult(result, rubrics) {
|
|
|
24710
25082
|
};
|
|
24711
25083
|
}
|
|
24712
25084
|
function resolveSandboxed(basePath, relativePath) {
|
|
24713
|
-
const resolved =
|
|
24714
|
-
if (!resolved.startsWith(basePath +
|
|
25085
|
+
const resolved = path33.resolve(basePath, relativePath);
|
|
25086
|
+
if (!resolved.startsWith(basePath + path33.sep) && resolved !== basePath) {
|
|
24715
25087
|
throw new Error(`Path '${relativePath}' is outside the workspace`);
|
|
24716
25088
|
}
|
|
24717
25089
|
return resolved;
|
|
@@ -24801,11 +25173,11 @@ async function searchDirectory(dirPath, workspacePath, regex, matches) {
|
|
|
24801
25173
|
for (const entry of entries) {
|
|
24802
25174
|
if (matches.length >= MAX_SEARCH_MATCHES) return;
|
|
24803
25175
|
if (SEARCH_SKIP_DIRS.has(entry.name)) continue;
|
|
24804
|
-
const fullPath =
|
|
25176
|
+
const fullPath = path33.join(dirPath, entry.name);
|
|
24805
25177
|
if (entry.isDirectory()) {
|
|
24806
25178
|
await searchDirectory(fullPath, workspacePath, regex, matches);
|
|
24807
25179
|
} else if (entry.isFile()) {
|
|
24808
|
-
const ext =
|
|
25180
|
+
const ext = path33.extname(entry.name).toLowerCase();
|
|
24809
25181
|
if (BINARY_EXTENSIONS.has(ext)) continue;
|
|
24810
25182
|
try {
|
|
24811
25183
|
const stat8 = await fs2.stat(fullPath);
|
|
@@ -24817,7 +25189,7 @@ async function searchDirectory(dirPath, workspacePath, regex, matches) {
|
|
|
24817
25189
|
regex.lastIndex = 0;
|
|
24818
25190
|
if (regex.test(lines[i])) {
|
|
24819
25191
|
matches.push({
|
|
24820
|
-
file:
|
|
25192
|
+
file: path33.relative(workspacePath, fullPath),
|
|
24821
25193
|
line: i + 1,
|
|
24822
25194
|
text: lines[i].substring(0, 200)
|
|
24823
25195
|
});
|
|
@@ -25444,115 +25816,115 @@ var FieldAccuracyEvaluator = class {
|
|
|
25444
25816
|
* Evaluate a single field against the expected value.
|
|
25445
25817
|
*/
|
|
25446
25818
|
evaluateField(fieldConfig, candidateData, expectedData) {
|
|
25447
|
-
const { path:
|
|
25448
|
-
const candidateValue = resolvePath(candidateData,
|
|
25449
|
-
const expectedValue = resolvePath(expectedData,
|
|
25819
|
+
const { path: path45, match, required = true, weight = 1 } = fieldConfig;
|
|
25820
|
+
const candidateValue = resolvePath(candidateData, path45);
|
|
25821
|
+
const expectedValue = resolvePath(expectedData, path45);
|
|
25450
25822
|
if (expectedValue === void 0) {
|
|
25451
25823
|
return {
|
|
25452
|
-
path:
|
|
25824
|
+
path: path45,
|
|
25453
25825
|
score: 1,
|
|
25454
25826
|
// No expected value means no comparison needed
|
|
25455
25827
|
weight,
|
|
25456
25828
|
hit: true,
|
|
25457
|
-
message: `${
|
|
25829
|
+
message: `${path45}: no expected value`
|
|
25458
25830
|
};
|
|
25459
25831
|
}
|
|
25460
25832
|
if (candidateValue === void 0) {
|
|
25461
25833
|
if (required) {
|
|
25462
25834
|
return {
|
|
25463
|
-
path:
|
|
25835
|
+
path: path45,
|
|
25464
25836
|
score: 0,
|
|
25465
25837
|
weight,
|
|
25466
25838
|
hit: false,
|
|
25467
|
-
message: `${
|
|
25839
|
+
message: `${path45} (required, missing)`
|
|
25468
25840
|
};
|
|
25469
25841
|
}
|
|
25470
25842
|
return {
|
|
25471
|
-
path:
|
|
25843
|
+
path: path45,
|
|
25472
25844
|
score: 1,
|
|
25473
25845
|
// Don't penalize missing optional fields
|
|
25474
25846
|
weight: 0,
|
|
25475
25847
|
// Zero weight means it won't affect the score
|
|
25476
25848
|
hit: true,
|
|
25477
|
-
message: `${
|
|
25849
|
+
message: `${path45}: optional field missing`
|
|
25478
25850
|
};
|
|
25479
25851
|
}
|
|
25480
25852
|
switch (match) {
|
|
25481
25853
|
case "exact":
|
|
25482
|
-
return this.compareExact(
|
|
25854
|
+
return this.compareExact(path45, candidateValue, expectedValue, weight);
|
|
25483
25855
|
case "numeric_tolerance":
|
|
25484
25856
|
return this.compareNumericTolerance(
|
|
25485
|
-
|
|
25857
|
+
path45,
|
|
25486
25858
|
candidateValue,
|
|
25487
25859
|
expectedValue,
|
|
25488
25860
|
fieldConfig,
|
|
25489
25861
|
weight
|
|
25490
25862
|
);
|
|
25491
25863
|
case "date":
|
|
25492
|
-
return this.compareDate(
|
|
25864
|
+
return this.compareDate(path45, candidateValue, expectedValue, fieldConfig, weight);
|
|
25493
25865
|
default:
|
|
25494
25866
|
return {
|
|
25495
|
-
path:
|
|
25867
|
+
path: path45,
|
|
25496
25868
|
score: 0,
|
|
25497
25869
|
weight,
|
|
25498
25870
|
hit: false,
|
|
25499
|
-
message: `${
|
|
25871
|
+
message: `${path45}: unknown match type "${match}"`
|
|
25500
25872
|
};
|
|
25501
25873
|
}
|
|
25502
25874
|
}
|
|
25503
25875
|
/**
|
|
25504
25876
|
* Exact equality comparison.
|
|
25505
25877
|
*/
|
|
25506
|
-
compareExact(
|
|
25878
|
+
compareExact(path45, candidateValue, expectedValue, weight) {
|
|
25507
25879
|
if (deepEqual(candidateValue, expectedValue)) {
|
|
25508
25880
|
return {
|
|
25509
|
-
path:
|
|
25881
|
+
path: path45,
|
|
25510
25882
|
score: 1,
|
|
25511
25883
|
weight,
|
|
25512
25884
|
hit: true,
|
|
25513
|
-
message:
|
|
25885
|
+
message: path45
|
|
25514
25886
|
};
|
|
25515
25887
|
}
|
|
25516
25888
|
if (typeof candidateValue !== typeof expectedValue) {
|
|
25517
25889
|
return {
|
|
25518
|
-
path:
|
|
25890
|
+
path: path45,
|
|
25519
25891
|
score: 0,
|
|
25520
25892
|
weight,
|
|
25521
25893
|
hit: false,
|
|
25522
|
-
message: `${
|
|
25894
|
+
message: `${path45} (type mismatch: got ${typeof candidateValue}, expected ${typeof expectedValue})`
|
|
25523
25895
|
};
|
|
25524
25896
|
}
|
|
25525
25897
|
return {
|
|
25526
|
-
path:
|
|
25898
|
+
path: path45,
|
|
25527
25899
|
score: 0,
|
|
25528
25900
|
weight,
|
|
25529
25901
|
hit: false,
|
|
25530
|
-
message: `${
|
|
25902
|
+
message: `${path45} (value mismatch)`
|
|
25531
25903
|
};
|
|
25532
25904
|
}
|
|
25533
25905
|
/**
|
|
25534
25906
|
* Numeric comparison with absolute or relative tolerance.
|
|
25535
25907
|
*/
|
|
25536
|
-
compareNumericTolerance(
|
|
25908
|
+
compareNumericTolerance(path45, candidateValue, expectedValue, fieldConfig, weight) {
|
|
25537
25909
|
const { tolerance = 0, relative = false } = fieldConfig;
|
|
25538
25910
|
const candidateNum = toNumber(candidateValue);
|
|
25539
25911
|
const expectedNum = toNumber(expectedValue);
|
|
25540
25912
|
if (candidateNum === null || expectedNum === null) {
|
|
25541
25913
|
return {
|
|
25542
|
-
path:
|
|
25914
|
+
path: path45,
|
|
25543
25915
|
score: 0,
|
|
25544
25916
|
weight,
|
|
25545
25917
|
hit: false,
|
|
25546
|
-
message: `${
|
|
25918
|
+
message: `${path45} (non-numeric value)`
|
|
25547
25919
|
};
|
|
25548
25920
|
}
|
|
25549
25921
|
if (!Number.isFinite(candidateNum) || !Number.isFinite(expectedNum)) {
|
|
25550
25922
|
return {
|
|
25551
|
-
path:
|
|
25923
|
+
path: path45,
|
|
25552
25924
|
score: 0,
|
|
25553
25925
|
weight,
|
|
25554
25926
|
hit: false,
|
|
25555
|
-
message: `${
|
|
25927
|
+
message: `${path45} (invalid numeric value)`
|
|
25556
25928
|
};
|
|
25557
25929
|
}
|
|
25558
25930
|
const diff = Math.abs(candidateNum - expectedNum);
|
|
@@ -25565,61 +25937,61 @@ var FieldAccuracyEvaluator = class {
|
|
|
25565
25937
|
}
|
|
25566
25938
|
if (withinTolerance) {
|
|
25567
25939
|
return {
|
|
25568
|
-
path:
|
|
25940
|
+
path: path45,
|
|
25569
25941
|
score: 1,
|
|
25570
25942
|
weight,
|
|
25571
25943
|
hit: true,
|
|
25572
|
-
message: `${
|
|
25944
|
+
message: `${path45} (within tolerance: diff=${diff.toFixed(2)})`
|
|
25573
25945
|
};
|
|
25574
25946
|
}
|
|
25575
25947
|
return {
|
|
25576
|
-
path:
|
|
25948
|
+
path: path45,
|
|
25577
25949
|
score: 0,
|
|
25578
25950
|
weight,
|
|
25579
25951
|
hit: false,
|
|
25580
|
-
message: `${
|
|
25952
|
+
message: `${path45} (outside tolerance: diff=${diff.toFixed(2)}, tolerance=${tolerance})`
|
|
25581
25953
|
};
|
|
25582
25954
|
}
|
|
25583
25955
|
/**
|
|
25584
25956
|
* Date comparison with format normalization.
|
|
25585
25957
|
*/
|
|
25586
|
-
compareDate(
|
|
25958
|
+
compareDate(path45, candidateValue, expectedValue, fieldConfig, weight) {
|
|
25587
25959
|
const formats = fieldConfig.formats ?? DEFAULT_DATE_FORMATS;
|
|
25588
25960
|
const candidateDate = parseDate(String(candidateValue), formats);
|
|
25589
25961
|
const expectedDate = parseDate(String(expectedValue), formats);
|
|
25590
25962
|
if (candidateDate === null) {
|
|
25591
25963
|
return {
|
|
25592
|
-
path:
|
|
25964
|
+
path: path45,
|
|
25593
25965
|
score: 0,
|
|
25594
25966
|
weight,
|
|
25595
25967
|
hit: false,
|
|
25596
|
-
message: `${
|
|
25968
|
+
message: `${path45} (unparseable candidate date)`
|
|
25597
25969
|
};
|
|
25598
25970
|
}
|
|
25599
25971
|
if (expectedDate === null) {
|
|
25600
25972
|
return {
|
|
25601
|
-
path:
|
|
25973
|
+
path: path45,
|
|
25602
25974
|
score: 0,
|
|
25603
25975
|
weight,
|
|
25604
25976
|
hit: false,
|
|
25605
|
-
message: `${
|
|
25977
|
+
message: `${path45} (unparseable expected date)`
|
|
25606
25978
|
};
|
|
25607
25979
|
}
|
|
25608
25980
|
if (candidateDate.getFullYear() === expectedDate.getFullYear() && candidateDate.getMonth() === expectedDate.getMonth() && candidateDate.getDate() === expectedDate.getDate()) {
|
|
25609
25981
|
return {
|
|
25610
|
-
path:
|
|
25982
|
+
path: path45,
|
|
25611
25983
|
score: 1,
|
|
25612
25984
|
weight,
|
|
25613
25985
|
hit: true,
|
|
25614
|
-
message:
|
|
25986
|
+
message: path45
|
|
25615
25987
|
};
|
|
25616
25988
|
}
|
|
25617
25989
|
return {
|
|
25618
|
-
path:
|
|
25990
|
+
path: path45,
|
|
25619
25991
|
score: 0,
|
|
25620
25992
|
weight,
|
|
25621
25993
|
hit: false,
|
|
25622
|
-
message: `${
|
|
25994
|
+
message: `${path45} (date mismatch: got ${formatDateISO(candidateDate)}, expected ${formatDateISO(expectedDate)})`
|
|
25623
25995
|
};
|
|
25624
25996
|
}
|
|
25625
25997
|
/**
|
|
@@ -25652,11 +26024,11 @@ var FieldAccuracyEvaluator = class {
|
|
|
25652
26024
|
};
|
|
25653
26025
|
}
|
|
25654
26026
|
};
|
|
25655
|
-
function resolvePath(obj,
|
|
25656
|
-
if (!
|
|
26027
|
+
function resolvePath(obj, path45) {
|
|
26028
|
+
if (!path45 || !obj) {
|
|
25657
26029
|
return void 0;
|
|
25658
26030
|
}
|
|
25659
|
-
const parts =
|
|
26031
|
+
const parts = path45.split(/\.|\[|\]/).filter((p) => p.length > 0);
|
|
25660
26032
|
let current = obj;
|
|
25661
26033
|
for (const part of parts) {
|
|
25662
26034
|
if (current === null || current === void 0) {
|
|
@@ -25818,9 +26190,7 @@ var PROVIDER_TOOL_SEMANTICS = {
|
|
|
25818
26190
|
"claude-sdk": CLAUDE_MATCHER,
|
|
25819
26191
|
codex: CODEX_MATCHER,
|
|
25820
26192
|
"pi-coding-agent": PI_CODING_AGENT_MATCHER,
|
|
25821
|
-
|
|
25822
|
-
// TODO: consider removing pi-agent-sdk provider entirely.
|
|
25823
|
-
"pi-agent-sdk": PI_CODING_AGENT_MATCHER,
|
|
26193
|
+
"pi-cli": PI_CODING_AGENT_MATCHER,
|
|
25824
26194
|
"copilot-cli": COPILOT_MATCHER,
|
|
25825
26195
|
"copilot-sdk": COPILOT_MATCHER,
|
|
25826
26196
|
vscode: COPILOT_MATCHER,
|
|
@@ -25942,7 +26312,7 @@ function assembleLlmGraderPrompt(input) {
|
|
|
25942
26312
|
function assembleFreeform(evalCase, candidate, promptInputs, fileChanges, evaluatorTemplateOverride) {
|
|
25943
26313
|
const formattedQuestion = promptInputs.question && promptInputs.question.trim().length > 0 ? promptInputs.question : evalCase.question;
|
|
25944
26314
|
const variables = {
|
|
25945
|
-
[TEMPLATE_VARIABLES.INPUT]: JSON.stringify(evalCase.
|
|
26315
|
+
[TEMPLATE_VARIABLES.INPUT]: JSON.stringify(evalCase.input, null, 2),
|
|
25946
26316
|
[TEMPLATE_VARIABLES.EXPECTED_OUTPUT]: JSON.stringify(evalCase.expected_output, null, 2),
|
|
25947
26317
|
[TEMPLATE_VARIABLES.OUTPUT]: JSON.stringify([], null, 2),
|
|
25948
26318
|
[TEMPLATE_VARIABLES.CRITERIA]: evalCase.criteria.trim(),
|
|
@@ -26129,8 +26499,8 @@ var TokenUsageEvaluator = class {
|
|
|
26129
26499
|
};
|
|
26130
26500
|
}
|
|
26131
26501
|
};
|
|
26132
|
-
function getNestedValue(obj,
|
|
26133
|
-
const parts =
|
|
26502
|
+
function getNestedValue(obj, path45) {
|
|
26503
|
+
const parts = path45.split(".");
|
|
26134
26504
|
let current = obj;
|
|
26135
26505
|
for (const part of parts) {
|
|
26136
26506
|
if (current === null || current === void 0 || typeof current !== "object") {
|
|
@@ -26993,7 +27363,7 @@ async function executePromptTemplate(script, context2, config, timeoutMs) {
|
|
|
26993
27363
|
};
|
|
26994
27364
|
const inputJson = JSON.stringify(toSnakeCaseDeep(payload), null, 2);
|
|
26995
27365
|
const scriptPath = script[script.length - 1];
|
|
26996
|
-
const cwd =
|
|
27366
|
+
const cwd = path34.dirname(scriptPath);
|
|
26997
27367
|
try {
|
|
26998
27368
|
const stdout = await executeScript(script, inputJson, timeoutMs, cwd);
|
|
26999
27369
|
const prompt = stdout.trim();
|
|
@@ -27264,11 +27634,11 @@ function createBuiltinRegistry() {
|
|
|
27264
27634
|
async function discoverAssertions(registry, baseDir) {
|
|
27265
27635
|
const patterns = ["*.ts", "*.js", "*.mts", "*.mjs"];
|
|
27266
27636
|
const candidateDirs = [];
|
|
27267
|
-
let dir =
|
|
27268
|
-
const root =
|
|
27637
|
+
let dir = path35.resolve(baseDir);
|
|
27638
|
+
const root = path35.parse(dir).root;
|
|
27269
27639
|
while (dir !== root) {
|
|
27270
|
-
candidateDirs.push(
|
|
27271
|
-
dir =
|
|
27640
|
+
candidateDirs.push(path35.join(dir, ".agentv", "assertions"));
|
|
27641
|
+
dir = path35.dirname(dir);
|
|
27272
27642
|
}
|
|
27273
27643
|
let files = [];
|
|
27274
27644
|
for (const assertionsDir of candidateDirs) {
|
|
@@ -27284,7 +27654,7 @@ async function discoverAssertions(registry, baseDir) {
|
|
|
27284
27654
|
}
|
|
27285
27655
|
const discoveredTypes = [];
|
|
27286
27656
|
for (const filePath of files) {
|
|
27287
|
-
const basename =
|
|
27657
|
+
const basename = path35.basename(filePath);
|
|
27288
27658
|
const typeName = basename.replace(/\.(ts|js|mts|mjs)$/, "");
|
|
27289
27659
|
if (registry.has(typeName)) {
|
|
27290
27660
|
continue;
|
|
@@ -27303,12 +27673,12 @@ async function discoverAssertions(registry, baseDir) {
|
|
|
27303
27673
|
async function discoverGraders(registry, baseDir) {
|
|
27304
27674
|
const patterns = ["*.ts", "*.js", "*.mts", "*.mjs"];
|
|
27305
27675
|
const candidateDirs = [];
|
|
27306
|
-
let dir =
|
|
27307
|
-
const root =
|
|
27676
|
+
let dir = path36.resolve(baseDir);
|
|
27677
|
+
const root = path36.parse(dir).root;
|
|
27308
27678
|
while (dir !== root) {
|
|
27309
|
-
candidateDirs.push(
|
|
27310
|
-
candidateDirs.push(
|
|
27311
|
-
dir =
|
|
27679
|
+
candidateDirs.push(path36.join(dir, ".agentv", "graders"));
|
|
27680
|
+
candidateDirs.push(path36.join(dir, ".agentv", "judges"));
|
|
27681
|
+
dir = path36.dirname(dir);
|
|
27312
27682
|
}
|
|
27313
27683
|
let files = [];
|
|
27314
27684
|
for (const gradersDir of candidateDirs) {
|
|
@@ -27324,7 +27694,7 @@ async function discoverGraders(registry, baseDir) {
|
|
|
27324
27694
|
}
|
|
27325
27695
|
const discoveredTypes = [];
|
|
27326
27696
|
for (const filePath of files) {
|
|
27327
|
-
const basename =
|
|
27697
|
+
const basename = path36.basename(filePath);
|
|
27328
27698
|
const typeName = basename.replace(/\.(ts|js|mts|mjs)$/, "");
|
|
27329
27699
|
if (registry.has(typeName)) {
|
|
27330
27700
|
continue;
|
|
@@ -27510,10 +27880,10 @@ async function stageNestedRepoChanges(workspacePath) {
|
|
|
27510
27880
|
}
|
|
27511
27881
|
for (const entry of entries) {
|
|
27512
27882
|
if (entry === ".git" || entry === "node_modules") continue;
|
|
27513
|
-
const childPath =
|
|
27883
|
+
const childPath = path37.join(workspacePath, entry);
|
|
27514
27884
|
try {
|
|
27515
27885
|
if (!statSync(childPath).isDirectory()) continue;
|
|
27516
|
-
if (!statSync(
|
|
27886
|
+
if (!statSync(path37.join(childPath, ".git")).isDirectory()) continue;
|
|
27517
27887
|
} catch {
|
|
27518
27888
|
continue;
|
|
27519
27889
|
}
|
|
@@ -27550,14 +27920,14 @@ async function isDirectory(filePath) {
|
|
|
27550
27920
|
}
|
|
27551
27921
|
function getWorkspacePath(evalRunId, caseId, workspaceRoot) {
|
|
27552
27922
|
const root = workspaceRoot ?? getWorkspacesRoot();
|
|
27553
|
-
return
|
|
27923
|
+
return path38.join(root, evalRunId, caseId);
|
|
27554
27924
|
}
|
|
27555
27925
|
async function copyDirectoryRecursive(src, dest) {
|
|
27556
|
-
await
|
|
27926
|
+
await mkdir12(dest, { recursive: true });
|
|
27557
27927
|
const entries = await readdir3(src, { withFileTypes: true });
|
|
27558
27928
|
for (const entry of entries) {
|
|
27559
|
-
const srcPath =
|
|
27560
|
-
const destPath =
|
|
27929
|
+
const srcPath = path38.join(src, entry.name);
|
|
27930
|
+
const destPath = path38.join(dest, entry.name);
|
|
27561
27931
|
if (entry.name === ".git") {
|
|
27562
27932
|
continue;
|
|
27563
27933
|
}
|
|
@@ -27569,7 +27939,7 @@ async function copyDirectoryRecursive(src, dest) {
|
|
|
27569
27939
|
}
|
|
27570
27940
|
}
|
|
27571
27941
|
async function createTempWorkspace(templatePath, evalRunId, caseId, workspaceRoot) {
|
|
27572
|
-
const resolvedTemplatePath =
|
|
27942
|
+
const resolvedTemplatePath = path38.resolve(templatePath);
|
|
27573
27943
|
if (!await fileExists(resolvedTemplatePath)) {
|
|
27574
27944
|
throw new TemplateNotFoundError(resolvedTemplatePath);
|
|
27575
27945
|
}
|
|
@@ -27618,7 +27988,7 @@ async function cleanupWorkspace(workspacePath) {
|
|
|
27618
27988
|
}
|
|
27619
27989
|
async function cleanupEvalWorkspaces(evalRunId, workspaceRoot) {
|
|
27620
27990
|
const root = workspaceRoot ?? getWorkspacesRoot();
|
|
27621
|
-
const evalDir =
|
|
27991
|
+
const evalDir = path38.join(root, evalRunId);
|
|
27622
27992
|
if (await fileExists(evalDir)) {
|
|
27623
27993
|
await rm4(evalDir, { recursive: true, force: true });
|
|
27624
27994
|
}
|
|
@@ -27672,11 +28042,11 @@ function computeWorkspaceFingerprint(repos) {
|
|
|
27672
28042
|
return createHash("sha256").update(JSON.stringify(canonical)).digest("hex");
|
|
27673
28043
|
}
|
|
27674
28044
|
async function copyDirectoryRecursive2(src, dest, skipDirs) {
|
|
27675
|
-
await
|
|
28045
|
+
await mkdir13(dest, { recursive: true });
|
|
27676
28046
|
const entries = await readdir4(src, { withFileTypes: true });
|
|
27677
28047
|
for (const entry of entries) {
|
|
27678
|
-
const srcPath =
|
|
27679
|
-
const destPath =
|
|
28048
|
+
const srcPath = path39.join(src, entry.name);
|
|
28049
|
+
const destPath = path39.join(dest, entry.name);
|
|
27680
28050
|
if (entry.name === ".git") {
|
|
27681
28051
|
continue;
|
|
27682
28052
|
}
|
|
@@ -27709,8 +28079,8 @@ var WorkspacePoolManager = class {
|
|
|
27709
28079
|
async acquireWorkspace(options) {
|
|
27710
28080
|
const { templatePath, repos, maxSlots, repoManager, poolReset } = options;
|
|
27711
28081
|
const fingerprint = computeWorkspaceFingerprint(repos);
|
|
27712
|
-
const poolDir =
|
|
27713
|
-
await
|
|
28082
|
+
const poolDir = path39.join(this.poolRoot, fingerprint);
|
|
28083
|
+
await mkdir13(poolDir, { recursive: true });
|
|
27714
28084
|
const drifted = await this.checkDrift(poolDir, fingerprint);
|
|
27715
28085
|
if (drifted) {
|
|
27716
28086
|
console.warn(
|
|
@@ -27719,7 +28089,7 @@ var WorkspacePoolManager = class {
|
|
|
27719
28089
|
await this.removeAllSlots(poolDir);
|
|
27720
28090
|
}
|
|
27721
28091
|
for (let i = 0; i < maxSlots; i++) {
|
|
27722
|
-
const slotPath =
|
|
28092
|
+
const slotPath = path39.join(poolDir, `slot-${i}`);
|
|
27723
28093
|
const lockPath = `${slotPath}.lock`;
|
|
27724
28094
|
const locked = await this.tryLock(lockPath);
|
|
27725
28095
|
if (!locked) {
|
|
@@ -27737,7 +28107,7 @@ var WorkspacePoolManager = class {
|
|
|
27737
28107
|
poolDir
|
|
27738
28108
|
};
|
|
27739
28109
|
}
|
|
27740
|
-
await
|
|
28110
|
+
await mkdir13(slotPath, { recursive: true });
|
|
27741
28111
|
if (templatePath) {
|
|
27742
28112
|
await copyDirectoryRecursive2(templatePath, slotPath);
|
|
27743
28113
|
}
|
|
@@ -27806,7 +28176,7 @@ var WorkspacePoolManager = class {
|
|
|
27806
28176
|
* Returns false (no drift) if metadata.json doesn't exist (first use).
|
|
27807
28177
|
*/
|
|
27808
28178
|
async checkDrift(poolDir, fingerprint) {
|
|
27809
|
-
const metadataPath =
|
|
28179
|
+
const metadataPath = path39.join(poolDir, "metadata.json");
|
|
27810
28180
|
try {
|
|
27811
28181
|
const raw = await readFile10(metadataPath, "utf-8");
|
|
27812
28182
|
const metadata = JSON.parse(raw);
|
|
@@ -27823,14 +28193,14 @@ var WorkspacePoolManager = class {
|
|
|
27823
28193
|
repos,
|
|
27824
28194
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
27825
28195
|
};
|
|
27826
|
-
await writeFile7(
|
|
28196
|
+
await writeFile7(path39.join(poolDir, "metadata.json"), JSON.stringify(metadata, null, 2));
|
|
27827
28197
|
}
|
|
27828
28198
|
/** Remove all slot directories and their lock files from a pool directory. */
|
|
27829
28199
|
async removeAllSlots(poolDir) {
|
|
27830
28200
|
const entries = await readdir4(poolDir);
|
|
27831
28201
|
for (const entry of entries) {
|
|
27832
28202
|
if (entry.startsWith("slot-") && !entry.endsWith(".lock")) {
|
|
27833
|
-
const lockPath =
|
|
28203
|
+
const lockPath = path39.join(poolDir, `${entry}.lock`);
|
|
27834
28204
|
if (existsSync2(lockPath)) {
|
|
27835
28205
|
try {
|
|
27836
28206
|
const pidStr = await readFile10(lockPath, "utf-8");
|
|
@@ -27846,12 +28216,12 @@ var WorkspacePoolManager = class {
|
|
|
27846
28216
|
} catch {
|
|
27847
28217
|
}
|
|
27848
28218
|
}
|
|
27849
|
-
await rm5(
|
|
28219
|
+
await rm5(path39.join(poolDir, entry), { recursive: true, force: true });
|
|
27850
28220
|
await rm5(lockPath, { force: true }).catch(() => {
|
|
27851
28221
|
});
|
|
27852
28222
|
}
|
|
27853
28223
|
}
|
|
27854
|
-
await rm5(
|
|
28224
|
+
await rm5(path39.join(poolDir, "metadata.json"), { force: true }).catch(() => {
|
|
27855
28225
|
});
|
|
27856
28226
|
}
|
|
27857
28227
|
/**
|
|
@@ -27861,7 +28231,7 @@ var WorkspacePoolManager = class {
|
|
|
27861
28231
|
*/
|
|
27862
28232
|
async resetSlot(slotPath, templatePath, repos, poolReset = "fast") {
|
|
27863
28233
|
for (const repo of repos) {
|
|
27864
|
-
const repoDir =
|
|
28234
|
+
const repoDir = path39.join(slotPath, repo.path);
|
|
27865
28235
|
if (!existsSync2(repoDir)) {
|
|
27866
28236
|
continue;
|
|
27867
28237
|
}
|
|
@@ -27982,7 +28352,7 @@ ${lines.join("\n")}`;
|
|
|
27982
28352
|
* Handles checkout, ref resolution, ancestor walking, shallow clone, sparse checkout.
|
|
27983
28353
|
*/
|
|
27984
28354
|
async materialize(repo, workspacePath) {
|
|
27985
|
-
const targetDir =
|
|
28355
|
+
const targetDir = path40.join(workspacePath, repo.path);
|
|
27986
28356
|
const sourceUrl = getSourceUrl(repo.source);
|
|
27987
28357
|
const startedAt = Date.now();
|
|
27988
28358
|
if (this.verbose) {
|
|
@@ -28073,7 +28443,7 @@ ${lines.join("\n")}`;
|
|
|
28073
28443
|
async reset(repos, workspacePath, reset) {
|
|
28074
28444
|
const cleanFlag = reset === "strict" ? "-fdx" : "-fd";
|
|
28075
28445
|
for (const repo of repos) {
|
|
28076
|
-
const targetDir =
|
|
28446
|
+
const targetDir = path40.join(workspacePath, repo.path);
|
|
28077
28447
|
await this.runGit(["reset", "--hard", "HEAD"], { cwd: targetDir });
|
|
28078
28448
|
await this.runGit(["clean", cleanFlag], { cwd: targetDir });
|
|
28079
28449
|
}
|
|
@@ -28083,11 +28453,11 @@ async function resolveWorkspaceTemplate(templatePath) {
|
|
|
28083
28453
|
if (!templatePath) {
|
|
28084
28454
|
return void 0;
|
|
28085
28455
|
}
|
|
28086
|
-
const resolved =
|
|
28456
|
+
const resolved = path41.resolve(templatePath);
|
|
28087
28457
|
const stats = await stat6(resolved);
|
|
28088
28458
|
if (stats.isFile()) {
|
|
28089
28459
|
return {
|
|
28090
|
-
dir:
|
|
28460
|
+
dir: path41.dirname(resolved),
|
|
28091
28461
|
workspaceFile: resolved
|
|
28092
28462
|
};
|
|
28093
28463
|
}
|
|
@@ -28099,14 +28469,14 @@ async function resolveWorkspaceTemplate(templatePath) {
|
|
|
28099
28469
|
if (workspaceFiles.length === 1) {
|
|
28100
28470
|
return {
|
|
28101
28471
|
dir: resolved,
|
|
28102
|
-
workspaceFile:
|
|
28472
|
+
workspaceFile: path41.join(resolved, workspaceFiles[0])
|
|
28103
28473
|
};
|
|
28104
28474
|
}
|
|
28105
28475
|
if (workspaceFiles.length > 1) {
|
|
28106
28476
|
const conventionFile = workspaceFiles.find((f) => f === "template.code-workspace");
|
|
28107
28477
|
return {
|
|
28108
28478
|
dir: resolved,
|
|
28109
|
-
workspaceFile: conventionFile ?
|
|
28479
|
+
workspaceFile: conventionFile ? path41.join(resolved, conventionFile) : void 0
|
|
28110
28480
|
};
|
|
28111
28481
|
}
|
|
28112
28482
|
return { dir: resolved };
|
|
@@ -28156,6 +28526,18 @@ var QUALITY_PASS_THRESHOLD = 0.8;
|
|
|
28156
28526
|
function classifyQualityStatus(score) {
|
|
28157
28527
|
return score >= QUALITY_PASS_THRESHOLD ? "ok" : "quality_failure";
|
|
28158
28528
|
}
|
|
28529
|
+
function buildSkippedEvaluatorError(scores) {
|
|
28530
|
+
const skippedScores = scores?.filter((score) => score.verdict === "skip") ?? [];
|
|
28531
|
+
if (skippedScores.length === 0) {
|
|
28532
|
+
return void 0;
|
|
28533
|
+
}
|
|
28534
|
+
const messages = skippedScores.map((score) => {
|
|
28535
|
+
const label = score.name || score.type;
|
|
28536
|
+
const assertionMessage = score.assertions.find((assertion) => !assertion.passed)?.text ?? "Evaluator skipped";
|
|
28537
|
+
return `${label}: ${assertionMessage}`;
|
|
28538
|
+
});
|
|
28539
|
+
return messages.length === 1 ? messages[0] : `Evaluators skipped: ${messages.join(" | ")}`;
|
|
28540
|
+
}
|
|
28159
28541
|
function usesFileReferencePrompt(provider) {
|
|
28160
28542
|
return isAgentProvider(provider) || provider.kind === "cli";
|
|
28161
28543
|
}
|
|
@@ -28227,7 +28609,7 @@ async function runEvaluation(options) {
|
|
|
28227
28609
|
);
|
|
28228
28610
|
useCache = false;
|
|
28229
28611
|
}
|
|
28230
|
-
const evalRunId =
|
|
28612
|
+
const evalRunId = randomUUID9();
|
|
28231
28613
|
const evalCases = preloadedEvalCases ?? await loadTests(evalFilePath, repoRoot, { verbose, filter: filter2 });
|
|
28232
28614
|
const filteredEvalCases = filterEvalCases(evalCases, filter2);
|
|
28233
28615
|
if (filteredEvalCases.length === 0) {
|
|
@@ -28272,7 +28654,7 @@ async function runEvaluation(options) {
|
|
|
28272
28654
|
if (!cliModel) {
|
|
28273
28655
|
throw new Error('--grader-target "agentv" requires --model (e.g., "openai:gpt-5-mini")');
|
|
28274
28656
|
}
|
|
28275
|
-
const { AgentvProvider: AgentvProvider2 } = await import("./agentv-provider-
|
|
28657
|
+
const { AgentvProvider: AgentvProvider2 } = await import("./agentv-provider-MIDKLYIH-6LIYKQRP.js");
|
|
28276
28658
|
return new AgentvProvider2("agentv", { model: cliModel, temperature: 0 });
|
|
28277
28659
|
}
|
|
28278
28660
|
const overrideTarget = resolveTargetByName(cliGraderTarget);
|
|
@@ -28306,7 +28688,7 @@ async function runEvaluation(options) {
|
|
|
28306
28688
|
];
|
|
28307
28689
|
const evaluatorRegistry = buildEvaluatorRegistry(evaluators, resolveGraderProvider);
|
|
28308
28690
|
const typeRegistry = createBuiltinRegistry();
|
|
28309
|
-
const discoveryBaseDir = evalFilePath ?
|
|
28691
|
+
const discoveryBaseDir = evalFilePath ? path422.dirname(path422.resolve(evalFilePath)) : process.cwd();
|
|
28310
28692
|
const evalDir = discoveryBaseDir;
|
|
28311
28693
|
await discoverAssertions(typeRegistry, discoveryBaseDir);
|
|
28312
28694
|
await discoverGraders(typeRegistry, discoveryBaseDir);
|
|
@@ -28453,7 +28835,7 @@ async function runEvaluation(options) {
|
|
|
28453
28835
|
const isEmpty = dirExists ? (await readdir6(configuredStaticPath)).length === 0 : false;
|
|
28454
28836
|
if (isYamlConfiguredPath && (!dirExists || isEmpty)) {
|
|
28455
28837
|
if (!dirExists) {
|
|
28456
|
-
await
|
|
28838
|
+
await mkdir14(configuredStaticPath, { recursive: true });
|
|
28457
28839
|
}
|
|
28458
28840
|
if (workspaceTemplate) {
|
|
28459
28841
|
await copyDirectoryRecursive(workspaceTemplate, configuredStaticPath);
|
|
@@ -28498,12 +28880,12 @@ async function runEvaluation(options) {
|
|
|
28498
28880
|
}
|
|
28499
28881
|
} else if (suiteWorkspace?.hooks || suiteWorkspace?.repos?.length && !isPerTestIsolation) {
|
|
28500
28882
|
sharedWorkspacePath = getWorkspacePath(evalRunId, "shared");
|
|
28501
|
-
await
|
|
28883
|
+
await mkdir14(sharedWorkspacePath, { recursive: true });
|
|
28502
28884
|
setupLog(`created empty shared workspace at: ${sharedWorkspacePath}`);
|
|
28503
28885
|
}
|
|
28504
28886
|
try {
|
|
28505
28887
|
if (suiteWorkspaceFile && sharedWorkspacePath) {
|
|
28506
|
-
const copiedWorkspaceFile =
|
|
28888
|
+
const copiedWorkspaceFile = path422.join(sharedWorkspacePath, path422.basename(suiteWorkspaceFile));
|
|
28507
28889
|
try {
|
|
28508
28890
|
await stat7(copiedWorkspaceFile);
|
|
28509
28891
|
suiteWorkspaceFile = copiedWorkspaceFile;
|
|
@@ -29085,7 +29467,7 @@ async function runEvalCase(options) {
|
|
|
29085
29467
|
);
|
|
29086
29468
|
}
|
|
29087
29469
|
if (caseWorkspaceFile && workspacePath) {
|
|
29088
|
-
const copiedFile =
|
|
29470
|
+
const copiedFile = path422.join(workspacePath, path422.basename(caseWorkspaceFile));
|
|
29089
29471
|
try {
|
|
29090
29472
|
await stat7(copiedFile);
|
|
29091
29473
|
caseWorkspaceFile = copiedFile;
|
|
@@ -29095,7 +29477,7 @@ async function runEvalCase(options) {
|
|
|
29095
29477
|
}
|
|
29096
29478
|
if (!workspacePath && (evalCase.workspace?.hooks || evalCase.workspace?.repos?.length) && evalRunId) {
|
|
29097
29479
|
workspacePath = getWorkspacePath(evalRunId, evalCase.id);
|
|
29098
|
-
await
|
|
29480
|
+
await mkdir14(workspacePath, { recursive: true });
|
|
29099
29481
|
}
|
|
29100
29482
|
if (evalCase.workspace?.repos?.length && workspacePath) {
|
|
29101
29483
|
const localPathErrors = RepoManager.validateLocalPaths(evalCase.workspace.repos);
|
|
@@ -29147,10 +29529,10 @@ async function runEvalCase(options) {
|
|
|
29147
29529
|
const files = evalCase.metadata.agent_skills_files;
|
|
29148
29530
|
if (baseDir && files.length > 0) {
|
|
29149
29531
|
for (const relPath of files) {
|
|
29150
|
-
const srcPath =
|
|
29151
|
-
const destPath =
|
|
29532
|
+
const srcPath = path422.resolve(baseDir, relPath);
|
|
29533
|
+
const destPath = path422.resolve(workspacePath, relPath);
|
|
29152
29534
|
try {
|
|
29153
|
-
await
|
|
29535
|
+
await mkdir14(path422.dirname(destPath), { recursive: true });
|
|
29154
29536
|
await copyFile2(srcPath, destPath);
|
|
29155
29537
|
} catch (error) {
|
|
29156
29538
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -29420,7 +29802,8 @@ async function runEvalCase(options) {
|
|
|
29420
29802
|
durationMs: totalDurationMs,
|
|
29421
29803
|
...evalRunTokenUsage ? { tokenUsage: evalRunTokenUsage } : {}
|
|
29422
29804
|
};
|
|
29423
|
-
const
|
|
29805
|
+
const skippedEvaluatorError = buildSkippedEvaluatorError(result.scores);
|
|
29806
|
+
const executionStatus = providerError || skippedEvaluatorError ? "execution_error" : classifyQualityStatus(result.score);
|
|
29424
29807
|
const finalResult = providerError ? {
|
|
29425
29808
|
...result,
|
|
29426
29809
|
evalRun,
|
|
@@ -29432,7 +29815,26 @@ async function runEvalCase(options) {
|
|
|
29432
29815
|
beforeAllOutput,
|
|
29433
29816
|
beforeEachOutput,
|
|
29434
29817
|
afterEachOutput
|
|
29435
|
-
} :
|
|
29818
|
+
} : skippedEvaluatorError ? {
|
|
29819
|
+
...result,
|
|
29820
|
+
score: 0,
|
|
29821
|
+
evalRun,
|
|
29822
|
+
error: skippedEvaluatorError,
|
|
29823
|
+
executionStatus,
|
|
29824
|
+
failureStage: "evaluator",
|
|
29825
|
+
failureReasonCode: "evaluator_error",
|
|
29826
|
+
executionError: { message: skippedEvaluatorError, stage: "evaluator" },
|
|
29827
|
+
beforeAllOutput,
|
|
29828
|
+
beforeEachOutput,
|
|
29829
|
+
afterEachOutput
|
|
29830
|
+
} : {
|
|
29831
|
+
...result,
|
|
29832
|
+
evalRun,
|
|
29833
|
+
executionStatus,
|
|
29834
|
+
beforeAllOutput,
|
|
29835
|
+
beforeEachOutput,
|
|
29836
|
+
afterEachOutput
|
|
29837
|
+
};
|
|
29436
29838
|
const isFailure = !!finalResult.error || finalResult.score < 0.5;
|
|
29437
29839
|
if (workspacePath && !isSharedWorkspace) {
|
|
29438
29840
|
if (forceCleanup) {
|
|
@@ -29776,7 +30178,7 @@ async function runEvaluatorList(options) {
|
|
|
29776
30178
|
fileChanges,
|
|
29777
30179
|
workspacePath
|
|
29778
30180
|
};
|
|
29779
|
-
const evalFileDir = evalCase.file_paths[0] ?
|
|
30181
|
+
const evalFileDir = evalCase.file_paths[0] ? path422.dirname(evalCase.file_paths[0]) : process.cwd();
|
|
29780
30182
|
const dispatchContext = {
|
|
29781
30183
|
graderProvider,
|
|
29782
30184
|
targetResolver,
|
|
@@ -30139,7 +30541,7 @@ async function evaluate(config) {
|
|
|
30139
30541
|
}
|
|
30140
30542
|
const gitRoot = await findGitRoot(process.cwd());
|
|
30141
30543
|
const repoRoot = gitRoot ?? process.cwd();
|
|
30142
|
-
const testFilePath = config.specFile ?
|
|
30544
|
+
const testFilePath = config.specFile ? path43.resolve(config.specFile) : path43.join(process.cwd(), "__programmatic__.yaml");
|
|
30143
30545
|
await loadEnvHierarchy(repoRoot, testFilePath);
|
|
30144
30546
|
let resolvedTarget;
|
|
30145
30547
|
let taskProvider;
|
|
@@ -30169,11 +30571,6 @@ async function evaluate(config) {
|
|
|
30169
30571
|
evalCases = (config.tests ?? []).map((test) => {
|
|
30170
30572
|
const input = typeof test.input === "string" ? [{ role: "user", content: test.input }] : test.input;
|
|
30171
30573
|
const question = typeof test.input === "string" ? test.input : test.input.find((m) => m.role === "user")?.content ?? "";
|
|
30172
|
-
const inputSegments = input.map((m) => ({
|
|
30173
|
-
type: "text",
|
|
30174
|
-
value: typeof m.content === "string" ? m.content : JSON.stringify(m.content),
|
|
30175
|
-
messageIndex: 0
|
|
30176
|
-
}));
|
|
30177
30574
|
const expectedOutputValue = test.expectedOutput ?? test.expected_output;
|
|
30178
30575
|
const expectedOutput = expectedOutputValue ? [
|
|
30179
30576
|
{ role: "assistant", content: expectedOutputValue }
|
|
@@ -30202,7 +30599,6 @@ async function evaluate(config) {
|
|
|
30202
30599
|
criteria: test.criteria ?? "",
|
|
30203
30600
|
question: String(question),
|
|
30204
30601
|
input,
|
|
30205
|
-
input_segments: inputSegments,
|
|
30206
30602
|
expected_output: expectedOutput,
|
|
30207
30603
|
reference_answer: expectedOutputValue,
|
|
30208
30604
|
file_paths: [],
|
|
@@ -30266,10 +30662,10 @@ function computeSummary(results, durationMs) {
|
|
|
30266
30662
|
var TARGET_FILE_CANDIDATES = [".agentv/targets.yaml", ".agentv/targets.yml"];
|
|
30267
30663
|
async function discoverDefaultTarget(repoRoot) {
|
|
30268
30664
|
const cwd = process.cwd();
|
|
30269
|
-
const chain = buildDirectoryChain(
|
|
30665
|
+
const chain = buildDirectoryChain(path43.join(cwd, "_placeholder"), repoRoot);
|
|
30270
30666
|
for (const dir of chain) {
|
|
30271
30667
|
for (const candidate of TARGET_FILE_CANDIDATES) {
|
|
30272
|
-
const targetsPath =
|
|
30668
|
+
const targetsPath = path43.join(dir, candidate);
|
|
30273
30669
|
if (!existsSync4(targetsPath)) continue;
|
|
30274
30670
|
try {
|
|
30275
30671
|
const definitions = await readTargetDefinitions(targetsPath);
|
|
@@ -30286,7 +30682,7 @@ async function loadEnvHierarchy(repoRoot, startPath) {
|
|
|
30286
30682
|
const chain = buildDirectoryChain(startPath, repoRoot);
|
|
30287
30683
|
const envFiles = [];
|
|
30288
30684
|
for (const dir of chain) {
|
|
30289
|
-
const envPath =
|
|
30685
|
+
const envPath = path43.join(dir, ".env");
|
|
30290
30686
|
if (existsSync4(envPath)) envFiles.push(envPath);
|
|
30291
30687
|
}
|
|
30292
30688
|
for (let i = 0; i < envFiles.length; i++) {
|
|
@@ -30475,13 +30871,13 @@ var ResponseCache = class {
|
|
|
30475
30871
|
}
|
|
30476
30872
|
async set(key, value) {
|
|
30477
30873
|
const filePath = this.keyToPath(key);
|
|
30478
|
-
const dir =
|
|
30479
|
-
await
|
|
30874
|
+
const dir = path44.dirname(filePath);
|
|
30875
|
+
await mkdir15(dir, { recursive: true });
|
|
30480
30876
|
await writeFile8(filePath, JSON.stringify(value, null, 2), "utf8");
|
|
30481
30877
|
}
|
|
30482
30878
|
keyToPath(key) {
|
|
30483
30879
|
const prefix = key.slice(0, 2);
|
|
30484
|
-
return
|
|
30880
|
+
return path44.join(this.cachePath, prefix, `${key}.json`);
|
|
30485
30881
|
}
|
|
30486
30882
|
};
|
|
30487
30883
|
function shouldEnableCache(params) {
|
|
@@ -30582,11 +30978,11 @@ var OtelTraceExporter = class {
|
|
|
30582
30978
|
async init() {
|
|
30583
30979
|
try {
|
|
30584
30980
|
const [sdkTraceNode, resourcesMod, semconvMod, api, coreMod] = await Promise.all([
|
|
30585
|
-
import("./src-
|
|
30586
|
-
import("./esm-
|
|
30981
|
+
import("./src-PXDA7QIS.js"),
|
|
30982
|
+
import("./esm-UYZ3HJBU.js"),
|
|
30587
30983
|
import("./esm-RVQPUGWH.js"),
|
|
30588
30984
|
import("./esm-R77SNOF5.js"),
|
|
30589
|
-
import("./esm-
|
|
30985
|
+
import("./esm-OJ2BXJK4-YKEI3Z7E.js").catch(() => null)
|
|
30590
30986
|
]);
|
|
30591
30987
|
const { NodeTracerProvider: Provider, SimpleSpanProcessor } = sdkTraceNode;
|
|
30592
30988
|
const { resourceFromAttributes } = resourcesMod;
|
|
@@ -30605,13 +31001,13 @@ var OtelTraceExporter = class {
|
|
|
30605
31001
|
processors.push(new SimpleSpanProcessor(exporter));
|
|
30606
31002
|
}
|
|
30607
31003
|
if (this.options.otlpFilePath) {
|
|
30608
|
-
const { OtlpJsonFileExporter: OtlpJsonFileExporter2 } = await import("./otlp-json-file-exporter-
|
|
31004
|
+
const { OtlpJsonFileExporter: OtlpJsonFileExporter2 } = await import("./otlp-json-file-exporter-VN67MK3S-RQIM6EHY.js");
|
|
30609
31005
|
processors.push(
|
|
30610
31006
|
new SimpleSpanProcessor(new OtlpJsonFileExporter2(this.options.otlpFilePath))
|
|
30611
31007
|
);
|
|
30612
31008
|
}
|
|
30613
31009
|
if (this.options.traceFilePath) {
|
|
30614
|
-
const { SimpleTraceFileExporter: SimpleTraceFileExporter2 } = await import("./simple-trace-file-exporter-
|
|
31010
|
+
const { SimpleTraceFileExporter: SimpleTraceFileExporter2 } = await import("./simple-trace-file-exporter-XWZTIZR2-4JKATE5G.js");
|
|
30615
31011
|
processors.push(
|
|
30616
31012
|
new SimpleSpanProcessor(new SimpleTraceFileExporter2(this.options.traceFilePath))
|
|
30617
31013
|
);
|
|
@@ -31103,4 +31499,4 @@ export {
|
|
|
31103
31499
|
OtelStreamingObserver,
|
|
31104
31500
|
createAgentKernel
|
|
31105
31501
|
};
|
|
31106
|
-
//# sourceMappingURL=chunk-
|
|
31502
|
+
//# sourceMappingURL=chunk-OYD2NB55.js.map
|