"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestRun = void 0;
const drizzle_orm_1 = require("drizzle-orm");
const database_1 = require("../database");
const tables_1 = require("../database/tables");
const convertEvalResultsToTable_1 = require("../util/convertEvalResultsToTable");
const testRunResult_1 = require("./testRunResult");
class TestRun {
    static async findById(id) {
        const db = (0, database_1.getDb)();
        const { testRun, evals } = await db.transaction(async (tx) => {
            const testRun = await tx.select().from(tables_1.testRunsTable).where((0, drizzle_orm_1.eq)(tables_1.testRunsTable.id, id));
            if (testRun.length === 0) {
                return { testRun: null, evals: [] };
            }
            // Get all evals associated with this test run
            const testRunEvals = await tx
                .select()
                .from(tables_1.testRunsToEvalsTable)
                .where((0, drizzle_orm_1.eq)(tables_1.testRunsToEvalsTable.testRunId, id));
            const evalIds = testRunEvals.map((rel) => rel.evalId);
            // Get all evals data
            const evals = await tx.select().from(tables_1.evalsTable).where((0, drizzle_orm_1.inArray)(tables_1.evalsTable.id, evalIds));
            return { testRun: testRun[0], evals };
        });
        if (!testRun) {
            return undefined;
        }
        // Combine prompts from all evals
        const prompts = evals.reduce((acc, eval_) => {
            return [...acc, ...(eval_.prompts || [])];
        }, []);
        return new TestRun({
            id: testRun.id,
            status: testRun.status,
            projectId: testRun.projectId,
            applicationIds: testRun.applicationIds,
            libraryId: testRun.libraryId,
            persisted: true,
            prompts,
        });
    }
    constructor(opts) {
        this.id = opts.id;
        this.status = opts.status;
        this.projectId = opts.projectId;
        this.applicationIds = opts.applicationIds;
        this.libraryId = opts.libraryId;
        this.persisted = opts.persisted || false;
        this.prompts = opts.prompts || [];
    }
    getPrompts() {
        return this.prompts;
    }
    getStats() {
        const stats = {
            successes: 0,
            failures: 0,
            errors: 0,
            tokenUsage: {
                cached: 0,
                completion: 0,
                prompt: 0,
                total: 0,
                duration: 0,
                model: 'default',
                characters: 0,
                numRequests: 0,
                completionDetails: {
                    reasoning: 0,
                    acceptedPrediction: 0,
                    rejectedPrediction: 0,
                    audio: 0,
                    text: 0,
                },
                promptDetails: {
                    audio: 0,
                    cached: 0,
                    image: 0,
                    text: 0,
                },
                assertions: {
                    total: 0,
                    prompt: 0,
                    completion: 0,
                    cached: 0,
                },
            },
        };
        for (const prompt of this.prompts) {
            stats.successes += prompt.metrics?.testPassCount || 0;
            stats.failures += prompt.metrics?.testFailCount || 0;
            stats.errors += prompt.metrics?.testErrorCount || 0;
            stats.tokenUsage.prompt += prompt.metrics?.tokenUsage.prompt || 0;
            stats.tokenUsage.cached += prompt.metrics?.tokenUsage.cached || 0;
            stats.tokenUsage.completion += prompt.metrics?.tokenUsage.completion || 0;
            stats.tokenUsage.total += prompt.metrics?.tokenUsage.total || 0;
            stats.tokenUsage.numRequests += prompt.metrics?.tokenUsage.numRequests || 0;
            stats.tokenUsage.completionDetails.reasoning +=
                prompt.metrics?.tokenUsage.completionDetails?.reasoning || 0;
            stats.tokenUsage.completionDetails.acceptedPrediction +=
                prompt.metrics?.tokenUsage.completionDetails?.acceptedPrediction || 0;
            stats.tokenUsage.completionDetails.rejectedPrediction +=
                prompt.metrics?.tokenUsage.completionDetails?.rejectedPrediction || 0;
        }
        return stats;
    }
    async toResultsFile(filter) {
        const results = await testRunResult_1.TestRunResult.findManyByTestRunId(this.id, filter);
        return {
            version: 4,
            createdAt: new Date().toISOString(),
            results: {
                version: 3,
                timestamp: new Date().toISOString(),
                prompts: this.getPrompts(),
                results: results.map((r) => r.toEvaluateResult()),
                stats: this.getStats(),
            },
            config: {},
            author: null,
            prompts: this.getPrompts(),
            datasetId: null,
        };
    }
    async getTable(filter) {
        return (0, convertEvalResultsToTable_1.convertResultsToTable)(await this.toResultsFile(filter), 'all');
    }
    async updateTable(fields) {
        const db = (0, database_1.getDb)();
        await db.update(tables_1.testRunsTable).set(fields).where((0, drizzle_orm_1.eq)(tables_1.testRunsTable.id, this.id));
        // Optionally, refresh this instance's fields if needed
        // Return the updated EvaluateTable
        return this.getTable();
    }
}
exports.TestRun = TestRun;
//# sourceMappingURL=testRun.js.map