import { _ as getEnvBool, m as safeJsonStringify } from "./logger-CATn0kWr.js";
import { D as isResultFailureReason, O as isApiProvider, k as isProviderOptions, m as ResultFailureReason } from "./types-CHrVA-1r.js";
import { t as getCurrentTimestamp } from "./time-D43HXtFW.js";
import { t as hashPrompt } from "./utils-B8cqmCfl.js";
import { n as isBlobStorageEnabled, t as extractAndStoreBinaryData } from "./extractor-ByYkZdqt.js";
import { i as evalResultsTable, p as getDb } from "./tables-BsaipJNh.js";
import { and, eq, gte, inArray, lt } from "drizzle-orm";

//#region src/models/evalResult.ts
function sanitizeProvider(provider) {
	try {
		if (isApiProvider(provider)) return {
			id: provider.id(),
			label: provider.label,
			...provider.config && { config: JSON.parse(safeJsonStringify(provider.config)) }
		};
		if (isProviderOptions(provider)) return {
			id: provider.id,
			label: provider.label,
			...provider.config && { config: JSON.parse(safeJsonStringify(provider.config)) }
		};
		if (typeof provider === "object" && provider) {
			const providerObj = provider;
			return {
				id: typeof providerObj.id === "function" ? providerObj.id() : providerObj.id,
				label: providerObj.label,
				...providerObj.config && { config: JSON.parse(safeJsonStringify(providerObj.config)) }
			};
		}
	} catch {}
	return JSON.parse(safeJsonStringify(provider));
}
var EvalResult = class EvalResult {
	static async createFromEvaluateResult(evalId, result, opts) {
		const persist = opts?.persist == null ? true : opts.persist;
		const { prompt, error, score, latencyMs, success, provider, gradingResult, namedScores, cost, metadata, failureReason, testCase } = result;
		const preSanitizeTestCase = {
			...testCase,
			...testCase.provider && { provider: sanitizeProvider(testCase.provider) }
		};
		const processedResponse = await extractAndStoreBinaryData(result.response, {
			evalId,
			testIdx: result.testIdx,
			promptIdx: result.promptIdx
		});
		const args = {
			id: crypto.randomUUID(),
			evalId,
			testCase: preSanitizeTestCase,
			promptIdx: result.promptIdx,
			testIdx: result.testIdx,
			prompt,
			promptId: hashPrompt(prompt),
			error: error?.toString(),
			success,
			score: score == null ? 0 : score,
			response: processedResponse || null,
			gradingResult: gradingResult || null,
			namedScores,
			provider: sanitizeProvider(provider),
			latencyMs,
			cost,
			metadata,
			failureReason
		};
		if (persist) return new EvalResult({
			...(await getDb().insert(evalResultsTable).values(args).returning())[0],
			persisted: true
		});
		return new EvalResult(args);
	}
	static async createManyFromEvaluateResult(results, evalId) {
		const db = getDb();
		const returnResults = [];
		const processedResults = [];
		for (const result of results) {
			const processedResponse = isBlobStorageEnabled() ? await extractAndStoreBinaryData(result.response, {
				evalId,
				testIdx: result.testIdx,
				promptIdx: result.promptIdx
			}) : result.response;
			processedResults.push({
				...result,
				response: processedResponse ?? void 0
			});
		}
		db.transaction(() => {
			for (const result of processedResults) {
				const dbResult = db.insert(evalResultsTable).values({
					...result,
					evalId,
					id: crypto.randomUUID()
				}).returning().get();
				returnResults.push(new EvalResult({
					...dbResult,
					persisted: true
				}));
			}
		});
		return returnResults;
	}
	static async findById(id) {
		const result = await getDb().select().from(evalResultsTable).where(eq(evalResultsTable.id, id));
		return result.length > 0 ? new EvalResult({
			...result[0],
			persisted: true
		}) : null;
	}
	static async findManyByEvalId(evalId, opts) {
		return (await getDb().select().from(evalResultsTable).where(and(eq(evalResultsTable.evalId, evalId), opts?.testIdx == null ? void 0 : eq(evalResultsTable.testIdx, opts.testIdx)))).map((result) => new EvalResult({
			...result,
			persisted: true
		}));
	}
	static async findManyByEvalIdAndTestIndices(evalId, testIndices) {
		if (!testIndices.length) return [];
		return (await getDb().select().from(evalResultsTable).where(and(eq(evalResultsTable.evalId, evalId), testIndices.length === 1 ? eq(evalResultsTable.testIdx, testIndices[0]) : inArray(evalResultsTable.testIdx, testIndices)))).map((result) => new EvalResult({
			...result,
			persisted: true
		}));
	}
	/**
	* Returns a set of completed (testIdx,promptIdx) pairs for a given eval.
	* Key format: `${testIdx}:${promptIdx}`
	*/
	static async getCompletedIndexPairs(evalId) {
		const rows = await getDb().select({
			testIdx: evalResultsTable.testIdx,
			promptIdx: evalResultsTable.promptIdx
		}).from(evalResultsTable).where(eq(evalResultsTable.evalId, evalId));
		const ret = /* @__PURE__ */ new Set();
		for (const r of rows) ret.add(`${r.testIdx}:${r.promptIdx}`);
		return ret;
	}
	static async *findManyByEvalIdBatched(evalId, opts) {
		const db = getDb();
		const batchSize = opts?.batchSize || 100;
		let offset = 0;
		while (true) {
			const results = await db.select().from(evalResultsTable).where(and(eq(evalResultsTable.evalId, evalId), gte(evalResultsTable.testIdx, offset), lt(evalResultsTable.testIdx, offset + batchSize))).all();
			if (results.length === 0) break;
			yield results.map((result) => new EvalResult({
				...result,
				persisted: true
			}));
			offset += batchSize;
		}
	}
	id;
	evalId;
	description;
	promptIdx;
	testIdx;
	testCase;
	prompt;
	promptId;
	error;
	success;
	score;
	response;
	gradingResult;
	namedScores;
	provider;
	latencyMs;
	cost;
	metadata;
	failureReason;
	persisted;
	pluginId;
	constructor(opts) {
		this.id = opts.id;
		this.evalId = opts.evalId;
		this.promptIdx = opts.promptIdx;
		this.testIdx = opts.testIdx;
		this.testCase = opts.testCase;
		this.prompt = opts.prompt;
		this.promptId = opts.promptId || hashPrompt(opts.prompt);
		this.error = opts.error;
		this.score = opts.score;
		this.success = opts.success;
		this.response = opts.response || void 0;
		this.gradingResult = opts.gradingResult;
		this.namedScores = opts.namedScores || {};
		this.provider = opts.provider;
		this.latencyMs = opts.latencyMs || 0;
		this.cost = opts.cost || 0;
		this.metadata = opts.metadata || {};
		this.failureReason = isResultFailureReason(opts.failureReason) ? opts.failureReason : ResultFailureReason.NONE;
		this.persisted = opts.persisted || false;
		this.pluginId = opts.testCase.metadata?.pluginId;
	}
	async save() {
		const db = getDb();
		if (this.persisted) await db.update(evalResultsTable).set({
			...this,
			updatedAt: getCurrentTimestamp()
		}).where(eq(evalResultsTable.id, this.id));
		else {
			this.id = (await db.insert(evalResultsTable).values(this).returning())[0].id;
			this.persisted = true;
		}
	}
	toEvaluateResult() {
		const shouldStripPromptText = getEnvBool("PROMPTFOO_STRIP_PROMPT_TEXT", false);
		const shouldStripResponseOutput = getEnvBool("PROMPTFOO_STRIP_RESPONSE_OUTPUT", false);
		const shouldStripTestVars = getEnvBool("PROMPTFOO_STRIP_TEST_VARS", false);
		const shouldStripGradingResult = getEnvBool("PROMPTFOO_STRIP_GRADING_RESULT", false);
		const shouldStripMetadata = getEnvBool("PROMPTFOO_STRIP_METADATA", false);
		const response = shouldStripResponseOutput && this.response ? {
			...this.response,
			output: "[output stripped]"
		} : this.response;
		const prompt = shouldStripPromptText ? {
			...this.prompt,
			raw: "[prompt stripped]"
		} : this.prompt;
		const testCase = shouldStripTestVars ? {
			...this.testCase,
			vars: void 0
		} : this.testCase;
		return {
			cost: this.cost,
			description: this.description || void 0,
			error: this.error || void 0,
			gradingResult: shouldStripGradingResult ? null : this.gradingResult,
			id: this.id,
			latencyMs: this.latencyMs,
			namedScores: this.namedScores,
			prompt,
			promptId: this.promptId,
			promptIdx: this.promptIdx,
			provider: {
				id: this.provider.id,
				label: this.provider.label
			},
			response,
			score: this.score,
			success: this.success,
			testCase,
			testIdx: this.testIdx,
			vars: shouldStripTestVars ? {} : this.testCase.vars || {},
			metadata: shouldStripMetadata ? {} : this.metadata,
			failureReason: this.failureReason
		};
	}
};

//#endregion
export { sanitizeProvider as n, EvalResult as t };
//# sourceMappingURL=evalResult-BrJ2GK2O.js.map