Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions apps/cli/src/commands/eval/artifact-writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
buildAggregateGradingArtifact,
buildIndexArtifactEntry as buildCoreIndexArtifactEntry,
buildResultIndexArtifact as buildCoreResultIndexArtifact,
buildEvalTestTargetKey,
buildEvaluationResultTargetKey,
buildGradingArtifact,
buildRunSummaryArtifact,
buildTestTargetKey,
Expand All @@ -41,6 +43,8 @@ import {
export {
aggregateRunDir,
buildAggregateGradingArtifact,
buildEvalTestTargetKey,
buildEvaluationResultTargetKey,
buildRunSummaryArtifact,
buildGradingArtifact,
buildTestTargetKey,
Expand Down
21 changes: 1 addition & 20 deletions apps/cli/src/commands/eval/progress-display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ export class ProgressDisplay {
private readonly workers: Map<number, WorkerProgress> = new Map();
private totalTests = 0;
private completedTests = 0;
private readonly logPaths: string[] = [];
private readonly logPathSet = new Set<string>();
private started = false;
private finished = false;
private readonly verbose: boolean;
Expand Down Expand Up @@ -133,24 +131,7 @@ export class ProgressDisplay {
}

addLogPaths(paths: readonly string[]): void {
const newPaths: string[] = [];
for (const path of paths) {
if (this.logPathSet.has(path)) {
continue;
}
this.logPathSet.add(path);
newPaths.push(path);
}

if (newPaths.length === 0) {
return;
}

this.logPaths.push(...newPaths);

for (const p of newPaths) {
console.log(`Provider log: ${p}`);
}
void paths;
}

finish(): void {
Expand Down
48 changes: 44 additions & 4 deletions apps/cli/src/commands/eval/result-layout.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { existsSync, statSync } from 'node:fs';
import { type Dirent, existsSync, readdirSync, statSync } from 'node:fs';
import path from 'node:path';

export const RESULT_INDEX_FILENAME = 'index.jsonl';
Expand Down Expand Up @@ -76,6 +76,37 @@ export function resolveExistingRunPrimaryPath(runDir: string): string | undefine
return undefined;
}

export function discoverRunManifestPaths(runDir: string): readonly string[] {
const direct = resolveExistingRunPrimaryPath(runDir);
if (direct) {
return [direct];
}

const manifests: string[] = [];
function walk(currentDir: string): void {
const primary = resolveExistingRunPrimaryPath(currentDir);
if (primary) {
manifests.push(primary);
return;
}

let entries: Dirent<string>[];
try {
entries = readdirSync(currentDir, { withFileTypes: true });
} catch {
return;
}
for (const entry of entries) {
if (entry.isDirectory()) {
walk(path.join(currentDir, entry.name));
}
}
}

walk(runDir);
return manifests.sort();
}

export function isDirectoryPath(filePath: string): boolean {
try {
return statSync(filePath).isDirectory();
Expand All @@ -90,11 +121,20 @@ export function resolveWorkspaceOrFilePath(filePath: string): string {
}

const existing = resolveExistingRunPrimaryPath(filePath);
if (!existing) {
throw new Error(`Result workspace is missing ${RESULT_INDEX_FILENAME}: ${filePath}`);
if (existing) {
return existing;
}

return existing;
const nested = discoverRunManifestPaths(filePath);
if (nested.length === 1) {
return nested[0];
}
if (nested.length > 1) {
throw new Error(
`Result workspace contains multiple ${RESULT_INDEX_FILENAME} manifests; pass one bundle directory or manifest: ${filePath}`,
);
}
throw new Error(`Result workspace is missing ${RESULT_INDEX_FILENAME}: ${filePath}`);
}

export function resolveRunManifestPath(filePath: string): string {
Expand Down
15 changes: 9 additions & 6 deletions apps/cli/src/commands/eval/run-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import path from 'node:path';

import {
RESULT_INDEX_FILENAME,
discoverRunManifestPaths,
resolveExistingRunPrimaryPath,
resolveRunIndexPath,
} from './result-layout.js';
Expand All @@ -27,7 +28,11 @@ export interface RunCache {
*/
export function resolveRunCacheFile(cache: RunCache): string {
if (cache.lastRunDir) {
return resolveExistingRunPrimaryPath(cache.lastRunDir) ?? resolveRunIndexPath(cache.lastRunDir);
const direct = resolveExistingRunPrimaryPath(cache.lastRunDir);
if (direct) {
return direct;
}
return discoverRunManifestPaths(cache.lastRunDir)[0] ?? resolveRunIndexPath(cache.lastRunDir);
}
return '';
}
Expand Down Expand Up @@ -61,14 +66,12 @@ export async function resolveCachedRunDir(cwd: string): Promise<string | undefin
}

export async function saveRunCache(cwd: string, resultPath: string): Promise<void> {
if (path.basename(resultPath) !== RESULT_INDEX_FILENAME) {
return;
}

const dir = path.join(cwd, '.agentv');
const lastRunDir =
path.basename(resultPath) === RESULT_INDEX_FILENAME ? path.dirname(resultPath) : resultPath;
await mkdir(dir, { recursive: true });
const cache: RunCache = {
lastRunDir: path.dirname(resultPath),
lastRunDir,
timestamp: new Date().toISOString(),
};
await writeFile(cachePath(cwd), `${JSON.stringify(cache, null, 2)}\n`, 'utf-8');
Expand Down
Loading
Loading