agentv 4.38.1 → 4.40.1-next.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/{artifact-writer-MK5X5MSO.js → artifact-writer-GIAIMGPQ.js} +14 -11
- package/dist/{chunk-QOBQ5XYF.js → chunk-76FOHROU.js} +16 -4
- package/dist/chunk-76FOHROU.js.map +1 -0
- package/dist/{chunk-VBHHZQS6.js → chunk-BLXYBUU4.js} +1825 -333
- package/dist/chunk-BLXYBUU4.js.map +1 -0
- package/dist/{chunk-NLTIK3LV.js → chunk-I3SC4FOT.js} +499 -347
- package/dist/chunk-I3SC4FOT.js.map +1 -0
- package/dist/{chunk-OIN3MVOD.js → chunk-S2JJCLHV.js} +67 -68
- package/dist/chunk-S2JJCLHV.js.map +1 -0
- package/dist/chunk-TWQP7JYQ.js +494 -0
- package/dist/chunk-TWQP7JYQ.js.map +1 -0
- package/dist/{chunk-6M5S4IJW.js → chunk-WKA5QDNQ.js} +586 -183
- package/dist/chunk-WKA5QDNQ.js.map +1 -0
- package/dist/cli.js +6 -6
- package/dist/dashboard/assets/index-BnYCCJ7O.css +1 -0
- package/dist/dashboard/assets/index-DaueD7GO.js +118 -0
- package/dist/dashboard/assets/{index-SIl6NbIJ.js → index-_jpKSzIf.js} +1 -1
- package/dist/dashboard/index.html +2 -2
- package/dist/{dist-HVLBDG5F.js → dist-6Z4OSITR.js} +54 -16
- package/dist/index.js +6 -6
- package/dist/{interactive-45LPG2YJ.js → interactive-OUB3GZRC.js} +6 -6
- package/dist/{otlp-json-file-exporter-RJFPCKVK-T6N4OGWG.js → otlp-json-file-exporter-RY63S3IG-PZBQPVYY.js} +2 -2
- package/dist/skills/agentv-eval-writer/SKILL.md +49 -24
- package/dist/skills/agentv-eval-writer/references/custom-evaluators.md +21 -15
- package/dist/{ts-eval-loader-TJT6BGFF-DI7XNSO4.js → ts-eval-loader-NWH3B4HG-UXXCZKLP.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-6M5S4IJW.js.map +0 -1
- package/dist/chunk-DKUAETXE.js +0 -1362
- package/dist/chunk-DKUAETXE.js.map +0 -1
- package/dist/chunk-NLTIK3LV.js.map +0 -1
- package/dist/chunk-OIN3MVOD.js.map +0 -1
- package/dist/chunk-QOBQ5XYF.js.map +0 -1
- package/dist/chunk-VBHHZQS6.js.map +0 -1
- package/dist/dashboard/assets/index-BpnllKET.css +0 -1
- package/dist/dashboard/assets/index-Cm9SUopp.js +0 -118
- /package/dist/{artifact-writer-MK5X5MSO.js.map → artifact-writer-GIAIMGPQ.js.map} +0 -0
- /package/dist/{dist-HVLBDG5F.js.map → dist-6Z4OSITR.js.map} +0 -0
- /package/dist/{interactive-45LPG2YJ.js.map → interactive-OUB3GZRC.js.map} +0 -0
- /package/dist/{otlp-json-file-exporter-RJFPCKVK-T6N4OGWG.js.map → otlp-json-file-exporter-RY63S3IG-PZBQPVYY.js.map} +0 -0
- /package/dist/{ts-eval-loader-TJT6BGFF-DI7XNSO4.js.map → ts-eval-loader-NWH3B4HG-UXXCZKLP.js.map} +0 -0
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
|
-
buildTraceFromMessages,
|
|
4
3
|
external_exports,
|
|
5
4
|
extractLastAssistantContent,
|
|
6
5
|
getAgentvDataDir,
|
|
7
6
|
getRepoCheckoutRef,
|
|
7
|
+
groupTranscriptJsonLines,
|
|
8
8
|
interpolateEnv,
|
|
9
9
|
normalizeRepoIdentity,
|
|
10
10
|
normalizeToolCall,
|
|
11
11
|
parseRepoConfig,
|
|
12
12
|
parseYamlValue,
|
|
13
|
+
readTranscriptJsonl,
|
|
13
14
|
resolveRepoCloneUrl
|
|
14
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-BLXYBUU4.js";
|
|
15
16
|
|
|
16
17
|
// ../../packages/core/dist/index.js
|
|
17
18
|
import { readFileSync } from "node:fs";
|
|
@@ -28,7 +29,7 @@ import {
|
|
|
28
29
|
rmSync,
|
|
29
30
|
writeFileSync
|
|
30
31
|
} from "node:fs";
|
|
31
|
-
import { cp, mkdtemp, readdir, rm, stat } from "node:fs/promises";
|
|
32
|
+
import { cp, lstat, mkdtemp, readdir, rm, stat } from "node:fs/promises";
|
|
32
33
|
import os from "node:os";
|
|
33
34
|
import path3 from "node:path";
|
|
34
35
|
import { promisify } from "node:util";
|
|
@@ -41,7 +42,6 @@ import path4 from "node:path";
|
|
|
41
42
|
import { readdir as readdir3, stat as stat3 } from "node:fs/promises";
|
|
42
43
|
import { homedir as homedir2 } from "node:os";
|
|
43
44
|
import path5 from "node:path";
|
|
44
|
-
import { readFile as readFile2 } from "node:fs/promises";
|
|
45
45
|
function codeGraderInstruction(graderName, description) {
|
|
46
46
|
const desc = description ? ` This grader: ${description}.` : "";
|
|
47
47
|
return `Run \`agentv eval assert ${graderName} --agent-output <agent_output> --agent-input <original_prompt>\` and check the result.${desc} The command accepts --agent-output (the agent's full response text) and --agent-input (the original user prompt). It returns JSON on stdout: {"score": 0-1, "reasoning": "..."}. A score >= 0.5 means pass (exit 0); below 0.5 means fail (exit 1).`;
|
|
@@ -529,6 +529,8 @@ var RESULTS_REPO_RESULTS_DIR = ".agentv/results";
|
|
|
529
529
|
var RESULTS_REPO_RUNS_DIR = `${RESULTS_REPO_RESULTS_DIR}/runs`;
|
|
530
530
|
var RESULTS_REPO_COMMIT_EMAIL = "agentv@results-repo";
|
|
531
531
|
var RESULTS_REPO_COMMIT_NAME = "AgentV Results";
|
|
532
|
+
var DEFAULT_RESULTS_BRANCH = "agentv/results/v1";
|
|
533
|
+
var GIT_EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
532
534
|
var activeResultsRepoSyncs = /* @__PURE__ */ new Set();
|
|
533
535
|
function sanitizeRepoSlug(repo) {
|
|
534
536
|
return repo.trim().replace(/[^A-Za-z0-9._-]+/g, "-");
|
|
@@ -547,16 +549,26 @@ function expandHome(p) {
|
|
|
547
549
|
}
|
|
548
550
|
return p;
|
|
549
551
|
}
|
|
550
|
-
function normalizeResultsConfig(config) {
|
|
551
|
-
const
|
|
552
|
-
const
|
|
553
|
-
const
|
|
552
|
+
function normalizeResultsConfig(config, options) {
|
|
553
|
+
const repoUrl = (config.repo_url ?? config.repo)?.trim();
|
|
554
|
+
const repoPath = config.repo_path?.trim();
|
|
555
|
+
const repo = repoUrl ?? repoPath ?? "";
|
|
556
|
+
const branch = config.branch?.trim() || (repoPath ? DEFAULT_RESULTS_BRANCH : void 0);
|
|
557
|
+
const remote = config.remote?.trim() || "origin";
|
|
558
|
+
const autoPush = config.sync?.auto_push ?? config.auto_push === true;
|
|
559
|
+
const requirePush = config.sync?.require_push === true;
|
|
560
|
+
const resolvedRepoPath = repoPath ? path3.resolve(options?.baseDir ?? process.cwd(), expandHome(repoPath)) : void 0;
|
|
561
|
+
const resolvedPath = config.path ? expandHome(config.path.trim()) : repoUrl ? path3.join(getAgentvDataDir(), "results", sanitizeRepoSlug(repoUrl)) : resolvedRepoPath ?? path3.join(getAgentvDataDir(), "results", sanitizeRepoSlug(repo));
|
|
554
562
|
return {
|
|
555
563
|
mode: "github",
|
|
556
564
|
repo,
|
|
565
|
+
...repoUrl ? { repo_url: repoUrl } : {},
|
|
566
|
+
...resolvedRepoPath ? { repo_path: resolvedRepoPath } : {},
|
|
557
567
|
...branch ? { branch } : {},
|
|
568
|
+
remote,
|
|
558
569
|
path: resolvedPath,
|
|
559
|
-
auto_push:
|
|
570
|
+
auto_push: autoPush,
|
|
571
|
+
require_push: requirePush,
|
|
560
572
|
branch_prefix: config.branch_prefix?.trim() || "eval-results"
|
|
561
573
|
};
|
|
562
574
|
}
|
|
@@ -614,10 +626,11 @@ function getGitEnv() {
|
|
|
614
626
|
env[key] = value;
|
|
615
627
|
}
|
|
616
628
|
}
|
|
629
|
+
env.GIT_TERMINAL_PROMPT = "0";
|
|
617
630
|
return env;
|
|
618
631
|
}
|
|
619
632
|
async function runGit(args, options) {
|
|
620
|
-
return runCommand("git", args, { ...options, env: getGitEnv() });
|
|
633
|
+
return runCommand("git", args, { ...options, env: { ...getGitEnv(), ...options?.env } });
|
|
621
634
|
}
|
|
622
635
|
async function runGh(args, options) {
|
|
623
636
|
return runCommand("gh", args, options);
|
|
@@ -645,40 +658,34 @@ async function resolveDefaultBranch(repoDir) {
|
|
|
645
658
|
}
|
|
646
659
|
return "main";
|
|
647
660
|
}
|
|
648
|
-
async function fetchResultsRepo(repoDir) {
|
|
649
|
-
await runGit(["fetch",
|
|
661
|
+
async function fetchResultsRepo(repoDir, remote = "origin") {
|
|
662
|
+
await runGit(["fetch", remote, "--prune"], { cwd: repoDir });
|
|
650
663
|
}
|
|
651
|
-
function remoteBranchRef(branch) {
|
|
652
|
-
return
|
|
664
|
+
function remoteBranchRef(branch, remote = "origin") {
|
|
665
|
+
return `${remote}/${branch}`;
|
|
653
666
|
}
|
|
654
|
-
function
|
|
655
|
-
const branch = config.branch ?? "<unknown>";
|
|
656
|
-
return new Error(
|
|
657
|
-
[
|
|
658
|
-
`Results repo remote branch '${branch}' does not exist in ${config.repo}.`,
|
|
659
|
-
"Create the storage branch once, then retry. Example:",
|
|
660
|
-
` git clone ${resolveResultsRepoUrl(config.repo)} /tmp/agentv-results-init`,
|
|
661
|
-
" cd /tmp/agentv-results-init",
|
|
662
|
-
` git switch --orphan ${branch}`,
|
|
663
|
-
" git rm -rf .",
|
|
664
|
-
' git commit --allow-empty -m "chore(results): initialize AgentV results branch"',
|
|
665
|
-
` git push origin HEAD:${branch}`
|
|
666
|
-
].join("\n")
|
|
667
|
-
);
|
|
668
|
-
}
|
|
669
|
-
async function assertConfiguredResultsBranchExists(repoDir, config) {
|
|
670
|
-
if (!config.branch) {
|
|
671
|
-
return void 0;
|
|
672
|
-
}
|
|
673
|
-
const ref = remoteBranchRef(config.branch);
|
|
667
|
+
async function gitRefExists(repoDir, ref) {
|
|
674
668
|
const { stdout } = await runGit(["rev-parse", "--verify", `${ref}^{commit}`], {
|
|
675
669
|
cwd: repoDir,
|
|
676
670
|
check: false
|
|
677
671
|
});
|
|
678
|
-
|
|
679
|
-
|
|
672
|
+
return stdout.trim().length > 0;
|
|
673
|
+
}
|
|
674
|
+
async function configuredResultsBranchRef(repoDir, config) {
|
|
675
|
+
if (!config.branch) {
|
|
676
|
+
return void 0;
|
|
677
|
+
}
|
|
678
|
+
const remoteRef = remoteBranchRef(config.branch, config.remote);
|
|
679
|
+
if (await gitRefExists(repoDir, remoteRef)) {
|
|
680
|
+
return remoteRef;
|
|
680
681
|
}
|
|
681
|
-
|
|
682
|
+
if (await gitRefExists(repoDir, config.branch)) {
|
|
683
|
+
return config.branch;
|
|
684
|
+
}
|
|
685
|
+
return void 0;
|
|
686
|
+
}
|
|
687
|
+
async function assertConfiguredResultsBranchExists(repoDir, config) {
|
|
688
|
+
return configuredResultsBranchRef(repoDir, config);
|
|
682
689
|
}
|
|
683
690
|
async function localBranchExists(repoDir, branch) {
|
|
684
691
|
const { stdout } = await runGit(["rev-parse", "--verify", `refs/heads/${branch}`], {
|
|
@@ -688,24 +695,40 @@ async function localBranchExists(repoDir, branch) {
|
|
|
688
695
|
return stdout.trim().length > 0;
|
|
689
696
|
}
|
|
690
697
|
async function checkoutConfiguredResultsBranch(repoDir, config) {
|
|
698
|
+
const branch = config.branch;
|
|
699
|
+
if (!branch) {
|
|
700
|
+
return void 0;
|
|
701
|
+
}
|
|
691
702
|
const remoteRef = await assertConfiguredResultsBranchExists(repoDir, config);
|
|
692
|
-
if (!
|
|
703
|
+
if (!remoteRef) {
|
|
704
|
+
await createOrphanResultsBranch(repoDir, branch);
|
|
705
|
+
await runGit(["checkout", branch], { cwd: repoDir });
|
|
693
706
|
return void 0;
|
|
694
707
|
}
|
|
695
708
|
const currentBranch = await getCurrentBranch(repoDir);
|
|
696
|
-
if (currentBranch !==
|
|
697
|
-
if (await localBranchExists(repoDir,
|
|
698
|
-
await runGit(["checkout",
|
|
709
|
+
if (currentBranch !== branch) {
|
|
710
|
+
if (await localBranchExists(repoDir, branch)) {
|
|
711
|
+
await runGit(["checkout", branch], { cwd: repoDir });
|
|
699
712
|
} else {
|
|
700
|
-
await runGit(["checkout", "--track", "-b",
|
|
713
|
+
await runGit(["checkout", "--track", "-b", branch, remoteRef], { cwd: repoDir });
|
|
701
714
|
}
|
|
702
715
|
}
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
716
|
+
if (remoteRef === remoteBranchRef(branch, config.remote)) {
|
|
717
|
+
await runGit(["branch", "--set-upstream-to", remoteRef, branch], {
|
|
718
|
+
cwd: repoDir,
|
|
719
|
+
check: false
|
|
720
|
+
});
|
|
721
|
+
}
|
|
707
722
|
return remoteRef;
|
|
708
723
|
}
|
|
724
|
+
async function createOrphanResultsBranch(repoDir, branch) {
|
|
725
|
+
await ensureResultsRepoCommitIdentity(repoDir);
|
|
726
|
+
const { stdout } = await runGit(
|
|
727
|
+
["commit-tree", GIT_EMPTY_TREE, "-m", "chore(results): initialize AgentV results branch"],
|
|
728
|
+
{ cwd: repoDir }
|
|
729
|
+
);
|
|
730
|
+
await runGit(["update-ref", `refs/heads/${branch}`, stdout.trim()], { cwd: repoDir });
|
|
731
|
+
}
|
|
709
732
|
async function isGitRepository(repoDir) {
|
|
710
733
|
try {
|
|
711
734
|
const { stdout } = await runGit(["rev-parse", "--is-inside-work-tree"], { cwd: repoDir });
|
|
@@ -714,8 +737,13 @@ async function isGitRepository(repoDir) {
|
|
|
714
737
|
return false;
|
|
715
738
|
}
|
|
716
739
|
}
|
|
740
|
+
async function resolveGitTopLevel(repoDir) {
|
|
741
|
+
const { stdout } = await runGit(["rev-parse", "--show-toplevel"], { cwd: repoDir });
|
|
742
|
+
return stdout.trim() || repoDir;
|
|
743
|
+
}
|
|
717
744
|
function updateStatusFile(config, patch) {
|
|
718
|
-
const
|
|
745
|
+
const repo = typeof config.repo === "string" ? config.repo : config.repo_url ?? config.repo_path ?? "";
|
|
746
|
+
const cachePaths = getResultsRepoLocalPaths(repo);
|
|
719
747
|
const current = readPersistedStatus(cachePaths.statusFile);
|
|
720
748
|
writePersistedStatus(cachePaths.statusFile, {
|
|
721
749
|
...current,
|
|
@@ -724,6 +752,12 @@ function updateStatusFile(config, patch) {
|
|
|
724
752
|
}
|
|
725
753
|
async function ensureResultsRepoClone(config) {
|
|
726
754
|
const normalized = normalizeResultsConfig(config);
|
|
755
|
+
if (normalized.repo_path) {
|
|
756
|
+
if (!await isGitRepository(normalized.repo_path)) {
|
|
757
|
+
throw new Error(`Results repo_path is not a git repository: ${normalized.repo_path}`);
|
|
758
|
+
}
|
|
759
|
+
return resolveGitTopLevel(normalized.repo_path);
|
|
760
|
+
}
|
|
727
761
|
const cachePaths = getResultsRepoLocalPaths(normalized.repo);
|
|
728
762
|
const cloneDir = normalized.path;
|
|
729
763
|
mkdirSync(cachePaths.rootDir, { recursive: true });
|
|
@@ -736,7 +770,7 @@ async function ensureResultsRepoClone(config) {
|
|
|
736
770
|
await runGit([
|
|
737
771
|
"clone",
|
|
738
772
|
"--filter=blob:none",
|
|
739
|
-
resolveResultsRepoUrl(normalized.repo),
|
|
773
|
+
resolveResultsRepoUrl(normalized.repo_url ?? normalized.repo),
|
|
740
774
|
cloneDir
|
|
741
775
|
]);
|
|
742
776
|
return cloneDir;
|
|
@@ -767,8 +801,10 @@ function getResultsRepoStatus(config) {
|
|
|
767
801
|
configured: true,
|
|
768
802
|
available: existsSync(normalized.path),
|
|
769
803
|
repo: normalized.repo,
|
|
804
|
+
...normalized.repo_path !== void 0 && { repo_path: normalized.repo_path },
|
|
770
805
|
path: normalized.path,
|
|
771
806
|
auto_push: normalized.auto_push,
|
|
807
|
+
require_push: normalized.require_push,
|
|
772
808
|
branch_prefix: normalized.branch_prefix,
|
|
773
809
|
local_dir: normalized.path,
|
|
774
810
|
last_synced_at: persisted.last_synced_at,
|
|
@@ -822,7 +858,7 @@ async function resolveComparisonRef(repoDir, config) {
|
|
|
822
858
|
return upstreamRef;
|
|
823
859
|
}
|
|
824
860
|
const baseBranch = await resolveDefaultBranch(repoDir);
|
|
825
|
-
const fallback =
|
|
861
|
+
const fallback = `${config?.remote ?? "origin"}/${baseBranch}`;
|
|
826
862
|
const { stdout: fallbackSha } = await runGit(["rev-parse", "--verify", fallback], {
|
|
827
863
|
cwd: repoDir,
|
|
828
864
|
check: false
|
|
@@ -845,6 +881,56 @@ async function getAheadBehind(repoDir, upstream) {
|
|
|
845
881
|
...Number.isFinite(behind) && { behind }
|
|
846
882
|
};
|
|
847
883
|
}
|
|
884
|
+
async function getAheadBehindForRefs(repoDir, leftRef, rightRef) {
|
|
885
|
+
const { stdout } = await runGit(
|
|
886
|
+
["rev-list", "--left-right", "--count", `${leftRef}...${rightRef}`],
|
|
887
|
+
{
|
|
888
|
+
cwd: repoDir,
|
|
889
|
+
check: false
|
|
890
|
+
}
|
|
891
|
+
);
|
|
892
|
+
const [aheadText, behindText] = stdout.trim().split(/\s+/);
|
|
893
|
+
const ahead = Number.parseInt(aheadText ?? "", 10);
|
|
894
|
+
const behind = Number.parseInt(behindText ?? "", 10);
|
|
895
|
+
return {
|
|
896
|
+
...Number.isFinite(ahead) && { ahead },
|
|
897
|
+
...Number.isFinite(behind) && { behind }
|
|
898
|
+
};
|
|
899
|
+
}
|
|
900
|
+
async function inspectResultsStorageBranchGit(repoDir, config) {
|
|
901
|
+
if (!config.branch) {
|
|
902
|
+
return {
|
|
903
|
+
syncStatus: "clean",
|
|
904
|
+
dirtyPaths: [],
|
|
905
|
+
conflictedPaths: []
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
const localRef = `refs/heads/${config.branch}`;
|
|
909
|
+
const upstream = remoteBranchRef(config.branch, config.remote);
|
|
910
|
+
const localExists = await gitRefExists(repoDir, localRef);
|
|
911
|
+
const remoteExists = await gitRefExists(repoDir, upstream);
|
|
912
|
+
const { ahead = 0, behind = 0 } = localExists && remoteExists ? await getAheadBehindForRefs(repoDir, localRef, upstream) : {
|
|
913
|
+
ahead: localExists && !remoteExists ? 1 : 0,
|
|
914
|
+
behind: !localExists && remoteExists ? 1 : 0
|
|
915
|
+
};
|
|
916
|
+
let syncStatus = "clean";
|
|
917
|
+
if (ahead > 0 && behind > 0) {
|
|
918
|
+
syncStatus = "diverged";
|
|
919
|
+
} else if (behind > 0) {
|
|
920
|
+
syncStatus = "behind";
|
|
921
|
+
} else if (ahead > 0) {
|
|
922
|
+
syncStatus = "ahead";
|
|
923
|
+
}
|
|
924
|
+
return {
|
|
925
|
+
syncStatus,
|
|
926
|
+
branch: config.branch,
|
|
927
|
+
...remoteExists && { upstream },
|
|
928
|
+
ahead,
|
|
929
|
+
behind,
|
|
930
|
+
dirtyPaths: [],
|
|
931
|
+
conflictedPaths: []
|
|
932
|
+
};
|
|
933
|
+
}
|
|
848
934
|
async function hasInProgressGitConflict(repoDir) {
|
|
849
935
|
const markers = ["MERGE_HEAD", "CHERRY_PICK_HEAD", "REVERT_HEAD", "REBASE_HEAD"];
|
|
850
936
|
for (const marker of markers) {
|
|
@@ -971,18 +1057,19 @@ function isSafeResultsRepoPath(p) {
|
|
|
971
1057
|
function areSafeResultsRepoPaths(paths) {
|
|
972
1058
|
return paths.length > 0 && paths.every(isSafeResultsRepoPath);
|
|
973
1059
|
}
|
|
974
|
-
async function getAheadPaths(repoDir, upstream) {
|
|
1060
|
+
async function getAheadPaths(repoDir, upstream, branch = "HEAD") {
|
|
975
1061
|
if (!upstream) {
|
|
976
1062
|
return [];
|
|
977
1063
|
}
|
|
978
|
-
const { stdout } = await runGit(["diff", "--name-only", `${upstream}
|
|
1064
|
+
const { stdout } = await runGit(["diff", "--name-only", `${upstream}..${branch}`], {
|
|
979
1065
|
cwd: repoDir,
|
|
980
1066
|
check: false
|
|
981
1067
|
});
|
|
982
1068
|
return stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).sort();
|
|
983
1069
|
}
|
|
984
|
-
function getPushTargetBranch(upstream, baseBranch) {
|
|
985
|
-
|
|
1070
|
+
function getPushTargetBranch(upstream, baseBranch, remote = "origin") {
|
|
1071
|
+
const prefix = `${remote}/`;
|
|
1072
|
+
return upstream?.startsWith(prefix) ? upstream.slice(prefix.length) : baseBranch;
|
|
986
1073
|
}
|
|
987
1074
|
async function statusFromInspection(normalized, repoDir) {
|
|
988
1075
|
return withGitInspection(
|
|
@@ -1009,8 +1096,15 @@ async function getResultsRepoSyncStatus(config) {
|
|
|
1009
1096
|
};
|
|
1010
1097
|
}
|
|
1011
1098
|
try {
|
|
1099
|
+
if (normalized.repo_path) {
|
|
1100
|
+
await fetchResultsRepo(normalized.path, normalized.remote).catch(() => void 0);
|
|
1101
|
+
return withGitInspection(
|
|
1102
|
+
baseStatus,
|
|
1103
|
+
await inspectResultsStorageBranchGit(normalized.path, normalized)
|
|
1104
|
+
);
|
|
1105
|
+
}
|
|
1012
1106
|
if (normalized.branch) {
|
|
1013
|
-
await fetchResultsRepo(normalized.path);
|
|
1107
|
+
await fetchResultsRepo(normalized.path, normalized.remote).catch(() => void 0);
|
|
1014
1108
|
await checkoutConfiguredResultsBranch(normalized.path, normalized);
|
|
1015
1109
|
}
|
|
1016
1110
|
return withGitInspection(baseStatus, await inspectResultsRepoGit(normalized.path, normalized));
|
|
@@ -1027,8 +1121,10 @@ async function syncResultsRepo(config) {
|
|
|
1027
1121
|
const normalized = normalizeResultsConfig(config);
|
|
1028
1122
|
try {
|
|
1029
1123
|
const repoDir = await ensureResultsRepoClone(normalized);
|
|
1030
|
-
await fetchResultsRepo(repoDir);
|
|
1031
|
-
|
|
1124
|
+
await fetchResultsRepo(repoDir, normalized.remote);
|
|
1125
|
+
if (!normalized.repo_path) {
|
|
1126
|
+
await checkoutConfiguredResultsBranch(repoDir, normalized);
|
|
1127
|
+
}
|
|
1032
1128
|
updateStatusFile(normalized, {
|
|
1033
1129
|
last_synced_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1034
1130
|
last_error: void 0
|
|
@@ -1061,7 +1157,59 @@ async function syncResultsRepoForProject(config) {
|
|
|
1061
1157
|
let commitCreated = false;
|
|
1062
1158
|
try {
|
|
1063
1159
|
const repoDir = await ensureResultsRepoClone(normalized);
|
|
1064
|
-
|
|
1160
|
+
if (normalized.repo_path) {
|
|
1161
|
+
try {
|
|
1162
|
+
await fetchResultsRepo(repoDir, normalized.remote);
|
|
1163
|
+
} catch (error) {
|
|
1164
|
+
if (normalized.require_push) {
|
|
1165
|
+
throw error;
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
if (normalized.auto_push || normalized.require_push) {
|
|
1169
|
+
if (normalized.branch) {
|
|
1170
|
+
const localRef = `refs/heads/${normalized.branch}`;
|
|
1171
|
+
if (await gitRefExists(repoDir, localRef)) {
|
|
1172
|
+
try {
|
|
1173
|
+
await runGit(
|
|
1174
|
+
[
|
|
1175
|
+
"push",
|
|
1176
|
+
"--porcelain",
|
|
1177
|
+
normalized.remote,
|
|
1178
|
+
`${localRef}:refs/heads/${normalized.branch}`
|
|
1179
|
+
],
|
|
1180
|
+
{ cwd: repoDir }
|
|
1181
|
+
);
|
|
1182
|
+
pushPerformed = true;
|
|
1183
|
+
} catch (error) {
|
|
1184
|
+
updateStatusFile(normalized, { last_error: getStatusMessage(error) });
|
|
1185
|
+
if (normalized.require_push) {
|
|
1186
|
+
throw error;
|
|
1187
|
+
}
|
|
1188
|
+
const status = await getResultsRepoSyncStatus(normalized);
|
|
1189
|
+
return withBlockedStatus(
|
|
1190
|
+
status,
|
|
1191
|
+
`Results repo push was rejected: ${getStatusMessage(error)}`,
|
|
1192
|
+
{
|
|
1193
|
+
pullPerformed,
|
|
1194
|
+
pushPerformed,
|
|
1195
|
+
commitCreated
|
|
1196
|
+
}
|
|
1197
|
+
);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
updateStatusFile(normalized, {
|
|
1203
|
+
last_synced_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1204
|
+
last_error: void 0
|
|
1205
|
+
});
|
|
1206
|
+
return withActionFlags(await getResultsRepoSyncStatus(normalized), {
|
|
1207
|
+
pullPerformed,
|
|
1208
|
+
pushPerformed,
|
|
1209
|
+
commitCreated
|
|
1210
|
+
});
|
|
1211
|
+
}
|
|
1212
|
+
await fetchResultsRepo(repoDir, normalized.remote);
|
|
1065
1213
|
await checkoutConfiguredResultsBranch(repoDir, normalized);
|
|
1066
1214
|
let inspection = await inspectResultsRepoGit(repoDir, normalized);
|
|
1067
1215
|
if (inspection.syncStatus === "conflicted") {
|
|
@@ -1198,14 +1346,14 @@ async function syncResultsRepoForProject(config) {
|
|
|
1198
1346
|
});
|
|
1199
1347
|
}
|
|
1200
1348
|
const baseBranch = normalized.branch ?? await resolveDefaultBranch(repoDir);
|
|
1201
|
-
const targetBranch = getPushTargetBranch(inspection.upstream, baseBranch);
|
|
1349
|
+
const targetBranch = getPushTargetBranch(inspection.upstream, baseBranch, normalized.remote);
|
|
1202
1350
|
try {
|
|
1203
|
-
await runGit(["push",
|
|
1351
|
+
await runGit(["push", normalized.remote, `HEAD:${targetBranch}`], { cwd: repoDir });
|
|
1204
1352
|
pushPerformed = true;
|
|
1205
|
-
await fetchResultsRepo(repoDir);
|
|
1353
|
+
await fetchResultsRepo(repoDir, normalized.remote);
|
|
1206
1354
|
inspection = await inspectResultsRepoGit(repoDir, normalized);
|
|
1207
1355
|
} catch (error) {
|
|
1208
|
-
await fetchResultsRepo(repoDir).catch(() => void 0);
|
|
1356
|
+
await fetchResultsRepo(repoDir, normalized.remote).catch(() => void 0);
|
|
1209
1357
|
inspection = await inspectResultsRepoGit(repoDir, normalized);
|
|
1210
1358
|
const status = withGitInspection(getResultsRepoStatus(normalized), inspection);
|
|
1211
1359
|
const reason = `Results repo push was rejected: ${getStatusMessage(error)}`;
|
|
@@ -1239,8 +1387,10 @@ async function checkoutResultsRepoBranch(config, branchName) {
|
|
|
1239
1387
|
const normalized = normalizeResultsConfig(config);
|
|
1240
1388
|
const repoDir = await ensureResultsRepoClone(normalized);
|
|
1241
1389
|
const baseBranch = await resolveDefaultBranch(repoDir);
|
|
1242
|
-
await fetchResultsRepo(repoDir);
|
|
1243
|
-
await runGit(["checkout", "-B", branchName,
|
|
1390
|
+
await fetchResultsRepo(repoDir, normalized.remote);
|
|
1391
|
+
await runGit(["checkout", "-B", branchName, `${normalized.remote}/${baseBranch}`], {
|
|
1392
|
+
cwd: repoDir
|
|
1393
|
+
});
|
|
1244
1394
|
updateStatusFile(normalized, { last_error: void 0 });
|
|
1245
1395
|
return {
|
|
1246
1396
|
branchName,
|
|
@@ -1252,12 +1402,15 @@ async function prepareResultsRepoBranch(config, branchName) {
|
|
|
1252
1402
|
const normalized = normalizeResultsConfig(config);
|
|
1253
1403
|
const cloneDir = await ensureResultsRepoClone(normalized);
|
|
1254
1404
|
const baseBranch = await resolveDefaultBranch(cloneDir);
|
|
1255
|
-
await fetchResultsRepo(cloneDir);
|
|
1405
|
+
await fetchResultsRepo(cloneDir, normalized.remote);
|
|
1256
1406
|
const worktreeRoot = await mkdtemp(path3.join(os.tmpdir(), "agentv-results-repo-"));
|
|
1257
1407
|
const worktreeDir = path3.join(worktreeRoot, "repo");
|
|
1258
|
-
await runGit(
|
|
1259
|
-
|
|
1260
|
-
|
|
1408
|
+
await runGit(
|
|
1409
|
+
["worktree", "add", "-B", branchName, worktreeDir, `${normalized.remote}/${baseBranch}`],
|
|
1410
|
+
{
|
|
1411
|
+
cwd: cloneDir
|
|
1412
|
+
}
|
|
1413
|
+
);
|
|
1261
1414
|
return {
|
|
1262
1415
|
branchName,
|
|
1263
1416
|
baseBranch,
|
|
@@ -1307,7 +1460,7 @@ async function commitAndPushResultsBranch(params) {
|
|
|
1307
1460
|
}
|
|
1308
1461
|
async function pushResultsRepoBranch(config, branchName, cwd) {
|
|
1309
1462
|
const normalized = normalizeResultsConfig(config);
|
|
1310
|
-
await runGit(["push", "-u",
|
|
1463
|
+
await runGit(["push", "-u", normalized.remote, branchName], {
|
|
1311
1464
|
cwd: cwd ?? normalized.path
|
|
1312
1465
|
});
|
|
1313
1466
|
updateStatusFile(normalized, {
|
|
@@ -1337,27 +1490,230 @@ async function createDraftResultsPr(params) {
|
|
|
1337
1490
|
return stdout.trim();
|
|
1338
1491
|
}
|
|
1339
1492
|
var DIRECT_PUSH_MAX_RETRIES = 3;
|
|
1340
|
-
async function hasUnpushedCommits(repoDir, upstreamRef) {
|
|
1341
|
-
const { stdout } = await runGit(["rev-list", "--count", `${upstreamRef}..
|
|
1493
|
+
async function hasUnpushedCommits(repoDir, upstreamRef, branch) {
|
|
1494
|
+
const { stdout } = await runGit(["rev-list", "--count", `${upstreamRef}..refs/heads/${branch}`], {
|
|
1342
1495
|
cwd: repoDir,
|
|
1343
1496
|
check: false
|
|
1344
1497
|
});
|
|
1345
1498
|
return Number.parseInt(stdout.trim(), 10) > 0;
|
|
1346
1499
|
}
|
|
1500
|
+
async function countUnpushedCommits(repoDir, upstreamRef, branch) {
|
|
1501
|
+
const { stdout } = await runGit(["rev-list", "--count", `${upstreamRef}..refs/heads/${branch}`], {
|
|
1502
|
+
cwd: repoDir,
|
|
1503
|
+
check: false
|
|
1504
|
+
});
|
|
1505
|
+
const count = Number.parseInt(stdout.trim(), 10);
|
|
1506
|
+
return Number.isFinite(count) ? count : 0;
|
|
1507
|
+
}
|
|
1508
|
+
async function assertValidResultsBranchName(repoDir, branch) {
|
|
1509
|
+
if (branch.length === 0 || branch.includes("..") || branch.startsWith("/") || branch.endsWith("/") || branch.endsWith(".lock") || [...branch].some((char) => {
|
|
1510
|
+
const code = char.charCodeAt(0);
|
|
1511
|
+
return code <= 31 || code === 127;
|
|
1512
|
+
})) {
|
|
1513
|
+
throw new Error(`Invalid results branch name: ${branch}`);
|
|
1514
|
+
}
|
|
1515
|
+
await runGit(["check-ref-format", "--branch", branch], { cwd: repoDir });
|
|
1516
|
+
}
|
|
1517
|
+
function normalizeDestinationPath(destinationPath) {
|
|
1518
|
+
const normalized = destinationPath.split(path3.sep).join("/");
|
|
1519
|
+
const segments = normalized.split("/").filter(Boolean);
|
|
1520
|
+
if (segments.length === 0 || normalized.startsWith("/") || segments.some((segment) => segment === "..")) {
|
|
1521
|
+
throw new Error(`Invalid results destination path: ${destinationPath}`);
|
|
1522
|
+
}
|
|
1523
|
+
return segments.join("/");
|
|
1524
|
+
}
|
|
1525
|
+
async function listSourceFiles(sourceDir) {
|
|
1526
|
+
const entries = [];
|
|
1527
|
+
async function visit(dir) {
|
|
1528
|
+
for (const entry of await readdir(dir, { withFileTypes: true })) {
|
|
1529
|
+
const absolutePath = path3.join(dir, entry.name);
|
|
1530
|
+
if (entry.isDirectory()) {
|
|
1531
|
+
await visit(absolutePath);
|
|
1532
|
+
} else if (entry.isFile() || entry.isSymbolicLink()) {
|
|
1533
|
+
entries.push(absolutePath);
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
await visit(sourceDir);
|
|
1538
|
+
entries.sort();
|
|
1539
|
+
return entries;
|
|
1540
|
+
}
|
|
1541
|
+
async function getExistingRunTreePaths(repoDir, ref, destinationTreePath) {
|
|
1542
|
+
if (!ref) {
|
|
1543
|
+
return [];
|
|
1544
|
+
}
|
|
1545
|
+
const { stdout } = await runGit(["ls-tree", "-r", "--name-only", ref, destinationTreePath], {
|
|
1546
|
+
cwd: repoDir,
|
|
1547
|
+
check: false
|
|
1548
|
+
});
|
|
1549
|
+
return stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
1550
|
+
}
|
|
1551
|
+
async function resolveStorageBranchBase(params) {
|
|
1552
|
+
const localRef = `refs/heads/${params.normalized.branch}`;
|
|
1553
|
+
const remoteRef = `refs/remotes/${params.normalized.remote}/${params.normalized.branch}`;
|
|
1554
|
+
const localExists = await gitRefExists(params.repoDir, localRef);
|
|
1555
|
+
const remoteExists = await gitRefExists(params.repoDir, remoteRef);
|
|
1556
|
+
const baseRef = params.preferRemote ? remoteExists ? remoteRef : localExists ? localRef : void 0 : localExists ? localRef : remoteExists ? remoteRef : void 0;
|
|
1557
|
+
const baseCommit = baseRef ? (await runGit(["rev-parse", `${baseRef}^{commit}`], {
|
|
1558
|
+
cwd: params.repoDir
|
|
1559
|
+
})).stdout.trim() : void 0;
|
|
1560
|
+
const baseTree = baseRef ? (await runGit(["rev-parse", `${baseRef}^{tree}`], {
|
|
1561
|
+
cwd: params.repoDir
|
|
1562
|
+
})).stdout.trim() : void 0;
|
|
1563
|
+
return { baseRef, baseCommit, baseTree, localRef, localExists, remoteRef, remoteExists };
|
|
1564
|
+
}
|
|
1565
|
+
async function ensureResultsBranchNotCheckedOut(repoDir, normalized) {
|
|
1566
|
+
const currentBranch = await getCurrentBranch(repoDir);
|
|
1567
|
+
if (currentBranch !== normalized.branch) {
|
|
1568
|
+
return;
|
|
1569
|
+
}
|
|
1570
|
+
if (normalized.repo_path) {
|
|
1571
|
+
throw new Error(
|
|
1572
|
+
`Refusing to publish results while '${normalized.branch}' is checked out in ${repoDir}`
|
|
1573
|
+
);
|
|
1574
|
+
}
|
|
1575
|
+
await runGit(["checkout", "--detach"], { cwd: repoDir });
|
|
1576
|
+
}
|
|
1577
|
+
async function commitResultsRunWithTemporaryIndex(params) {
|
|
1578
|
+
const { normalized } = params;
|
|
1579
|
+
await assertValidResultsBranchName(params.repoDir, normalized.branch);
|
|
1580
|
+
await ensureResultsBranchNotCheckedOut(params.repoDir, normalized);
|
|
1581
|
+
const destinationRunPath = normalizeDestinationPath(params.destinationPath);
|
|
1582
|
+
const destinationTreePath = path3.posix.join(RESULTS_REPO_RUNS_DIR, destinationRunPath);
|
|
1583
|
+
const base = await resolveStorageBranchBase({
|
|
1584
|
+
repoDir: params.repoDir,
|
|
1585
|
+
normalized,
|
|
1586
|
+
preferRemote: params.preferRemoteBase
|
|
1587
|
+
});
|
|
1588
|
+
const indexRoot = await mkdtemp(path3.join(os.tmpdir(), "agentv-results-index-"));
|
|
1589
|
+
const indexFile = path3.join(indexRoot, "index");
|
|
1590
|
+
const indexEnv = { GIT_INDEX_FILE: indexFile };
|
|
1591
|
+
try {
|
|
1592
|
+
if (base.baseRef) {
|
|
1593
|
+
await runGit(["read-tree", base.baseRef], { cwd: params.repoDir, env: indexEnv });
|
|
1594
|
+
} else {
|
|
1595
|
+
await runGit(["read-tree", "--empty"], { cwd: params.repoDir, env: indexEnv });
|
|
1596
|
+
}
|
|
1597
|
+
const existingPaths = await getExistingRunTreePaths(
|
|
1598
|
+
params.repoDir,
|
|
1599
|
+
base.baseRef,
|
|
1600
|
+
destinationTreePath
|
|
1601
|
+
);
|
|
1602
|
+
for (const existingPath of existingPaths) {
|
|
1603
|
+
await runGit(["update-index", "--force-remove", "--", existingPath], {
|
|
1604
|
+
cwd: params.repoDir,
|
|
1605
|
+
env: indexEnv,
|
|
1606
|
+
check: false
|
|
1607
|
+
});
|
|
1608
|
+
}
|
|
1609
|
+
const sourceFiles = await listSourceFiles(params.sourceDir);
|
|
1610
|
+
for (const sourceFile of sourceFiles) {
|
|
1611
|
+
const relativeFile = path3.relative(params.sourceDir, sourceFile).split(path3.sep).join("/");
|
|
1612
|
+
const destinationFile = path3.posix.join(destinationTreePath, relativeFile);
|
|
1613
|
+
const fileStat = await lstat(sourceFile);
|
|
1614
|
+
let mode = fileStat.mode & 73 ? "100755" : "100644";
|
|
1615
|
+
let hashInputPath = sourceFile;
|
|
1616
|
+
if (fileStat.isSymbolicLink()) {
|
|
1617
|
+
mode = "120000";
|
|
1618
|
+
hashInputPath = sourceFile;
|
|
1619
|
+
}
|
|
1620
|
+
const { stdout: blob } = await runGit(["hash-object", "-w", "--no-filters", hashInputPath], {
|
|
1621
|
+
cwd: params.repoDir
|
|
1622
|
+
});
|
|
1623
|
+
await runGit(
|
|
1624
|
+
["update-index", "--add", "--cacheinfo", `${mode},${blob.trim()},${destinationFile}`],
|
|
1625
|
+
{
|
|
1626
|
+
cwd: params.repoDir,
|
|
1627
|
+
env: indexEnv
|
|
1628
|
+
}
|
|
1629
|
+
);
|
|
1630
|
+
}
|
|
1631
|
+
const { stdout: newTreeStdout } = await runGit(["write-tree"], {
|
|
1632
|
+
cwd: params.repoDir,
|
|
1633
|
+
env: indexEnv
|
|
1634
|
+
});
|
|
1635
|
+
const newTree = newTreeStdout.trim();
|
|
1636
|
+
if (base.baseTree && newTree === base.baseTree) {
|
|
1637
|
+
return {
|
|
1638
|
+
commitCreated: false,
|
|
1639
|
+
branchUpdated: false,
|
|
1640
|
+
upstreamRef: base.remoteExists ? base.remoteRef : void 0
|
|
1641
|
+
};
|
|
1642
|
+
}
|
|
1643
|
+
await ensureResultsRepoCommitIdentity(params.repoDir);
|
|
1644
|
+
const commitArgs = [
|
|
1645
|
+
"commit-tree",
|
|
1646
|
+
newTree,
|
|
1647
|
+
...base.baseCommit ? ["-p", base.baseCommit] : [],
|
|
1648
|
+
"-m",
|
|
1649
|
+
params.commitMessage,
|
|
1650
|
+
"-m",
|
|
1651
|
+
`AgentV-Run: ${params.targetRunId}`
|
|
1652
|
+
];
|
|
1653
|
+
const { stdout: commitStdout } = await runGit(commitArgs, { cwd: params.repoDir });
|
|
1654
|
+
const commitSha = commitStdout.trim();
|
|
1655
|
+
await runGit(
|
|
1656
|
+
[
|
|
1657
|
+
"update-ref",
|
|
1658
|
+
`refs/heads/${normalized.branch}`,
|
|
1659
|
+
commitSha,
|
|
1660
|
+
...base.localExists && !params.preferRemoteBase ? [base.baseCommit ?? ""] : []
|
|
1661
|
+
].filter(Boolean),
|
|
1662
|
+
{ cwd: params.repoDir }
|
|
1663
|
+
);
|
|
1664
|
+
if (base.remoteExists) {
|
|
1665
|
+
await runGit(["branch", "--set-upstream-to", base.remoteRef, normalized.branch], {
|
|
1666
|
+
cwd: params.repoDir,
|
|
1667
|
+
check: false
|
|
1668
|
+
});
|
|
1669
|
+
}
|
|
1670
|
+
return {
|
|
1671
|
+
commitCreated: true,
|
|
1672
|
+
branchUpdated: true,
|
|
1673
|
+
upstreamRef: base.remoteExists ? base.remoteRef : void 0
|
|
1674
|
+
};
|
|
1675
|
+
} finally {
|
|
1676
|
+
await rm(indexRoot, { recursive: true, force: true }).catch(() => void 0);
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1347
1679
|
async function pushDirectResultsToStorageBranch(params) {
|
|
1348
1680
|
for (let attempt = 1; attempt <= DIRECT_PUSH_MAX_RETRIES; attempt++) {
|
|
1349
1681
|
try {
|
|
1350
|
-
await runGit(
|
|
1682
|
+
await runGit(
|
|
1683
|
+
[
|
|
1684
|
+
"push",
|
|
1685
|
+
"--porcelain",
|
|
1686
|
+
params.normalized.remote,
|
|
1687
|
+
`refs/heads/${params.storageBranch}:refs/heads/${params.storageBranch}`
|
|
1688
|
+
],
|
|
1689
|
+
{ cwd: params.repoDir }
|
|
1690
|
+
);
|
|
1351
1691
|
updateStatusFile(params.normalized, {
|
|
1352
1692
|
last_synced_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1353
1693
|
last_error: void 0
|
|
1354
1694
|
});
|
|
1695
|
+
await fetchResultsRepo(params.repoDir, params.normalized.remote).catch(() => void 0);
|
|
1355
1696
|
return;
|
|
1356
1697
|
} catch (error) {
|
|
1357
1698
|
const message = error instanceof Error ? error.message : String(error);
|
|
1358
1699
|
if (attempt < DIRECT_PUSH_MAX_RETRIES && message.includes("non-fast-forward")) {
|
|
1359
|
-
await fetchResultsRepo(params.repoDir);
|
|
1360
|
-
|
|
1700
|
+
await fetchResultsRepo(params.repoDir, params.normalized.remote);
|
|
1701
|
+
const remoteRef = remoteBranchRef(params.storageBranch, params.normalized.remote);
|
|
1702
|
+
const localOnlyCount = await gitRefExists(params.repoDir, remoteRef) ? await countUnpushedCommits(params.repoDir, remoteRef, params.storageBranch) : 0;
|
|
1703
|
+
if (localOnlyCount > 1) {
|
|
1704
|
+
throw new Error(
|
|
1705
|
+
`Results branch has ${localOnlyCount} local commits and remote advanced; push manually after reconciling ${params.storageBranch}`
|
|
1706
|
+
);
|
|
1707
|
+
}
|
|
1708
|
+
await commitResultsRunWithTemporaryIndex({
|
|
1709
|
+
normalized: params.normalized,
|
|
1710
|
+
repoDir: params.repoDir,
|
|
1711
|
+
sourceDir: params.sourceDir,
|
|
1712
|
+
destinationPath: params.destinationPath,
|
|
1713
|
+
commitMessage: params.commitMessage,
|
|
1714
|
+
targetRunId: params.targetRunId,
|
|
1715
|
+
preferRemoteBase: true
|
|
1716
|
+
});
|
|
1361
1717
|
} else {
|
|
1362
1718
|
throw error;
|
|
1363
1719
|
}
|
|
@@ -1367,43 +1723,63 @@ async function pushDirectResultsToStorageBranch(params) {
|
|
|
1367
1723
|
async function directPushResults(params) {
|
|
1368
1724
|
const normalized = normalizeResultsConfig(params.config);
|
|
1369
1725
|
const repoDir = await ensureResultsRepoClone(normalized);
|
|
1370
|
-
await fetchResultsRepo(repoDir)
|
|
1371
|
-
|
|
1726
|
+
await fetchResultsRepo(repoDir, normalized.remote).catch((error) => {
|
|
1727
|
+
if (normalized.require_push) {
|
|
1728
|
+
throw error;
|
|
1729
|
+
}
|
|
1730
|
+
});
|
|
1372
1731
|
const storageBranch = normalized.branch ?? await resolveDefaultBranch(repoDir);
|
|
1373
|
-
const
|
|
1732
|
+
const storageConfig = {
|
|
1733
|
+
...normalized,
|
|
1734
|
+
branch: storageBranch
|
|
1735
|
+
};
|
|
1374
1736
|
const targetRunId = buildGitRunId(params.destinationPath);
|
|
1375
|
-
const
|
|
1376
|
-
|
|
1377
|
-
RESULTS_REPO_RESULTS_DIR,
|
|
1378
|
-
"runs",
|
|
1379
|
-
params.destinationPath
|
|
1380
|
-
);
|
|
1381
|
-
await stageResultsArtifacts({
|
|
1737
|
+
const result = await commitResultsRunWithTemporaryIndex({
|
|
1738
|
+
normalized: storageConfig,
|
|
1382
1739
|
repoDir,
|
|
1383
1740
|
sourceDir: params.sourceDir,
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
const { stdout: status } = await runGit(["status", "--porcelain"], {
|
|
1388
|
-
cwd: repoDir,
|
|
1389
|
-
check: false
|
|
1741
|
+
destinationPath: params.destinationPath,
|
|
1742
|
+
commitMessage: params.commitMessage,
|
|
1743
|
+
targetRunId
|
|
1390
1744
|
});
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1745
|
+
const shouldPush = normalized.auto_push || normalized.require_push;
|
|
1746
|
+
if (!shouldPush) {
|
|
1747
|
+
updateStatusFile(storageConfig, { last_error: void 0 });
|
|
1748
|
+
return result.commitCreated;
|
|
1749
|
+
}
|
|
1750
|
+
if (!result.commitCreated) {
|
|
1751
|
+
const hasUnpushed = result.upstreamRef ? await hasUnpushedCommits(repoDir, result.upstreamRef, storageBranch) : true;
|
|
1752
|
+
if (hasUnpushed) {
|
|
1753
|
+
const aheadPaths = result.upstreamRef ? await getAheadPaths(repoDir, result.upstreamRef, `refs/heads/${storageBranch}`) : [];
|
|
1754
|
+
if (result.upstreamRef && !areSafeResultsRepoPaths(aheadPaths)) {
|
|
1755
|
+
const error = new Error("Results repo has non-results committed changes");
|
|
1756
|
+
updateStatusFile(storageConfig, { last_error: error.message });
|
|
1757
|
+
throw error;
|
|
1396
1758
|
}
|
|
1397
|
-
await pushDirectResultsToStorageBranch({
|
|
1759
|
+
await pushDirectResultsToStorageBranch({
|
|
1760
|
+
normalized: storageConfig,
|
|
1761
|
+
repoDir,
|
|
1762
|
+
storageBranch,
|
|
1763
|
+
upstreamRef: result.upstreamRef,
|
|
1764
|
+
sourceDir: params.sourceDir,
|
|
1765
|
+
destinationPath: params.destinationPath,
|
|
1766
|
+
commitMessage: params.commitMessage,
|
|
1767
|
+
targetRunId
|
|
1768
|
+
});
|
|
1398
1769
|
return true;
|
|
1399
1770
|
}
|
|
1400
1771
|
return false;
|
|
1401
1772
|
}
|
|
1402
|
-
await
|
|
1403
|
-
|
|
1404
|
-
|
|
1773
|
+
await pushDirectResultsToStorageBranch({
|
|
1774
|
+
normalized: storageConfig,
|
|
1775
|
+
repoDir,
|
|
1776
|
+
storageBranch,
|
|
1777
|
+
upstreamRef: result.upstreamRef,
|
|
1778
|
+
sourceDir: params.sourceDir,
|
|
1779
|
+
destinationPath: params.destinationPath,
|
|
1780
|
+
commitMessage: params.commitMessage,
|
|
1781
|
+
targetRunId
|
|
1405
1782
|
});
|
|
1406
|
-
await pushDirectResultsToStorageBranch({ normalized, repoDir, storageBranch, upstreamRef });
|
|
1407
1783
|
return true;
|
|
1408
1784
|
}
|
|
1409
1785
|
function buildGitRunId(relativeRunPath) {
|
|
@@ -1517,10 +1893,18 @@ function buildWipBranchName(runDir) {
|
|
|
1517
1893
|
async function setupWipWorktree(params) {
|
|
1518
1894
|
const normalized = normalizeResultsConfig(params.config);
|
|
1519
1895
|
const cloneDir = await ensureResultsRepoClone(normalized);
|
|
1520
|
-
await fetchResultsRepo(cloneDir)
|
|
1521
|
-
|
|
1896
|
+
await fetchResultsRepo(cloneDir, normalized.remote).catch((error) => {
|
|
1897
|
+
if (normalized.require_push) {
|
|
1898
|
+
throw error;
|
|
1899
|
+
}
|
|
1900
|
+
});
|
|
1901
|
+
let baseRef = normalized.branch ? await configuredResultsBranchRef(cloneDir, normalized) : remoteBranchRef(await resolveDefaultBranch(cloneDir), normalized.remote);
|
|
1902
|
+
if (!baseRef && normalized.branch) {
|
|
1903
|
+
await createOrphanResultsBranch(cloneDir, normalized.branch);
|
|
1904
|
+
baseRef = normalized.branch;
|
|
1905
|
+
}
|
|
1522
1906
|
if (!baseRef) {
|
|
1523
|
-
throw
|
|
1907
|
+
throw new Error("Could not resolve a base ref for the WIP results branch");
|
|
1524
1908
|
}
|
|
1525
1909
|
const worktreeRoot = await mkdtemp(path3.join(os.tmpdir(), "agentv-wip-"));
|
|
1526
1910
|
const worktreeDir = path3.join(worktreeRoot, "repo");
|
|
@@ -1533,6 +1917,7 @@ async function setupWipWorktree(params) {
|
|
|
1533
1917
|
wipBranch: params.wipBranch,
|
|
1534
1918
|
worktreeDir,
|
|
1535
1919
|
cloneDir,
|
|
1920
|
+
remote: normalized.remote,
|
|
1536
1921
|
cleanup: async () => {
|
|
1537
1922
|
try {
|
|
1538
1923
|
await runGit(["worktree", "remove", "--force", worktreeDir], { cwd: cloneDir });
|
|
@@ -1568,7 +1953,7 @@ async function pushWipCheckpoint(params) {
|
|
|
1568
1953
|
["commit", "--amend", "-m", `wip(results): checkpoint ${params.handle.wipBranch} ${timestamp}`],
|
|
1569
1954
|
{ cwd: params.handle.worktreeDir }
|
|
1570
1955
|
);
|
|
1571
|
-
await runGit(["push", "--force",
|
|
1956
|
+
await runGit(["push", "--force", params.handle.remote, params.handle.wipBranch], {
|
|
1572
1957
|
cwd: params.handle.worktreeDir
|
|
1573
1958
|
});
|
|
1574
1959
|
return true;
|
|
@@ -1576,7 +1961,7 @@ async function pushWipCheckpoint(params) {
|
|
|
1576
1961
|
async function deleteWipBranch(params) {
|
|
1577
1962
|
const normalized = normalizeResultsConfig(params.config);
|
|
1578
1963
|
const cloneDir = await ensureResultsRepoClone(normalized);
|
|
1579
|
-
await runGit(["push",
|
|
1964
|
+
await runGit(["push", normalized.remote, "--delete", params.wipBranch], { cwd: cloneDir });
|
|
1580
1965
|
}
|
|
1581
1966
|
async function listGitRuns(repoDir, ref = "origin/main") {
|
|
1582
1967
|
const { stdout: treeOut } = await runGit(
|
|
@@ -1745,38 +2130,6 @@ function deriveCategory(relativePath) {
|
|
|
1745
2130
|
const dirs = parts.slice(0, -1).filter((d) => d !== "evals");
|
|
1746
2131
|
return dirs.length > 0 ? dirs.join("/") : DEFAULT_CATEGORY;
|
|
1747
2132
|
}
|
|
1748
|
-
var OTEL_BACKEND_PRESETS = {
|
|
1749
|
-
langfuse: {
|
|
1750
|
-
name: "langfuse",
|
|
1751
|
-
endpoint: process.env.LANGFUSE_HOST ? `${process.env.LANGFUSE_HOST}/api/public/otel/v1/traces` : "https://cloud.langfuse.com/api/public/otel/v1/traces",
|
|
1752
|
-
headers: (env) => {
|
|
1753
|
-
const pub = env.LANGFUSE_PUBLIC_KEY ?? "";
|
|
1754
|
-
const secret = env.LANGFUSE_SECRET_KEY ?? "";
|
|
1755
|
-
return { Authorization: `Basic ${Buffer.from(`${pub}:${secret}`).toString("base64")}` };
|
|
1756
|
-
}
|
|
1757
|
-
},
|
|
1758
|
-
braintrust: {
|
|
1759
|
-
name: "braintrust",
|
|
1760
|
-
endpoint: "https://api.braintrust.dev/otel/v1/traces",
|
|
1761
|
-
headers: (env) => {
|
|
1762
|
-
const headers = {
|
|
1763
|
-
Authorization: `Bearer ${env.BRAINTRUST_API_KEY ?? ""}`
|
|
1764
|
-
};
|
|
1765
|
-
const parent = env.BRAINTRUST_PARENT ?? (env.BRAINTRUST_PROJECT_ID ? `project_id:${env.BRAINTRUST_PROJECT_ID}` : void 0) ?? (env.BRAINTRUST_PROJECT ? `project_name:${env.BRAINTRUST_PROJECT}` : void 0);
|
|
1766
|
-
if (parent) {
|
|
1767
|
-
headers["x-bt-parent"] = parent;
|
|
1768
|
-
}
|
|
1769
|
-
return headers;
|
|
1770
|
-
}
|
|
1771
|
-
},
|
|
1772
|
-
confident: {
|
|
1773
|
-
name: "confident",
|
|
1774
|
-
endpoint: "https://otel.confident-ai.com/v1/traces",
|
|
1775
|
-
headers: (env) => ({
|
|
1776
|
-
"x-confident-api-key": env.CONFIDENT_API_KEY ?? ""
|
|
1777
|
-
})
|
|
1778
|
-
}
|
|
1779
|
-
};
|
|
1780
2133
|
var OtelTraceExporter = class {
|
|
1781
2134
|
constructor(options) {
|
|
1782
2135
|
this.options = options;
|
|
@@ -1799,9 +2152,11 @@ var OtelTraceExporter = class {
|
|
|
1799
2152
|
const { NodeTracerProvider: Provider, SimpleSpanProcessor } = sdkTraceNode;
|
|
1800
2153
|
const { resourceFromAttributes } = resourcesMod;
|
|
1801
2154
|
const { ATTR_SERVICE_NAME } = semconvMod;
|
|
1802
|
-
const
|
|
1803
|
-
[ATTR_SERVICE_NAME]: this.options.serviceName ?? "agentv"
|
|
1804
|
-
|
|
2155
|
+
const resourceAttributes = {
|
|
2156
|
+
[ATTR_SERVICE_NAME]: this.options.serviceName ?? "agentv",
|
|
2157
|
+
...this.options.resourceAttributes
|
|
2158
|
+
};
|
|
2159
|
+
const resource = resourceFromAttributes(resourceAttributes);
|
|
1805
2160
|
const processors = [];
|
|
1806
2161
|
if (this.options.endpoint) {
|
|
1807
2162
|
const otlpHttp = await import("./esm-TTEMJEVV.js");
|
|
@@ -1813,9 +2168,11 @@ var OtelTraceExporter = class {
|
|
|
1813
2168
|
processors.push(new SimpleSpanProcessor(exporter));
|
|
1814
2169
|
}
|
|
1815
2170
|
if (this.options.otlpFilePath) {
|
|
1816
|
-
const { OtlpJsonFileExporter: OtlpJsonFileExporter2 } = await import("./otlp-json-file-exporter-
|
|
2171
|
+
const { OtlpJsonFileExporter: OtlpJsonFileExporter2 } = await import("./otlp-json-file-exporter-RY63S3IG-PZBQPVYY.js");
|
|
1817
2172
|
processors.push(
|
|
1818
|
-
new SimpleSpanProcessor(
|
|
2173
|
+
new SimpleSpanProcessor(
|
|
2174
|
+
new OtlpJsonFileExporter2(this.options.otlpFilePath, resourceAttributes)
|
|
2175
|
+
)
|
|
1819
2176
|
);
|
|
1820
2177
|
}
|
|
1821
2178
|
if (processors.length === 0) {
|
|
@@ -2776,204 +3133,6 @@ async function discoverClaudeSessions(opts) {
|
|
|
2776
3133
|
sessions.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime());
|
|
2777
3134
|
return sessions.slice(0, limit);
|
|
2778
3135
|
}
|
|
2779
|
-
function dropUndefined(value) {
|
|
2780
|
-
return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
|
|
2781
|
-
}
|
|
2782
|
-
function toTranscriptTokenUsage(usage) {
|
|
2783
|
-
if (!usage) {
|
|
2784
|
-
return void 0;
|
|
2785
|
-
}
|
|
2786
|
-
return dropUndefined({
|
|
2787
|
-
input: usage.input,
|
|
2788
|
-
output: usage.output,
|
|
2789
|
-
cached: usage.cached,
|
|
2790
|
-
reasoning: usage.reasoning
|
|
2791
|
-
});
|
|
2792
|
-
}
|
|
2793
|
-
function toTranscriptToolCall(toolCall) {
|
|
2794
|
-
return dropUndefined({
|
|
2795
|
-
tool: toolCall.tool,
|
|
2796
|
-
input: toolCall.input,
|
|
2797
|
-
output: toolCall.output,
|
|
2798
|
-
id: toolCall.id,
|
|
2799
|
-
start_time: toolCall.startTime,
|
|
2800
|
-
end_time: toolCall.endTime,
|
|
2801
|
-
duration_ms: toolCall.durationMs
|
|
2802
|
-
});
|
|
2803
|
-
}
|
|
2804
|
-
function toTranscriptMessageFields(message) {
|
|
2805
|
-
return dropUndefined({
|
|
2806
|
-
role: message.role,
|
|
2807
|
-
name: message.name,
|
|
2808
|
-
content: message.content,
|
|
2809
|
-
tool_calls: message.toolCalls?.map(toTranscriptToolCall),
|
|
2810
|
-
start_time: message.startTime,
|
|
2811
|
-
end_time: message.endTime,
|
|
2812
|
-
duration_ms: message.durationMs,
|
|
2813
|
-
metadata: message.metadata,
|
|
2814
|
-
token_usage: toTranscriptTokenUsage(message.tokenUsage)
|
|
2815
|
-
});
|
|
2816
|
-
}
|
|
2817
|
-
function toTranscriptJsonLines(entry, options) {
|
|
2818
|
-
const source = {
|
|
2819
|
-
provider: entry.source.provider,
|
|
2820
|
-
session_id: entry.source.sessionId,
|
|
2821
|
-
model: entry.source.model,
|
|
2822
|
-
timestamp: entry.source.startedAt,
|
|
2823
|
-
git_branch: entry.source.gitBranch,
|
|
2824
|
-
cwd: entry.source.cwd ?? entry.source.projectPath,
|
|
2825
|
-
version: entry.source.version
|
|
2826
|
-
};
|
|
2827
|
-
const transcriptTokenUsage = entry.tokenUsage ? {
|
|
2828
|
-
input: entry.tokenUsage.input,
|
|
2829
|
-
output: entry.tokenUsage.output,
|
|
2830
|
-
cached: entry.tokenUsage.cached,
|
|
2831
|
-
reasoning: entry.tokenUsage.reasoning
|
|
2832
|
-
} : void 0;
|
|
2833
|
-
const testId = options?.testId ?? entry.source.sessionId;
|
|
2834
|
-
const target = options?.target ?? entry.source.provider;
|
|
2835
|
-
return entry.messages.map((message, index) => ({
|
|
2836
|
-
test_id: testId,
|
|
2837
|
-
target,
|
|
2838
|
-
message_index: index,
|
|
2839
|
-
...toTranscriptMessageFields(message),
|
|
2840
|
-
transcript_token_usage: transcriptTokenUsage,
|
|
2841
|
-
transcript_duration_ms: entry.durationMs,
|
|
2842
|
-
transcript_cost_usd: entry.costUsd,
|
|
2843
|
-
source
|
|
2844
|
-
}));
|
|
2845
|
-
}
|
|
2846
|
-
function traceToTranscriptJsonLines(trace, options) {
|
|
2847
|
-
const provider = (typeof trace.metadata?.provider === "string" ? trace.metadata.provider : void 0) ?? options?.target ?? "agentv";
|
|
2848
|
-
const sessionId = (typeof trace.metadata?.provider_session_id === "string" ? trace.metadata.provider_session_id : void 0) ?? (typeof trace.metadata?.eval_case_id === "string" ? trace.metadata.eval_case_id : void 0) ?? options?.testId ?? "trace";
|
|
2849
|
-
return toTranscriptJsonLines(
|
|
2850
|
-
{
|
|
2851
|
-
messages: [...trace.messages],
|
|
2852
|
-
source: {
|
|
2853
|
-
provider,
|
|
2854
|
-
sessionId,
|
|
2855
|
-
startedAt: trace.startTime
|
|
2856
|
-
},
|
|
2857
|
-
tokenUsage: trace.tokenUsage,
|
|
2858
|
-
durationMs: trace.durationMs,
|
|
2859
|
-
costUsd: trace.costUsd
|
|
2860
|
-
},
|
|
2861
|
-
options
|
|
2862
|
-
);
|
|
2863
|
-
}
|
|
2864
|
-
function traceFromTranscriptJsonLines(lines) {
|
|
2865
|
-
const [entry] = groupTranscriptJsonLines(lines);
|
|
2866
|
-
if (!entry) {
|
|
2867
|
-
return buildTraceFromMessages();
|
|
2868
|
-
}
|
|
2869
|
-
return buildTraceFromMessages({
|
|
2870
|
-
output: entry.messages,
|
|
2871
|
-
tokenUsage: entry.tokenUsage,
|
|
2872
|
-
durationMs: entry.durationMs,
|
|
2873
|
-
costUsd: entry.costUsd ?? void 0,
|
|
2874
|
-
startTime: entry.source.startedAt,
|
|
2875
|
-
provider: entry.source.provider,
|
|
2876
|
-
target: entry.target,
|
|
2877
|
-
testId: entry.testId,
|
|
2878
|
-
conversationId: entry.source.sessionId
|
|
2879
|
-
});
|
|
2880
|
-
}
|
|
2881
|
-
function fromTranscriptTokenUsage(usage) {
|
|
2882
|
-
if (!usage) {
|
|
2883
|
-
return void 0;
|
|
2884
|
-
}
|
|
2885
|
-
return {
|
|
2886
|
-
input: usage.input,
|
|
2887
|
-
output: usage.output,
|
|
2888
|
-
cached: usage.cached,
|
|
2889
|
-
reasoning: usage.reasoning
|
|
2890
|
-
};
|
|
2891
|
-
}
|
|
2892
|
-
function readOptionalString(record, key) {
|
|
2893
|
-
const value = record[key];
|
|
2894
|
-
return typeof value === "string" ? value : void 0;
|
|
2895
|
-
}
|
|
2896
|
-
function readOptionalNumber(record, key) {
|
|
2897
|
-
const value = record[key];
|
|
2898
|
-
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
2899
|
-
}
|
|
2900
|
-
function fromTranscriptToolCall(wire) {
|
|
2901
|
-
const tool = readOptionalString(wire, "tool");
|
|
2902
|
-
if (!tool) {
|
|
2903
|
-
return void 0;
|
|
2904
|
-
}
|
|
2905
|
-
return {
|
|
2906
|
-
tool,
|
|
2907
|
-
input: wire.input,
|
|
2908
|
-
output: wire.output,
|
|
2909
|
-
id: readOptionalString(wire, "id"),
|
|
2910
|
-
startTime: readOptionalString(wire, "start_time"),
|
|
2911
|
-
endTime: readOptionalString(wire, "end_time"),
|
|
2912
|
-
durationMs: readOptionalNumber(wire, "duration_ms")
|
|
2913
|
-
};
|
|
2914
|
-
}
|
|
2915
|
-
function buildReplayMessage(line) {
|
|
2916
|
-
return {
|
|
2917
|
-
role: line.role,
|
|
2918
|
-
name: line.name,
|
|
2919
|
-
content: line.content,
|
|
2920
|
-
toolCalls: line.tool_calls?.map(fromTranscriptToolCall).filter((toolCall) => toolCall !== void 0),
|
|
2921
|
-
startTime: line.start_time,
|
|
2922
|
-
endTime: line.end_time,
|
|
2923
|
-
durationMs: line.duration_ms,
|
|
2924
|
-
metadata: line.metadata,
|
|
2925
|
-
tokenUsage: fromTranscriptTokenUsage(line.token_usage)
|
|
2926
|
-
};
|
|
2927
|
-
}
|
|
2928
|
-
function groupTranscriptJsonLines(lines) {
|
|
2929
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
2930
|
-
for (const line of lines) {
|
|
2931
|
-
const existing = grouped.get(line.test_id);
|
|
2932
|
-
const source = {
|
|
2933
|
-
provider: line.source.provider,
|
|
2934
|
-
sessionId: line.source.session_id,
|
|
2935
|
-
startedAt: line.source.timestamp,
|
|
2936
|
-
model: line.source.model,
|
|
2937
|
-
gitBranch: line.source.git_branch,
|
|
2938
|
-
cwd: line.source.cwd,
|
|
2939
|
-
version: line.source.version
|
|
2940
|
-
};
|
|
2941
|
-
const transcriptTokenUsage = line.transcript_token_usage ? {
|
|
2942
|
-
input: line.transcript_token_usage.input,
|
|
2943
|
-
output: line.transcript_token_usage.output,
|
|
2944
|
-
cached: line.transcript_token_usage.cached,
|
|
2945
|
-
reasoning: line.transcript_token_usage.reasoning
|
|
2946
|
-
} : void 0;
|
|
2947
|
-
if (existing) {
|
|
2948
|
-
existing.messages.push({ index: line.message_index, message: buildReplayMessage(line) });
|
|
2949
|
-
continue;
|
|
2950
|
-
}
|
|
2951
|
-
grouped.set(line.test_id, {
|
|
2952
|
-
target: line.target,
|
|
2953
|
-
tokenUsage: transcriptTokenUsage,
|
|
2954
|
-
durationMs: line.transcript_duration_ms,
|
|
2955
|
-
costUsd: line.transcript_cost_usd,
|
|
2956
|
-
source,
|
|
2957
|
-
messages: [{ index: line.message_index, message: buildReplayMessage(line) }]
|
|
2958
|
-
});
|
|
2959
|
-
}
|
|
2960
|
-
return [...grouped.entries()].map(([testId, entry]) => ({
|
|
2961
|
-
testId,
|
|
2962
|
-
target: entry.target,
|
|
2963
|
-
tokenUsage: entry.tokenUsage,
|
|
2964
|
-
durationMs: entry.durationMs,
|
|
2965
|
-
costUsd: entry.costUsd,
|
|
2966
|
-
source: entry.source,
|
|
2967
|
-
messages: entry.messages.sort((first, second) => first.index - second.index).map((item) => item.message)
|
|
2968
|
-
}));
|
|
2969
|
-
}
|
|
2970
|
-
async function readTranscriptJsonl(filePath) {
|
|
2971
|
-
const text = await readFile2(filePath, "utf8");
|
|
2972
|
-
return text.split("\n").filter((line) => line.trim().length > 0).map((line) => JSON.parse(line));
|
|
2973
|
-
}
|
|
2974
|
-
async function readTranscriptFile(filePath) {
|
|
2975
|
-
return readFile2(filePath, "utf8");
|
|
2976
|
-
}
|
|
2977
3136
|
var TranscriptProvider = class _TranscriptProvider {
|
|
2978
3137
|
id;
|
|
2979
3138
|
kind = "transcript";
|
|
@@ -3061,7 +3220,6 @@ export {
|
|
|
3061
3220
|
trimBaselineResult,
|
|
3062
3221
|
DEFAULT_CATEGORY,
|
|
3063
3222
|
deriveCategory,
|
|
3064
|
-
OTEL_BACKEND_PRESETS,
|
|
3065
3223
|
OtelTraceExporter,
|
|
3066
3224
|
OtelStreamingObserver,
|
|
3067
3225
|
RunBudgetTracker,
|
|
@@ -3071,13 +3229,7 @@ export {
|
|
|
3071
3229
|
parseCodexSession,
|
|
3072
3230
|
discoverCodexSessions,
|
|
3073
3231
|
discoverClaudeSessions,
|
|
3074
|
-
toTranscriptJsonLines,
|
|
3075
|
-
traceToTranscriptJsonLines,
|
|
3076
|
-
traceFromTranscriptJsonLines,
|
|
3077
|
-
groupTranscriptJsonLines,
|
|
3078
|
-
readTranscriptJsonl,
|
|
3079
|
-
readTranscriptFile,
|
|
3080
3232
|
TranscriptProvider,
|
|
3081
3233
|
createAgentKernel
|
|
3082
3234
|
};
|
|
3083
|
-
//# sourceMappingURL=chunk-
|
|
3235
|
+
//# sourceMappingURL=chunk-I3SC4FOT.js.map
|